Equivalence tests: compare the update state, not only the loss
Build canonical small-step references for gradients, parameters, moments, clipping, masks, and precision-dependent drift across replicated and sharded execution.
On this page
The question for today
What you’ll understand
- Design a deterministic separable reference objective and canonical state mapping.
- Compare several optimizer boundaries, including nonzero restored state.
- Distinguish expected floating-point variation from incorrect scaling or ownership.
A distributed training change can preserve the printed loss while moving one optimizer moment to the wrong parameter or applying weight decay twice. Equivalence testing should therefore compare the mathematical update and its hidden state at defined boundaries. We use pinned PyTorch 2.9 DDP, FSDP, optimizer, and mixed-precision contracts, with small explicit reference calculations. Numerical agreement under a selected fixture is valuable evidence, but it does not prove that every graph, dtype, or failure path behaves equivalently.
Make the reference objective and state mapping unambiguous
Start with a tiny deterministic model and a known global example or token multiset. Use a separable objective so that splitting inputs does not change model semantics; rank-local batch normalization, randomness, and stateful layers need separate intended contracts. Compute a high-precision unsharded reference and preserve masks, reduction mode, eligible counts, parameter identities, and optimizer hyperparameter groups. Reconstruct sharded tensors in canonical logical order before comparison. Equal norms cannot detect a permutation that attaches correct numerical moments to the wrong coordinates.
Compare at several boundaries: local loss-sum accounting, normalized aggregate gradients, post-clipping gradients, updated parameters, and optimizer state after the step. Include zero gradients, unequal token counts, uneven parameter shapes, and a final partial accumulation window. A reference that repeats the implementation’s mistaken denominator will agree for the wrong reason, so derive expected values independently for at least a few scalar fixtures. Record which differences are algorithmic changes and which are supposed to preserve the same update.
Multiple steps expose missing state and boundary errors
The first optimizer step can hide a lost momentum or adaptive-moment checkpoint because the initial buffers are often zero. Test multiple steps and restore a fixture with known nonzero state. Check the step counter, schedule position, weight-decay mode, and parameter-group settings as well as tensor values. Advancing an optimizer or scheduler once per microbatch instead of once per accumulation window can change every later step even if the initial gradient matches. A state-sharding test must verify each owner’s identity and state, not just that the final model contains finite numbers.
Mixed precision needs explicit expected ordering: accumulate under a consistent scale, synchronize according to the wrapper’s contract, unscale at the proper boundary, and clip the intended global gradient. Overflow and skipped-step behavior must leave ranks compatible. Floating-point reductions are not associative, so a different legal collective or bucket order may introduce small drift without an objective error. Choose tolerances based on dtype and the operation, then investigate structured discrepancies such as an exact world-size factor, a swapped parameter block, or a step counter that differs by the accumulation count.
Use metamorphic cases with independent expected outcomes
Change the number of workers while preserving the intended global batch and objective, or repartition the same canonical gradient among owners, then compare the next state. Such transformations should preserve the stated mathematics only when their assumptions remain true. A local-batch-dependent model or changed sample duplication invalidates that expectation. Also test a save-and-resume boundary against uninterrupted execution, including optimizer and input progress state. Keep the result scoped to the evaluated implementation and configurations, and retain a failing fixture rather than weakening tolerance until every difference disappears.
For a simple update-boundary check, Reset the optimization lab, explicitly set step size 0.1 and initial position two, predict two iterates, then Step twice. Compare a fresh Reset with both step size 0.2 and initial position two set before one Step. Results are 1.8 then 1.62 versus 1.6. The fixed quadratic is a small independent arithmetic oracle, not a momentum, Adam, DDP, or sharding implementation. It demonstrates why distinct update schedules should not be labeled equivalent merely because their total nominal step sizes match.
Work it through
A missing momentum buffer appears on the second update
Use the stated momentum fixture with initial parameter one, v₀=0, β=0.9, and learning rate 0.1. The first supplied gradient is two and the second is one. Compare correct state retention with resetting the momentum buffer before the second update.
For the first update, momentum becomes 0.9×0+2=2 and the parameter becomes 1−0.1×2=0.8. A mistaken implementation that starts from zero can still match this first result.
Retaining state, the next momentum is 0.9×2+1=2.8 and the next parameter is 0.8−0.1×2.8=0.52. Both the parameter and the momentum are expected reference outputs.
Resetting momentum before the second update gives v=1 and parameter 0.7 instead. The parameter difference is 0.18, with a state difference of 1.8; inspecting only the first update or the supplied gradient would miss the bug.
The correct two-update parameter is 0.52 with momentum 2.8. A nonzero-state fixture distinguishes restoration from coincidental first-step agreement.
The living notebook
Explore the model
Interactive lab · optimization
One independent scalar schedule can expose a boundary mismatch
Use separate Reset → set BOTH controls → predict → Step runs. With η=.1,x₀=2, two Steps give 1.8 and 1.62; with η=.2,x₀=2, one Step gives 1.6. The lab models only fixed quadratic gradient descent, with no momentum state or distributed execution.
- 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 forChoose an oracle whose expected state can be derived independently, and compare at the intended optimizer boundaries.
Pause & reason
Check your understanding
Your turn
Try it yourself
For the same momentum fixture, use β=0.5, learning rate 0.2, initial parameter two, and initial momentum zero. Supply gradients four and two on consecutive updates. Calculate the two momentum values and final parameter. What if momentum is reset before the second update?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Apply the recurrence at each optimizer boundary and retain the first state as an input to the second.
Compare with the solution
The first momentum is four and the parameter becomes 2−0.2×4=1.2. The second momentum is 0.5×4+2=4, so the correct final parameter is 0.4. Resetting before the second update instead gives momentum two and parameter 0.8. Compare both state and parameters against these values, using an appropriate floating-point tolerance. This deliberately simple fixture isolates state retention; it does not validate a different optimizer’s adaptive moments, loss-scaling, or distributed clipping without additional cases.
Keep the idea
Take it with you
- Derive the global objective and canonical parameter identity independently.
- Compare gradients, parameters, and hidden optimizer state across multiple boundaries.
- Scope tolerance-based evidence and investigate structured discrepancies.
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.