Skip to content

[Engine] DS4_LOOKUP: draft a round from the request's own history (opt-in) - #4619

Open
lyesrock wants to merge 1 commit into
Niko1221:mainfrom
lyesrock:f-dsv41-lookup
Open

lyesrock wants to merge 1 commit into
Niko1221:mainfrom
lyesrock:f-dsv41-lookup

Conversation

@lyesrock

@lyesrock lyesrock commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Problem

On a machine whose drafter the auto rule turns off, decode is one token a round even when the model is copying: repeating a list, rewriting a file, echoing a document. DeepSeek-V4.1-Flash with the IST-DAS 2.25 bpw pack on an RTX 5090 is exactly that case - the engine itself says so (DSpark not loaded: the routed experts (149 GB) are far more than the GPU holds (33 GB)), and its continuation lives in the request, past any drafter's block. Measured there: reproducing 48 commands, 620 tokens, 619 rounds, decode 39.8 tok/s.

Result (opt-in, default path unchanged)

DS4_LOOKUP=1 drafts each round from the request's own history. Same reproduction: 39.8 -> 68-70 tok/s (+74%), 35-46 rounds instead of 619, and the 300-token check is byte-identical off/on. Real agent traffic (a 220 000-token coding conversation at temperature 1.0) went 37-39 -> 43 tok/s with 2041 tokens accepted from the lookup; short prompts and warm prose are unchanged within run-to-run spread.

Approach

Lookup keeps an incrementally maintained bigram chain over everything the request has read and written (a 220 000-token conversation costs microseconds a round). Each round its tail's last two tokens find their earlier occurrences, the copy is extended back up to 64 tokens, and what followed the match is proposed as the round's block. The proposal goes through the trunk's own verify, greedy against its argmax and sampled through the same point-mass rejection the drafter's argmax drafts already use - the model keeps every token, nothing here decides one. With the drafter loaded the two coexist (a long match wins the block, or the sources agree on the first token). On a drafter-less machine the window rollback buffers and the verify scratch are allocated for lookup too (small, and only when the knob is set), and an empty round no longer cools the request (a plain step always offers nothing). A guard keeps prose out of the window: the match must be 12 tokens or more (16 after two empty rounds; 4 once a copy runs). DS4_LK_STATS=1 prints rounds, kept drafts and the longest match.

Validation - RTX 5090 32 GB, 121 GB DDR5, Ryzen 9950X3D, engine 0.1.52 with this branch, pack IST-DAS 2.25 bpw, --mmap-experts off --prefill-chunk 8192 --dspark auto (auto off), fresh prompt-cache key per request, drop_caches between boots

Passed

  • CUDA build of the submitted revision (commit 3aacc78).

  • Lossless, submitted revision: stock 0.1.52 binary and this binary each booted --serve with the same args; the same GEN 300 greedy request (an 873-token prompt) answered with 300 T lines byte-identical (cmp).

  • Reproduction, 48 commands, greedy, 620 tokens, cold boots: off 39.80 / 39.68 tok/s; on 68.32 / 69.37 / 70.17 tok/s; --spec-eval: 1.00 tok/round off vs 14.07 tok/round on.

  • Same reproduction sampled at temperature 1.0: 85.2 tok/s, 981 of 3992 drafts kept.

  • Real traffic (an agent at ~220 000 tokens): a 1232-token answer at 43.06 tok/s with 161 lookup rounds on the request, vs 37-39 tok/s for the same agent before the branch.

  • Passed, hybrid with the drafter forced on (--dspark on - the only arm where the agree/override rule runs): same binary, DS4_LOOKUP=0 vs 1, one boot each: the 300-token greedy T lines byte-identical (cmp); the reproduction decodes 81.63 vs 94.07 tok/s cold (+15.2%) and 102.85 vs 112.34 warm (+9.2%), the lookup taking 58 rounds and 840 of 3430 proposals kept. The agreement check follows HyperQwen's _AGREE: the two sources must propose the same first two tokens.

Not run

Known noise, for honesty: two stock 0.1.52 boots of the same request differ by one character at the max_tokens cutoff on their own (expert-tier copies drift per boot), so identity is asserted per boot-class, off vs on.

Limits

Off by default; one extra environment knob to learn. The 12-token floor is measured on the prose ramp and short prompts (unchanged), not exhaustively on all prose. The lookup can only help copies whose tail's bigram appeared before; anything new pays one proposal attempt.

…t-in). A model that reproduces a document, a list, a file or its own recent code keeps the continuation inside the sequence, beyond any drafter's block: the tail's last two tokens find their earlier occurrences through a small incrementally kept bigram chain (a 220 000-token agent conversation costs microseconds a round), the copy is extended back up to 64 tokens and what followed it is proposed as the round's block; the trunk's verify decides every token exactly as it decides the drafter's - greedy against its own argmax, sampled through the same point-mass rejection the drafter's argmax drafts already go through - so the answers stay the model's own. It works with the drafter (it wins the block when the match is long, or when the two sources agree on the first two tokens) and - the case it was built for - on a machine the drafter's auto rule turned off: the window rollback's buffers (ring_bak, c_snap, c_rows) and the verify's scratch (d_ints, d_specq) are allocated for lookup too, small and only when the knob is set; without a drafter an empty round no longer cools the request (a plain step always offers nothing). A guard keeps prose untouched: the match must be 12 tokens or more (16 after two empty rounds; 4 once a copy runs), so a request that merely repeats phrases never pays for a 16-row window. Measured on an RTX 5090, DeepSeek-V4.1-Flash IST-DAS 2.25 bpw, mmap-experts off: reproduce 48 commands, greedy, 620 tokens, fresh prompt cache, cold boots caches dropped: decode 39.80/39.68 tok/s off vs 68.32/69.37/70.17 on (+74-76%), 35-46 rounds instead of 619, 14.07 tokens a round; the 620 tokens are byte-identical on/off in batch (cmp) and against a stock control boot in serve (and two stock boots differ by one character at the cutoff by themselves - expert-tier copies vary per boot - so identity is asserted per state class). Sampled (temperature 1, the spelling an agent like Kilo Code sends): the same reproduction 85.2 tok/s, and real agent traffic (220 000-token conversation, file rewrites) went 37-39 to 43 t/s with 2041 tokens accepted from the lookup. Short prompts and the warm 900-2200 ramp are unchanged within run-to-run spread. Not run: HIP/Metal builds (files are the CUDA dsv41 engine's; no ROCm on the test box - same as the FAT_ROWS PR, maintainer CI to confirm), sampled-identity (point-mass rejection preserves the distribution, not a fixed token sequence). Idea credit: drafting from the request's own context is what the community's context-lookup drafters (e.g. HyperQwen for vLLM) do; this is the dsv41 round-loop port.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant