ggml-cuda: MoE MMQ tile sizing + D=256 flash-attn tuning on RDNA3.5#35
Open
roberteg16 wants to merge 3 commits into
Open
ggml-cuda: MoE MMQ tile sizing + D=256 flash-attn tuning on RDNA3.5#35roberteg16 wants to merge 3 commits into
roberteg16 wants to merge 3 commits into
Conversation
For MUL_MAT_ID, choose the tile width from ~2x the average tokens-per-expert (ncols_dst/nchannels_y) instead of ncols_max, so the common per-expert tiles are filled instead of mostly empty at mmq_x=128. Assisted-by: Claude Opus 4 (1M context)
Route D=256 GQA attention to the mma-f16 kernel and allow its AMD_WMMA path up to DKQ=256. On RDNA the kernel still runs on WMMA instructions, and it packs ncols2 GQA heads into a full 16-wide tile that the wmma kernel leaves mostly empty. Assisted-by: Claude Opus 4 (1M context)
With rocWMMA FlashAttention off, D=256 prefill runs on the tile kernel. Add an RDNA3.5 config that overrides the D=256, ncols=32 row with a smaller K tile and higher occupancy (nbatch_K 128->64, occupancy 3->4); other cases fall back to the shared RDNA table. Selection is matched on host (cc) and device (RDNA3_5 macro). Assisted-by: Claude Opus 4 (1M context)
dc6c3fd to
080392f
Compare
|
Nice wins! Can we split the PR to have each of the changes in its own PR? |
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.
ggml-cuda: MoE MMQ tile sizing + D=256 flash-attn tuning on RDNA3.5
Branch:
rogarcia.mmq-moe-fattn(base:gfx11@ 4b5ac96)Target: gfx1151 (Radeon 8060S, Strix Halo, RDNA3.5)
Build: Release,
GGML_HIP=ON,GGML_HIP_ROCWMMA_FATTN=OFF,GGML_HIP_ROOFLINE=OFF.What this changes
Three prefill kernel-selection/config fixes for the HIP backend. All change which kernel/tile/launch is used, not the math, so outputs are bit-identical to the baseline.
Size the MMQ tile to MoE tokens-per-expert (
mmq.cuh). ForMUL_MAT_IDthe tile width was minimized overncols_max(worst case = all tokens routed to one expert), landing onmmq_x=128. In practice each expert receives~ncols_dst/nchannels_ytokens (e.g. ~16 at pp512), so each 128-wide tile was ~1/8 full and the weight load dominated. The selection now derives the tile width from ~2x the average tokens-per-expert; batch-adaptive (large batches converge back to 128).Route D=256 GQA attention to the mma-f16 kernel (
fattn.cu,fattn-mma-f16.cuh). Raises the AMD_WMMA DKQ cap from 128 to 256 and routes D=256 to the mma-f16 kernel (packingncols2GQA heads into a full 16-wide tile). Decode (Q->ne[1] <= 2) still uses the vector kernel. NOTE: only takes effect inROCWMMA_FATTN=ONbuilds - see the flash-attn section below.Tune the D=256 tile flash-attn config for RDNA3.5 (
fattn-tile.cuh). WithROCWMMA_FATTN=OFF(the fastest and intended build), D=256 prefill runs on the tile kernel. Adds an RDNA3.5-specific config that overrides theD=256, ncols=32row (nbatch_K128->64,occupancy3->4); all other head sizes / ncols fall back to the shared RDNA table. Mirrors the MMQ device-table pattern; selection is matched on host (GGML_CUDA_CC_IS_RDNA3_5) and device (RDNA3_5macro) so the__launch_bounds__stay consistent with the host launch params.Measured results (llama-bench, -fa 1, f16 KV, -ngl 999, -r 5, ROCWMMA_FATTN=OFF)
A/B by hot-swapping
libggml-hip.so(gfx11 baseline vs this branch), interleaved per model (baseline run first / slightly cooler, so gains are conservative).End-to-end latency (ms; derived tokens / t/s). e2e* = 4096 prefill + 128 decode
TTFT at context depth 4096 (Qwen3.6-35B-A3B, -p 4096 -n 128 -d 4096 -r 10)
Reading the results
ROCWMMA_FATTN=OFF(it lives behind a gate that is compiled out), so it shows ~0% in the tables above. It is a large win inROCWMMA_FATTN=ONbuilds, growing with context length - see the dedicated section below.Flash-attn commit: motivating config is GGML_HIP_ROCWMMA_FATTN=ON
The D=256 routing lives inside the
ggml_cuda_should_use_wmma_fattn(cc)branch ofggml_cuda_get_best_fattn_kernel. That helper returnsfalsewheneverGGML_HIP_ROCWMMA_FATTNis not compiled in, so withROCWMMA_FATTN=OFFthe whole branch (and this commit's routing) is never reached - which is why the tables above show the FA change as a no-op. The commit exists to fix the ON build: there, RDNA3.5 D=256 GQA attention is dispatched to the rocWMMA kernel, which is badly underutilized, and this reroutes it to the mma-f16 kernel.To prove the flash-attn commit helps on its own (independent of the MoE tile fix), an FA-only lib was built (
gfx11+ only commit 47beebe,mmq.cuhuntouched) and swept against depth on Qwen3.6-35B-A3B,ROCWMMA_FATTN=ON,-p 512 -n 0 -r 5. Attention's share of prefill grows with context depth, so the D=256 kernel choice dominates as depth increases:TTFT at the
p4096 d4096point (prompt = 4096 / t/s x 1000):So the flash-attn commit is a large, clean win within
ROCWMMA_FATTN=ONbuilds and scales with context length. It is inert (harmless) inROCWMMA_FATTN=OFF.But ON + this commit is still not faster than OFF
Comparing the branch (FA commit present in both) across build flags on Qwen3.6-35B-A3B shows
ONis equal-to-slower thanOFF, progressively so at depth:Reason (
ggml_cuda_get_best_fattn_kernel, gfx1151): withOFF, D=256 skips the wmma branch and falls through toBEST_FATTN_KERNEL_TILE; withON, this commit selectsmma-f16. On this APU the tile kernel beats mma-f16 for D=256, more so at long context. Ordering: OFF (tile) > ON + this commit (mma-f16) >> ON baseline (rocWMMA).RDNA3.5 tile flash-attn config (the OFF-path win)
Since
ROCWMMA_FATTN=OFFis the fastest build, the highest-value lever is the tile kernel it uses for D=256 prefill. Its per-arch config table (fattn-tile.cuh,ggml_cuda_fattn_tile_get_config_amd_rdna) is shared across all RDNA GPUs and was not tuned for gfx1151. For a D=256 long prefill the launcher lands on thencols=32row, whose fields are(nthreads, occupancy, nbatch_fa, nbatch_K).Swept on Qwen3.6-35B-A3B (
-p 512 -n 0, deep context where attention dominates):nbatch_K128->64 andoccupancy3->4 are the wins;nbatch_fa=64andnthreads=256are already optimal. Confirmed A/B (interleaved, upstream RDNA row256,3,64,128vs tuned256,4,64,64):The gain scales with context length (attention-bound) and is ~0 at shallow context - no regression. Verified again after wiring the RDNA3.5 branch (default build): +7.1% d16384, +6.0% d32768. Only D=256/ncols=32 on RDNA3.5 changes; every other GPU, head size, and ncols falls back unchanged. Output is bit-identical (launch/tiling only). Scope left for follow-up: the D=256
ncols=16/8rows (short prompts / other GQA packings) still fall back to the shared RDNA values.Recommendation
OFF) path itself, +6-7% on long-context D=256 prefill, with no downside - keep it.ROCWMMA_FATTN=ONbuilds from the rocWMMA kernel; it does not make ON beat OFF. If the shipped build isOFF, it is a safety net at best - keep it solely to protect ON builds, but do not sell it as a net speedup over the OFF default.Caveats
ppNt/s swing run-to-run (see largepp128stddevs). Decode (tgN) is stable to ~1%.Qwen3.5-*stand in for the requestedQwen3-*); several requested models were absent.