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 ilusion del tiempo de respuesta

Le haces una pregunta a ChatGPT. Tarda alrededor de un segundo en empezar a responder. Despues las palabras salen casi al instante, mas rapido de lo que puedes leerlas.

Esta asimetria no es un capricho de interfaz. Es la huella de una optimizacion fundamental, sin la cual generar texto con un LLM costaria cien veces mas: el KV cache.

Como un Transformer genera un token

En cada paso de generacion, el Transformer debe producir un nuevo token. Para ello, calcula la atencion del ultimo token sobre todos los tokens anteriores. Eso es lo que le permite tener en cuenta el contexto entero.

Pero la atencion necesita, para cada token del contexto, dos vectores: una clave (K) y un valor (V). Sin optimizacion, 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 numero de tokens cuadruplica el coste.

Es trabajo desperdiciado: esos vectores no han cambiado. El token nº3 tiene la misma clave K₃ que tenia 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 generacion, se calcula solo la K y la V del nuevo token, que se añade al cache.

La atencion entonces lee el cache completo, pero el calculo a hacer en este paso es O(1) en tamaño — no O(n).

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 lineas. A la derecha, con cache: solo se añade una linea. Tras unos pocos tokens, la diferencia en operaciones acumuladas se vuelve enorme.

Prefill vs decode: dos fases bien distintas

La generacion 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 rapido en terminos de throughput — el GPU esta 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 rapido 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?Si (todos los tokens a la vez)No (secuencial)
Cuello de botella hardwareComputo (FLOPs)Memoria (lectura del cache)
Efecto de la longitudLineal en NLineal en N por token
Metrica claveTTFTITL

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

Por que los providers facturan los input tokens de forma distinta

Si miras los precios de OpenAI, Anthropic o Google, los input tokens son sistematicamente mas baratos que los output tokens — a menudo 4× o 5× 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.

Mas 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 economicamente viables: sin prefix caching, cada turno costaria reprocesar la conversacion entera.

El coste oculto: la memoria GPU

El KV cache no es gratis en memoria. Ocupa:

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

Para un modelo de 70 mil millones de parametros 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, mas que la capacidad del modelo en si para razonar sobre la secuencia.

Para empujar mas alla, existen varias tecnicas:

  • 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 drasticamente el tamaño del cache.
  • Sliding window attention: mantener solo una ventana reciente del cache (Mistral, Gemma).
  • PagedAttention (vLLM): tratar el cache como paginas de memoria virtual, para gestionar mejor el batching dinamico.

Quantization, en dos palabras

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

Quantizar es representar cada parametro del modelo con menos bits. Un numero 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.

PrecisionBytes / parametroModelo 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 mas cercano en una rejilla discreta. La perdida de calidad depende del modelo y del metodo, pero suele ser pequeña hasta INT8, modesta en INT4 (un par de % de degradacion en los benchmarks), significativa por debajo.

Las tecnicas modernas (GPTQ, AWQ, GGUF) no cuantizan todos los pesos por igual — preservan la precision en las capas sensibles y comprimen mas agresivamente las demas. Y la quantization del KV cache, mencionada arriba, aplica exactamente la misma idea a las activaciones almacenadas en memoria durante la generacion.

Es esta tecnica la que permite hacer correr Llama 70B en un MacBook con 64 GB de RAM, alli donde la version FP16 pide un cluster.

La leccion

Sin el KV cache, los LLMs en produccion serian impracticables. Una conversacion larga, un agente que razona, un chatbot que recuerda lo que dijiste cinco mensajes atras — nada de eso seria viable economicamente.

Pero ese cache es tambien lo que limita la longitud de contexto. Cuando hablamos de "ventana de 1 millon de tokens", es en gran parte un problema de memoria de cache, no un problema de calculo de atencion.

El KV cache no es una optimizacion mas entre otras. Es lo que transforma la atencion de un mecanismo teorico en una infraestructura de produccion.

Actualizado el

KV cache: por qué el 2º token es más rápido que el 1º · Step by Token