Lección 12

Arquitectura GPT completa

Llegamos a la cima. Todas las piezas que construimos lección a lección — tokenización, embeddings, atención, backprop — se ensamblan aquí en un GPT de 3.808 parámetros que genera nombres reales.

1. La vista completa de arriba hacia abajo

Un GPT es una función: entra una secuencia de tokens, salen probabilidades para el siguiente token. Todo lo que hace internamente es transformar ese vector de tokens en probabilidades, capa por capa.

Arquitectura · microgpt de extremo a extremo
Arquitectura completa de microgpt Flujo de datos de arriba a abajo: tokens de entrada → embeddings → bloque de atención → MLP → lm_head → probabilidades. Tokens de entrada [ 26, 10, 0, 17 ] → "[BOS] k a r" 4 tokens Embeddings wte (27×16) = 432 p + wpe (16×16) = 256 p → 4 × 16 dims matriz [4×16] Bloque de atención + MLP (×1) RMSNorm (16×1 = 16 p) Multi-head Attention (4 cabezas) 4 × (3×16×4) + 16×16 = 768+256 = 1024 p x = x + attn(x) RMSNorm (16×1 = 16 p) MLP: Linear(16→64) → ReLU → Linear(64→16) 16×64 + 64×16 = 2048 p x = x + mlp(x) matriz [4×16] lm_head: Linear(16→27) 16×27 = 432 p Nota: peso compartido con wte (weight tying) Softmax → probabilidades 27 valores Total (con weight tying): 3.808 parámetros

El GPT de microgpt tiene un solo bloque de atención. Los GPTs grandes (GPT-2, GPT-4) tienen docenas, pero la arquitectura es idéntica: más bloques apilados, más parámetros por bloque.

2. Contando los parámetros

microgpt tiene 3.808 parámetros con weight tying (ó 4.240 sin él). Contemos pieza por pieza. Un "parámetro" es cualquier número que el entrenamiento puede ajustar (pesos y biases).

✍️ Cuenta completa de parámetros en microgpt
Configuración del modelo:
  vocab_size  = 27   (letras a-z + [BOS])
  n_embd      = 16   (tamaño del embedding)
  block_size  = 16   (longitud máxima de secuencia)
  n_head      = 4    (cabezas de atención)
  n_layer     = 1    (número de bloques)
  mlp_hidden  = 64   (neuronas ocultas del MLP)

─────────────────────────────────────────────────
1. wte: tabla de token embeddings
   27 tokens × 16 dimensiones = 432 parámetros

2. wpe: tabla de position embeddings
   16 posiciones × 16 dimensiones = 256 parámetros

3. Bloque de atención (×1):
   a) RMSNorm antes de la atención:
      1 vector de scale, 16 valores = 16 parámetros

   b) Atención multi-cabeza (4 cabezas, cada una con d=4):
      W_q, W_k, W_v para cada cabeza: 16×4 × 3 cabezas × 4 = 768 p
      W_o (proyección de salida): 16×16 = 256 parámetros
      Subtotal atención: 1024 parámetros

   c) RMSNorm antes del MLP:
      16 parámetros

   d) MLP:
      Linear(16→64): 16×64 pesos = 1024 parámetros
      Linear(64→16): 64×16 pesos = 1024 parámetros
      Subtotal MLP: 2048 parámetros

4. RMSNorm final: 16 parámetros

5. lm_head: Linear(16→27) = 432 p
   ⚠️ Pero microgpt comparte estos pesos con wte.
   En PyTorch: lm_head.weight = wte.weight (pointer sharing)
   Así que NO se cuentan dos veces.

─────────────────────────────────────────────────
TOTAL con weight tying (lm_head comparte pesos con wte):
  432 + 256 + 16 + 1024 + 16 + 2048 + 16 = 3.808 parámetros
  (lm_head.weight = wte.weight → no suma parámetros nuevos)

TOTAL sin weight tying (si lm_head tuviera sus propios pesos):
  3.808 + 432 = 4.240 parámetros

→ microgpt activa el weight tying, por lo que el modelo real
  tiene 3.808 parámetros.

Para comparar:
  GPT-2 pequeño:  ~117 millones de parámetros
  GPT-4 (estimado): ~1 billón de parámetros
  microgpt:           3.808 parámetros ← ¡lo tenemos en perspectiva!
      

3. El forward pass paso a paso

Sigamos el recorrido de la secuencia "[BOS] k a r" a través de la red. En cada paso, el tensor cambia de forma o de contenido, pero siempre avanza hacia la predicción del siguiente token.

PasoOperaciónForma del tensorContenido
0 Entrada [4] Índices de tokens: [26, 10, 0, 17]
1 Token embedding (wte) [4, 16] 4 vectores de 16 dims (uno por token)
2 + Position embedding (wpe) [4, 16] Suma elemento a elemento, posiciones 0-3
3 RMSNorm [4, 16] Misma forma, valores normalizados (media≈0, rms≈1)
4 Multi-head Attention [4, 16] Cada token ve los anteriores, actualiza su vector
5 Conexión residual [4, 16] x = x_antes + x_attn
6 RMSNorm [4, 16] Normalizar antes del MLP
7 MLP (16→64→16) [4, 16] No linealidad: ReLU en la capa oculta de 64
8 Conexión residual [4, 16] x = x_antes + x_mlp
9 RMSNorm final [4, 16] Normalización final
10 lm_head (16→27) [4, 27] Logits: puntuación cruda para cada token del vocabulario
11 Softmax (última fila) [27] Probabilidades para el token siguiente a "r"
El secreto de la última fila: El lm_head produce una matriz [4, 27] — una fila por cada posición. Para predecir qué sigue después del token en posición 3 ("r"), solo nos importa la fila 3 (índice 3). Las otras filas se usan durante el entrenamiento como señales adicionales de aprendizaje, pero en inferencia solo se muestrea la última.

🎮 Pruébalo: forward pass interactivo

Introduce el inicio de un nombre y observa cómo la red transforma los tokens en probabilidades en tiempo real:

4. Lo que aprendiste

En esta lección:
  • El GPT es un pipeline: tokens → embeddings → [bloques de atención+MLP] → lm_head → probabilidades.
  • Microgpt tiene 3.808 parámetros (con weight tying) en un solo bloque. GPT-2 tiene 117 millones con la misma arquitectura pero 12 bloques y embeddings de 768 dims.
  • El truco del "weight tying": lm_head comparte sus pesos con wte. Tiene sentido porque ambos trabajan en el mismo espacio de vocabulario.
  • La forma del tensor nunca cambia después de los embeddings: siempre es [longitud_secuencia × n_embd] hasta el lm_head.