Versionare i modelli: perché nomi dei file e metadati sono importanti
Imparerete a progettare una convenzione di denominazione che includa data di addestramento, versione del dataset e punteggio della metrica, oltre a scrivere un sidecar di metadati JSON per la governance.
Versionare i modelli: perché nomi dei file e metadati sono importanti è una lezione Machine Learning Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Machine Learning Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Machine Learning Academy include 4 lezioni in totale.
Il problema in assenza di versionamento
Senza una strategia di versionamento rigorosa, i team accumulano rapidamente file come model.pkl, model_v2.pkl, model_final.pkl, model_FINAL_v2.pkl, senza alcuna indicazione dei dati usati per l'addestramento, della metrica raggiunta o della versione effettivamente in esecuzione in produzione. Questo caos porta a distribuire modelli obsoleti, perdere il miglior checkpoint o non riuscire a riprodurre un risultato passato per eseguire il debug.
Informazioni da codificare nel nome del file
Un buon nome di file per un modello dovrebbe codificare un contesto sufficiente a essere autoesplicativo: dataset, algoritmo, data e, facoltativamente, la metrica principale e la versione del dataset o il Git SHA. In questo modo la cartella del registro dei modelli diventa a colpo d'occhio una traccia di audit leggibile, senza dover aprire ogni file.
from datetime import date
def model_filename(dataset, algorithm, metric_name, metric_value,
data_version='v1', ext='joblib'):
today = date.today().strftime('%Y%m%d')
metric_str = f'{metric_name}{int(metric_value * 100)}'
return f'{dataset}__{algorithm}__{today}__dv{data_version}__{metric_str}.{ext}'
# Examples
print(model_filename('titanic', 'rf', 'acc', 0.834, data_version='2'))
print(model_filename('fraud', 'xgb', 'auc', 0.971))
print(model_filename('cancer', 'logreg', 'f1', 0.955))Il sidecar JSON dei metadati
Ogni file di modello dovrebbe avere un file sidecar JSON associato, con lo stesso nome di base. Il sidecar documenta tutto ciò che il nome del file non può indicare: versioni delle librerie, iperparametri, dimensione del set di addestramento, prestazioni sul set di test per tutte le metriche, elenco delle feature ed eventuali note sull'esecuzione dell'addestramento. Questa è la model card minima necessaria.
import json
import sklearn, sys
from datetime import datetime
def save_metadata(path, dataset, algorithm, params, metrics, features, notes=''):
meta = {
'model_path': path,
'dataset': dataset,
'algorithm': algorithm,
'hyperparameters': params,
'metrics': metrics,
'features': features,
'sklearn_version': sklearn.__version__,
'python_version': sys.version.split()[0],
'trained_at': datetime.utcnow().isoformat(),
'notes': notes
}
meta_path = path.replace('.joblib', '_metadata.json')
with open(meta_path, 'w') as f:
json.dump(meta, f, indent=2)
print('Metadata saved to:', meta_path)
return meta
# Usage example
save_metadata(
'/tmp/cancer__logreg__20260620__dv1__acc97.joblib',
dataset='breast_cancer', algorithm='LogisticRegression',
params={'C': 1.0, 'max_iter': 300},
metrics={'accuracy': 0.9789, 'roc_auc': 0.9941, 'f1': 0.9831},
features=['mean radius', 'mean texture', '... 30 total'],
notes='Trained on full UCI breast cancer dataset'
)Tracciamento della versione del dataset
Anche il dataset di addestramento deve essere versionato. Un modello addestrato su data_v1.csv e un altro addestrato su data_v2.csv non dovrebbero mai avere lo stesso identificativo. Per il versionamento dei dataset è possibile: memorizzare il Git SHA del file di dati, registrare un hash MD5/SHA256 del CSV oppure usare uno strumento di versionamento dei dati come DVC (Data Version Control), che gestisce la provenienza dei dataset nello stesso modo in cui Git gestisce il codice.
import hashlib
def file_hash(path, algo='sha256'):
h = hashlib.new(algo)
with open(path, 'rb') as f:
for chunk in iter(lambda: f.read(65536), b''):
h.update(chunk)
return h.hexdigest()[:12] # first 12 hex chars as short ID
# Example: hash the model file itself as a unique ID
model_path = '/tmp/cancer_model.joblib'
model_hash = file_hash(model_path)
print('Model hash (short):', model_hash)Versionamento semantico dei modelli
Prenda spunto dall'ingegneria del software: utilizzi il versionamento semantico (MAJOR.MINOR.PATCH) per i modelli. MAJOR: modifica incompatibile (insieme di feature diverso o schema incompatibile). MINOR: miglioramento delle prestazioni con la stessa API. PATCH: correzione di un bug o ricalibrazione minore. Questa convenzione aiuta gli utilizzatori a valle a comprendere l'impatto dell'aggiornamento della dipendenza dal modello.
model_registry = [
{'version': '1.0.0', 'algorithm': 'LogisticRegression', 'auc': 0.921,
'note': 'Initial production model'},
{'version': '1.1.0', 'algorithm': 'LogisticRegression', 'auc': 0.935,
'note': 'Retrained on 3 months more data'},
{'version': '2.0.0', 'algorithm': 'XGBoost', 'auc': 0.971,
'note': 'New algorithm; feature set changed — incompatible schema'}
]
print('Model Registry:')
for entry in model_registry:
print(f" v{entry['version']} AUC={entry['auc']} {entry['note']}")Un semplice registro locale dei modelli
Un registro leggero dei modelli può essere costituito da una directory con un file registry.json che indicizza tutti i modelli salvati. Ogni voce registra il nome del file, la versione, le metriche principali e l'indicatore di produzione. Lo script di deployment legge questo file per determinare quale modello caricare.
import json
import os
REGISTRY_PATH = '/tmp/model_registry.json'
def register_model(filename, version, metrics, is_production=False):
try:
with open(REGISTRY_PATH) as f:
registry = json.load(f)
except FileNotFoundError:
registry = []
# Mark all as not-production if this one is production
if is_production:
for entry in registry:
entry['is_production'] = False
registry.append({
'filename': filename,
'version': version,
'metrics': metrics,
'is_production': is_production
})
with open(REGISTRY_PATH, 'w') as f:
json.dump(registry, f, indent=2)
print(f'Registered v{version} (production={is_production})')
register_model('cancer__logreg__v1.0.0.joblib', '1.0.0',
{'accuracy': 0.979, 'auc': 0.994}, is_production=True)Lettura del modello di produzione dal registro
Al momento dell'inferenza, il servizio carica il registro e individua il modello contrassegnato come modello di produzione, quindi carica quel file specifico. In questo modo lo script di deployment non dipende da nomi di file codificati nel codice: per aggiornare il modello di produzione è sufficiente modificare l'indicatore nel registro, senza cambiare il codice di serving.
import json
import joblib
def load_production_model(registry_path, model_dir='/tmp'):
with open(registry_path) as f:
registry = json.load(f)
prod = next((r for r in registry if r['is_production']), None)
if prod is None:
raise RuntimeError('No production model registered!')
path = f'{model_dir}/{prod["filename"]}'
print(f'Loading production model: {prod["filename"]} (v{prod["version"]})')
print(f'Metrics: {prod["metrics"]}')
# return joblib.load(path) # would load for real
return None # demo
load_production_model('/tmp/model_registry.json')MLflow: registro professionale dei modelli
MLflow è lo strumento standard del settore per il tracciamento degli esperimenti e il registro dei modelli. Registra parametri, metriche e artefatti per ogni esecuzione dell'addestramento; consente di confrontare le esecuzioni tramite un'interfaccia utente e offre un registro dei modelli con stati di staging, produzione e archiviazione. Per i team, MLflow sostituisce i registri JSON manuali con un backend robusto e interrogabile.
import mlflow
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
import numpy as np
X, y = load_iris(return_X_y=True)
with mlflow.start_run(run_name='logreg_iris_v1'):
model = LogisticRegression(C=1.0, max_iter=200)
cv_score = cross_val_score(model, X, y, cv=5).mean()
mlflow.log_param('C', 1.0)
mlflow.log_param('max_iter', 200)
mlflow.log_metric('cv_accuracy', cv_score)
model.fit(X, y)
mlflow.sklearn.log_model(model, 'model')
print(f'CV Accuracy: {cv_score:.4f}')
print('Run logged to MLflow')Applicazione di tag alle versioni dei modelli
I tag aggiungono annotazioni chiave-valore in formato libero a una versione del modello. Sono utili per registrare il contesto dell'esperimento, il nome dell'analista, il tipo di attività o l'esito positivo di un audit di equità. I tag sono interrogabili, quindi è facile filtrare il registro in base a qualsiasi attributo.
# Simulated registry entry with tags (no MLflow required)
model_entry = {
'version': '2.1.0',
'filename': 'fraud__xgb__2.1.0.joblib',
'tags': {
'analyst': 'data-science-team',
'task': 'binary-classification',
'fairness_audit': 'passed',
'retrain_trigger': 'monthly-schedule',
'deployment_region': 'eu-west-1'
},
'metrics': {'roc_auc': 0.971, 'precision': 0.83, 'recall': 0.79}
}
print('Model entry:')
print(json.dumps(model_entry, indent=2))Criteri di promozione automatizzati
Definisca criteri di promozione chiari prima di portare qualsiasi modello in produzione: il nuovo modello deve ottenere un miglioramento dell'AUC di almeno X%, superare un controllo di equità, non peggiorare in nessuna fetta demografica monitorata e completare l'inferenza entro Y millisecondi. Codificare questi criteri nel codice, anziché nella documentazione, consente a una pipeline CI/CD di automatizzare obiettivamente le decisioni di promozione.
def should_promote(new_metrics, baseline_metrics, min_auc_improvement=0.005):
if new_metrics['auc'] < baseline_metrics['auc'] + min_auc_improvement:
return False, 'AUC improvement too small'
if new_metrics.get('fairness_delta', 0) > 0.05:
return False, 'Fairness constraint violated'
if new_metrics.get('latency_ms', 0) > 100:
return False, 'Latency too high'
return True, 'All criteria met'
baseline = {'auc': 0.921}
candidate = {'auc': 0.937, 'fairness_delta': 0.02, 'latency_ms': 45}
promote, reason = should_promote(candidate, baseline)
print(f'Promote: {promote} — {reason}')Model card e documentazione
Oltre ai metadati tecnici, una model card (termine coniato da Google) documenta l'uso previsto del modello, i suoi limiti, le caratteristiche dei dati di addestramento, le prestazioni nei diversi sottogruppi demografici e le considerazioni etiche. Per i modelli che prendono decisioni rilevanti (approvazione di prestiti, triage medico), le model card stanno diventando un requisito normativo. Includa almeno: uso previsto, usi esclusi dall'ambito, metriche delle prestazioni e modalità di errore note.
Verifica rapida
Verifichi la comprensione del versionamento dei modelli e dei metadati trattati in questa lezione.
Riepilogo della lezione
In questa lezione ha imparato che: nomi di file descrittivi che incorporano dataset, algoritmo, data e metrica rendono autoesplicativa la directory del modello; i sidecar JSON dei metadati registrano versioni delle librerie, iperparametri e metriche necessari per la governance e la riproducibilità; infine, un registro dei modelli (JSON locale o MLflow) disaccoppia il codice di serving dai nomi di file codificati. Prossimamente racchiuderemo un modello salvato in un endpoint FastAPI per fornire previsioni tramite HTTP.
Impara Python con un tutor IA — gratis
Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.
- Corsi
- 30
- Lezioni
- 120
Domande Frequenti
La lezione «Versionare i modelli: perché nomi dei file e metadati sono importanti» è gratuita?
Sì — il testo completo di «Versionare i modelli: perché nomi dei file e metadati sono importanti» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Machine Learning Academy, passa a CoddyKit PRO. Il corso Machine Learning Academy include 4 lezioni in totale.
Cosa imparerò in «Versionare i modelli: perché nomi dei file e metadati sono importanti»?
Imparerete a progettare una convenzione di denominazione che includa data di addestramento, versione del dataset e punteggio della metrica, oltre a scrivere un sidecar di metadati JSON per la governa… Eserciti Machine Learning Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Machine Learning Academy?
Non è richiesta alcuna esperienza precedente. Machine Learning Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Versionare i modelli: perché nomi dei file e metadati sono importanti»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Machine Learning Academy?
Sì. Ogni lezione Machine Learning Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Salvare i modelli con joblib e pickle
- Versionare i modelli: perché nomi dei file e metadati sono importanti
- Servire previsioni con un endpoint FastAPI
- Monitorare le previsioni: registrare input e output