[Spec] Add Domino projector support to DFlash speculative decoding (V2) - #28998
Closed
heiheiha798 wants to merge 1 commit into
Closed
heiheiha798 wants to merge 1 commit into
heiheiha798 wants to merge 1 commit into
Conversation
Port the Domino DFlash draft method onto DFlashWorkerV2. Domino augments the
ordinary DFlash draft model with a GRU prefix encoder (`prefix_gru`) and an MLP
(`embed_proj`) that emits a per-step bias on top of the target lm_head logits,
producing draft tokens via a short sequential rollout.
Scope of this first PR: CUDA + TP=1 only.
- dflash_utils.py: recognize `projector_type` in {"domino", "causal_v5"};
add Domino fields to DFlashDraftConfig (gru_hidden_dim, emb_dim,
pure_draft_prefix_len, shift_label) and validate them. DFlashDraftConfig is
migrated from @DataClass to msgspec.Struct per the repo container convention.
- models/dflash.py: instantiate prefix_gru + embed_proj only for Domino
projectors; flatten_parameters() after weight load.
- domino_helper.py / domino_kernels.py / domino_rollout.py: Domino rollout state,
Triton kernels (fused SiLU+fc2 full-vocab argmax, fused GRU cell), and the
sequential draft-block rollout with a CUDA-graph captured loop.
- dflash_worker_v2.py: create the Domino helper/rollout only for Domino draft
models, reject TP>1 early at init, and branch to the Domino rollout at the
existing draft-token selection hook. Verify / accept / bonus-token / draft-KV
paths are unchanged.
Scoring is full-vocab: each step is the exact argmax of base_logits + Domino
bias over the whole vocabulary (no candidate-pool approximation), verified
against a dense reference. No new env vars are introduced.
Unsupported in this PR (clear errors where reachable): TP>1, non-CUDA devices,
added-vocab lm_head shards. TP>1 needs per-step cross-rank synchronization
(the selected draft token feeds the next GRU step) and is left as follow-up.
Tests:
- test/registered/unit/spec/test_dflash_domino_config.py (CPU): config parsing
and validation.
- test/registered/unit/spec/test_dflash_domino_kernel.py (CUDA): fused full-vocab
scoring matches a dense torch reference, plus a mutation check.
Issue: sgl-project#28977
heiheiha798
requested review from
Qiaolin-Yu,
hnyls2002 and
merrymercy
as code owners
June 23, 2026 05:45
Contributor
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
4 tasks
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.
Motivation
Add Domino projector support to DFlash speculative decoding so the public Domino draft checkpoints (e.g.
Qwen3-8B-Domino-b16) can run on SGLang. Closes the request in #28977.Domino augments the ordinary DFlash draft model with a GRU prefix encoder (
prefix_gru) and an MLP (embed_proj) that emits a per-step bias on top of the targetlm_headlogits. Draft tokens for the block are then produced by a short sequential rollout (each selected token feeds the next GRU step). The verify / accept / bonus-token / draft-KV paths are the existing DFlash V2 paths, unchanged.Scope of this PR: CUDA + TP=1 only
This first PR intentionally supports single-GPU (TP=1) on CUDA only. The Domino rollout is sequential — the token selected at step k is the input to the GRU at step k+1 — so TP>1 would require a cross-rank synchronization after every drafted token. That is non-trivial and is deliberately deferred to a follow-up commit/PR.
Behavior for unsupported configurations (clear errors, no silent fallback):
DFlashWorkerV2.__init__as soon as a Domino projector is detected (--tp-size 1required).NotImplementedErrorbefore touching CUDA graphs / Triton kernels.lm_headshards: explicitNotImplementedError.Other DFlash limitations are unchanged and still apply (DP attention, PP>1, grammar-constrained decoding,
return_logprob,return_hidden_stateswith overlap).Implementation
dflash_utils.py: recognizeprojector_type in {"domino", "causal_v5"}; add Domino fields toDFlashDraftConfig(gru_hidden_dim,emb_dim,pure_draft_prefix_len,shift_label) with validation.DFlashDraftConfigis migrated from@dataclasstomsgspec.Structto follow the repo container convention.models/dflash.py: instantiateprefix_gru+embed_projonly for Domino projectors;flatten_parameters()after weight load.domino_helper.py/domino_kernels.py/domino_rollout.py(new): Domino rollout state, Triton kernels (fusedSiLU(z+s) @ fc2.T + bias + base_logitsfull-vocab argmax, fused GRU cell), and the sequential draft-block rollout with a CUDA-graph-captured loop.dflash_worker_v2.py: create the Domino helper/rollout only for Domino draft models, reject TP>1 early, and branch to the Domino rollout at the existing draft-token selection hook. Ordinary DFlash draft selection is untouched.Scoring is full-vocab: each step computes the exact argmax of
base_logits + domino_biasover the entire vocabulary (no candidate-pool approximation), so the result matches a dense reference exactly. No new environment variables are introduced.Tests
test/registered/unit/spec/test_dflash_domino_config.py(CPU,base-a-test-cpu): config parsing + validation (Domino fields, unsupported projector, missing required fields,pure_draft_prefix_len != 1, non-boolshift_label).test/registered/unit/spec/test_dflash_domino_kernel.py(CUDA,base-b1-gpu-small): the fused full-vocab scoring kernel matches a densetorchreference across bf16/fp16/fp32 and multiple vocab sizes, plus a mutation check.Local validation (RTX A6000, single GPU)
Qwen3-8B-DFlash-b16), baselineQwen3-8B-Domino-b16), V2 overlap--disable-overlap-schedule)Target model:
Qwen3-8B. Prompt: one GSM8K sample,temperature=0,max_new_tokens=512. Ordinary DFlash numbers are unchanged by this PR; Domino output text is identical between overlap and non-overlap.Follow-ups
Closes #28977
CI States
Latest PR Test (Base): ❌ Run #28005093292
Latest PR Test (Extra): ❌ Run #28005093197