[gfx950] Retune the small-M tiles and wave counts in the A16W16 fallback config - #4781
Open
akii96 wants to merge 2 commits into
Open
[gfx950] Retune the small-M tiles and wave counts in the A16W16 fallback config#4781akii96 wants to merge 2 commits into
akii96 wants to merge 2 commits into
Conversation
BLOCK_SIZE_M=32 overshoots the bucket's own M=16 bound, wasting half of every MFMA tile and forcing the masked address-wrapping path. Setting BM/BN to 16 is 1.796x weighted over the 34 affected rows with no regression, and is bit-identical since only M/N tiling changes. Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
Contributor
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
|
Wave count should track tile size, and it stops doing so in the middle of this table. M_LEQ_32 computes a 32x32 tile with four waves and M_LEQ_64 a 64x32 tile with four, while every bucket from M_LEQ_128 up already uses eight. These are skinny bandwidth-bound GEMMs, so four waves do not cover the memory latency. M_LEQ_8 BLOCK_SIZE_N 32 -> 16, num_warps 4 -> 8 1.83x weighted, min 1.10x M_LEQ_32 num_warps 4 -> 8 1.98x weighted, min 1.14x M_LEQ_64 num_warps 4 -> 8 1.18x weighted, min 1.09x Weighted over the measurable gfx950 bf16 shapes in each bucket (49, 34 and 10), with no shape in any bucket regressing. Measured on one gfx950 with CUDA-graph replay, arms interleaved within each pass, median of seven passes. M_LEQ_8 also takes a narrower N tile because it is the bucket that serves every M from 1 to 8 -- the table has no M_LEQ_1 or M_LEQ_4 key -- so it carries the low-concurrency decode shapes. Doubling its waves alone is worth more in aggregate (2.05x) but costs 4-5% near N=4096/K=512, and halving N recovers those while keeping most of the gain. M_LEQ_16 and M_LEQ_128 were measured the same way and are left alone: both lose to a doubled wave count (0.79x and 0.85x), the 16x16 and 64x64 tiles already being matched to their waves. Halving N does not transfer above M_LEQ_8 either, costing 0.41x at M_LEQ_32. Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
Contributor
Author
|
@azaidy validated this PR alone on on 4x MI355X (gfx950) with Image: Before the said Additional fix mentioned above, server startup fails during graph capture. Performance
Serving commandexport VLLM_USE_BREAKABLE_CUDAGRAPH=1
export VLLM_ROCM_USE_AITER=1
export VLLM_ROCM_USE_AITER_MOE=1
export VLLM_ROCM_USE_AITER_UNIFIED_ATTENTION=1
export VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS=1
export VLLM_ROCM_QUICK_REDUCE_QUANTIZATION=INT4
export VLLM_WORKER_MULTIPROC_METHOD=spawn
export SAFETENSORS_FAST_GPU=1
vllm serve amd/MiniMax-M3-MXFP4 \
--tensor-parallel-size 4 \
--distributed-executor-backend mp \
--trust-remote-code \
--block-size 128 \
--no-enable-prefix-caching \
--language-model-only \
--max-model-len 133120 \
--gpu-memory-utilization 0.95 \
--max-num-batched-tokens 32768 \
--max-num-seqs 128 \
--enable-chunked-prefill \
--async-scheduling \
--attention-backend ROCM_AITER_UNIFIED_ATTN \
--moe-backend aiter \
--tool-call-parser minimax_m3 \
--enable-auto-tool-choice \
--reasoning-parser minimax_m3 \
--no-enable-log-requests |
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.
What this changes
M_LEQ_8BLOCK_SIZE_N32 → 16,num_warps4 → 8M_LEQ_16BLOCK_SIZE_MandBLOCK_SIZE_N32 → 16M_LEQ_32num_warps4 → 8M_LEQ_64num_warps4 → 8Why
Two problems in the same table.
The
M_LEQ_16tile overshoots its own bucket. It only handles M of 16 or smaller, but the tile was sized for 32 rows, so half of every tile did no useful work and the kernel took a slower path for leftover rows that were not really there.Wave count stops tracking tile size in the middle of the table.
M_LEQ_32computes a 32x32 tile with four waves andM_LEQ_64a 64x32 tile with four, while every bucket fromM_LEQ_128up already uses eight. These are skinny bandwidth-bound GEMMs, and four waves cannot cover the memory latency.M_LEQ_8has both problems, and matters more than its name suggests: the table has noM_LEQ_1orM_LEQ_4key, so every M from 1 to 8 resolves to it.Numbers
Weighted over every measurable gfx950 bf16 shape in each bucket. Nothing regresses.
M_LEQ_8M_LEQ_16M_LEQ_32M_LEQ_64Accuracy
Bit for bit identical.
BLOCK_SIZE_Nandnum_warpschange how a tile is partitioned across waves, not the order any output element accumulates over K, andNUM_KSPLITstays at 1. Verified withtorch.equalagainst the shipped config on all 93 shapes: zero differ.