Gemma4 FFPA attention backend support for accelerating Gemma4-family training #2928
Butterfingrz
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
NeMo-Automodel recently added FFPA attention backend support for Gemma4 full-attention layers with
head_dim=512. In the Gemma4-31B training path, these full-attention layers can now useffpa-attnCuTeDSL kernels instead of the existing SDPA or FlexAttention implementations.This targets Gemma4's expensive
head_dim=512full-attention layers. Sliding-window layers havehead_dim=256and windowed, vision-aware masks, so they are explicitly routed to FlexAttention instead of FFPA. In our end-to-end tests, FlexAttention was noticeably faster than SDPA for those sliding-window layers.For reference, these are the operators observed when profiling Gemma4 with the SDPA and FlexAttention backends:
aten::_scaled_dot_product_cudnn_attentioncudnn_generated_fort_native_sdpa_sm90_flash_{fprop,bprop}_wgmma_f16is_causalfast path)aten::bmmx6 +aten::_softmax(materializesS x S)aten::_scaled_dot_product_efficient_attentionfmha_cutlassF/B_bf16_aligned_*_sm80aten::_scaled_dot_product_cudnn_attentiontorch.ops.higher_order.flex_attention(compiled)triton_tem_fused_flex_attention*Integration
For non-CP training,
attn_implementation: ffparegisters"ffpa"as a Hugging Face attention backend during model build.setup_ffpa_backend(...)validates this path before preload overrides run: direct"ffpa"requirescp_size == 1and rejects packed sequences. This path also requires theffpa-attndependency, exposed through theffpaextra.At runtime,
ffpa_attention_forward()uses FFPA only for eligible full-attention calls:head_dim=512, fp16/bf16, no attention dropout, a non-null scale, and an available FFPA CuTeDSL kernel. The dense no-mask path uses the high-levelffpa_attn_func; a 2D bool padding mask uses the FFPA varlen path. Unsupported full-attention cases fall back to SDPA or eager, withsoftcapforced to eager. Sliding-window and other non-causal mask functions are routed through a FlexAttentionBlockMask, so those layers use FlexAttention rather than SDPA. Gemma4 MoE still uses Hugging FaceGemma4Attention, so the Gemma4-26B-A4B attention dispatcher can use the same"ffpa"backend.For context parallelism, FFPA is wired through Gemma4's model-owned ring path instead.
attn_implementation: ffpais rejected whencp_size > 1, because the Hugging Face backend calls the FFPA op directly and would bypass the ring SDPA swap. CP runs should keepattn_implementation: sdpaand settext_config.cp_full_attn_backend: ffpa. The ring path uses a rank-uniform gate, checking causal full attention, no sliding window,_packed_seq_ids,head_dim=512, fp16/bf16, scale, and FFPA availability. Eligible full-attention ring chunks use FFPA, choosing dense or varlen per chunk; everything else stays on the compiled FlexAttention ring path.Joint Finetuning Recipes
For non-CP Gemma4-31B fine-tuning, enable the Hugging Face attention backend directly:
With this setting,
head_dim=512full-attention layers dispatch to FFPA when the layer is eligible. Layers that do not match the FFPA constraints fall back to SDPA, eager, or FlexAttention as appropriate.Do not combine the direct Hugging Face
"ffpa"backend with CP orpacked_sequence; AutoModel fails fast for both cases. Packed long-sequence FFPA runs should use the CP ring configuration below.For context-parallel Gemma4-31B fine-tuning, keep the Hugging Face attention implementation as SDPA and opt the Gemma4 ring path into FFPA:
This is the required CP setup because
attn_implementation="ffpa"calls the FFPA op directly and bypasses Gemma4's model-owned CP ring hook. In CP mode,cp_full_attn_backend: ffparoutes full-attention ring chunks through FFPA, while sliding-window layers continue to use the compiled FlexAttention ring path. The CP batch path supplies_packed_seq_ids, so the ring backend can use dense chunks for single-document shards and varlen chunks when packing or cross-document masking is needed.Results
Upstream H200 E2E result from PR #2436
The PR description also reported an end-to-end Gemma4-31B run on H200. At the same reported peak-memory level, FFPA improved TPS/GPU by about 40-50%, while the loss curve overlapped the SDPA baseline within bf16 noise.
Environment and hyperparameters:
DP=8,GBS=8,local_bs=1,grad-accum=4,L=8192sdpabaselineffpacandidatesdpawithin bf16 noiseW&B report: Gemma4 FFPA H200 E2E comparison
Note: the small memory gap visible in this early H200 plot comes from the first FFPA SAC integration. FFPA forward ops were pinned to
MUST_SAVE, soactivation_checkpointing: truedid not recompute the FFPA attention ops. Read the memory line here as an artifact of that checkpointing policy, not as a pure kernel-memory comparison.The benchmark recipes used for these runs are
examples/vlm_finetune/gemma4/gemma4_31b_ffpa_mock_8k.yamlfor the non-CP path andexamples/vlm_finetune/gemma4/gemma4_31b_ffpa_mock_packing_cp8_16k.yamlfor the Ring CP path.Perf summary for PR #2436, rerun on a local 8x H100 80GB setup at local rerun commit
dac1683f7. The CP1 mock 4k and 8k FFPA rows were updated from the latest reruns. Each run used 30 train steps; TPS/GPU is averaged over steps 20-29 only.FFPA speedup:
Notes:
attn_implementation: ffpais non-CP and non-packed only; packed FFPA uses the CP ring path.PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True.Follow-up
Future work will extend this FFPA full-attention backend path across Gemma4-family models that use
head_dim=512full-attention layers."ffpa"attention backend directly; it runs through Gemma4's model-owned ring hook, so each attention module must be attached withuse_ffpa=True. Today only the dense Gemma4 branch readstext_config.cp_full_attn_backendand passes that flag intoattach_gemma4_cp_ring_attention(...). The Gemma4-MoE decoder layer still callsattach_gemma4_cp_ring_attention(self.self_attn)with the defaultuse_ffpa=False, sogoogle/gemma-4-26B-A4B-itRing CP currently falls back to the FlexAttention ring for full-attention layers instead of using FFPA.Debugging notes
Gemma4 full-attention layers exposed a separate SDPA debugging issue before the FFPA path:
head_dim=512plus the no-padding causal fast path can makeattention_mask=None, which previously caused Transformers'sdpa_attention_forwardto passenable_gqa=True. PyTorch's fused SDPA backends cannot handle that GQA broadcast case forhead_dim > 256, so dispatch silently falls back to the MATH backend and materializes theS x Sscore matrix, turning streaming fused attention memory into O(S^2) memory and causing long-sequence OOMs. Hugging Face Transformers PR #46960 fixes this by only enabling GQA-in-SDPA for the safe case where key/value head dimensions are equal and<= 256; Gemma4head_dim=512full-attention therefore takes the repeat-KV path instead of the unsupportedenable_gqa=Truepath.The local 8x H100 80GB 8K run did not reach the expected ~30% TPS gain, but the bottleneck was not the FFPA kernel suddenly getting slower. At 8K, the run pushed the real reserved-memory watermark to the allocator/FSDP2 boundary. It did not OOM, but the allocator frequently flushed cache and retried allocations. Those retries usually bring synchronization and the
cudaMallocslow path, which can consume the TPS gain FFPA should provide at this sequence length.PYTORCH_CUDA_ALLOC_CONF=expandable_segments:Truehelps reduce slivers and fragmentation, but it does not reduce the real live-tensor footprint, FSDP2 all-gather demand, or FFPA layout-copy demand. This is why the H200 result looks closer to the ideal case, with roughly 40-50% TPS improvement, while the local H100 CP1 mock 8K run only shows +16.9% over Flex.Related PRs:
I'm truly grateful to @HuiyingLi , @athitten and @akoumpa for their help, and to the Automodel team for their trust.
All reactions