Repository navigation
[ROCm][Perf][DSv4.1] Mono decode for the DSpark draft layers - #62131
Merged
Merged
Conversation
The DSpark draft's three layers are DeepseekV4DecoderLayers with window-only attention, so the mono K1 / K2 serve them with four differences, all in the build or the step's integers: - their routing: 128 routed experts, top-3 (the MoE stage already takes ``MoeBuild(experts, topk, ug_groups)``); - their SWA index rows: the block's non-causal rows, 192 wide on V4.1-Flash (the key table reads the row width from the build); - the first layer takes the embedding already broadcast to the hc copies; - a runner of their own (its epoch, scratch and peer buffers), since the scratch layout depends on the experts. They follow ``--monokernel``, as the target's layers do. Target builds are unchanged: their kernels' ISA is identical to main's. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Fangzhou Ai <fangzhou.ai@amd.com>
Fangzhou-Ai
marked this pull request as ready for review
October 17, 2026 19:59
Fangzhou-Ai
requested review from
AndreasKaratzas,
DarkLight1337,
dllehr-amd,
hongxiayang,
tjtanaa and
ywang96
as code owners
October 17, 2026 19:59
Collaborator
Author
|
/ci run |
|
✅ Triggered Buildkite CI #95619 for commit |
ChuanLi1101
approved these changes
Oct 17, 2026
ChuanLi1101
left a comment
Collaborator
There was a problem hiding this comment.
LGTM. The draft's three layers drop from about 640 us to 227 us a step. On the same build, GSM8K and the acceptance length stay flat.
The AgentX ITL p50 is against a different node and nightly, so I am not counting that 0.030 ms as this PR's gain.
shen-shanshan
approved these changes
Oct 19, 2026
shen-shanshan
left a comment
Contributor
There was a problem hiding this comment.
Reviewed by @ChuanLi1101
maeehart
added a commit
to maeehart/vllm
that referenced
this pull request
Oct 19, 2026
main now has vllm-project#62131, which runs the DSpark draft layers whole on gfx950 on a runner of their own. It conflicted with this branch in mono_decode.py, mono/layer.py, mono/runner.py and the model test. Both sides are kept: - On gfx950 the draft layers run as vllm-project#62131 runs them. - On gfx942 the draft layers keep the FFN launch after vLLM's attention, on the target's runner. The draft routing comes from the config, as in vllm-project#62131, and the test config now carries it. - run_ffn reads the target's scratch layout in the FFN launch, because that launch runs on the target's runner. K2 reads the layout of its own runner. Signed-off-by: Markus Hartikainen <markus.hartikainen@amd.com> Co-authored-by: Cursor <cursoragent@cursor.com>
maeehart
added a commit
to maeehart/vllm
that referenced
this pull request
Oct 19, 2026
…groups The DSpark draft's runner (vllm-project#62131) builds its MoE with one FP4 group an ug task (DRAFT_UG_GROUPS), but its scratch was laid out for the default two. With one group a task the ug flags take twice the room. So the flags of the upper half of the tasks were written past their region, over the start of the normed rows that the MoE reads as its input, at TP 2 and 4 and for every step width. scratch_layout and scratch_bytes now take the runner's ug_groups, and K1, K2 and the runner pass it. The target's layout does not change. run_ffn checks that each MoE region of a build fits the layout, and that check stopped the build of the draft runner's K2. Signed-off-by: Markus Hartikainen <markus.hartikainen@amd.com> Co-authored-by: Cursor <cursoragent@cursor.com>
6 tasks done
edwingao28
added a commit
to SemiAnalysisAI/InferenceX
that referenced
this pull request
Oct 20, 2026
…de on the latest ROCm nightly / [AMD][MI355X] DSv4.1 Flash vLLM:在最新 ROCm nightly 上以草稿模型 mono decode 重新测试 (#4319) * dsv41flash mi355x vllm: move to the e68efc68 ROCm nightly with draft mono decode Update dsv41flash-fp4-mi355x-vllm-agentic-dspark to vllm/vllm-openai-rocm:nightly-e68efc685ab1e6f1eda004ced7157e3ca411da2f (pinned by digest), the 2026-10-19 nightly. ROCm 10.0 is now the default nightly build, so the tag drops the rocm100 prefix. The image carries vllm-project/vllm#62131, which runs the DSpark draft layers on the mono decode kernels under --monokernel. Recipe and search space are unchanged. 将 dsv41flash-fp4-mi355x-vllm-agentic-dspark 更新到 vllm/vllm-openai-rocm:nightly-e68efc685ab1e6f1eda004ced7157e3ca411da2f (以 digest 固定),即 2026-10-19 的 nightly。ROCm 10.0 现为默认 nightly 构建,因此标签不再带 rocm100 前缀。该镜像包含 vllm-project/vllm#62131, 在 --monokernel 下让 DSpark 草稿层也走 mono decode 内核。配方与搜索空间不变。 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * perf-changelog: link #4319 perf-changelog:关联 #4319 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * perf-changelog: restore other entries' placeholder pr-links perf-changelog:恢复其他条目的占位 pr-link Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: Chun Fang <chun.fang@amd.com> Co-authored-by: Wenyao Gao <wenyao.gao28@gmail.com>
3 of 5 tasks
tpopp
added a commit
to tpopp/vllm
that referenced
this pull request
Oct 23, 2026
…the stock front/head runtime/draft.py: DraftDecode, the MTP drafter's own executor, built and bound the same way the target's is (--monokernel; no switch of its own). This commit's draft step runs the stock embedding branch (plain torch: pre_fc_norm_embedding/hidden, fc_embedding/fc_hidden, the residual add) and the proposer's own greedy-token path; only the decoder layer's hyper- connection fronts and blocks are on the kernels. Reuses Mikko Tukiainen's generic launches for the draft decoder layer -- front.hc_front for both hyper-connections' mixes, blocks.oproj_block, blocks.moe_block and the final mixer's front -- since the draft layer's shapes match the target's exactly; "QSA attention stays stock" (unmodified, its own test suite covers it). Its own epoch, health, scratch and peer buffers (DSv4.1's drafter precedent, vllm-project#62131): a mailbox word must never be a tag to one launch and data to another, so the drafter's mailbox is never the target's. Default-deny config refusals (draft_unsupported) share the target's parallelism / feature / platform checks and add MTP-only and the draft model's own shape; model-stage refusals (model_reasons) check the loaded draft layer's modules and weight layouts, same as the target's. vllm/models/qwen4_exp/amd/mtp.py: wires DraftDecode into Qwen4ExpMTP -- init at __init__ (the config check, before any weight loads), build/refusal-check in process_weights_after_loading (the loader's generic post-load hook, so no core change is needed), run in forward, and the fail-stop watch in compute_logits. get_top_tokens (the fused draft head) is not added yet. Tests: - tests/models/qwen4_exp/amd_specialized_decode/test_runtime.py (CPU): the drafter's config refusals and widths, SimpleNamespace configs, no FlyDSL import (draft.py keeps mono.* / runtime.layers imports local to DraftDecode's own methods for exactly this reason). - tests/.../test_kernels.py (GPU, two ranks, S in 1/3/8): the stock-front draft step's whole launch sequence -- the attention HC front, a fixed random (core, gate) standing in for QSA (out of scope here), the o_proj block, the MLP HC front, the MoE block, the final mixer's front (its down zero-padded from LORA to layout.DOWN_ROWS rows) -- each stage checked against the same stock-ops references the individual block tests use (GatedResidual.mix, the HC combine math, the MoE emulation), a port of md-int's test_amd_mono_draft.py::test_draft_step_matches_vllm_ops onto the split package's materialized-state API (no scratch-buffer peeking needed: oproj_block / moe_block hand back the next state directly). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Tres Popp <tres.popp@amd.com>
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.
Overview
DSv4.1-Flash mono decode (MI355X,
--monokernel): the DSpark draft's three layers now run on the mono K1 / K2 kernels too, as ATOM'sDraftMonoRunnerdoes, instead of vLLM's per-op path. Follow-up to #60397 and #61082; they follow--monokernellike the target's layers, with no new switch. Overlaps files with #60731 (gfx942 port), so whichever merges second needs a rebase.Claims
--monokernel, at TP4 (1.646 against 1.678 ms) and at TP2 (1.970 against 2.000 ms).main's.Validation
All on MI355X, DeepSeek-V4.1-Flash, the InferenceX #3690 recipe,
mainatce49c47cbbplus this PR unless a row says otherwise. "Off" is the same build with the draft layers on vLLM's path (a throwaway env switch for the A/B, not in this PR).Layer level. The draft layers against the original layers on real eager decode steps (TP4 c1 and TP2 c1, 5- and 10-row steps), same inputs: x output cosine >= 0.99975 (relative L2 up to 2.3%, the MoE's top-3 routing near-ties), residual, post / comb / pre mixes >= 0.9999 cosine.
Acceptance and accuracy (real block rejection, GSM8K as in InferenceX's DSv4.1-Flash eval: custom
gsm8ktask, chat, 5-shot multiturn,max_tokens12288, 64 requests in flight, full 1,319):AgentX, c1, 3,600 s (InferenceX's
infx.bench agenticclient, the #3690 recipe with--monokernel, DSpark with synthetic acceptance 3.51, the Rust frontend). Reference: InferenceX's run 38377181342 (same recipe, nightly 5555a2d, its own node). TP4 and TP2 ran at the same time on one node. The confidence intervals are bootstrap over the per-request ITL of the profiling phase (about 330 requests an arm).The p50 gain is outside the noise at both TP sizes; the p90 interactivity gain (+4.0% and +6.1%) is not (its interval spans zero), and the TTFT difference is the node, not this PR (prefill is untouched). The reference is not a same-node baseline, so the p50 difference also includes any difference of node, image and commit; an earlier run on the same node of
mainplus only #61934's change (a different kernel change) gave ITL p50 1.670 / 2.000 ms (per-request 1.675 / 1.998).Kernel time (graph-mode torch profile, TP4 c1, draft on mono): K1 about 20 us and K2 about 56 us a layer for the three draft layers (227 us a step); the non-target kernels of a step total 1.76 ms against 2.17 ms with the draft off (excluding all-reduce spin-waits).
Tests.
tests/models/test_dsv41_mono_decode.py: 41 pass, 3 new (the draft layer takes the mono path on its own runner, its first layer takes the broadcast embedding, a layer takes only its own SWA row width). The K1 / K2 ISA of the target builds at TP4, M=6 is identical tomain's (FLYDSL_DUMP_IRdiff: 0 lines).Accuracy (RFC #59665 protocol, as in #60397: thinking on,
reasoning_efforthigh, temperature 0.6, top-p 0.95, 8 requests in flight a server, DSpark with block rejection,--monokernelso the draft layers run on mono; pass@1, ± is the standard error across questions). The baselines are #60397's numbers; no reference arm of this build was rerun.AIME25's wrong samples: 8 of 480 at TP2 (3 empty, out of the 64K budget; 4 on one hard problem) and 3 of 240 at TP4 (1 empty).
RULER NIAH (lm-eval, prefix-free chat copies, thinking on, greedy, 40 samples a cell):
niah_single_1,niah_multikey_2andniah_multikey_3at 32K, 128K and 256K score 40/40 in every cell at both TP2 and TP4, as in #60397.Details
The draft layers are
DeepseekV4DecoderLayers with window-only attention (compress ratio 0, no indexer), so the kernels need no new stage. What differs is carried by the build and the step's integers:dspark_n_routed_experts/dspark_num_experts_per_tok) and one FP4 group per ug task.MoeBuildalready took these;MonoBuildnow carriesexperts,topk,ug_groupsandswa_widthinto the MoE stage and the scratch layout.get_dspark_swa_index_width(window, num_speculative_tokens)wide (192 for window 128 and 5 drafts). K1's key-table stage read the row width as the constant 128; it reads it from the build now.[rows, hc, dim]; K1 takes it as the settled residual (fold=False), as for the target's layer 0.DSV41MonoLayer(epoch, scratch, peer buffers) as in ATOM. Every rank creates it at the same layer of the same eager step, like the target's.Target builds are unchanged: every new field defaults to the target's value, the kernel symbols gain no suffix for them, and the ISA diff above is empty.
Limitations: MI355X (CDNA4), TP2 / TP4, steps of at most 48 rows (the draft's are 5 per request, so up to 8 requests); the layer comparison is on eager steps only. The draft's remaining per-step cost is outside its layers:
_prepare_dflash_inputs(3 launches of 113 us), the six skinny head GEMMs (279 us), and about 75 small elementwise and copy kernels. I found no open PR doing this. Developed and measured with Claude Code; the submitter's line-by-line review is still pending.Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.
🤖 Generated with Claude Code