Phase 07 - Lesson 04
Codificación Posicional — Sinusoidal, RoPE, ALiBi
This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.
La atención es invariante a permutaciones. "El gato se sentó en la alfombra" y "alfombra la en sentó gato el" producen la misma salida sin una señal posicional. Tres algoritmos lo resuelven, cada uno con una apuesta distinta sobre qué significa "posición".
Tipo: Build Lenguajes: Python Prerrequisitos: Fase 7 · 02 (Self-Attention), Fase 7 · 03 (Multi-Head Attention) Tiempo: ~45 minutos
El Problema
La atención por producto punto escalado es ciega al orden. La matriz de atención softmax(Q K^T / √d) V se calcula a partir de similitudes por pares. Mezcla las filas de X y obtienes las filas de la salida mezcladas de la misma manera. A nada dentro de la atención le importa la posición.
Eso no es un bug en un modelo bag-of-words. Para lenguaje, código, audio, video — cualquier cosa en la que el orden carga significado — es fatal.
La solución es inyectar la posición en los embeddings de alguna manera. Tres eras de respuestas:
- Sinusoidal absoluta (Vaswani 2017). Suma
sin/cosde la posición al embedding. Simple, sin parámetros aprendibles, extrapola mal más allá de las longitudes entrenadas. - RoPE — Rotary Position Embeddings (Su 2021). Rota los vectores Q y K por un ángulo proporcional a la posición. Codifica la posición relativa directamente en el producto punto. Dominante en 2026.
- ALiBi — Attention with Linear Biases (Press 2022). Omite los embeddings por completo; suma una penalización lineal por cabeza a las puntuaciones de atención según la distancia. Excelente extrapolación de longitud.
A 2026, esencialmente todo modelo abierto de frontera usa RoPE: Llama 2/3/4, Qwen 2/3, Mistral, Mixtral, DeepSeek-V3, Kimi. Un puñado de modelos de contexto largo usa ALiBi o sus variantes modernas. La sinusoidal absoluta es histórica.
El Concepto
Sinusoidal absoluta
Precalcula una matriz fija PE de forma (max_len, d_model):
PE[pos, 2i] = sin(pos / 10000^(2i / d_model))
PE[pos, 2i+1] = cos(pos / 10000^(2i / d_model))
Luego X' = X + PE[:N] antes de la atención. Cada dimensión es una sinusoide en una frecuencia distinta. El modelo aprende a leer la posición a partir del patrón de fase. Falla más allá de max_len: nada le dijo al modelo qué pasa en la posición 2048 cuando solo vio las posiciones 0–2047.
RoPE
Rota los vectores Q y K (no los embeddings). Para un par de dimensiones (2i, 2i+1):
[q'_2i ] [ cos(pos·θ_i) -sin(pos·θ_i) ] [q_2i ]
[q'_2i+1 ] = [ sin(pos·θ_i) cos(pos·θ_i) ] [q_2i+1 ]
θ_i = base^(-2i / d_head), base = 10000 by default
Aplica la misma rotación a las claves con la posición pos_k. El producto punto q'_m · k'_n se convierte en una función solo de (m - n). Es decir: la puntuación de atención depende únicamente de la distancia relativa, aunque la rotación se haya basado en posiciones absolutas. Un truco hermoso.
Extendiendo RoPE: base puede escalarse (NTK-aware, YaRN, LongRoPE) para extrapolar a contextos más largos sin reentrenamiento. Llama 3 extendió de 8K a 128K de contexto de esta forma.
ALiBi
Omite el truco del embedding. Aplica sesgo directamente a las puntuaciones de atención:
attn_score[i, j] = (q_i · k_j) / √d - m_h · |i - j|
Donde m_h es una pendiente específica por cabeza (por ejemplo, 1 / 2^(8·h/H)). Los tokens más cercanos reciben un impulso; los tokens lejanos reciben una penalización. Sin costo en tiempo de entrenamiento. El artículo muestra que la extrapolación de longitud supera a la sinusoidal e iguala a RoPE en su longitud de entrenamiento original.
Qué elegir en 2026
| Variante | Extrapolación | Costo de entrenamiento | Usada por |
|---|---|---|---|
| Sinusoidal absoluta | pobre | gratis | transformer original, BERT temprano |
| Absoluta aprendida | ninguna | mínimo | GPT-2, GPT-3 |
| RoPE | buena con escalado | gratis | Llama 2/3/4, Qwen 2/3, Mistral, DeepSeek-V3, Kimi |
| RoPE + YaRN | excelente | etapa de fine-tune | Qwen2-1M, Llama 3.1 128K |
| ALiBi | excelente | gratis | BLOOM, MPT, Baichuan |
RoPE ganó porque encaja en la atención sin cambiar la arquitectura, codifica la posición relativa y su hiperparámetro base ofrece un control limpio para el fine-tuning de contexto largo.
Constrúyelo
Paso 1: codificación sinusoidal
Ver code/main.py. Un cálculo de 4 líneas:
def sinusoidal(N, d):
pe = [[0.0] * d for _ in range(N)]
for pos in range(N):
for i in range(d // 2):
theta = pos / (10000 ** (2 * i / d))
pe[pos][2 * i] = math.sin(theta)
pe[pos][2 * i + 1] = math.cos(theta)
return pe
Suma esto a la matriz de embedding antes de la primera capa de atención.
Paso 2: RoPE aplicado a Q, K
RoPE opera in-place sobre Q y K. Para cada par de dimensiones:
def apply_rope(x, pos, base=10000):
d = len(x)
out = list(x)
for i in range(d // 2):
theta = pos / (base ** (2 * i / d))
c, s = math.cos(theta), math.sin(theta)
a, b = x[2 * i], x[2 * i + 1]
out[2 * i] = a * c - b * s
out[2 * i + 1] = a * s + b * c
return out
Crucial: aplica la misma función a Q en la posición m y a K en la posición n. Su producto punto adquiere un factor cos((m-n)·θ_i) en cada par de coordenadas. La atención aprende la posición relativa gratis.
Paso 3: pendientes y sesgo de ALiBi
def alibi_bias(n_heads, seq_len):
# slope_h = 2 ** (-8 * h / n_heads) for h = 1..n_heads
slopes = [2 ** (-8 * (h + 1) / n_heads) for h in range(n_heads)]
bias = []
for m in slopes:
row = [[-m * abs(i - j) for j in range(seq_len)] for i in range(seq_len)]
bias.append(row)
return bias # add to attention scores before softmax
Suma bias[h] a la matriz de puntuaciones de atención (seq_len, seq_len) de la cabeza h y luego aplica softmax.
Paso 4: verifica la propiedad de distancia relativa de RoPE
Elige dos vectores aleatorios a, b. Rótalos por (pos_a, pos_b). Luego por (pos_a + k, pos_b + k). Ambos productos punto deben coincidir dentro del error de punto flotante. Esa propiedad es el objetivo central de RoPE — es invariante al desplazamiento absoluto, solo importa la brecha relativa.
Úsalo
PyTorch 2.5+ incluye utilidades de RoPE en torch.nn.functional. La mayor parte del código de producción usa flash_attn o xformers, donde RoPE se aplica dentro del kernel de atención.
from transformers import AutoModel
model = AutoModel.from_pretrained("meta-llama/Llama-3.2-3B")
# model.config.rope_scaling → {"type": "yarn", "factor": 32.0, "original_max_position_embeddings": 8192}
Trucos de contexto largo en 2026:
- Interpolación NTK-aware. Reescala
baseabase * (scale_factor)^(d/(d-2))al extender de 4K a 16K+. - YaRN. Interpolación más inteligente que preserva la entropía de la atención en contextos largos. Llama 3.1 128K la usa.
- LongRoPE. Método de 2024 de Microsoft que usa búsqueda evolutiva para elegir factores de escala por dimensión. Phi-3-Long lo usa.
- Interpolación de posición + fine-tuning. Solo reduce las posiciones por el factor de extensión y haz fine-tune durante 1–5B tokens. Sorprendentemente eficaz.
Entrégalo
Ver outputs/skill-positional-encoding-picker.md. La skill elige una estrategia de codificación para un modelo nuevo según la longitud de contexto objetivo, las necesidades de extrapolación y el presupuesto de entrenamiento.
Ejercicios
- Fácil. Grafica la matriz
PEsinusoidal como un mapa de calor paramax_len=512, d=128. Confirma el patrón de "las franjas se ensanchan a medida que crece el índice de la dimensión". - Medio. Implementa el escalado RoPE NTK-aware. Entrena un LM diminuto en secuencias de longitud 256, luego prueba en longitud 1024 con y sin escalado. Mide la perplejidad.
- Difícil. Implementa ALiBi y RoPE en el mismo módulo de atención. Entrena un transformer de 4 capas en una tarea de copia con secuencias de longitud 512. Extrapola a 2048 en tiempo de prueba. Compara la degradación.
Términos Clave
| Término | Lo que la gente dice | Lo que realmente significa |
|---|---|---|
| Codificación posicional | "Le dice a la atención sobre el orden" | Cualquier señal añadida a los embeddings o a la atención que codifica la posición. |
| Sinusoidal | "La original" | sin/cos en frecuencias geométricas añadidos a los embeddings; no extrapola. |
| RoPE | "Rotary embeddings" | Rota Q, K por un ángulo dependiente de la posición; el producto punto codifica la distancia relativa. |
| ALiBi | "Truco del sesgo lineal" | Suma `-m· |
| base | "El control de RoPE" | El escalador de frecuencia en RoPE; auméntalo para extender el contexto en la inferencia. |
| NTK-aware | "Un truco de escalado de RoPE" | Reescala base para que las dimensiones de alta frecuencia no se compriman cuando el contexto se expande. |
| YaRN | "El sofisticado" | Interpolación+extrapolación por dimensión que preserva la entropía de la atención. |
| Extrapolación | "Funciona más allá de la longitud entrenada" | ¿El esquema de posición puede generar salida correcta más allá del max_len visto en el entrenamiento? |
Lectura Adicional
- Vaswani et al. (2017). Attention Is All You Need §3.5 — sinusoidal original.
- Su et al. (2021). RoFormer: Enhanced Transformer with Rotary Position Embedding — artículo de RoPE.
- Press, Smith, Lewis (2021). Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation — ALiBi.
- Peng et al. (2023). YaRN: Efficient Context Window Extension of Large Language Models — estado del arte en escalado de RoPE.
- Chen et al. (2023). Extending Context Window of Large Language Models via Positional Interpolation — artículo de contexto largo de Llama 2 de Meta.
- Ding et al. (2024). LongRoPE: Extending LLM Context Window Beyond 2 Million Tokens — el método de Microsoft usado por Phi-3-Long y citado en la sección Úsalo.
- HuggingFace Transformers —
modeling_rope_utils.py— implementaciones de nivel de producción de cada esquema de escalado RoPE (default, linear, dynamic, YaRN, LongRoPE, Llama-3).