[None][feat] Run Gemma4 head_dim 512 attention on Triton - #17772
Closed
yuzisun wants to merge 1 commit into
Closed
Conversation
Gemma4's full-attention layers use head_dim=512, which no SM90 paged attention kernel serves: trtllm-gen has the cubins but ships them for datacenter Blackwell only, TRTLLM paged FMHA does not cover 512, and FlashInfer's fa2/fa3 paged kernels stop at 256. Gemma4 therefore does not run on Hopper through the PyTorch backend at all. Route those layers through Triton instead. The context phase already had a suitable kernel in triton_prefill.py (head_dim 512 capable, with a Hopper tile heuristic); the decode half is ported from the AutoDeploy Triton attention backend, which uses the identical combined HND cache layout [num_pages, 2, num_kv_heads, page_size, head_dim]. Both phases are handled before metadata.plan(), so no FlashInfer wrapper is ever created for these layers and they never touch workspace_buffer. That keeps a single wrapper type in play across the rest of the model and avoids the workspace corruption that mixing wrapper types under CUDA graphs causes. Sliding layers (head_dim 256) are unaffected and stay on FlashInfer. KV-shared layers, speculative-decoding draft views and multi-token generation steps raise NotImplementedError on this path rather than returning incorrect results. CUDA graph capture and perf tuning are left to a follow-up. Signed-off-by: Dan Sun <dsun20@bloomberg.net>
Author
|
/bot run |
Collaborator
|
Hi Dan, thanks for your contribution. We’re currently preparing PR #18002, which adds SM90 support to the FlashInfer FA2 backend and will unblock Gemma 4 on Hopper. Could you please verify whether this official implementation works for your use case? |
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.
Description
Gemma 4's full-attention layers use
head_dim=512, which no SM90 paged attention kernel serves:is_sm_100f).PR #17557 routed all non-SM100 architectures to fa2, but that branch was validated only through unit tests with
is_sm_100fmocked, and the same PR removed the comment# head_dim>256 needs trtllm-gen (fa2 JIT doesn't support it). So Gemma 4 does not currently run on Hopper through the PyTorch backend at all. Text-only inference is available today only via AutoDeploy, whose configs selectattn_backend: tritonfor exactly this reason.This PR routes those layers through Triton in the PyTorch backend.
Approach
Prefill already had a suitable kernel in-tree:
attention_backend/triton_prefill.pyhandles head_dim 512, reads FlashInfer's HND paged layout, gives causal attention whencustom_mask is None, and its_get_block_sizesalready has a Hopper branch forLq > 256. Only the call-site gate needed widening.Decode is ported from the AutoDeploy Triton attention backend (
auto_deploy/custom_ops/attention/triton_attention.py), which uses the identical combined HND cache layout[num_pages, 2, num_kv_heads, page_size, head_dim]. The AutoDeploy file importsflashinferonly for a metadata helper, not for the attention math, so the kernels port cleanly. AutoDeploy registry wiring and the context-phase kernels were stripped.The plumbing lines up with what the backend already maintains:
triton_decodeargkv_cachekv_cache_manager.get_buffers(layer_idx, kv_layout="HND")returns exactly this shape; its docstring already covers Gemma 4's 256/512 multi-pool casekv_indptr/kv_indices/kv_last_page_lenmetadata.swap_paged_kv_indices_for_layer(), already called inforward_implFP8 KV cache keeps working: the kernels cast on load, so the cache is dequantized in-kernel.
Why both phases are handled in one branch
PR #17557 noted that "uniform backend avoids workspace corruption between different wrapper types under CUDA graphs". Doing prefill and decode in Triton lets the branch return before
metadata.plan(), so head_dim 512 layers never create a FlashInfer wrapper or touchworkspace_buffer. The sliding layers (head_dim 256) all stay on fa2, leaving exactly one wrapper type in play. Sliding-layer behaviour is unchanged.The trigger is
head_dim > 256 and not is_sm_100f()— a general statement about FlashInfer paged kernel capability, not a Gemma 4 special case — so no model code changes.Not covered
These raise
NotImplementedErrorrather than returning incorrect results:k is None). Their current tokens' KV is already paged, so feeding them as Triton's "prefix" would drop causal masking between them. Models withnum_kv_shared_layers > 0will fail loudly on this path.triton_decodederives batch size fromq's leading dim.CUDA graph capture and perf tuning are deliberately deferred;
triton_decodestill allocates its split-K workspaces per call. Triton FlashDecoding will not match trtllm-gen. Multimodal is out of scope (the vision tower forcesattn_backend="TRTLLM"with sm100a-derived head-dim padding).Test Coverage
tests/unittest/_torch/attention/test_triton_decode.py— new kernel tests: head_dims 64–512, the real Gemma 4 E2B/31B shapes, GQA ratios including non-power-of-2 (12/4, 24/4) that exercise head padding, page sizes 1–64, partial and exact-multiple last pages, split-K, sliding windows, FP8 KV.backend_capability.py— head_dim 512 is no longer skipped for FLASHINFER below sm100, activating the existinggemma4_e2b_mqa_hd512/gemma4_26b_gqa_hd512/gemma4_31b_gqa_hd512cases against the VanillaAttention golden. It remains skipped on sm100+, where the harness builds FlashInfer with the defaultfa2and this path is off.test_modeling_gemma4.py— four tests running the existing HF-comparison harness with the non-Blackwell dispatch forced on, across the E2B/31B/26B real-dims configs, plustest_triton_path_is_actually_taken, which spies on both Triton entry points so a dispatch regression cannot masquerade as passing coverage. Bothis_sm_100fcall sites are patched together so the simulation is faithful on any GPU.l0_h100.yml— individual node ids rather than the whole file, since the rest oftest_modeling_gemma4.pyassumes trtllm-gen.test_triton_decode.pyand the attention-backend sweep are already picked up by the existingunittest/_torch/attentiondirectory entry.This has not been run on a GPU — hence draft. Opening it to get CI signal on H100.
PR Checklist
[JIRA/NVBUG/None][type] Summary