You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[BugFix](pcp): align decode classification with vLLM reorder logic (vllm-project#10580)
## What this PR does / why we need it?
With PCP enabled and speculative decoding (e.g. MTP),
`PCPManager.init_batch_info()` previously marked a request as decode
whenever `num_scheduled_tokens <= decode_threshold`. That is
insufficient for chunked prefill: a request can still be prefilling
while scheduling only a small token chunk (≤ `mtp + 1`), and it would be
misclassified as decode.
Misclassified requests were routed through the PCP **decode** attention
path with inconsistent metadata (e.g. `actual_seq_lengths_q` vs local
`Q_S`), which triggered `aclnnFusedInferAttentionScoreV3` failures
(error `561002`).
This PR aligns PCP decode/prefill classification with upstream vLLM
`reorder_batch_to_split_decodes_and_prefills`:
- Add `classify_decode_request_mask()` in `attention/utils.py`. A
request is treated as decode only if it has context
(`num_computed_tokens > 0`), is below the decode threshold, and has
finished prefilling (`num_computed_tokens >= num_prompt_tokens`).
- Update `PCPManager.init_batch_info()` to use this mask instead of a
scheduled-token threshold alone, and pass `num_computed_tokens` /
`num_prompt_tokens` from model runners.
- Extend `split_decodes_and_prefills()`:
- Default `treat_short_extends_as_decodes=False`, so short extends are
prefills by default.
- Honor `is_prefilling` when short extends are not treated as decodes.
- Add a `num_reqs == 0` guard and PyTorch tensor input support in
`classify_decode_request_mask()`.
- Set `is_prefilling` in spec-decode graph-capture dummy-run paths
(`llm_base_proposer`, `dflash_proposer`) to avoid startup assertion
failures.
- Correct stale E2E golden outputs in `test_accuracy.py` for DSV2 PCP
and Qwen3 PCP/DCP cases after re-verifying greedy outputs on NPU.
## Does this PR introduce any user-facing change?
No API or configuration changes. This is a bug fix for PCP + speculative
decoding workloads, especially with chunked prefill.
Users who previously hit decode/prefill misclassification and NPU
attention kernel errors should see correct routing and stable inference.
Behavior for true decode batches is unchanged.
## How was this patch tested?
**Unit tests**
- Added `test_split_decodes_short_extend_with_default_false` in
`tests/ut/worker/test_pcp_manager.py` to verify short extends with
`is_prefilling=True` are classified as prefills when
`decode_threshold=4` (MTP scenario).
- Updated existing PCP manager tests to pass `num_computed_tokens` and
`num_prompt_tokens` into `init_batch_info`.
**Manual reproduction**
- Reproduced the original failure with PCP + MTP + chunked prefill
(short prefill chunk misrouted to decode kernel).
- Verified the fix routes those chunks through the prefill path and
inference completes without `aclnnFusedInferAttentionScoreV3` error
`561002`.
**E2E**
- Re-ran four-card CP accuracy tests on NPU and updated
`DSV2_PCP_GOLDEN` / `QWEN3_GOLDEN` to match verified greedy outputs.
DeepSeek-V3.1-Terminus-w8a8-mtp-QuaRot test result
| dataset | version | metric | mode | vllm-api-stream-chat |
|----- | ----- | ----- | ----- | -----|
| gsm8k | d486ce | accuracy | gen | 94.20 |
Qwen3-30B-A3B-W8A8 test result
| dataset | version | metric | mode | vllm-api-stream-chat |
|----- | ----- | ----- | ----- | -----|
| gsm8k | d486ce | accuracy | gen | 92.80 |
**CI**
- Existing unit tests and lint checks.
- vLLM version: v0.22.1
- vLLM main:
vllm-project/vllm@967c5c3
---------
Signed-off-by: recky-c <ruiqicheng510@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
0 commit comments