You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
sprint-8: ADR-012 -- sweeps run with cudnn_benchmark false
C8.1b established that disabling cudnn.benchmark alone gives bit-identical
runs; permitting nondeterministic algorithms changed nothing for this workload.
The operational consequence had not been stated: if the noise can be removed
there is no reason to keep estimating it. Ablation sweeps now set
repro.cudnn_benchmark: false, so run-to-run noise at fixed seed is zero and any
difference between two configs is the effect plus seed variance only.
That is the fix for the problem Step 0 opened and Sprint 6 could not close --
whether Mixup or RandAugment beats plain Cutout was 4.5 sigma under one noise
estimate and 1.8 under the other, and the sprint could not say which.
Cost measured, not assumed, in two interleaved blocks per ADR-011:
cudnn_benchmark: true (default) 13.99 s/epoch --
cudnn_benchmark: false 14.07 s/epoch +0.6%
deterministic: true 15.93 s/epoch +13.8%
+0.6% is indistinguishable from free and is written that way: the block-to-
block spread within the default mode alone was 13.01 to 14.98, wider than the
gap being measured.
The earlier ~25% determinism figure is withdrawn from README, PRD, the sprint 8
spec and EXPERIMENTS.md. It compared runs from different sessions on a drifting
thermal state -- exactly the confound this measurement was built to avoid, and
exactly what ADR-011 exists to name. It survives only in the paragraph that
withdraws it.
ADR-011 is retained; its motivation narrows to keeping timing columns and
thermal exposure fair, since it no longer has to rescue accuracy comparisons.
Sprint 6's sigma ambiguity stands as recorded and is not retro-fitted.
Copy file name to clipboardExpand all lines: PRD.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -242,7 +242,7 @@ Bands are estimates from the literature, not promises. If a stage underperforms
242
242
| Risk | Impact | Mitigation |
243
243
|---|---|---|
244
244
| Accuracy plateaus below 94% | Primary metric misses | Sprint 5 has a debug checklist: verify normalization stats, LR range test, confirm no val leakage, check wd is not applied to BN/bias |
245
-
| Bit-exact reproducibility unattainable on GPU | M2 misses | Measured in C8.1: `deterministic=true`**is** bit-exact here, including across a power-state change mid-run, at ~25% throughput cost. The default fast mode is not, and M2 states its measured spread instead of bounding it |
245
+
| Bit-exact reproducibility unattainable on GPU | M2 misses | Measured in C8.1: `deterministic=true`**is** bit-exact here, including across a power-state change mid-run, at ~14% throughput cost. The default fast mode is not, and M2 states its measured spread instead of bounding it |
246
246
| Test set used for model selection | Inflated, dishonest number | Sprint 1 carves a 5,000-image val split from train. Test set is touched **only** by `eval.py`, only at the end of a stage. Enforced by a test that asserts `Trainer` never receives the test loader |
247
247
| Scope creep into a framework | Never ships | Non-goals in §3 are binding; new ideas go to `docs/BACKLOG.md`|
248
248
| Long runs lost to a crash | Time waste | Checkpoint every epoch with resume from Sprint 3, not later |
Copy file name to clipboardExpand all lines: docs/sprints/08-hardening-release.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@
19
19
20
20
Also measure and document the throughput cost of `deterministic=true`. Put the number in the README so the tradeoff is explicit rather than folklore.
21
21
22
-
**Run 2026-08-02 — passed.** Three 10-epoch runs of `configs/repro_check.yaml` were bit-identical, weights hashing to `866f747125539331`, one of them on battery under CPU contention and straddling a replug mid-run at 2.1× the wall clock. Cost of determinism: ~25% (15.1–16.7 s/epoch against fast mode's 12.6). C8.1b then separated the two things `deterministic=true` switches off, and found disabling `cudnn.benchmark` alone sufficient. See `EXPERIMENTS.md`.
22
+
**Run 2026-08-02 — passed.** Three 10-epoch runs of `configs/repro_check.yaml` were bit-identical, weights hashing to `866f747125539331`, one of them on battery under CPU contention and straddling a replug mid-run at 2.1× the wall clock. Cost of determinism: **13.8%**, re-measured in interleaved blocks (ADR-012); an initial ~25% from cross-session runs is withdrawn. Turning off `cudnn.benchmark` alone costs **0.6%**, which is why ADR-012 makes it the sweep default. C8.1b then separated the two things `deterministic=true` switches off, and found disabling `cudnn.benchmark` alone sufficient. See `EXPERIMENTS.md`.
23
23
24
24
If the two runs diverge beyond tolerance, work backward: is a `DataLoader` worker unseeded? Is an augmentation using a global RNG instead of the seeded generator? Is a non-deterministic CUDA kernel in play that `use_deterministic_algorithms` didn't catch?
0 commit comments