Reproducible ML Pipelines
Reproducible ML pipelines ensure that a model training run can be exactly re-executed by anyone at any time, producing identical outputs from identical inputs. This covers component-based DAG design, data versioning with DVC, environment pinning, and artifact tracking across the full ML lifecycle.
Overview
Why reproducibility matters in ML
Notebooks are where most ML work starts, and they are poor at reproducibility. Cell order is implicit and often non-linear, library versions go unrecorded and data paths are hardcoded. A notebook that scores 0.91 today can score 0.87 tomorrow because a package updated or a dataset changed.
A reproducible pipeline treats every step (data preparation, feature engineering, training, evaluation, registration) as a versioned, parameterized and cacheable unit of work.
- Implicit cell order — Explicit DAG
- Undocumented library versions — Pinned environment per component
- Hardcoded data paths — Versioned data referenced by hash
- Re-runs everything — Caches unchanged steps
The pipeline as a DAG
A pipeline is a directed acyclic graph: each node is a component and each edge is an artifact (data, model, metrics). No component reads from another without declaring it as an input.
Component interface
- Inputs: data paths, upstream artifacts, hyperparameters.
- Outputs: datasets, model files, metric JSON.
- Environment: a pinned Docker image or conda spec.
- Parameters: runtime configuration values.
> [!NOTE] Explicit interfaces let you test components on their own, reuse them across pipelines and swap one without touching the rest of the graph.
Azure ML Pipelines and Kubeflow
- Azure ML — CommandComponent in YAML or the Python SDK, with inputs, outputs and environment (image URI or curated environment) — Component outputs wired to the next component's inputs — PipelineJob; the scheduler tracks lineage and caches unchanged steps
- Kubeflow Pipelines (KFP) — Containerized function decorated with @component — Python function decorated with @pipeline — Compiled YAML sent to a Kubeflow cluster
Software dependency tracking
Pinning dependencies is the foundation of a reproducible environment.
- pip freeze > requirements.txt — Installed versions — Not the resolution graph
- pip-compile (pip-tools) — Fully resolved lock from a high-level requirements.in, including transitive deps — Python packages only
- conda env export --no-builds > environment.yml — Conda environment without platform build strings — Not the OS layer
- Docker, pinned base image plus locked requirements — The whole environment — Strongest guarantee, fully portable
DVC: data version control
Git tracks code but cannot handle large binaries like datasets or model weights. DVC reduces each large file to a small pointer that Git can track.
- dvc.yaml — Stages: command, dependencies, outputs, parameters, metrics
- dvc.lock — Exact content hashes of every dependency and output from the last run
- *.dvc — Pointer to one tracked data file
> [!TIP] Commit dvc.yaml and dvc.lock together. Checking out that commit and running dvc repro rebuilds the exact pipeline state, pulling the right data versions from the remote.
Git plus DVC: the full stack
- Source code, dvc.yaml, dvc.lock, params.yaml, .dvc pointers, requirements.txt — Large data files, model artifacts, their content hashes and remote locations
Pipeline caching
Caching skips a component whose inputs have not changed since the last run.
- DVC: content-addressed. If a stage's dependencies match a dvc.lock entry, outputs come back from the cache.
- Azure ML: a component is skipped when its inputs, parameters and environment hash match a prior run.
CI/CD integration
> [!IMPORTANT] Reproducibility needs three things versioned independently: code (Git), data (DVC) and environment (Docker or conda). Missing any one breaks the chain.
Interview questions
- Compare component-based pipelines to monolithic training scripts. What problems does a component-based design solve?
- Explain how DVC achieves data versioning and pipeline reproducibility. Walk through the full lifecycle from adding data to reproducing an old run.
- How does pipeline caching work in Azure ML and DVC? What are the failure modes and how do you control cache behavior?
- Design a CI/CD pipeline for ML that enforces reproducibility on every pull request and automates model registration on merge to main.
Sign up free to read the full topic
More MLOps & LLMOps topics
Start free on Cariara · Coding problems · System design studio