Automatizzare il ciclo di riaddestramento
Trasforma una distribuzione in un ciclo ripetibile: un runbook, un controllo di promozione con script, un rilascio automatizzato con rollback e una revisione settimanale.
La prima distribuzione è un progetto; tutte le successive sono un processo. I team che automatizzano il ciclo completano il riaddestramento in un pomeriggio ogni volta che scatta l'avviso del holdout; gli altri devono ricostruire la procedura a memoria sotto pressione e distribuiscono regressioni. In questa lezione eseguirai il ciclo completo una volta sul modello delle pillole, dal fine-tuning al controllo e al rilascio, e scriverai il runbook che renderà ordinaria la prossima esecuzione.
Pratico
Il ciclo, con un responsabile per ogni fase#
La tracciabilità è già disponibile se hai seguito le lezioni precedenti: la scheda Informazioni sull'esecuzione di un modello indica il modello padre e la versione del dataset fissata; la scheda Modelli del dataset elenca tutti i modelli addestrati su ciascuna versione; la pagina di deployment rimanda al modello utilizzato. Quando l'accuratezza cala, parti dal deployment e ripercorri i passaggi a ritroso.

Agents automatizza la fase di raccolta. Raccogli rilevamenti incerti esegue predizioni tramite il tuo deployment e copia in un dataset di revisione le immagini con rilevamenti che rientrano in un intervallo di confidenza; Acquisisci e avvisa salva le immagini corrispondenti e pubblica un messaggio su Slack. I workflow vengono eseguiti quando fai clic su Esegui, quindi includi un'esecuzione nella revisione settimanale.

Esempio pratico: un ciclo completo sul modello delle pillole#
1. Esegui il fine-tuning a partire dal modello distribuito. Su Platform, seleziona il modello distribuito in I miei modelli, attiva Salva versione del dataset e imposta esplicitamente l'ottimizzatore. In locale, il passaggio è lo stesso:
from ultralytics import YOLO
model = YOLO("pills-v1.pt") # il file best.pt del modello distribuito
model.train(data="medical-pills.yaml", epochs=5, imgsz=320, optimizer="SGD", lr0=0.001, name="v2-finetune")Questo è il fine-tuning descritto in Addestrare, leggere e perfezionare le esecuzioni: mAP50-95 0.659 → 0.687.
2. Confrontalo con il modello distribuito. Riutilizza gate.py della lezione 6 con il set di holdout e i due checkpoint:
DATA = "medical-pills.yaml" # il file YAML del tuo dataset di holdout o un URI ul://
BASELINE, CANDIDATE = "pills-v1.pt", "pills-v2.pt" # modello distribuito rispetto al candidato riaddestratoPASS mAP50-95 0.659 -> 0.687 beats noise
PASS every class keeps 90% of its AP (weak: none)
PASS inference 4.0 ms within 100 ms
verdict: ship the candidateIl gate restituisce 0, quindi la CI può proseguire alla fase di rilascio. (In questa demo, lo split di validazione medical-pills viene usato al posto di un holdout; in produzione, usa una versione di holdout che il modello non ha mai visto.)
3. Rilascialo. Carica o addestra il candidato nello stesso workspace, poi lascia che la CI richiami Sostituisci modello tramite l'SDK ultralytics-platform e verifica quale modello è in uso:
import time
from ultralytics_platform import Platform
OWNER, DEPLOYMENT = "your-username", "pill-detector-st-ghislain"
PROJECT, NEW_MODEL = "pill-inspection", "v2-finetune"
with Platform() as client: # reads ULTRALYTICS_API_KEY
body = {"action": "replace", "project": PROJECT, "model": NEW_MODEL}
reply = client.deployments.update(OWNER, DEPLOYMENT, body=body)
print(reply["status"], "-", reply["message"]) # "deploying" while the new model starts
while (deployment := client.deployments.retrieve(OWNER, DEPLOYMENT)["deployment"])["status"] == "deploying":
time.sleep(15)
print(f"status={deployment['status']} model={deployment.get('model')}")
if deployment.get("model") != NEW_MODEL: # a failed rollout leaves the previous model serving
raise SystemExit("Replacement failed; the previous model is still live")Con un'API simulata che restituisce deploying una volta e poi ready, il comando stampa:
deploying - Replacement model is deploying
status=ready model=v2-finetunedeployments.update invia PATCH /api/deployments/{owner}/{deployment} con action: "replace"; il vecchio modello continua a essere in uso finché il nuovo non è pronto. Il ciclo interroga retrieve finché lo stato non esce da deploying, poi verifica il modello in uso, perché anche un rilascio non riuscito termina con ready, ma lascia in uso il vecchio modello. Per eseguire il rollback, usa lo stesso script impostando NEW_MODEL sulla versione precedente. Lo strumento a riga di comando ul cloud fornito con ultralytics utilizza la stessa API, e la documentazione di riferimento dell'API descrive ogni chiamata.
4. Reimposta la baseline. Esegui holdout_check.py della lezione 8 con il nuovo checkpoint e un file di cronologia vuoto.
Scrivi il runbook#
# Retraining runbook: pill-detector
## Trigger
- Holdout mAP50-95 more than 1 point below baseline for 2 consecutive weeks, OR
- Batch Annotation edit rate above 25% on a new batch.
## Steps
1. Collect: Save to dataset from Monitoring, plus the "Collect Uncertain Detections" agent into pill-review.
2. Label: Batch Annotation with the deployed model at the swept threshold; review every image; record the edit rate.
3. Merge into the training dataset; rerun the duplicate check, class audit, and Clustering.
4. Create dataset version v(n+1) with a description of what changed.
5. Fine-tune from the deployed model with Save Dataset Version on; optimizer SGD, lr0 0.001.
6. Run gate.py against the deployed model on the holdout. Stop here on any FAIL.
7. ML lead approves; CI runs release.py.
8. Watch endpoint_check.py for 24 hours; start a new holdout baseline.
## Rollback
- Run release.py with NEW_MODEL set to the previous version. Never delete that model while it's the rollback target.
## Owner
- ML lead approves step 7. On-call runs steps 1-6 and 8.Dedica 15 minuti alla revisione settimanale in calendario e rispondi a due domande: c'è qualcosa in rosso (controllo dell'endpoint, holdout, tasso di modifica)? È cambiato qualcosa nel deployment, e perché? Nella maggior parte delle settimane la risposta a entrambe è no e la riunione dura cinque minuti. Ecco un esempio di trimestre tipico:
Week 1 : Holdout alert. Collect, label, retrain, gate, release v(n+1).
Week 2-3 : Quiet. Checks green.
Week 4 : New defect class requested. Label, new version, retrain v(n+2).
Week 5-7 : Quiet.
Week 8 : Second plant in Poland. Check regions; add an endpoint in europe-central2.
Week 9-11: Quiet.
Week 12 : Quarterly holdout refresh and review.Insidie#
Sintomo: una release non va a buon fine e il modello precedente non è più disponibile. Soluzione: mantieni nel progetto almeno gli ultimi due modelli in produzione. L'eliminazione di un modello lo sposta nel Cestino, mentre l'eliminazione definitiva rimuove anche ogni deployment che lo sta ancora servendo.
Sintomo: avevi pianificato un canary al 10%/50%/100%, ma Sostituisci modello sposta tutto il traffico in una sola volta. Soluzione: gli endpoint servono un solo modello. Per un canary, esegui il deployment del modello candidato su un secondo endpoint e suddividi il traffico nel tuo router, quindi sostituisci il modello ed elimina il secondo endpoint.
Sintomo: tutti i candidati superano il gate, ma in produzione le prestazioni continuano a peggiorare. Soluzione: il gate è affidabile solo su una versione di holdout su cui nessuna esecuzione è stata addestrata. Mantieni il set di holdout in un dataset privato separato e non unirlo mai ai dati di addestramento.
Mostra la soluzione
Ciclo completato per la linea delle pillole. Trigger: il controllo del holdout del turno di notte è calato di 0.05. Raccolta: 180 esempi serali di Monitoring salvati in pill-review più 120 dall'agente Raccogli rilevamenti incerti; Annotazione batch a 0.35 con il modello distribuito v2-finetune, tasso di modifica del 18%; dati revisionati e uniti; verifiche senza problemi; versione v6: +300 night-shift frames. Fine-tuning di v3-night a partire da v2-finetune, SGD, lr0 0.001, 20 epoche. Gate sul holdout di 300 immagini, incluse 100 immagini notturne: mAP50-95 0.66 → 0.71, nessuna classe debole, 4 ms: SUPERATO. release.py con NEW_MODEL = "v3-night" riporta status=ready model=v3-night; holdout_check.py scrive una nuova baseline di 0.71. v2-finetune resta nel progetto come modello di riferimento per il rollback e il runbook, il gate e lo script di rilascio vengono registrati insieme.