Repository navigation
server : share prompt prefix cells between slots (--slot-attach) - #30970
rochaudhari wants to merge 1 commit into
Conversation
Assisted-by: Claude Opus 5.5
| | `-cram, --cache-ram N` | set the maximum cache size in MiB (default: 8192, 0 for decision models, -1 - no limit, 0 - disable)[(more info)](https://github.com/ggml-org/llama.cpp/pull/16391)<br/>(env: LLAMA_ARG_CACHE_RAM) | | ||
| | `-kvu, --kv-unified, -no-kvu, --no-kv-unified` | use single unified KV buffer shared across all sequences (default: enabled if number of slots is auto)<br/>(env: LLAMA_ARG_KV_UNIFIED) | | ||
| | `--cache-idle-slots, --no-cache-idle-slots` | save idle slots to the prompt cache on new task, and clear them when using unified KV (default: enabled, requires cache-ram)<br/>(env: LLAMA_ARG_CACHE_IDLE_SLOTS) | | ||
| | `--slot-attach, --no-slot-attach` | start a new prompt from the KV cells of another slot that holds the same prefix; the cells are shared, not copied (default: disabled, requires unified KV)<br/>(env: LLAMA_ARG_SLOT_ATTACH) | |
There was a problem hiding this comment.
Why should this be an option? It should be the default IMO, is there a reason we do not want to do this optimization?
There was a problem hiding this comment.
some of the features, such as --cache-reuse and --context-shift cannot go along-with --slot-attach since these features require sliding and shifting of cells. To enable all of these together will require copy-on-write (making private copies) which would be follow-up for current MR (avoided that purposely in current MR to keep scope minimal).
Additionally, IMO providing an option also helps in narrowing down any perf gaps/regressions.
There was a problem hiding this comment.
But we can disable the feature automatically if something incompatible is turned on right? I don't see why it needs to be yet another option. It should be "let's do this if we can" automatically. Did I miss something?
There was a problem hiding this comment.
yes, we can keep it on by default. If we have to follow convention of other features, we can keep --no-slot-attach as kill switch. WDYT?
There was a problem hiding this comment.
Yes makes sense to me. I like this approach better because it makes it easier for user to not have to know about the option.
Overview
A new session has following limitations which reusing prefix that another slot holds:
With
--slot-attachand unified cache, a new session takes the shared prefix from another slot withseq_cp, which shares the KV cells instead of copying them. Hybrid models attach at one of the other slot's checkpoints.For hybrid models, because the recurrent state cannot be cut back to an earlier token, when a prompt matches the cached state only up to a point before the first user message, the server saves a checkpoint there. Later sessions can then resume exactly where prompts differ.
Additional information
Original discussion: #30664
Design
seq_cpwithin one stream adds the new slot's tag to the donor's cells without copying data. The whole sequence is copied (llama_memory_hybrid_idxonly supports that), thenseq_rm(slot, n, -1)drops the tags after the attach point.nis loaded. This first removes the new slot from the recurrent cell it shares with the donor, so the donor's state is untouched. The slot's own state then ends at n-1, so the finalseq_rmleaves it alone.Numbers
Setup: NVIDIA A40 (48 GB), CUDA 12.8, q8_0 KV, 4 slots with unified KV, 3 concurrent sessions, MTP off. Prompts use Hermes's real tools and system prompt; the project context, skills and memory parts are synthetic. The shared prefix is 14.1K tokens. Times are the mean of 3 runs. The KV cell counts come from one separate run.
Values are "off -> attach":
A checkpoint copy on the 35B is 62.8 MiB and takes about 29 ms per attach.
Tests
Three new test functions, five cases, in
tools/server/tests/unit/test_completion.py:test_slot_attach, with and without idle-slot clearing:test_slot_attach_off, for non-unified KV and for speculative decoding: nothing attaches.test_slot_attach_hybrid:The server suite
tools/server/testswithout slow tests: 438 passed, 4 skipped.Related and follow-ups
seq_cpsharing idea on attention-only models.--cache-dir). ngxson mentions a block-hash prompt cache there that would replace it.abort_all_slotsreleases slots without clearing their memory, so a slot's token list can be ahead of its KV cache. The attach code guards against this by capping the attach atseq_pos_max + 1.Requirements