Conversation
Two related defects made every speculative round on a hybrid (recurrent + attention) target fall back to a whole-KV checkpoint save and restore. need_n_rs_seq() tested MTP, EAGLE3, DFLASH and DSPARK but not DRAFT_SIMPLE, so a plain drafter plus target got n_rs_seq = 0 and common_context_can_seq_rm() classified the context as SEQ_RM_TYPE_FULL. The arch was never the blocker: LLM_ARCH_QWEN35 is already in llm_arch_supports_rs_rollback(). The draft context then hardcoded cparams.n_rs_seq = 0 regardless of type, so its llama_memory_seq_rm() silently failed and it retained stale positions. That half affects every drafter type, not only DRAFT_SIMPLE. Nothing is needed in speculative-simple.cpp: the partial-acceptance path there already drops the rejected draft tokens unconditionally once the checkpoint branch is skipped, via llama_memory_seq_rm(ctx, seq_id, n_past, -1) on both contexts.
Author
|
Duplicate of #173, closing in favour of it. We opened these three minutes apart against the same base, working the same two defects. The code is the same change: the #173 also carries the original B390 measurements and the ablation history first-hand, so it is the one that should carry the change. My fault for not checking for an open PR before pushing. Nothing here is lost: everything in this description that is worth keeping is already in #173. |
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.
What
Two lines of behaviour, in two files. The draft context now reserves the same per-sequence recurrent-state slots as the target, and
DRAFT_SIMPLEis recognised as a type that needs them.Why
On a hybrid (recurrent + attention) target, every speculative round was falling back to a whole-KV checkpoint save and restore instead of a cheap suffix drop. Two defects had to hold together:
common/common.h—need_n_rs_seq()testedDRAFT_MTP,DRAFT_EAGLE3,DRAFT_DFLASHandDRAFT_DSPARK, but notDRAFT_SIMPLE. A plain drafter plus target therefore gotn_rs_seq = 0, andcommon_context_can_seq_rm()classified the context asSEQ_RM_TYPE_FULL, which is the "cannot remove part of a sequence" case that selects the checkpoint path inspeculative-simple.cpp. The arch was never the blocker:LLM_ARCH_QWEN35is already inllm_arch_supports_rs_rollback().common/speculative.cpp— the draft context hardcodedcparams.n_rs_seq = 0regardless of type, with a comment wondering whether it should. Itsllama_memory_seq_rm()then silently failed and it retained stale positions. This half affects every drafter type, not onlyDRAFT_SIMPLE.What is deliberately not here
Nothing in
examples/speculative-simple/speculative-simple.cpp. The partial-acceptance path there already removes rejected draft tokens once the checkpoint branch is skipped:unconditional, no
use_ckpt_tgtguard, always reached whenuse_ckpt_tgtis false. An earlier draft of this fix added a third hunk there; it was removed after an ablation showed it duplicated the above and changed nothing (identical acceptance, 33.190%).Because those models already had
use_ckpt_tgt == falseand always took that path, there is no behaviour change for pure-attention targets.Evidence
Measured on an Intel Arc B390 (Vulkan) against a matched 2B/27B PTQ1_0 pair: k=2 went 0.482x to 1.085x, with the checkpoint save/restore previously accounting for 74-77% of each round on the 27B. The k-sweep optimum at k=1 reached 1.137x/1.356x against a 4.43 t/s AR baseline, output byte-identical to a k=1 reference over the common prefix.
That measurement is not mine and I have not reproduced it. It was made by a colleague on the B390; I verified the two defects in-tree at
6ac5eb087and confirmed the third claimed defect did not exist.What still needs doing before merge
n_rs_seqallocation is now non-zero forDRAFT_SIMPLE, which costs recurrent-state memory that these configurations did not previously reserve. On a small drafter that should be negligible, but it is a real allocation change and worth a look from someone who knows the memory budget.How to tell if you are affected
If a speculative run logs
at startup, it is taking the fallback, and any throughput number from it is measuring this bug rather than the method.