Cada ficha de modelo local presume ahora de una ventana de 128k. En un desktop, ese número es un contrato de arrendamiento que tu RAM firma sin leer. Lo que decide hasta dónde puedes llevar un documento largo no son los pesos — es la caché KV, y escala con el contexto como un impuesto acordado en la moneda de otro.
La ventana de contexto no es una función que activas. Es un arrendamiento de memoria que pagas cada segundo que el servidor corre.
¿Cuánta RAM usa realmente un contexto de 128k?
La aritmética es pública y corta. Como detalla Transformer Inference Arithmetic, la caché KV guarda dos tensores — claves y valores — por cada capa, cada cabeza KV, cada token:
cache_bytes = 2 × capas × contexto × cabezas_kv × head_dim × bytes_por_elemento Tomemos Llama 3.1 8B: 32 capas, 8 cabezas KV, head_dim 128, directo del config.json en Hugging Face. A 131.072 tokens en fp16 (2 bytes):
2 × 32 × 131072 × 8 × 128 × 2 = 17.179.869.184 bytes ≈ 16 GiB Los pesos de ese mismo modelo en fp16 pesan unos 16 GiB. A contexto máximo, la caché es tan grande como el modelo al que pertenece. El “modelo 8B que cabe en 16 GiB” se convierte en silencio en un problema de 32 GiB en cuanto pones num_ctx a 128k.
¿Por qué crece la caché con la ventana?
Porque la atención debe comparar cada token con todos los anteriores, y la inferencia es autorregresiva — nada se recalcula, todo se recuerda. Ese es todo el truco que hace rápida la generación: las claves y valores de cada token se calculan una vez y se almacenan. El almacenamiento por token es constante, así que el total es lineal en el contexto. 128k no es “un número más grande” — es 128× la caché de una ventana de 1k, asignada durante toda la sesión.
La grouped-query attention (GQA) es el descuento del lado del modelo: menos cabezas KV, caché más delgada. Qwen2.5 7B usa 28 capas con solo 4 cabezas KV (config aquí), así que la misma ventana de 128k cuesta unos 7 GiB en fp16 — alivio real, y una razón por la que esos modelos se sienten más amables en máquinas modestas.
| Modelo (fp16) | Capas × cabezas KV | Caché KV @ 128k | Pesos | Caché vs pesos |
|---|---|---|---|---|
| Llama 3.1 8B | 32 × 8 | ~16 GiB | ~16 GiB | ~100 % |
| Qwen2.5 7B | 28 × 4 | ~7 GiB | ~15 GiB | ~47 % |
Haz los números tú mismo — esta es toda la comprobación:
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 Lo que el número de marketing omite
Aquí está el registro honesto de este argumento — incluyendo donde se dobla:
- El prefill es la segunda factura. Antes del primer token de respuesta, todo el prompt se procesa de golpe. Un prompt de 100k tokens son 100k tokens que masticar antes del primer carácter. En una 3060, eso son minutos, no milisegundos.
- Los modelos sliding-window rompen el cálculo — a tu favor. Las arquitecturas estilo Mistral limitan la atención a una ventana fija por capa, así que la caché deja de crecer. La fórmula simple los sobreestima. Este post va sobre transformers de atención completa, que es la mayoría de lo que la gente ejecuta.
- La cuantización del KV es real pero parcial. llama.cpp puede cachear el KV en q8_0, reduciendo la caché a la mitad con cierto riesgo de calidad. La mitad de 16 GiB sigue siendo 8 GiB.
- Las specs rara vez mencionan las cabezas KV. Tendrás que excavar en el config.json para encontrarlas, lo cual dice mucho sobre cómo está pensado para leerse ese número.
Nada de esto hace inútil el contexto largo. El RAG existe precisamente porque llenar una ventana es la forma cara de decir “lee la sección 4”. Pero una ficha que imprime “128k” sin imprimir la factura de memoria vende un coche por su velocidad punta sin mencionar nunca el depósito.
Nadie lee 128.000 tokens. Tu RAM los paga igualmente, todos.
El remedio es aburrido: configura el contexto que tu carga de trabajo realmente usa. Una ventana de 32k cuesta un cuarto de la caché de 128k y cubre casi todos los prompts que un desarrollador en solitario envía de verdad. Es la misma disciplina de registro que la aritmética de RAM para LLMs locales — el tamaño del modelo es solo la mitad del presupuesto, y los niveles de cuantización encogen los pesos pero dejan intacto el cálculo de la caché.
Si la caché es el precio real del contexto, ¿por qué las fichas venden la ventana y nunca la factura? Y ronda confesional: ¿cuál es el contexto más grande que has llenado hasta el último token — y la salida justificó los gigabytes? Los comentarios están abiertos; la siguiente pieza de la serie tomará el bando que pierda.
FAQ
¿Cuánta RAM usa una ventana de contexto de 128k?
Para Llama 3.1 8B en fp16, la caché KV sola pesa unos 16 GiB a 131.072 tokens — aproximadamente el tamaño de los pesos. Fórmula: 2 × capas × contexto × cabezas KV × head_dim × bytes.
¿Por qué el contexto largo usa más memoria?
Cada token en caché guarda tensores de claves y valores para cada capa de atención. Duplica el contexto, duplicas la caché. La asignación existe aunque nunca llenes la ventana.
¿Cómo reduzco la memoria de la caché KV en local?
Configura el contexto que realmente usas, elige modelos con grouped-query attention (menos cabezas KV), cuantiza la caché KV a q8 si el runtime lo soporta, o usa arquitecturas sliding-window e híbridas.
— mrsaynothing
— mrsaynothing
Opiniones load-testeadas antes de publicar. Casi siempre.
Recibe el próximo argumento por email
Un email por post. Estás de acuerdo o lo destrozas.
¿qué es esto?git stash: un solo archivo sin perder el resto
¿Te gustan estos artículos? Hago esto para vivir. contrátame