Repository navigation
[ROCm] Calibrate gfx950 decode Top-K routing by rows × compressed-context - #57844
nehaprakriya wants to merge 1 commit into
Conversation
…text
The existing _get_aiter_top_k_kernel() gate for the C4A (k=1024) path used
a fixed max_valid_seq_len threshold of 64K against the passed sequence length.
This threshold was miscalibrated in two ways:
1. Under CUDAGraphMode.FULL the call site passes max_model_len (typically
1M tokens) instead of the live compressed length, making the condition
always true and routing every FULL-graph decode step to native regardless
of actual context length.
2. Even with the correct live length, the one-dimensional 64K threshold is
too conservative. Measured on gfx950 (MI350X): AITER is faster than
native at C32 (192 verification rows) for live compressed contexts up to
262K tokens — well above the old 64K cutoff.
Replace the single threshold with a two-dimensional (rows, live_ctx) policy
calibrated on MI350X. Native is preserved for FULL-graph replay (max_model_len
does not match any policy entry, giving the same safe outcome as before but
for the correct reason). The DSV4.1 (topk=512, k<=384 rows) early-return
introduced upstream is preserved unchanged.
Calibration (gfx950, nightly-eed1f3d0c6, Top-K 512, logits width 524288):
20/20 correct policy decisions across rows x {32K,65K,131K,262K,524K} grid.
C32 operating grid (192 rows, live_ctx <= 262K): 1.39x aggregate speedup.
End-to-end on MI350X TP4, DeepSeek-V4.1-Flash FP4, AgentX C32, DURATION=600s:
Output throughput: 236.70 vs 237.96 tok/s/chip (-0.53%, within noise band)
p90 interactivity: 36.78 vs 34.46 tok/s/user (+6.75%, outside noise band)
The throughput delta is within the measured ±0.79% run-to-run spread.
The p90 interactivity gain is well outside the ±1.7% secondary band.
FULL-graph steps (majority at high concurrency) conservatively retain native;
the gain comes from PIECEWISE steps where live context is available.
Co-Authored-By: Claude <noreply@anthropic.com>
|
👋 Hi! Thank you for contributing to the vLLM project. 💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in PRs do not trigger a full CI run by default. Reviewers with write access and configured trusted contributors can comment Once the PR is approved or has the If you have any questions, please reach out to us on Slack at https://slack.vllm.ai. Agent GuidelinesIMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban. 🚀 |
|
This pull request has merge conflicts that must be resolved before it can be |
Purpose
Fix a miscalibrated kernel routing gate in
_get_aiter_top_k_kernel()(vllm/v1/attention/ops/rocm_aiter_mla_sparse.py) that causes the AITERtop_k_per_row_decodekernel to be bypassed in favor of native on gfx950, even when AITER is measurably faster.Two bugs in the existing gate:
Bug 1 — FULL-graph replay always forces native. The call site passes
max_model_len(1 048 576) instead of the live compressed sequence length underCUDAGraphMode.FULL. The conditionmax_valid_seq_len > _GFX950_C4A_AITER_MAX_COMPRESSED_SEQ_LENevaluates to1 048 576 > 65 536 = Truefor every FULL-graph decode step, unconditionally routing to native.Bug 2 — The 64 K threshold is wrong even with the correct live length. Measured on gfx950 (MI350X): AITER is 1.08–2.08× faster than native at C32 (192 verification rows) for live compressed contexts up to 262 144 tokens. The 64 K cutoff forces native for any context above 64 K, including the typical long-context operating point (50 K–300 K tokens).
This PR replaces the one-dimensional
max_valid_seq_len > 64Kgate with a two-dimensional(rows, live_compressed_ctx)policy calibrated on gfx950. Native is preserved conservatively forCUDAGraphMode.FULL(where live context is unavailable at replay time).Test Plan
Policy correctness (no GPU required):
Full suite on gfx950/gfx942:
Tests cover:
rows ∈ {48, 96, 192, 384}×live_ctx ∈ {32 K, 65 K, 131 K, 262 K, 524 K})CUDAGraphMode.FULLalways returns native (live_ctx=None)requires_rocm_cdna3_or_newer)Test Result
Kernel-level calibration — gfx950 MI350X,
nightly-eed1f3d0c6Method: graph-captured weakest-of-5, 200-iteration GPU clock warmup,
logits_width = 524 288,Top-K = 512. Bitwise index-set correctness verified before timing accepted.Context sweep at C32 (192 rows):
Full 20-shape policy validation:
End-to-end — MI350X 4-chip TP4, DeepSeek-V4.1-Flash FP4
Workload: AgentX agentic-coding trace replay, concurrency 32, DSpark depth 5,
DURATION=600 s. Run-to-run noise: ±0.79% throughput, ±1.7% p90 interactivity.Throughput −0.53% is within the ±0.79% noise band. p90 interactivity +6.75% is well outside the ±1.7% band. The gain is concentrated in the slow tail (requests with moderate context hitting native unnecessarily); full-context requests are unchanged.
Why throughput is not positive:
CUDAGraphMode.FULLsteps (majority at high concurrency) conservatively retain native — live context is absent from the graph replay key. The p90 gain comes fromPIECEWISEsteps. Extending the policy to FULL graphs by bucketinglive_compressed_ctxinto the capture key is a follow-on.Essential Elements of an Effective PR Description Checklist
supported_models.mdandexamplesfor a new model.