Skip to content

Inference determinism: atom aggregation, feature seeding, and chunk-size reuse - #320

Open
heathcliff233 wants to merge 4 commits into
aqlaboratory:mainfrom
heathcliff233:lhong/2026-07/refactor/inference-foundation
Open

Inference determinism: atom aggregation, feature seeding, and chunk-size reuse#320
heathcliff233 wants to merge 4 commits into
aqlaboratory:mainfrom
heathcliff233:lhong/2026-07/refactor/inference-foundation

Conversation

@heathcliff233

@heathcliff233 heathcliff233 commented Jul 18, 2026

Copy link
Copy Markdown

Summary

First PR in a planned breakdown of #318. This lands only the inference-determinism and chunk-reuse foundation.

Why current inference can disagree across identical runs

Two independent sources of nondeterminism show up even with a fixed sample seed and production math (TF32 on):

  1. Feature creation RNG. On-the-fly features such as ligand conformers draw from ambient Python / NumPy / Torch RNG. Upstream does not pin that RNG to the datapoint seed during featurization, so the same query can produce different ref_pos (and related features) depending on prior process state.
  2. CUDA atom→token aggregation. Inference aggregation uses scatter_add_, whose CUDA atomic reductions are not order-stable. Small differences are amplified through diffusion and can change the final pose.

These are independent: seeding features alone does not make model outputs repeatable under scatter aggregation, and segmented aggregation alone does not make ligand features repeatable under polluted ambient RNG.

What this PR changes

  • Scope feature creation to each datapoint's seed (save/restore Python, NumPy, and CPU Torch RNG) so conformers and other feature RNG no longer depend on ambient process state
  • Use packed segment_reduce for atom→token aggregation in inference / no-grad, keeping scatter_add_ for training/autograd
  • Use indexed token→atom broadcast in the atom decoder
  • Cache ChunkSizeTuner results per argument shape and max chunk size so alternating targets reuse prior probes instead of retuning every revisit

Gather token features through precomputed atom-to-token indices in the
decoder, and use segmented reductions for packed inference aggregation
to avoid CUDA atomic scatter nondeterminism. Keep the scatter path under
autograd.

Tests: pytest openfold3/tests/test_atomize_utils.py -q
Tests: pytest openfold3/tests/test_sequence_local_atom_attention.py -q
Keep separate chunk-size entries keyed by argument structure and
max_chunk_size so alternating inference targets can reuse prior OOM
probes instead of re-tuning on every revisit.

Tests: pytest openfold3/tests/utils/test_utils.py -k chunk_size_tuner -q
Scope on-the-fly feature RNG (e.g. ligand conformers) to each sample's
seed with save/restore so featurization no longer depends on ambient
Python/NumPy/Torch RNG state.

Tests: pytest openfold3/tests/core/data/framework/single_datasets/test_inference_seeding.py -q
Factorial check of feature seeding and segmented atom aggregation under
TF32 production math, with ambient RNG pollution between feature and
forward repeats.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

training Relating to the training pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants