Support SGLANG_SIMULATE_ACC_LEN for DFLASH (#32595)

This commit is contained in:
saatwiknagpal
2026-07-30 14:10:06 -07:00
committed by GitHub
parent 3312645a30
commit 5339450ed4
2 changed files with 73 additions and 0 deletions
@@ -12,6 +12,7 @@ import torch.nn.functional as F
from sglang.srt.layers.quantization.unquant import UnquantizedLinearMethod from sglang.srt.layers.quantization.unquant import UnquantizedLinearMethod
from sglang.srt.layers.sampler import apply_custom_logit_processor from sglang.srt.layers.sampler import apply_custom_logit_processor
from sglang.srt.managers.schedule_batch import Req from sglang.srt.managers.schedule_batch import Req
from sglang.srt.speculative.spec_utils import _sample_simulated_acc_len
from sglang.srt.utils import is_cuda, is_musa from sglang.srt.utils import is_cuda, is_musa
DEFAULT_DFLASH_MASK_TOKEN = "<|MASK|>" DEFAULT_DFLASH_MASK_TOKEN = "<|MASK|>"
@@ -585,6 +586,43 @@ def compute_dflash_correct_drafts_and_bonus(
return correct_len, bonus.to(torch.int64) return correct_len, bonus.to(torch.int64)
def apply_dflash_simulated_acceptance(
*,
candidates: torch.Tensor,
target_predict: Optional[torch.Tensor],
accept_len: torch.Tensor,
commit_lens: torch.Tensor,
bonus: torch.Tensor,
out_tokens: torch.Tensor,
simulate_acc_len: float,
simulate_acc_method: str,
simulate_acc_token_mode: str,
fixed_token_id: int = 100,
) -> None:
"""Forces the DFlash acceptance length (SGLANG_SIMULATE_ACC_LEN benchmark knob)."""
block_size = candidates.shape[1]
# _sample_simulated_acc_len clamps to [1, block_size].
forced_commit_len = _sample_simulated_acc_len(
simulate_acc_len, simulate_acc_method, block_size
)
forced_accept_len = forced_commit_len - 1
accept_len.fill_(forced_accept_len)
commit_lens.fill_(forced_commit_len)
if simulate_acc_token_mode != "real-draft-token":
bonus.fill_(fixed_token_id)
out_tokens.fill_(fixed_token_id)
return
out_tokens.zero_()
if forced_accept_len > 0:
out_tokens[:, :forced_accept_len].copy_(candidates[:, 1:forced_commit_len])
bonus.copy_(target_predict[:, forced_accept_len].to(dtype=bonus.dtype))
out_tokens[:, forced_accept_len].copy_(bonus.to(dtype=out_tokens.dtype))
def compute_dflash_sampling_correct_drafts_and_bonus( def compute_dflash_sampling_correct_drafts_and_bonus(
*, *,
candidates: torch.Tensor, candidates: torch.Tensor,
@@ -32,6 +32,7 @@ from sglang.srt.speculative.base_spec_worker import BaseSpecWorker
from sglang.srt.speculative.dflash_info import DFlashVerifyInput from sglang.srt.speculative.dflash_info import DFlashVerifyInput
from sglang.srt.speculative.dflash_info_v2 import DFlashDraftInputV2 from sglang.srt.speculative.dflash_info_v2 import DFlashDraftInputV2
from sglang.srt.speculative.dflash_utils import ( from sglang.srt.speculative.dflash_utils import (
apply_dflash_simulated_acceptance,
apply_dflash_verify_logits_adjustments, apply_dflash_verify_logits_adjustments,
can_dflash_use_fused_qkv_proj, can_dflash_use_fused_qkv_proj,
compute_dflash_correct_drafts_and_bonus, compute_dflash_correct_drafts_and_bonus,
@@ -48,6 +49,9 @@ from sglang.srt.speculative.draft_worker_common import (
) )
from sglang.srt.speculative.spec_info import SpeculativeAlgorithm from sglang.srt.speculative.spec_info import SpeculativeAlgorithm
from sglang.srt.speculative.spec_utils import ( from sglang.srt.speculative.spec_utils import (
SIMULATE_ACC_LEN,
SIMULATE_ACC_METHOD,
SIMULATE_ACC_TOKEN_MODE,
GrammarTree, GrammarTree,
assign_req_to_token_pool_func, assign_req_to_token_pool_func,
build_grammar_vocab_mask, build_grammar_vocab_mask,
@@ -1728,6 +1732,9 @@ class DFlashWorkerV2(BaseSpecWorker):
candidates = draft_tokens candidates = draft_tokens
new_seq_lens = None new_seq_lens = None
# Only the greedy branch sets target_predict; the simulated-acceptance
# override below checks for it.
target_predict = None
if ( if (
sampling_info is not None sampling_info is not None
and not sampling_info.is_all_greedy and not sampling_info.is_all_greedy
@@ -1811,6 +1818,34 @@ class DFlashWorkerV2(BaseSpecWorker):
1, accept_len.to(torch.int64)[:, None], bonus[:, None] 1, accept_len.to(torch.int64)[:, None], bonus[:, None]
) )
if SIMULATE_ACC_LEN > 0:
if SIMULATE_ACC_TOKEN_MODE not in ("fixed", "real-draft-token"):
raise ValueError(
"Invalid SGLANG_SIMULATE_ACC_TOKEN_MODE "
f"{SIMULATE_ACC_TOKEN_MODE!r}; expected 'fixed' or "
"'real-draft-token'."
)
if SIMULATE_ACC_TOKEN_MODE == "real-draft-token" and target_predict is None:
# The sampling-verify branch does not materialize the target argmax.
target_predict = torch.argmax(
logits_output.next_token_logits, dim=-1
).view(bs, int(self.block_size))
apply_dflash_simulated_acceptance(
candidates=candidates,
target_predict=target_predict,
accept_len=accept_len,
commit_lens=commit_lens,
bonus=bonus,
out_tokens=out_tokens,
simulate_acc_len=SIMULATE_ACC_LEN,
simulate_acc_method=SIMULATE_ACC_METHOD,
simulate_acc_token_mode=SIMULATE_ACC_TOKEN_MODE,
)
# The Triton path may have written new_seq_lens from the real
# accept_len; recompute it from the forced commit_lens.
new_seq_lens = None
if self._need_mamba_verify_commit: if self._need_mamba_verify_commit:
assert seq_lens_pre_verify is not None assert seq_lens_pre_verify is not None
self._update_target_mamba_state_after_verify( self._update_target_mamba_state_after_verify(