Repository navigation
[Perf][Spec Decode] Sharded greedy verification and fused vocab-parallel draft argmax - #62604
Closed
jiacao-amd wants to merge 3 commits into
Closed
jiacao-amd wants to merge 3 commits into
jiacao-amd wants to merge 3 commits into
Conversation
… fused draft argmax Greedy EAGLE verification currently all-gathers the full-vocabulary target logits across TP ranks before taking the argmax. Instead, each rank reduces its own vocabulary shard to compact per-block (max, index) statistics, only those are all-gathered, and one fused kernel finishes the global argmax, acceptance (including synthetic acceptance), bonus token and sampled/rejected counts. The draft side similarly takes the argmax over compact rank-major partials of the stock BF16 LM head instead of gathering full-vocabulary logits. Both paths are opt-in (MM3_SHARDED_GREEDY_VERIFY_EXPERIMENT, MM3_FUSED_DRAFT_ARGMAX_EXPERIMENT) and currently limited to the measured MiniMax-M3 TP4 greedy EAGLE3 configuration on ROCm; every other case keeps the native path. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: jiacao-amd <jiahui.cao@amd.com>
Drop the MiniMax-M3/TP4/K=3 restrictions and the model-private hooks: - Models opt in through compute_logits_local, the hook batch-sharded sampling already uses (added to the ROCm MiniMax-M3 model, matching the NVIDIA one). Any TP size > 1, vocabulary size < 2**24, hidden size and number of speculative tokens; CUDA and ROCm. - Gate with VLLM_SHARDED_GREEDY_VERIFY in vllm/envs.py. - Per step, fall back to the native path unless every request is greedy with no logits processing, logprobs, structured output, draft logits, adaptive/block verification or watermarking. - Non-power-of-two TP sizes and shards narrower than a vocabulary block. - Remove the fused draft argmax: the existing speculative_config.use_local_argmax_reduction covers the draft side (Eagle3 Llama drafts already implement get_top_tokens). - Unit tests emulate TP2/3/4/8 in one process and compare against rejection_sample on the full logits, including synthetic acceptance, prefilling and placeholder drafts, bf16 and planted cross-shard ties, and vocabulary padding. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: jiacao-amd <jiahui.cao@amd.com>
get_top_tokens (speculative_config.use_local_argmax_reduction) masked the padding in place, reduced with torch, stacked the (value, id) pairs and all-gathered them along the last dim. Replace that with two Triton kernels: per-tile (max, id) partials over the real vocabulary columns of the shard, an all-gather along dim 0, and a merge. Ties resolve to the lowest id and NaN wins, as with torch.argmax on the full logits. This restores the draft side of the measured MiniMax-M3 gain that the model-specific fused draft argmax provided. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: jiacao-amd <jiahui.cao@amd.com>
Contributor
Author
|
Closing for now. The target workload for this work is the InferenceX AgenticX benchmark, which sends no sampling parameters, so requests use the model's |
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.
Purpose
With a vocab-parallel LM head, greedy speculative decoding all-gathers the full-vocabulary logits across TP ranks: on the target side before rejection sampling, and (without
use_local_argmax_reduction) on the draft side before the argmax. For a 200k vocabulary at TP4 that is a large gather on every decode step, although greedy verification only needs the argmax of each row.This PR keeps the logits on each rank:
v1/worker/gpu/spec_decode/sharded_greedy_verifier.py, opt-in viaVLLM_SHARDED_GREEDY_VERIFY=1). Each rank reduces its vocabulary shard to compact per-block(max, token id)statistics, only those are all-gathered, and one kernel finishes the global argmax, acceptance (including synthetic acceptance), bonus token and sampled/rejected counts. The blocks keep the native kernels' global boundaries (8192 for draft positions, 1024 for the bonus), also across shard edges, so ties resolve exactly as on the full logits.compute_logits_local, the hook batch-sharded sampling already uses (added here to the ROCm MiniMax-M3 model, matching the NVIDIA one). Any TP size > 1 (including non-power-of-two), vocabulary < 2^24, hidden size and number of speculative tokens; CUDA and ROCm.LogitsProcessor.get_top_tokens(model_executor/layers/vocab_parallel_argmax.py), i.e. the existingspeculative_config.use_local_argmax_reductiondraft path. The in-place padding mask, the torch reduction, the stack and the last-dim all-gather become two Triton kernels with a dim-0 all-gather. Same result (lowest id on ties, NaN wins, astorch.argmax); it applies to every model usingLocalArgmaxMixin.Results (MI355X, MiniMax-M3-MXFP4 TP4, EAGLE3-GQA, K=3)
Base image
vllm/vllm-openai-rocm:nightly-rocm72-1b2a666391f2a24228a1436b64d547c34cc6b6ceplus the AITER gfx950 unified-attention routing fix (ROCm/aiter#6336) so an unrelated draft-attention regression does not dilute the numbers. This branch is based on the same vLLM commit; the measured image contains exactly these files. Server:VLLM_SHARDED_GREEDY_VERIFY=1,--speculative-config '{..., "use_local_argmax_reduction": true}'.8k/1k C24 (240 requests, zero HTTP warmup, warmed compile caches, interleaved rounds vs same-round baseline):
use_local_argmax_reductionMean TPOT −3.0%, p99 E2EL −1.3%. Per decode step (profiler, 24 req × 4 tokens), NCCL in the cycle went from 385 µs to 83 µs.
AgenticX C24 (InferenceX recipe
minimaxm3/vllm/mi355x-fp4-mtp/agentic.yaml, 3600 s, one run of this revision vs the same baseline): P50 interactivity +1.9%, P90 interactivity +0.7%, mean TPOT −0.5%; throughput is trace-saturated (+0.3%). TTFT regresses: mean +6.8%, P90 +8.1%. Two earlier runs that combined this change with a draft-metadata change showed the same TTFT shift (+6.3% / +5.3% mean), while other changes measured against the same baseline did not, so the TTFT cost is attributed to this PR and is being investigated before this leaves draft.Correctness: real-acceptance greedy EAGLE3 smoke (24 concurrent ≥8k-token prompts + 4 short requests): generated text and token counts identical to the baseline (24/24, 4/4).
Test Plan
tests/v1/worker/test_gpu_sharded_greedy_verify.py: TP2/3/4/8 emulated in one process (per-shard statistics concatenated in rank order, asall_gather(dim=0)produces), compared withrejection_sample+get_num_sampled_and_rejectedon the full logits. Covers vocab 1000/50257/200064 (including shards narrower than a block), K=1/3/5, synthetic acceptance, prefilling requests and placeholder drafts, bf16 ties and planted cross-shard ties, unaligned vocabulary padding, and NaN rows staying in-vocabulary.tests/model_executor/layers/test_vocab_parallel_argmax.py: fused argmax vstorch.argmaxfor TP1/2/3/4/8, fp32/bf16, ties, NaN, padding, empty batch and all-infrows.Draft: E2E measured on MiniMax-M3 / ROCm only so far.
🤖 Generated with Claude Code