perf(rocm): MFMA batch-invariant GEMM and chunked Triton attention for strict R/R - #396
Merged
Merged
Conversation
…r strict R/R Replace the scalar-FMA/BF16-K-tree deterministic GEMM on gfx942 with a pinned-order MFMA kernel (rlkernel.det_gemm.triton_mfma_rocm.v1): fixed 16x16x16 bf16 MFMA with kpack=2, BLOCK_K=64 tiles inside 1024-wide K chunks, FP32 chunk partials combined ascending, single BF16 rounding. Every output element depends only on its own row and column, so tile shape, warp count, weight layout, row count and the split-K decode schedule are bit-identical (verified by tests). Selected through RL_KERNEL_DET_GEMM_BACKEND (auto -> MFMA on gfx942, triton_tree keeps the previous contract). Add a chunked-KV flash attention contract for ROCm (rlkernel.rocm.triton_chunked_flash_attention.v1) that serves Megatron full-sequence forward, vLLM prefill, prefix-cached extend and paged decode from one arithmetic path (fixed 64-key blocks inside 512-token chunks with an ascending exact merge), so all four agree bitwise by construction. Opt in with RL_KERNEL_ROCM_ATTENTION_BACKEND=triton; the CK fixed-M128 path stays default. Vime harness: parameterized PR377-workload runner and summary table, proxy variables stripped from Ray arms, GPU_ARCHS pinned for AITER JIT builds, validator accepts the two Triton contracts, decode-step profiler scripts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BunaEZQBLE3hDxHyYcb76V
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Where the strict R/R time went, the MFMA GEMM and chunked attention microbenchmarks, the one-round PR377 workload results for P/P versus both R/R variants, the node-degradation caveat and the remaining gaps. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BunaEZQBLE3hDxHyYcb76V
…96 report Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ms5CP2SrVboniULA1vE8s1
Flink-ddd
changed the base branch from
perf/rocm-fixed-paged-bitwise
to
test
September 9, 2026 15:57
Flink-ddd
marked this pull request as ready for review
September 9, 2026 15:57
Flink-ddd
requested review from
EthanZero2Hero,
KJLdefeated,
bitborne and
inaniloquentee
as code owners
September 9, 2026 15:57
maxiaosong1124
approved these changes
Sep 9, 2026
inaniloquentee
approved these changes
Sep 10, 2026
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.
Stacked on #394 (
perf/rocm-fixed-paged-bitwise). Draft: strict R/R is bitwise consistent, the whole training side beats native, and the end-to-end step is within 4.8% of native on a healthy node; rollout per-token throughput is still 1.75x behind, so this is not yet a net end-to-end win. Numbers and the open items are below.What changes
1. MFMA batch-invariant deterministic GEMM (
rlkernel.det_gemm.triton_mfma_rocm.v1)The gfx942 strict GEMM from #325 used scalar-FMA leaves plus a BF16 K-tree (no matrix cores), which cost 3-30x versus hipBLASLt and dominated every R/R phase.
rl_engine/kernels/ops/triton/matmul/mfma_gemm.pyreplaces it on gfx942:v_mfma_f32_16x16x16_bf16withmatrix_instr_nonkdim=16andkpack=2pinned (both change the in-tile K order, so they are part of the contract).BLOCK_K=64tiles inside fixedCHUNK_K=1024chunks; chunk partials combined ascending in FP32; one BF16 rounding.num_stages, weight layout ([N,K]view or[K,N]prepared), row countM, and the split-K decode schedule are bitwise identical —tests/test_rocm_mfma_gemm.pyasserts this across nine configs, four Qwen3-8B TP4 shapes, sub-batches and strided rows.RL_KERNEL_DET_GEMM_BACKEND=auto|triton_tree|triton_mfma;autoselects MFMA on gfx942, the previous tree contract stays selectable.Reuse survey (asked in the task): vLLM's
VLLM_BATCH_INVARIANTregisters its Triton matmul overrides only for CUDA SM80/XPU (ROCm gets nothing at the aten level and the ROCm attention backends do not claimsupports_batch_invariance), and AITER's Triton GEMMs autotuneBLOCK_Kand use split-K, so neither is reusable as-is; only the fixed-config idea carries over.Microbench (MI300X, per rank TP4 shapes, median):
2. Chunked-KV Triton flash attention (
rlkernel.rocm.triton_chunked_flash_attention.v1)rl_engine/kernels/ops/triton/attention/chunked_flash_attn.pyserves Megatron full-sequence forward, vLLM prefill, prefix-cached extend and single-token paged decode from one arithmetic path: 64-key blocks inside 512-token KV chunks, each chunk's online softmax from an empty state, chunks merged ascending with the exact FA2 rescale, fully masked blocks/chunks leave a row's state untouched, FP contraction disabled. A monolithic (per query tile) and a split (per sequence/kv-head/chunk plus merge) schedule are bit-identical, which is what makes decode agree with training. Mixed decode/extend/prefill vLLM batches go through one launch.tests/test_rocm_triton_chunked_attention.pycovers prefill-vs-decode-vs-extend identity, batch composition, mixed batches, the unmasked fast path and the core binding. Opt in withRL_KERNEL_ROCM_ATTENTION_BACKEND=triton; the #394 CK fixed-M128 path remains the default.3. Harness
examples/vime_rocm_attention_ablation/run_pr377_workload.py(parameterized P/P or R/R arm of the PR377 workload) andsummarize_pr377_runs.py(the consistency/performance tables below).launch_arm.sh/run.py: strip inherited proxy variables (an operator-shell proxy turned every >30 s generation into a 502 retry loop), pinGPU_ARCHSfor AITER JIT builds, forward the two new knobs.benchmarks/profile_rocm_rollout_decode.py+summarize_rollout_trace.pyfor kernel-level decode profiles.Full analysis (where the time went, microbenchmarks, one-round tables, node caveat):
benchmarks/results/pr396_rocm_mi300x/report.md.Results (1 round, PR377 workload: Qwen3-8B, actor TP4/CP2, 2 x TP4 rollout engines, 8 samples, 7168 response, 4096 tokens/GPU, seeds 1234)
Healthy node after host GPU reset (vLLM memory utilization 0.38) — primary numbers
Mean sampled response length was 5255 tokens (P/P) vs 3581 (R/R), so the per-token rollout throughput (93 vs 53 tokens/GPU/s, 1.75x) is the honest measure of the remaining gap, not the 19% rollout-time difference. Against the #394 R/R baseline on a healthy node (round 0: 39 tokens/GPU/s, log probs 25.5 s, actor train 50.1 s, step 183.0 s) this branch is 1.36x faster in rollout throughput and 4.7x faster in actor train.
Same degraded node, same conditions for all three arms (vLLM memory utilization 0.30; see caveat)
Against the #394 R/R baseline on the same workload (round 0: rollout 104.9 s, log probs 25.5 s, actor train 50.1 s, step 183.0 s, measured when the node was healthy), the earlier healthy-node R/R run of this branch gave actor train 11.6 s, log probs 21.0 s, step 169.1 s with 0/33320 mismatches.
Caveat for the degraded-node table. The node had degraded during this work (a native P/P round went from 69 s to 276 s uniformly across phases while single-GPU microbenchmarks stayed unchanged; the driver held GPU contexts of killed vLLM workers). After a host-side GPU reset the primary table above was measured with 8-GPU copy bandwidth 3.8-3.9 TB/s and TP4 all-reduce 1 MB at 43-53 us. The degraded-node relative numbers are same-condition, the absolute ones are inflated for every arm.
Open items before this is a net win
benchmarks/profile_rocm_rollout_decode.py) on the healthy node is the next step to attribute it (GEMM is within 1.3x of hipBLASLt, the attention core is faster than CK).