[Test][Scheduler] Regression coverage for multi-module MTP prefill-lookahead chunking - #53506
AnkitNakhawa wants to merge 1 commit into
Conversation
…daries No existing test exercises `num_prefill_lookahead > 1`, the regime that `_reserve_prefill_lookahead` (scheduler.py) only enters for multi-module MTP (num_speculative_tokens > 1 with a multi-layer draft config). Add a regression test verifying a lookahead-shortened first chunk and the following chunk still cover the whole prompt with no gap or overlap. Part of the investigation into vllm-project#53488 (prompt_logprobs corrupted under MTP speculative decoding). This test confirms the scheduler's chunk bookkeeping itself is not the cause; root-causing the actual corruption needs a GPU + a real multi-layer MTP checkpoint to reproduce against. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Ankit Nakhawa <ankitnakhawa@gmail.com>
|
Reporter of #53488 here. Your coverage finding stands on its own, but I think one of your ruled-out candidates was scoped to the wrong buffer, and I have a measurement that discriminates between your remaining hypothesis and the fix that has since been proposed. On timing, not awareness: your dup check was correct when you ran it. You opened this at 2026-08-24T03:26Z; @hoobnn cross-referenced #53520 onto the issue at 04:31Z, an hour later. So #53520 ("Fix prompt_logprobs corruption from CUDA graph output buffer reuse by padded drafter") may simply postdate your search. The buffer you ruled out is not the buffer #53520 fixes. You wrote:
That is correct about the speculator's private hidden-states buffer. #53520 is about a different object: the CUDA graph output buffer that the padded drafter writes over. A negative result on the first does not exclude the second — and I think that is why your remaining hypothesis points one layer too high (at A discriminator, from the runs I did while validating #53520 on Jetson AGX Thor (sm110a, aarch64): Every corrupted row I have runs with CUDA graphs on. Two earlier speculative K=3 rows that were run with I want to be precise about how much that carries: those eager rows are not strict single-variable controls — they also differ in kernel path (triton vs the fused CUDA path) and were built on a different day, so I record them as corroboration, not proof. What does not depend on that caveat is the scheduler-side reasoning: Two more data points pointing the same way:
One caveat I want to state rather than let you infer: I did not run a knob-isolating experiment to establish which setting fixes the number at 512. In this configuration Your test is not made redundant by #53520. The gap you found is real and orthogonal: Offer: you mention you lack a GPU with a real multi-layer MTP checkpoint. I have that — Jetson AGX Thor (sm110a) and a GB10, with three Qwen3.8-27B checkpoints (NVFP4 ModelOpt, NVFP4 compressed-tensors, W4A16) and the scoring harness from the issue. Root-causing may be moot now, but if it is useful I am happy to run your test on top of #53520's head and report back, or to re-run any specific configuration you want to see. Disclosure: this analysis was done with AI assistance; the runs, the hardware and the numbers above are real and reproducible, and the account owner reviewed the content before posting. Raw artifacts available on request. |
|
Clarification on my earlier comment, and one new measurement that bears on the root cause. Clarification. I wrote "… New measurement. I have since run the single-variable experiment I owed on my earlier claim, and it lands on the CUDA-graph side rather than the scheduler side. Same box, same image, same unpatched
The boundary moved from 512│513 to 256│257, tracking the capture limit exactly, while That is consistent with the graph-replay mechanism and, I think, with why the lookahead-chunking hypothesis did not pan out: the scheduler-side bookkeeping you verified is correct, and the corruption is downstream of it. Your coverage gap is still real and still unfilled by #53520 — it just isn't where this particular bug lives. Offer stands: if it is useful I can run your test on top of #53520's current head ( Disclosure: this analysis and the runs behind it were done with AI assistance; the hardware, the runs and the numbers are real and reproducible, and the account owner reviewed the content before posting. |
What this is
Investigation into #53488 (
prompt_logprobscorrupted for some requests under MTP speculative decoding). This is not a fix — it's a checkpoint: a regression test that closes a real coverage gap found while root-causing the issue, opened as draft while I continue reproducing on a GPU with a real multi-layer MTP checkpoint.What I found
Scheduler._reserve_prefill_lookaheadonly does real work whennum_prefill_lookahead > 1, which only happens for multi-module MTP (num_speculative_tokens > 1with a multi-layer draft config) — exactly the reporter's config (num_speculative_tokens=3).num_prefill_lookahead > 1; the two closest tests (test_mamba_align_eagle_schedules_encoder_at_boundary, one other) hardcode1. So this lookahead-shortened-chunk regime is entirely untested.draft_slotsbudget subtraction (max_num_new_slots_for_drafting) is provably0for plainmethod="mtp"— it can't be shrinking this request's budget.vllm/v1/worker/gpu/spec_decode/multi_module_mtp/speculator.py) uses its own private hidden-states buffer, not the base model's — no shared-buffer clobber.num_computed_tokensprogression across a lookahead-shortened chunk) is also correct.So the corruption most likely lives in how
_get_prompt_logprobs_dict(or the V2 runner'scompute_prompt_logprobs_with_chunking) reads hidden states for a chunk shaped by this lookahead reservation — but confirming the exact line needs a real GPU run against a multi-layer MTP checkpoint, which I don't have in this environment.Test plan
Duplicate check
gh issue view 53488 --repo vllm-project/vllm --commentsandgh pr list --repo vllm-project/vllm --state open --search "53488 in:body"— no open PR addresses this issue yet.AI assistance
Investigation and this test were written with AI assistance (Claude). I've reviewed the diff and reasoning above myself; I'm continuing the GPU-side root-cause work before this is ready for review.