La atención es el mecanismo que le permite a un token "mirar" a los tokens anteriores y decidir cuáles son relevantes. Aquí lo hacemos con números reales, paso a paso.
Un detective examina una escena del crimen. No lee todo el expediente de principio a fin — tiene una pregunta específica: "¿quién estaba aquí a las 9pm?". Compara esa pregunta con cada pista disponible: el testimonio de un vecino, las huellas en el suelo, el registro de la cámara. Algunos se ajustan bien a su pregunta, otros no. Las pistas más relevantes tienen más peso en su conclusión.
Cada token de salida es una mezcla ponderada de los Values anteriores. Los pesos de la mezcla vienen de qué tan bien coincide la Query del token actual con las Keys de los tokens anteriores.
Tenemos 3 tokens: k(pos 0), a(pos 1), r(pos 2) Embeddings de entrada (simplificados a 4 dimensiones): x_k = [1.2, 0.3, -0.5, 0.8] x_a = [0.4, 1.1, 0.7, -0.2] x_r = [0.9, -0.4, 1.3, 0.6] ← el token activo Paso 1: Proyectamos en Q, K, V con matrices entrenadas (simplificamos: cada proyección es una combinación lineal) Q_r = [1.0, 0.5, 0.2, 0.8] ← "la pregunta de r" K_k = [0.9, 0.4, 0.1, 0.7] ← "lo que ofrece k" K_a = [0.3, 1.2, 0.6, 0.2] ← "lo que ofrece a" K_r = [0.8, 0.3, 0.9, 0.5] ← "lo que ofrece r" V_k = [0.5, -0.3, 0.8, 0.1] V_a = [1.1, 0.2, 0.4, -0.5] V_r = [0.7, 0.9, 0.3, 0.6] Paso 2: Scores = Q_r · K / √d (dividimos por √4 = 2) score(r,k) = (1.0×0.9 + 0.5×0.4 + 0.2×0.1 + 0.8×0.7) / 2 = (0.9 + 0.2 + 0.02 + 0.56) / 2 = 1.68 / 2 = 0.84 score(r,a) = (1.0×0.3 + 0.5×1.2 + 0.2×0.6 + 0.8×0.2) / 2 = (0.3 + 0.6 + 0.12 + 0.16) / 2 = 1.18 / 2 = 0.59 score(r,r) = (1.0×0.8 + 0.5×0.3 + 0.2×0.9 + 0.8×0.5) / 2 = (0.8 + 0.15 + 0.18 + 0.4) / 2 = 1.53 / 2 = 0.77 Paso 3: Softmax de los scores exp(0.84) = 2.316, exp(0.59) = 1.804, exp(0.77) = 2.160 suma = 6.280 pesos = [2.316/6.280, 1.804/6.280, 2.160/6.280] = [0.369, 0.287, 0.344] ← suman 1.000 ✅ Paso 4: Suma ponderada de los Values output_r = 0.369 × V_k + 0.287 × V_a + 0.344 × V_r dimensión 0: 0.369×0.5 + 0.287×1.1 + 0.344×0.7 = 0.185+0.316+0.241 = 0.742 dimensión 1: 0.369×(-0.3) + 0.287×0.2 + 0.344×0.9 = -0.111+0.057+0.310 = 0.256 ... (y así para las 4 dimensiones) output_r = [0.742, 0.256, ...] ← vector de 4 dims con contexto mezclado
Un detalle importante: durante el entrenamiento, el modelo procesa toda la secuencia a la vez. Pero cada token solo puede mirar hacia atrás, no hacia adelante. Si estamos prediciendo el carácter en posición 3, no podemos usar la información de la posición 4 — eso sería "hacer trampa".
La máscara causal pone -∞ en los scores de posiciones futuras. Después del softmax, exp(-∞) = 0, así que esas posiciones tienen peso 0 en la suma ponderada.
Cada fila representa un token. Los -∞ (triángulo superior) bloquean la atención hacia el futuro. El token 'k' solo se ve a sí mismo; 'a' ve a 'k' y a sí misma; 'r' ve a los tres.
Selecciona qué token es el "activo" y ve sus pesos de atención sobre los anteriores: