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.
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.
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.
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).
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!
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.
| Paso | Operación | Forma del tensor | Contenido |
|---|---|---|---|
| 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" |
Introduce el inicio de un nombre y observa cómo la red transforma los tokens en probabilidades en tiempo real: