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 KV | Cache KV @ 128k | Pesos | Cache vs pesos |
|---|---|---|---|---|
| Llama 3.1 8B | 32 × 8 | ~16 GiB | ~16 GiB | ~100 % |
| Qwen2.5 7B | 28 × 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.
o que é isso?git stash: um único arquivo sem perder o resto
Gostou dos artigos? É assim que eu construo profissionalmente. me contrate