Repository navigation
Conversation
chuyeh
force-pushed
the
feat/rocm-smallm-fp8-blockscale-gemm
branch
from
October 2, 2026 14:47
2e39384 to
e3eddae
Compare
This was referenced Oct 2, 2026
chuyeh
force-pushed
the
feat/rocm-smallm-fp8-blockscale-gemm
branch
from
October 4, 2026 07:14
e3eddae to
d0bab1b
Compare
…-scale GEMM At decode-sized M the aiter per-1x128 quant + CK blockscale GEMM pair is two launch-bound kernels; one bandwidth-bound kernel over the preshuffled weight cuts Qwen3.5-397B-A17B-FP8 TP4 step time ~10% at bs1 and ~6% at bs4. Co-authored-by: Cursor <cursoragent@cursor.com>
chuyeh
force-pushed
the
feat/rocm-smallm-fp8-blockscale-gemm
branch
from
October 7, 2026 03:54
d0bab1b to
d9d4318
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
chuyeh
marked this pull request as ready for review
October 7, 2026 13:50
chuyeh
requested review from
Alisehen,
AniZpZ,
BBuf,
DarkSharpness,
Edwardf0t1,
FlamingoPg,
HaiShaw,
HydraQYH,
OrangeRedeng,
b8zhong,
celve,
ch-wan,
mmangkad and
yuan-luo
as code owners
October 7, 2026 13:50
Collaborator
|
@chuyeh
|
Skip the gfx950-only test when the AITER bpreshuffle path is unavailable instead of failing during its lazy imports.
This comment was marked as resolved.
This comment was marked as resolved.
This branch has not been deployed
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.
Motivation
On MI355X, Qwen3.5-397B-A17B-FP8 decode at concurrency 1 spends 1.6 to 1.7 ms per cycle in dense FP8 projections. EAGLE with four draft tokens runs a projection at 4 to 32 tokens per rank for concurrency 1 to 8. Each projection currently launches two latency-bound kernels, taking about 4 µs and 9 µs.
This PR fuses them into one HIP kernel for M ≤ 32; larger inputs retain the AITER path.
Modifications
New
python/sglang/kernels/ops/gemm/smallm_fp8_blockscale_gfx950/(__init__.py,smallm_fp8_blockscale_gemm.hip): built withhipccon first use and launched through ctypes with the helpers ofsmallm_moe_gfx950([AMD] Small-M MXFP4 fused-MoE kernel for gfx950 (Qwen) #40204), no build-time or wheel change.Each wave loads bf16 activations and quantizes them to fp8 in registers (1x128 groups, row amax via lane shuffles),
reproducing AITER's per-group scale and fp8 bytes exactly. It streams the AITER (16, 16)-preshuffled FP8 weight
once with non-temporal loads, runs one
v_mfma_scale_f32_16x16x128_f8f6f4per 128-wide K block, appliesx_scale * w_scalein fp32, and reduces across waves through LDS to a bf16 output.Uses the existing weight layout and
weight_scale_inv([N/128, K/128]fp32), so loading and preprocessing areuntouched.
Dispatch table (Qwen3.5-397B-A17B TP4 shapes), first matching M bucket wins:
in_proj_qkvzqkv_projout_proj, attentiono_projfp8_utils.py: one guarded call inaiter_w8a8_block_fp8_linear, taken on the gfx950 bpreshuffle path (HIP ≥ 7.2)with no
input_scale(input not pre-quantized) and no bias, whensmallm_fp8_bs_supportedaccepts a bf16 inputwith 16-byte aligned rows, a weight marked
is_shuffled, a contiguous[N/128, K/128]weight scale, a shape/M inthe table, and not under
torch.compile. Everything else is unchanged. Other TP sizes have different shapes andkeep the current path.
On by default on gfx950;
SGLANG_ROCM_SMALLM_FP8_BS=0turns it off.Registered AMD unit test
test/registered/amd/test_smallm_fp8_blockscale_gfx950.py: matches AITER quant + GEMM(rel 2e-2) at M = 1 / 3 / 4 / 8 / 9 / 16 / 17 / 24 / 32 on all three shapes, quant bit-exact against
aiter_per1x128_quant, fallback for M = 33 / fp16 / an unaligned row stride / an unshuffled weight / the offswitch, graph replay == eager. Passes on
v0.5.20-rocm720-mi35x-20260927.Accuracy Tests
All runs use image
rocm/sgl-dev:v0.5.20-rocm720-mi35x-20260927, InferenceX recipe flags with real draft acceptance,sglang.test.few_shot_gsm8k, 1319 questions.--max-running-requests 8keeps every verify pass at 32 tokens orfewer, so all dense FP8 projections take the new kernel. "main" is the image's tree (main at
a0ba1968b1); baselineis the same tree with
SGLANG_ROCM_SMALLM_FP8_BS=0.Qwen/Qwen3.5-397B-A17B-FP8TP4One run's standard error at 1319 questions is about 0.006.
Benchmarking and Profiling
Kernel microbenchmarks
MI355X, one GPU, CUDA graph replay, weights rotated over 24 copies so they are not cache resident. AITER
aiter_per1x128_quant+gemm_a8w8_blockscale_bpreshuffle(tuned Qwen3.5 config) vs this kernel, in µs:in_proj_qkvz5120 x 4096qkv_proj4608 x 4096out_proj/o_proj4096 x 2048Max relative difference to AITER over all points is 3.1e-3; the quantized activations are bit-exact.
Decode step time
Time for one EAGLE draft + verify cycle at a fixed batch size. MI355X TP4, image
rocm/sgl-dev:v0.5.20-rocm720-mi35x-20260927, InferenceX recipe flags (FP8 KV cache, EAGLE 3 / 1 / 4 with simulatedacceptance 3.39). Mean of two runs with the GPU sets swapped, in ms:
AgentX benchmark
Qwen/Qwen3.5-397B-A17B-FP8with the InferenceX recipeqwen3.5-fp8-mi355x-sglang-agentic,image
rocm/sgl-dev:v0.5.20-rocm720-mi35x-20260927.CUDA graph batch at 2x concurrency.
aiperf profile --scenario inferencex-agentx-mvponsemianalysis_cc_traces_weka_062126_256k, 3600 s per run.Concurrency 1:
Concurrency 4:
Concurrency 8:
Each EAGLE verify pass sends 4 tokens per running request through every projection, so the kernel covers running
batches of 8 or fewer. The running batch never exceeded 8 in these runs, so every decode step took the kernel. The
kernel does not run in prefill.
Checklist
CI States
Latest PR Test (Base): ✅ Run #37760502231
Latest PR Test (Extra): ❌ Run #37760501789
Latest PR Test (AMD ROCm 10): ❌ Run #37760502073