Transformers — Módulo 10: contexto largo, KV cache y FlashAttention
Décimo módulo del Curso de Transformers: por qué la atención cuesta O(n²) y qué hace caro el contexto largo. El KV cache que evita recomputar Keys y Values en cada token, FlashAttention como atención consciente de la memoria, y extensiones posicionales RoPE y ALiBi para estirar la ventana.
☰ Índice del contenido
- La tesis del módulo
- El problema: la atención es O(n²)
- El primer ahorro: KV cache
- El costo del KV cache: VRAM que crece
- El segundo ahorro: FlashAttention
- Estirar la ventana: RoPE y ALiBi
- El mito peligroso: “más contexto siempre es mejor”
- Errores comunes
- La frase para llevarse
- Qué viene
- Material relacionado
En el módulo 9 vimos cómo el modelo elige cada token. Pero dijimos algo al pasar que ahora toca desarmar: generar el token número mil es mucho más caro que generar el primero. Y no un poco más caro — dramáticamente más. Detrás de esa frase están las dos preguntas de infraestructura que definen qué tan largo puede ser tu contexto, cuánta VRAM te cuesta y por qué “sube el contexto y ya” no es gratis. Hoy abrimos el motor de la inferencia larga: el costo cuadrático de la atención, el truco que lo hace viable (KV cache) y las optimizaciones modernas que lo aceleran.
La tesis del módulo
El contexto largo no es gratis: la atención cuesta O(n²) y el KV cache crece linealmente con cada token, ocupando VRAM real. Todo lo que llamas “ventana de contexto grande” es, por debajo, memoria que alguien está pagando. Entender ese costo es entender los límites reales de los LLM en producción.
El problema: la atención es O(n²)
Volvamos al corazón del Transformer. En la atención, cada token mira a todos los demás para entender su contexto. Si la secuencia tiene n tokens, cada uno calcula un puntaje contra los otros n → eso es n × n comparaciones. Esa es la notación O(n²) (crece con el cuadrado del largo): la matemática que dice cuánto crece el costo cuando la entrada crece.
Las consecuencias son brutales:
| Largo del contexto | Operaciones de atención (∝ n²) | Costo relativo |
|---|---|---|
| 1.000 tokens | 1 millón | ×1 |
| 2.000 tokens | 4 millones | ×4 |
| 10.000 tokens | 100 millones | ×100 |
| 100.000 tokens | 10.000 millones | ×10.000 |
Duplicar el contexto cuadruplica el trabajo de atención. Multiplicarlo por 10 lo multiplica por 100. Por eso el contexto largo fue durante años el techo de los Transformers: no es un problema de “más memoria y listo”, es un crecimiento que se dispara.
El primer ahorro: KV cache
Aquí entra la optimización más importante de la inferencia. Recordemos que la atención usa tres proyecciones de cada token: Query, Key y Value (Q, K, V — las tres piezas del módulo 2). Cuando el modelo genera texto, lo hace token por token, y en cada paso reprocesa la secuencia.
El detalle clave: las Keys y los Values de los tokens anteriores no cambian. Cuando generas el token 501, las K y V de los tokens 1 a 500 son idénticas a las que calculaste en el paso anterior. Recalcularlas sería tirar cómputo a la basura.
El KV cache (caché de Keys y Values) hace exactamente eso: guarda las Keys y Values ya calculados para no recomputarlos en cada token nuevo. En cada paso solo calculas la K y V del token nuevo, las agregas al caché, y reutilizas todo lo anterior. La generación pasa de recomputar toda la secuencia cada vez, a agregar una columna por token.
sin KV cache: cada token recomputa TODO
token 3: [K1 K2 K3] ← recalcula K1, K2, K3
token 4: [K1 K2 K3 K4] ← recalcula K1..K4 otra vez
con KV cache: reusa lo guardado, agrega uno
token 3: [K1 K2]cache + K3nuevo
token 4: [K1 K2 K3]cache + K4nuevo
\... ya estaban, no se recalculan
El truco es tan efectivo que es estándar en todo motor de inferencia. Pero no es gratis: ese caché vive en la VRAM y crece con cada token. Y ahí aparece el nuevo cuello de botella.
El costo del KV cache: VRAM que crece
Cada token que entra al contexto agrega su K y su V a la VRAM, en cada capa, para cada cabeza de atención. La cuenta se acumula rápido:
KV cache (bytes) ≈
2 (K y V) × capas × tokens × d_model × bytes_por_valor
Para un modelo de 7B con contexto de 8.000 tokens, el KV cache puede pesar varios GB — a veces más que el margen de VRAM que te quedaba. Y crece linealmente con el contexto: doblar la ventana dobla el caché. Esto conecta directo con el serving en producción: gestionar bien este caché (paginarlo, compartirlo entre peticiones) es la razón de ser de motores como vLLM, que vimos en el curso de GPU, módulo de serving. Su técnica estrella, PagedAttention, es esencialmente un administrador de memoria para el KV cache.
| Qué crece con el contexto | Cómo crece | Dónde duele |
|---|---|---|
| Cómputo de atención | Cuadrático O(n²) | Velocidad (tokens/s) |
| KV cache | Lineal O(n) | VRAM ocupada |
| Latencia del primer token | Con el prompt entero | Tiempo de espera inicial |
El segundo ahorro: FlashAttention
Si la atención es O(n²) en cómputo, también genera una matriz de puntajes n×n gigante que hay que mover entre la memoria rápida (la del chip) y la lenta (la VRAM). Ese ir y venir de datos —no el cálculo en sí— es el verdadero cuello de botella en GPUs modernas.
FlashAttention es una implementación de la atención consciente de la memoria: reorganiza el cálculo para procesar la matriz por bloques que caben en la memoria rápida del chip, evitando escribir la matriz n×n completa en VRAM. El resultado es mucho más rápido y usa mucha menos memoria — y, lo más importante, da exactamente el mismo resultado. No es una aproximación ni un atajo que sacrifica calidad: es la misma atención, calculada de forma inteligente.
Ojo: FlashAttention no reduce el orden O(n²) del cómputo — sigue siendo cuadrático. Lo que ataca es el movimiento de memoria, que en la práctica era el freno real. Por eso acelera tanto sin cambiar ni un decimal del resultado.
Estirar la ventana: RoPE y ALiBi
Queda una pregunta: un modelo entrenado con 4.000 tokens de contexto, ¿puede procesar 16.000? Depende de cómo codifique las posiciones. Recuerda del módulo 4 que el Transformer es ciego al orden y hay que inyectarle la posición. Cómo se inyecta decide qué tan bien extrapola.
- RoPE (Rotary Position Embedding, “embedding posicional rotatorio”) codifica la posición rotando los vectores Query y Key un ángulo proporcional a su posición. Su gracia: representa posiciones relativas de forma natural, y se puede “estirar” (interpolar los ángulos) para extender el contexto más allá del entrenamiento con poco reajuste. Es el estándar de las familias modernas (Llama, Qwen, Mistral).
- ALiBi (Attention with Linear Biases, “atención con sesgos lineales”) toma otro camino: no toca los embeddings, sino que resta una penalización a la atención proporcional a la distancia entre tokens. Cuanto más lejos está un token, menos peso recibe. Eso le da una capacidad natural de extrapolar a contextos más largos que los vistos en entrenamiento.
RoPE: rota Q y K un ángulo según la posición
pos 1: ang 0° (el ángulo codifica la posición;
pos 2: ang 30° la distancia relativa entre dos
pos 3: ang 60° tokens se conserva al rotar)
ALiBi: penaliza la atención por distancia
token actual mira hacia atrás:
[-0]..[-1]..[-2]..[-3]..[-4] sesgo resta más
cerca lejos cuanto más lejos
El mito peligroso: “más contexto siempre es mejor”
Con ventanas de 100k o 1M de tokens en el mercado, es tentador creer que más contexto es gratis y siempre conviene. Dos verdades incómodas:
- Cuesta. Cómputo cuadrático + KV cache lineal = más lento y más caro por cada token que sumas. Un prompt de 100k tokens no es “solo” 25 veces más largo que uno de 4k: la atención sobre él es cientos de veces más costosa.
- “Lost in the middle”. Los estudios muestran que los modelos atienden bien al principio y al final del contexto, pero pierden información en el medio. Meter un documento gigante y esperar que el modelo recuerde el párrafo 300 es apostar contra la evidencia.
Cuidado: llenar la ventana no es una estrategia. Para muchas tareas, recuperar los 5 fragmentos relevantes con RAG y pasarlos cortos supera a volcar 100k tokens crudos — más barato, más rápido y más preciso. El contexto largo es una herramienta, no una meta.
Errores comunes
- Creer que el contexto largo es gratis. Es cuadrático en cómputo y lineal en VRAM. Cada token del prompt se paga en velocidad y memoria.
- Confundir FlashAttention con una aproximación. Da el resultado idéntico; solo cambia cómo se calcula. Actívalo siempre que puedas.
- Ignorar el KV cache al dimensionar VRAM. Los pesos del modelo no son todo: en contextos largos el caché puede pesar tanto como el modelo. El módulo de VRAM del curso de GPU insiste en esto.
- Asumir que un modelo procesa cualquier largo. Sin RoPE estirado o ALiBi, pasarse del contexto de entrenamiento degrada la salida. La ventana anunciada tiene límites reales.
- Rellenar la ventana “por si acaso”. El “lost in the middle” y el costo cuadrático castigan el relleno. Contexto relevante y corto le gana a contexto largo y ruidoso.
La frase para llevarse
“El contexto largo no lo pagas en tokens de tu prompt: lo pagas en cómputo cuadrático y en VRAM que crece con cada palabra. El KV cache lo hace posible, FlashAttention lo hace rápido, y el sentido común lo hace conveniente — o no.”
Qué viene
Módulo 11: variantes modernas — Mixture of Experts y eficiencia. Ya sabes qué hace caro un Transformer; ahora veremos las arquitecturas que rompen la regla de “más parámetros = más cómputo”. MoE, GQA/MQA y las familias que dominan hoy (Llama, Mixtral, Qwen).
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.