Skip to content

fit: count llama-server's host caches - #216

Closed
88plug wants to merge 1 commit into
mainfrom
claude/fit-llamacpp-host-caches
Closed

88plug wants to merge 1 commit into
mainfrom
claude/fit-llamacpp-host-caches

Conversation

@88plug

@88plug 88plug commented Oct 29, 2026

Copy link
Copy Markdown
Owner

llama-server b11749 keeps two host caches next to the KV cache, and the fit counted neither:

  • the host prompt cache, -cram/--cache-ram, default 8192 MiB (common/common.h cache_ram_mib = 8192);
  • context checkpoints, -ctxcp/--ctx-checkpoints, default 32 per slot (n_ctx_checkpoints = 32). Each one is a host copy of the slot's partial state (tools/server/server-context.cpp create_checkpoint, LLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY): the SWA cache (llama_kv_cache::state_write skips a non-SWA cache under that flag) plus any recurrent state (llama_memory_hybrid::state_write). The server makes them only for models with SWA or recurrent layers.

For the Gemma QAT GGUF on the desktop fixture's CPU plan (5 slots at 262144, KV filling the room), the defaults add 8 GiB plus 5 x 32 x 300 MiB, about 47 GiB of checkpoints, on top of a 45Gi pod limit.

Changes:

  • console/fit.py: the llama.cpp flags carry --cache-ram 0 -ctxcp 4 (LLAMA_CTX_CHECKPOINTS, with the reason next to it). ckpt_seq gives one slot's checkpoint bytes: 4 x (SWA bytes per token x GGML_PAD(min(n_ctx_seq, n_swa + n_ubatch), 256) cells + recurrent state).
  • On the CPU placement the checkpoints share the KV room in size_kv, so the slot count already accounts for them. On the GPU and experts-in-DRAM placements they are added to the host bytes.
  • The doc's ckpt_bytes, the pod limit and every guard rung's limit include them.
  • docs/fit.md: the flags and the arithmetic.

Effect on the fixtures: the Gemma QAT desktop CPU plan goes from 262144 x 5 with no caches counted to 262144 x 4 with 4.7 GiB of checkpoints, and its pod limit goes from 45Gi to 44Gi. The GPU plans keep their contexts and slots.

Overlap: #214 (fit: size sliding-window KV per engine) adds the same _pad helper and moves llama.cpp's SWA KV to the same 1536-cell count. Whichever lands second needs a rebase; ckpt_seq can then use swa_tokens.

Tests:

  • tests/fit_test.py LlamaHostCaches:
    • the Gemma QAT CPU plan on desktop-i9-nogpu emits --cache-ram 0 and -ctxcp K, and counts seqs x K x 300 MiB in host_bytes, the pod limit and each rung's limit;
    • Flash-Next's checkpoints equal seqs x K x its recurrent state;
    • a full-attention model makes no checkpoints.
  • tests/fit_test.sh: k3d-gpu fit --json for the Gemma QAT on the desktop shows the flags, and its host bytes and pod limit hold the checkpoints.
  • Both suites failed before the change.

Run before opening:

  • tests/fit_test.sh: 35 passed
  • python3 tests/fit_test.py: 59 tests OK
  • tests/model_opt_test.sh: 37 passed
  • tests/claims_check.sh and python3 tests/ledger_drift_check.py: clean
  • ruff (F, E9) and shellcheck v0.11.0 at warning severity: clean

llama-server b11749 keeps two host caches beside the KV cache that the fit did not count: a prompt cache of up to 8192 MiB (--cache-ram) and up to 32 context checkpoints per slot (-ctxcp), each a host copy of the slot's SWA cache and recurrent state. For the Gemma QAT GGUF on the desktop CPU plan (5 slots at 262144, KV filling the room) that is 8 GiB plus about 47 GiB of checkpoints over a 45Gi pod limit.

The llama.cpp flags now carry --cache-ram 0 and -ctxcp 4, and the fit counts slots x 4 x one checkpoint (the SWA cache of GGML_PAD(min(n_ctx_seq, n_swa + n_ubatch), 256) cells plus the recurrent state) in the host bytes, the pod limit and every guard rung. On the CPU placement the checkpoints share the KV room, so the slot count accounts for them; on the GPU and experts-in-DRAM placements they are host bytes. A model with neither sliding-window nor linear-attention layers makes none.

Tests: the Gemma QAT CPU plan on desktop-i9-nogpu emits --cache-ram 0 and -ctxcp K and counts seqs x K x 300 MiB in the host bytes, the pod limit and each rung's limit; Flash-Next's checkpoints are its recurrent state; a full-attention model makes none; k3d-gpu fit --json on the desktop shows the same.
88plug added a commit that referenced this pull request Oct 29, 2026
88plug added a commit that referenced this pull request Oct 29, 2026
The textual merge keeps #217's moe-offload search, which runs through _llama_multi; the
context checkpoints #216 counted on that path are not carried over yet, and #217's
per-layer KV still counts the sliding-window cache at the window. The next commit fixes
both.
88plug added a commit that referenced this pull request Oct 29, 2026
…checkpoints

With #214, #216 and #217 together, the multi-card llama.cpp path (_llama_multi, which
now also runs every moe-offload plan) had two gaps. Its per-layer KV counted a
sliding-window layer at the window (1024 tokens for Gemma 4) while llama.cpp b11749
allocates GGML_PAD(min(n_ctx_seq, n_swa + n_ubatch), 256) = 1536 cells per slot, so
card_bytes disagreed with kv_bytes. And it left the context checkpoints out of the host
bytes and the pod limit, which #216 counts on one card: the Flash-Next IQ4_NL plan on
the Xeon fixture reported ckpt_bytes 0 with -ctxcp 4 in its flags.

kv_parts now takes the sliding-window tokens from swa_tokens, so per_seq, the per-layer
KV and the checkpoints share one cell count, and _llama_multi adds slots x checkpoints
to the host bytes. The Flash-Next plan's pod limit goes from 74Gi to 76Gi.

Tests: the Gemma split's per-card bytes are worked out at 1536 SWA cells and the KV over
the cards equals kv_bytes; a split plan counts its checkpoints in host bytes; the
Flash-Next two-card shell check asserts the checkpoints are on the host.
88plug added a commit that referenced this pull request Oct 29, 2026
…checkpoints

With #214, #216 and #217 together, the multi-card llama.cpp path (_llama_multi, which
now also runs every moe-offload plan) had two gaps. Its per-layer KV counted a
sliding-window layer at the window (1024 tokens for Gemma 4) while llama.cpp b11749
allocates GGML_PAD(min(n_ctx_seq, n_swa + n_ubatch), 256) = 1536 cells per slot, so
card_bytes disagreed with kv_bytes. And it left the context checkpoints out of the host
bytes and the pod limit, which #216 counts on one card: the Flash-Next IQ4_NL plan on
the Xeon fixture reported ckpt_bytes 0 with -ctxcp 4 in its flags.

kv_parts now takes the sliding-window tokens from swa_tokens, so per_seq, the per-layer
KV and the checkpoints share one cell count, and _llama_multi adds slots x checkpoints
to the host bytes. The Flash-Next plan's pod limit goes from 74Gi to 76Gi.

Tests: the Gemma split's per-card bytes are worked out at 1536 SWA cells and the KV over
the cards equals kv_bytes; a split plan counts its checkpoints in host bytes; the
Flash-Next two-card shell check asserts the checkpoints are on the host.
@88plug 88plug mentioned this pull request Oct 30, 2026
@88plug

88plug commented Oct 30, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #229 (merged)

@88plug 88plug closed this Oct 30, 2026
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