Continuous Integration (CI)
L'integrazione continua (CI) unisce spesso le modifiche al codice e le testa automaticamente; le pipeline di ML aggiungono controlli sui dati e soglie di qualità dei modelli.
L'integrazione continua (CI) è la pratica di unire frequentemente le modifiche di ogni sviluppatore a un branch main condiviso, almeno una volta al giorno, e di creare e testare automaticamente ogni modifica, così i problemi di integrazione emergono in pochi minuti anziché al momento del rilascio. Grady Booch propose il termine nel 1991, Kent Beck lo rese una pratica fondamentale di Extreme Programming alla fine degli anni 1990 e l'articolo di Martin Fowler Continuous Integration descrive il flusso di lavoro seguito ancora oggi dalla maggior parte dei team. Nell'apprendimento automatico (ML), la CI verifica anche i dati, il codice di addestramento e il comportamento del modello, perché una modifica può lasciare superare tutti i test unitari ma ridurre la precisione del modello.
Come funziona una pipeline CI#
Quando uno sviluppatore invia un branch o apre una pull request, un servizio CI come GitHub Actions, GitLab CI/CD o Jenkins avvia un runner nuovo, recupera il codice, installa le dipendenze ed esegue una pipeline di job: linter e type checker, test unitari, test di integrazione e build di pacchetti o immagini container. Ogni job comunica il proprio stato alla pull request e le regole di protezione del branch possono impedire il merge finché tutti i controlli obbligatori non sono superati. Spesso le pipeline ripetono gli stessi test su una matrice di sistemi operativi e versioni Python, ed eseguono di nuovo l'intera suite sul branch main dopo ogni merge. La velocità fa parte della pratica: Extreme Programming di Beck fissava a dieci minuti l'obiettivo per creare l'intero sistema ed eseguire tutti i test, perché una build più lenta viene eseguita meno spesso.
CI per l'apprendimento automatico#
I progetti ML aggiungono controlli specifici. I test sui dati verificano che i nuovi dati di addestramento corrispondano allo schema previsto, che tutti i file delle etichette siano analizzabili e che nessuna immagine compaia sia nella divisione di addestramento sia in quella di validazione, causando una fuga di dati. Un test rapido addestra il modello per una epoca su un dataset minuscolo per individuare in pochi minuti errori di forma e crash. I test che confrontano gli output del modello fissano i seed casuali e ammettono piccole tolleranze numeriche, poiché i kernel GPU e l'ordine di caricamento dei dati possono modificare i risultati in virgola mobile da un'esecuzione all'altra. Un controllo qualità valuta il modello su un insieme di validazione fisso e interrompe la build se una metrica come la precisione media media (mAP) scende sotto una soglia; i test di esportazione verificano che le versioni del modello in ONNX o TensorRT continuino a caricarsi e a ottenere punteggi simili all'originale. L'addestramento completo è lento e i runner GPU sono costosi, quindi i team eseguono solitamente controlli rapidi a ogni pull request e riservano il riaddestramento completo e la distribuzione del modello alle esecuzioni pianificate o sul branch main; strumenti di versionamento come DVC permettono a ogni job di recuperare la versione esatta del dataset necessaria.
La modalità benchmark di Ultralytics YOLO funziona come un simile controllo: quando verbose è impostato su un valore float come 0.216, genera un errore se un'esportazione non riesce o se il mAP50-95 di un formato esportato non supera la soglia; la CI del repository Ultralytics la usa per testare le esportazioni YOLO26 su runner Linux, macOS e ARM. Un workflow GitHub Actions minimo combina test unitari e controllo:
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v6
with:
python-version: "3.13"
- run: pip install ultralytics pytest
- run: pytest tests/
# Fail if the ONNX export breaks or its mAP50-95 is not above the 0.216 floor
- run: yolo benchmark model=yolo26n.pt format=onnx imgsz=160 verbose=0.216Il job viene eseguito su un runner Ubuntu nuovo a ogni pull request e a ogni push su main. Un test unitario non superato o un modello ONNX con un punteggio pari o inferiore alla soglia sul piccolo dataset COCO8 fa fallire il controllo prima che la modifica possa essere integrata.
CI, CD, MLOps e addestramento continuo#
- Consegna continua (CD): Prende le build che superano la CI e le mantiene pronte per il rilascio, spesso distribuendole automaticamente in un ambiente di staging. Il deployment continuo fa un ulteriore passo avanti e porta in produzione ogni modifica che supera i controlli.
- MLOps: Disciplina più ampia che combina CI e CD con versionamento dei dati, deployment dei modelli, monitoraggio e riaddestramento durante il ciclo di vita ML.
- Addestramento continuo (CT): Riaddestra e ridistribuisce automaticamente un modello quando arrivano nuovi dati o il monitoraggio rileva un drift. I livelli di maturità MLOps di Google collocano il riaddestramento automatizzato al livello 1 e la CI/CD automatizzata per la pipeline di addestramento stessa al livello 2.










