[Cute Sm100] support dropout#2597
Open
endurehero wants to merge 9 commits into
Open
Conversation
Author
|
hi @tridao, this is a function implemented according to my actual production requirements on GB200. I would be very happy if you could give me any suggestions |
Contributor
|
Hi @endurehero, I have a few organization-type comments:
|
Author
|
@reubenconducts Thank you very much for your suggestion. I think it is very reasonable. I will modify it today |
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.
FA4 SM100 Dropout Support
With the help of CodeAgent, this MR adds a dropout implementation
on FA4 SM100 whose per-element mask is aligned with FA2.
1. Summary
p_dropout,rng_state,return_dropout_maskarguments on theFA4
flash_attn_func(forward + backward, SM100 / SM110 only).are fed the same Philox
(seed, offset)— verified at the cell levelby the new pytest suite. Forward output and
dq / dk / dverrors arebounded by FA2's own bf16 error against an fp32 reference.
per-step training-loss difference between an FA4-dropout run and an
FA2-dropout run under the same seed schedule stays in the
1e-3 – 1e-4 band throughout the run, and downstream evaluation
metrics match within run-to-run noise. See §3.
costs ~20–40 % over no-drop FA4, but with dropout enabled it
dominates cuDNN on backward (up to ~1.7× on hdim = 64 long
sequences) and is competitive with cuDNN on forward. See §2.
2. Performance
Benchmarks captured on a single NVIDIA GB200 with cuDNN 9.22.0 (which was released
in May 2026),
dtype=bfloat16,nheads = 16,total_seqlen ≈ 32 k(batch chosenso
batch * seqlen ≈ 32 k). Each cell is averaged overtriton.testing.do_bench(warmup=5, rep=10)with a 1 s GPU-idle pause between cells to suppress DVFS / thermal bleed between runs.
Forward
Backward
Highlights:
hdim = 64; FA4 catches up at hdim = 128 long sequences. I am not sure
about this conclusion, please check it together.
~1.4 – 1.7× on hdim = 64 (cuDNN's bwd dropout path appears to fall
off a fast tile here) and by ~1.1 – 1.2× on hdim = 128.
hdim = 64 non-causal, FA4 leads on causal long sequences for both
head dims.
seq lengths (fwd ≈ 75–85 %, bwd ≈ 60–70 %), so dropout-injection
overhead is amortised inside the tile loop, not seqlen-dependent.
dropout_rate to be a multiple of 1/16. However, fa4 dropout does
not have this limitation.
Reproduction
3. Correctness
Validated at three levels.
3.1 Bit-identical dropout mask vs FA2 (unit test)
tests/cute/test_flash_attn_dropout.pyseeds both FA4 and FA2 with thesame Philox
(seed, offset)and asserts that the per-cell dropoutdecision in the valid (non-causal-masked) region matches exactly,
then bounds FA4's forward and
dq / dk / dverror by FA2's own bf16error against an fp32 reference. Coverage:
causal ∈ {F, T},p_dropout ∈ {0.1, 0.25},d ∈ {64, 128}, three (batch, seqlen,nheads) shapes. A second test confirms the empirical kept-fraction is
1 − pto within ±2 %.3.2 End-to-end training-loss agreement (MoE on GB200)
An internal MoE model was trained on GB200 with FA4 dropout, and the
same schedule was replayed with FA2 dropout under an identical seed
schedule. The per-step training-loss difference stays in the
1e-3 – 1e-4 band throughout the run.
3.3 Downstream evaluation parity
Downstream eval metrics on the same MoE checkpoints match between the
FA4-dropout and FA2-dropout runs to within standard run-to-run noise.
4. Implementation Notes
The implementation reuses FA2's Philox layout so the masks line up
cell-for-cell, but generates and consumes the mask inline with the
softmax tile loop — there is no global dropout-mask tensor on the
critical path.
4.1 Forward (
flash_fwd_sm100.py+softmax.py+philox.py)philox.pyexposes a 7-round Philox-4×32 with amul.wide.u32lowering and alop3.b32-fused 3-input XOR fast path(
philox_rounds_with_keys). The per-round key chain is precomputedonce per tile; the inner softmax step only redoes the counter mix.
softmax_step.apply_dropout_rP(softmax.py), each 32-bit Philoxword is split into 4 bytes and each byte is compared against an
8-bit threshold derived from
p_dropout(
f32_to_dropout_threshold_byte). Keep ⇔byte ≥ threshold. Skipsany float conversion and yields one branch-free predicate per
element.
rp = 1 / (1 − p)and dropped ones are zeroed in registers viaapply_dropout_pair, which fuses the keep-test and* rpinto asingle
selp+fmapair on the rP fragment, so dropout does notchange the MMA tile layout.
return_dropout_mask=True, thesame Philox bits are packed into a
(b, h, sq, sk)uint8 tensor viastore_dropout_mask_u8for testing / debugging; the backward neverreads it.
4.2 Backward (
flash_bwd_sm100.py)The forward does not store the mask. The backward replays the
Philox stream (same
seed/offsetcarried viarng_state) andregenerates the mask on the fly per tile. Dropout is then folded into
the existing
dS = P · (dP · scale − dPsum)chain.To stay inside the SM100 register budget once dropout is on, several
dropout-specific knobs are auto-enabled in
FlashAttentionBackwardSm100.__init__:merge_exp_dropout_dsP = exp(S − LSE) → dropanddS = P · dP_effinto one per-stage loop; halves the livetSrS_t2rfootprint (64 → 32 F32 regs) and keepsdrop_bitsstage-local.packed_dropout_fmamul_packed_f32x2/fma_packed_f32x2forpdrop = S · scaleanddP_eff = dP · scale − dPsum; drops the FP32 op count of the dropout consumer warpgroup from ~70 M to ~1 M.direct_sdS_xchg_writedSstraight into SMEM instead of an intermediate ~16-reg fragment (2-CTA tiles,hdim ≠ 192).skip_drop_bits_packqhead_per_kvhead ≥ 2, re-walks the SMEM mask in thedSapply step instead of carrying packed bits across phases; avoids the persistent_cached_mask_wordspill at GQA = 1.These are all internal and not user-visible.
4.3 Public API
p_dropoutis rounded to 6 decimals before becoming part of thekernel cache key, so nearby probabilities share the same compiled
binary.
rng_stateis a length-2int64tensor[seed, offset]. When it isNoneandp_dropout > 0, FA4 samples it from the default CUDAgenerator and returns it to the caller so the backward (or an
external replay) can reuse the same Philox stream.
qv(MLA),split_kv,block_sparsityand the dedicated hdim-256 kernel.