InterviewsVector
Arc 1
Build labFoundation80 min estimateOriginal publication

Reproducible Experiments, Not Reproducible Notebooks

A notebook can preserve visible cells while losing the state that made a result possible. Reproducibility begins with an immutable execution contract and ends with an independently checked claim.

Authorship
InterviewsVector
Published / updated
2026-08-11 / 2026-08-11
Review status
Artifact tests passing · primary sources recorded

Original InterviewsVector material. Code examples are covered by repository tests and primary references are recorded. No named human reviewer is claimed.

The decision in one pass

A reproducible experiment binds a result to inspectable code, an immutable data snapshot, canonical configuration, every known random source, exact dependencies, runtime and hardware assumptions, an entry command, and evaluation output. A seed controls a named random-number stream; it does not freeze libraries, kernels, thread schedules, data order, or hardware. Treat the notebook as an interface for exploration, then promote the claim into a clean process driven by a content-addressed manifest and tests.

Why this matters

Without an execution identity, two runs that share a chart title may have different code, data, preprocessing, dependencies, or evaluation slices. The team cannot tell whether a gain came from the proposed change, hidden notebook state, or an unrelated environment difference—and cannot reliably investigate a later regression.

You will be able to

  • Distinguish a saved document from a reconstructable experiment execution.
  • Model a result as a function of code, data, configuration, randomness, software, runtime, and hardware.
  • Build a canonical manifest whose identifier changes when a material input changes.
  • Explain what seeding controls and what it cannot guarantee across releases and platforms.
  • Promote an exploratory notebook into a clean, testable command with retained evidence.

Prerequisite contract

Your Vector Loop for this lab

  1. 01

    Model

    Treat every reported result as an execution with material inputs and evidence.

  2. 02

    Derive

    Enumerate the state required to reconstruct and compare executions.

  3. 03

    Build

    Create a canonical, content-addressed experiment manifest and validator.

  4. 04

    Stress

    Change data, dependencies, hidden state, randomness, and hardware assumptions.

  5. 05

    Operate

    Run experiments in clean environments and retain manifests, logs, and artifacts.

  6. 06

    Defend

    State the exact reproducibility scope instead of promising identical results everywhere.

The unit of evidence is an execution, not a notebook

A notebook records cells and outputs, but its kernel may also contain variables created by deleted or out-of-order cells, imported local modules that later changed, cached data, environment variables, working-directory assumptions, and package versions that never appear on the page. Restart-and-run-all is a valuable test, yet it still says nothing about whether another machine can reconstruct the same inputs.

A run identifier is useful only when it commits to the inputs that could change the claim.
LayerIdentity to retainFailure if omitted
codecommit plus content digestlocal edits or generated code disappear
dataimmutable snapshot or content digestthe same path serves different examples
configurationcanonical resolved valuesdefaults and override order change
randomnessseed and generator/worker policysampling and initialization diverge
softwareexact dependency and runtime versionsalgorithm or default behavior changes
hardwaredevice, precision, and relevant kernelsnumeric and scheduling behavior differ
evaluationcode, slice, metric, and raw resultonly a selected summary survives

Derive the experiment identity from causal inputs

result = F(code, data, config, random state, software, runtime, hardware)

The function notation is a review tool: if an input can materially change the result, either bind it into the manifest or explicitly declare it outside the reproducibility scope.

run_id = prefix(SHA-256(canonical_json(manifest)))

Canonical key ordering and JSON encoding prevent irrelevant dictionary order from changing identity. The short prefix is convenient for display; retain the full manifest and content digests as evidence.

Do not put wall-clock start time into the content identity: time would force equivalent inputs to receive different IDs. Record attempt ID, start time, operator, and infrastructure allocation in a separate execution record that points to the immutable manifest ID. One manifest may therefore have several attempts whose outputs can be compared.

Build a content-addressed manifest

The reference implementation hashes code and data bytes; recursively freezes canonical configuration, runtime, and hardware mappings; rejects wildcard, conditional, and range dependency specifiers; and binds the entry command, evaluation data/code/metrics/slices, named RNG seeds, worker policy, and deterministic-algorithm policy into identity. It rejects non-finite JSON and refuses to verify an execution when current bytes differ from the recorded digests.

experiment_manifest.py
1if __name__ == "__main__":
2 example = example_manifest()
3 print(f"run_id={example.run_id}")
4 print(f"code_sha256={example.code_sha256[:12]}")
5 print(f"data_sha256={example.data_sha256[:12]}")
6 print(f"inputs_verified={verify_inputs(example, code=EXAMPLE_CODE, data=EXAMPLE_DATA)}")

Expected output

run_id=20b6ce0ee288
code_sha256=c2121bf12852
data_sha256=f2823c5bc5d7
inputs_verified=True

Verify: Run python3 -m unittest discover courses/ai-engineering/reference-impl/experiment_manifest.

  1. 01Resolve inputsConvert references such as latest, a mutable table, or a branch name into immutable revisions or snapshots before execution.
  2. 02Canonicalize the manifestSerialize one validated schema with stable key ordering, finite values, explicit units, and no hidden defaults.
  3. 03Execute from clean stateCreate a fresh process and environment, verify input digests, then invoke one entry command rather than depending on prior cells.
  4. 04Retain evidenceStore the resolved manifest, stdout/stderr, metrics by slice, artifacts, exit status, and attempt metadata together.
  5. 05Reconstruct independentlyHave another clean worker—or another engineer—resolve the manifest without access to the original interactive session.

A seed names one stream; it does not freeze the world

Random libraries keep separate generators. Data-loader workers can receive their own seeds. GPU operations may select nondeterministic algorithms, parallel reductions can accumulate floating-point values in a different order, and library releases can change implementations. PyTorch explicitly states that completely reproducible results are not guaranteed across releases, commits, platforms, or CPU/GPU execution even with identical seeds.

ControlWhat it helps controlWhat remains
single RNG seedone generator's sequenceother generators and algorithms
deterministic algorithmsknown supported kernel choicesrelease/platform equivalence and numerical drift
exact dependenciessoftware resolutionOS, drivers, hardware, external services
container imageuserspace environmenthost kernel, device behavior, mutable remote data
content digestsbyte identitysemantic validity and authorized use

Run failure experiments against the record

  1. 01Reorder notebook cellsRestart the kernel and execute the promoted command without notebook state. Any missing symbol or changed output exposes an undeclared dependency.
  2. 02Mutate one data byteThe manifest must fail verification before training. A stable URI with changed contents is not the same input.
  3. 03Relax one package pinResolve the environment twice and compare dependency graphs. A range expresses compatibility intent, not a historical execution identity.
  4. 04Change device or precisionCompare whether the claim requires exact values, tolerance-based equivalence, or distributional bounds; do not silently accept the difference.
  5. 05Rerun only the winning seedExpose seed selection in the report. Searching many seeds and reporting one is experimental selection, not a reproducibility control.

Promote exploration into an evidence pipeline

  • Keep notebooks thin: import tested functions, render retained results, and avoid owning the only copy of training or evaluation logic.
  • Resolve and verify manifests before allocating expensive compute so invalid inputs fail early.
  • Build environments from lock files and retained artifacts; exact pins alone can still resolve unavailable or different distribution files.
  • Separate manifest identity from execution-attempt metadata and never overwrite earlier result artifacts.
  • Record evaluation dataset, slices, metric implementation, thresholds, uncertainty, and failures—not only the best aggregate number.
  • Define retention, access, and deletion rules for data and artifacts; reproducibility does not authorize indefinite storage.
  • Test reconstruction on a schedule before an incident or audit makes the missing dependency urgent.

Operate at three altitudes

Production lens

  • Verify code and data digests before execution; fail rather than silently rebuilding a different input.
  • Record dependency distributions, runtime, drivers, device, precision, and deterministic settings at the scope required by the claim.
  • Retain resolved configuration and evaluation slices beside metrics so a dashboard is not the sole evidence store.
  • Periodically reconstruct representative runs in a clean environment and measure failures as an engineering reliability signal.

Staff lens

  • Define different reproducibility contracts for unit tests, offline evaluation, stochastic training, and production inference.
  • Fund immutable data/version infrastructure and artifact retention as shared capabilities, not individual notebook hygiene.
  • Require experimental comparisons to declare all material differences and the selection process for seeds, checkpoints, and metrics.
  • Balance deterministic debugging modes against performance, then document the production equivalence criterion.

Interview defense

How would you make an ML experiment reproducible across a team?

I would define a versioned experiment manifest that binds code and immutable data digests, resolved config, random generators and worker seeding, exact dependencies, runtime, device, precision, entry command, and evaluation contract. Runs execute from clean environments after verifying inputs, while attempt metadata and artifacts are immutable and point back to the manifest. I would state the required scope—bitwise, tolerance-based, or distributional—because a seed does not guarantee equality across releases or hardware, and I would periodically test reconstruction on another worker.

Expect the interviewer to press on

  • Why is a seed insufficient?
  • What belongs in the run ID versus attempt metadata?
  • How would you reproduce a mutable warehouse query?
  • When is bit-for-bit determinism the wrong target?

Misconceptions to remove

Saving the notebook and its outputs reproduces the experiment.

The document can omit kernel state, local modules, mutable data, packages, hardware, caches, and the actual execution order.

Using the same seed guarantees the same result.

A seed controls a particular generator sequence; other generators, algorithms, scheduling, releases, and devices can still differ.

A container makes the run reproducible.

It helps bind userspace software but does not by itself freeze input data, configuration, host/device behavior, external services, or evaluation semantics.

A matching hash proves the experiment is valid.

It proves byte identity under the selected digest; it does not prove correctness, provenance, authorization, or sound experimental design.

Check your model

1. Why should start time usually not be part of a content-addressed manifest ID?

It changes for every attempt even when material inputs are identical. Store it in an attempt record that references the stable manifest ID.

2. What should happen if the current data bytes do not match the manifest digest?

Fail before execution and resolve the intended immutable snapshot; continuing would produce a different experiment under a misleading identity.

3. When can tolerance-based reproducibility be more appropriate than bitwise equality?

For numerically sensitive or stochastic workloads where the claim concerns stable behavior or metrics under a pinned scope, not identical floating-point accumulation.

Prove the mechanism

Promote one notebook experiment into a clean command. Produce a manifest, rebuild from an empty environment, verify code and data digests, and write a comparison report that lists every material difference from the original attempt.

Add a production constraint

Add signed manifest attestations and an attempt ledger, then run the same manifest on two declared platforms and define a justified equivalence test for their outputs.

Artifact: Experiment manifest

courses/ai-engineering/reference-impl/experiment_manifest/experiment_manifest.py

Download reference implementation

Primary references and next links

References

  1. 1. Reproducibility

    PyTorch. Official documentation for controlling randomness and the limits of reproducibility across releases, platforms, and CPU/GPU execution.

  2. 2. Repeatable Installs

    Python Packaging Authority. Official pip guidance for exact pins, controlled distributions, and hash-checked installation inputs.

  3. 3. hashlib — Secure hashes and message digests

    Python documentation. Official API documentation for the SHA-256 content digests used by the reference manifest.

Continue through the graph

Glossary: experiment manifest · content address · random seed · deterministic algorithm · dependency lock · artifact