Saltar al contenido
← Attention Is All You Need

Lección 4 de 10 · El mecanismo de atención · 20 min

Positional encoding: devolverle el orden a las palabras

Por qué la atención es ciega al orden, cómo funcionan las codificaciones sinusoidales, su propiedad de posición relativa y cómo evolucionaron hacia RoPE y ALiBi.

Notebook del episodio

El código de esta lección, para correrlo y modificarlo en Google Colab, gratis y con tu cuenta. Para guardar tus cambios: Archivo → Guardar una copia en Drive.


La atención es un conjunto, no una secuencia

Haz este experimento mental: toma la oración "el perro mordió al hombre" y permuta las palabras a "el hombre mordió al perro". ¿Qué cambia en la self-attention?

Nada sustancial. Los puntajes qi⋅kjq_i \cdot k_j dependen solo del contenido de los tokens ii y jj, no de dónde están. Si permutas la entrada, la salida se permuta exactamente igual. Formalmente, la self-attention es equivariante a permutaciones: para cualquier matriz de permutación PP,

Attention(PXWQ, PXWK, PXWV)=P⋅Attention(XWQ, XWK, XWV)\text{Attention}(PX W^Q,\, PX W^K,\, PX W^V) = P \cdot \text{Attention}(XW^Q,\, XW^K,\, XW^V)

si desordenas las palabras de entrada (PP las permuta), la salida sale desordenada igual: la atención sola no sabe en qué orden venían

Para un modelo de lenguaje esto es un desastre: el orden lo es todo. Las RNN tenían el orden "gratis", porque procesaban token por token. Al quitar la recurrencia, el Transformer lo perdió. Hay que inyectarlo explícitamente.

Comprueba tu comprensión

Sin codificación posicional, ¿qué pasa con la salida de una capa de self-attention si permutas el orden de los tokens de entrada?

La solución del paper: sumar una señal de posición

El Transformer suma a cada embedding de token un vector PEpos∈RdmodelPE_{pos} \in \mathbb{R}^{d_{\text{model}}} que depende solo de la posición. Los autores eligieron una función fija, sin parámetros, hecha de senos y cosenos:

PE(pos, 2i)=sin⁡ ⁣(pos100002i/dmodel),PE(pos, 2i+1)=cos⁡ ⁣(pos100002i/dmodel)PE_{(pos,\, 2i)} = \sin\!\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right), \qquad PE_{(pos,\, 2i+1)} = \cos\!\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right)

a cada posición pospos le toca una huella de senos y cosenos: cada par de dimensiones (2i2i y 2i+12i+1) oscila a su propio ritmo, rápido en las primeras y lento en las últimas

Cada par de dimensiones (2i,2i+1)(2i, 2i+1) es una sinusoide con su propia frecuencia ωi=1/100002i/dmodel\omega_i = 1/10000^{2i/d_{\text{model}}}. Las longitudes de onda forman una progresión geométrica desde 2π2\pi (dimensiones bajas, oscilan rápido) hasta 10000⋅2π10000 \cdot 2\pi (dimensiones altas, casi constantes).

Explora el widget: el mapa de calor muestra PEPE para cada posición (filas) y dimensión (columnas). Observa cómo las primeras dimensiones oscilan rápido y las últimas varían lentamente. El panel de similitud muestra el producto punto entre posiciones: decae suavemente con la distancia.

La propiedad clave: posiciones relativas como rotaciones

¿Por qué senos y cosenos y no, por ejemplo, el número de posición normalizado? El paper da la razón:

“We chose this function because we hypothesized it would allow the model to easily learn to attend by relative positions, since for any fixed offset k, PE_{pos+k} can be represented as a linear function of PE_{pos}.”
— Sección 3.5

Veámoslo. Para un par de dimensiones con frecuencia ω\omega, escribe el bloque como el vector (sin⁡(ω pos),cos⁡(ω pos))(\sin(\omega\, pos), \cos(\omega\, pos)). Por las identidades trigonométricas de suma de ángulos:

(sin⁡(ω(pos+k))cos⁡(ω(pos+k)))=(cos⁡(ωk)sin⁡(ωk)−sin⁡(ωk)cos⁡(ωk))(sin⁡(ω pos)cos⁡(ω pos))\begin{pmatrix} \sin(\omega(pos+k)) \\ \cos(\omega(pos+k)) \end{pmatrix} = \begin{pmatrix} \cos(\omega k) & \sin(\omega k) \\ -\sin(\omega k) & \cos(\omega k) \end{pmatrix} \begin{pmatrix} \sin(\omega\, pos) \\ \cos(\omega\, pos) \end{pmatrix}

correr la posición kk lugares es girar el par (seno, coseno) un ángulo ωk\omega k: el giro depende de cuánto te mueves, no de dónde estás

La matriz es una rotación que depende solo del desplazamiento kk, no de pospos. Así que existe una única transformación lineal MkM_k (bloque-diagonal, una rotación por frecuencia) tal que PEpos+k=Mk PEposPE_{pos+k} = M_k \, PE_{pos} para toda posición. Una capa lineal, como las proyecciones WQW^Q y WKW^K, puede en principio aprender a explotar esa estructura para atender "tres posiciones atrás" sin importar dónde estés.

Corolario útil: el producto punto PEpos⋅PEpos+k=∑icos⁡(ωik)PE_{pos} \cdot PE_{pos+k} = \sum_i \cos(\omega_i k) depende solo de kk. La similitud entre codificaciones es una función de la distancia relativa, que es justo lo que ves en el widget.

Comprueba tu comprensión

¿Qué propiedad matemática hace que, en las codificaciones sinusoidales, PE_{pos+k} sea una función lineal de PE_{pos}?

¿Sumar o concatenar?

Una pregunta frecuente: ¿por qué sumar la posición al embedding en vez de concatenarla? Sumar no agrega dimensiones ni parámetros, y en espacios de alta dimensión dos señales sumadas pueden convivir en subespacios casi ortogonales. La red aprende a separarlas cuando lo necesita. El costo es cierta interferencia entre contenido y posición, que es una de las motivaciones de los métodos posteriores.

Otro detalle de implementación del paper: los embeddings se multiplican por dmodel\sqrt{d_{\text{model}}} antes de sumar la codificación posicional, para que la señal de contenido no quede eclipsada.

python
import math
import torch

def sinusoidal_pe(max_len: int, d_model: int) -> torch.Tensor:
    pos = torch.arange(max_len).unsqueeze(1)                       # (L, 1)
    div = torch.exp(torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model))
    pe = torch.zeros(max_len, d_model)
    pe[:, 0::2] = torch.sin(pos * div)
    pe[:, 1::2] = torch.cos(pos * div)
    return pe                                                       # (L, d_model)

# x = embedding(tokens) * math.sqrt(d_model) + pe[:seq_len]

¿Aprendidas o fijas?

Los autores también probaron embeddings posicionales aprendidos (un vector entrenable por posición) y obtuvieron resultados casi idénticos (Tabla 3, fila E). Eligieron las sinusoides porque podrían permitir extrapolar a secuencias más largas que las vistas en entrenamiento. BERT y GPT-2, en cambio, usaron posiciones aprendidas, con un límite duro de longitud.

En la práctica, ni las sinusoides absolutas ni las aprendidas extrapolan bien. Eso motivó una línea de investigación entera.

Los descendientes: RoPE y ALiBi

La intuición de "posición relativa como rotación" resultó tan buena que se convirtió en el estándar, pero aplicada de otra manera.

RoPE (Rotary Position Embedding, Su et al., 2021). En vez de sumar la posición al embedding una vez al principio, RoPE rota directamente las queries y keys en cada capa de atención, con los mismos bloques de rotación 2×2 que vimos arriba. Si rotas qq por un ángulo proporcional a su posición mm y kk por uno proporcional a nn, su producto punto depende solo de m−nm - n:

(Rmq)⊤(Rnk)=q⊤Rm⊤Rnk=q⊤Rn−m k(R_m q)^\top (R_n k) = q^\top R_m^\top R_n k = q^\top R_{n-m}\, k

girar la query según su posición mm y la key según la suya, nn, deja un puntaje que solo depende de la distancia n−mn - m

La posición relativa entra exactamente en el puntaje de atención, sin contaminar los values. RoPE es la codificación usada por la mayoría de los LLM abiertos actuales (LLaMA, Mistral, Qwen, entre otros), y técnicas como el escalado de frecuencias (por ejemplo, YaRN) permiten extender su contexto.

ALiBi (Attention with Linear Biases, Press et al., 2021). Ni siquiera usa embeddings posicionales: suma a cada puntaje de atención un sesgo negativo proporcional a la distancia, −m⋅∣i−j∣-m \cdot |i - j|, con una pendiente mm distinta por cabeza. Penaliza la atención lejana de forma simple y mostró buena extrapolación a longitudes mayores que las de entrenamiento.

Comprueba tu comprensión

¿Cuál es la diferencia central entre la codificación sinusoidal del paper original y RoPE?

Resumen

  • La self-attention es equivariante a permutaciones: sin información de posición no distingue el orden.
  • El paper suma sinusoides de frecuencias geométricas a los embeddings.
  • Desplazar la posición equivale a una rotación, así que las posiciones relativas son linealmente accesibles.
  • Embeddings aprendidos rinden parecido; la extrapolación motivó RoPE y ALiBi, hoy dominantes.

¿Qué tal esta lección?

Sé el primero en calificarla

Entra para calificar

¿Terminaste la lección?

Márcala para sumar +50 XP y mantener tu racha.