feat(mtp): add optional ASD acceptance policy for greedy MTP verification - #1555
Open
Kissmetothemoon wants to merge 1 commit into
Open
feat(mtp): add optional ASD acceptance policy for greedy MTP verification#1555Kissmetothemoon wants to merge 1 commit into
Kissmetothemoon wants to merge 1 commit into
Conversation
…tion Approximate Speculative Decoding (arXiv:2608.03447): relax strict greedy MTP verification by accepting draft tokens whose target-logit regret stays within a bounded per-request budget. Default off (strict, lossless); budget=0 or max_mismatch=0 recovers strict verification exactly. All ASD logic lives in the new plugin module triton_kernel/mtp_asd.py; existing files only carry config fields and the dispatch seam. Implements ModelTC#1552.
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.
Implements the proposal in #1552.
Motivation
Strict greedy MTP verification (
_fwd_kernel_mtp_verify) discards the whole draft suffix atthe first mismatched token. ASD (Approximate Speculative Decoding, arXiv:2608.03447,
Apache-2.0 reference implementation) relaxes this:
a draft token is accepted while its local regret against the target logits,
r_i = max_v z_i(v) - z_i(x_i), stays within an explicit per-request budget. This raisesaccept length and throughput for greedy users in exchange for a bounded, user-configurable
deviation. Budget
B=0(orm=0) recovers strict verification exactly — enforced as aunit-test gold standard — and the default (flag unset) keeps today's behavior bit-for-bit.
ASD is the acceptance-side counterpart of LightSpec: LightSpec decides how much to verify;
ASD decides how strictly to accept. The planner only consumes
accept_lenstatistics, sothe two compose without interference.
Measured on the paper's research evaluator (pure PyTorch, Qwen3-14B + DSpark block-7 draft,
8xL20, greedy, 1319 GSM8K requests): strict 66.21 tok/s / 79.682% vs ASD (B=2.0625)
75.04 tok/s (+13.34%) / 79.454% (-0.227pp); the B=0 arm is token-identical to strict
on every request. Engine-level LightLLM numbers will be filled in below before marking this
PR ready.
Modifications
StartArgs):--mtp_asd_regret_budget(B, defaultNone= strict),--mtp_asd_local_regret_ratio(g, suffix-value-weighted local cap), and--mtp_asd_block_max_mismatch(m, per-verify-step relaxed-token cap); validated in_launch_subprocesses(requires an enabledmtp_mode, non-negative values)._fwd_kernel_mtp_asd_verify+mtp_asd_verify()inlightllm/common/basemodel/triton_kernel/mtp_utils.py, mirroringmtp_verify's launchcontract. Per-row regrets are precomputed on device (max + gather over the same logits
that produced
next_token_ids; no host synchronization); the kernel applies the threeASD gates with the same accept_len semantics as strict verification (first infeasible
position stops, the target row is still committed). Rows accepted under a nonzero regret
commit the draft token into
next_token_idsin place, so the token counter,scatter_mtp_next_tokens, and response construction all work unchanged.ReqSamplingParamsManager.req_to_asd_cum_regret(allocated only whenASD is enabled, zeroed per request at the prefill seam
init_req_sampling_params,updated in-kernel after each verify step).
verify_mtp_tokensroutes to ASD only when the flag is set AND the wholebatch is greedy (
top_k == 1, same rule assample); sampled/mixed batches take thestrict path unchanged. The three decode call sites (
chunked_prefill,dp_backend,dp_backendoverlap) passlogitsandrun_reqsthrough; the overlap path refreshesthe pinned
next_token_idscopy after verify when ASD is enabled (the early copy racesahead of the in-place commit).
unit_tests/server/router/model_infer/mtp_speculative/test_mtp_asd_verify.py(6 CUDA tests: B=0/m=0 strict equivalence vs
mtp_verify, hand-computed budgetdeduction, local-ratio gate, mismatch cap, all-accepted bonus semantics, cross-step
budget persistence) + ASD arg-validation cases in
unit_tests/server/test_mtp_start_args.py.Accuracy Tests
pytest unit_tests/server/router/model_infer/mtp_speculative/test_mtp_asd_verify.py— 6 CUDA tests(B=0/m=0 strict equivalence vs
mtp_verify, hand-computed budget deduction, local-ratiogate, mismatch cap, all-accepted bonus semantics, cross-step budget persistence).
Written alongside the kernel; I do not have a CUDA box at hand right now, so these are
intended to run on GPU CI — happy to post results once CI (or a maintainer's GPU run)
executes them.
pytest unit_tests/server/test_mtp_start_args.py— ASD arg-validation cases pass locally(CPU, monkeypatched launch path).
to be run on GPU hardware during review; the algorithm-level numbers above come from the
paper's research evaluator.
Speed Tests
The only added hot-path work when ASD is enabled is one
max+gatherreduction overthe verify logits plus a per-request verify kernel with the same launch shape as
mtp_verify; strict path is untouched (zero overhead when disabled).Usage
Unset
--mtp_asd_regret_budget= strict verification, zero behavioral change.--mtp_asd_regret_budget 0= ASD code path with exact strict semantics (sanity arm).ASD is approximate decoding: outputs may deviate from strict greedy within the configured
budget; v1 applies to all-greedy batches only (sampled batches fall back to strict).