Repository navigation
Conversation
akii96
force-pushed
the
feat/rocm-flydsl-prefill-attention
branch
from
August 22, 2026 10:44
03c9345 to
705d705
Compare
Adds ROCM_FLYDSL_ATTN, which runs causal prefill on the FlyDSL DUALWAVE_SWP gfx950 kernel and serves everything else, decode included, with the AITER unified attention kernel it subclasses. It shares the parent's KV cache shape, metadata builder and cache-update path, so the two are interchangeable without re-laying-out the cache. Enable with VLLM_ROCM_USE_FLYDSL_PREFILL_ATTN=1, which moves the backend to the front of the preference order; an explicit --attention-backend works without it. The attention kernels are not in the flydsl wheel, so VLLM_FLYDSL_KERNELS_PATH must point at a FlyDSL checkout. The kernel beats AITER on prefill-shaped batches but not everywhere, so dispatch is gated on four shape terms: q-block occupancy, a minimum context length, the number of single-token rows in the batch, and the causal q-block ordering flag. Each is a host-side shape fact, so one shape traces one launch sequence and the decision is fixed for a CUDA graph capture key. The constants carry their measurements. On MI350X the gated range is 1.09x to 1.79x against AITER over 44 shapes, with no shape admitted below 1.0x. End to end on MiniMax-M3-MXFP4 at TP=4, output token throughput improves 35.6% at 60k/600 concurrency 16 and 9.6% at 8k/1k concurrency 64, and is unchanged on decode-bound 1k/1k. gsm8k 5-shot is unchanged at 0.940. Signed-off-by: Aakif Nawaz <aakif.nawaz@amd.com>
akii96
force-pushed
the
feat/rocm-flydsl-prefill-attention
branch
from
August 22, 2026 10:53
705d705 to
803e082
Compare
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.
Important
Needs ROCm/FlyDSL#1056 merged first, and then picked up by the flydsl install that ships with aiter. Until that lands the backend has no kernel to call.
Motivation
On ROCm the attention kernel that serves long prompts is the same one that serves single token decode steps. Those two jobs want different things: a long prompt has plenty of work to spread across the GPU, while a decode step has almost none and mostly waits on memory. Using one kernel for both gives up throughput on the prompt side.
FlyDSL has a gfx950 kernel built for the prompt side. It is meaningfully faster there and much slower on decode, so it is not a drop in replacement. What is missing is a way to use it only where it wins.
Technical Details
Adds
ROCM_FLYDSL_DUALWAVE_ATTN, which sends causal prefill batches to the FlyDSL dualwave kernel and lets everything else, decode included, fall through to the AITER unified attention kernel it subclasses. It reuses the parent's KV cache layout, metadata builder and cache update path, so the two are interchangeable without touching the cache.The name says dualwave because FlyDSL also ships MLA decode, fp8 and MoE kernels, and this backend is specifically the gfx950 dualwave prefill path.
Which batches go to FlyDSL is decided per batch from the batch shape alone, through four checks:
Every term is a host side shape fact, so one shape always traces one launch sequence and the decision stays fixed for a CUDA graph capture key.
num_decode_rowsis derived fromquery_start_loc_cpualongside the existingnum_short_query_rows, sharing one numpy diff, so there is no device read and no sync.Enable with
VLLM_ROCM_USE_FLYDSL_DUALWAVE_PREFILL_ATTN=1, or select it directly with--attention-backend ROCM_FLYDSL_DUALWAVE_ATTN. The kernels are not in the flydsl wheel, soVLLM_FLYDSL_KERNELS_PATHpoints at a FlyDSL checkout.Test Plan
Unit tests in
tests/v1/attention/test_rocm_flydsl_attn_dispatch.pyreplay measured shapes through the dispatch rules and assert the faster kernel is chosen for each.Then an A/B against a server running only AITER UA, same model and flags on both arms, on
amd/MiniMax-M3-MXFP4at TP=4 with 133k max model len. Low and high concurrency across three ISL/OSL points, followed by gsm8k on each arm.Test Result
Output token throughput, mean TPOT, mean TTFT:
The 8k runs are flat by design. At 8k a scheduler step is one chunk plus more decode rows than the cap allows, so those batches fall back and both arms run the same code. Kernel level, admitting them measures 0.92x.
The one TTFT regression, 32k/1k C32, is a scheduling artefact of
ISL == --max-num-batched-tokens. At 32768 both, the scheduler fits exactly one prefill per step with no slack, so prefills serialise and TTFT is set by queue position rather than prefill speed. Varying only that flag, with the same workload and backend:At 16384 this config beats the AITER baseline on every metric: throughput +15.2%, mean TTFT -24.4%, median TTFT -37.2%, median E2EL -14.4%.
gsm8k, full set, 8 shot:
Reproduction
Both arms use the same flags; only
--attention-backenddiffers. Drop the two FlyDSL env vars and set--attention-backend ROCM_AITER_UNIFIED_ATTNfor the baseline arm.Sweep, per ISL/OSL and concurrency:
gsm8k:
TO-DO
The gsm8k difference is 1.4 points at a stderr of about 0.006, measured once per arm. Comparing the two arms token by token on the same prompts, 80 percent of answers diverge somewhere but only 6 percent of those change the final answer, and the divergences sit at a median logprob margin of 0.25 with a quarter of them at exactly zero. That points at near tie tokens being re-rolled rather than reasoning degrading. But need to investigate this over multiple runs so listing this as a to-do item