Cómo le decimos al modelo "esta palabra es la primera, esa la segunda, aquella la tercera". Sin esto, "el perro come" y "come perro el" se ven idénticos.
El positional encoding le inyecta a cada token la información de en qué posición está dentro de la frase.
Decirle al modelo el orden de las palabras, sumando a cada embedding un vector que codifica su posición (0, 1, 2, ...).
Información de posición. Permite distinguir "el perro come" de "come perro el" aunque tengan exactamente las mismas palabras.
El Transformer procesa todos los tokens en paralelo (no uno por uno), así que "pierde" el orden. Sin positional encoding, trataría la frase como un conjunto desordenado de palabras.
↓ A continuación, el detalle con ejemplos y visualizaciones ↓
En el paso 2 vimos que tokenizar + buscar en la matriz E nos da un vector por cada token. Pero esos vectores no saben en qué posición están. El embedding de "perro" es exactamente el mismo si "perro" es la primera palabra o la última.
Aquí tienes una frase tokenizada y embebida. Después la misma frase, pero con las palabras desordenadas. Fíjate qué pasa con los vectores.
En las redes neuronales antiguas (RNNs, LSTMs), el orden estaba implícito porque procesaban los tokens uno por uno, secuencialmente. Pero el Transformer los procesa todos a la vez en paralelo — esa es su gran ventaja en velocidad. El precio: pierde el orden, y hay que inyectárselo de otra forma.
Antes de ver la solución correcta, veamos por qué la idea más obvia falla. Lo más simple sería: "al embedding del token de la posición 0 sumarle 0, al de la posición 1 sumarle 1, al de la posición 2 sumarle 2..."
Cantidad de tokens en la frase:
Necesitamos algo que: (1) esté acotado (no crezca sin límite), (2) sea distinto en cada dimensión, y (3) varíe de forma suave y predecible con la posición. La solución del paper "Attention is All You Need" (2017) usa senos y cosenos. Vamos a ver primero qué son esas funciones.
Si en el colegio te dijeron "seno es el cateto opuesto sobre la hipotenusa" y no entendiste nada, olvídate. Para nuestro propósito, los necesitamos por una sola razón: son las funciones más útiles para generar valores que oscilan suavemente entre -1 y +1.
La idea fundamental en una frase: seno y coseno son las funciones matemáticas que describen cualquier cosa que se repite, gira u oscila. Si algo va en círculos, sube y baja periódicamente, o vibra — seno y coseno están involucrados.
Imaginá una rueda girando (la vas a ver en vivo más abajo). Tomá un punto en el borde y miralo girar:
Ambos son proyecciones de un movimiento circular sobre una línea recta. Por eso, cualquier cosa con algo de "circular" o "periódico" se puede describir con ellos.
La lista es enorme. Algunos ejemplos:
Cuatro propiedades que las hacen ideales:
Ahora con todo esto en la cabeza, podés ver por qué fueron la elección obvia para inyectar posición en el Transformer. Necesitábamos una función que:
| Que esté acotada (no crezca sin límite) | ✓ sen/cos viven en [-1, +1] |
| Que sea suave (posiciones cercanas → valores parecidos) | ✓ las ondas son continuas y suaves |
| Que dé un patrón único para cada posición | ✓ combinando varias frecuencias |
| Que funcione para cualquier longitud, incluso no vista en entrenamiento | ✓ la fórmula calcula bien cualquier posición |
Seno y coseno cumplen las 4 propiedades gratis, sin necesidad de aprender nada. Por eso fueron la elección natural.
Imagina que tomas una rueda y le pintas un punto rojo en el borde. Ahora la haces girar lentamente. Si miras la rueda desde un lado, ves que el punto rojo sube y baja una y otra vez.
Ambos valores oscilan suavemente entre -1 y +1 (porque la rueda tiene radio 1).
Izquierda: la rueda girando. Derecha: el seno (rojo) y coseno (azul) de su posición a lo largo del tiempo. Fíjate cómo ambos son la misma onda, solo que desfasada — el coseno empieza arriba (1), el seno empieza en el medio (0).
Las funciones seno y coseno toman un número (que llamaremos x) y devuelven otro número entre -1 y +1:
Para entender cómo cambia el output según x:
Cada vez que x avanza 2π (≈ 6.28), las funciones completan un ciclo. Esto se llama período.
Si en lugar de sen(x) calculamos sen(k · x), la onda oscila más rápido (si k > 1) o más lento (si k < 1). A ese factor k se le llama frecuencia.
La curva azul es sen(x) (frecuencia 1). La curva amarilla es sen(k·x), con el k que controlas. Mueve el slider para ver el efecto.
La idea genial del paper original: para cada posición pos, generar un vector de d valores usando seno y coseno con frecuencias distintas en cada par de dimensiones.
Sí, se ve intimidante. Vamos a desarmar cada pedazo:
pos = la posición del token en la frase (0, 1, 2, 3, ...). En "el perro come": "el" → pos=0, "perro" → pos=1, "come" → pos=2.i = el índice del PAR de dimensiones (0, 1, 2, ..., d/2 − 1). OJO: i NO es el número de la dimensión individual — es el número del par. Cada valor de i produce DOS dimensiones a la vez: una usa seno (la 2i), otra usa coseno (la 2i+1). Lo aclaramos abajo con una tabla.d = la cantidad total de dimensiones del embedding (ej: 4, 768, 12288). Como i indexa pares, hay d/2 valores de i.10000 = una constante elegida por los autores. Controla cuánto cambian las frecuencias entre dimensiones. No tiene nada mágico — eligieron 10000 porque funcionó bien empíricamente.i y "dimensión"
Este es el detalle que más confunde a la gente. En la fórmula, i NO es el número de la dimensión que estamos calculando — es el número del par al que pertenece esa dimensión. Cada i produce dos dimensiones simultáneamente:
i en el exponente 10000^(2i/d).i y la fórmula (con d=4)| dim del vector | ¿qué par es? | i | 2i | exponente (2i/d) | divisor (10000^exp) | función |
|---|---|---|---|---|---|---|
| 0 | par #0 | 0 | 0 | 0/4 = 0 | 10000⁰ = 1 | seno |
| 1 | par #0 | 0 | 0 | 0/4 = 0 | 10000⁰ = 1 | coseno |
| 2 | par #1 | 1 | 2 | 2/4 = 0.5 | 10000⁰·⁵ = 100 | seno |
| 3 | par #1 | 1 | 2 | 2/4 = 0.5 | 10000⁰·⁵ = 100 | coseno |
Observaciones clave de la tabla:
i=0, comparten el divisor 1, pero una usa seno y la otra coseno.i=1, comparten el divisor 100, pero una usa seno y la otra coseno.d=4 hay solo 4/2 = 2 valores posibles de i: 0 y 1.Vamos a calcular el PE para cada una de las 3 palabras de nuestra frase de ejemplo. Recordá: "el" está en pos=0, "perro" en pos=1, "come" en pos=2.
Elegimos pos=1 para verlo en detalle porque pos=0 es un caso trivial (todos los ángulos son 0).
Par i=0 (produce las dimensiones 0 y 1): divisor = 10000^(2·0/4) = 10000^0 = 1 ángulo = pos / divisor = 1 / 1 = 1.000 dim 0 = sen(1.000) = +0.841 dim 1 = cos(1.000) = +0.540 ↑ mismo ángulo que dim 0 (ambos son del par i=0), pero uno usa sen y el otro cos. Par i=1 (produce las dimensiones 2 y 3): divisor = 10000^(2·1/4) = 10000^0.5 = 100 ángulo = pos / divisor = 1 / 100 = 0.010 dim 2 = sen(0.010) = +0.010 dim 3 = cos(0.010) = +0.99995 ↑ mismo ángulo que dim 2 (ambos son del par i=1), pero uno usa sen y el otro cos. Vector PE final para pos=1 ("perro"): PE(1) = [+0.841, +0.540, +0.010, +0.99995]
Aplicando exactamente la misma receta a pos=0 y pos=2:
| palabra | pos | dim 0 (sen) | dim 1 (cos) | dim 2 (sen) | dim 3 (cos) |
|---|---|---|---|---|---|
| "el" | 0 | sen(0/1) = 0.000 | cos(0/1) = +1.000 | sen(0/100) = 0.000 | cos(0/100) = +1.000 |
| "perro" | 1 | sen(1/1) = +0.841 | cos(1/1) = +0.540 | sen(1/100) = +0.010 | cos(1/100) = +0.99995 |
| "come" | 2 | sen(2/1) = +0.909 | cos(2/1) = -0.416 | sen(2/100) = +0.020 | cos(2/100) = +0.9998 |
Cada vector PE se suma posición por posición al embedding de su palabra correspondiente. Estos embeddings vienen de la matriz E (paso 2) — recordá que para esta guía usamos valores específicos para cada palabra:
"el" (pos=0): embedding: [+0.21, -0.55, +0.08, +0.43] + PE(0): [+0.00, +1.00, +0.00, +1.00] ────────────────────────────────────────────────────── = input final: [+0.21, +0.45, +0.08, +1.43] "perro" (pos=1): embedding: [-0.34, +0.61, +0.77, -0.12] + PE(1): [+0.84, +0.54, +0.01, +1.00] ────────────────────────────────────────────────────── = input final: [+0.50, +1.15, +0.78, +0.88] "come" (pos=2): embedding: [+0.45, -0.22, -0.30, +0.91] + PE(2): [+0.91, -0.42, +0.02, +1.00] ────────────────────────────────────────────────────── = input final: [+1.36, -0.64, -0.28, +1.91]
Estos 3 vectores finales son lo que entra al Paso 4 (Self-Attention). Fíjate que si reordenáramos la frase a "come perro el", la palabra "el" estaría en pos=2 en lugar de pos=0, así que se le sumaría PE(2) en lugar de PE(0) — y el input final sería distinto. Ese es justamente el punto del positional encoding.
2i" como un solo símbolo que vale 0, 2, 4, ... (no "i = 0, 1, 2"). Cada par produce dos dimensiones consecutivas, así que i hace de "contador de pares", no de "contador de dimensiones".
Las dimensiones con índice par dentro del vector (dim 0, dim 2, dim 4, ...) usan seno. Las dimensiones con índice impar (dim 1, dim 3, dim 5, ...) usan coseno. Esto alterna las dos funciones a lo largo del vector. Tener ambas (no solo seno) le da al modelo más información sobre cada frecuencia — si solo tuvieras sen(x), valores como 0.5 podrían corresponder a múltiples ángulos. Con sen y cos juntos, el ángulo queda determinado de forma única.
100002i/d en el divisor?Esta es la parte clave. Recuerda que en seno/coseno, un divisor pequeño = frecuencia alta (oscila rápido con la posición), y un divisor grande = frecuencia baja (oscila lento con la posición).
Cada par i tiene su propio divisor, y como i va de 0 a d/2 − 1, los divisores recorren un rango muy amplio:
i = 0, dimensiones 0 y 1): 100000 = 1 → divisor mínimo → frecuencia más alta. Estas dimensiones oscilan rápido y sirven para distinguir tokens cercanos.i = d/2 − 1, dimensiones d−2 y d−1): el exponente 2i/d se acerca a 1, así que el divisor se acerca a 10000 → frecuencia más baja. Estas dimensiones casi no cambian y sirven para distinguir tokens muy lejanos.Resultado: los primeros pares de dimensiones del vector PE cambian rápido con la posición, y los últimos pares cambian lento. Es como tener un reloj con muchas manecillas a distintas velocidades — combinando todas, cada posición tiene una "hora" única.
Vamos a calcular el positional encoding para un par de dimensiones específicas, con números reales. Recordá: cada valor de i produce dos dimensiones (2i con seno y 2i+1 con coseno).
Y ahora calculemos el vector PE completo (con todas las dimensiones) para una sola posición:
Aquí ves el PE completo para una secuencia de posiciones. Cada fila es una posición; cada columna es una dimensión. Los colores representan el valor (azul = negativo, blanco = cero, naranja = positivo).
Fíjate cómo las primeras columnas (dimensiones bajas) cambian rápido entre filas — alta frecuencia. Las últimas columnas (dimensiones altas) casi no cambian — baja frecuencia. Cada fila tiene un patrón único y eso es lo que el modelo usa como "huella digital" de la posición.
Ahora la pregunta del millón: ¿cómo se mezclan el embedding del token (que tiene "qué" palabra es) y el positional encoding (que tiene "dónde" está)? La respuesta es muy simple:
Sí, literalmente se suman. Element-wise (posición por posición). Como ambos vectores tienen la misma dimensión d, la suma es directa.
Aquí tienes una frase de 3 tokens con sus embeddings, sus positional encodings, y la suma resultante:
Concatenar significaría poner los dos vectores uno al lado del otro: si embedding es de 4 dim y PE es de 4 dim, el resultado sería de 8 dim. Pero sumar tiene varias ventajas:
Volvamos al ejemplo del principio: "el perro come" vs "come perro el". Ahora con positional encoding sumado a los embeddings:
El PE sinusoidal del paper original funciona, pero en 2026 la mayoría de los LLMs grandes usan variantes mejores:
Pero la idea fundamental sigue siendo la misma: hay que inyectar información posicional de alguna manera, porque self-attention pura no la tiene. El paper original es la primera y más clara forma de hacerlo, por eso lo estudiamos primero.
[847, 2103, 1492][v_el, v_perro, v_come][PE(0), PE(1), PE(2)][v_el + PE(0), v_perro + PE(1), v_come + PE(2)][n_tokens × d] que tiene tanto el qué como el dónde de cada token.En el Paso 4: Self-Attention, esta matriz se convierte en la entrada del corazón del Transformer. Ahí cada token va a "mirar" a los demás y decidir cuáles son relevantes para entenderse a sí mismo. Es el paso más importante de todos — y donde se concentra la magia.