PROMETHEUS OS
NATIVE AI OPERATING SYSTEM
[INIT] Prometheus OS loading...
[CORE] Neural interface initializing...
[AI] LLM router connecting...
[MEM] Memory graph loading...
[AGT] Agent chains on standby...
[SEC] Security protocols active...
[NET] Provider mesh established...
[UI] Workspace rendering...
[DONE] All systems nominal.
Welcome to PROMETHEUS OS.
READY · OFFLINE · SECURE · PRIVATE
🎨 THEME ENGINE
PROMETHEUS OS · 23 THEMES
Trial version: Dark + Light themes only.
Full theme access with PROMETHEUS OS license.
Dark theme active
Experience all 23 themes in PROMETHEUS OS

The ML Lifecycle, Reproducibility and Experiment Tracking

Advanced 14 min· 4 exercises

Run machine learning work as an engineering process: make experiments reproducible, track them with tools such as MLflow, version data, code and models together, and set up CI/CD gates that move models safely from notebook to production.

By the end of this lesson you will be able to
  • Describe the stages of the ML lifecycle and the feedback loops between them.
  • Identify the sources of non-reproducibility in ML and record everything needed to reproduce a run.
  • Implement experiment tracking and model registration with MLflow, and compare it neutrally with alternatives such as Weights & Biases.
  • Version data, code and models together using git and DVC, and explain lineage from a deployed model back to its inputs.
  • Design CI/CD/CT pipelines with evaluation gates, and place a team on Google's MLOps maturity levels 0-2.

Before this: The ML Workflow: Framing, Data, Splits and Leakage, Model Evaluation and Metrics

Most ML projects that fail do not fail because the model was wrong; they fail because nobody can say which data, code and settings produced the model in production, why last week's result cannot be reproduced, or how to ship an improvement without breaking something. MLOps is the set of practices that makes ML work repeatable, auditable and deployable. This lesson opens the MLOps & LLMOps course with the foundation everything else rests on: the lifecycle, reproducibility, experiment tracking, versioning and automation.

Intuition: a lab notebook and a flight recorder

A good scientist keeps a lab notebook: every experiment's materials, procedure, conditions and results, written so that someone else could repeat it. A good airline keeps a flight recorder: an automatic, tamper-evident log of what happened, so that when something goes wrong you can reconstruct why.

ML engineering needs both. Experiment tracking is the lab notebook, recording what you tried and what happened. Versioning and lineage are the flight recorder, letting you trace any prediction in production back to the exact model, the run that trained it, the commit, the data snapshot and the configuration. Neither is glamorous. Both separate hobby projects from professional systems.

The ML lifecycle

ML is a loop, not a line:

  1. Problem framing: define the decision the model supports, the success metric, constraints (latency, cost, fairness, regulation) and a non-ML baseline.
  2. Data: collect, label, validate and version the data (next lesson: Data engineering for AI).
  3. Experimentation: features, model families, hyperparameters; track every run.
  4. Evaluation: offline metrics on held-out data, slice analysis, robustness and fairness checks, comparison with the current production model.
  5. Deployment: package, register, release gradually (shadow, canary, A/B).
  6. Monitoring: data drift, prediction drift, performance against delayed labels, latency and cost.
  7. Retraining and iteration: triggered by schedule, drift or new data, which loops back to step 2 or 3.

Sculley et al.'s widely cited paper "Hidden Technical Debt in Machine Learning Systems" (NeurIPS 2015) observed that the model code is a small fraction of a real ML system; the surrounding configuration, data collection, verification, serving and monitoring infrastructure is far larger. It also named ML-specific debts such as entanglement ("changing anything changes everything") and undeclared consumers of model outputs. MLOps exists to manage that surrounding system.

Reproducibility

A run is reproducible if someone else, given your records, can obtain the same model, or a statistically equivalent one, and the same evaluation results.

Sources of non-reproducibility

SourceExampleMitigation
Randomnessweight init, data shuffling, dropoutSet and log seeds for Python, NumPy and the framework
Data drift between runsa table updated overnightSnapshot or version the data; log its hash
Code changesuncommitted notebook editsRun from a committed git SHA; refuse dirty trees in CI
Environmentdifferent library versionsLockfiles, container images with pinned digests
Hardware and kernelsnon-deterministic GPU reductions, different GPU typesDeterministic modes where affordable; log hardware
Hidden configurationdefaults changed between library versionsLog the full resolved configuration, not just overrides

Bit-exact reproducibility on GPUs is expensive and sometimes impossible across hardware; floating-point addition is not associative, and parallel reductions can sum in different orders. The practical standard is usually statistical reproducibility: re-running gives results within the known run-to-run variance. That requires knowing the variance.

Worked example 1: is the improvement real?

You compare a baseline and a new model, each trained with 5 seeds, on validation AUC:

  • Baseline: 0.842, 0.838, 0.845, 0.840, 0.843
  • New: 0.848, 0.851, 0.846, 0.850, 0.849

Means. Baseline: (0.842+0.838+0.845+0.840+0.843)/5=4.208/5=0.8416(0.842+0.838+0.845+0.840+0.843)/5 = 4.208/5 = 0.8416. New: 4.244/5=0.84884.244/5 = 0.8488. Difference Δ=0.0072\Delta = 0.0072.

Sample standard deviations s=∑i(xi−xˉ)2/(n−1)s = \sqrt{\sum_i (x_i - \bar{x})^2 / (n-1)}.

  • Baseline deviations: $0.0004, -0.0036, 0.0034, -0.0016, 0.0014;squaressumto; squares sum to 29.2\times10^{-6};; s_b^2 = 7.3\times10^{-6},, s_b \approx 0.0027$.
  • New deviations: −0.0008,0.0022,−0.0028,0.0012,0.0002-0.0008, 0.0022, -0.0028, 0.0012, 0.0002; squares sum to 14.8×10−614.8\times10^{-6}; sn2=3.7×10−6s_n^2 = 3.7\times10^{-6}, sn≈0.0019s_n \approx 0.0019.

Welch's t statistic:

t=Δsb2/nb+sn2/nn=0.00721.46×10−6+0.74×10−6=0.00720.00148≈4.9.t = \frac{\Delta}{\sqrt{s_b^2/n_b + s_n^2/n_n}} = \frac{0.0072}{\sqrt{1.46\times10^{-6} + 0.74\times10^{-6}}} = \frac{0.0072}{0.00148} \approx 4.9.

With about 7 degrees of freedom, t≈4.9t \approx 4.9 corresponds to a two-sided p-value well below 0.01. The improvement is larger than seed noise. Had you compared a single seed of each (say 0.845 vs 0.846), you could not have told. Tracking multiple seeds per configuration, and logging them as grouped runs, is what makes this analysis possible. (This tests seed variance only; it does not account for validation-set sampling error or for multiple comparisons across many experiments.)

Experiment tracking

An experiment tracker records, for every training run:

  • Parameters: hyperparameters and configuration.
  • Metrics: scalar values over steps or epochs (loss, accuracy, AUC), plus final evaluation results.
  • Artifacts: model files, plots, confusion matrices, sample predictions.
  • Metadata: git commit, data version, environment, hardware, start/end time, user, tags.

and lets you search, compare and visualize runs.

Tools

  • MLflow is an open-source platform with components for tracking, a model registry, model packaging (the "MLmodel" format with "flavors" for scikit-learn, PyTorch, Transformers and others), and evaluation, including features for LLM and GenAI tracing in recent versions. You can self-host it (a tracking server with a database backend and an artifact store such as S3), and several cloud platforms offer managed versions.
  • Weights & Biases (W&B) is a commercial platform, offered as SaaS and in self-hosted/dedicated deployments, with experiment tracking and rich dashboards, hyperparameter sweeps, artifact versioning with lineage, a model registry, and LLM tracing and evaluation tools. It has a free tier for individuals; team use is paid.
  • Others: TensorBoard (visualization, often used locally), and managed services within cloud ML platforms (for example Amazon SageMaker and Google Vertex AI) that include tracking and registries.

Choosing among them is mostly about hosting constraints (data residency, air-gapped environments), cost, collaboration features, and what integrates with your training and serving stack. The concepts transfer across tools.

MLflow in code

The example below trains a scikit-learn classifier, logs parameters, metrics, the model, and data/code identifiers, all in one tracked run.

import hashlib, subprocess
import mlflow, mlflow.sklearn
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split

X, y = load_breast_cancer(return_X_y=True)
X_tr, X_va, y_tr, y_va = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
data_hash = hashlib.sha256(X.tobytes() + y.tobytes()).hexdigest()[:12]
try:
    git_sha = subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip()
except Exception:
    git_sha = "unknown"

mlflow.set_experiment("breast-cancer-logreg")
for C in [0.01, 0.1, 1.0]:
    with mlflow.start_run(run_name=f"logreg-C{C}"):
        params = {"C": C, "max_iter": 5000, "seed": 42}
        mlflow.log_params(params)
        mlflow.set_tags({"data_hash": data_hash, "git_sha": git_sha})
        model = LogisticRegression(C=C, max_iter=5000).fit(X_tr, y_tr)
        auc = roc_auc_score(y_va, model.predict_proba(X_va)[:, 1])
        mlflow.log_metric("val_auc", auc)
        mlflow.sklearn.log_model(model, name="model")
        print(f"C={C}: val_auc={auc:.4f}")

By default MLflow writes to a local store; run mlflow ui to browse and compare runs. In a team, set MLFLOW_TRACKING_URI to a shared tracking server. (The name= keyword is the MLflow 3 form; on MLflow 2.x write artifact_path="model" instead.) Many frameworks also support autologging (mlflow.autolog()), which captures parameters and metrics automatically; still log data and code identifiers explicitly, because autologging cannot know them.

Model registry

A model registry is the catalog of models intended for use: each registered model has numbered versions, each linked to the run (and therefore the code, data and metrics) that produced it. Registries support:

  • Aliases or stages, such as champion and challenger, that deployment systems resolve to a specific version. (MLflow moved from fixed stages like "Staging"/"Production" to flexible aliases and tags.)
  • Approval workflows and audit history: who promoted which version, when, and why.
  • Model metadata: input/output signatures, evaluation reports, model cards, licenses.

In MLflow, info = mlflow.sklearn.log_model(model, name="model") returns a ModelInfo object, and mlflow.register_model(info.model_uri, "breast-cancer-clf") registers that model (older code passes runs:/<run_id>/model URIs, which MLflow 3 documents as deprecated); the registry requires a database-backed tracking store (for example mlflow server --backend-store-uri sqlite:///mlflow.db). Serving code should load models by alias (models:/breast-cancer-clf@champion) so promotion and rollback are registry operations, not code changes.

Versioning data, code and models together

  • Code: git. Every training run should reference a commit SHA, and production training should run only from committed code.
  • Data: files too large for git are versioned with tools such as DVC (Data Version Control). dvc add data/train.parquet computes a content hash, moves the file into a cache, and writes a small .dvc pointer file that you commit to git; dvc push uploads the content to remote storage (S3, GCS, Azure, SSH). Checking out an old commit and running dvc pull restores the matching data. DVC pipelines (dvc.yaml) also declare stages with their inputs and outputs so that only changed stages re-run. Alternatives include lakeFS (git-like branches over object storage) and table formats with time travel (Delta Lake, Apache Iceberg).
  • Models: registry versions plus immutable artifacts with content hashes.

The goal is lineage: for model version 17 you can answer "which run, which commit, which data snapshot, which config, which evaluation?" in seconds. This is increasingly a regulatory expectation, not just good hygiene (see AI governance frameworks).

Worked example 2: tracing a regression

A production fraud model's precision drops. Lineage lets you compare version 17 (current) with version 16: same code SHA, same hyperparameters, but data hash differs. The DVC diff shows the training snapshot gained a month of data in which a labeling rule changed upstream. Without lineage, this investigation means days of guessing; with it, a few queries.

CI/CD for ML

Software CI/CD tests and ships code. ML adds two moving parts, data and models, and a third practice, continuous training (CT).

  • Continuous integration (CI): on every change, run unit tests for feature code, data validation tests on sample data (schema, ranges, null rates), training smoke tests on a tiny dataset, and lint/type checks.
  • Continuous training (CT): an automated pipeline retrains the model on fresh data on a schedule or trigger.
  • Continuous delivery (CD): a candidate model passes gates before promotion:
    • beats the current champion on primary metrics by a margin larger than seed noise;
    • no regression beyond a tolerance on important slices (regions, device types, demographic groups where lawful and appropriate);
    • latency, memory and cost budgets;
    • fairness and safety checks;
    • then a shadow deployment or canary with live traffic before full rollout, with automated rollback.

Google's MLOps maturity levels

Google Cloud's architecture guide "MLOps: Continuous delivery and automation pipelines in machine learning" describes three levels:

LevelNameCharacteristics
0Manual processNotebooks and scripts; data scientists hand a model artifact to engineers; infrequent releases; no CI/CD; little monitoring
1ML pipeline automationThe training pipeline itself is automated and deployed; continuous training on new data; data and model validation steps; feature store and metadata tracking; pipeline code is the unit of deployment
2CI/CD pipeline automationAutomated build, test and deployment of the pipelines themselves; rapid, reliable iteration on new ideas; orchestrator, registry and metadata store as shared infrastructure

Most teams start at level 0. The jump to level 1 (automated retraining with validation) pays off when data changes frequently; level 2 pays off when many people iterate on many models. Other vendors publish similar maturity models with more levels; the idea is the same.

Common pitfalls

  • Logging metrics but not data versions, so results cannot be reproduced after the source table changes.
  • Training from uncommitted notebooks.
  • Comparing single runs and shipping noise; always know seed variance.
  • Selecting on the test set through many tracked experiments; keep a final holdout untouched.
  • Registry as a file dump: versions without metrics, signatures or owners.
  • Hard-coding model paths in serving code instead of resolving registry aliases.
  • Gates on aggregate metrics only, missing large regressions on important slices.
  • Over-engineering early: a level-2 platform for one model that changes yearly.

In practice

  • From day one: commit code, set seeds, log params, metrics, data hash and git SHA for every run, even in notebooks.
  • Group runs by experiment and tag them with the question being tested; write a one-line conclusion on the winning run.
  • Version datasets with DVC or your lakehouse's snapshots, and reference the version in every run.
  • Register only candidates you would deploy, with signature, evaluation report and owner.
  • Automate the path you repeat most first: usually retraining plus validation (level 1), then CI/CD for the pipeline itself.
  • The same discipline applies to LLM applications: prompts, retrieval indexes and evaluation sets are versioned artifacts too (see LLMOps in production).

Key takeaways

  • The ML lifecycle is a loop of framing, data, experimentation, evaluation, deployment, monitoring and retraining, and the model code is a small part of the system.
  • Reproducibility requires recording code commit, data version, full configuration, environment, hardware and seeds; statistical reproducibility needs known seed variance.
  • Experiment trackers such as MLflow and Weights & Biases log parameters, metrics, artifacts and metadata so runs can be compared and audited.
  • A model registry with versions, aliases and lineage turns promotion and rollback into controlled operations.
  • CI/CD/CT with metric, slice, cost and safety gates moves teams from Google's level 0 (manual) toward level 1 (pipeline automation) and level 2 (CI/CD of pipelines).

Terms in this lesson

Experiment tracking
Systematically recording each training run's parameters, metrics, artifacts and metadata for search and comparison.
Model registry
A versioned catalog of deployable models with lineage, aliases or stages, and approval history.
Lineage
The recorded chain linking a model version to the run, code, data, configuration and evaluation that produced it.
DVC
Data Version Control: an open-source tool that versions large data files via content hashes and small pointer files committed to git.
Continuous training (CT)
Automated retraining of models in a production pipeline on a schedule or trigger.
Statistical reproducibility
Obtaining results within known run-to-run variance when re-running an experiment, rather than bit-identical outputs.
Evaluation gate
An automated check a candidate model must pass before promotion, such as beating the champion on metrics and slices.

Check your understanding

  1. 1.

    Which record is most essential for reproducing a run after the source data table has been updated?

  2. 2.

    Two configurations differ by 0.003 AUC on single runs; across seeds, each configuration's standard deviation is 0.004. What should you conclude?

  3. 3.

    Which characterizes Google's MLOps level 1?

  4. 4.

    Why should serving code load models via a registry alias such as models:/fraud@champion?

  5. 5.

    What does dvc add data/train.parquet followed by a git commit put in git?

Exercises

Work each problem before opening the solution.

  1. Exercise 1Core

    List at least six items you would record for every training run so that a colleague could reproduce it six months later, and for each say how you would capture it automatically.

    Show solution
    1. Code version: git SHA via git rev-parse HEAD; CI refuses dirty working trees.
    2. Data version: DVC pointer or content hash of the snapshot; logged as a tag.
    3. Full resolved configuration: dump the merged config (e.g. Hydra/OmegaConf or argparse namespace) as an artifact, not only overrides.
    4. Environment: lockfile (requirements.lock, poetry.lock, uv.lock) and container image digest; log pip freeze as an artifact.
    5. Seeds: Python, NumPy and framework seeds, plus deterministic flags.
    6. Hardware: GPU type and count, driver/CUDA version (e.g. from nvidia-smi).
    7. Metrics and artifacts: per-step metrics, final evaluation, model file with hash, evaluation report.
    8. Who/when/why: user, timestamps, and a tag describing the hypothesis.

    A tracker such as MLflow or W&B stores these as params, tags and artifacts; a small wrapper function called at the start of every run makes it automatic.

  2. Exercise 2Core

    Baseline accuracy across 4 seeds: 0.910, 0.914, 0.912, 0.916. Candidate: 0.913, 0.915, 0.911, 0.917. Compute the means, the sample standard deviations and Welch's t. Would you ship the candidate on accuracy alone?

    Show solution

    Baseline mean =3.652/4=0.913= 3.652/4 = 0.913. Deviations: −0.003,0.001,−0.001,0.003-0.003, 0.001, -0.001, 0.003; squares sum =20×10−6= 20\times10^{-6}; sb2=20×10−6/3=6.67×10−6s_b^2 = 20\times10^{-6}/3 = 6.67\times10^{-6}; sb≈0.00258s_b \approx 0.00258.

    Candidate mean =3.656/4=0.914= 3.656/4 = 0.914. Deviations: −0.001,0.001,−0.003,0.003-0.001, 0.001, -0.003, 0.003; squares sum =20×10−6= 20\times10^{-6}; same sn≈0.00258s_n \approx 0.00258.

    t=0.001/6.67×10−6/4×2=0.001/3.33×10−6=0.001/0.001826≈0.55t = 0.001 / \sqrt{6.67\times10^{-6}/4 \times 2} = 0.001/\sqrt{3.33\times10^{-6}} = 0.001/0.001826 \approx 0.55.

    t≈0.55t \approx 0.55 is far from significant. Do not ship on accuracy alone; the candidate would need another advantage (cost, latency, a slice where it clearly wins) or more evidence.

  3. Exercise 3Core

    Extend the lesson's MLflow example so that it (a) runs 3 seeds per value of C using different train/validation splits, (b) logs the mean and standard deviation of val_auc to a parent run, with each seed as a nested child run.

    Show solution
    import numpy as np, mlflow, mlflow.sklearn
    from sklearn.datasets import load_breast_cancer
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import roc_auc_score
    from sklearn.model_selection import train_test_split
    
    X, y = load_breast_cancer(return_X_y=True)
    mlflow.set_experiment("breast-cancer-logreg-seeds")
    for C in [0.01, 0.1, 1.0]:
        with mlflow.start_run(run_name=f"C{C}"):
            mlflow.log_param("C", C)
            aucs = []
            for seed in [0, 1, 2]:
                with mlflow.start_run(run_name=f"C{C}-seed{seed}", nested=True):
                    X_tr, X_va, y_tr, y_va = train_test_split(
                        X, y, test_size=0.2, random_state=seed, stratify=y)
                    m = LogisticRegression(C=C, max_iter=5000).fit(X_tr, y_tr)
                    auc = roc_auc_score(y_va, m.predict_proba(X_va)[:, 1])
                    mlflow.log_params({"C": C, "seed": seed})
                    mlflow.log_metric("val_auc", auc)
                    aucs.append(auc)
            mlflow.log_metric("val_auc_mean", float(np.mean(aucs)))
            mlflow.log_metric("val_auc_std", float(np.std(aucs, ddof=1)))
            print(C, round(np.mean(aucs), 4), round(np.std(aucs, ddof=1), 4))
    

    nested=True makes each seed a child of the active parent run, so the UI groups them. Varying random_state in the split captures data-sampling variance as well as any training randomness; ddof=1 gives the sample standard deviation.

  4. Exercise 4Challenge

    Your team retrains a churn model monthly by hand from a notebook (level 0). Design a level-1 pipeline: list the pipeline steps, the data and model validation checks, the promotion gates (with concrete thresholds you would justify), and the artifacts and metadata stored at each step.

    Show solution

    Pipeline steps (orchestrated, e.g. Airflow, Dagster, Kubeflow or a managed equivalent):

    1. Extract the latest labeled snapshot (customers whose churn outcome window has closed); write a versioned snapshot (DVC/lakehouse snapshot id).
    2. Validate data: schema matches contract; null rates within +/-2 percentage points of the last 6 months; churn rate within historical range (e.g. 3-8%); no future-dated features (leakage check); row count within +/-20% of previous month. Fail the pipeline on violations and alert the owner.
    3. Feature build with the same code used in serving (shared library or feature store) to avoid training-serving skew.
    4. Train with logged config, seeds (3), code SHA, data version.
    5. Evaluate on a time-based holdout (most recent month): AUC, precision at the top 10% (the retention team's capacity), calibration (Brier score), slice metrics by region, tenure band and plan.
    6. Gate:
      • mean AUC >= champion AUC - 0.002 (no meaningful regression), and either an improvement larger than 2 seed standard deviations or fresher data justification;
      • precision@10% not lower than champion by more than 1 point;
      • no slice with more than 3 points AUC drop where the slice has at least 1,000 examples;
      • calibration error within tolerance;
      • inference latency p95 < 50 ms and model size within budget.
    7. Register the candidate with signature, evaluation report, data version and lineage; set alias challenger.
    8. Shadow the challenger on live traffic for a week; compare score distributions and agreement with champion.
    9. Promote by moving alias champion (with human approval in the first months), keep the previous version for one-click rollback.

    Stored metadata: data snapshot id and validation report (step 1-2); feature code version (3); run params, metrics, model artifact and environment (4); evaluation report with slices (5); gate decisions with reasons (6); registry version and alias history (7-9).

    Thresholds are justified by measured seed variance (gate margins exceed noise) and by business capacity (precision at the retention team's call volume).

Further reading

Go further

Sources

Fact-checked and last reviewed 2026-11-05

Stay in the loop
Prometheus OS™ · Native AI OS · Built for the future © 2025 - 2026