Capítulo 18 · Inferencia · 8 min

Por qué el 2.º token es más rápido que el 1.º

El KV cache y la generación autorregresiva. Prefill vs decode, TTFT, y por qué el cache lo cambia todo.

La ilusión del tiempo de respuesta

Le haces una pregunta a ChatGPT. Tarda alrededor de un segundo en empezar a responder. Después las palabras salen casi al instante, más rápido de lo que puedes leerlas.

Esta asimetría no es un capricho de interfaz. Es la huella de una optimización fundamental, sin la cual generar texto con un LLM costaría cien veces más: el KV cache.

Cómo un Transformer genera un token

En cada paso de generación, el Transformer debe producir un nuevo token. Para ello, calcula la atención del último token sobre todos los tokens anteriores. Eso es lo que le permite tener en cuenta el contexto entero.

Pero la atención necesita, para cada token del contexto, dos vectores: una clave (K) y un valor (V). Sin optimización, en cada nuevo token generado, el modelo recalcula K y V para toda la secuencia — incluidos los tokens ya procesados en el paso anterior. Es un trabajo O(n²) sobre la longitud de la secuencia: doblar el número de tokens cuadruplica el coste.

Es trabajo desperdiciado: esos vectores no han cambiado. El token nº3 tiene la misma clave K₃ que tenía en el paso anterior.

El KV cache: nunca recalcular lo que ya tienes

La idea es trivial y decisiva. Se mantienen en memoria (en el GPU) las K y V de todos los tokens ya procesados. En cada nuevo paso de generación, se calcula solo la K y la V del nuevo token, que se añade al cache.

Cuidado con no sobrestimar la ganancia: lo que se vuelve constante es el cálculo de las K y V del nuevo token. La atención, en cambio, sigue teniendo que comparar ese token con cada una de las claves del cache — eso sigue siendo proporcional a n. Lo que se ahorra es el recálculo de todo el prefijo: cada paso pasa de O(n²) a O(n).

Lanza la generación en las dos columnas de abajo y mira el contador de operaciones más que la animación. Pregúntate en cada paso: ¿qué se recalcula de verdad, y qué se calcula una sola vez?

Sin caché, cada nuevo token recalcula toda la attention sobre el prefijo — coste en O(n²). Con caché, solo se calcula la nueva línea. Eso es lo que separa el primer token (lento, prefill) del segundo (rápido, decode).

A la izquierda, sin cache: cada paso vuelve a dibujar todas las líneas. A la derecha, con cache: solo se añade una línea. Tras unos pocos tokens, la diferencia en operaciones acumuladas se vuelve enorme.

Prefill vs decode: dos fases bien distintas

La generación con un LLM se divide en dos fases que los ingenieros de inferencia distinguen cuidadosamente.

Prefill. El modelo recibe el prompt completo y calcula K y V para todos sus tokens en paralelo. Es rápido en términos de throughput — el GPU está saturado — pero tarda si el prompt es largo. Eso es lo que determina el TTFT (Time To First Token), el retraso antes de que aparezca la primera palabra.

Decode. El modelo genera el resto, un token a la vez, reutilizando el cache. Cada paso es rápido individualmente, pero secuencial: no se pueden paralelizar los tokens futuros, porque cada uno depende del anterior. Eso es lo que determina el ITL (Inter-Token Latency).

Las dos fases tienen perfiles completamente distintos:

PrefillDecode
¿Paralelizable?Sí (todos los tokens a la vez)No (secuencial)
Cuello de botella hardwareCómputo (FLOPs)Memoria (lectura del cache)
Efecto de la longitudLineal en NLineal en N por token
Métrica claveTTFTITL

En un prompt largo, el prefill puede tardar varios segundos. En una salida larga, el decode domina — y está limitado por la velocidad a la que se puede leer el KV cache desde la memoria HBM del GPU.

Por qué los providers facturan los input tokens de forma distinta

Si miras los precios de OpenAI, Anthropic o Google, los input tokens son sistemáticamente más baratos que los output tokens — a menudo de 4× a 8× menos. No es arbitrario. El prefill, que procesa los input tokens, es masivamente paralelo y usa el GPU eficientemente. El decode genera los output tokens uno a uno y aprovecha mal el hardware.

Más sutilmente: Anthropic, OpenAI y otros ofrecen ahora prefix caching. Si varias peticiones empiezan con el mismo system prompt, el KV cache de ese prefijo se calcula una sola vez y se reutiliza. Eso es lo que hace que los agentes y los chatbots multi-turno sean económicamente viables: sin prefix caching, cada turno costaría reprocesar la conversación entera.

El coste oculto: la memoria GPU

El KV cache no es gratis en memoria. Ocupa:

memoria = 2 × n_layers × n_kv_heads × d_head × seq_len × batch_size × 2 bytes (FP16)

n_kv_heads es el número de heads que tienen realmente sus propias K y V. En un Transformer multi-head clásico vale simplemente n_heads. En los modelos recientes es mucho más pequeño — veremos por qué justo debajo.

Para un modelo de 70 mil millones de parámetros con un contexto de 128.000 tokens y batch de 1, hablamos de decenas de gigabytes. Esto es a menudo lo que limita la longitud de contexto practicable, más que la capacidad del modelo en sí para razonar sobre la secuencia.

Para empujar más allá, existen varias técnicas:

  • Cache quantization: almacenar K y V en INT8 o INT4 en vez de FP16, dividiendo la memoria entre 2 o 4.
  • MQA / GQA (Multi-Query / Grouped-Query Attention): compartir las K/V entre varias heads. Llama 2 70B y Llama 3 usan GQA, lo que reduce drásticamente el tamaño del cache.
  • Sliding window attention: mantener solo una ventana reciente del cache (Mistral, Gemma).
  • PagedAttention (vLLM): tratar el cache como páginas de memoria virtual, para gestionar mejor el batching dinámico.

Quantization, en dos palabras

La palabra aparece por todas partes en esta parte: QLoRA en 4 bits (capítulo 14), cache quantization justo arriba, modelos GGUF que descargas de Hugging Face. Es el momento de explicar lo que significa.

Quantizar es representar cada parámetro del modelo con menos bits. Un número en coma flotante de 32 bits (FP32) ocupa 4 bytes. En FP16, 2 bytes. En INT8, 1 byte. En INT4, medio byte — la memoria que ocupan los pesos se divide entre 8 respecto al FP32 original.

PrecisiónBytes / parámetroModelo 70B ocupa
FP324280 GB
FP16 / BF162140 GB
INT8170 GB
INT40,535 GB
INT2 (extremo)0,2517,5 GB

El truco: un peso 0,237 no se vuelve exactamente 0,237 en INT4 (que solo tiene 16 valores posibles), sino su valor más cercano en una rejilla discreta. La pérdida de calidad depende del modelo y del método, pero suele ser pequeña hasta INT8, modesta en INT4 (un par de % de degradación en los benchmarks), significativa por debajo.

Las técnicas modernas (GPTQ, AWQ, GGUF) no cuantizan todos los pesos por igual — preservan la precisión en las capas sensibles y comprimen más agresivamente las demás. Y la quantization del KV cache, mencionada arriba, aplica exactamente la misma idea a las activaciones almacenadas en memoria durante la generación.

Es esta técnica la que permite hacer correr Llama 70B en un MacBook con 64 GB de RAM, allí donde la versión FP16 pide un cluster.

La lección

Sin el KV cache, los LLMs en producción serían impracticables. Una conversación larga, un agente que razona, un chatbot que recuerda lo que dijiste cinco mensajes atrás — nada de eso sería viable económicamente.

Pero ese cache es también lo que limita la longitud de contexto. Cuando hablamos de "ventana de 1 millón de tokens", es en gran parte un problema de memoria de cache, no un problema de cálculo de atención.

El KV cache no es una optimización más entre otras. Es lo que transforma la atención de un mecanismo teórico en una infraestructura de producción.

Y eso desplaza la cuestión del tamaño. Un modelo no cuesta solo lo que se pagó por entrenarlo una vez: cuesta memoria y cómputo en cada token, en cada petición, para siempre. Así que si un modelo más pequeño puede servirse miles de millones de veces por una fracción del precio, ¿sigue significando "más grande" lo mismo que "mejor"? El siguiente capítulo enseña que la investigación ya lo ha decidido — y no en el sentido que uno cree.

Actualizado el