n4ksworks commited on
Commit
f24bdea
·
1 Parent(s): 8222dc6

fix(diagnosis): ship the CNN weights the Space was missing

Browse files

Every /api/v1/diagnosis/predict on the live Space answered 503 "Diagnosis
model is not available": model_wrapper.load() raised FileNotFoundError
because the TorchScript export and its metadata were never committed.

The cause was one unanchored .gitignore pattern. `trained_artifacts_fast/`
has no leading slash, so git matched it at every depth -- it was meant for
the scratch copy training drops at the repo root, but it also swallowed
ml/post_symptom_diagnosis/saved_models/trained_artifacts_fast/. Every other
module ships its saved_models/; this one shipped a lone README, and the gap
read as intentional -- the top-level README documented the 503 under Known
Issues as "the CNN artifacts are not in this repo".

Anchor the pattern to /trained_artifacts_fast/ and commit the two files
inference actually reads. The .pt goes through LFS, which the Space requires
for binaries. The .pth checkpoint stays ignored: it is the training-side
fallback, no inference path opens it, and it would add 14 MB to the image
for nothing.

Verified by loading the wrapper from the shipped pair alone -- 88 classes,
img_size 192 -- and running a forward pass to a normalised top-3.

.gitignore CHANGED
@@ -59,7 +59,18 @@ backend/.env.*
59
  backend/artifacts/*/advisor/
60
  backend/artifacts/edge/fallback_events.jsonl
61
  backend/artifacts/**/sync_state.json
62
- trained_artifacts_fast/
 
 
 
 
 
 
 
 
 
 
 
63
 
64
  # Local user files
65
  *.crdownload
 
59
  backend/artifacts/*/advisor/
60
  backend/artifacts/edge/fallback_events.jsonl
61
  backend/artifacts/**/sync_state.json
62
+
63
+ # The scratch copy of the diagnosis CNN that training drops at the repo root.
64
+ # The leading slash is load-bearing: written bare, this pattern matched at every
65
+ # depth and silently swallowed the *real* artifacts under
66
+ # ml/post_symptom_diagnosis/saved_models/trained_artifacts_fast/ too. They never
67
+ # reached the Space, so model_wrapper.load() raised FileNotFoundError and every
68
+ # /api/v1/diagnosis/predict answered 503 "Diagnosis model is not available".
69
+ /trained_artifacts_fast/
70
+
71
+ # The .pth checkpoint is the training-side fallback; inference only ever reads
72
+ # the TorchScript export and the metadata JSON, so keep 14 MB out of the image.
73
+ ml/post_symptom_diagnosis/saved_models/trained_artifacts_fast/*.pth
74
 
75
  # Local user files
76
  *.crdownload
README.md CHANGED
@@ -439,7 +439,7 @@ Full walkthrough: [README_HUGGINGFACE.md](README_HUGGINGFACE.md).
439
 
440
  ## Known Issues & Limitations
441
 
442
- - **Disease diagnosis needs external weights.** The CNN artifacts are not in this repo. Place them at `ml/post_symptom_diagnosis/saved_models/trained_artifacts_fast/` (see that folder's README). Until then, `/api/v1/diagnosis/predict` returns an error.
443
 
444
  - **Dependency versions are load-bearing.** `scikit-learn==1.8.0` and `numpy>=2.0,<3` are pinned exactly because the committed models embed the library versions that serialized them. Installing a different scikit-learn breaks unpickling with `No module named '_loss'`, and every advisor request fails. Don't relax these pins without retraining.
445
 
 
439
 
440
  ## Known Issues & Limitations
441
 
442
+ - **Disease diagnosis weights are LFS-tracked, so a plain clone won't run it.** The CNN artifacts now ship with the repo at `ml/post_symptom_diagnosis/saved_models/trained_artifacts_fast/`, but a clone made without Git LFS leaves the 14 MB TorchScript export as a 133-byte pointer file, and `/api/v1/diagnosis/predict` answers `503 Diagnosis model is not available`. Run `git lfs pull` after cloning.
443
 
444
  - **Dependency versions are load-bearing.** `scikit-learn==1.8.0` and `numpy>=2.0,<3` are pinned exactly because the committed models embed the library versions that serialized them. Installing a different scikit-learn breaks unpickling with `No module named '_loss'`, and every advisor request fails. Don't relax these pins without retraining.
445
 
ml/post_symptom_diagnosis/saved_models/README.md CHANGED
@@ -7,14 +7,25 @@ This directory stores the trained model artifacts for the **Post-Symptom Diagnos
7
  ```
8
  saved_models/
9
  └── trained_artifacts_fast/
10
- ├── best_plant_disease_model_fast.pth # PyTorch checkpoint (fallback)
11
- ── class_metadata_fast.json # Class names, crop mapping, img_size
12
- └── plant_disease_model_fast_torchscript.pt # TorchScript export (primary inference)
13
  ```
14
 
 
 
 
 
15
  ## How to populate
16
 
17
- Copy the contents of the externally-trained `trained_artifacts_fast/` folder into `saved_models/trained_artifacts_fast/`.
 
 
 
 
 
 
 
 
18
 
19
  ## Usage
20
 
 
7
  ```
8
  saved_models/
9
  └── trained_artifacts_fast/
10
+ ├── class_metadata_fast.json # Class names, crop mapping, img_size — committed
11
+ ── plant_disease_model_fast_torchscript.pt # TorchScript export, primary inference — committed via LFS
 
12
  ```
13
 
14
+ Both files are committed, so the deployed Space can serve diagnoses. Only these
15
+ two are: `best_plant_disease_model_fast.pth` is the training-side checkpoint and
16
+ no inference path reads it, so `.gitignore` keeps its 14 MB out of the image.
17
+
18
  ## How to populate
19
 
20
+ Nothing to do for a normal clone but clone *with* Git LFS, or run `git lfs
21
+ pull` afterwards. Without it the `.pt` stays a 133-byte pointer, `torch.jit.load`
22
+ fails, and `/api/v1/diagnosis/predict` answers `503 Diagnosis model is not
23
+ available`.
24
+
25
+ After retraining, copy the fresh `trained_artifacts_fast/` contents over these
26
+ files. Keep the `.gitignore` rule anchored as `/trained_artifacts_fast/` — written
27
+ bare it matches at every depth and silently re-excludes this directory, which is
28
+ exactly how the artifacts went missing from the Space before.
29
 
30
  ## Usage
31
 
ml/post_symptom_diagnosis/saved_models/trained_artifacts_fast/class_metadata_fast.json ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "class_names": [
3
+ "Apple__black_rot",
4
+ "Apple__healthy",
5
+ "Apple__rust",
6
+ "Apple__scab",
7
+ "Cassava__bacterial_blight",
8
+ "Cassava__brown_streak_disease",
9
+ "Cassava__green_mottle",
10
+ "Cassava__healthy",
11
+ "Cassava__mosaic_disease",
12
+ "Cherry__healthy",
13
+ "Cherry__powdery_mildew",
14
+ "Chili__healthy",
15
+ "Chili__leaf curl",
16
+ "Chili__leaf spot",
17
+ "Chili__whitefly",
18
+ "Chili__yellowish",
19
+ "Coffee__cercospora_leaf_spot",
20
+ "Coffee__healthy",
21
+ "Coffee__red_spider_mite",
22
+ "Coffee__rust",
23
+ "Corn__common_rust",
24
+ "Corn__gray_leaf_spot",
25
+ "Corn__healthy",
26
+ "Corn__northern_leaf_blight",
27
+ "Cucumber__diseased",
28
+ "Cucumber__healthy",
29
+ "Gauva__diseased",
30
+ "Gauva__healthy",
31
+ "Grape__black_measles",
32
+ "Grape__black_rot",
33
+ "Grape__healthy",
34
+ "Grape__leaf_blight_(isariopsis_leaf_spot)",
35
+ "Jamun__diseased",
36
+ "Jamun__healthy",
37
+ "Lemon__diseased",
38
+ "Lemon__healthy",
39
+ "Mango__diseased",
40
+ "Mango__healthy",
41
+ "Peach__bacterial_spot",
42
+ "Peach__healthy",
43
+ "Pepper_bell__bacterial_spot",
44
+ "Pepper_bell__healthy",
45
+ "Pomegranate__diseased",
46
+ "Pomegranate__healthy",
47
+ "Potato__early_blight",
48
+ "Potato__healthy",
49
+ "Potato__late_blight",
50
+ "Rice__brown_spot",
51
+ "Rice__healthy",
52
+ "Rice__hispa",
53
+ "Rice__leaf_blast",
54
+ "Rice__neck_blast",
55
+ "Soybean__bacterial_blight",
56
+ "Soybean__caterpillar",
57
+ "Soybean__diabrotica_speciosa",
58
+ "Soybean__downy_mildew",
59
+ "Soybean__healthy",
60
+ "Soybean__mosaic_virus",
61
+ "Soybean__powdery_mildew",
62
+ "Soybean__rust",
63
+ "Soybean__southern_blight",
64
+ "Strawberry___leaf_scorch",
65
+ "Strawberry__healthy",
66
+ "Sugarcane__bacterial_blight",
67
+ "Sugarcane__healthy",
68
+ "Sugarcane__red_rot",
69
+ "Sugarcane__red_stripe",
70
+ "Sugarcane__rust",
71
+ "Tea__algal_leaf",
72
+ "Tea__anthracnose",
73
+ "Tea__bird_eye_spot",
74
+ "Tea__brown_blight",
75
+ "Tea__healthy",
76
+ "Tea__red_leaf_spot",
77
+ "Tomato__bacterial_spot",
78
+ "Tomato__early_blight",
79
+ "Tomato__healthy",
80
+ "Tomato__late_blight",
81
+ "Tomato__leaf_mold",
82
+ "Tomato__mosaic_virus",
83
+ "Tomato__septoria_leaf_spot",
84
+ "Tomato__spider_mites_(two_spotted_spider_mite)",
85
+ "Tomato__target_spot",
86
+ "Tomato__yellow_leaf_curl_virus",
87
+ "Wheat__brown_rust",
88
+ "Wheat__healthy",
89
+ "Wheat__septoria",
90
+ "Wheat__yellow_rust"
91
+ ],
92
+ "class_to_crop": {
93
+ "Apple__black_rot": "Apple",
94
+ "Apple__healthy": "Apple",
95
+ "Apple__rust": "Apple",
96
+ "Apple__scab": "Apple",
97
+ "Cassava__bacterial_blight": "Cassava",
98
+ "Cassava__brown_streak_disease": "Cassava",
99
+ "Cassava__green_mottle": "Cassava",
100
+ "Cassava__healthy": "Cassava",
101
+ "Cassava__mosaic_disease": "Cassava",
102
+ "Cherry__healthy": "Cherry",
103
+ "Cherry__powdery_mildew": "Cherry",
104
+ "Chili__healthy": "Chili",
105
+ "Chili__leaf curl": "Chili",
106
+ "Chili__leaf spot": "Chili",
107
+ "Chili__whitefly": "Chili",
108
+ "Chili__yellowish": "Chili",
109
+ "Coffee__cercospora_leaf_spot": "Coffee",
110
+ "Coffee__healthy": "Coffee",
111
+ "Coffee__red_spider_mite": "Coffee",
112
+ "Coffee__rust": "Coffee",
113
+ "Corn__common_rust": "Corn",
114
+ "Corn__gray_leaf_spot": "Corn",
115
+ "Corn__healthy": "Corn",
116
+ "Corn__northern_leaf_blight": "Corn",
117
+ "Cucumber__diseased": "Cucumber",
118
+ "Cucumber__healthy": "Cucumber",
119
+ "Gauva__diseased": "Gauva",
120
+ "Gauva__healthy": "Gauva",
121
+ "Grape__black_measles": "Grape",
122
+ "Grape__black_rot": "Grape",
123
+ "Grape__healthy": "Grape",
124
+ "Grape__leaf_blight_(isariopsis_leaf_spot)": "Grape",
125
+ "Jamun__diseased": "Jamun",
126
+ "Jamun__healthy": "Jamun",
127
+ "Lemon__diseased": "Lemon",
128
+ "Lemon__healthy": "Lemon",
129
+ "Mango__diseased": "Mango",
130
+ "Mango__healthy": "Mango",
131
+ "Peach__bacterial_spot": "Peach",
132
+ "Peach__healthy": "Peach",
133
+ "Pepper_bell__bacterial_spot": "Pepper_bell",
134
+ "Pepper_bell__healthy": "Pepper_bell",
135
+ "Pomegranate__diseased": "Pomegranate",
136
+ "Pomegranate__healthy": "Pomegranate",
137
+ "Potato__early_blight": "Potato",
138
+ "Potato__healthy": "Potato",
139
+ "Potato__late_blight": "Potato",
140
+ "Rice__brown_spot": "Rice",
141
+ "Rice__healthy": "Rice",
142
+ "Rice__hispa": "Rice",
143
+ "Rice__leaf_blast": "Rice",
144
+ "Rice__neck_blast": "Rice",
145
+ "Soybean__bacterial_blight": "Soybean",
146
+ "Soybean__caterpillar": "Soybean",
147
+ "Soybean__diabrotica_speciosa": "Soybean",
148
+ "Soybean__downy_mildew": "Soybean",
149
+ "Soybean__healthy": "Soybean",
150
+ "Soybean__mosaic_virus": "Soybean",
151
+ "Soybean__powdery_mildew": "Soybean",
152
+ "Soybean__rust": "Soybean",
153
+ "Soybean__southern_blight": "Soybean",
154
+ "Strawberry___leaf_scorch": "Strawberry",
155
+ "Strawberry__healthy": "Strawberry",
156
+ "Sugarcane__bacterial_blight": "Sugarcane",
157
+ "Sugarcane__healthy": "Sugarcane",
158
+ "Sugarcane__red_rot": "Sugarcane",
159
+ "Sugarcane__red_stripe": "Sugarcane",
160
+ "Sugarcane__rust": "Sugarcane",
161
+ "Tea__algal_leaf": "Tea",
162
+ "Tea__anthracnose": "Tea",
163
+ "Tea__bird_eye_spot": "Tea",
164
+ "Tea__brown_blight": "Tea",
165
+ "Tea__healthy": "Tea",
166
+ "Tea__red_leaf_spot": "Tea",
167
+ "Tomato__bacterial_spot": "Tomato",
168
+ "Tomato__early_blight": "Tomato",
169
+ "Tomato__healthy": "Tomato",
170
+ "Tomato__late_blight": "Tomato",
171
+ "Tomato__leaf_mold": "Tomato",
172
+ "Tomato__mosaic_virus": "Tomato",
173
+ "Tomato__septoria_leaf_spot": "Tomato",
174
+ "Tomato__spider_mites_(two_spotted_spider_mite)": "Tomato",
175
+ "Tomato__target_spot": "Tomato",
176
+ "Tomato__yellow_leaf_curl_virus": "Tomato",
177
+ "Wheat__brown_rust": "Wheat",
178
+ "Wheat__healthy": "Wheat",
179
+ "Wheat__septoria": "Wheat",
180
+ "Wheat__yellow_rust": "Wheat"
181
+ },
182
+ "num_classes": 88,
183
+ "img_size": 192
184
+ }
ml/post_symptom_diagnosis/saved_models/trained_artifacts_fast/plant_disease_model_fast_torchscript.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:878a6a60624e180f0fa295fed20a2a8532faa6e7f6cc37719465f6850cd13f66
3
+ size 14678584