Saltar al contenido
← Attention Is All You Need

Lección 1 de 10 · El problema · 18 min

Antes del Transformer: el cuello de botella de la recurrencia

Por qué las RNN y seq2seq dominaban la traducción automática, qué resolvió la atención de Bahdanau y por qué eso no alcanzaba.

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.


El mundo en 2016

Si en 2016 querías traducir una frase del inglés al alemán con redes neuronales, la respuesta estándar era un modelo secuencia a secuencia (seq2seq) construido con redes recurrentes (RNN), casi siempre LSTM o GRU. La idea es elegante: un encoder lee la frase de entrada palabra por palabra y la comprime en un vector; un decoder toma ese vector y genera la traducción, también palabra por palabra.

Una RNN procesa una secuencia x1,…,xnx_1, \dots, x_n manteniendo un estado oculto (hidden state) que se actualiza en cada paso:

ht=f(ht−1,xt)h_t = f(h_{t-1}, x_t)

donde ff es una función aprendida (en una LSTM, un conjunto de compuertas). Todo lo que el modelo "sabe" sobre el pasado tiene que pasar por hth_t. Esa ecuación, tan simple, esconde los dos problemas que motivaron el Transformer.

Problema 1: la secuencialidad mata el paralelismo

Mira la dependencia: para calcular hth_t necesitas ht−1h_{t-1}, que a su vez necesita ht−2h_{t-2}, y así hasta el principio. No puedes calcular el estado del token 50 sin haber calculado antes los 49 anteriores. Dentro de una misma secuencia, el cómputo es inherentemente serial.

Las GPU son máquinas de paralelismo masivo: brillan cuando haces miles de multiplicaciones de matrices independientes a la vez. Una RNN las obliga a esperar. Puedes paralelizar entre ejemplos del batch, pero con secuencias largas la memoria limita el tamaño del batch, y vuelves a quedar atado al número de pasos.

“This inherently sequential nature precludes parallelization within training examples, which becomes critical at longer sequence lengths, as memory constraints limit batching across examples.”
— Sección 1

Problema 2: el camino largo entre dos palabras

El segundo problema es sobre flujo de información. Si la palabra 3 de una oración es relevante para entender la palabra 40, la señal tiene que atravesar 37 aplicaciones sucesivas de ff. En el forward pass la información se diluye; en el backward pass los gradientes se desvanecen o explotan. Las LSTM mitigaron esto con sus compuertas y su celda de memoria, pero no lo eliminaron: la longitud del camino entre dos posiciones sigue siendo O(n)O(n).

El paper de Vaswani et al. lo formula como una de sus tres métricas centrales (Tabla 1): la longitud máxima de camino entre dos posiciones cualesquiera de la red. Cuanto más corto, más fácil aprender dependencias de largo alcance.

Comprueba tu comprensión

¿Cuál es la principal razón por la que una RNN no puede paralelizar el cómputo dentro de una misma secuencia durante el entrenamiento?

El cuello de botella del vector fijo

En el seq2seq original (Sutskever et al., 2014; Cho et al., 2014), el encoder comprimía toda la oración de entrada en un único vector de contexto c=hnc = h_n, el último estado oculto. El decoder generaba la traducción completa a partir de ese vector.

Esto funciona para frases cortas, pero un vector de tamaño fijo no escala: una oración de 5 palabras y una de 50 tienen que caber en el mismo espacio. Empíricamente, la calidad de traducción caía de forma abrupta con la longitud de la oración.

La atención de Bahdanau (2015)

La solución llegó con Bahdanau, Cho y Bengio: en vez de forzar al decoder a depender de un único vector, le permitimos mirar todos los estados del encoder en cada paso y decidir cuáles importan. Para generar la palabra ii de la salida, el decoder calcula un puntaje de alineamiento (alignment score) entre su estado si−1s_{i-1} y cada estado del encoder hjh_j:

eij=v⊤tanh⁡(Wsi−1+Uhj)e_{ij} = v^\top \tanh(W s_{i-1} + U h_j)

cuánto le sirve la palabra de entrada jj (su estado hjh_j) al decoder, que acaba de quedar en el estado si−1s_{i-1}. WW, UU y vv son pesos que se aprenden

Esos puntajes se normalizan con softmax para obtener pesos αij\alpha_{ij} que suman 1, y el contexto es un promedio ponderado:

αij=exp⁡(eij)∑kexp⁡(eik),ci=∑jαijhj\alpha_{ij} = \frac{\exp(e_{ij})}{\sum_k \exp(e_{ik})}, \qquad c_i = \sum_j \alpha_{ij} h_j

los puntajes pasan a porcentajes que suman 1 (αij\alpha_{ij}), y el contexto cic_i es el promedio de los estados de entrada, pesado por esos porcentajes

Ahora cada palabra de salida tiene su propio contexto, enfocado en las partes relevantes de la entrada. Al traducir un adjetivo, el modelo puede "mirar" el sustantivo al que modifica aunque esté en otra posición. Las matrices α\alpha resultantes producían visualizaciones de alineamiento muy interpretables, y la calidad dejó de degradarse con la longitud.

Esta forma de puntaje se conoce como atención aditiva (additive attention), porque combina las dos representaciones sumándolas antes de la no linealidad. Más adelante Luong et al. (2015) propusieron variantes multiplicativas basadas en producto punto, más baratas. El Transformer se apoyará en esta segunda familia.

Comprueba tu comprensión

¿Qué problema específico del seq2seq original resolvió la atención de Bahdanau?

Lo que la atención no resolvió

Aquí está el punto clave para entender la motivación del paper. Después de Bahdanau, la atención era un complemento de las RNN: un mecanismo que conectaba encoder y decoder. Pero los estados hjh_j seguían siendo producidos por una recurrencia. Seguías teniendo:

  • Cómputo serial dentro de la secuencia (problema 1 intacto).
  • Caminos de longitud O(n)O(n) dentro del encoder para relacionar palabras de la entrada entre sí (problema 2 solo parcialmente aliviado).

Hubo intentos de quitar la recurrencia usando convoluciones: ByteNet y ConvS2S procesaban todas las posiciones en paralelo. Pero una convolución con kernel de tamaño kk solo ve kk vecinos; para conectar posiciones lejanas necesitas apilar muchas capas, y la longitud de camino crece como O(n/k)O(n/k) o O(log⁡kn)O(\log_k n) según la arquitectura.

La apuesta del paper

La pregunta de Vaswani et al. fue radical: ¿y si la atención no es un complemento sino todo el modelo? Si cada posición puede atender directamente a cada otra posición —incluyendo posiciones de la misma secuencia, lo que se llama autoatención (self-attention)— entonces:

Tipo de capaComplejidad por capaOperaciones secuencialesLongitud máx. de camino
Self-attentionO(n2⋅d)O(n^2 \cdot d)O(1)O(1)O(1)O(1)
RecurrenteO(n⋅d2)O(n \cdot d^2)O(n)O(n)O(n)O(n)
ConvolucionalO(k⋅n⋅d2)O(k \cdot n \cdot d^2)O(1)O(1)O(log⁡kn)O(\log_k n)

Esta es la Tabla 1 del paper, y resume el argumento entero. La autoatención conecta cualquier par de posiciones en un solo paso y todas las posiciones se calculan en paralelo. El precio es la complejidad cuadrática en nn, que para las longitudes típicas de traducción (donde nn suele ser menor que la dimensión dd) resultaba más barata que la recurrencia.

Comprueba tu comprensión

Según la Tabla 1 del paper, ¿qué ventaja tiene la self-attention frente a una capa recurrente en cuanto a la longitud máxima de camino entre dos posiciones?

Qué viene

En las próximas lecciones vamos a construir el Transformer pieza por pieza: la atención de producto punto escalada, la atención multi-cabeza, las codificaciones posicionales (porque, como vas a ver, al quitar la recurrencia perdimos la noción de orden) y finalmente el bloque completo con su receta de entrenamiento.

¿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.