Caching and KV Cache

Purpose and Scope

Caching in Transformers is an inference-time optimization for autoregressive generation. Autoregressive models predict one token at a time, and each next-token decision depends on the context that came before it. Without a cache, the model repeatedly recomputes key and value projections for previous tokens at every generation step. A key-value cache, usually shortened to KV cache, stores those attention-layer key and value tensors after they are computed so later steps can reuse them. This page explains the attention reason caching works, the cache strategies documented by Transformers, and how the strategy choice affects memory, speed, and generation workflows.

Sources: docs/source/en/cache_explanation.md, docs/source/en/kv_cache.md

The core warning is simple: caching is for inference, not training. The documentation explicitly warns that enabling caching during training can cause unexpected errors. That boundary matters because the optimization relies on the fact that, during causal generation, previously processed token representations do not change with respect to future tokens. Training and full-sequence forward passes have different correctness and gradient requirements, so the cache is presented as a generation-time mechanism rather than a general acceleration switch for all model execution.

Sources: docs/source/en/cache_explanation.md, docs/source/ko/cache_explanation.md

Caching is tightly connected to text generation strategy, but it is not itself a decoding strategy. Greedy search, sampling, and beam search decide which token or sequence candidate to choose next. The cache decides how efficiently the model computes the attention inputs needed to score those next tokens. The generation strategy documentation describes generate() as the API where decoding behavior is customized with parameters such as max_new_tokens, do_sample, num_beams, and num_return_sequences; the cache strategy documentation places cache control in the same generation workflow through use_cache, past_key_values, and GenerationConfig#cache_implementation. Sources: docs/source/en/generation_strategies.md, docs/source/en/kv_cache.md

Relevant Source Files

  • docs/source/en/cache_explanation.md - Explains why autoregressive generation repeats attention work, defines the KV cache concept, shows the scaled dot-product attention framing, and states the inference-only warning.
  • docs/source/en/kv_cache.md - Documents cache strategy selection, the default DynamicCache, use_cache=False, pre-initialized cache objects, past_key_values, and GenerationConfig#cache_implementation.
  • docs/source/ko/cache_explanation.md - Korean localization of the cache explanation, including additional visible details about the basic cache.update(k_t, v_t, layer_idx) interface, attention mask shape requirements, and layer storage examples.
  • docs/source/en/generation_strategies.md - Provides the generation context in which cache strategies operate, including GenerationConfig, generate(), greedy search, sampling, beam search, and common generation parameters.
  • docs/source/ja/generation_strategies.md - Japanese generation strategy documentation that reinforces the relationship between PreTrainedModel.generate(), model.generation_config, and customizable decoding parameters.
  • docs/source/ko/generation_strategies.md - Korean generation strategy documentation that reinforces the same generation API concepts and common parameters for multilingual documentation users.

Conceptual Model

Transformer attention uses query, key, and value tensors. The cache explanation describes scaled dot-product attention over a batch size, number of attention heads, sequence length so far, and dimension per head. The query, key, and value matrices are projections from input embeddings with a shape conceptually described as batch, heads, sequence length, and head dimension. In causal attention, the mask prevents attending to future tokens. Once a previous token is processed, its key and value representation can be reused because future tokens do not alter that past representation.

Sources: docs/source/en/cache_explanation.md

At step t, the model only needs the query for the current last token to produce the representation used to predict token t plus one. The prior keys and values can be treated as already-known context. The cache grows by storing the new key and value vectors and appending them to the past keys and values. The documentation emphasizes that attention is computed independently in each model layer, so caching is also per-layer. That per-layer structure is important when reasoning about memory: every layer maintains its own stored key and value tensors, not a single global attention buffer.

Sources: docs/source/en/cache_explanation.md, docs/source/ko/cache_explanation.md

The efficiency tradeoff follows directly from that structure. Without caching, each step recomputes all previous K and V tensors; with caching, each step computes only the current token's K and V and reuses the stored tensors from earlier steps. The documentation summarizes this as a move from quadratic attention work per step with respect to sequence length to linear per-step behavior for the cache update path, while memory still grows linearly with the amount of stored context. In practice, this is why KV caching is central to responsive long-form generation.

Sources: docs/source/en/cache_explanation.md

Cache Strategies

Transformers documents several Cache classes with different optimization goals. DynamicCache is the default for all models. It grows as generation progresses, storing more keys and values as new tokens are produced. This makes it convenient because users usually do not need to size the cache up front. The cache strategy page notes that for models with sliding window attention, such as Mistral and Gemma2, or chunked attention, such as Llama4, the cache stops growing once those layers reach their maximum sliding window or chunk size. That model-specific behavior keeps cache growth aligned with the attention mechanism.

Sources: docs/source/en/kv_cache.md

StaticCache is documented as the option that supports torch.compile(), while DynamicCache does not. This difference is a direct consequence of shape stability: a dynamically growing cache is easier to use, but changing shapes can be unfriendly to graph capture and compilation. The documented tradeoff is that StaticCache has high expected memory usage, while DynamicCache has medium expected memory usage. When the priority is maximizing compiled generation throughput and the memory budget is available, the static strategy is the one the cache comparison table points readers toward.

Sources: docs/source/en/kv_cache.md

QuantizedCache is documented as the low-memory option, but with narrower support: it does not support sliding layers, offloading, or torch.compile() in the comparison table. This makes it a memory-saving strategy rather than a universal default. The table also states that DynamicCache and StaticCache support offloading and sliding layers, while QuantizedCache does not. A useful way to choose is to start with the default dynamic behavior, move to static when compile support and predictable shapes matter, and consider quantized caching when memory pressure dominates the decision.

Sources: docs/source/en/kv_cache.md

API Components and Controls

The most direct user-facing control is use_cache=False passed to GenerationMixin.generate. The cache strategy documentation shows disabling the cache when calling model.generate(**inputs, do_sample=False, max_new_tokens=20, use_cache=False). Disabling the cache is useful for comparison, debugging, or cases where memory is more important than generation speed. For normal autoregressive inference, however, leaving caching enabled is the optimized path because it avoids repeated computation of previous key and value tensors.

Sources: docs/source/en/kv_cache.md

For finer control, the documentation states that cache classes can be initialized before generation and passed through the model output path associated with GenerateDecoderOnlyOutput#past_key_values. This is especially useful for advanced workflows such as context caching, where a prefix or conversation context may be reused across subsequent generation calls. Most readers should still prefer GenerationConfig#cache_implementation, because the docs describe it as the easier way to define the cache strategy in common cases. In other words, explicit cache objects are for control; generation configuration is for ergonomic strategy selection.

Sources: docs/source/en/kv_cache.md

The Korean cache explanation makes the underlying contract concrete with a small interface sketch: a cache receives the current token's key and value tensor for a layer, updates storage, and returns the updated key and value tensors used by that attention layer. It also calls out an important shape constraint for custom generation loops. When forward is called repeatedly, the attention mask must match the combined length of past and current key-value pairs, commonly shaped as batch size by past KV length plus new token length. generate() usually handles this internally, but custom loops must preserve it.

Sources: docs/source/ko/cache_explanation.md

Execution Flow in Generation

A typical cached generation flow starts by tokenizing the prompt and sending the tensors to the model device. The generation strategy documentation uses AutoTokenizer.from_pretrained, AutoModelForCausalLM.from_pretrained, and model.generate(**inputs, max_new_tokens=20) for greedy search. With caching enabled, the first forward pass computes keys and values for the prompt context. Subsequent decoding steps then pass or maintain past_key_values so each layer can combine cached keys and values with the newly computed current token projections instead of rebuilding the full history from scratch.

Sources: docs/source/en/generation_strategies.md, docs/source/en/kv_cache.md

Decoding parameters change how many candidate paths may need cache state. Greedy search chooses the most likely next token at each step, while sampling randomly selects from the vocabulary probability distribution when do_sample=True and num_beams=1. Beam search tracks multiple candidate sequences at each time step. These strategies affect generation quality and search breadth, while the cache keeps the repeated attention computation efficient for whichever strategy is active. The key distinction for developers is that cache strategy optimizes the mechanics of scoring tokens; decoding strategy governs which scored tokens become output.

Sources: docs/source/en/generation_strategies.md, docs/source/ja/generation_strategies.md, docs/source/ko/generation_strategies.md

The generation docs also explain that GenerationConfig is where a model's default decoding behavior is stored and inspected through model.generation_config. Parameters passed directly to generate() override that configuration for a call. The cache docs use the same configuration surface for cache_implementation, so cache selection belongs beside other generation decisions such as length, sampling, and beams. This placement is helpful operationally: production code can keep cache policy and decoding policy together, while still overriding per-request settings when latency, memory, or output diversity requirements differ.

Sources: docs/source/en/kv_cache.md, docs/source/en/generation_strategies.md

Compact Reference

Component or optionDocumented rolePractical implication
CacheShared cache abstraction for generation key-value storageChoose an implementation based on memory, offloading, compile support, and model attention style
DynamicCacheDefault cache class for all modelsConvenient growing cache with medium expected memory usage, sliding-layer support, and offloading support
StaticCacheFixed-shape cache strategyHigher memory use, but supports torch.compile() and offloading
QuantizedCacheLow-memory cache strategySaves memory, but lacks sliding-layer, offloading, and compile support in the documented comparison
use_cache=Falsegenerate() option to disable cachingUseful for debugging or memory tradeoffs, but slower for autoregressive inference
GenerationConfig#cache_implementationConfiguration field for cache strategyPreferred common path for selecting a cache implementation
past_key_valuesAdvanced cache handoff pointUseful for explicit cache objects and context caching workflows
cache.update(k_t, v_t, layer_idx)Basic conceptual cache update operationStores current layer key-value tensors and returns combined tensors for attention

Sources: docs/source/en/kv_cache.md, docs/source/ko/cache_explanation.md

Practical Guidance and Next Steps

Start with the default DynamicCache unless you have a clear reason to do otherwise. It matches the default documented behavior, supports sliding and chunked attention constraints, and grows with generation length. If you are optimizing a compiled inference path, evaluate StaticCache because compile support is the key documented differentiator. If the model or deployment is memory constrained, compare QuantizedCache against the default, while remembering that the documented support matrix removes offloading, sliding layers, and torch.compile() from that option. Always validate quality and latency with the same decoding parameters you will use in production.

Sources: docs/source/en/kv_cache.md, docs/source/en/generation_strategies.md

When building custom generation loops, treat mask length and cache length as part of the public correctness contract. The docs state that the attention mask must cover both past cached tokens and new tokens, even though generate() handles this for standard usage. For most applications, keep the high-level generation API and configure max_new_tokens, do_sample, num_beams, and cache behavior through generate() or GenerationConfig. Next, read the Text Generation page for decoding behavior, the Generation API reference for lower-level generation objects, and the Inference Optimization page for broader serving and latency techniques.

Sources: docs/source/ko/cache_explanation.md, docs/source/en/generation_strategies.md