Inicio / Artículos / La caché KV explicada: por qué el contexto largo es una factura de memoria y no inteligencia

La caché KV explicada: por qué el contexto largo es una factura de memoria y no inteligencia

Una explicación clara de la caché KV: qué guarda, cómo calcular su tamaño, por qué el contexto largo se come la memoria y cuatro formas de reducir el gasto en modelos locales.

1921 palabras

Cuando haces cuentas de memoria para modelos locales, el término «caché KV» aparece una y otra vez. Es fácil de calcular y sorprendentemente difícil de explicar. Este texto es pura teoría, sin elegir hardware ni hablar de formatos de archivo. Al terminar sabrás qué hay en la caché, por qué un modelo no puede funcionar sin ella y por qué una ventana de contexto más grande es en realidad una petición de memoria, no de inteligencia.

Por qué existe la caché

Un modelo de lenguaje escribe un token cada vez y, para elegir el siguiente, mira hacia atrás a todos los anteriores. Esa mirada atrás se llama atención (attention) y es un paso costoso.

Imagina ahora que no hubiera caché. Para generar el token 5, el modelo procesa los tokens del 1 al 4. Para el token 6, del 1 al 5. Para el token 7, del 1 al 6. El mismo trabajo se repite sobre los mismos tokens, y el desperdicio crece con cada palabra nueva.

La caché convierte el trabajo repetido en trabajo guardado. El modelo sigue prestando atención a cada token anterior, pero no los recalcula cada vez. La aportación de cada token se calcula una vez, se guarda y se reutiliza durante el resto de la conversación. Por cada token se guardan dos cosas, y de ahí viene el nombre.

Queries, keys y values

Un token empieza siendo una lista de números llamada embedding: puedes pensar en ella como el significado del token escrito en forma de coordenadas. El modelo multiplica ese embedding por tres matrices entrenadas distintas. Quedan fijadas durante el entrenamiento y después no cambian. Cada una convierte la misma entrada en un vector diferente.

Las tres matrices forman parte de los pesos del modelo y son iguales para todos los tokens. Solo cambia el embedding de entrada, así que cada token obtiene sus propios tres vectores de salida.

Piensa en una biblioteca. Cada libro tiene una etiqueta en el lomo y texto en su interior. La etiqueta hace de key (clave), el texto hace de value (valor) y la pregunta con la que llega un visitante hace de query (consulta). Nadie lee la estantería entera. Los visitantes recorren los lomos con la vista, escogen las etiquetas que encajan y abren solo esos libros. La atención hace lo mismo con un matiz: abre todos los libros y luego mezcla su contenido, dando más peso a aquellos cuyas etiquetas encajan mejor con la pregunta.

Las keys sirven para emparejar; los values, para el contenido. Esa separación explica por qué hay que guardar ambas cosas. Una decide cuánto importa un token pasado y la otra dice lo que contiene.

Qué se tira y qué se queda

Solo el token más reciente hace una pregunta. Cuando termina su turno, la pregunta ya tiene respuesta y no vuelve a hacer falta, así que las queries se descartan.

Con las keys y los values es distinto. El modelo volverá a la key y al value del token 5 cuando escriba el token 6, el token 600 y el token 60.000. Y nunca cambian, porque nada de lo que ocurre después altera lo que aportó el token 5. Calcular una vez y guardar para siempre es justo el compromiso correcto.

Por qué la caché crece tanto

Volvamos a la biblioteca. Cada token que llega rellena dos fichas, una etiqueta y una ficha de contenido, y las archiva en el fichero. Mientras la conversación sigue abierta, no se borra nada. Dos factores hacen que ese fichero sea más grande de lo que parece.

Primero, los modelos tienen muchas capas, y cada capa tiene su propia biblioteca. Ochenta capas son ochenta edificios, y en cada uno se archiva un par de fichas por token. Segundo, cada capa reparte el trabajo entre varios lectores, llamados cabezas (heads), y cada lector guarda su propio par, de modo que la cantidad se multiplica otra vez.

En este modelo, un token de conversación cuesta 320 KiB. Mil tokens cuestan 320 MiB. La caché es diminuta por token y enorme por conversación.

Todo en una sola fórmula

Todo lo anterior cabe en una línea, y cada término se puede leer en el config.json del modelo:

cache bytes = 2  ×  layers  ×  tokens  ×  kv_heads  ×  head_dim  ×  bytes_each
              │        │          │           │            │            │
              │        │          │           │            │            └ 2 at FP16, 1 at 8-bit
              │        │          │           │            └ numbers per head
              │        │          │           └ how many key/value sets per layer
              │        │          └ your context length
              │        └ every layer keeps its own
              └ one key and one value

Solo puedes elegir uno de los términos. Las capas, las cabezas y las dimensiones se fijan en el entrenamiento. Los bytes por valor dependen de la precisión de la caché. Los tokens son la longitud del contexto, y esa es la palanca que controlas tú.

Como los tokens están en una multiplicación simple, el crecimiento es lineal e implacable: duplica el contexto y la caché se duplica. No hay descuento por conversaciones largas.

Dos modelos reales, comparados

Con números reales resulta menos abstracto:

  • Qwen3.6-27B mantiene una caché creciente solo en 16 de sus 64 capas, con 4 conjuntos de keys y values en cada una. Coste: 64 MiB por cada 1000 tokens.
  • Llama-3.1-70B la mantiene en sus 80 capas, con 8 conjuntos de keys y values en cada una. Coste: 320 MiB por cada 1000 tokens.

Es cinco veces más caro por token, y la razón es la arquitectura, no el tamaño. El número de parámetros de un modelo no dice nada sobre la factura de su caché.

Un detalle más: Llama-3.1-70B tiene 64 lectores pero solo guarda 8 juegos de fichas. Esa diferencia es intencionada. Grupos de ocho lectores comparten un juego en lugar de que cada uno acumule su propia copia. La técnica se llama grouped-query attention (atención con consultas agrupadas) y la usa casi cualquier modelo moderno. Es como si sesenta y cuatro personas compraran cada una su periódico y, en lugar de eso, circularan ocho ejemplares por la oficina. Todos siguen leyendo, pero la factura del quiosco baja a la octava parte.

El ahorro es de ocho veces con una pequeña pérdida de calidad. Sin él, el contexto largo en un modelo de 70B necesitaría más memoria de la que tiene cualquier máquina individual.

De tokens a páginas

Los recuentos de tokens cuestan de imaginar, así que aquí van las mismas ventanas en unidades de lectura conocidas, contando unas tres cuartas partes de palabra por token:

8K tokens  ≈   6,000 words  ≈   25 pages   a long report
32K tokens  ≈  25,000 words  ≈  100 pages   a short book
128K tokens  ≈  98,000 words  ≈  390 pages   a full novel
256K tokens  ≈ 197,000 words  ≈  790 pages   two novels

Pedir una ventana de 128K es pedirle al modelo que tenga una novela en la cabeza y no la suelte. Llevémoslo a hardware real: Llama-3.1-70B con pesos de 8 bits en una máquina con unos 114 GiB disponibles.

context      weights      cache      total      left over
   8K        65.2 GiB     2.5 GiB    67.7 GiB    46.0 GiB
  32K        65.2 GiB    10.0 GiB    75.2 GiB    38.5 GiB
 128K        65.2 GiB    40.0 GiB   105.2 GiB     8.5 GiB

Con 25 páginas, la caché apenas se nota. Con la longitud de una novela, crece hasta 40 GiB. Para comparar: Qwen3.6-27B completo, con todos sus pesos, ocupa 25 GiB, así que un solo chat del largo de una novela en el modelo de 70B necesita más memoria de la que un buen modelo de 27B necesita en total.

Los pesos no han cambiado. Lo único que ha cambiado es cuánta conversación se le ha pedido al modelo que recuerde.

Una ventana de contexto larga no es un ajuste. Es una reserva de memoria permanente que se paga de nuevo por cada conversación abierta.

Esta parte se pasa por alto a menudo. Los pesos son como el inventario de una tienda: se compran una vez y todos los clientes miran lo mismo. La caché es como un probador. Cada cliente necesita el suyo y queda ocupado hasta que se va. Dos lectores, cada uno con su propia novela, necesitan dos cachés de 40 GiB. Por eso un modelo que va holgado en una máquina personal empieza a ahogarse cuando lo usan varias personas a la vez.

Cuatro formas de reducir la factura

Estas son cuatro palancas, en el orden en que conviene usarlas.

  1. Limita el contexto según la tarea. Es la solución más barata. Un chat normal usa unos pocos miles de tokens, y 32K cubren la mayoría de las tareas de programación. Si pides la ventana máxima para cada tarea, pagas el precio máximo cada vez.
  2. Cuantiza la caché, pero con cuidado. Guardar cada número en 8 bits en lugar de 16 la reduce a la mitad. El problema es que las keys y los values no lo toleran igual. Las mediciones publicadas muestran que las keys de 8 bits mantienen alrededor de un 98 % de coincidencia con una ejecución a precisión completa, mientras que las de 4 bits caen a cerca de un 12 %. Los values aguantan un trato más tosco, así que comprime primero los values y mantén las keys en 8 bits o más.
  3. Elige arquitecturas pensadas para ello. Grouped-query attention ya está en todas partes, y las arquitecturas híbridas van más allá: la mayoría de las capas recibe un pequeño resumen de tamaño fijo en vez de una pila creciente de fichas. Así un modelo puede anunciar 256K y seguir cabiendo.
  4. Replantéate los pesos. Bajar la precisión de los pesos libera memoria para la caché. En la fila de 128K de arriba, los pesos de 4 bits convierten 8,5 GiB de espacio libre en 37,8 GiB.

Elegir un modelo pensando en la caché

Haz los números para tres modelos lado a lado, todos con pesos de 8 bits en la misma máquina, y el panorama puede desplazarse en una dirección inesperada.

El mismo presupuesto de caché da dieciséis veces más contexto con el mejor de ellos. Los recuentos de parámetros, comparados como se suelen comparar, apenas se diferencian, pero el coste de la caché varía 16 veces.

Qwen3.6-35B-A3B es aquí el buen modelo para el día a día. A 20 MiB por cada 1000 tokens, el contexto es casi gratis, e incluso la ventana completa de 256K solo necesita 5 GiB de caché. Ya no hay que racionar el contexto, y precisamente para eso merece la pena tener una máquina potente. Cuando una tarea corta necesita más profundidad de razonamiento, el siguiente paso es el 27B denso, tres veces más caro por token, que sigue siendo poco.

Llama-3.1-70B es más difícil de justificar con contexto largo en una máquina de 114 GiB. El modelo no es más flojo. A 128K ocupa 105 GiB, y a 256K pide 145 GiB que sencillamente no existen. Para mantener su caché en unos razonables 20 GiB, habría que limitar el contexto a unos 66K. Si un modelo te obliga a racionar el contexto de todos modos, es mejor gastar la memoria en uno que no lo haga.

De ahí sale un hábito útil: mira el coste de la caché por cada 1000 tokens antes que el número de parámetros. Los parámetros dicen cuánto cuesta cargar el modelo. La cifra de la caché dice cuánto cuesta usarlo. Son respuestas a preguntas distintas, y el nombre del modelo solo anuncia una de ellas.

En resumen

La caché KV es un registro de la conversación hasta el momento, hecho una vez por token para que el modelo nunca tenga que recalcularlo. Para cada token, en cada capa y para cada conjunto de keys y values, guarda una key que decide cuánto importa ese token y un value que recoge lo que aporta.

Es también la única parte de la factura de memoria que crece mientras el modelo funciona. Los pesos cuestan una cantidad fija al cargarse; la caché es un gasto continuo que sube con el número de tokens y de conversaciones abiertas.

La próxima vez que fijes una longitud de contexto, piensa en ella en gigabytes y no en tokens. En los modelos vistos aquí, una ventana de 128K cuesta entre 8 y 40 GiB según la elección, así que conviene decidir a conciencia.