Skip to content

[ROCm] FlyDSL paged MQA-logits kernel for the sparse indexer - #14

Open
amd-sriram wants to merge 2 commits into
mainfrom
rocm/flydsl-paged-mqa-logits-nextn
Open

amd-sriram wants to merge 2 commits into
mainfrom
rocm/flydsl-paged-mqa-logits-nextn

Conversation

@amd-sriram

Copy link
Copy Markdown
Owner

Depends on ROCm/aiter#4221 (FlyDSL paged MLA indexer, gfx950).

What this does

  1. Routes the gfx950 branch of rocm_fp8_paged_mqa_logits at aiter's FlyDSL
    paged (decode) MQA-logits kernel when
    VLLM_ROCM_USE_AITER_FLYDSL_PAGED_MQA_LOGITS is set. Off by default while
    [Feature]: Multi-node serving vllm-project/vllm#4221 is unmerged, and any aiter without the PR falls back to Gluon.
  2. Passes the kernel one context length per sequence.

Why (2) is needed

The kernel takes context_lens of shape (B,) and derives each Q row's causal
bound itself as col <= context_len - next_n + row. vLLM instead precomputes
those bounds and passes (B, next_n) (indexer.py, native spec decode) or
(B, 1) otherwise. The kernel's context_lens.reshape(batch_size) therefore
raised for any next_n > 1. The last column of the vLLM tensor is the
per-sequence length in both layouts, so that is what gets passed.

Interaction with the next_n cap

At num_speculative_tokens >= 2 the indexer flattens decode on ROCm and this
kernel is called at next_n = 1 regardless. #13 lifts that cap.
Both are needed to exercise vllm-project#4221 above next_n = 2.

Not yet verified

  • No GPU run since the rebase onto current main.
  • No accuracy run. This kernel decides which KV columns the sparse attention
    keeps, so gsm8k/niah/gpqa are still outstanding.

The decode half of the sparse-attention indexer runs on aiter's Triton/Gluon
deepgemm_fp8_paged_mqa_logits. ROCm/aiter#4221 adds a gfx950 FlyDSL
implementation of the same kernel, reported at 1.3-4.2x over Gluon on MI355X,
and the decode logits are the indexer's dominant per-step cost at long
context.

Route the gfx950 branch of rocm_fp8_paged_mqa_logits at it when
VLLM_ROCM_USE_AITER_FLYDSL_PAGED_MQA_LOGITS is set, so one build can run both
arms and any aiter without the PR falls back to the existing path. Off by
default while the PR is unmerged.

This is a second call site rather than the module swap used for the prefill
kernel in the preceding commit. The two launchers take the same tensors in
the same order, but the FlyDSL one's remaining knobs are keyword-only with
its own tuned defaults, so sharing a caller would mean forcing the Gluon
ChunkK=256 on it. KVBlockSize is not optional: the kernel asserts it against
the KV cache's own block dimension, so it is passed through along with
Preshuffle, exactly as the Gluon call does.

The FlyDSL path skips the -inf prefill the kernel's docstring asks for. That
request is for a caller that reads the whole row; this one does not. FlyDSL
writes every column up to its causal bound `context_lens[b] - next_n + n` and
nothing past it (`is_writer = ... & (col <= q_limit)`), and that bound is the
decode top-k's read bound, so the tail the fill would cover is never written
and never read.

The sanitize is kept, and is the same bounded sanitize_decode_logits() the
Gluon path calls. Its window is that same causal bound, so it covers exactly
the columns FlyDSL wrote: no more work than the Gluon path already does, and
both paths hand the top-k a workspace in the same state. Keeping it means the
flag toggles the kernel and nothing else, which is what makes the two arms
comparable.

The FlyDSL kernel is written against gfx950, so
_flydsl_paged_mqa_logits_kernel() returns None on every other architecture
and the Triton/Gluon kernel is used regardless of the flag.

Signed-off-by: Sriram Kumar <sriramkumar.kishorekumar@amd.com>
…ts kernel

vLLM hands the indexer (B, next_n) per-row causal bounds; the kernel takes one length per sequence, so next_n > 1 raised on the reshape.

Signed-off-by: Sriram Kumar <sriramkumar.kishorekumar@amd.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant