A run is only as useful as what you log into it. Capture hyperparameters, metrics over time, the model artifact, and the context needed to reproduce it.
Why: to reproduce a result you need not just params and metrics but the CONTEXT — the dataset version, the code commit, the environment — so log all of it as part of the run. When: log the data version and git SHA every time; they are what make a run reproducible months later. Where: params are single values, metrics are numbers you can plot, tags are searchable labels.
import mlflow, subprocess
with mlflow.start_run():
mlflow.log_params({"max_depth": 6, "lr": 0.1, "n_estimators": 200})
# Context that makes the run reproducible:
mlflow.set_tag("dataset_version", "v2024-07-06")
sha = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode().strip()
mlflow.set_tag("git_commit", sha)
mlflow.log_metric("accuracy", 0.91)Why: training produces a curve, not a single number — logging a metric with a step lets MLflow plot loss and accuracy per epoch, so you can see overfitting and convergence in the UI. When: log per-epoch (or per-batch) inside the training loop. Where: the step argument is the x-axis; MLflow charts the series automatically.
with mlflow.start_run():
for epoch in range(n_epochs):
train_loss, val_loss = train_one_epoch(model)
mlflow.log_metric("train_loss", train_loss, step=epoch)
mlflow.log_metric("val_loss", val_loss, step=epoch)
# The UI plots these as curves — spot overfitting when val_loss rises.Why: the whole point is to keep the trained model tied to the run that produced it — the flavor-specific log_model saves the model plus its dependencies so it can be reloaded and served anywhere. When: log the model at the end of the run, along with any plots, confusion matrices, or reports. Where: MLflow "flavors" (sklearn, pytorch, etc.) know how to save and reload each framework.
import mlflow.sklearn
with mlflow.start_run():
model = train_model(X_train, y_train) # any sklearn model
mlflow.sklearn.log_model(model, name="model") # model + environment
mlflow.log_artifact("confusion_matrix.png") # any file
mlflow.log_artifact("requirements.txt")
# Reload later, exactly as saved:
# model = mlflow.sklearn.load_model("runs:/<run_id>/model")