Transformers — Módulo 3: multi-head attention — varias miradas a la vez
Tercer módulo del Curso de Transformers: multi-head attention. Por qué una sola atención capta una sola relación y cómo varias cabezas aprenden relaciones distintas en paralelo — sintaxis, correferencia, posición. Cómo se parte d_model en h cabezas, se corren en paralelo y se recombinan, con código PyTorch correcto y comentado.
☰ Índice del contenido
En el Módulo 2 montamos la atención: cada token mira a los demás y arma un promedio ponderado con contexto. Pero hay un límite escondido. Una sola operación de atención produce un patrón de pesos por token —una sola manera de repartir la mirada—. Y una frase tiene muchas relaciones en juego al mismo tiempo: quién es el sujeto del verbo, a qué sustantivo apunta un pronombre, qué adjetivo modifica a qué. Pedirle a una sola atención que capture todo eso a la vez es pedirle demasiado. La solución es tan simple como potente: correr varias atenciones en paralelo.
La tesis del módulo
Varias cabezas chicas ven más que una cabeza grande. En vez de una atención mirando todo, multi-head attention corre h atenciones independientes, cada una sobre un pedazo del vector, cada una libre de aprender una relación distinta. Después se juntan. Mismo costo de cómputo, muchísima más expresividad.
El problema de una sola cabeza
Piensa en la frase “el gato que perseguía al ratón estaba cansado”. Para entenderla, el modelo necesita, al mismo tiempo:
- Conectar “estaba cansado” con “gato” (quién está cansado), saltándose la subordinada.
- Conectar “perseguía” con “ratón” (a quién persigue).
- Conectar “que” con “gato” (correferencia).
Una sola atención tiene que comprimir todas esas relaciones en un único reparto de pesos. Es como pedirle a una persona que, con una sola mirada, atienda la sintaxis, el significado y la posición a la vez. Se puede a medias; se hace mucho mejor con miradas separadas.
La idea: partir, mirar en paralelo, juntar
Multi-head attention (atención de múltiples cabezas) resuelve esto con una cabeza (head): una copia independiente del mecanismo de atención, con sus propias matrices W_Q, W_K, W_V. En vez de una, usamos h cabezas (típicamente 8, 12, 16…).
El truco de eficiencia: no agrandamos nada. Tomamos el vector de dimensión d_model y lo partimos en h pedazos de tamaño d_k = d_model / h. Cada cabeza trabaja sobre su pedazo. Así, h cabezas cuestan casi lo mismo que una sola atención de tamaño completo, pero cada una es libre de especializarse.
El pipeline tiene cuatro movimientos:
vector del token (d_model = 512)
│
▼ proyectar y PARTIR en h=8 cabezas
┌──────┬──────┬──────┬─────┬──────┐
│ head1│ head2│ head3│ ... │ head8│ cada una d_k=64
└──┬───┴──┬───┴──┬───┴─────┴──┬───┘
│ │ │ │
▼ ▼ ▼ ▼ atención en paralelo
┌──────┬──────┬──────┬─────┬──────┐
│ out1 │ out2 │ out3 │ ... │ out8 │
└──────┴──────┴──────┴─────┴──────┘
│
▼ concatenar las 8 salidas ► d_model otra vez
│
▼ proyección final W_O (mezcla las cabezas)
vector de salida (d_model = 512)
- Proyectar y partir. El vector se proyecta a Q, K, V y se reparte en
hcabezas ded_kcada una. - Atención en paralelo. Cada cabeza corre la misma fórmula del módulo 2 (
softmax(QKᵀ/√d_k)·V) sobre su pedazo, independiente de las demás. - Concatenar. Las
hsalidas se pegan una tras otra, reconstruyendo un vector ded_model. - Proyección final. Una última matriz
W_Omezcla la información de todas las cabezas. Sin este paso, las cabezas quedarían aisladas;W_Oes donde “conversan”.
Qué aprende cada cabeza
Cuando se inspeccionan modelos entrenados, las cabezas muestran especializaciones sorprendentemente nítidas. No están programadas: emergen solas del entrenamiento.
| Cabeza (ejemplo típico) | En qué se especializa |
|---|---|
| Cabeza posicional | Mira al token anterior o al siguiente |
| Cabeza sintáctica | Conecta verbo con su sujeto u objeto |
| Cabeza de correferencia | Une el pronombre con el sustantivo que reemplaza |
| Cabeza de puntuación | Se ancla a comas, puntos, delimitadores |
| Cabeza “difusa” | Reparte atención amplia, tipo resumen del contexto |
Ojo: estas etiquetas son interpretaciones humanas a posteriori. El modelo no sabe qué es “sintaxis”; simplemente descubrió que repartir la atención de cierta forma reduce el error. Que emerjan roles legibles es un regalo, no un diseño.
En código: multi-head attention en PyTorch
Así se implementa el bloque completo. Los comentarios marcan los cuatro movimientos del diagrama:
import torch
import torch.nn as nn
import torch.nn.functional as F
class MultiHeadAttention(nn.Module):
def __init__(self, d_model, n_heads):
super().__init__()
assert d_model % n_heads == 0
self.d_model = d_model
self.n_heads = n_heads
self.d_k = d_model // n_heads # tamaño de cada cabeza
# Una sola proyección grande para Q, K, V y para la salida.
# (Proyectar todo junto y luego partir es más eficiente
# que tener h matrices separadas.)
self.W_q = nn.Linear(d_model, d_model)
self.W_k = nn.Linear(d_model, d_model)
self.W_v = nn.Linear(d_model, d_model)
self.W_o = nn.Linear(d_model, d_model) # proyección final
def forward(self, x):
# x: (batch, n_tokens, d_model)
B, T, _ = x.shape
# 1. Proyectar y PARTIR en cabezas.
# (B, T, d_model) -> (B, n_heads, T, d_k)
def partir(t):
return t.view(B, T, self.n_heads, self.d_k).transpose(1, 2)
Q = partir(self.W_q(x))
K = partir(self.W_k(x))
V = partir(self.W_v(x))
# 2. Atención en paralelo (todas las cabezas de una vez).
puntajes = (Q @ K.transpose(-2, -1)) / (self.d_k ** 0.5)
pesos = F.softmax(puntajes, dim=-1)
salida = pesos @ V # (B, n_heads, T, d_k)
# 3. Concatenar: volver a juntar las cabezas -> d_model.
salida = salida.transpose(1, 2).contiguous().view(B, T, self.d_model)
# 4. Proyección final que mezcla las cabezas.
return self.W_o(salida)
# Uso: 12 cabezas sobre vectores de 768 (config estilo BERT-base).
mha = MultiHeadAttention(d_model=768, n_heads=12)
x = torch.randn(2, 10, 768) # 2 frases, 10 tokens, 768 dims
print(mha(x).shape) # (2, 10, 768): misma forma que la entrada
Fíjate en algo clave: la entrada y la salida tienen la misma forma (d_model). Eso es a propósito —permite apilar muchos bloques uno tras otro, que es lo que haremos en el módulo 4—.
¿Por qué varias chicas y no una grande?
| Una cabeza grande (d_k = 512) | h cabezas chicas (d_k = 64 × 8) |
|---|---|
| Un solo patrón de atención | h patrones simultáneos e independientes |
| Debe comprimir todas las relaciones | Cada una se especializa en una |
| Menos robusta: un solo punto de vista | Redundancia y diversidad de miradas |
| Mismo costo de cómputo aproximado | Mismo costo, mucha más expresividad |
La clave está en la última fila: partir en cabezas no cuesta más. 8 × 64 = 512. Es el mismo cómputo repartido de forma que produce muchas vistas en lugar de una. Sale gratis; por eso todos los modelos lo usan.
Cuidado: más cabezas no siempre es mejor. Si
hcrece demasiado, cadad_kse vuelve tan chico que la cabeza casi no tiene espacio para representar nada útil. Hay un equilibrio; 8–16 cabezas es lo habitual parad_modelde cientos.
Errores comunes
- Creer que cada cabeza ve el vector completo. No: cada una trabaja sobre su pedazo de
d_k = d_model / h. Partir es parte del diseño. - Pensar que las cabezas se coordinan durante la atención. Corren independientes. Solo se mezclan al final, en la proyección
W_O. - Olvidar la proyección final
W_O. Sin ella, concatenar deja las cabezas como compartimentos estancos.W_Oes donde la información entre cabezas se combina. - Asumir que las especializaciones están programadas. Emergen del entrenamiento. Nadie le dice a una cabeza “encárgate de la sintaxis”.
- Subir
hsin mirard_k. Muchas cabezas diminutas pueden rendir peor que pocas con espacio suficiente.
La frase para llevarse
“Una sola mirada te da una opinión; ocho miradas en paralelo te dan una perspectiva. Multi-head attention es el modelo mirando la misma frase con ocho pares de ojos, cada uno buscando algo distinto.”
Qué viene
Módulo 4: la arquitectura completa. Ya tenemos la pieza estrella. Ahora la envolvemos en el bloque Transformer de verdad —con conexiones residuales, layer normalization y una red feed-forward— le devolvemos la noción de orden con positional encoding, y apilamos N bloques. Cierre del bloque básico.
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.