33 · El bloque encoder
Ensambla el bloque encoder del transformer: atención multi-cabeza, residual + LayerNorm, una red feed-forward por posición, luego otro residual + LayerNorm. Apila N de ellos.
Un bloque encoder = Atención Multi-Cabeza → Add & Norm → Feed-Forward → Add & Norm. Los residuales permiten apilar en profundidad, LayerNorm estabiliza, la FFN añade no-linealidad por token.
Sin esto:
Sin la estructura del bloque (residuales + norm + FFN) no puedes apilar la atención en los transformers profundos que realmente funcionan.
Ya tenemos los dos ingredientes — atención multi-cabeza (lección 31) y codificación posicional (lección 32). Esta lección los ensambla en la unidad repetible de un encoder transformer: el bloque encoder. Un bloque es:
x → Atención Multi-Cabeza → Add & Norm → Feed-Forward → Add & Norm
Tres decisiones de diseño hacen que esto funcione, y cada una se gana su lugar:
-
Conexiones residuales (skip). La salida de cada subcapa se SUMA a su entrada:
x + Subcapa(x), no soloSubcapa(x). Esto permite que la señal original — y, durante la retropropagación, el gradiente — fluya directamente, así podemos apilar docenas de bloques sin que se desvanezcan los gradientes. (Es la misma idea que viste en las ResNets.) -
Normalización por capa (LayerNorm). Tras cada suma residual, LayerNorm normaliza cada vector de token a media cero y varianza unitaria (a través de sus características), y luego reescala con
gammaybetaaprendidos. Mantiene las activaciones en un rango estable capa tras capa, que es lo que hace entrenables las pilas muy profundas. -
Red feed-forward por posición (FFN). La atención MEZCLA información entre posiciones pero es, por posición, un promedio ponderado casi lineal. La FFN —
Linear → ReLU (o GELU) → Linear— se aplica de forma INDEPENDIENTE a cada token (los mismos pesos para cada posición) y añade no-linealidad y capacidad por token. La dimensión interna suele ser4 × d_model(p. ej. 2048 para d_model = 512): la red expande, aplica una no-linealidad y luego proyecta de vuelta.
Un encoder transformer es simplemente N bloques idénticos apilados (N = 6 en el paper original, 12/24/96 en los modelos modernos). Cada bloque tiene sus propios pesos; la forma de salida (seq, d_model) iguala a la de entrada, así que los bloques se componen limpiamente.
Python (in browser)
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Las flechas verdes punteadas son las conexiones residuales que rodean cada subcapa.
Read-along de PyTorch: nn.TransformerEncoderLayer (un bloque) y nn.TransformerEncoder (pila de N)
¿Cuál es el papel de la conexión residual (skip) en un bloque Transformer?
- Un bloque encoder es Atención Multi-Cabeza → Add & Norm → Feed-Forward → Add & Norm, y un encoder transformer apila N bloques idénticos manteniendo la forma (seq, d_model) en todo momento.
- Las conexiones residuales dan a la señal y al gradiente una ruta de paso limpia (permitiendo pilas profundas), y LayerNorm reescala cada token a media/varianza estables tras cada suma residual.
- La FFN por posición (Linear → ReLU/GELU → Linear, dimensión interna usualmente 4·d_model) añade no-linealidad por token, complementando la mezcla entre posiciones de la atención.
El bloque encoder es la unidad repetida de BERT, RoBERTa, ViT y la mitad encoder de T5 y Whisper. 'BERT-large tiene 24 capas' significa 24 de estos bloques apilados.
Si lo quitas: Conocerías la atención pero no cómo se conecta en una red profunda entrenable — dejando 'Add & Norm', 'FFN' y 'pre-norm vs post-norm' como etiquetas misteriosas en cada diagrama de arquitectura.