Phase 07 - Lesson 15

Variantes de Atención — Ventana Deslizante, Esparza, Diferencial

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

La atención completa es un círculo. Cada token ve a cada token, y la memoria paga el precio. Cuatro variantes doblan la forma del círculo y recuperan la mitad del costo.

Tipo: Build Lenguajes: Python Prerrequisitos: Phase 7 · 02 (Self-Attention), Phase 7 · 03 (Multi-Head), Phase 7 · 12 (KV Cache / Flash Attention) Tiempo: ~60 minutos

El Problema

La atención completa cuesta O(N²) en memoria y O(N²) en cómputo con respecto a la longitud de la secuencia. Para un Llama 3 70B con contexto de 128K, eso representa 16 mil millones de entradas de atención por capa, multiplicado por 80 capas. Flash Attention (Lección 12) oculta la memoria de activación O(N²), pero no cambia el costo aritmético: cada token sigue atendiendo a todos los demás tokens.

Tres clases de variantes cambian la topología de la matriz de atención en sí:

  1. Atención por ventana deslizante (Sliding Window Attention - SWA). Cada token atiende a una ventana fija de vecinos, no a todo el prefijo. La memoria y el cómputo caen a O(N · W) donde W es la ventana. Gemma 2/3, primeras capas de Mistral 7B, Phi-3-Long.
  2. Atención esparza / por bloques (Sparse / block attention). Solo parejas seleccionadas (i, j) obtienen puntuación; el resto se fuerza a peso cero. Longformer, BigBird, OpenAI sparse transformer.
  3. Atención diferencial (Differential attention). Calcula dos mapas de atención con proyecciones Q/K separadas y resta uno del otro. Elimina el "sumidero de atención" (attention sink) que drena peso hacia los primeros tokens. DIFF Transformer de Microsoft (2024).

Estas variantes coexisten. Un modelo de frontera en 2026 a menudo las combina: la mayoría de las capas son SWA-1024, cada quinta capa es de atención completa global, y un puñado son cabezas diferenciales que limpian la recuperación de información. La relación 5:1 de SWA a global de Gemma 3 es el estándar actual en los libros de texto.

El Concepto

Atención por Ventana Deslizante (SWA)

Cada query en la posición i atiende solo a las posiciones en [i - W, i] (SWA causal) o [i - W/2, i + W/2] (bidirecional). Los tokens fuera de la ventana reciben -inf en la matriz de puntuación (score matrix).

full causal:           sliding window (W=4):
positions 0-7          positions 0-7, W=4
    0 1 2 3 4 5 6 7        0 1 2 3 4 5 6 7
0 | x                0 |  x
1 | x x              1 |  x x
2 | x x x            2 |  x x x
3 | x x x x          3 |  x x x x
4 | x x x x x        4 |    x x x x
5 | x x x x x x      5 |      x x x x
6 | x x x x x x x    6 |        x x x x
7 | x x x x x x x x  7 |          x x x x

Para N = 8192 y W = 1024, la matriz de puntuación tiene en promedio 1024 × 8192 filas no nulas, una reducción de 8×.

El KV cache se reduce con SWA. Solo los últimos W tokens de K y V deben mantenerse por capa. Para una configuración similar a Gemma-3 (ventana de 1024, contexto de 128K), el KV cache cae 128×.

Costo en calidad. Los modelos basados únicamente en SWA tienen dificultades con la recuperación de información a largo alcance. La solución: intercalar capas de SWA con capas de atención completa (global). Gemma 3 utiliza una relación SWA a global de 5:1. Mistral 7B utilizó una pila de SWA causal donde la información "fluye hacia adelante" a través de ventanas superpuestas: cada capa extiende el campo receptivo efectivo por W y, después de L capas, el modelo puede atender a L × W tokens en el pasado.

Atención Esparza / por Bloques

Se elige un patrón de esparcimiento de tamaño N × N de antemano. Tres formas clásicas:

  • Local + strided (OpenAI sparse transformer). Atiende a los últimos W tokens más cada stride-ésimo token anterior. Captura tanto lo local como el largo alcance con una complejidad de cómputo de O(N · sqrt(N)).
  • Longformer / BigBird. Ventana local + un pequeño conjunto de tokens globales (p. ej., [CLS]) que atienden a todos y reciben atención de todos + conexiones esparzas aleatorias. Permite empíricamente el doble de contexto con calidad equivalente.
  • Native Sparse Attention (DeepSeek, 2025). Aprende qué bloques de (Q, K) importan; omite los bloques de ceros a nivel de kernel. Compatible con FlashAttention.

La atención esparza es una historia de ingeniería de kernel. La matemática es simple (enmascarar la matriz de puntuación); la ganancia proviene de nunca cargar las entradas de ceros en la SRAM. FlashAttention-3 y la API FlexAttention de 2026 hacen que los patrones esparzos personalizados sean ciudadanos de primera clase en PyTorch.

Atención Diferencial (DIFF Transformer, 2024)

La atención regular sufre del problema del "sumidero de atención" (attention sink): softmax obliga a cada fila a sumar 1, por lo que las queries que no quieren atender a nada en particular acumulan peso en el primer token (or los primeros). Esto consume capacidad de representación que debería haberse destinado al contenido real.

La atención diferencial soluciona esto calculando dos mapas de atención y restándolos:

A1 = softmax(Q1 K1^T / √d)
A2 = softmax(Q2 K2^T / √d)
DiffAttn = (A1 - λ · A2) V

donde λ es un escalar aprendido (típicamente 0.5–0.8). A1 captura los pesos del contenido real; A2 captura el sumidero. La resta cancela el sumidero y reasigna el peso a los tokens relevantes.

Resultados reportados (Microsoft 2024): perplexity entre un 5% y 10% menor, contexto efectivo de 1.5 a 2× más largo con la misma longitud de entrenamiento, y una recuperación del tipo "aguja en un pajar" (needle-in-a-haystack) mucho más precisa.

Comparación de Variantes

Variante Cómputo KV cache Calidad vs. completa Uso en producción
Full attention O(N²) O(N) por capa línea base capa predeterminada de cada modelo
SWA (ventana 1024) O(N·W) O(W) por capa -0.1 ppl, bueno con capas globales Gemma 2/3, Phi-3-Long
Local + strided esparza O(N·√N) mixto similar a SWA OpenAI sparse transformer, Longformer
BigBird (local + global + aleatoria) O(N) aprox. mixto iguala a la completa con 2× contexto BERT inicial de contexto largo
Native Sparse (DeepSeek-V3.2) O(N · fracción activa) O(N) dentro de 0.05 ppl DeepSeek-V3.2, 2025
Diferencial O(2·N²) O(2N) -5 a -10% ppl DIFF Transformer, modelos de principios de 2026

Impleméntalo

Consulta code/main.py. Implementamos un comparador de máscara causal que muestra la atención completa, SWA, local+strided y diferencial lado a lado en una secuencia de prueba.

Paso 1: máscara causal completa (línea base)

def causal_mask(n):
    return [[0.0 if j <= i else float("-inf") for j in range(n)] for i in range(n)]

Línea base de la Lección 07. Triangular inferior; peso cero por encima de la diagonal.

Paso 2: máscara causal de ventana deslizante

def swa_mask(n, window):
    M = [[float("-inf")] * n for _ in range(n)]
    for i in range(n):
        lo = max(0, i - window + 1)
        for j in range(lo, i + 1):
            M[i][j] = 0.0
    return M

Un parámetro: window. Para window >= n, recuperas la atención causal completa. Para window = 1, cada token se atiende solo a sí mismo.

Paso 3: máscara esparza local + strided

def strided_mask(n, window, stride):
    M = [[float("-inf")] * n for _ in range(n)]
    for i in range(n):
        lo = max(0, i - window + 1)
        for j in range(lo, i + 1):
            M[i][j] = 0.0
        for j in range(0, i + 1, stride):
            M[i][j] = 0.0
    return M

Ventana local densa más cada stride-ésimo token de regreso al inicio de la secuencia. El campo receptivo crece en pasos logarítmicos con capas adicionales.

Paso 4: atención diferencial

def diff_attention(Q1, K1, Q2, K2, V, lam):
    A1 = softmax_causal(Q1 @ K1.T / sqrt_d)
    A2 = softmax_causal(Q2 @ K2.T / sqrt_d)
    return (A1 - lam * A2) @ V

Dos pasos de atención, restados con un coeficiente de mezcla aprendido. En el código comparamos el mapa de calor del sumidero de atención de una sola atención contra la diferencial y observamos el colapso del sumidero.

Paso 5: tamaños del KV cache

Imprime el tamaño del caché por capa con N = 131072 para cada variante. Las variantes SWA y esparzas se reducen de 10 a 100×. La diferencial se duplica. Paga tu factura de memoria conscientemente.

Úsalo

Patrones de producción de 2026:

from transformers import AutoModelForCausalLM
# Gemma 3 mezcla SWA (window=1024) y capas globales en una proporción de 5:1.
model = AutoModelForCausalLM.from_pretrained("google/gemma-3-27b-it")
# print(model.config.sliding_window, model.config.layer_types)

FlexAttention en PyTorch 2.5+ acepta una función de máscara:

from torch.nn.attention.flex_attention import flex_attention, create_block_mask

def swa_pattern(b, h, q_idx, kv_idx):
    return (q_idx - kv_idx < 1024) & (q_idx >= kv_idx)

mask = create_block_mask(swa_pattern, B=batch, H=heads, Q_LEN=n, KV_LEN=n)
out = flex_attention(q, k, v, block_mask=mask)

Esto se compila en un kernel Triton personalizado. Queda a un 10% de la velocidad de FlashAttention-3 para patrones comunes, y la función de máscara es un invocable de Python.

Cuándo elegir cada una:

  • Atención completa pura — todas las capas hasta un contexto de ~16K, o cuando la calidad de recuperación es primordial.
  • Mezcla SWA + global — contextos largos (>32K), entrenamiento e inferencia limitados por memoria. El estándar de 2026 por encima de 32K.
  • Atención esparza por bloques — kernel personalizado, patrón personalizado. Reservado para cargas de trabajo especializadas (recuperación, audio).
  • Atención diferencial — cualquier carga de trabajo donde la contaminación del sumidero de atención perjudique (RAG de contexto largo, needle-in-a-haystack).

Envíalo

Consulta outputs/skill-attention-variant-picker.md. La skill elige una topologia de atención para un nuevo modelo considerando la longitud del contexto objetivo, las demandas de recuperación y el perfil de cómputo de entrenamiento/inferencia.

Ejercicios

  1. Fácil. Ejecuta code/main.py. Verifica que SWA con window=4 ponga a cero todo lo que esté fuera de los últimos 4 tokens por fila. Verifica que window=n reproduzca la atención causal completa de forma idéntica bit a bit.
  2. Medio. Implementa SWA causal con window=1024 sobre el proyecto final de la Lección 07. Entrena durante 1,000 pasos en tinyshakespeare. ¿Cuánto empeora la pérdida de validación vs. la atención completa? ¿Cuánto disminuye la memoria máxima?
  3. Difícil. Implementa una mezcla de capas estilo Gemma-3 de 5:1 (5 SWA, 1 global) en el modelo del proyecto final. Compara la pérdida, la memoria y la calidad de generación con las líneas base de solo SWA y solo global con parámetros equivalentes.
  4. Difícil. Implementa atención diferencial con un λ aprendido por cabeza. Entrena en una tarea de recuperación sintética (una aguja, 2,000 distractores). Mide la precisión de recuperación frente a una línea base de atención única con parámetros equivalentes.

Términos Clave

Término Lo que la gente dice Lo que realmente significa
Atención por ventana deslizante (SWA) "Atención local" Cada query atiende a sus últimos W tokens; el KV cache se reduce a O(W).
Campo receptivo efectivo "Qué tan atrás ve el modelo" En una pila SWA de L capas con ventana W, hasta L × W tokens.
Longformer / BigBird "Local + global + aleatorio" Patrones esparzos con unos pocos tokens globales que siempre atienden y reciben atención; enfoque inicial para contextos largos.
Native Sparse Attention "El truco de kernel de DeepSeek" Aprende la esparcidad a nivel de bloque; omite bloques de ceros a nivel de kernel manteniendo la calidad.
Atención diferencial "Dos mapas, uno resta" DIFF Transformer: resta un mapa de atención secundario multiplicado por un λ aprendido del mapa primario para cancelar los sumideros de atención.
Sumidero de atención (Attention sink) "El peso se va al token 0" La normalización de softmax obliga a las filas a sumar 1; las queries no informativas depositan el peso sobrante en la posición 0.
FlexAttention "Máscara como Python" API de PyTorch 2.5+ que compila funciones de máscara arbitrarias en kernels con formato de FlashAttention.
Mezcla de tipos de capa "5:1 SWA a global" Intercala capas de atención esparza y completa en una pila para mantener la calidad con menor memoria.

Lectura Adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).