In MLflow 3 the model, not the run, is the central object, which matters for GenAI apps and checkpoint selection.
Before MLflow 3, a model was just an artifact inside a run. MLflow 3 introduces the LoggedModel as a first-class entity with its own ID (m-...), parameters, metrics, tags and status, which can be linked to several runs.
What this enables:
- Checkpoints as models: during deep learning training you can log a model per epoch (
log_model(..., step=epoch)) and log metrics withmodel_id=...; thenmlflow.search_logged_models(filter_string="metrics.val_acc > 0.9", order_by=[...])picks the best checkpoint directly. - Evaluation across runs: evaluating an existing model in a new run links the resulting metrics back to that model's ID, so each model page shows all its evaluations.
- GenAI versions without weights:
mlflow.set_active_model(name="support-agent-v3")creates or selects a LoggedModel that represents an application version (code, prompts, config). Traces produced while it is active are linked to it, so you can compare quality and latency between app versions.
mlflow.last_logged_model() returns the most recent one, and mlflow.get_logged_model(model_id) loads metadata. Registry versions point at LoggedModels, so lineage runs from deployed alias to model to training run and dataset.
Code written for MLflow 2 (artifact_path=, runs:/ URIs) mostly still works, but artifact_path is deprecated in favour of name, and new features assume model IDs.
Example
import mlflow
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
X, y = load_iris(return_X_y=True, as_frame=True)
mlflow.set_experiment("checkpoints")
with mlflow.start_run():
for i, C in enumerate([0.01, 0.1, 1.0]):
m = LogisticRegression(C=C, max_iter=1000).fit(X, y)
info = mlflow.sklearn.log_model(m, name=f"lr-{i}", params={"C": C},
input_example=X.head(2))
mlflow.log_metric("train_acc", m.score(X, y), model_id=info.model_id)
best = mlflow.search_logged_models(
order_by=[{"field_name": "metrics.train_acc", "ascending": False}],
output_format="list", max_results=1)[0]
print(best.name, best.params) # lr-2 {'C': '1.0'}
mlflow.set_active_model(name="support-agent-v3") # GenAI app version; traces link to itRemember
- LoggedModel is a first-class entity with an ID, metrics and params
- Log metrics with
model_idand pick checkpoints withsearch_logged_models set_active_modelversions GenAI apps and links their traces
Watch out for
- Continuing to use artifact_path= and parsing run artifact paths, instead of using model IDs that MLflow 3 features rely on.