Cache KV vs cache de prompt: qual a diferença?
Entenda por que o cache KV consome RAM ou VRAM a cada pedido, pode impedir o carregamento do modelo e não é igual ao cache de prompt do fornecedor.
Cache KV vs. cache de prompt: a resposta curta
O cache KV e o cache de prompt de um fornecedor partilham uma palavra e quase nada mais. O cache KV é memória de trabalho por pedido. Fica na RAM ou VRAM do seu servidor durante toda a duração de um pedido e cresce com o tamanho do contexto e com o número de pedidos executados em simultâneo. O cache de prompt é uma funcionalidade de faturação e latência. Um prefixo estável do seu prompt é armazenado nos servidores do fornecedor e, quando o envia novamente, é cobrado com desconto.
Um é memória que compra como hardware. O outro é memória que outra entidade mantém e pela qual lhe cobra renda.
A diferença prática é mais importante do que a definição. Pode ficar sem cache KV e, quando isso acontece, o modelo não carrega ou o pedido é rejeitado. Não pode ficar sem cache de prompt. Pode apenas não conseguir obter um acerto no cache e, nesse caso, paga discretamente o preço total.
O que a cache KV armazena e por que existe
Um transformer que gera o token número 500 tem de prestar atenção aos 499 tokens anteriores. Para cada um desses tokens, cada camada precisa de um vetor de chave e de um vetor de valor. Recalculá-los todos para cada novo token faria a geração crescer com o quadrado do comprimento, por isso o runtime mantém esses dados. Esse armazenamento é a cache KV (cache de chave/valor).
É um estado por pedido, porque é construído a partir da sequência exata de tokens desse pedido. Dois utilizadores que enviem prompts diferentes não podem partilhá-lo, exceto se o runtime usar cache de prefixo, uma funcionalidade separada descrita mais adiante.
O serving ocorre em duas fases. O prefill lê todo o prompt e preenche a cache, sendo limitado pelo processamento. O decode produz um token de cada vez e acrescenta-o à cache, sendo limitado pela largura de banda da memória. É por isso que o processamento do prompt e a geração de tokens apresentam velocidades diferentes quando mede tokens por segundo no seu próprio servidor.
Quanta memória a cache KV utiliza?
Não procure uma tabela do fornecedor. O tamanho resulta de uma operação aritmética que pode repetir para qualquer modelo:
bytes per token = 2 * layers * kv_heads * head_dim * bytes per elementO 2 corresponde à chave e ao valor. Todos os outros números vêm da config.json do modelo, publicada na respetiva página no Hugging Face.
Considere o Llama 3.1 8B. A configuração lista num_hidden_layers 32 e num_key_value_heads 8. A hidden_size de 4096, distribuída por 32 cabeças de atenção, resulta numa dimensão de cabeça de 128. Em f16, cada elemento ocupa 2 bytes:
2 * 32 * 8 * 128 * 2 = 131072 bytes = 128 KiB per tokenMultiplique esse valor pelo contexto solicitado e depois pelo número de pedidos executados em simultâneo.
The data behind this chart
[
{
"label": "2k context",
"one_request_gib": 0.25,
"four_requests_gib": 1
},
{
"label": "8k context",
"one_request_gib": 1,
"four_requests_gib": 4
},
{
"label": "32k context",
"one_request_gib": 4,
"four_requests_gib": 16
},
{
"label": "128k context",
"one_request_gib": 16,
"four_requests_gib": 64
}
]Com um contexto de 8k, a cache ocupa 1 GiB para um pedido. Com 32k, ocupa 4 GiB, um valor da mesma ordem dos próprios pesos de 4 bits. No contexto máximo de 128k do modelo, ocupa 16 GiB para um pedido e 64 GiB se quatro pedidos a preencherem completamente. Os pesos não mudaram. Apenas a cache mudou.
A atenção de consulta agrupada (GQA) tem um impacto importante nesse valor. O Llama 3.1 8B tem 8 cabeças de chave/valor a servir 32 cabeças de consulta, pelo que cada quatro cabeças de consulta partilham um par de chave/valor armazenado. Um modelo cujo num_key_value_heads seja igual a num_attention_heads utiliza quatro vezes mais cache com o mesmo número de parâmetros. Verifique esse campo antes de assumir que dois modelos 8B têm o mesmo custo de execução.
Por que um modelo que funcionava com 2k recusa carregar com 32k
O runtime reserva a cache KV quando carrega o modelo. O tamanho baseia-se no comprimento de contexto configurado, não no prompt que envia efetivamente. A janela de contexto predefinida do Ollama é de 4096 tokens. Se a aumentar para 32k, está a pedir 4 GiB de alocação adicional antes de chegar um único token.
OLLAMA_CONTEXT_LENGTH=32768 ollama serveA mesma definição por sessão, a partir do prompt interativo:
ollama run llama3.1:8b
/set parameter num_ctx 32768A falha manifesta-se de forma diferente em cada stack. O vLLM verifica os cálculos no arranque e recusa executar:
ValueError: The model's max seq len (131072) is larger than the maximum number of tokens that can be stored in KV cache (78336). Try increasing `gpu_memory_utilization` or decreasing `max_model_len` when initializing the engine.Numa VPS apenas com CPU, não existe essa verificação, porque a alocação usa RAM normal do sistema. Em vez disso, o kernel OOM killer termina o processo e deixa as evidências no buffer circular do kernel:
dmesg -T | grep -i "killed process"Uma linha que identifique o processo de serving significa que o sistema prometeu mais memória do que tinha. A correção é usar um contexto menor, não um ficheiro de swap maior: uma cache KV paginada em disco é lida a cada token gerado, por isso a geração fica tão lenta que se torna inútil. A escolha de um valor adequado é explicada no nosso guia sobre num_ctx e o comprimento de contexto no Ollama.
O efeito da concorrência no número
Cada pedido em execução mantém a sua própria cache KV. Esta é a parte que falta na maioria dos planos de capacidade. Quatro utilizadores, cada um com um contexto de 32k, precisam de 16 GiB no total, além dos pesos.
Os runtimes diferem no grau de rigidez deste comportamento. O Ollama e o llama.cpp reservam, quando o modelo é carregado, o contexto que foi configurado, pelo que a memória fica comprometida mesmo que ninguém a utilize. O vLLM divide o pool em blocos de tamanho fixo e atribui-os à medida que cada pedido cresce, pelo que um pedido de 500 tokens ocupa apenas o espaço correspondente a 500 tokens. Em qualquer dos casos, o pool é finito. Quando fica cheio, os novos pedidos entram em fila em vez de serem executados. O impacto dessa fila nos tempos de resposta é explicado em quantos utilizadores simultâneos um LLM autoalojado consegue servir.
Four ways to make the KV cache smaller
- Lower the context length. This is the biggest lever and usually the cheapest. Most chat workloads never come close to 32k.
- Quantise the cache itself. Ollama's
OLLAMA_KV_CACHE_TYPEdefaults tof16and acceptsq8_0, which uses about half the memory, andq4_0, which uses about a quarter. The llama.cpp equivalents are-ctk q8_0and-ctv q8_0. - Pick a model with fewer key/value heads or fewer layers. Read
config.jsonbefore you download 40 GB of weights. - Serve fewer requests at once and queue the rest.
At q4_0 the Llama 3.1 8B figure drops from 128 KiB per token to roughly 32 KiB, so 32k of context costs about 1 GiB instead of 4 GiB. That saving is not free. The keys and values are stored with less precision, so compare output on your own prompts before you keep it.
O que o armazenamento em cache de prompts do fornecedor realmente oferece
O armazenamento em cache de prompts do fornecedor é um produto diferente, com uma unidade de cobrança diferente. Você define um prefixo estável, o fornecedor armazena-o e as chamadas posteriores que repetem exatamente o mesmo prefixo são cobradas a uma tarifa reduzida, em vez do preço total dos tokens de entrada.
Multiplicadores publicados pela Anthropic, em agosto de 2026: uma gravação em cache de 5 minutos custa 1.25 vezes o preço base dos tokens de entrada. Uma gravação de 1 hora custa 2 vezes, e uma leitura do cache custa 0.1 vezes. Se colocar um prompt de sistema com 20,000 tokens nesses valores, a vantagem fica evidente.
The data behind this chart
[
{
"label": "No caching, every call",
"billed_token_equivalents": "20,000"
},
{
"label": "First call, 5 minute cache write",
"billed_token_equivalents": "25,000"
},
{
"label": "First call, 1 hour cache write",
"billed_token_equivalents": "40,000"
},
{
"label": "Every later call, cache hit",
"billed_token_equivalents": "2,000"
}
]Leia isto como uma operação aritmética. O custo adicional da gravação de 5 minutos equivale a 5,000 tokens na primeira chamada: 25,000 contra 20,000 pelo envio sem cache. Cada chamada posterior dentro da janela custa 2,000 em vez de 20,000, uma economia de 18,000. Portanto, o cache de 5 minutos é vantajoso a partir da segunda chamada.
O cache de 1 hora é uma aposta diferente. A gravação custa 40,000, um adicional de 20,000 tokens equivalentes. Por isso, precisa de dois acessos dentro da hora para começar a compensar. Isso depende do seu padrão de tráfego, não do modelo. O cálculo completo, incluindo como escolher a janela, está em a matemática do ponto de equilíbrio do armazenamento em cache de prompts do Claude.
Dois detalhes determinam se você usará o cache. Primeiro, um prefixo abaixo do comprimento mínimo do modelo não é armazenado em cache, sem aviso: em agosto de 2026, o mínimo documentado é de 512 tokens para Claude Opus 5 e 1,024 tokens para Claude Sonnet 5. Uma solicitação mais curta é processada normalmente e não retorna nenhum erro. Segundo, a duração é medida a partir do início da solicitação que grava ou lê a entrada, e cada leitura atualiza o prazo sem custo adicional. Portanto, um endpoint ocupado mantém um cache de 5 minutos ativo indefinidamente. Um endpoint chamado uma vez a cada dez minutos paga o custo adicional da gravação todas as vezes e nunca obtém leituras do cache.
Verifique a resposta em vez de presumir. O objeto usage informa cache_creation_input_tokens e cache_read_input_tokens. Uma contagem de leituras igual a zero em todas as chamadas significa que você está pagando pelas gravações e não está obtendo nenhum benefício.
Onde os dois caches se encontram
Um prompt de sistema longo é o ponto de encontro entre eles e é cobrado dos dois lados ao mesmo tempo.
Localmente, um prompt de sistema com 20,000 tokens ocupa cerca de 2.4 GiB do cache KV num servidor Llama 3.1 8B a f16. Isto acontece separadamente para cada pedido simultâneo que o inclui. Remotamente, esse mesmo prefixo custa uma escrita no cache e, depois, 0.1 vezes o custo de entrada em cada chamada seguinte. O custo local aumenta com o número de utilizadores. O custo remoto aumenta com o tráfego e é reposto durante os períodos de inatividade.
Existe uma funcionalidade local semelhante ao prompt caching do fornecedor e que é frequentemente confundida com ele: o prefix caching. A documentação do vLLM descreve o automatic prefix caching como o armazenamento em cache "do cache KV de consultas existentes, para que uma nova consulta possa reutilizar diretamente o cache KV se partilhar o mesmo prefixo com uma das consultas existentes". O servidor llama.cpp mantém, por predefinição, um prompt cache por slot, e --cache-reuse N define o menor bloco que tentará reutilizar.
O prefix caching poupa computação de prefill. O seu prompt de sistema com 20,000 tokens é processado uma vez, em vez de ser processado em cada pedido, o que reduz bastante o tempo até ao primeiro token. No vLLM, os blocos partilhados são reutilizados em vez de duplicados, pelo que o consumo de memória também melhora. O que esta funcionalidade nunca faz é reduzir o cache que tem de manter para os tokens atualmente ativos. Manter os pesos residentes entre pedidos é uma medida relacionada, mas separada, abordada em manter um modelo Ollama carregado entre pedidos.
O que medir no seu próprio servidor
Carregue o modelo com o contexto pretendido e leia os valores reais, em vez de confiar na estimativa.
ollama ps
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
free -gollama ps lista o modelo carregado, com o respetivo tamanho e indicação de que está a ser executado na GPU ou na CPU. Se esperava que um modelo ficasse totalmente na GPU, mas é apresentada uma divisão com a CPU, isso significa que a cache KV expulsou parte do modelo da GPU, e a velocidade de geração diminuirá proporcionalmente. nvidia-smi apresenta o valor real de VRAM, e free -g faz o mesmo numa VPS apenas com CPU. Aumente o contexto em etapas, recarregue o modelo e observe a variação do valor. O seu cálculo e o valor apresentado devem ficar próximos. Quando isso não acontece, a diferença costuma corresponder aos buffers de computação do próprio runtime, e não a um erro na fórmula.
Se esses valores o levarem a escolher hardware que preferia não alugar, a comparação com o pagamento por token está desenvolvida em GPU VPS em comparação com tokens de API.
FAQ
A KV cache é a mesma coisa que o prompt caching?
Não. A KV cache é uma memória por pedido dentro do processo de serving. Contém os vetores key e value de cada token no contexto atual. Fica na RAM ou na VRAM e é libertada quando o pedido termina. O prompt caching do fornecedor é uma funcionalidade de faturação. Armazena um prefixo estável do prompt na infraestrutura do fornecedor e aplica uma tarifa reduzida quando o envia novamente. Ficar sem KV cache impede o carregamento do modelo. Não haver prompt cache apenas aumenta o valor da fatura e o tempo até ao primeiro token.
Porque é que o meu modelo carrega com contexto de 2k, mas falha com 32k?
Porque o runtime aloca toda a KV cache no carregamento. O tamanho baseia-se no comprimento de contexto configurado, não no prompt que envia. Para Llama 3.1 8B em f16, a cache ocupa 128 KiB por token. Assim, 2k de contexto custa 0.25 GiB e 32k custa 4 GiB. Os pesos cabem nos dois casos. O que falha é a reserva de memória. O vLLM apresenta o problema como ValueError, indicando o número máximo de tokens que conseguiu armazenar, e sugere aumentar gpu_memory_utilization ou reduzir max_model_len. Num servidor apenas com CPU, o kernel out-of-memory killer termina o processo. Pode confirmar isso com dmesg -T | grep -i "killed process".
Como calculo o tamanho da KV cache do meu modelo?
Multiplique 2 pelo número de camadas, pelo número de cabeças key/value, pela dimensão da cabeça e pelo número de bytes por elemento. O resultado corresponde ao número de bytes por token. Depois, multiplique esse valor pelo comprimento de contexto e pelo número de pedidos concorrentes. Consulte no config.json do modelo o número de camadas e de cabeças. Use 2 bytes por elemento para f16 ou bf16. Uma cache q8_0 ocupa aproximadamente metade desse espaço, e uma cache q4_0 aproximadamente um quarto.
O prompt caching reduz a memória necessária no meu próprio servidor?
O prompt caching do fornecedor não afeta o seu hardware, porque o armazenamento fica do lado do fornecedor. O equivalente local é o prefix caching, disponibilizado pelo vLLM e pelo servidor llama.cpp. Esta funcionalidade reutiliza os vetores key e value já calculados para um prefixo partilhado. Isso reduz o processamento de prefill e o tempo até ao primeiro token. No vLLM, os blocos partilhados são reutilizados em vez de duplicados, pelo que o consumo de memória também melhora. Nenhuma das duas funcionalidades reduz a cache necessária para os tokens que estão atualmente em processamento. Por isso, o cálculo do contexto e da concorrência continua a definir o mínimo necessário.
Vale a pena colocar em cache um prompt que só envio uma vez?
Não. Escrever na cache custa mais do que uma entrada normal. Na opção de 5 minutos, o custo é 1.25 vezes a tarifa base em agosto de 2026. Portanto, um prefixo que nunca seja reenviado durante essa janela representa uma perda direta. O caching compensa quando o mesmo prefixo se repete, por exemplo, num system prompt longo ou num documento sobre o qual fará várias perguntas. Consulte cache_read_input_tokens na resposta da API para confirmar que está a obter hits, em vez de pagar por operações de escrita.