[Spec Decode] Remove eager metadata rebuild during MTP fused multi-step decode by TheEpicDolphin · Pull Request #58463 · vllm-project/vllm · GitHub
Skip to content

[Spec Decode] Remove eager metadata rebuild during MTP fused multi-step decode - #58463

Merged
ywang96 merged 2 commits into
vllm-project:mainfrom
TheEpicDolphin:optimize-multi-step-decode-fusion
Oct 6, 2026
Merged

ywang96 merged 2 commits into
vllm-project:mainfrom
TheEpicDolphin:optimize-multi-step-decode-fusion

Conversation

@TheEpicDolphin

@TheEpicDolphin TheEpicDolphin commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

Context

#46849 added the infrastructure to fuse last N-1 draft steps into a single cudagraph for models with attention backends that support it. Currently DeepSeek V4 satisfies the conditions to enable this, when using MTP > 1.

This PR

It turns out we can remove the first attention metadata build before drafting the last N-1 speculative tokens in a fused loop. In this PR, I make the necessary changes to DeepseekSparseSWAMetadataBuilder.update_draft_decode_metadata and refactor AutoRegressiveSpeculator so that the first draft metadata build can be safely skipped during FULL cudagraph replay.

With these changes, DSV4 + MTP no longer rebuilds metadata during proposal, resulting in a correctness-preserving removal of about 1ms of host work per decode step. No significant throughput improvement was observed from these changes.

Profile

Captured while serving DeepSeek-V4-Flash + MTP=3 on 4xGB200:
Before
image
After
image

In the decode step above, propose's CPU time shrinks by an entire millisecond.

Benchmarks / Evals

Setup. DeepSeek-V4-Flash, MTP with num_speculative_tokens=3, 4x GB200 (TP4), --block-size 256 --kv-cache-dtype fp8 --moe-backend deep_gemm --no-enable-prefix-caching, VLLM_USE_V2_MODEL_RUNNER=1. Baseline is main at 34b069080d; PR is cfb93dedca. One server per arm; trace, benchmark and eval share it.

Speed-Bench 2K/2K (throughput_16k, low_entropy, temperature 0)

Prompts scaled 8x concurrency (min 16), seed 0. Greedy decoding keeps acceptance deterministic, so ITL p50 is the step-time metric.

Concurrency ITL p50 base (ms) ITL p50 PR (ms) Δ TPOT p50 base (ms) TPOT p50 PR (ms) Output tok/s base Output tok/s PR Δ Accept. len base Accept. len PR
1 8.97 8.97 0.0% 3.41 3.42 290.3 288.3 -0.7% 2.705 2.685
16 19.13 19.15 +0.1% 8.71 8.57 1806.7 1819.4 +0.7% 2.664 2.717
64 22.96 22.96 0.0% 14.52 14.58 4415.5 4380.6 -0.8% 2.693 2.693

Step time is unchanged at every concurrency. The ~1 ms of host work removed per step is not on the critical path for this model at TP4; throughput deltas track the small acceptance-length differences and are within noise.

AIME25 (MQA, 2 epochs x 30 problems, thinking on, temperature 1.0, top-p 0.95, max 98304 tokens, 64 concurrent)

Arm Exact match pass@2 Samples Request errors
base 0.9333 0.9667 60 0
PR 0.9333 0.9333 60 0

Mean accuracy identical. pass@2 differs by one problem in 30, which is expected sampling variance at temperature 1.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@TheEpicDolphin TheEpicDolphin added the ready ONLY add when PR is ready to merge/full CI is needed label Sep 23, 2026
@TheEpicDolphin

Copy link
Copy Markdown
Member Author

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #90794 for commit 66746447d8f6.

@TheEpicDolphin

Copy link
Copy Markdown
Member Author

/ci retry

@github-actions

Copy link
Copy Markdown

✅ Queued 2 failed job(s) for retry in Buildkite CI #90794.

@TheEpicDolphin
TheEpicDolphin force-pushed the optimize-multi-step-decode-fusion branch from 6674644 to e0eaf5a Compare September 24, 2026 04:49
@TheEpicDolphin

Copy link
Copy Markdown
Member Author

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #90856 for commit e0eaf5abff52.

@mergify

mergify Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @TheEpicDolphin.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Oct 5, 2026
@vllm-agent

vllm-agent commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

CI selector (shadow): 51 test steps (93 jobs) instead of 88 (115 jobs)

Shadow mode: this changes nothing about what CI runs. It shows what the evidence-based selector would pick for this PR, next to today's rules. How it works.

Feedback welcome: reply here if it would skip a step this change needs, or runs something unrelated.

steps (jobs) Today's rules Selector Would skip Would add
NVIDIA, CPU and others 88 (115) 51 (93) 57 (65) 20 (43)
AMD mirrors 83 (108) 39 (55) 54 (63) 10 (10)
Selector would run (51)
  • amd-kernels-mi355
  • amd-qwen3-next-mtp-async-eplb-accuracy
  • arm-cpu-test ×3
  • basic-models-tests-extra-initialization ×14
  • basic-models-tests-other
  • cpu-kernel-tests ×2
  • cpu-language-generation-and-pooling-model-tests ×3
  • cpu-multi-modal-model-tests-n ×4
  • cpu-params-env-tokenizers-parser
  • cpu-spec-decode-tests
  • deepseek-v4-kernel-test-b200
  • deepseek-v4-kernel-test-h100
  • distributed-dp-tests-2-gpus
  • distributed-dp-tests-4-gpus
  • distributed-model-tests-2-gpus ×3
  • e2e-core-1-gpu
  • e2e-core-large-memory
  • engine
  • entrypoints-integration-api-server-openai-chat_completion
  • entrypoints-integration-llm
  • examples
  • fusion-and-compile-unit-tests-2xb200
  • hybrid-ssm-nixlconnector-pd-accuracy-tests-4-gpus
  • inkling-unit-tests-b200
  • kernels-attention-test ×7
  • kernels-b200 ×3
  • kernels-flashmla-test-h100
  • kernels-mhc-test-b200
  • kernels-root-misc-test-b200
  • kimi-k3-unit-tests-b200
  • kv-offload-large
  • lm-eval-small-models
  • model-executor
  • multi-modal-models-standard-4-other-whisper
  • multi-modal-processor-cpu ×4
  • pytorch-compilation-passes-unit-tests
  • pytorch-compilation-unit-tests
  • replayssm-e2e
  • spec-decode-draft-model ×4
  • spec-decode-eagle-1-deepseek-qwen
  • spec-decode-eagle-2-llama3-qwen-vl-other
  • spec-decode-mtp-deepseek-mimo
  • spec-decode-mtp-gemma4
  • spec-decode-mtp-qwen3-5
  • spec-decode-speculators
  • v1-attention-b200 ×2
  • v1-attention-h100-mi300 ×2
  • v1-core
  • v1-executor-worker
  • v1-kv-connectors ×4
  • v1-spec-decode
Would skip (today's rules run them) (57)
  • amd-lm-eval-small-models-harness
  • ascend-npu-test
  • async-engine-inputs-utils-worker
  • basic-correctness ×2
  • basic-correctness-cpu-offload
  • basic-correctness-cumem
  • basic-correctness-prefetch-offload
  • basic-correctness-sleep-mode
  • basic-models-test-other-cpu
  • basic-models-tests-initialization
  • batch-invariance-b200
  • batch-invariance-h100
  • benchmarks-cli-test
  • cpu-multimodal-config
  • cpu-reasoning-renderers
  • cpu-tool-parsers
  • distributed-compile-rpc-tests-2-gpus
  • distributed-torchrun-shutdown-tests-2-gpus
  • e2e-scheduling-1-gpu
  • e2e-scheduling-accuracy-1-gpu
  • entrypoints-integration-api-server ×4
  • entrypoints-integration-api-server-generate
  • entrypoints-integration-api-server-openai-completion
  • entrypoints-integration-multimodal
  • entrypoints-integration-pooling
  • entrypoints-integration-responses-api
  • entrypoints-integration-speech_to_text
  • fault-tolerance-e2e-2xh100
  • fusion-e2e-quick-h100
  • fusion-e2e-tp2-ar-rms-dynamo-partition-amd
  • fusion-e2e-tp2-ar-rms-inductor-partition-amd
  • fusion-e2e-tp2-b200
  • fusion-e2e-tp2-quick-h100
  • kernels-fla-ops-test-b200
  • language-models-tests-granite-l4-compatibility
  • language-models-tests-hybrid ×2
  • language-models-tests-standard
  • lm-eval-dspark-watermark-2xh100
  • lm-eval-watermarking
  • metrics-tracing-2-gpus
  • multi-modal-models-standard-1-qwen2
  • multi-modal-models-standard-2-qwen3-gemma
  • multi-modal-models-standard-3-llava-qwen2-vl
  • multi-modal-processor ×4
  • pipeline-context-parallelism-4-gpus
  • pytorch-compilation-dynamic-shapes
  • pytorch-compilation-unit-tests-h100
  • pytorch-fullgraph-cudagraph-l4-compatibility
  • pytorch-fullgraph-test
  • regression
  • rust-frontend-distributed
  • spec-decode-ngram-suffix
  • v1-kv-offload
  • v1-logits-oracle
  • v1-metrics-lmeval
  • v1-others-cpu
  • v1-sample
Would add (today's rules do not run them) (20)
  • amd-kernels-mi355 (code map)
  • arm-cpu-test ×3 (code map)
  • basic-models-tests-extra-initialization ×14 (code map)
  • cpu-kernel-tests ×2 (code map)
  • cpu-multi-modal-model-tests-n ×4 (code map)
  • deepseek-v4-kernel-test-b200 (code map)
  • deepseek-v4-kernel-test-h100 (code map)
  • distributed-dp-tests-4-gpus (code map)
  • distributed-model-tests-2-gpus ×3 (code map)
  • engine (code map)
  • examples (Python record)
  • fusion-and-compile-unit-tests-2xb200 (code map)
  • hybrid-ssm-nixlconnector-pd-accuracy-tests-4-gpus (Python record)
  • inkling-unit-tests-b200 (code map)
  • kernels-b200 ×3 (code map)
  • kernels-flashmla-test-h100 (code map)
  • kimi-k3-unit-tests-b200 (code map)
  • kv-offload-large (Python record)
  • lm-eval-small-models (Python record)
  • model-executor (code map)
AMD mirrors: would skip (54)
  • async-engine-inputs-utils-worker
  • basic-correctness ×2
  • basic-correctness-cpu-offload
  • basic-correctness-cumem
  • basic-correctness-prefetch-offload
  • basic-correctness-sleep-mode
  • basic-models-tests-initialization
  • batch-invariance-h100
  • benchmarks-cli-test
  • distributed-compile-rpc-tests-2-gpus
  • distributed-torchrun-shutdown-tests-2-gpus
  • e2e-core-1-gpu
  • entrypoints-integration-api-server ×4
  • entrypoints-integration-api-server-generate
  • entrypoints-integration-api-server-openai-completion
  • entrypoints-integration-multimodal
  • entrypoints-integration-pooling
  • entrypoints-integration-responses-api
  • entrypoints-integration-speech_to_text
  • extract-hidden-states-integration-2-gpus
  • fault-tolerance-e2e-2xh100
  • fusion-e2e-quick-h100
  • fusion-e2e-tp2-ar-rms-config-sweep-h100
  • fusion-e2e-tp2-b200
  • fusion-e2e-tp2-quick-h100
  • jit-monitor-no-runtime-jit
  • kernels-fla-ops-test-b200
  • language-models-tests-extra-standard ×2
  • language-models-tests-granite-l4-compatibility
  • language-models-tests-hybrid ×2
  • language-models-tests-standard
  • lm-eval-dspark-watermark-2xh100
  • lm-eval-small-models
  • lm-eval-watermarking
  • metrics-tracing-2-gpus
  • mrcr-eval-small-models
  • multi-modal-models-standard-1-qwen2
  • multi-modal-models-standard-2-qwen3-gemma
  • multi-modal-models-standard-3-llava-qwen2-vl
  • multi-modal-processor ×4
  • openai-api-correctness
  • pipeline-context-parallelism-4-gpus
  • platform-tests
  • pytorch-compilation-dynamic-shapes
  • pytorch-compilation-unit-tests-h100
  • pytorch-fullgraph-cudagraph-l4-compatibility
  • pytorch-fullgraph-test
  • quantized-moe-test-b200
  • regression
  • rust-frontend-distributed
  • spec-decode-ngram-suffix
  • v1-kv-offload
  • v1-logits-oracle
  • v1-metrics-lmeval
AMD mirrors: would add (10)
  • deepseek-v4-kernel-test-h100 (code map)
  • distributed-dp-tests-4-gpus (Python record)
  • engine (code map)
  • examples (Python record)
  • hybrid-ssm-nixlconnector-pd-accuracy-tests-4-gpus (Python record)
  • kernels-flashmla-test-h100 (code map)
  • kimi-k3-unit-tests-b200 (code map)
  • kv-offload-large (Python record)
  • model-executor (code map)
  • nixlconnector-pd-spec-decode-acceptance-2-gpus (Python record)

8 changed files · base 74c5cbcd7b · head e95249a280 · Python record: build 92956 at 18c8a65edd · kernel record: table 18c8a65 (build 92956), map 18c8a65 · not counted: 10 build steps, 5 A100 steps the generator no longer emits, 48 optional steps the selector would also run

…ep decode

Signed-off-by: Giancarlo Delfin <gdelfin@inferact.ai>
@TheEpicDolphin
TheEpicDolphin force-pushed the optimize-multi-step-decode-fusion branch from e0eaf5a to 89bb941 Compare October 5, 2026 22:08
@TheEpicDolphin

Copy link
Copy Markdown
Member Author

/ci run

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown

✅ Triggered Buildkite CI #92970 for commit 781af0b382cc.

@mergify mergify Bot removed the needs-rebase label Oct 5, 2026
@TheEpicDolphin
TheEpicDolphin force-pushed the optimize-multi-step-decode-fusion branch from 781af0b to afea33b Compare October 6, 2026 00:59
@TheEpicDolphin
TheEpicDolphin marked this pull request as draft October 6, 2026 01:09
@TheEpicDolphin
TheEpicDolphin force-pushed the optimize-multi-step-decode-fusion branch 2 times, most recently from 9165493 to 1878566 Compare October 6, 2026 01:42
@TheEpicDolphin
TheEpicDolphin marked this pull request as ready for review October 6, 2026 03:53

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@TheEpicDolphin

Copy link
Copy Markdown
Member Author

/ci run

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

✅ Triggered Buildkite CI #93021 for commit 441a24027cf4.

Signed-off-by: Giancarlo Delfin <gdelfin@inferact.ai>
@TheEpicDolphin
TheEpicDolphin force-pushed the optimize-multi-step-decode-fusion branch from 441a240 to e95249a Compare October 6, 2026 05:43
@mergify mergify Bot added the deepseek Related to DeepSeek models label Oct 6, 2026

@ZJY0516 ZJY0516 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ZJY0516

ZJY0516 commented Oct 6, 2026

Copy link
Copy Markdown
Member

/ci run --allow-stale

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deepseek Related to DeepSeek models mrv2 Model Runner V2 specific ready ONLY add when PR is ready to merge/full CI is needed speculative-decoding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants