5.1 KiB
Deep CFR Reproducibility Policy
Last verified: 2026-05-08, commit 0f85fa8
Source: docs/research/deep-cfr-reproducibility.md
Policy
Deep CFR experiments should target two different kinds of reproducibility:
- Debug reproducibility: short runs should be bitwise reproducible on the same machine when using deterministic settings.
- Research reproducibility: reported conclusions should survive repeated seeds and reasonable hardware differences, even when exact metric rows do not match bit-for-bit.
Do not treat a single seeded multi-worker GPU run as a final research result. Use it as an exploratory signal unless it is confirmed with matched seeds.
Hardware Expectations
Exact same metrics are not guaranteed across machines, even with the same CUDA version. GPU model, driver, PyTorch build, CPU scheduling, multiprocessing timing, and floating-point reduction order can all affect exact trajectories.
Expected reliability by setting:
| Setting | Expected result |
|---|---|
Same machine, same GPU, same code, traversal.num_workers=1 |
Best current option for bitwise debug checks |
| Same machine, same GPU, same code, multi-worker traversal | Current implementation target: bitwise stable across repeated runs |
| Same GPU/CUDA but different CPU | Current implementation target: same seed should follow the same logical trajectory |
| Different GPU or PyTorch/CUDA build | Exact equality is not expected; use multi-seed conclusions |
Required Experiment Practice
For exploratory experiments:
- Single-seed runs are acceptable.
- Record the resolved config, run directory, W&B URL when used, and final eval metrics.
- Label conclusions as provisional.
For claims worth keeping:
- Use matched seeds across baseline and treatment.
- Use at least 3 seeds; prefer 5 when runtime allows.
- Report mean and standard deviation for the key metrics.
- Keep
run.seed, commit SHA, GPU, CUDA/PyTorch versions, andtraversal.num_workersvisible in the run record.
Example matched-seed comparison:
baseline: seeds 79, 80, 81
treatment: seeds 79, 80, 81
Compare the treatment against the baseline seed-by-seed, then report aggregate statistics.
Batch Size Interpretation
Not every batch size is a reproducibility-neutral setting.
Batching that should be algorithm-neutral under the deterministic target:
- traversal/interleaved policy inference batch size, such as
traversal.interleave_max_batch - evaluation inference batch size, such as
evaluation.batch_size
These settings should affect throughput, not the logical trajectory. Same code, seed, hardware stack, and training config should produce the same non-timing metrics when only these batching knobs change.
Batching that is an algorithmic training setting:
optimization.advantage_batch_sizeoptimization.strategy_batch_size- update counts or optimizer schedule parameters
These settings change gradient estimates or optimizer updates. They are experiment variables, not reproducibility-neutral execution settings. A run with training mini-batch size 3 is not expected to match one with training mini-batch size 7.
Debug Mode
Use debug mode when checking exact reproducibility or suspected regressions:
traversal.num_workers=1evaluation.num_workers=1- PyTorch deterministic settings enabled:
torch.use_deterministic_algorithms(True)torch.backends.cudnn.benchmark = Falsetorch.backends.cuda.matmul.allow_tf32 = Falsetorch.backends.cudnn.allow_tf32 = False
- short
run.max_iterations, usually 3 - checkpoint writes disabled unless specifically needed
- W&B disabled
The expected check is to run the same command twice and compare non-timing
metrics in metrics.jsonl, including:
traversal/nodesmemory/advantagememory/strategyloss/advantageloss/strategy- eval scores, if evaluation is enabled
Timing fields are not expected to match exactly.
Implementation Priorities
Current implementation target:
- Add a small reproducibility smoke script that runs two short debug jobs and compares non-timing metrics.
- Make worker count a performance setting, not an algorithm setting:
traversal.num_workers=1,4, and8should produce the same non-timing metrics on the same code/config/seed. - Assign stable traversal IDs, derive RNG streams from traversal IDs, and merge samples by traversal order rather than worker, batch, or completion order.
- Stabilize interleaved scheduler request/context ordering so CPU scheduling differences do not change the logical traversal path.
- Enable PyTorch deterministic settings for reproducibility/debug runs. Keep the speed impact explicit when comparing runtime.
- Re-test same-seed runs across
traversal.num_workers=1,4, and8. - Re-test on the same GPU/CUDA stack with a different CPU when available.
Current Interpretation Rule
Until traversal-ID based deterministic scheduling and merge are implemented, default multi-worker runs with the same seed may diverge. Interpret exact curves cautiously. For research conclusions, prefer matched multi-seed comparisons over bitwise row matching.