Repository navigation
Conversation
…s-dir) Context checkpoints (the state of recurrent/hybrid and SWA models that cannot be rolled back token by token) are kept in host memory, up to --ctx-checkpoints per slot. They are written once and read back only to rewind a slot. On a hybrid model with a large recurrent state they dominate a busy slot's memory: 112.6 MiB each on Qwen3.8-Flash-Next, so 4 slots x 32 checkpoints can hold 14 GiB of RAM. With --ctx-checkpoints-dir PATH, each new checkpoint moves its target and draft state into a file in PATH that is unlinked at once and kept open, so nothing is left behind when it is dropped or the server exits or crashes. Copies of a checkpoint (the prompt cache) share the file. The state is read back to rewind a slot and to write the slot save file; checkpoints restored from a slot file are moved out again one by one. The small speculative state stays in memory. Without the flag nothing changes. Not available on Windows (the data stays in memory). Assisted-by: Claude Code
e616f82 to
4913fa7
Compare
load_tgt() and load_dft() return bool on master since the rebase: false when the state does not load, and the caller aborts for a checkpoint of this server or falls back to reprocessing for one restored from a slot file. The file-backed branch still aborted on its own and returned no value, which does not compile. Return the result like the in-memory branch. Assisted-by: Claude Code
|
Thanks for rebasing. The rebased branch does not compile against the new master: Verified on gfx1150 (Radeon 890M, Vulkan), Qwen3.8-Flash-Next IQ3_XXS with MTP: Unrelated to this PR: the base 93e6d02 does not build |
Joins halo-box#149 and halo-box#180: a disk cache entry is written from the checkpoint files, and the checkpoints restored from an entry move to --ctx-checkpoints-dir again. Assisted-by: Claude Code
Joins halo-box#149 and halo-box#180: a disk cache entry is written from the checkpoint files, and the checkpoints restored from an entry move to --ctx-checkpoints-dir again. Assisted-by: Claude Code
Scope first
Like #171 and #176, this is general server code, not Strix specific: it applies to any model whose memory needs context
checkpoints (recurrent/hybrid and SWA models). I am opening it here because this fork syncs from ggml-org directly now
that halo-box/llama.cpp is archived, and because it matters most on the boxes this fork targets, where the GPU and the
host share one pool of RAM. If you would rather not carry it here, please close it; as an agent I cannot open it in
ggml-org.
This PR was written by an AI agent (Claude Code), working for @rcfa; what was and was not verified is listed below.
Overview
Context checkpoints hold the part of a slot's memory that cannot be rolled back token by token. They are written once,
when a prompt is processed, and read back only to rewind the slot when a later prompt diverges. Today they are kept in
host memory, up to
--ctx-checkpoints(default 32) per slot. On a hybrid model with a large recurrent state that ismost of a busy slot's memory: on Qwen3.8-Flash-Next each checkpoint is 112.6 MiB whatever the position, so 4 slots x 32
checkpoints can hold 14 GiB.
server : keep context checkpoints in unlinked files (
--ctx-checkpoints-dir). With--ctx-checkpoints-dir PATH,each new checkpoint moves its target and draft state into a file in PATH that is unlinked at once and kept by its
descriptor. Nothing is left behind when the checkpoint is dropped, or when the server exits or crashes, and there is no
cleanup to run at startup.
Checkpoints restored from a slot file are moved out again one by one, so a restore does not need them all in memory.
data_spec) stays in memory.while RAM is free, and evicted under pressure instead of staying pinned in the server.
Measurements
Master vs this PR. One scenario, three servers in turn: master, this PR without the flag, this PR with
--ctx-checkpoints-dir. A, B, C are 12000 tokens each; 16 greedy tokens per request.Server anonymous RSS (master / PR / PR + flag): 1095 / 1104 / 871 MiB after r3 (2 checkpoints), 2060 / 2069 /
1385 MiB at the end (6 checkpoints: 675 MiB = 6 x 112.6 MiB). With the flag the checkpoint directory looked empty
throughout (the files are unlinked), and it was still empty after
kill -9of that server.In production (this commit on our production stack: #149's disk prompt cache, #171, #176), with a real workload: an
agent holding two conversations of 51k and 53k tokens. After it had re-read them, 19 checkpoints (2.1 GiB) were in
files and the server's anonymous RSS was 1.1 GiB; with checkpoints in memory it would have been about 3.2 GiB (earlier
the same agent's slots held 34 checkpoints, 5.4 GiB). Prompt processing ran at 149-151 t/s, as before.
With #149 (disk prompt cache) two more places read checkpoints: the cache entry is written from the checkpoint files,
and checkpoints restored from an entry are moved out again. We carry those two hunks on top of #149 and can add them to
whichever of the two PRs merges second.
Correctness
file and one restored from the prompt cache.
kill -9the checkpoint directory is empty and the space is freed (the files are unlinked).test-backend-ops, the corpus comparison andllama-benchdo notapply.
Not verified
tools/serverpytest suite was not run (it needs Python packages and model downloads we have not installed).n_parallel x --ctx-checkpoints, plus the copies the RAM prompt cachekeeps. Fine under the usual 1024 limit for 4 x 32, but a large
-npwith the RAM cache may need a higher limit.--cache-ram(unchanged, conservative).Generated with Claude Code