Training systems and reproducible experiments
Make an experiment restartable and interpretable by controlling data order, state, reductions, and evaluation behavior.
On this page
The question for today
What you’ll understand
- Define the full state needed to resume training.
- Weight variable-sized microbatches correctly.
- Distinguish repeatability from robust scientific conclusions.
An experiment is more than a weights file and a seed. It is a data snapshot, preprocessing, model definition, optimizer history, sampling order, numerical environment, and evaluation procedure. A training run becomes useful evidence when someone can reconstruct what happened and compare it fairly with another run. These habits matter before distributed infrastructure enters the picture.
A training step has explicit state and boundaries
A typical step obtains a batch, computes predictions and loss, accumulates derivatives, updates parameters, and advances the intended schedule. Define where each boundary occurs. Does the learning-rate schedule count examples, optimizer updates, or epochs? Does a skipped nonfinite update advance it? Does the last short batch have the same per-example weight? These choices can change the mathematical experiment even when every line executes without an exception.
Checkpoint enough state to continue that experiment: model parameters and buffers, optimizer moments, scheduler position, random-number generator states, and data-sampling position. Mixed-precision training may also require loss-scaler state. The exact state depends on the pipeline, but restarting with only weights is generally a new optimization history. Associate each checkpoint with the configuration, code revision, data version, and evaluation results rather than trusting a filename such as final-final.
Correct reductions preserve the intended objective
When memory requires microbatches, match the global objective rather than merely repeating backward. If one microbatch contains two valid target tokens and another contains six, their mean token losses should be weighted by two and six. Equal averaging of the two means gives the small microbatch too much weight. Exclude padding consistently from both numerator and denominator, and make a deliberate choice between per-token and per-sequence weighting when sequence lengths differ.
Gradient accumulation reproduces a large-batch gradient only under suitable assumptions: parameters must stay fixed until the combined update, the loss weights must match, and the computation must behave consistently across microbatches. Batch-dependent normalization can change forward values, and stochastic layers or floating-point reduction order can prevent exact equality. Measure numerical differences instead of promising bitwise identity. Separately profile input preparation, transfers, forward, backward, and updates before optimizing the wrong bottleneck.
Repeatability and robustness are different evidence
Set and record relevant random seeds, including data workers and other numerical libraries, and use deterministic algorithms where required and available. A seed does not guarantee identical results across hardware, library versions, or kernels. Save environment details and tolerate justified floating-point differences in regression checks. Repeatability helps isolate bugs; multiple seeds and independent evaluation assess whether an improvement survives ordinary variation. A single reproducible lucky run is still a lucky run.
Evaluation has its own state. In PyTorch, model.eval() changes behavior of modules such as dropout and batch normalization; it does not disable gradient tracking. A no-grad or inference context controls autograd separately, with its own usage constraints. Evaluate the frozen checkpoint under the documented preprocessing, target mask, and decoding policy. Log raw aggregate numerators and denominators, not only batch averages. Finally, compare quality at a stated compute or time budget so an apparent improvement is not just more training.
Work it through
Unequal microbatches, one correct mean
Two microbatches contain 2 and 6 valid tokens. Their mean losses are 3 and 1. You want the mean over all 8 tokens.
Recover each loss sum: the first contributes 2×3=6, and the second contributes 6×1=6.
Combine the sums and counts: total loss 12 divided by 8 valid tokens gives 1.5. Averaging the means directly gives 2, which overweights the smaller microbatch.
For accumulation with a fixed model, scale the first mean by 2/8 and the second by 6/8 before summing their gradient contributions, then perform one optimizer update.
The correct token-mean loss is 1.5. Reproducing a single large-batch update additionally requires matching stochastic and batch-dependent behavior.
The living notebook
Explore the model
Interactive lab · optimization
Reproduce a simple update trajectory
The lab follows exact gradient descent on x²/2 with step size and starting-value controls. Resetting the same settings reproduces this analytic trajectory; it does not reproduce data loading, optimizer moments, dropout, or hardware kernels.
- Position x0
- 2
- Objective x²/2
- 2
- Iteration behavior
- Stable step
Gradient descent on f(x) = x²/2: xₙ = (1 − η)ⁿx₀. Playback advances two discrete iterations per second. Values outside |x| ≤ 4 are explicitly reported. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forA reproducible trajectory requires the update rule and initial state, while a real training run has substantially more state to record.
Pause & reason
Check your understanding
Your turn
Try it yourself
A resumed Adam run uses identical saved model weights but fresh zero optimizer moments and a reshuffled dataset. Is this an exact continuation? What should be saved for a closer continuation?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
The next update depends on more than the current parameter values.
Compare with the solution
It is not an exact continuation: Adam's historical moments and the next batches affect future updates. Save and restore optimizer and scheduler state, random states, sampler or data cursor, and relevant mixed-precision state alongside model weights and buffers. Record code, data, and environment versions. Even then, cross-platform bitwise equality is not guaranteed; verify behavior within the intended numerical tolerance.
Keep the idea
Take it with you
- An experiment's state includes data order and optimizer history.
- Reduce losses by the intended target count, including masked and uneven batches.
- Reproducibility helps debugging; repeated evidence supports robust conclusions.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.