F8 fmha ASM gfx950 - #2911
Conversation
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
|
0a674a6 to
bae1614
Compare
|
@JohnNikolay84 while this was developed in the context of Diffusion Inference on xDiT, I think the testing can be limited to AITER. Your change to aiter/ops/mha.py makes it so your ASM gets selected in the MHA fp8 path, right? In that case op_tests/test_mha_fp8.py is now expected to jump from 1200 TFlops to 2000 TFlops on mi355. If you can paste those logs, I'd consider that enough. |
|
python3 op_tests/test_mha_fp8.py -b 1 -n 5 -q 75600 -d 128 |
|
Thanks! Here is a plot of the long-context TFlops (per head) for @valarLip et al |
|
@JohnNikolay84 Thanks for the effort. To clarify: is this kernel limited to MHA with hd128, or might it be extended to other head dimensions in the future? |
|
@yichiche what other head dimensions do you have in mind? hd192 might be trivial since Sergey derived his MHA from the persistent fp8 MLA. However our focus is diffusion models where hd128 is typically enough |
|
@jcaraban While running Wan 2.2 end-to-end, I hit a segmentation fault. In this model, both self-attention (where Q/K/V share the same sequence length) and cross-attention go through the MHA path. The crash occurs in cross-attention with Minimal repro (CLI)cd /sgl-workspace/aiter_mha_fp8/aiter
python3 op_tests/test_mha_fp8.py -b 1 -n 40 -q 90000 -k 512 -d 128
[aiter] import [module_aiter_core] under /sgl-workspace/aiter_mha_fp8/aiter/aiter/jit/module_aiter_core.so
[aiter] import [module_fmha_v3_fwd] under /sgl-workspace/aiter_mha_fp8/aiter/aiter/jit/module_fmha_v3_fwd.so
[aiter] type hints mismatch, override to --> fmha_v3_fwd(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor, dropout_p: float, softmax_scale: float, is_causal: bool, window_size_left: int, window_size_right: int, return_softmax_lse: bool, return_dropout_randval: bool, how_v3_bf16_cvt: int, out: Optional[torch.Tensor] = None, bias: Optional[torch.Tensor] = None, alibi_slopes: Optional[torch.Tensor] = None, q_descale: Optional[torch.Tensor] = None, k_descale: Optional[torch.Tensor] = None, v_descale: Optional[torch.Tensor] = None, gen: Optional[torch.Generator] = None) -> List[torch.Tensor]
[aiter] hipModuleLoad: /sgl-workspace/aiter_mha_fp8/aiter/hsa//gfx950/fmha_v3_fwd/fwd_hd128_fp8.co GetFunction: _ZN5aiter24fmha_fwd_hd128_fp8_gfx950E
[aiter] hipModuleGetFunction: _ZN5aiter24fmha_fwd_hd128_fp8_gfx950E Success
Memory access fault by GPU node-2 (Agent handle: 0x5592cecab380) on address 0x7f1c01000000. Reason: Unknown.
|
|
Thanks for the minimal repro 👍 The crash seems constrained to cross attention (K != Q) and Heads 2, 4, 8, 10, 20, 40... however it doesn't crash for H 1, 3, 5, 6, 7, 9... |
|
@yichiche thank you for the report. Great catch. The issue should be fixed now. |
Hi, may I follow up the status of this PR? When will merge it? |
|
@valarLip do you have any ,comments/objections about this PR? |
|
looks really good |
Commit c437cca dropped fwd_hd128_fp8_group.co and fwd_hd128_fp8_causal_group.co from hsa/gfx950/fmha_v3_fwd/fmha_fwd.csv. The gfx950 FP8 varlen ASM kernels will be re-added later; for now route those calls through CK by tightening can_impl_fmha_v3_fwd in flash_attn_varlen_fp8_pertensor_func's path. The condition is gated on get_gfx() == "gfx950" so gfx942 keeps using its own ASM group kernels. Without this change, dropping the gfx950 CSV rows alone would cause RuntimeError: invalid argument for fmha_v3_varlen_fwd: the dispatcher in module_fmha_v3_varlen_fwd is built with FAV3_ON=1 only (no FAV2_ON), so the in-module CK fallback in cpp_itfs/mha_fwd.cu is compiled out and a CSV miss propagates as -1 to the TORCH_CHECK in asm_mha_varlen_fwd. Verified with op_tests/test_mha_varlen_fp8.py for both causal and non-causal at b=2,n=32,nk=32,q=k=1024,d=128 on gfx950: no fp8_*_group.co LoadKernel attempts, output max_diff within tolerance. Fixed-shape FP8 (mha_fwd) is unaffected -- fwd_hd128_fp8.co and fwd_hd128_fp8_causal.co remain in the CSV and still picked by ASM. Co-authored-by: Cursor <cursoragent@cursor.com>
54ec0e8 to
425b2aa
Compare
* mla with hd128 * Fix GPU fault * Fix register clobbing bug in s_load * Fix a bug in group causal attention kernel * Fix GPU fault * Remove broken varlen variants * Route FP8 varlen MHA on gfx950 to CK; ASM group will land later Commit c437cca dropped fwd_hd128_fp8_group.co and fwd_hd128_fp8_causal_group.co from hsa/gfx950/fmha_v3_fwd/fmha_fwd.csv. The gfx950 FP8 varlen ASM kernels will be re-added later; for now route those calls through CK by tightening can_impl_fmha_v3_fwd in flash_attn_varlen_fp8_pertensor_func's path. The condition is gated on get_gfx() == "gfx950" so gfx942 keeps using its own ASM group kernels. Without this change, dropping the gfx950 CSV rows alone would cause RuntimeError: invalid argument for fmha_v3_varlen_fwd: the dispatcher in module_fmha_v3_varlen_fwd is built with FAV3_ON=1 only (no FAV2_ON), so the in-module CK fallback in cpp_itfs/mha_fwd.cu is compiled out and a CSV miss propagates as -1 to the TORCH_CHECK in asm_mha_varlen_fwd. Verified with op_tests/test_mha_varlen_fp8.py for both causal and non-causal at b=2,n=32,nk=32,q=k=1024,d=128 on gfx950: no fp8_*_group.co LoadKernel attempts, output max_diff within tolerance. Fixed-shape FP8 (mha_fwd) is unaffected -- fwd_hd128_fp8.co and fwd_hd128_fp8_causal.co remain in the CSV and still picked by ASM. Co-authored-by: Cursor <cursoragent@cursor.com> * Reintroduce group mode kernels --------- Co-authored-by: Sergey Solo <ssolovye@amd.com> Co-authored-by: Cursor <cursoragent@cursor.com>
The gfx950 tg_div=1 override (from PR #2911) applied to all dtypes, but only the FP8 ASM kernel needs it. The bf16 ASM kernels support causal tile-skipping and should use tg_div=2 for causal masks. Guard the tg_div=1 override with data_type=="fp8bf16" so bf16 causal launches half the grid. Also halve the FLOP count for causal in the C++ benchmark to align with the standard TFLOPS convention.



Motivation
There is no f8 fmha ASM kernel for gfx950, despite a similar kernel exists for gfx942.
Diffusion model spend 60-70% flops just in attention, so f8 can gives even 25% e2e improvement over bf16.
Technical Details
I used MLA ASM kernel for hd192 and reworked it as a pure fmha with hd128. In the end of the day it is not that hard as it is essentially fmha and mfma is 32x32x64 which is perfectly compatible with hd128 too.
Test Plan
Test Result
The improvement is 60->45s. No noticeable artifacts.
wan22_i2v_14b_fp8_aiter_mla-mha_fp8_gemms_hybrid_aiter_2steps_staging.mp4
Submission Checklist