Skip to content

kv-cache: add LLAMA_STATE_SEQ_FLAGS_APPEND for incremental state restore - #21221

Open
sammshen wants to merge 1 commit into
ggml-org:masterfrom
sammshen:lmcache-append-flag
Open

kv-cache: add LLAMA_STATE_SEQ_FLAGS_APPEND for incremental state restore#21221
sammshen wants to merge 1 commit into
ggml-org:masterfrom
sammshen:lmcache-append-flag

Conversation

@sammshen

@sammshen sammshen commented Mar 31, 2026

Copy link
Copy Markdown

Overview

state_read_meta unconditionally calls seq_rm(dest_seq_id, -1, -1) before restoring so every state_seq_set_data_ext wipes the sequence first, making chunk by chunk restore impossible (e.g. restoring chunk 1 destroys chunk 0)

This PR adds a new flag LLAMA_STATE_SEQ_FLAGS_APPEND (value 2) that skips the seq_rm call, allowing repeated state_seq_set_data_ext calls to append to the same sequence, using the existing llama_state_seq_flags mechanism (precedentLLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY is from #16382).

Exact changes:

  • include/llama.h: add #define LLAMA_STATE_SEQ_FLAGS_APPEND 2
  • src/llama-kv-cache.h: add flags param to state_read_meta
  • src/llama-kv-cache.cpp: thread flags through state_readstate_read_meta, gate seq_rm on !(flags & APPEND)

default behavior (flags=0) is unchanged.

motivation: this enables external KV cache systems (e.g. LMCache) to store and restore opaque state blobs one chunk at a time, without reassembling into a single monolithic blob or parsing the internal serialization format.

Requirements

Add a new flag LLAMA_STATE_SEQ_FLAGS_APPEND (value 2) that skips the
seq_rm() call in state_read_meta, allowing incremental chunk-by-chunk
restore to the same sequence via repeated state_seq_set_data_ext calls.

This enables external KV cache systems to restore opaque state blobs
one chunk at a time without each chunk clearing the previous one.

- Add #define LLAMA_STATE_SEQ_FLAGS_APPEND 2 in llama.h
- Thread flags parameter through state_read() to state_read_meta()
- Gate seq_rm() on !(flags & LLAMA_STATE_SEQ_FLAGS_APPEND)
- Default behavior (flags=0) is unchanged
@sammshen
sammshen requested a review from ggerganov as a code owner March 31, 2026 10:55
@ggerganov

Copy link
Copy Markdown
Member

But how do you store the chunks in the first place? We currently only store full sequences.

@ggml-gh-bot

ggml-gh-bot Bot commented Mar 31, 2026

Copy link
Copy Markdown

Hi @sammshen, thanks for your contribution!

Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:

  • AI-generated content: This project does not accept PRs, descriptions or commit messages that are fully or predominantly AI-generated. If you have used AI to assist you in writing code, please make sure to disclose that explicitly.

Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below.

Comment thread src/llama-kv-cache.h
void state_write_data(llama_io_write_i & io, const cell_ranges_t & cr) const;

bool state_read_meta(llama_io_read_i & io, uint32_t strm, uint32_t cell_count, slot_info & sinfo, llama_seq_id dest_seq_id = -1);
bool state_read_meta(llama_io_read_i & io, uint32_t strm, uint32_t cell_count, slot_info & sinfo, llama_seq_id dest_seq_id = -1, llama_state_seq_flags flags = 0);

@sammshen sammshen Mar 31, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default no change

@sammshen

sammshen commented Mar 31, 2026

Copy link
Copy Markdown
Author

@ggerganov thanks for the quick response!

we can use the existing API via seq_cp.

for instance:

to serialize only positions [256, 512) from seq 0, we can do:

  1. seq_cp(0, TEMP_SEQ, 256, 512) // tag cells [256, 512) with metadata w/o GPU xfer
  2. state_seq_get_data(ctx, buf, size, TEMP_SEQ) // serialize only cells tagged TEMP_SEQ (i.e. read only chunk's rows)
  3. seq_rm(TEMP_SEQ, -1, -1) // remove temp tag (w/o GPU xfer)

so store is seq_cp + state_seq_get_data + seq_rm and restore is state_seq_set_data_ext w/ APPEND flag (from this PR

sorry I chose 256 here because I am planning on using this to integrate with LMCache's "chunk" size

@ggerganov

Copy link
Copy Markdown
Member

Ah, yes. Interesting.

@sammshen

sammshen commented Mar 31, 2026

Copy link
Copy Markdown
Author

@ggerganov if the change doesn't make sense, I would happy to make any needed changes (or please lmk if you think it doesn't make sense in general, I can go back to the drawing board). I can link the LMCache integration once it's ready if that helps? (even though this PR has nothing to do with LMCache)

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.

2 participants