Repository navigation
serve: --prompt-cache-spread, checkpoints kept spread back from the conversation's end (opt-in) - #1959
serve: --prompt-cache-spread, checkpoints kept spread back from the conversation's end (opt-in)#1959xrip wants to merge 1 commit into
Conversation
…onversation's end (opt-in) Least recent use keeps the newest checkpoints and every turn adds one, so after a few short turns all 6 sit in the last 1-2K tokens. An agent client that rewrites its history a few thousand tokens back then resumes from the system prompt: on 2x CMP 50HX with the pi coding agent a 210,528-token prompt that was the same as the session for 204,349 tokens resumed at 9,525 and read 201,003 again (100 s). With the flag the victim is the checkpoint whose removal leaves the smallest gap for its distance from the newest, so the kept points thin out geometrically: after 200 turns of 1,000 tokens they sit 0, 1K, 3K, 8K, 43K and 200K before the end, and an edit 6K back reads 8K again (least recent use: 200K), 42K back 43K. The same number of checkpoints, no more RAM; never the root, the newest or a pinned one, the tail rule first, the plain policy without a candidate. The resume is the usual exact-prefix match. On the box: an 82,593-token conversation grown turn by turn, a turn ~6 steps back rewritten, resumed at 73,610 tokens in 10.2 s against 40.0 s read in full; with the expert placement fixed (--adapt-swaps 0, --pcie-frac 0.17) the greedy answer was the same text as the full read. conv_cache_test: the spread cases (a 200-turn simulation against least recent use, the fallbacks). docs/DETAILS.md: a paragraph after the prompt cache's options. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thank you, this is in for 0.1.45 as an opt-in with your authorship (docs included). The conv_cache_test cases pass on CUDA sm_86, sm_60 and HIP. Our engine run did not reach the case your flag changes: with appended turns and an edit 6 turns back both arms resumed at the root, so we have no engine measurement of our own; your 10.2 s against 40 s stands as your number. |
|
@Niko1221 Thank you for taking it in, docs and all! |
|
Thanks for the pull request. Your change is already in If part of your work did not make it in and you want it considered, open a new pull request on top of |
…h "parallel", the fork's changes and the measured costs docs/BATCHING.md "This fork" and docs/NVFP4.md "Several dialogs at once": the switch cost of dialogs that take turns without and with --conversation-cache-mib (8K / 32K / 100K), why "parallel" was unusable on the 262K config (14.6 GiB of slots), --batch-max-context in the options table, the control-vector window fix, the conversation-cache PRs taken (Niko1221#1503, Niko1221#1163, Niko1221#1164, Niko1221#1959, Xiaomi2008's STRATA_PARK_REWIND_MAX), the checks, one dialog's decode per config, and the recommended setting (the conversation cache; "parallel": 2 with 64K slots when requests really overlap). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
…gs, the rope warning, the final build's checks (81049f34)
What's new and "Upstream 0.1.43.1" add the EOS-literal fix ("stop_token_text"), the parallel-dialog fixes (upstream
PRs Niko1221#1503 Niko1221#1163 Niko1221#1164 Niko1221#1959; link to "Several dialogs at once") and the --max-context warning; the checks name the
release build 81049f34: 2K / 32K logits and tokens = 0.1.42-nvfp4.2's engine, the serve KL texts byte-identical,
ctest 116/119, serve 849, tools 821.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
…3-way merge each (base v0.1.44.1, upstream v0.2.0-beta, fork rel/0.1.44) The cherry-picks took HEAD's copy of these files at every stop (deferred: upstream changed generate.cpp by +2.6K lines, 35 conflict hunks on the whole file), so the commits that touched only generate.cpp were dropped as empty (114851a 34bb231 f482c2a a4f1c78 b2f564a 437947e b38dbaa 5cb54da 4c9b2d0 a0ec12c 7281f76 deb8265 6b04110); their content is here. generate.cpp, 27 hunks: - both sides: the disk tier's options + --conversation-cache-park-gain; adapt_fetch() + upstream's evict-sync helpers; the slow-link stage check + Niko1221#2644's stage floors; the disk tier's idle sync + upstream's BYIELD-nodrain drain; the restore's ms + the lent slot reset; upstream's --prefill-pipe resume plan + the dynamic RoPE switch; the fetch line + the residency check; slot_kv_fit + upstream's opt-in STRATA_SLOT_COPY_DIRECT copy. - upstream's: Niko1221#1959's spread_victim with the checkpoint pool; the Niko1221#669 lend warning (Niko1221#1683 keeps the lend region in the RAM budget now: the fork's "the budget keeps no copy" wording dropped, its auto:8192 hint kept). - reworked: the card check the fork opens above the expert arena's thread is the tag's block (HIP: the hipBLAS warm-up thread); upstream's pinned-memory reserve (pin_budget.hpp) is taken before the fork's arena thread and handed back after the join; res_dirty is set where evict sync or the fork's fetch admission drains it (the fork set it always); STRATA_ADAPT_CHECKRES (upstream's name) and the fork's STRATA_ADAPT_FETCH_CHECKRES both read; give_way (upstream's BYIELD refactor) keeps the fork's --batch-max-context fit; the prompt chunk is Niko1221#2824's planned_chunk within the fork's STRATA_SPLIT_PF_CHUNKS chunk; parking: park-gain and STRATA_PARK_REWIND_MAX both. - the usage text: the fork's auto up to 32768 + upstream's --prefill-pipe (the cherry-pick had left both auto texts). serve/test_server.py: the clean merge, less the fork's old Niko1221#567 IncrementalPrompts class (upstream's f13a870 carries it); upstream's Mac telemetry test resets the fork sampler's cache before its patched read. tools/strata_mcp.py: upstream's Gyro entries; no nvfp4 fallback entries (setup maps --family nvfp4 onto this fork's families, as since 0.1.44). src/core/pinned.cu: the wddm-pin merge's hand edit (31bb176) again - the pin-by-need constructor calls shared_pin_limit (sliced_pin_limit's name since extras/wddm-pin). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
What
Opt-in
--prompt-cache-spread: when the conversation checkpoints are over--prompt-cache, the one that leaves ischosen so that the kept ones stay spread back from the conversation's end, instead of the least recently used. Without
the flag nothing changes.
Why
The engine keeps 6 checkpoints and rotates them by least recent use. Every turn adds one at its start, so after a few
short turns all of them sit within the last 1-2K tokens (plus the pinned system-prompt root). That is fine while a
client only appends. Agent clients do not always: they trim an old tool output, drop a step, or rewrite an earlier turn
a few thousand tokens back. The new prompt then matches none of the recent checkpoints, the resume falls back to the
system prompt, and the whole conversation is read again.
Found with the pi coding agent (and the pi-blackhole extensions) on a long agent session, from the engine log:
In both, a checkpoint a few thousand tokens before the edit would have saved most of the read; least recent use had
rotated those out.
How
conv_cache::spread_victim(include/strata/program/conv_cache.hpp): over the chain (ascending), the victim is thecheckpoint whose removal leaves the smallest gap for its distance from the newest one,
(len[i+1] - len[i-1]) / (len[newest] - len[i-1]). Dense recent points go first, so the kept ones thin outgeometrically towards the root. Never the root, the newest or a pinned (
strata_prefix) one; the--prompt-cache-tailcheckpoint first, as in the existing policy; with no candidate, the existing policy.generate.cpp: the flag, and the choice between the two policies at the one place a checkpoint is dropped.In a simulation of 200 turns of 1,000 tokens after a 9,525-token system prompt (
conv_cache_test):Measured
2x CMP 50HX (Turing sm_75,
--layer-split auto), 2x Xeon E5-2670 v2, 64 GB RAM, Qwen3.8-Flash-Next IQ3_XXS, CUDA 13.3,GCC 14. An 82,593-token conversation (a 65K-token document, then 20 short turns sent 2 at a time, each request
continuing the previous one), then the same conversation with a turn ~6 steps back rewritten and a question; greedy,
thinking off:
--prompt-cache-spread--prompt-cache 0(read in full)With the expert placement fixed (
--adapt-swaps 0 --pcie-frac 0.17) the answer after the resume was the same text asthe full read. Without fixing it, two full reads already differ in wording (the placement moves with timing), so that
comparison needs the fixed placement.
Tests:
conv_cache_testpasses, with the new cases (the simulation above against least recent use; every candidatepinned and one slot fall back to the existing policy). Not run on Windows or HIP.
Relation to #1937
Found while measuring the disk tier of #1937 on the same agent sessions, with a diagnostic that logs how many tokens a
request read again although a held conversation had them. It is independent of #1937: any long conversation whose
client edits its history benefits, with or without parked conversations.
How to try
Add
"--prompt-cache-spread"to the config'sargs.🤖 Generated with Claude Code