Lesson 10 / 25

Model Registry, Versions and Aliases

One place that says which model is live.

Versions and pointers

A model registry stores named models with numbered versions, each linked to the run that produced it. Production code should not load a file path; it loads a reference such as an alias (champion, challenger) or a stage that the registry resolves to a version. Promoting or rolling back then means moving the alias, not redeploying code. Record who promoted which version and why, and require evaluation evidence before promotion.

Version, test, gate

A registry tracks model versions and their status; CI tests code, data and models before promotion.

Three ideas: registry, ML tests, evaluation gate.
Figure 4.1 — Registry, tests and gate.

Registering versions and loading by alias, run

I ran this with Python 3, MLflow 3.16.1, scikit-learn 1.9.1, scipy 1.18.1 and numpy 2.5.3, using bundled or seeded synthetic data and a local SQLite tracking store. Two logistic regression runs register versions 1 and 2 of cancer-clf in a local MLflow registry. The champion alias is pointed at version 2 and the model is loaded through models:/cancer-clf@champion to make a prediction.

import os, tempfile, logging, warnings
os.environ["MLFLOW_DISABLE_AGENT_HINT"] = "1"; logging.getLogger("mlflow").setLevel(logging.ERROR); warnings.filterwarnings("ignore")
import mlflow
from mlflow import MlflowClient
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
d = tempfile.mkdtemp()
mlflow.set_tracking_uri("sqlite:///" + os.path.join(d, "mlflow.db"))
mlflow.set_experiment("cancer-classifier")
X, y = load_breast_cancer(return_X_y=True)
for c in [0.01, 1.0]:
    with mlflow.start_run():
        model = make_pipeline(StandardScaler(), LogisticRegression(C=c)).fit(X, y)
        mlflow.sklearn.log_model(model, name="model", registered_model_name="cancer-clf", input_example=X[:2])
client = MlflowClient()
versions = sorted(int(v.version) for v in client.search_model_versions("name='cancer-clf'"))
print("registered versions:", versions)
client.set_registered_model_alias("cancer-clf", "champion", "2")
champion = mlflow.sklearn.load_model("models:/cancer-clf@champion")
print("champion alias ->", client.get_model_version_by_alias("cancer-clf", "champion").version)
print("prediction for first row:", champion.predict(X[:1]).tolist())

Output:

registered versions: [1, 2]
champion alias -> 2
prediction for first row: [0]

Roll back by moving the alias

Keep the previous champion version available; rollback should be a one-line alias change.

Quick check: Why load production models by alias rather than a file path?

  • Promotion and rollback become pointer changes without code changes
  • Aliases make models more accurate
  • File paths are illegal
  • Aliases compress the model
Answer

Promotion and rollback become pointer changes without code changes — The registry decides which version is live.