Experiment Tracking
Experiment tracking records parameters, metrics, and artifacts for every training run. MLflow and Weights & Biases are the standard tools for comparing runs and reproducing results.
Recipe
import mlflow
with mlflow.start_run(run_name="rf_baseline"):
mlflow.log_params({"n_estimators": 100, "max_depth": 10})
mlflow.log_metric("f1", 0.87)
mlflow.sklearn.log_model(model, "model")Working Example
"""experiment_tracking.py - MLflow tracking with sklearn."""
from __future__ import annotations
import mlflow
import mlflow.sklearn
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score, train_test_split
mlflow.set_experiment("breast-cancer-classification")
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
for n_est in [50, 100, 200]:
with mlflow.start_run(run_name=f"rf_{n_est}"):
clf = RandomForestClassifier(n_estimators=n_est, random_state=42)
cv_scores = cross_val_score(clf, X_train, y_train, cv=5, scoring="f1")
clf.fit(X_train, y_train)
test_f1 = cross_val_score(clf, X_test, y_test, cv="prefit", scoring="f1")[0]
mlflow.log_param("n_estimators", n_est)
mlflow.log_metric("cv_f1_mean", cv_scores.mean())
mlflow.log_metric("test_f1", test_f1)
mlflow.sklearn.log_model(clf, artifact_path="model",
registered_model_name="breast-cancer-rf")
print(f"n={n_est} cv_f1={cv_scores.mean():.3f} test_f1={test_f1:.3f}")Gotchas
- Not logging data version - cannot reproduce runs. Fix: log data hash or DVC revision.
- Logging in notebooks without run context - orphaned metrics. Fix:
with mlflow.start_run()in scripts. - Too many runs without naming - impossible to compare. Fix:
run_nameand tags.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| MLflow | General ML, self-hosted | Need built-in collaboration UI |
| W&B | Team dashboards, deep learning | Minimal local setup |
| TensorBoard | PyTorch training curves | Non-deep-learning experiments |
| CSV log | Quick personal experiments | Team collaboration |
FAQs
MLflow local vs server?
`mlflow ui` for local; tracking server for team sharing.How do I compare runs?
MLflow UI Experiments tab; sort by metric.What to log?
Params, metrics, model artifact, data hash, git commit, library versions.W&B setup?
`wandb.init(project="...")` then `wandb.log({"f1": 0.9})`.Log artifacts?
`mlflow.log_artifact("confusion_matrix.png")`.Nested runs?
Hyperparameter search with parent/child runs in MLflow.Auto-logging?
`mlflow.sklearn.autolog()` logs params/metrics automatically.How long to keep runs?
Define retention policy; archive old experiments.Track GPU usage?
Log as param; W&B tracks system metrics automatically.CI integration?
Log eval metrics from CI training runs for regression detection.Multiple experiments?
`mlflow.set_experiment("name")` separates project runs.Reproduce a run?
Load logged params, data version, and seed from run metadata.Related
- Model Registries & Versioning
- Hyperparameter Tuning
- MLOps Best Practices
- Data & Model Versioning (DVC)
- Monitoring and Drift
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.