Skip to main content

Reproducible Environments

An environment is part of a model's input. Python, scikit-learn, NumPy, SciPy, their transitive dependencies, the operating system, and hardware can affect whether training runs and whether floating-point results agree. “Works on my machine” becomes actionable only when the machine contract is recorded.

Prerequisites​

Complete From Notebook to Maintainable Project. Know the difference between installing a package and importing it at runtime.

Learning goals​

  • distinguish isolation, version pinning, locking, and artifact availability.
  • define a supported reproducibility envelope.
  • record runtime versions with each Study Sprint run.

Isolation is not a lock​

A virtual environment isolates installed packages from another Python installation. It does not say which packages should be present. Exact top-level pins constrain named versions, but a requirements file without hashes may still resolve different transitive wheels as indexes evolve. A lock or fully pinned, hash-checked set closes more of that space; an internal artifact mirror can also preserve the referenced distributions.

The repository pins scikit-learn 1.9.1, NumPy 2.5.4, and SciPy 1.18.1 in requirements-content.txt. PyPI and the stable scikit-learn documentation were re-checked on 2026-10-15; 1.9.1 remains the current stable scikit-learn release. The broader content requirements are a verification environment, not a minimal deployable package and not a hash-locked supply-chain guarantee.

Worked example​

Create an isolated environment and install the declared verification set when network access is intentionally available:

python3 -m venv .venv-content
.venv-content/bin/python -m pip install -r requirements-content.txt
.venv-content/bin/python -m pip check

Training itself uses only local inputs. Its run.json records the effective Python, NumPy, and scikit-learn versions, for example:

{
"runtime": {
"numpy": "2.5.4",
"python": "3.13.7",
"scikit_learn": "1.9.1"
}
}

Recording the effective environment catches drift between intention and execution. It does not make an old binary wheel available forever, certify the dependency supply chain, or guarantee identical arithmetic on different hardware.

Define the envelope before comparing runs​

Choose the strength appropriate to the decision:

  • For local teaching, exact direct versions, a clean environment, CPU execution, and regression tolerances may be sufficient.
  • For regulated or long-lived reconstruction, retain hashed distributions, transitive resolution, operating-system/container identity, hardware details, and build provenance.
  • For statistical robustness, rerun across relevant seeds or environments instead of interpreting one deterministic execution as uncertainty analysis.

If a future library cannot load an old artifact, reconstruct from the recorded recipe and data, then compare behavior. scikit-learn does not support loading persisted estimators across arbitrary version changes.

Common mistakes​

  • Calling venv alone reproducible.
  • Pinning only scikit-learn while leaving NumPy and SciPy unconstrained.
  • Copying a developer's entire environment into production without minimizing or reviewing it.
  • Treating a container tag such as latest as an immutable environment identity.
  • Demanding byte equality across CPUs when a metric tolerance and behavior test express the real requirement.

Practice​

Write two environment policies for the Study Sprint workflow: one for this local lesson and one for a five-year audit obligation. State which package files, hashes, platform identifiers, and hardware facts each policy retains, and why the policies differ.

Next steps​

Configuration Without Hidden State moves choices that vary between runs out of code and shell folklore.

Primary sources​

Checked 2026-10-15: Python venv documentation, pip repeatable installs, pip secure installs, scikit-learn installation guidance, and scikit-learn 1.9.1 on PyPI.