Production model β floor300r2-medsiglip-s17 (app pointer updated; deploy gated)
Date: 2026-08-14
Points the ai_service at the round-2 expanded-diagnosis model
(floor300r2-medsiglip-s17, 71 classes + βotherβ) instead of the 25-class
gen2a_medsiglip. The app code/config is updated; the live deploy and a
required threshold re-fit are intentionally NOT done here β see the gate below.
What changed (committed)
src/ai_service/src/config.pyβmodels_s3_prefixdefaultmodels/gen2a_medsiglipβmodels/floor300r2-medsiglip-s17. This is the appβs declared production model. The serving stack is class-count agnostic (predictor.pyreadslabels.txtdynamically, response schema is a free-form list, red-flag rules are anamnesis-keyed not diagnosis-keyed), so the swap is a drop-in at the artifact level.src/api_gateway/src/api/cases.pyβ physician-annotation autocomplete (GET /labels/diseases) now readsfloor300_r2.txt(71 names) instead ofcommon25.txt, so newly-predictable diagnoses autocomplete. (Mounted via the existing./src/training/labels:/app/labelsvolume.)
Model artifacts verified in s3://dermadetect-models/models/floor300r2-medsiglip-s17/
(best_model.pt, config.json, labels.txt (71 lines), feature_schema.json).
GATE β do NOT serve to patients until these are done
- Re-fit the tier thresholds.
config.pytier_confident_threshold=0.815,tier_refer_threshold=0.444,possible_item_threshold=0.25were fit on the 25-class modelβs max-probability distribution. They are global thresholds on the top class probability; a 71-class multi-label sigmoid model has a different distribution, so the confident/possible/refer split and the 10% triage cut will be mis-calibrated (no crash, wrong behavior). Re-fit before live traffic:Then update the three# 1. dump production-shaped probs for the r2 model on the test split uv run --package ddtrain python scripts/eval/dump_probs.py \ ~/floor300r2_medsiglip_model --out ~/.cache/dermadetect/r2_prod_probs # 2. produce candidate thresholds + accuracy@coverage reports uv run --package ddtrain python scripts/eval/refit_tier_thresholds.py \ --probs ~/.cache/dermadetect/r2_prod_probs/*.parquetconfig.pythresholds to the chosen values. (Per the Round-1 note these remain provisional pending dermatologist-cleaned test labels; current split has ~7β16% label noise.) - Clinical validation. The round-1 deployable model went through
clinical_eval+ a red-flag audit before shipping. Round 2 has research metrics only (val top-1 0.627; 25-class apples-to-apples eval in progress) β no dermatologist sign-off yet.
Deploy runbook (the actual cut-over β human-gated)
The model is pulled from S3 on container start; it is NOT baked into the image.
Live deployment is AWS ECS (Fargate GPU / T4), provisioned by the separate
terraform repo, env env-dev (env-prod app_infra is still commented out).
Two options once the gate is cleared:
- Rebuild + redeploy (matches the committed config default): build & push
src/ai_service/Dockerfileto ECR, then force a new ECS deployment. The new task pullsmodels/floor300r2-medsiglip-s17into/models/gen2a. - No-rebuild override: set
MODELS_S3_PREFIX=models/floor300r2-medsiglip-s17on the ECS task viaterraform/env-dev/main.tf(ai_service_environment_variables, currently[]),terraform apply, restart the task.
Either way: after the task restarts, hit /health and a smoke /diagnosis/predict
and confirm labels.txt loaded 71 classes before routing patient traffic.