Opt-in batched block-diagonal attention: 2x pretraining throughput, validated equivalent#5
Open
alex-crlhmmr wants to merge 1 commit into
Conversation
FaceTransformerLayer and EdgeTransformerLayer process each part of the batch in a Python loop, launching thousands of small kernels per step from a single thread. On fast GPUs the forward becomes kernel-launch-bound: we measured ~40% GPU utilization and 90% of step time spent in these loops. This adds _bd_attn, a batched block-diagonal attention path: parts are padded onto a batch axis (parts cannot attend across it, so block-diagonal structure comes free), the topology bias scatter is batched through a single index_add over flattened (part, src, dst) indices, pad keys are masked with -inf, and attention dropout is applied exactly as in the loop path. The edge layer falls back to the loop when the largest part exceeds EDGE_CAP edges (default 2000) to bound the padded allocation. Opt-in via BATCHED_FACE=1 / BATCHED_EDGE=1; default behavior is unchanged. Measured on the pretraining task (batch 16, paper config): 2.03x step throughput (5.39 -> 10.96 it/s on one H100; 13+ it/s on H200 with a high-clock host). Equivalence: identical to the loop path within 6e-8 on synthetic checks; training curves match a stock run within seed noise at every epoch over 5-epoch and 16-epoch full-corpus comparisons; a full 100-epoch pretraining on Brep2Shape-250k followed by fine-tuning reproduces downstream results (FabWave 100.0, TMCAD 86.4). Not bit-exact with the loop path because the dropout RNG stream differs.
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.
Motivation
FaceTransformerLayer.forwardandEdgeTransformerLayer.forwarditerate over the parts of a batch in a Python loop, computing attention per part. Each step launches thousands of small kernels from one Python thread, and on fast GPUs the forward becomes kernel-launch-bound rather than compute-bound. Profiling pretraining (paper config, batch 16) on an H100: the dataloader accounts for 0.3% of wall time, the two per-part loops for ~90%, GPU utilization sits around 40%, and py-spy shows the main thread pinned inside the per-part einsum. The GPU starves while the CPU dispatches kernels.Change
Adds
_bd_attn, a batched block-diagonal attention path used by both layers:_mean_multiedge_biasscatter) is computed for all parts in oneindex_add_over flattened(part, src, dst)indices instead of per part.-infbefore the softmax.attention_dropoutis active at its 0.1 default during pretraining, see Expose --attention_dropout in pretraining (consistency with classification/segmentation) #2).EDGE_CAPedges (default 2000), bounding the padded[P, Emax, Emax]allocation on edge-heavy parts (see Edge/face transformer attention is O(E^2) per part with no cap, OOMs on high-edge-count B-reps #3).The path is opt-in via
BATCHED_FACE=1andBATCHED_EDGE=1; without the env vars, behavior is byte-identical to the current code.Measured speedup
Pretraining, paper config (batch 16, 6-layer Dual Transformer):
2.03x from the code change alone. The training math is untouched (same batch size, same LR schedule).
Equivalence evidence
Not bit-exact with the loop path: the dropout RNG stream differs because dropout is applied to one batched tensor instead of per part. Statistically the runs are indistinguishable from a seed change, as shown above.