Repository navigation
Conversation
aw471
marked this pull request as ready for review
November 13, 2026 23:47
aw471
requested review from
RBendias,
akihironitta and
rusty1s
as code owners
November 13, 2026 23:47
aw471
marked this pull request as draft
November 14, 2026 03:21
aw471
force-pushed
the
compile-skip-chunking
branch
from
November 14, 2026 03:33
3f0067e to
d793044
Compare
aw471
force-pushed
the
compile-attention-operator
branch
2 times, most recently
from
November 14, 2026 05:43
c5339a7 to
9f6b7ae
Compare
aw471
force-pushed
the
compile-skip-chunking
branch
from
November 14, 2026 05:43
d793044 to
08ad0dd
Compare
A compiled graph records the number of chunks of the inputs it was traced with, so it is only valid for inputs that need the same number. Compiled code now processes its inputs in one chunk wherever the chunk size is derived from the memory budget: `TransformerBlock` without an explicit `batch_size_limit`, `CellEmbedding` with `batch_size_limit="auto"` and `split_size`. Explicit limits are honoured as before, and eager code chunks as before. The check is `torch.compiler.is_dynamo_compiling()`: PyTorch 2.14 sets `torch.compiler.is_compiling()` for the whole process while any thread compiles, which would switch chunking off for eager calls in other threads.
aw471
force-pushed
the
compile-attention-operator
branch
from
November 14, 2026 06:03
9f6b7ae to
7196981
Compare
aw471
force-pushed
the
compile-skip-chunking
branch
from
November 14, 2026 06:03
08ad0dd to
731c92f
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Compiled code no longer chunks its inputs automatically, so one graph serves any batch size. Before, a graph recorded the number of chunks, and a
TransformerBlockwith a dynamic batch size failed withConstraintViolationErrorabove 65,535 batch entries. Withouttorch.compile, chunking is unchanged.Description of the change
To bound peak memory on CUDA, three places split a large input into chunks and run them one after another:
split_sizeinsdm/_memory.py, which the numerical processorsClipSigma,RobustScaleandRankGaussianuse,TransformerBlock.forward, unless an integerbatch_size_limitis passed,CellEmbedding.forwardwithbatch_size_limit="auto".The number of chunks depends on the size of the input and on the free memory of the device.
torch.compileunrolls the loop over the chunks, so a graph holds a fixed number of them and guards on the sizes that give this number. For a batch size that is marked dynamic, the guard contradicts the mark:The three places now take one chunk while Dynamo traces them, as they already do while gradients are enabled. An integer
batch_size_limitis still honoured in compiled code.A
TransformerBlockwithout a limit chunked at 65,535 batch entries for the attention kernel. It no longer has to in compiled code: the attention operator of the previous change in this stack slices such a batch when it runs.The check is
torch.compiler.is_dynamo_compiling(). It isFalsein ordinary Python andTrueonly in code that Dynamo traces.torch.compiler.is_compiling()reads a process-wide flag instead, so it would also switch chunking off for uncompiled calls in other threads while a compile runs.Cost. Compiled code takes one chunk, so the chunking no longer bounds its peak memory. A caller with inputs that needed several chunks splits them or uses uncompiled
predict. For queries of up to 5,000 rows, a graph compiled for one query size has the same speed and peak memory as onmain: at 5,000 rows it takes 77.6 ms (4 columns, fp32) and 70.5 ms (50 columns, bf16) on this stack, against 78.2 ms and 71.2 ms onmain(small Kumo Tabular model, RTX PRO 6000, PyTorch 2.14.1, 3,000 context rows, 4 estimators). Larger queries were not measured for this change alone.Reproduction (CPU, PyTorch 2.14.1):
Validation
Ran the script above with
TORCH_LOGS="recompiles"and theeagerandinductorbackends, before and after this change (BEGIN/ENDlines are printed by the script). Both backends give the same result.Before:
After, no recompile line in the log:
test_transformer_block_compile_dynamic_batchfails without the change (ConstraintViolationError) and passes with it.FULL_TEST=1 pytest test/nn: 149 passed.inductorbackend): the script gives the same result on CUDA,ConstraintViolationErrorat 70,000 and 140,000 before and 1 graph after.FULL_TEST=1 pytest -m cuda test/nn: 125 passed.