KV Cache Reuse#
KV cache reuse is a process-local, content-addressed cache for repeated input prefixes. It can reuse prefill state from documents, prior turns, generated continuations, and repeated image prefixes. Entries are isolated by LoRA adapter and live for the lifetime of one runtime instance.
Support Matrix#
This is the authoritative support matrix for generalized context reuse. It does not describe the legacy exact system-prompt cache or the separate encoder embedding cache.
Every supported attention pool, including an independently owned draft pool, must use FP16 or FP8 KV storage and valid page geometry. For speculative deployments, the base role, draft role, method, and execution geometry must match.
Deployment |
Status |
Contract |
|---|---|---|
Vanilla, attention-only text model |
Supported |
No snapshot pool is required. |
Vanilla, pure recurrent text model |
Supported |
The recurrent snapshot budget must provide at least one slot. |
Vanilla, hybrid attention/recurrent text model |
Supported |
Recurrent and partial-KV snapshot budgets must each provide at least one slot. |
Vanilla image input on a supported base topology |
Supported in the C++ runtime |
Uses media identity. |
Vanilla audio input on a supported base topology |
Implemented, not release-qualified |
Uses media identity, but release validation does not cover audio-input reuse. |
Attention-only EAGLE3 |
Supported |
The draft owns an independent KV pool, and the final matched page is replayed for the one-token future dependency. Linear and tree drafting are accepted. |
Attention-only DFlash, JetSpec, or DSpark |
Supported |
The draft owns an independent KV pool. These methods have no future-token replay dependency. |
Gemma4 MTP |
Supported |
The read-only assistant shares target KV, owns no draft page pool, and has no future-token replay dependency. |
MTP with a hybrid attention/recurrent base |
Supported |
The attention-only draft owns independent KV. Reuse requires a text-only batch of one, endpoint-only capture, |
Standard MTP with an attention-only base |
Rejected |
Only hybrid MTP and the separate Gemma4 MTP contract are supported. |
Pure-recurrent speculative decoding, or hybrid EAGLE3/DFlash/JetSpec/DSpark |
Rejected |
The only supported recurrent speculative deployment is hybrid MTP. |
Speculative request containing image or audio input |
Bypassed |
The request runs cold on coordinator-managed pages and neither looks up nor publishes reusable state. |
Speech generation or thinker-hidden-state output |
Bypassed |
The request runs without lookup or publication. |
Vision-bidirectional attention or block diffusion |
Rejected |
The runtime cannot initialize generalized context reuse for these deployments. |
Action runner |
Rejected |
The runtime cannot initialize an action runner and generalized context reuse together. |
Tensor parallel execution |
Not supported |
The public inference workflows reject context reuse when tensor-parallel size is greater than one. |
The experimental Python API and server expose the supported text-only contracts through the same native runtime.
Media Identity#
For vanilla media requests, decoded image bytes or PCM audio samples and their placeholder positions are part of the cache identity. Audio without decoded PCM uses its mel-spectrogram path. Changing media content or order invalidates the affected prefix. Speculative media requests follow the bypass behavior in the matrix.
Cache Domain#
A cache-enabled runtime is one trusted domain. Use separate runtime instances when requests require tenant isolation; there is no request-level tenant or salt key.
Build Capacity#
--maxKVPoolPages controls the total page pool. Reserve pages beyond the
active-request minimum when retained contexts must remain resident:
./build/examples/llm/llm_build \
--onnxDir /path/to/onnx/llm \
--engineDir /path/to/engine \
--maxInputLen 1024 \
--maxKVCacheCapacity 4096 \
--maxKVPoolPages 64
Enable Reuse#
./build/examples/llm/llm_inference \
--engineDir /path/to/engine \
--inputFile input.json \
--outputFile output.json \
--enableContextReuse
For a VLM, pass the visual engine and a request set containing repeated image prefixes:
./build/examples/llm/llm_inference \
--engineDir /path/to/engine \
--multimodalEngineDir /path/to/visual/engine \
--inputFile tests/test_cases/vlm_context_reuse.json \
--outputFile output.json \
--enableContextReuse \
--profileOutputFile profile.json
Reuse remains page-aligned, and the runtime recomputes a media span when a page boundary would split it.
The cache retains up to 1024 records by default. Use
--contextCacheMaxRecords only when the deployment needs a different limit.
For matrix rows that require snapshot storage, configure the corresponding budgets:
--contextCacheRecurrentSnapshotPoolBytes 67108864 \
--contextCachePartialKVSnapshotPoolBytes 67108864
The values above are example 64 MiB budgets. Required capacity depends on the model state dimensions and number of retained contexts.
Request Policies#
The top-level request fields select lookup and publication behavior for the entire invocation:
{
"context_cache_lookup_policy": "use_cache",
"context_cache_commit_policy": "prefill_state_only",
"requests": [
{
"messages": [
{"role": "user", "content": "A long reusable context followed by a question"}
]
}
]
}
context_cache_lookup_policy:use_cache(default) orbypass.context_cache_commit_policy:including_generated_tokens(default) orprefill_state_only.
bypass uses coordinator-managed private pages but does not look up or publish
reusable state. Do not combine generalized context reuse with the legacy
save_system_prompt_kv_cache request field.
Configuring the Encoder Embedding Cache#
The encoder embedding cache is separate from KV cache reuse. A runtime with a
ViT or audio runner allows cache entries to use up to 256 MiB of device memory
by default even when --enableContextReuse is not set. It hashes decoded image
bytes or PCM audio samples and retains the corresponding encoder output on the
GPU. A request for identical media can then skip ViT or audio encoder
execution. The cache evicts least-recently-used entries when its budget is
full; an individual entry larger than the budget runs uncached.
Set the C++ runtime budget in bytes with --encoderCacheBudgetBytes; zero
disables the cache:
./build/examples/llm/llm_inference \
--engineDir /path/to/engine \
--multimodalEngineDir /path/to/encoder/engine \
--inputFile input.json \
--outputFile output.json \
--encoderCacheBudgetBytes 134217728
The experimental Python API and server use the same default but do not expose a separate encoder-cache budget in this release. An INFO log reports when all media items hit and encoder execution is skipped. Encoder-cache hit/miss counters are not included in the profile JSON; the context-cache profile fields below describe KV/recurrent-state reuse only.
Use runtime profile output to verify reuse. prefill.reused_tokens must be
positive for a request that reused cached state. For image requests,
context_cache.media_aware_sequences reports how many admitted sequences used
media-aware cache identities.