Control de versiones de modelos: por qué importan los nombres de archivo y los metadatos
Diseñará una convención de nombres que incluya la fecha de entrenamiento, la versión del conjunto de datos y la puntuación de la métrica, y escribirá un archivo JSON de metadatos complementario para la gobernanza.
Control de versiones de modelos: por qué importan los nombres de archivo y los metadatos es una lección gratuita de Machine Learning Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Machine Learning Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Machine Learning Academy incluye 4 lecciones en total.
Partes de esta lección aún no han sido traducidas y se muestran en inglés.
The Problem Without Versioning
Without a disciplined versioning strategy, teams quickly accumulate model.pkl, model_v2.pkl, model_final.pkl, model_FINAL_v2.pkl files with no record of which was trained on what data, which metric it achieved, or which is actually running in production. This chaos leads to deploying stale models, losing the best checkpoint, or being unable to reproduce a past result for debugging.
What to Encode in the Filename
A good model filename should encode enough context to be self-describing: dataset, algorithm, date, and optionally the primary metric and the dataset version or git SHA. This makes the model registry folder a readable audit trail at a glance, without needing to open each 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))The JSON Metadata Sidecar
Every model file should have a companion JSON sidecar file with the same stem name. The sidecar documents everything the filename cannot: library versions, hyperparameters, training set size, test set performance across all metrics, feature list, and any notes about the training run. This is the minimum viable model card.
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'
)Dataset Version Tracking
The training dataset itself must be versioned. A model trained on data_v1.csv and another on data_v2.csv should never have the same model identifier. Options for dataset versioning: store a Git SHA of the data file, record an MD5/SHA256 hash of the CSV, or use a data versioning tool like DVC (Data Version Control) which manages dataset lineage the same way Git manages code.
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)Semantic Versioning for Models
Borrow from software engineering: use semantic versioning (MAJOR.MINOR.PATCH) for models. MAJOR: breaking change (different feature set or incompatible schema). MINOR: performance improvement with same API. PATCH: bug fix or minor recalibration. This convention helps downstream consumers understand the impact of updating their dependency on the model.
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']}")A Simple Local Model Registry
A lightweight model registry can be a directory with a registry.json file that indexes all saved models. Each entry records the filename, version, key metrics, and the production flag. The deployment script reads this file to determine which model to load.
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)Reading the Production Model from Registry
At inference time, the service loads the registry and finds the model flagged as production, then loads that specific file. This decouples the deployment script from hardcoded filenames — updating the production model only requires updating the registry flag, not modifying serving code.
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: Professional Model Registry
MLflow is the industry-standard tool for experiment tracking and model registry. It logs parameters, metrics, and artefacts for each training run; lets you compare runs via a UI; and provides a Model Registry with staging/production/archived states. For teams, MLflow replaces manual JSON registries with a robust, queryable backend.
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')Tagging Model Versions
Tags add freeform key-value annotations to a model version — useful for recording experiment context, the analyst's name, the task type, or whether the model passed a fairness audit. Tags are queryable, making it easy to filter the registry by any attribute.
# 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))Automated Promotion Criteria
Define clear promotion criteria before any model goes to production: the new model must achieve at least X% AUC improvement, must pass a fairness check, must not degrade on any monitored demographic slice, and must complete inference within Y milliseconds. Encoding these criteria in code (not documentation) lets a CI/CD pipeline automate promotion decisions objectively.
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 Cards and Documentation
Beyond technical metadata, a model card (coined by Google) documents the model's intended use, limitations, training data characteristics, performance across demographic subgroups, and ethical considerations. For models making consequential decisions (loan approvals, medical triage), model cards are becoming a regulatory requirement. Include at minimum: intended use, out-of-scope uses, performance metrics, and known failure modes.
Quick Check
Test your understanding of model versioning and metadata from this lesson.
Lesson Recap
In this lesson you learned: descriptive filenames embedding dataset, algorithm, date, and metric make your model directory self-documenting, JSON metadata sidecars record library versions, hyperparameters, and metrics needed for governance and reproducibility, and a model registry (local JSON or MLflow) decouples serving code from hardcoded filenames. Next up we wrap a saved model in a FastAPI endpoint to serve predictions over HTTP.
Preguntas frecuentes
¿La lección «Control de versiones de modelos: por qué importan los nombres de archivo y los metadatos» es gratis?
Sí — el texto completo de «Control de versiones de modelos: por qué importan los nombres de archivo y los metadatos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Machine Learning Academy, actualiza a CoddyKit PRO. El curso de Machine Learning Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Control de versiones de modelos: por qué importan los nombres de archivo y los metadatos»?
Diseñará una convención de nombres que incluya la fecha de entrenamiento, la versión del conjunto de datos y la puntuación de la métrica, y escribirá un archivo JSON de metadatos complementario para… Practicas Machine Learning Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Machine Learning Academy?
No se requiere experiencia previa. Machine Learning Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Control de versiones de modelos: por qué importan los nombres de archivo y los metadatos»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Machine Learning Academy?
Sí. Cada lección de Machine Learning Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Guardado de modelos con joblib y pickle
- Control de versiones de modelos: por qué importan los nombres de archivo y los metadatos
- Servir predicciones con un endpoint de FastAPI
- Supervisión de predicciones: registro de entradas y salidas