v2.10.7
Highlights
- Fixed affinity prediction running ~5× slower than necessary at default settings. Upstream hardcoded
max_parallel_samples=1for the affinity diffusion path, which was silently a no-op under upstream's buggy chunking math. Our earlier diffusion fix made that hardcode actually take effect, forcing N sequential single-sample forward passes per affinity record. The affinity path now honors the user's--max_parallel_samples, capped at--diffusion_samples_affinity.
Details
Background — how this regression slipped in
Upstream's chunking math in diffusionv2.py was:
sample_ids_chunks = sample_ids.chunk(multiplicity % max_parallel_samples + 1)tensor.chunk(n) splits a tensor into n chunks, not into chunks of size n. For affinity (multiplicity=5, max_parallel_samples=1) this collapsed to chunk(1) — one chunk of 5 samples, all batched into a single forward pass. The hardcoded =1 upstream put on the affinity path never actually took effect.
Our v2.10.x diffusion fix replaced that with the obviously correct:
sample_ids_chunks = sample_ids.split(max_parallel_samples)That fix was independently correct — it made --max_parallel_samples behave as documented in divisible cases — but it changed the semantics under the affinity caller, which was unknowingly tuned against the broken behavior. With the fix in place, the hardcoded 1 started doing what it said: 5 sequential single-sample passes per affinity record.
What changed
- New helper
_resolve_affinity_max_parallel_samples(max_parallel_samples, diffusion_samples_affinity)insrc/boltz/main.py:- Honors the CLI
--max_parallel_samplesfor affinity, matching the behavior already used for structure prediction. - Caps at
diffusion_samples_affinityso we never claim to batch more affinity samples than diffusion will actually run. - Treats
max_parallel_samples=Nonethe same way the diffusion code does ("use multiplicity") — relevant for programmatic callers ofpredict.callback(...)that passNone.
- Honors the CLI
predict_affinity_argscalls the helper instead of hardcoding1.
Behavior matrix
--max_parallel_samples |
--diffusion_samples_affinity |
Resolved affinity max | Affinity behavior |
|---|---|---|---|
| 5 (default) | 5 (default) | 5 | 1 batched forward pass (matches upstream's effective pre-fix behavior) |
| 2 | 5 | 2 | User override respected |
| 50 | 5 | 5 | Capped — no inflated work |
| 1 | 5 | 1 | Explicit single-sample preserved |
None |
5 | 5 | Falls back to diffusion sample count |
Tests
Six new unit tests in tests/test_cli.py::TestAffinityMaxParallelSamples:
- Default CLI setting batches all samples.
- User overrides below the cap are honored.
- User overrides above the cap are capped.
- Explicit
1is preserved. Nonefalls back todiffusion_samples_affinity(regression guard againstTypeError: '<' not supported between 'NoneType' and 'int').- Source regression guard: scans
main.pyfor thepredict_affinity_argsblock and fails if anyone re-hardcodes\"max_parallel_samples\": 1there or removes the helper.
Total fork test count is now 283.
What did not change
- The chunking primitive itself is correct; this only fixes the call site that was implicitly relying on the old broken behavior.
- Structure prediction was already routing
--max_parallel_samplescorrectly. - Numerical outputs are unchanged — this is purely a parallelism / wall-clock fix.
Commits since v2.10.6
5103619Release 2.10.7