Transformers — Módulo 5: del Transformer al GPT — decoder-only y generación autoregresiva
Quinto módulo del Curso de Transformers: el Transformer original era encoder-decoder para traducir; GPT es decoder-only. Cómo el causal masking, los logits y la generación autoregresiva convierten esa arquitectura en una máquina de escribir texto token a token.
☰ Índice del contenido
En el Módulo 4 armamos el Transformer completo tal como lo publicó Google en 2017: dos mitades, un encoder que lee la frase de entrada y un decoder que escribe la salida. Esa forma nació para traducir (español entra, inglés sale). Pero los modelos que usas todos los días — GPT, Claude, Llama — no traducen de una lengua a otra: continúan texto. Y para eso sobra la mitad de la arquitectura. Este módulo explica cómo el Transformer se transforma en GPT quedándose con una sola mitad, y cómo esa mitad genera texto una palabra a la vez.
La tesis del módulo
GPT no es un Transformer distinto: es medio Transformer usado en bucle. Se queda solo con el decoder, le prohíbe mirar hacia el futuro (causal masking) y lo pone a hacer una sola cosa millones de veces: predecir el siguiente token, agregarlo, y volver a empezar. Toda la magia de “conversar” sale de ese bucle.
Recordar: qué hacía cada mitad
En el Transformer original, el encoder (codificador: la parte que comprime la entrada en representaciones ricas) leía la frase completa de golpe — podía mirar todas las palabras a la vez porque ya las tenía todas. El decoder (decodificador: la parte que produce la salida) escribía la traducción palabra por palabra, y en cada paso miraba dos cosas: lo que ya llevaba escrito, y la salida del encoder.
GPT tira el encoder a la basura. Se queda solo con el decoder, y le quita la parte que miraba al encoder (ya no hay encoder que mirar). Lo que queda es un modelo que solo mira su propio texto y predice cómo sigue. A eso se le llama decoder-only (solo-decodificador).
El truco central: causal masking
Aquí está el corazón del asunto. Si el modelo va a aprender a predecir la siguiente palabra, no puede tener permiso para verla mientras entrena. Sería como estudiar para una prueba con las respuestas pegadas al lado: aprendería a copiar, no a predecir.
El causal masking (glosar: la máscara causal, un filtro que le tapa al modelo los tokens que vienen después de la posición actual, para que solo pueda apoyarse en el pasado) resuelve esto dentro del mecanismo de atención que vimos en los módulos 2 y 3. Recuerda que la atención calcula, para cada token, cuánto le importa cada otro token. La máscara simplemente pone en menos infinito los puntajes hacia el futuro, de modo que tras el softmax esos pesos quedan en cero: el token de la posición 3 puede atender a los tokens 1, 2 y 3, pero jamás al 4, 5 o 6.
Quién puede mirar a quién (■ permitido, · tapado)
el gato se subió
el ■ · · ·
gato ■ ■ · ·
se ■ ■ ■ ·
subió ■ ■ ■ ■
Cada fila es un token preguntando “¿a quién puedo mirar?”. La diagonal y todo lo de la izquierda está permitido (el presente y el pasado); todo lo de la derecha, tapado (el futuro). Por eso también se le dice atención causal: la causa siempre está antes que el efecto.
Ojo: el causal masking solo importa en el entrenamiento y al procesar el prompt, donde el modelo ve muchos tokens a la vez y hay que impedir que “haga trampa”. Cuando ya está generando texto nuevo, el futuro literalmente no existe todavía — no hay nada que tapar.
De vectores a palabras: logits y softmax
El decoder procesa la secuencia y, al final, entrega para la última posición un vector de números crudos: uno por cada palabra posible del vocabulario. Esos números son los logits (glosar: los puntajes en bruto que el modelo asigna a cada token del vocabulario; todavía no son probabilidades, solo “qué tan a favor” está de cada opción).
Un vocabulario típico tiene ~50.000 tokens, así que hay ~50.000 logits. Para convertirlos en algo con lo que decidir, se pasan por softmax (la misma función del módulo 2), que los aplasta a una distribución de probabilidad: todos entre 0 y 1, sumando 1.
estado final del decoder (un vector)
│
▼
┌────────────────────────────┐
│ capa de salida │
│ (proyecta al vocabulario) │
└──────────────┬─────────────┘
▼
logits: 50.000 puntajes crudos
│
▼
softmax ──► probabilidades
│
▼
"casa" 0.41 "perro" 0.22 "sol" 0.08 ...
De esa lista de probabilidades sale el siguiente token. Cómo se elige exactamente (siempre el más probable, o con algo de azar controlado) es todo un tema con impacto enorme en la personalidad del modelo — lo dedicaremos entero al Módulo 9. Por ahora quédate con: logits crudos → softmax → probabilidades → un token.
El bucle autoregresivo
Ya tenemos las piezas. La generación autoregresiva (glosar: “auto” = sobre sí mismo; el modelo predice el siguiente token, lo pega al final de la secuencia y usa esa secuencia más larga como nueva entrada, repitiendo el proceso) es simplemente hacer esto en bucle:
START
│
▼
prompt: "El cielo es"
│
▼
┌──────────────────────────────┐
│ modelo decoder-only │◄─────────┐
└──────────────┬───────────────┘ │
▼ │
predice: "azul" │
│ │
▼ │
"El cielo es azul" ─── se reinyecta ─────┘
│
▼
¿token de fin? ── no ──► sigue el bucle
│ sí
▼
END
Fíjate en la flecha que vuelve: la salida de un paso es parte de la entrada del siguiente. El modelo no planea la frase completa de antemano; la va construyendo token a token, y en cada paso toda la frase acumulada vuelve a entrar. El bucle termina cuando el modelo emite un token especial de fin de secuencia (o cuando alcanzas el largo máximo que pediste).
Aquí tienes el bucle en código, lo más pelado posible con Hugging Face:
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
nombre = "gpt2" # el clásico decoder-only, chico y descargable
tok = AutoTokenizer.from_pretrained(nombre)
modelo = AutoModelForCausalLM.from_pretrained(nombre)
# 1. el prompt se convierte en tokens (ids del vocabulario)
ids = tok("El cielo es", return_tensors="pt").input_ids
# 2. el bucle autoregresivo, a mano, para verlo por dentro
for _ in range(10):
with torch.no_grad():
salida = modelo(ids)
# logits del ÚLTIMO token: puntajes sobre todo el vocabulario
logits_ultimo = salida.logits[0, -1, :]
probs = torch.softmax(logits_ultimo, dim=-1)
# elegimos el más probable (greedy); el módulo 9 verá alternativas
siguiente = torch.argmax(probs).unsqueeze(0).unsqueeze(0)
# 3. se reinyecta: la secuencia crece en un token
ids = torch.cat([ids, siguiente], dim=1)
print(tok.decode(ids[0]))
Ese torch.cat es, literalmente, la flecha que vuelve en el diagrama. En la práctica no escribirás este bucle: modelo.generate(...) lo hace por ti (y con optimizaciones como la KV cache del Módulo 10). Pero verlo a mano una vez vale por mil explicaciones.
Encoder-decoder vs decoder-only
| Encoder-decoder | Decoder-only (GPT) | |
|---|---|---|
| Ejemplo | T5, el Transformer original, BART | GPT, Claude, Llama, Mistral |
| Tarea natural | Transformar A en B (traducir, resumir) | Continuar / generar texto |
| Cómo mira la entrada | Encoder la ve completa y sin máscara | Todo pasa por atención causal |
| Partes | Dos pilas + atención cruzada | Una sola pila |
| Ventaja | Separa “entender” de “generar” | Simple, escala increíble, un solo objetivo |
| Reina hoy en | Traducción, tareas cerradas | Chat, asistentes, casi todo lo generativo |
La industria se volcó al decoder-only por una razón práctica: es una sola arquitectura, un solo objetivo de entrenamiento (predecir el siguiente token), y eso resultó escalar de forma extraordinaria. Menos piezas, más datos, más parámetros — y funciona mejor. Ese “más datos, más parámetros” es justo el tema del próximo módulo.
El linaje GPT: la misma idea, escalada
Algo que confunde a mucha gente: GPT-2, GPT-3 y GPT-4 no son arquitecturas nuevas cada una. Son, en esencia, el mismo decoder-only de este módulo, crecido:
| Modelo | Año aprox. | Idea clave | Parámetros (orden) |
|---|---|---|---|
| GPT-2 | 2019 | ”esto genera texto sorprendentemente bien” | ~1.500 M |
| GPT-3 | 2020 | escalar 100× revela habilidades nuevas | ~175.000 M |
| GPT-4 | 2023 | más escala + técnicas de entrenamiento | no publicado |
La lección de este linaje es incómoda y poderosa a la vez: buena parte del salto de calidad no vino de reinventar la arquitectura, sino de agrandarla y alimentarla con más texto. Por qué eso funciona tan bien tiene nombre —scaling laws— y lo veremos en el Módulo 6 y a fondo en el 12.
Errores comunes
- Creer que GPT “planea” la respuesta completa. No: genera token a token, y cada token se decide con la información acumulada hasta ese punto. La coherencia global emerge del bucle, no de un plan previo.
- Confundir logits con probabilidades. Los logits son crudos y pueden ser negativos o enormes; recién tras el softmax son probabilidades comparables.
- Pensar que el causal masking se aplica también al generar. Al generar texto nuevo no hay futuro que tapar; la máscara vive en el entrenamiento y en el procesamiento del prompt.
- Creer que GPT-3 y GPT-4 son inventos arquitectónicos distintos. Comparten la columna vertebral decoder-only; lo que cambia dramáticamente es la escala y el afinado.
La frase para llevarse
“GPT es medio Transformer que aprendió una sola regla — predecir la siguiente palabra sin espiar el futuro — y la repite hasta que la frase se termina sola.”
Qué viene
Módulo 6: pretraining. Cómo ese decoder-only pasa de estar vacío a “saber” gramática, hechos y algo de razonamiento, entrenándose sobre cantidades absurdas de texto con un solo objetivo. Y por qué el modelo que sale de ahí todavía no conversa: apenas completa texto.
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.