Hace doce días, el 12 de junio, apareció en los servidores de arXiv un artículo con un título inusualmente desafiante: "Attention Is All You Need", firmado por ocho investigadores de Google Brain y Google Research (Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Łukasz Kaiser e Illia Polosukhin). Lo imprimí al día siguiente en el trabajo y llevo dos semanas destripando sus ecuaciones entre café y café.

Para quien siga de cerca el procesamiento de lenguaje natural (NLP), la propuesta resulta chocante. A finales del año pasado, Google acaparó portadas al migrar Google Translate a GNMT (Google Neural Machine Translation), una bestia de ingeniería compuesta por ocho capas de redes LSTM en el codificador y otras ocho en el decodificador, cargada de conexiones residuales y mecanismos de atención aditiva. Hace apenas unas semanas, en mayo, Facebook AI Research presentó ConvS2S, intentando sustituir la recurrencia por capas convolucionales para ganar velocidad en GPUs.

Y justo cuando el sector debatía si el futuro pertenecía a las LSTM profundas o a las convoluciones temporales, llega este equipo de Google y propone algo radical: prescindir por completo de la recurrencia y de las convoluciones. Bautizan a su arquitectura como Transformer, y sostienen que el mecanismo de atención no es un simple complemento para recordar secuencias, sino el único motor necesario para procesar lenguaje.

La servidumbre del cálculo secuencial

El dominio de las redes recurrentes (RNN, GRU y LSTM) se sostenía sobre una premisa intuitiva: el lenguaje es intrínsecamente temporal. Leemos y escuchamos palabra tras palabra, de izquierda a derecha. Por tanto, los modelos calculaban su estado oculto $h_t$ encadenando cada token con la memoria del paso anterior:

$$ h_t = f(h_{t-1}, x_t) $$

Esa dependencia temporal arrastra dos problemas graves cuando nos enfrentamos al hardware real:

  1. Incompatibilidad con el paralelismo de las GPUs: Para procesar la palabra número cincuenta de una frase, la tarjeta gráfica debe esperar a que se hayan calculado en serie las cuarenta y nueve anteriores. Las GPUs modernas, diseñadas para devorar álgebra lineal y miles de operaciones matriciales simultáneas, pasan gran parte del tiempo ociosas esperando ciclos de reloj secuenciales.
  2. Dilución de la señal a larga distancia: Para que la información del primer token llegue al último, la señal debe sobrevivir a decenas de multiplicaciones matriciales y activaciones no lineales intermedias. Incluso con las compuertas de memoria de las LSTM, el vector de estado oculto sufre para retener dependencias sintácticas distantes.

El Transformer rompe esta baraja de un solo golpe: inyecta la secuencia completa a la vez en la red. En lugar de procesar palabra a palabra en un bucle temporal forzado, calcula las dependencias de todas las palabras contra todas las demás simultáneamente. La distancia de paso entre cualquier par de tokens dentro de una capa pasa de ser $O(n)$ a ser exactamente $O(1)$.

La mecánica de la Autoatención (Self-Attention)

El corazón matemático del Transformer es el cálculo de Autoatención por Producto Escalar Escalado (Scaled Dot-Product Attention).

La idea parte de una metáfora clásica de recuperación de información. Cada palabra de la frase proyecta tres vectores distintos mediante matrices aprendidas durante el entrenamiento: una Consulta (Query $Q$), una Clave (Key $K$) y un Valor (Value $V$).

Imaginemos que procesamos la frase:

"El banco del parque está roto."

Para determinar el significado contextual de la palabra "banco", su vector de consulta $Q$ realiza un producto escalar con las claves $K$ de todas las palabras de la oración. Cuanto mayor sea la afinidad vectorial entre dos conceptos en ese contexto, mayor será el resultado.

La fórmula fundamental del paper es:

$$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $$

El detalle del divisor $\sqrt{d_k}$ responde a una necesidad puramente numérica: cuando la dimensión de los vectores ($d_k$) es grande, los productos escalares crecen en magnitud, empujando la función softmax hacia zonas con gradientes extremadamente pequeños donde el aprendizaje se estanca. Dividir por la raíz cuadrada estabiliza el entrenamiento.

import numpy as np

def scaled_dot_product_attention(Q, K, V, mask=None):
    """Implementación conceptual de la atención escalada (Vaswani et al., 2017)."""
    d_k = Q.shape[-1]

    # 1. Producto matricial entre Consultas (Q) y Claves (K) transpuestas
    scores = np.matmul(Q, K.swapaxes(-1, -2)) / np.sqrt(d_k)

    # 2. Máscara opcional para el decodificador (evita mirar palabras futuras)
    if mask is not None:
        scores = np.where(mask == 0, -1e9, scores)

    # 3. Softmax sobre la última dimensión para normalizar afinidades entre 0 y 1
    exp_scores = np.exp(scores - np.max(scores, axis=-1, keepdims=True))
    attention_weights = exp_scores / np.sum(exp_scores, axis=-1, keepdims=True)

    # 4. Multiplicación ponderada por los Valores (V)
    context_vectors = np.matmul(attention_weights, V)
    return context_vectors, attention_weights

Atención multicabezal: múltiples perspectivas simultáneas

En lugar de calcular una única atención con vectores de 512 dimensiones, los autores proponen dividir el espacio en $h = 8$ cabezales independientes de dimensión $d_k = d_v = 64$.

Esto permite que la red preste atención a distintos tipos de relaciones sintácticas y semánticas a la vez. Mientras un cabezal puede especializarse en enlazar pronombres con sus sujetos distantes, otro puede captar concordancias de género y número o dependencias preposicionales. Al terminar, las ocho salidas se concatenan y se proyectan de vuelta a la dimensión principal mediante otra matriz de pesos.

El problema del orden: Encodings Posicionales

Al descartar por completo las redes recurrentes y las convoluciones, surge un problema inmediato: las multiplicaciones de matrices no entienden de orden temporal. Para una capa de atención pura, "el perro mordió al gato" y "el gato mordió al perro" contienen exactamente las mismas palabras y generarían los mismos cálculos. La red es insensible al orden secuencial.

Para solucionar esto sin recurrir a bucles paso a paso, los autores introducen Codificaciones Posicionales (Positional Encodings) que se suman directamente a los vectores de entrada (embeddings). En lugar de aprender vectores estáticos, utilizan funciones trigonométricas sinusoidales de diferentes frecuencias:

$$ PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$ $$ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$

Cada dimensión de la posición corresponde a una longitud de onda diferente, similar a un reloj digital binario pero continuo. Esta fórmula permite al modelo atender fácilmente a posiciones relativas, ya que para cualquier desplazamiento fijo $k$, la codificación de $pos + k$ puede representarse como una transformación lineal de la codificación de $pos$.

Rendimiento en traducción y coste en silicio

Los resultados presentados en el benchmark WMT 2014 son contundentes: - En la tarea de inglés a alemán, el modelo Transformer grande alcanza un índice BLEU de 28.4, superando por más de 2.0 puntos al mejor sistema existente hasta la fecha (incluyendo combinaciones de múltiples modelos). - En la tarea de inglés a francés, alcanza 41.0 BLEU, marcando una nueva marca absoluta en la literatura.

Pero lo verdaderamente impactante para quienes gestionamos recursos de cálculo no es solo el incremento del BLEU, sino el tiempo de entrenamiento. Mientras el modelo GNMT de Google requirió semanas en clústeres masivos de aceleradoras, el Transformer base se entrenó en apenas 12 horas sobre 8 GPUs NVIDIA Tesla P100. El modelo más grande completó su ciclo en 3.5 días.

Al eliminar el obstáculo secuencial, las GPUs pueden saturar sus núcleos de cálculo matricial con bloques enteros de oraciones en paralelo. Google ha liberado además el código bajo la librería tensor2tensor en GitHub, lo que permitirá a cualquier equipo reproducir la arquitectura sin depender de implementaciones cerradas.

Hacia dónde apunta este cambio

Este paper está pensado estrictamente para traducción automática entre pares de idiomas mediante una estructura de seis capas en el codificador y seis en el decodificador. Sin embargo, las implicaciones conceptuales van mucho más allá de traducir textos.

Si la representación profunda del lenguaje puede resolverse con pura multiplicación de matrices algebraicas y capas de normalización, el cuello de botella que frenaba el aprendizaje automático en texto acaba de romperse. Quien disponga de grandes colecciones de documentos y capacidad para costear clústeres de GPUs podrá entrenar modelos con una cantidad de parámetros impensable hace solo un par de años con LSTMs.

Prescindir del tiempo como eje rector de la computación lingüística parecía una herejía; tras leer este paper, todo apunta a que la recurrencia tiene los días contados.