Repository navigation
[Spec Decode][DSpark] Batch-sharded sequential block - #63886
Merged
WoosukKwon merged 2 commits intoOct 30, 2026
Merged
Conversation
TheEpicDolphin
force-pushed
the
dspark-batch-sharded-seq-block
branch
3 times, most recently
from
October 27, 2026 22:09
2197f38 to
6aa6c87
Compare
Contributor
|
This pull request has merge conflicts that must be resolved before it can be |
TheEpicDolphin
force-pushed
the
dspark-batch-sharded-seq-block
branch
from
October 28, 2026 20:06
6aa6c87 to
a975e0a
Compare
TheEpicDolphin
force-pushed
the
dspark-batch-sharded-seq-block
branch
from
October 29, 2026 17:10
a975e0a to
02dbb1c
Compare
Open
2 of 6 tasks
zyongye
added a commit
that referenced
this pull request
Oct 29, 2026
#63886 covers batch-sharded DSpark draft sampling, so this PR keeps only the Markov sampling in the Gumbel kernel. Remove DraftBatchSharder, compute_draft_logits_local and the drafter's sharding hooks. Without the sharded path the bias row is the token's own row, so gumbel_sample drops bias_rows. The fused-vs-unfused Markov test moves to test_dspark_markov_sampling.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yongye Zhu <zyy1102000@gmail.com>
TheEpicDolphin
force-pushed
the
dspark-batch-sharded-seq-block
branch
from
October 29, 2026 20:52
02dbb1c to
eda22d4
Compare
2 of 6 tasks
Under batch-sharded sampling, shard the DSpark sequential Markov loop across TP ranks: each rank runs the loop only for the requests whose draft logits it caches. Vocab-shard base logits are exchanged with a PyNCCL all-to-all and the drafts are all-gathered back in batch order. Ownership follows DraftLogits (batch position i on rank shard_owner(i)), so every shape depends only on the batch size and the step is captured in the existing draft CUDA graphs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Giancarlo Delfin <gdelfin@inferact.ai>
TheEpicDolphin
force-pushed
the
dspark-batch-sharded-seq-block
branch
from
October 30, 2026 01:44
eda22d4 to
39cf6d4
Compare
TheEpicDolphin
marked this pull request as ready for review
October 30, 2026 01:46
Member
Author
|
/ci run |
|
✅ Triggered Buildkite CI #98523 for commit ℹ️ This PR is 26 commits behind upstream |
6 tasks done
WoosukKwon
approved these changes
Oct 30, 2026
ischencheng
added a commit
to ischencheng/vllm
that referenced
this pull request
Nov 2, 2026
Follow the speculator config classes (vllm-project#63205): dspark_markov_quantization is a DSpark supported option, validated in DSparkSpeculatorConfig.apply_options and part of its hash factors. Follow the batch-sharded draft logits and sequential block (vllm-project#63554, vllm-project#64356, vllm-project#63886): the walk writes DraftLogitsCache.values at full size, so it keeps the cache replicated and the sequential sampling on every rank. Loading now also fails for a draft model with its own sample_sequential or an output logit transform, and for a non-bf16 draft logits cache. The benchmark's eager arm uses greedy_argmax, as _sample_logits does since vllm-project#57770. Signed-off-by: Chen Cheng <85005591+ischencheng@users.noreply.github.com>
hyukjlee
added a commit
to hyukjlee/vllm
that referenced
this pull request
Nov 2, 2026
vllm-project#63886 moved the Markov loop out of DSparkSpeculator._sample_sequential into _sample_markov_chain; the test's reference Spec needs it too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: hyukjlee <hyukjlee@amd.com>
kimseunghyun-kr
added a commit
to kimseunghyun-kr/vllm
that referenced
this pull request
Nov 3, 2026
…_all_vocab_shards, shard counts) and the model-state sampler hook Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: kimseunghyun <incongnito12@gmail.com>
kimseunghyun-kr
added a commit
to kimseunghyun-kr/vllm
that referenced
this pull request
Nov 3, 2026
…_all_vocab_shards, shard counts) and the model-state sampler hook Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: kimseunghyun <incongnito12@gmail.com>
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.
Context
Under batch-sharded sampling, #64356 shards verification and the draft logits cache by batch position: request
iis owned by ranki % tp_size. The DSpark sequential (Markov) block still runs replicated, though. Every rank computes full-vocab draft logits and samples every request at every draft step, even though each rank only keeps the draft logits of the requests it owns.This PR
This PR shards the DSpark sequential block along the same ownership rule, so each rank runs the Markov loop only for its own requests.
DSparkSpeculator._sample_sequential_sharded. Each rank owns at mostcapacity = cdiv(num_reqs, tp_size)requests, so every shape depends only onnum_reqsand the step is captured in the existing draft CUDA graphs. No second graph set is needed. Each step:compute_draft_logits_local) for every request, in owner-major order. Padding slots read request 0's rows and are discarded._sample_markov_chain, now shared with the replicated path) samples those rows and writes the owner's draft logits rows. Padding lanes pass-1and write nothing.Single NCCL communicator.
PyNcclCommunicator.all_to_all_single(new) does a variable-split all-to-all, and is graph-capturable when the split sizes are fixed.all_to_all_vocab_shards(which replacesall_to_all_logits) andget_tp_pynccl_comm().When the loop stays replicated. It logs the reason and runs replicated when:
sample_sequentialwrites the full cache);compute_draft_logits_local;Models.
compute_draft_logits_localis added for DeepSeek-V4 and V4.1 DSpark (NVIDIA) and Qwen3 DSpark.Benchmarks
Setup:
max_num_seqs=256, FP8 KV cache, prefix caching off, natural EOS.--enable-batch-sharded-sampling, so the comparison isolates the sharded loop.low_entropy,throughput_2k, temperature 1. GSM8K: 1319 questions, temperatures 0 and 1.Speed (this PR vs main)
With AV off, ITL at c256 goes from 48.43 to 47.16 ms; the two boots of each arm agree within about 0.05 ms. Throughput and the AV-on runs are noisier. At c1 the extra collectives cost about 1%. A minimum batch size for the sharded loop (no extra CUDA graphs needed) could remove that cost as a follow-up.
Accuracy and acceptance (main → this PR)
Tests
test_pynccl_all_to_all_singlecovers uneven and zero-row splits, plus CUDA graph replay.test_dspark_sharded_sampling_equivalence(new) runs Qwen3-4B-FP8 + DSpark at TP2. It checks that the draft logits cache and the loop are sharded only when the flag is on, and that greedy and seeded outputs match replicated sampling up to near-tie noise. The general e2e test covers verification's all-to-all, which now runs on PyNCCL.