mlops machine-learning devops produzione

MLOps: Quello Che Nessuno Ti Dice Quando Passi alla Produzione

MLOps spiegato da chi ci è passato. Come portare i modelli ML in produzione senza impazzire. Tool, workflow, e lezioni imparate sul campo.

Il modello funziona nel notebook. L'accuracy è buona. Il tuo capo è contento. "Perfetto, mettiamolo in produzione." E lì iniziano i problemi.

Se hai mai provato a portare un modello ML dal prototipo alla produzione, sai di cosa parlo. Quello che funzionava perfettamente sul tuo laptop improvvisamente si comporta in modo strano. I dati in produzione sono diversi da quelli di training. Il modello è troppo lento. Occupa troppa memoria. Nessuno sa quale versione del codice è in produzione. Benvenuto nel mondo del MLOps.

Cos'è MLOps (Sul Serio)

MLOps è l'applicazione dei principi DevOps al machine learning. Sembra semplice, ma c'è una differenza fondamentale: nel software tradizionale, il codice è deterministic. Se funziona oggi, funziona domani. Nel ML, hai codice più dati più modello, e tutti e tre cambiano nel tempo in modi che interagiscono.

Un pipeline ML in produzione deve gestire:

  • Codice che cambia (come nel software normale)
  • Dati che cambiano (nuovi dati, distribuzione che deriva)
  • Modelli che cambiano (retraining, nuove versioni)
  • Dipendenze tra tutti questi elementi

Se hai mai debuggato un problema causato da una combinazione di versione del codice, snapshot dei dati, e checkpoint del modello, sai quanto può diventare complicato.

Il Ciclo di Vita Reale di un Progetto ML

La teoria dice: raccogli dati, traina il modello, deploya, monitora, ripeti. La pratica è molto più caotica.

Fase 1: Prototipazione

Tutti iniziano qui. Jupyter notebook, dataset locale, modello che funziona "abbastanza bene". Questa fase è divertente. Puoi sperimentare, iterare velocemente, provare cose diverse.

Il problema è che molti progetti restano bloccati qui per sempre. Il notebook diventa sempre più complesso, pieno di celle commentate, varianti di codice, output intermedi. Nessuno sa più cosa fa cosa.

Fase 2: Il Primo Tentativo di Produzione

Arriva il momento di "mettere in produzione". La soluzione tipica è prendere il codice dal notebook, metterlo in uno script Python, wrapparlo in un'API Flask, deployarlo su un server. Funziona, più o meno.

Poi qualcuno chiede: "quale versione del modello stiamo usando?". E nessuno sa rispondere con certezza.

Fase 3: Le Cose Iniziano a Rompersi

Il modello in produzione degrada nel tempo. I dati cambiano, il mondo cambia. Servono nuove feature. Qualcuno rompe qualcosa in un update. Il server va giù di notte e nessuno se ne accorge.

Questa è la fase dove la maggior parte dei team capisce che serve un approccio più strutturato.

Fase 4: MLOps per Davvero

Si introducono strumenti per versioning, pipeline automatizzate, monitoring. Il processo diventa più lento ma più affidabile. I deployment diventano prevedibili. I rollback sono possibili.

Gli Strumenti che Uso

Dopo aver provato praticamente tutto quello che c'è sul mercato, ecco cosa uso per i progetti di lavoro.

Experiment Tracking: MLflow

MLflow non è fancy, ma funziona. Ogni esperimento viene loggato con parametri, metriche, e artefatti. Posso confrontare run diverse, tornare indietro a vedere cosa ho provato tre mesi fa, riprodurre risultati.

import mlflow

with mlflow.start_run():
    mlflow.log_param("learning_rate", 0.001)
    mlflow.log_param("batch_size", 32)

    # Training...

    mlflow.log_metric("accuracy", accuracy)
    mlflow.log_metric("loss", loss)
    mlflow.sklearn.log_model(model, "model")

Sembra banale, ma la differenza tra avere questo logging e non averlo è enorme quando devi capire perché il modello di tre mesi fa funzionava meglio di quello attuale.

Weights & Biases (wandb) è l'alternativa più moderna, con UI migliore e features come gli sweep per hyperparameter tuning. Lo uso per progetti di ricerca dove voglio visualizzazioni più belle. Per produzione, MLflow mi basta.

Data Versioning: DVC

Git versiona il codice. DVC versiona i dati. L'idea è semplice: invece di committare file grossi in Git (che lo odierebbe), committa solo un puntatore. I dati veri stanno su S3, GCS, o qualsiasi storage tu voglia.

dvc add data/training_data.csv
git add data/training_data.csv.dvc
git commit -m "Add training data v2"
dvc push

Ora posso tornare a qualsiasi versione dei dati nella storia Git. Se il modello di tre mesi fa funzionava meglio, posso prendere esattamente quei dati e quel codice e riprodurre l'esperimento.

Pipeline: Non Usare Airflow per ML

So che Airflow è lo standard per orchestrazione, e se già ce l'hai va bene usarlo. Ma per pipeline ML puro, preferisco strumenti pensati per ML.

Prefect è quello che uso di più. È come Airflow ma meno doloroso. Le pipeline sono Python normale, non DAG XML o YAML. Il debugging è più facile perché puoi eseguire le funzioni direttamente.

Kubeflow Pipelines se sei su Kubernetes e vuoi scalare. È più complesso da setup ma integra bene training distribuito, serving, e monitoring.

Metaflow (Netflix) è interessante se fai data science e vuoi qualcosa che scala senza cambiare molto codice. È pensato per rendere facile il passaggio da laptop a cloud.

Model Serving: Dipende

Per servire modelli in produzione, ho usato di tutto. La scelta dipende molto dal contesto.

Per LLM e modelli grossi: vLLM. È velocissimo, supporta batching continuo, e gestisce bene la memoria. Se servi un modello da miliardi di parametri, vLLM ti cambia la vita.

Per modelli tradizionali (sklearn, xgboost): Spesso basta FastAPI. Non serve overthinking. Wrappa il modello in un endpoint, metti un load balancer davanti, e hai finito.

Per scale enterprise: BentoML o Seldon. Gestiscono versioning, A/B testing, canary deployment, monitoring. Più complessi ma più completi.

Per inferenza batch: Non serve un server. Script che legge da una queue, processa, scrive risultati. Kubernetes Job o AWS Batch.

Monitoring: La Parte Che Tutti Dimenticano

Deploya un modello senza monitoring e scoprirai i problemi solo quando gli utenti si lamentano. O peggio, quando i danni sono già fatti.

Due tipi di monitoring:

Monitoring tecnico: Il modello risponde? Quanto veloce? Quanta memoria usa? Per questo basta Prometheus + Grafana, come per qualsiasi servizio.

Monitoring ML: Il modello sta performando bene? I dati in input sono ancora simili a quelli di training? C'è data drift? Per questo servono tool specifici.

Evidently è quello che uso. Open source, si integra bene con MLflow, genera report su drift e performance. Puoi settare alert quando le metriche escono dai range attesi.

from evidently.report import Report
from evidently.metrics import DataDriftPreset

report = Report(metrics=[DataDriftPreset()])
report.run(reference_data=train_data, current_data=prod_data)
report.save_html("drift_report.html")

Feature Store: Ne Hai Bisogno?

I feature store sono andati molto di moda. L'idea è di avere un sistema centralizzato per creare, gestire, e servire feature ML. Le feature vengono calcolate una volta e usate da più modelli. Hai consistenza tra training e serving.

Detto questo, per molti progetti non servono. Se hai un team piccolo, pochi modelli, e feature semplici, un feature store è overkill. Aggiunge complessità senza dare abbastanza valore in cambio.

Ne hai bisogno se:

  • Hai molti modelli che usano le stesse feature
  • Le feature sono costose da calcolare
  • Hai bisogno di feature realtime da multiple sorgenti
  • Il team è abbastanza grande da giustificare l'overhead

Se decidi che ti serve, Feast è l'opzione open source più matura. I cloud provider hanno le loro soluzioni managed (SageMaker Feature Store, Vertex Feature Store).

CI/CD per ML

Il CI/CD per ML è diverso dal CI/CD normale perché devi testare non solo il codice ma anche il modello.

Test del codice: Unit test normali, test di integrazione, linting. Niente di speciale.

Test dei dati: Validazione schema, check su range di valori, test per valori mancanti. Great Expectations è ottimo per questo.

Test del modello: Qui diventa interessante. Devi testare:

  • Il modello carica senza errori
  • L'inference funziona con input validi
  • Le predizioni sono nel range atteso
  • La performance su un test set di riferimento non è degradata

Una pipeline CI/CD tipica per ML:

  1. Push su feature branch
  2. Lint e unit test
  3. Data validation
  4. Training su subset di dati
  5. Model validation
  6. Se tutto passa, merge allowed
  7. Su merge a main, training completo
  8. Model validation su test set completo
  9. Se passa threshold, deploy automatico (o notifica per review)

Lezioni Imparate

Dopo anni a fare questo mestiere, qualche lezione che avrei voluto sapere prima.

Inizia semplice. Non hai bisogno di Kubeflow, Feast, e monitoring distribuito per il tuo primo modello in produzione. Inizia con MLflow per tracking, uno script di training, FastAPI per serving. Aggiungi complessità solo quando serve.

Versiona tutto. Codice, dati, modelli, configurazioni. Quando qualcosa si rompe (e succederà), devi poter tornare indietro e capire cosa è cambiato.

Automatizza il retraining, ma non troppo. Retraining automatico è comodo ma pericoloso. Almeno all'inizio, fai review manuale prima di deployare un nuovo modello. Aggiungi automazione gradualmente man mano che capisci meglio come si comporta il sistema.

Monitora i dati, non solo le metriche. Se i dati in input cambiano, il modello performerà male anche se non hai toccato niente. Data drift monitoring non è opzionale per sistemi in produzione seria.

Documenta le decisioni. Perché hai scelto quel modello? Perché quei parametri? Perché quei dati di training? Tra sei mesi non ti ricorderai, e neanche il tuo collega che erediterà il progetto.

Il modello è solo una parte. Nel sistema finale, il modello ML è forse il 20% del codice. Il resto è data pipeline, preprocessing, postprocessing, API, monitoring, logging, error handling. Non sottovalutare questo "resto".

Setup Minimo Consigliato

Se dovessi partire da zero oggi con un nuovo progetto ML, questo è lo stack minimo che userei:

  • Experiment tracking: MLflow
  • Versioning: Git + DVC
  • Training: Script Python pulito, non notebook
  • Serving: FastAPI (per modelli semplici) o vLLM (per LLM)
  • Monitoring: Prometheus + Grafana + Evidently
  • CI/CD: GitHub Actions

Questo setup copre il 90% dei casi senza essere overengineered. Aggiungi complessità solo quando hai prove concrete che ti serve.

Risorse per Andare Oltre

Se vuoi approfondire:

Il libro "Designing Machine Learning Systems" di Chip Huyen è eccellente. Copre MLOps end-to-end con esempi pratici.

La documentazione di MLflow è sorprendentemente buona. Inizia da lì se non l'hai mai usato.

Il corso "Full Stack Deep Learning" è gratuito online e copre molti aspetti pratici che i corsi accademici ignorano.

E ovviamente, niente batte l'esperienza. Prendi un progetto, mettilo in produzione, rompi cose, impara. È l'unico modo per capire davvero cosa funziona e cosa no.


MLOps non è sexy come trainare modelli, ma è quello che separa i progetti che funzionano da quelli che restano nei notebook.