Voltar ao blog

128k de contexto no desktop é mentira. O cache KV comeu tudo.

22 de setembro de 2026

Toda ficha de modelo local agora se gaba de uma janela de 128k. No desktop, esse número é um contrato de aluguel que sua RAM assina sem ler. O que decide até onde você consegue empurrar um documento longo não são os pesos — é o cache KV, e ele escala com o contexto como um imposto combinado na moeda de outro país.

A janela de contexto não é um recurso que você liga. É um aluguel de memória que você paga a cada segundo em que o servidor roda.

Quanta RAM um contexto de 128k realmente usa?

A aritmética é pública e curta. Como detalha Transformer Inference Arithmetic, o cache KV guarda dois tensores — chaves e valores — para cada camada, cada cabeça KV, cada token:

cache_bytes = 2 × camadas × contexto × cabeças_kv × head_dim × bytes_por_elemento

Pegue o Llama 3.1 8B: 32 camadas, 8 cabeças KV, head_dim 128, direto do config.json no Hugging Face. A 131.072 tokens em fp16 (2 bytes):

2 × 32 × 131072 × 8 × 128 × 2 = 17.179.869.184 bytes ≈ 16 GiB

Os pesos desse mesmo modelo em fp16 pesam uns 16 GiB. No contexto máximo, o cache é tão grande quanto o modelo a que pertence. O “modelo 8B que cabe em 16 GiB” vira silenciosamente um problema de 32 GiB no instante em que você sobe o num_ctx para 128k.

Por que o cache cresce com a janela?

Porque a atenção precisa comparar cada token com todos os anteriores, e a inferência é autorregressiva — nada é recalculado, tudo é lembrado. Esse é todo o truque que torna a geração rápida: as chaves e valores de cada token são calculados uma vez e guardados. O armazenamento por token é constante, então o total é linear no contexto. 128k não é “um número maior” — é 128× o cache de uma janela de 1k, alocado pela sessão inteira.

A grouped-query attention (GQA) é o desconto do lado do modelo: menos cabeças KV, cache mais magro. O Qwen2.5 7B usa 28 camadas com apenas 4 cabeças KV (config aqui), então a mesma janela de 128k custa uns 7 GiB em fp16 — alívio real, e um motivo pelo qual esses modelos parecem mais generosos em máquinas modestas.

Modelo (fp16)Camadas × cabeças KVCache KV @ 128kPesosCache vs pesos
Llama 3.1 8B32 × 8~16 GiB~16 GiB~100 %
Qwen2.5 7B28 × 4~7 GiB~15 GiB~47 %

Faça a conta você mesmo — esta é toda a verificação:

def kv_cache_gib(layers, kv_heads, head_dim, ctx, bytes_per=2):
    return 2 * layers * ctx * kv_heads * head_dim * bytes_per / 2**30

print(kv_cache_gib(32, 8, 128, 131_072))  # Llama 3.1 8B  -> 16.0
print(kv_cache_gib(28, 4, 128, 131_072))  # Qwen2.5 7B    -> 7.0

O que o número de marketing deixa de fora

Aqui está o livro-razão honesto deste argumento — incluindo onde ele dobra:

  • O prefill é a segunda conta. Antes do primeiro token de resposta, o prompt inteiro é processado de uma vez. Um prompt de 100k tokens são 100k tokens para mastrar antes do primeiro caractere. Numa 3060, isso são minutos, não milissegundos.
  • Modelos sliding-window quebram a conta — a seu favor. Arquiteturas estilo Mistral limitam a atenção a uma janela fixa por camada, então o cache para de crescer. A fórmula simples superestima esses modelos. Este post vale para transformers de atenção completa, que é a maioria do que as pessoas rodam.
  • Quantização do KV é real, mas parcial. O llama.cpp pode guardar o KV em q8_0, reduzindo o cache à metade com algum risco de qualidade. Metade de 16 GiB ainda é 8 GiB.
  • As specs raramente citam as cabeças KV. Você vai ter que escavar o config.json para achá-las — o que diz muito sobre como esse número foi pensado para ser lido.

Nada disso torna o contexto longo inútil. O RAG existe justamente porque encher uma janela é a forma cara de dizer “leia a seção 4”. Mas uma ficha que imprime “128k” sem imprimir a conta de memória vende um carro pela velocidade máxima e nunca menciona o tanque.

Ninguém lê 128.000 tokens. Sua RAM paga por todos eles mesmo assim.

O remédio é sem graça: configure o contexto que sua carga de trabalho realmente usa. Uma janela de 32k custa um quarto do cache de 128k e cobre quase todo prompt que um desenvolvedor sozinho realmente envia. É a mesma disciplina de a aritmética de RAM para LLMs locais — o tamanho do modelo é só metade do orçamento, e os níveis de quantização encolhem os pesos mas deixam a conta do cache intacta.

Se o cache é o preço real do contexto, por que as fichas vendem a janela e nunca a conta? E rodada confessional: qual o maior contexto que você realmente encheu até o último token — e a saída justificou os gigabytes? Os comentários estão abertos; o próximo texto da série fica com o lado que perder.

FAQ

Quanta RAM uma janela de contexto de 128k usa?

Para o Llama 3.1 8B em fp16, só o cache KV pesa cerca de 16 GiB a 131.072 tokens — aproximadamente o tamanho dos pesos. Fórmula: 2 × camadas × contexto × cabeças KV × head_dim × bytes.

Por que contexto longo usa mais memória?

Cada token em cache guarda tensores de chaves e valores para cada camada de atenção. Dobrou o contexto, dobra o cache. A alocação existe mesmo que você nunca encha a janela.

Como reduzir a memória do cache KV em LLMs locais?

Configure o contexto que você realmente usa, escolha modelos com grouped-query attention (menos cabeças KV), quantize o cache KV para q8 onde o runtime suporta, ou use arquiteturas sliding-window e híbridas.

— mrsaynothing

— mrsaynothing

Opiniões load-testadas antes de publicar. Quase sempre.

Receba o próximo argumento por email

Um email por post. Concorde ou desmonte.

self-hosted · sem terceiros · cancelamento com um clique

o que é isso?

git stash: um único arquivo sem perder o resto

Gostou dos artigos? É assim que eu construo profissionalmente. me contrate