Distributed debugging and determinism
Localize the first divergence across workers while distinguishing randomness, nondeterministic execution, synchronization errors, and expected rounding.
On this page
The question for today
What you’ll understand
- Define levels of reproducibility appropriate to a debugging question.
- Use structured traces to find a first inconsistent event.
- Explain the limits of seeds and deterministic operation settings.
A distributed job fails after six hours on one worker, while the other workers appear frozen inside a collective. The visible hang may be a consequence rather than the original defect: a rank could have exhausted memory or skipped a branch earlier. Effective debugging reconstructs the order of relevant events and asks where workers first disagreed. Deterministic replay can help, but it is a tool with a scope, not a promise that one seed makes every machine and software release identical.
State what kind of repeatability the investigation needs
Bitwise replay means reproducing exactly the same stored values under a defined environment. Numerical agreement within a tolerance is weaker but can be appropriate for parallel floating-point computation. Statistical reproducibility asks whether repeated experiments support the same performance or quality conclusion. Choose the level required by the bug: a mismatched collective order needs event traces, while a claimed validation improvement may need repeated training runs rather than identical weights.
Random seeds initialize particular pseudorandom generators; they do not control every source of nondeterminism. Data-loader worker initialization, sampler order, random augmentation, asynchronous execution, and nondeterministic kernels need separate treatment. Floating-point reductions can differ when worker topology or execution order changes. Record software and driver versions, device type, world size, rank mapping, and deterministic settings. A checkpoint containing weights alone does not capture the complete replay state.
Find the first divergence rather than the final symptom
Give each trace event a job identity, rank, logical step, microbatch, operation category, and local sequence number. Wall clocks may be skewed, so use causal relationships such as send-before-receive and collective participation, not a naive global timestamp sort. Log summaries or hashes of selected tensors at carefully chosen boundaries. Hash equality can locate identical bytes, but different hashes do not quantify numerical error or explain whether a difference is acceptable.
When a collective stalls, inspect earlier errors on every rank and compare intended collective sequences. A data-dependent branch that performs an extra synchronization on one worker can deadlock otherwise healthy code. Reproduce with fewer ranks and smaller inputs while retaining the failing structure. Add synchronization or debug instrumentation deliberately, because it changes timing and can hide races. Keep the original trace so the reduced case can be checked against the observed failure.
Build a replay capsule and test its boundary
A useful capsule includes exact input identities, code revision, dependencies, configuration, model and optimizer state, scheduler state, gradient-scaler state where used, and relevant random-generator states. Distributed samplers and input cursors also matter when resuming in the middle of an epoch. Save enough metadata to detect a changed world size or shard assignment rather than silently replaying a different example sequence.
Deterministic modes may choose slower algorithms or reject an operation without a deterministic implementation. They do not establish identical behavior across arbitrary releases or hardware. Run the capsule twice in its stated environment, compare the earliest checkpoints, then vary one dimension at a time. Once the issue is understood, retain a small regression reproducer. Restore production settings and measure again so the fix is validated under the execution mode that actually serves users or trains models.
Work it through
Budget traces and diagnose a mismatched update
Four ranks log 12 compact events per step for 1,000 steps, at 240 bytes per record. During an incorrect update, ranks 0–2 intend collective 41 at step 500, while rank 3 skipped an invalid batch and intends collective 41 at step 501. The latest good checkpoint is step 480. Estimate trace size and a 20-step replay window.
A complete trace contains 4 × 12 × 1,000 = 48,000 records, assuming all ranks reach the logging boundary for every planned step.
Uncompressed payload is 48,000 × 240 = 11,520,000 bytes, or 11.52 decimal MB; indexes and file framing add overhead.
A 20-step window after checkpoint 480 contains 4 × 12 × 20 = 960 planned records, or 230,400 bytes. This gives a manageable targeted replay, provided the checkpoint captures the required state.
Compare semantic identities: collective number 41 refers to different steps on rank 3. Investigate invalid-batch handling and coordinated participation, then reproduce with two ranks and one invalid batch before repeating at scale.
The trace exposes gradients from different logical steps being combined. Compatible collective calls may complete despite this semantic bug; a hang requires further evidence of unmatched participation or another failure.
The living notebook
Explore the model
Interactive lab · reliability
Distinguish live workers from coordinated workers
Set n replicas and k unavailable to inspect up=n−k and the majority floor(n/2)+1. This availability illustration does not model collective order, worker replay, consistency protocols, or a rule that training can proceed whenever a majority survives.
- Available replicas
- 4 of 5
- Majority needed
- 3
- Majority available?
- Yes
A replica count and a majority threshold, without a consensus protocol. Playback highlights fixed replica states. Having a majority alone does not establish linearizability, durability or failure independence. 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 forHaving live processes is different from having a valid coordinated execution.
Pause & reason
Check your understanding
Your turn
Try it yourself
A reference tensor has norm 10 and a candidate has norm 10.01, with difference norm 0.02. Using ε=10⁻⁶, calculate the relative diagnostic. Can that number alone establish a correct training implementation?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Use the larger tensor norm in the denominator, then consider what the metric omits.
Compare with the solution
The ratio is 0.02/10.01 ≈ 0.0019980, or about 0.1998%. Correctness still depends on the operation, conditioning, absolute errors, nonfinite values, and downstream behavior. One aggregate norm can also hide a large error concentrated in a small but important component.
Keep the idea
Take it with you
- Define bitwise, numerical, or statistical reproducibility before debugging.
- Trace logical identities and first divergence across every worker.
- Seeds and deterministic flags work within a documented environment and state boundary.
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.