Make RotatingKVCache trimmable so prefix cache reuse works for sliding-window models#1437
Open
amirarsalan90 wants to merge 1 commit into
Open
Make RotatingKVCache trimmable so prefix cache reuse works for sliding-window models#1437amirarsalan90 wants to merge 1 commit into
amirarsalan90 wants to merge 1 commit into
Conversation
…g-window models RotatingKVCache reported itself non-trimmable once its ring buffer wrapped, which made can_trim_prompt_cache() return False for the whole interleaved cache of sliding-window models (Gemma 3, GPT-OSS). The server then discarded the prompt cache and recomputed the full prompt on every request. Split the rotating cache's chronological position (offset, drives RoPE) from its physical fill (_offset), implement a correct trim() for the wrapped case by linearizing the ring buffer, and make the server's reuse/eviction paths aware that a rotating cache can only be trimmed back within its window. Refs ml-explore#980.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mlx-lm's automatic prompt-cache prefix reuse works for full-attention models but silently fails for sliding-window-attention models (Gemma 2/3/3n, GPT-OSS) once the prompt exceeds the attention window — every request reprocesses the whole prompt.Root cause:
RotatingKVCache.is_trimmable()returnedFalseonce its ring buffer wrapped. Since sliding-window models interleave layer types (e.g. Gemma 3 mixesRotatingKVCachewith a fullKVCacheevery 6th layer), the all-or-nothingcan_trim_prompt_cache()gate then returnedFalsefor the entire model, so the server discarded the prompt cache and recomputed from scratch.Fix
RotatingKVCache's overloadedoffsetinto two fields:offset(absolute chronological position, drives RoPE) and_offset(physical tokens resident in the ring buffer, capped atmax_size). They diverge only after a trim; pre-wrap behavior is byte-identical. This mirrors the designBatchRotatingKVCachealready uses.trim()for the wrapped case by linearizing the ring buffer into temporal order, bounded bymax_size(older tokens are physically overwritten on wrap, so reuse is bounded by the window).fetch_nearest_cacheonly reuses a trimmed entry if the trim fully succeeded;insert_cachekeeps prefixes older than the window as fallbacks;trim_prompt_cachereturns the min trimmed across layers.Scope:
RotatingKVCache+BatchRotatingKVCache. SSM/Mamba (ArraysCache) is out of scope — recurrent state can't be split at a token boundary.Results
gemma-3-1b-it-4bit, 2802-token prompt ([long fixed prefix] + [short changing tail]), sliding window W=512:cached_tokensGreedy (temperature=0) warm output is identical to cold.
Tests
RotatingKVCache/BatchRotatingKVCachenow report trimmable after wrap and trim correctly back within the window._offsetsave/load round-trip and backward-compat loading of the old 4-valuemeta_state.python -m unittest tests.test_prompt_cache tests.test_server tests.test_generatepasses.Refs #980.