Skip to content

[Model Runner V2][MTP] Share topk index buffer between draft steps - #47352

Merged
WoosukKwon merged 2 commits into
vllm-project:mainfrom
TheEpicDolphin:mrv2-mtp-topk-index-sharing
Aug 10, 2026
Merged

WoosukKwon merged 2 commits into
vllm-project:mainfrom
TheEpicDolphin:mrv2-mtp-topk-index-sharing

Conversation

@TheEpicDolphin

@TheEpicDolphin TheEpicDolphin commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Context

Deepseek-style topk index selection for MTP has a bug during proposal stage when the topk indices are shared among all MTP draft step forward passes. After the first draft step, set_skip_topk is called on the MTP model to force the remaining draft steps to reuse the same topk indices values (held within topk_indices_buffer of the attention module).

This feature was introduce in #44420 for Model Runner V1.

This PR

Enable this feature for Model Runner V2. I didn't want to leak model-specific optimizations into AutoRegressiveSpeculator, so i introduced a callback pattern. New optimizations/features that need to run at specific points during the propose operation can inherit from this class and override whatever methods are needed.

class AutoRegressiveSpeculatorCallbacks(Protocol):
    def on_prefill_begin(self) -> None: ...
    def on_prefill_end(self, last_token_indices: torch.Tensor) -> None: ...
    def on_multi_step_decode_begin(self) -> None: ...
    def on_multi_step_decode_end(self) -> None: ...

The topk indexer sharing feature registers itself after MTPSpeculator loads its draft model. After determining whether the draft model is a MTP model that can do index sharing AND index sharing is enabled, it is added to the list of callback classes for the auto regressive speculator to call during prefill begin/end and multi step decode begin/end.

Benchmarks

Server

vllm serve nvidia/DeepSeek-V3.2-NVFP4 \
  -tp 4 \
  -O3 \
  --no-enable-prefix-caching \
  --max-num-seqs 64 \
  --kernel-config.enable_flashinfer_autotune=False \
  --speculative_config '{"method":"mtp","num_speculative_tokens":3}' \
  --compilation-config '{"cudagraph_mode": "full_decode_only", "mode": 0}'

Bench

vllm-bench \
    --model $MODEL \
    --backend openai-chat \
    --dataset-name speed-bench \
    --speed-bench-config throughput_16k \
    --speed-bench-max-input-len 10240 \
    --speed-bench-category low_entropy \
    --request-rate inf \
    --max-concurrency 32 \
    --num-prompts 256 \
    --output-len 2048 \
    --ignore-eos \
    --temperature 1.0 \
    --percentile-metrics "ttft,tpot,itl,e2el" \
    --result-dir ~/dev \
    --save-result

Results

Metric topk index sharing = False topk index sharing = True
Request throughput (req/s) 0.80 0.80
Output token throughput (tok/s) 1629.90 1640.71
Total token throughput (tok/s) 9779.42 9844.27
Median TTFT (ms) 608.38 601.95
P90 TTFT (ms) 4206.77 3501.30
Median TPOT (ms) 18.41 18.24
P90 TPOT (ms) 22.15 21.66
Acceptance rate (%) 60.96 60.72
Acceptance length 2.83 2.82
Drafts 185,354 185,828
Draft tokens 556,062 557,484
Accepted tokens 338,992 338,495
Pos 0 (%) 87.45 86.91
Pos 1 (%) 60.10 60.18
Pos 2 (%) 35.34 35.06

@mergify mergify Bot added deepseek Related to DeepSeek models speculative-decoding v1 labels Jul 1, 2026
@TheEpicDolphin
TheEpicDolphin force-pushed the mrv2-mtp-topk-index-sharing branch 4 times, most recently from c3be20b to 6aa8615 Compare July 2, 2026 20:20
@TheEpicDolphin
TheEpicDolphin marked this pull request as ready for review July 2, 2026 20:41

@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.

@WoosukKwon WoosukKwon added the ready ONLY add when PR is ready to merge/full CI is needed label Jul 8, 2026
@mergify mergify Bot added the mrv2 Model Runner V2 specific label Jul 31, 2026
@TheEpicDolphin
TheEpicDolphin force-pushed the mrv2-mtp-topk-index-sharing branch from 974e9f6 to 80c510e Compare August 7, 2026 23:48
Signed-off-by: Giancarlo Delfin <gdelfin@inferact.ai>
@TheEpicDolphin
TheEpicDolphin force-pushed the mrv2-mtp-topk-index-sharing branch from 80c510e to bbdcdb5 Compare August 7, 2026 23:56
@WoosukKwon

Copy link
Copy Markdown
Collaborator

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #83222 for commit b2cae9c53691.

@WoosukKwon
WoosukKwon merged commit 3e174bb into vllm-project:main Aug 10, 2026
7 of 9 checks passed
@TheEpicDolphin
TheEpicDolphin deleted the mrv2-mtp-topk-index-sharing branch August 10, 2026 22:46
justtestingthingsx pushed a commit to meandmyboiclaude/vllm that referenced this pull request Aug 22, 2026
…re-pads an already-padded layer to the shared page (boot AssertionError class); commensurate per-token-bytes zero guard; AR speculator draft-prefill dispatches on num_tokens_padded (restores upstream vllm-project#47352, reverted by carried vllm-project#48244 pick); gemma4_dspark + laguna_dflash fused-KV dtype derived from norm weight + bias cast (fp16 drafters); unpadded() propagates mm_req_doc_ranges; V1 runner zeroes padded-row num_prompt_tokens_cpu (stale-length dummy-row class); fused_recurrent + fused_sigmoid_gating INPLACE_FINAL_STATE load masked to the row (SM-fault class, mirrors vllm-project#50021's sibling bound); profile_cudagraph_memory empty-sample guard; TQ spec head_size_v; packed-codec (kvarn_/turboquant_) branch in _validate_cache_dtype logging; max_page_block_lcm includes padded-to-max layers (PR vllm-project#52804 intent)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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 v1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants