Repository navigation
[Bugfix][Spec Decode] Build MRV2 draft attention groups with the allocated kernel block sizes - #64707
Closed
ldkhang1201 wants to merge 1 commit into
Closed
ldkhang1201 wants to merge 1 commit into
ldkhang1201 wants to merge 1 commit into
Conversation
…cated kernel block sizes The Model Runner V2 speculator re-picked each KV cache group's kernel block size from the drafter's backends alone. When the drafter shares a group with target layers whose backend supports only smaller kernel pages, the KV cache is allocated and viewed with the target's split pages while draft decode steps 2+ built unsplit block tables, so they read the wrong KV and acceptance after the first draft position collapsed (vllm-project#64652). Pass the runner's kernel block sizes to the speculator, as Model Runner V1 already does for its drafter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Khang Le Duy <ldkhang1201@gmail.com>
ldkhang1201
force-pushed
the
khangl/fix-64652-draft-kernel-block-size
branch
from
October 30, 2026 09:17
4917ff2 to
251af6f
Compare
ldkhang1201
marked this pull request as ready for review
October 30, 2026 09:18
ldkhang1201
requested review from
TheEpicDolphin and
yewentao256
as code owners
October 30, 2026 09:18
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
Fixes #64652. In Model Runner V2, the speculator builds its own attention groups. It picked each KV cache group's kernel block size from the drafter's backends alone, so it can disagree with the kernel pages the KV cache was allocated with. When that happens, draft steps 2+ read the wrong KV. This PR passes the runner's
kernel_block_sizesto the speculator, which is what Model Runner V1 already does for its drafter (gpu_model_runner.py,drafter.initialize_attn_backend(kv_cache_config, kernel_block_sizes)).Claims
--block-size. On the exact config from [Bug]: EAGLE3 draft acceptance collapses after the first position with --block-size > 128 (MiniMax-M3, GB200) #64652 (MiniMax-M3-NVFP4 + EAGLE3,--block-size 512), acceptance length goes from 2.11 to 3.09, matching--block-size 128.mainand passes with this change.Validation
Regression test (
test_qwen3_eagle3_split_kernel_pages_keep_draft_acceptance):AngelSlim/Qwen3-8B_eagle3, targetFLASHINFER, drafterTRITON_ATTN.block_size=128matchesblock_size=64within 0.05.3966924d5(the nightly from [Bug]: EAGLE3 draft acceptance collapses after the first position with --block-size > 128 (MiniMax-M3, GB200) #64652), without and with this patch.Without the fix:
With the fix:
Most of that time is a cold first read of the weights. Each engine takes about 70 s to profile, compile and warm up, plus 5 s of generation.
Serving, same setup, 1x GH200.
/metrics, the method used in [Bug]: EAGLE3 draft acceptance collapses after the first position with --block-size > 128 (MiniMax-M3, GB200) #64652.--block-sizeEach cell shows positions 1 / 2 / 3, with the acceptance length in parentheses.
The configuration from #64652, 1x GB300 (SM103).
335dd77b0nightly with and without this patch;nvidia/MiniMax-M3-NVFP4at9014640, drafterInferact/MiniMax-M3-EAGLE3-GQAat9669248.--tensor-parallel-size 1 --offload-backend uva --cpu-offload-gb 40 --disable-flashinfer-autotune --gpu-memory-utilization 0.95)./metricsmeasurement as above.--block-sizeThe 128 and 512 rows on main match the report (0.78 / 0.60 / 0.45 and 0.82 / 0.15 / 0.02 on GB200 at TP2).
Unit tests. These ran on GH200 against this branch's Python tree and its parent
1fbde73aa1:tests/v1/spec_decode/test_draft_attention_backend_override.pytests/v1/worker/test_gpu_model_runner_v2.pytests/v1/worker/test_attn_utils.pytests/v1/worker/test_gpu_target_dependent_ar_speculator.pyBoth trees: 150 passed.
pre-commit runpasses on the changed files.Details
Root cause
init_attn_backend(..., active_layer_names=<draft layers>)to build metadata only for the groups the drafter uses. [Bugfix][MRV2] Fix KVCache tensor explicitkernel_block_sizedim #42766 later movedprepare_kernel_block_sizesintoinit_attn_backend. So the speculator now votes a kernel block size per group from the drafter's backends only, while the runner votes over all layers and allocates the KV cache with its own result.kernel_block_size, so a disagreement between the two now matters.kernel_block_size.Fix.
init_attn_backendtakes an optionalkernel_block_sizesand skips the vote when given.DraftModelSpeculator.set_attn(with the DFlash and standalone pass-throughs) takes the runner'sself.kernel_block_sizesand forwards it. The runner's vote already includes the draft layers' backends, so every backend in a group supports the chosen size.AttentionGroup.create_metadata_buildersstill narrows it per backend, the same way it does for the runner's groups.CI coverage
tests/v1/e2e/spec_decode/eagle/test_eagle_correctness.py. The-k qwen3_eagle3filter of the H200 step "Spec Decode Eagle 1: DeepSeek + Qwen" selects it, and that step depends onvllm/v1/worker/gpu/spec_decode/.Not a duplicate. No open PR references #64652. #62800 changes FlashInfer's per-layer page vote and padded-page splitting. It does not touch the speculator's separate vote.
AI assistance (Claude Code) was used to investigate, implement and validate this change. The runs above were done on the hardware listed.
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