Why exact reproducibility is hard
Modern GPU code uses non-deterministic kernels for speed: parallel reductions can reorder operations, atomic adds aren't bitwise reproducible, cuDNN picks the fastest convolution algorithm at runtime. Even with seeds set, two training runs can diverge in the third decimal place after a few epochs.
What you usually want is statistical reproducibility — same final accuracy ± 0.1%, same loss curve shape — not bitwise reproducibility. Achievable with seeds, deterministic data ordering, and a few cuDNN flags.
random, numpy, PyTorch CPU, PyTorch CUDA, and your DataLoader's worker_init. Then accept that GPU non-determinism still costs you the third decimal place.The seed-set ritual
Call set_seed(42) at the very top of training, before constructing the model. Use the same seed across runs you want to compare. For ablations, change one knob and keep the seed.
When you actually need bitwise determinism
For unit tests, regression tests, and certain regulated pipelines, set torch.use_deterministic_algorithms(True) and accept the slowdown (often 2x). Set CUBLAS_WORKSPACE_CONFIG=:4096:8 for matmul determinism. Save your full environment (Python version, package versions, GPU driver) — small differences across these can break determinism even with all flags set.