Skip to Content
Ai LogProduction model β†’ floor300r2-medsiglip-s17 (app pointer updated; deploy gated)

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_prefix default models/gen2a_medsiglip β†’ models/floor300r2-medsiglip-s17. This is the app’s declared production model. The serving stack is class-count agnostic (predictor.py reads labels.txt dynamically, 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 reads floor300_r2.txt (71 names) instead of common25.txt, so newly-predictable diagnoses autocomplete. (Mounted via the existing ./src/training/labels:/app/labels volume.)

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

  1. Re-fit the tier thresholds. config.py tier_confident_threshold=0.815, tier_refer_threshold=0.444, possible_item_threshold=0.25 were 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:
    # 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/*.parquet
    Then update the three config.py thresholds to the chosen values. (Per the Round-1 note these remain provisional pending dermatologist-cleaned test labels; current split has ~7–16% label noise.)
  2. 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/Dockerfile to ECR, then force a new ECS deployment. The new task pulls models/floor300r2-medsiglip-s17 into /models/gen2a.
  • No-rebuild override: set MODELS_S3_PREFIX=models/floor300r2-medsiglip-s17 on the ECS task via terraform/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.

Last updated on