flydsl: gfx942 FP8 MQA logits indexer kernel (+ Triton FN/FNUZ fix) - #3913
Conversation
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
|
|
why there is a mixed FN/FNUZ path? |
|
The mixed types come from vllm. On gfx942 the KV cache is fnuz, but DSv4 Flash quantizes Q to fn ( We can fix that at the source and give the Q-quant an fnuz path like the KV cache already has (I can look at it later today!) Even with both fnuz (no conversion on either side), flydsl is faster (compared below) so my thinking is that we can still have this PR
I am still polishing this work up but do you think the flydsl kernel improvements for the mono dtype are upstream worthy or do you have other concerns ? 😅 |
976b50f to
138d402
Compare
|
@valarLip I've updated the PR description significantly to give a fuller picture of this work, could you have a second look and advise how you'd like to scope this PR?
Thankful for any insight you can provide here! |
| convert_kv_fn = KV.dtype != _fnuz | ||
| scale_mul = 1.0 | ||
| if convert_q_fn: | ||
| scale_mul *= 2.0 |
There was a problem hiding this comment.
We should add
if arch == "gfx942":
such that we don't accidentally convert FP8-FN on other architectures that support FP8.
There was a problem hiding this comment.
fixed now in 99bd4d3! Thanks
| _fnuz, | ||
| _fn, | ||
| ), f"Q/KV must be e4m3 fp8 (fnuz or fn); got {Q.dtype}, {KV.dtype}" | ||
| convert_q_fn = Q.dtype != _fnuz |
There was a problem hiding this comment.
We need to check
if arch == "gfx942":
to ensure that we don't convert to FP8-FNUZ on other architectures.
This kernel is optimized for gfx942 and while it should run also on other FP8 supported architectures, the performance will probably be suboptimal as the it is not using e.g. async loads that are available in new architectures. At minimum, we should test that the current implementation works on gfx950.
There was a problem hiding this comment.
fixed now in 99bd4d3! Thanks. The decision to claify for others is to gate this kernel for now on gfx942
FlyDSL gfx942 kernel for the DeepSeek lightning indexer (fp8 MQA logits), a drop-in for the Triton fp8_mqa_logits. Includes an adaptive grid.y KV-column split for block-starved small-M/long-context prefill, in-kernel FP8 FN->FNUZ handling, and correctness tests vs the torch and Triton references. Also fixes the Triton fp8_mqa_logits mixed FN/FNUZ path (no-op for fnuz/fnuz inputs). Co-authored-by: Ville Pietilä <Ville.Pietila@amd.com> Co-authored-by: Kristoffer Peyron <Kristoffer.Peyron@amd.com> Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
Co-authored-by: Ville Pietilä <Ville.Pietila@amd.com> Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
99bd4d3 to
079edff
Compare
| WPB = waves_per_block | ||
| MR_BLOCK_THREADS = 64 * WPB | ||
|
|
||
| assert H % 16 == 0, f"num_heads={H} must be a multiple of 16 for MFMA" |
There was a problem hiding this comment.
We should add here named constants
MFMA_M = 16
MFMA_N = 16
MFMA_K = 32
And use those constants in the rest of the code. Now there too many magic number 16 and 32 floating around.
There was a problem hiding this comment.
Yeah made sense! and now addressed in d0d58f0. Added MFMA_M/MFMA_N/MFMA_K and used them for the tile dims everywhere, and renamed the lane_div_16/lane_mod_16 vars to lane_div_N/lane_mod_N to match
Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
vpietila-amd
left a comment
There was a problem hiding this comment.
Reviewed the implementation and the new FlyDSL kernel looks good to me.
|
@valarLip we gathered more results with the new FlyDSL kernel introduced in this PR Outside of DSv4 Flash we also tried replacing the Triton kernel with the FlyDSL counterpart for GLM-5.2-FP8:
TTFT reduction is consistent (18–24%) across concurrency levels Hoping to get your review on this and get this merged as we noticed similar improvements across DS3.2/GLM5.1 as well (happy to provide more results on request!) |
There was a problem hiding this comment.
please refact ut follow this one https://github.com/ROCm/aiter/tree/main/.claude/skills/aiter-op-test
Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
3ad3e13 to
9e8797b
Compare
…3913) * flydsl: add gfx942 fp8 MQA logits indexer kernel FlyDSL gfx942 kernel for the DeepSeek lightning indexer (fp8 MQA logits), a drop-in for the Triton fp8_mqa_logits. Includes an adaptive grid.y KV-column split for block-starved small-M/long-context prefill, in-kernel FP8 FN->FNUZ handling, and correctness tests vs the torch and Triton references. Also fixes the Triton fp8_mqa_logits mixed FN/FNUZ path (no-op for fnuz/fnuz inputs). Co-authored-by: Ville Pietilä <Ville.Pietila@amd.com> Co-authored-by: Kristoffer Peyron <Kristoffer.Peyron@amd.com> Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com> * flydsl: fix i32 index overflow in fp8 MQA logits output write Co-authored-by: Ville Pietilä <Ville.Pietila@amd.com> Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com> * flydsl/triton: gate FN->FNUZ conversion to gfx942 Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com> * flydsl: name MFMA tile-dim constants (MFMA_M/N/K) Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com> * flydsl: refactor fp8_mqa_logits test to aiter-op-test standard Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com> --------- Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com> Co-authored-by: Ville Pietilä <Ville.Pietila@amd.com>
… (#49544) Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
… (vllm-project#49544) Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
… (vllm-project#49544) Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com> Signed-off-by: Wyett <wyettzeng@gmail.com>
… (vllm-project#49544) Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com> Signed-off-by: Zhu, Zufang <zufang.zhu@intel.com>
… (vllm-project#49544) Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com> Signed-off-by: khushali9 <khushali.desai9@gmail.com>
Motivation
DeepSeek-V4 Flash's sparse attention uses a lightning indexer (fp8 MQA logits). This PR adds a FlyDSL gfx942 drop-in for the Triton
fp8_mqa_logitsthat is faster on the DSv4 prefill shapes for both the mono-dtype config (q/k both e4m3fnuz) as well as the currently vllm upstream's mixed config.The uplift does not depend on operand dtype: even with both operands fnuz (no conversion on either side), FlyDSL is 1.5–2.5× faster at the kernel level and cuts end-to-end prefill TTFT by up to 17% at 128K and increases with increasing ctx size.
Technical Details
clean_logitssemantics).fp8_mqa_logitsFN/FNUZ fix by @vpietila-amd; a no-op for fnuz/fnuz, so existing callers are unchanged. This only matters while callers still send mixed q=fn/k=fnuz (see note below); it can be dropped if maintainers prefer the source-side fix only.FlyDSL kernel initially translated from GEAK by @peyron-amd, with perf iterated by myself and @vpietila-amd.
Test Plan
pytest op_tests/flydsl_tests/test_flydsl_fp8_mqa_logits.py— validated against the torch reference and cross-checked vs the Triton kernel (calc_diff < 1e-3): both fp8 dtype combosTest Result
335/335 pass.
Kernel speedup (gfx942, H=64, D=128). FlyDSL wins in both operand configs:
Mixed q=e4m3fn / k=e4m3fnuz (current vLLM behavior):
Mono fnuz/fnuz (the production config; gfx942, H=64, D=128):
End-to-end DeepSeek-V4 Flash TTFT (TP4, MI300-class gfx942, OSL=27, concurrency=1; Triton gfx942 indexer vs FlyDSL, leveraging PR 46730 on vLLM which fixes the mixed dtype):
The E2E gain grows with context length (the indexer logits cost scales with N), which is where prefill latency hurts most.
Note on the mixed FN/FNUZ path (re: @valarLip)
You were right to push on the mixed dtype usage. The mixed q=fn/k=fnuz inputs come from vLLM, not aiter. Currently DSv4-Flash's
fused_indexer_q.pyquantizes Q to e4m3fn while the gfx942 KV cache is fnuz. The proper fix is at the source: vllm-project/vllm#46730 makes Q fnuz so both operands match. The Triton FN/FNUZ fix here is an optional bridge for the current vLLM behavior and can be dropped if you'd rather rely on the source fix.