Repository navigation
Conversation
8fd2432 to
72868c7
Compare
7e83853 to
98b7608
Compare
52d381d to
9650161
Compare
00a97d6 to
c913b8d
Compare
| vllm-flash-attn | ||
| GIT_REPOSITORY https://github.com/vllm-project/flash-attention.git | ||
| GIT_TAG b273a02621d3c94bc747df67204f591b67f38fae | ||
| GIT_TAG 6d71c3f914eb7943f49647ea4828c6b2fe9176c6 |
There was a problem hiding this comment.
note: this needs to change when FA PR lands
jhaotingc
left a comment
There was a problem hiding this comment.
Some general comments about: why there are more restriction to use this kernel after switching to FP8 MMA "within the kernel".
I'm curious about whether these restrictions will be traversed by code for actual use case (Gemma4)
Test seems too extensive.
| # specialization supports equal d512 heads, including sinks and dynamic causal. | ||
| sm90_fp8_kv_supported = fa_version == 3 or ( | ||
| fa_version == 4 and head_size in (None, 512) | ||
| fa_version == 4 and head_size in (None, 512) and head_size_v in (None, 512) |
There was a problem hiding this comment.
Is there a reason why this restriction needs to be stricken? or it's just missing from previous PR.
Will removing this change breaks Gemma4 + FP8 KV + FP8 MMA for hd 512?
There was a problem hiding this comment.
This check was missing from the previous vLLM integration. PR164 already requires equal K/V head dimensions, but the vLLM support check only checked the Q/K dimension.
Removing this addition would not break Gemma-4 with FP8 KV + FP8 MMA, since its full-attention Q/K/V dimensions are all 512. It would, however, allow unsupported Diff-KV shapes through backend selection.
| if sm90_fp8_kv and head_size == 512: | ||
| # Framework blocks can be split into the advertised 64-token pages. | ||
| if block_size is not None and block_size % 64 != 0: | ||
| return "SM90 d512 FP8 KV requires a block size divisible by 64" | ||
| if use_sparse: | ||
| return "SM90 d512 FP8 KV does not support block sparsity" |
There was a problem hiding this comment.
Are these restrictions specific to after your change? Flash attention PR 164 does not need these restrictions?
There was a problem hiding this comment.
The page-size requirement already existed in PR 164 (page_size == tile_n, which is 64 for d512). The vLLM check ensures framework blocks can be split into those kernel pages.
Block-sparsity rejection is specific to the current FP8 MMA implementation. Its producer traverses consecutive KV blocks, and its buffer/barrier schedule is not integrated with sparse block-list traversal. Neither restriction rejects Gemma-4’s standard text workload.
There was a problem hiding this comment.
No need to create a sm90_fp8_kv if not used elsewhere, just fold in if statement.
| if sm90_fp8_kv and head_size == 512: | ||
| # Framework blocks can be split into the advertised 64-token pages. | ||
| if block_size is not None and block_size % 64 != 0: | ||
| return "SM90 d512 FP8 KV requires a block size divisible by 64" | ||
| if use_sparse: | ||
| return "SM90 d512 FP8 KV does not support block sparsity" |
There was a problem hiding this comment.
No need to create a sm90_fp8_kv if not used elsewhere, just fold in if statement.
2adc688 to
5446e6c
Compare
|
Thanks @katec846, this is a nice, compact integration. Overall the vLLM wiring looks good to me. Before merge: Fixes you can cherry-pickI put a few small fixes on a branch on top of your head (5446e6c): https://github.com/simon-veitner-redhat/vllm/tree/pr60372-review-fixes Each commit applies on its own, except the test, which expects the first two.
PR descriptionCould you update the description with the following?
Our independent resultsAll runs used 4x H200 with
One small observation, not a blocker: in a harder multi-value retrieval test (6 values plus 10 distractor keys) at 196k tokens, mean recall was slightly lower with this PR. It was 0.86 vs 0.94 on main, over 36 trials (p≈0.06). The results were identical up to 64k and similar at 254k. I'm mentioning it for awareness only. This comment was drafted with Claude Code and reviewed by a human. |
|
This pull request has merge conflicts that must be resolved before it can be |
e71fe29 to
2b76f07
Compare
MatthewBonanni
left a comment
There was a problem hiding this comment.
The new kernel doesn't support non-causal attention, right? So if we swap over entirely don't we lose DCP support? Do we need to run DCP through the old kernel?
|
Right that the new kernel can't serve DCP's non-causal context call: the SM90 FP8 MMA kernel from FA#199 only builds its split QK accumulation for causal and local masks. But no working setup is lost, because DCP never worked on this path in vLLM, before or after this PR. The FP8 MMA path only applies to head-size-512 layers with an FP8 KV cache on SM90, which means Gemma-4. On main (merge-base
The old fp16-dequant FA4 kernel computed the non-causal call correctly when called directly (rel L2 1.60e-3 on a captured Gemma-4 31B layer, H100), but no real config could reach it, and it no longer exists at This PR makes the limitation explicit: For reference, if DCP ever gains sliding-window support: running the context call as local attention with a window covering every key gives the same mask and uses the accurate local build. It matched the BF16-cache DCP path in a DCP=2 emulation on the same layer (rel L2 2.38e-3 vs 2.29e-3 decode). It's a workaround that relies on FA building the QK split for local masks; the cleaner fix would be in FA. - if uses_sm90_fa4_fp8_kv_dequant and self.dcp_world_size > 1:
- raise NotImplementedError(...)
+ self.dcp_context_window = list(self.sliding_window)
+ if (
+ uses_sm90_fa4_fp8_kv_dequant
+ and self.dcp_world_size > 1
+ and self.sliding_window == (-1, -1)
+ ):
+ max_model_len = vllm_config.model_config.max_model_len
+ self.dcp_context_window = [max_model_len, max_model_len]
...
causal=False,
- window_size=sliding_window_size,
+ window_size=self.dcp_context_window,This review was prepared with Claude Code and reviewed by a human (@simon-veitner-redhat). |
|
/ci run |
|
✅ Triggered Buildkite CI #100019 for commit |
|
✅ @katec846, CI is now available for this PR.
|
pytest 9 only skips ModuleNotFoundError in importorskip by default, so the ImportError raised by vllm.vllm_flash_attn on ROCm broke collection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matthew Bonanni <mbonanni@redhat.com>
|
/ci run |
|
✅ Triggered Buildkite CI #100033 for commit |
|
/ci retry |
|
✅ Triggered Buildkite CI #100131 for commit |
|
Hi @katec846, the pre-commit checks have failed. Please run: uv pip install pre-commit>=4.5.1
pre-commit install
pre-commit run --all-filesThen, commit the changes and push to your branch. For future commits, |
The conversion helper no longer accepts input_dtype. Remove the stale keyword from the Zen CPU width-logging test so the call matches the API and passes mypy. Co-authored-by: Codex <codex@openai.com> Signed-off-by: Kate Cheng <yunhsuanc@nvidia.com>
Head branch was pushed to by a user without write access
|
/ci run |
|
✅ Triggered Buildkite CI #100154 for commit |
Run Gemma-4-31B-FP8 from models-large-hopper.txt instead of a dedicated 2xH100 step that ran on every attention-backend change. The lm-eval harness gains an hf_overrides key, needed for the text-only override that routes Gemma-4's full-attention layers to the SM90 FP8 MMA path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matthew Bonanni <mbonanni@redhat.com>
Measured on 4x H100 at TP4 with this branch and FA 9ed6b12; the SM90 FP8 MMA kernel ran for the head_size=512 layers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matthew Bonanni <mbonanni@redhat.com>
|
/ci run |
|
✅ Triggered Buildkite CI #100296 for commit |
Overview
Enable FP8 MMA in the SM90 FA4 full-attention kernel (PR199) for Gemma-4 while retaining FP8 KV-cache storage.
Gemma-4 uses head dimension 512 for full attention and 256 for sliding-window attention. This change compares FP8 MMA against the existing path that reads FP8 KV, dequantizes it, and performs FP16 MMA.
On H200, FP8 full attention uses FA4, while FP8 sliding-window attention continues to use FA3. FA4 FP8 sliding-window attention with head dimension 256 is currently unsupported.
Claims
Validation
The MMA labels describe the full-attention path. Both FP8-KV configurations use FA3 FP8 sliding-window attention; the BF16-KV reference uses FA4 BF16 sliding-window attention.
Serving setup:
Serving performance
The
8k-in-1k-outbenchmark ofgemma_4_31b_it_h200on one H200 at TP=1, with GPU clocks locked. Each number is the median of 3 repetitions, as perf-eval aggregates them; no request failed.5d35ce3934+ FAb273a02)Reproduce
5d35ce3934, with FlashAttention at Add SM90 FP8 MMA forward for head dimension 512 flash-attention#199's base,b273a02. After is this PR's head,237043eee6, with Add support for H100 #199's head,2648f1b.237043eee6withVLLM_FLASH_ATTN_SRC_DIRset to the FlashAttention checkout, and differ only in Python sources.RedHatAI/gemma-4-31B-it-FP8-dynamic. Server and benchmark match perf-eval@5f4e445 (lib/server.sh,lib/run_vllm_bench.sh,lib/aggregate_perf.py).Model evaluation
Accuracy scores are percentages. 87.19% for AIME 2025, 85.73% for GPQA Diamond (avg@16), and 86.86% for MMLU-Pro are measured in this PR; the two reference columns are reported baselines from PR #48666.
* Note that in a paird GPQA Diamond comparison using the same 198 questions and 16 seeds, FP8 MMA scored 85.73% versus 85.32% for the FP8 KV + FP16 MMA. The difference was +0.41 percentage points, with a paired question-bootstrap 95% interval of [−0.51, +1.36] points. Both runs had zero invalid or truncated answers. The table’s 86.55% reference is imported from PR #48666 and is separate from this matched control.
MTP speculative decoding
Mean acceptance length (AL), median of three rounds, from the same sweep as the serving-performance table above. All configurations use FP8 model weights, TP4 on four H200 GPUs, three speculative tokens, and prefix-cache reuse enabled. Each measurement completed 128/128 requests without errors. AL includes the bonus token emitted per speculative step.
Reproduction commands
The Hopper FP8 MMA path supports text-only workloads. The commands use --hf-overrides '{"text_config":{"use_bidirectional_attention":null}}' to disable Gemma-4’s bidirectional/mm-prefix attention. Multimodal Gemma-4 with FP8 KV uses Triton instead of this kernel. FP8 sliding-window layers use FA3, so do not force FA4 globally.
Serve and benchmark: 25K shared prefix, TP4, MTP3, cache reuse on
(The two FP8-KV serving commands are identical because MMA selection depends on the FlashAttention kernel source, not a CLI flag. For the control, we kept the same vLLM integration but replaced its vendored CuTe sources with the PR #164 dequantizing kernel, including the baseline safety fixes, then restarted the server. --kv-cache-dtype fp8 selects FP8 cache storage in both cases)
These recorded runs left the FA version unset. The dequantized control uses the PR #164 baseline kernel environment.
Benchmark:
Run at concurrency 1, 2, 4, 8, 16, 32, and 64; report the median of three rounds.
Evaluation commands
Evaluation server on four H200 GPUs. AIME and GPQA use
--max-num-seqs 16; MMLU-Pro uses32. No MTP.AIME 2025, avg@64
Use
aime.yamlwith 64 samples per problem, temperature 1.0, top-p 0.95, and the GPT-4.1 judge configuration. ExportINFERENCE_API_KEY.GPQA Diamond, avg@16
Use
gpqa.yamlwith all 198 questions, theeval/aai/mcq-4choicesprompt, temperature 1.0, and top-p 0.95. Run seeds 0–15.MMLU-Pro
Restart the evaluation server with
--max-num-seqs 32. Usemmlu.yamlwith all 12,032 questions, one sample per question, theeval/aai/mcq-10choices-boxedprompt, temperature 1.0, and top-p 0.95.Details
Why FP8 is slower than BF16
Nsight shows that faster FP8 full attention does not necessarily produce faster end-to-end execution.
Sliding-window attention and KV-cache operations offset full-attention gains
The profiling setup uses 25K inputs, TP4, MTP enabled, prefix reuse enabled, and offered concurrency 64.
Time reduction is
100 × (BF16 time − FP8 time) / BF16 time, calculated from the displayed times. Positive values mean less time (faster); negative values mean more time (slower).Full attention is approximately 12% faster, but sliding-window attention is approximately 30% slower, with additional KV-write, preparation, and combine work.
KV-write overhead refers to the kernels that reshape and write newly generated keys and values into the paged cache, including the FP8 conversion/quantization path. Attention reads and prefix-cache reuse accounting are separate from this kernel category.
Reuse-off profiles show the same pattern.
The following comparison uses cc16, 25K inputs, TP4, MTP enabled, and prefix-cache reuse disabled. These matched pure-decode cycles process 16 active requests per target step. Values are medians across four GPU ranks of each rank's per-cycle medians, with 69 matched cycles per rank for BF16 and 87 for FP8.
Full attention is faster, but SWA, KV-cache writes, and attention preparation/combine offset the gain. The whole-cycle GPU span is 2.6% longer for FP8. This is a profiling comparison, not an unprofiled end-to-end throughput measurement.
Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.