Runs, params, metrics and tags

MLflow · Essentials · 12 min

Consistent logging is what makes experiments comparable weeks later.

An experiment groups related runs, e.g. one per project or model family. mlflow.set_experiment("churn") selects it (creating it if needed). A run is one execution, opened with a context manager so it is closed even when the code raises:

with mlflow.start_run(run_name="rf-depth-8"):
    ...

What to log:

  • Parameters: inputs that define the run, logged once (log_param, log_params(dict)). Values are stored as strings; logging the same key again with a different value raises an error.
  • Metrics: numbers that can change over time, with an optional step (log_metric("loss", v, step=epoch), log_metrics(dict, step=...)). The UI plots them as curves.
  • Tags: free-form metadata such as git commit, dataset version or owner (set_tag, set_tags). MLflow adds system tags like the source file and user automatically.

The run object exposes run.info.run_id, used to reload results or models later. Outside a with block, call mlflow.end_run() yourself; the run's status becomes FINISHED, or FAILED if the block raised an exception.

Log parameters for everything that affects results, including data version and random seed. A run without them can be seen but not reproduced.

Example

import mlflow

mlflow.set_experiment("churn-model")

with mlflow.start_run(run_name="gbm-lr-0.1") as run:
    mlflow.log_params({"learning_rate": 0.1, "max_depth": 4, "seed": 42})
    mlflow.set_tags({"data_version": "2026-10-01", "owner": "ml-team"})
    for epoch in range(3):
        mlflow.log_metric("val_loss", 0.9 / (epoch + 1), step=epoch)
    mlflow.log_metric("val_auc", 0.87)

finished = mlflow.get_run(run.info.run_id)
print(finished.info.status)          # FINISHED
print(finished.data.params)          # {'learning_rate': '0.1', 'max_depth': '4', 'seed': '42'}
print(finished.data.metrics["val_loss"])   # 0.3  (latest value)

Remember

  • Use with mlflow.start_run() so runs always close with the right status
  • Params are logged once as strings; metrics can have steps
  • Tag runs with data version, commit and owner for later filtering

Watch out for

  • Logging a changing value such as epoch loss with log_param, which fails on the second call; use log_metric.

Check yourself

  1. You call mlflow.log_param('lr', 0.1) and later in the same run mlflow.log_param('lr', 0.01). What happens?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: mlflow.org/docs/latest/ml/tracking/tracking-api/