Phase 10 - Lesson 14

Modelos Abiertos: Análisis Detallado de Arquitectura

Construiste un GPT-2 Small desde cero en la Lección 04. Los modelos abiertos de frontera en 2026 pertenecen a la misma familia con cinco o seis cambios concretos. RMSNorm en lugar de LayerNorm. SwiGLU en lugar de GELU. RoPE en lugar de posiciones aprendidas. GQA o MLA en lugar de MHA completo. Mixture-of-Experts a escala. Las matemáticas que ya conoces cubren el 95% de ellos. Esta lección analiza Llama 3, DeepSeek-V3, Mixtral, Qwen y Gemma lado a lado e identifica la línea exacta donde cada arquitectura diverge.

Tipo: Aprender Lenguajes: Python (stdlib) Prerrequisitos: Fase 10, Lecciones 04, 05, 12 (Preentrenamiento, Escalado, Inferencia) Tiempo: ~45 minutos

Objetivos de Aprendizaje

  • Leer el config.json de Llama 3, Mistral, Mixtral, Gemma 2, Qwen 2.5 y DeepSeek-V3 y explicar cada campo
  • Identificar el cambio arquitectónico específico que cada modelo realizó en comparación con GPT-2 Small y justificarlo a partir de principios fundamentales
  • Calcular el número de parámetros, el tamaño del KV cache y la memoria de activación para cualquier modelo abierto a partir únicamente de su configuración
  • Elegir el modelo abierto adecuado para un objetivo de implementación dadas las restricciones de latencia, memoria y capacidad

El Problema

En la Lección 04, escribiste 350 líneas de numpy y obtuviste un modelo con la forma de GPT-2. Llama 3 405B tiene un reporte técnico de 200 páginas. Tu instinto te dice que son bestias diferentes. No lo son. Las 200 páginas describen el mismo objeto con cinco o seis modificaciones bien justificadas, además de miles de detalles de implementación sobre escalado. El esqueleto —incorporación (embedding), bloques de transformer, atención, MLP, normalización, cabeza (head)— permanece inalterado.

Esta lección es un diff. Para cada familia principal de modelos abiertos, listamos exactamente qué cambió respecto a GPT-2, por qué y a qué costo. Cuando termines, podrás leer una nueva ficha técnica (model card) y traducirla mentalmente de vuelta a la línea base de GPT-2.

La recompensa práctica es que cuando Meta lance Llama 5 o DeepSeek lance V4, no necesitarás un nuevo modelo mental. Mirarás la configuración, verás cuál de las perillas (knobs) conocidas se movió y sabrás cuáles son las implicaciones downstream. Las arquitecturas de 2026 son una caja de herramientas finita. Cada nuevo modelo elige un subconjunto diferente.

El Concepto

El Núcleo Invariante

Todos los modelos abiertos autorregresivos comparten:

  • Matriz de incorporación de tokens (vocab_size x hidden_dim).
  • Pila de N bloques decodificadores: normalización, autoatención, residual, normalización, MLP, residual.
  • Normalización final y cabeza linear que proyecta a vocab_size (a menudo con pesos compartidos con las incorporaciones).
  • Máscara causal, pérdida de entropía cruzada para el siguiente token.

Esa es la estructura. El resto son perillas (knobs).

Las Seis Perillas que Realmente se Mueven

En todos los modelos abiertos de frontera de 2024 a 2026, se eligen las mismas seis decisiones de diseño una y otra vez:

  1. Normalización. LayerNorm -> RMSNorm.
  2. Codificación posicional. Absoluta aprendida -> RoPE (más variantes: YaRN, NTK).
  3. Activación. GELU -> SwiGLU (o GeGLU).
  4. Compartición de cabezas de atención. MHA -> GQA -> MQA -> MLA.
  5. MLP denso vs. esparso. Denso -> Mixture-of-Experts.
  6. Ubicación de la pre-normalización. La pre-normalización (pre-norm) se queda. La post-normalización (post-norm) desaparece.

Todo lo demás (cronograma de tasa de aprendizaje, mezcla de datos, tamaño de lote, longitud del contexto) vive en la configuración de entrenamiento, no en la arquitectura. Seis perillas.

Knob 1: RMSNorm

LayerNorm resta la media, divide por la desviación estándar, escala y desplaza. RMSNorm conserva únicamente la escala:

RMSNorm(x) = x / sqrt(mean(x^2) + eps) * gamma

Sin resta de media. Sin sesgo (bias). Una multiplicación de matriz (matmul) menos por token. Zhang y Sennrich (2019) argumentaron que igualaba a LayerNorm en traducción automática siendo un 10% más rápida. Todos los modelos abiertos modernos la ejecutan.

Costo: ninguno. Beneficio: pequeña ganancia en el rendimiento de procesamiento (throughput), código más simple.

Knob 2: RoPE

Las incorporaciones de posición aprendidas eran una tabla de búsqueda de 1024 entradas en GPT-2. El contexto 1025 queda fuera de la tabla. Los modelos no pueden extrapolar más allá de su longitud de entrenamiento.

La Incorporación Posicional Rotatoria (RoPE, Su et al. 2021) inyecta la posición rotando cada vector Q y K en parejas antes del producto escalar de la atención. El ángulo de rotación es una función determinística de la posición, por lo que no hay nada aprendido ni nada que se agote. Con trucos de escalado (interpolación sensible a NTK, YaRN), un modelo entrenado con un contexto de 8k puede extenderse a 128k en la inferencia con una pérdida modesta de precisión.

q_rotated = rotate(q, angle(pos))
k_rotated = rotate(k, angle(pos))
score = q_rotated . k_rotated

Todos los modelos Llama, Mistral, Qwen, DeepSeek y Gemma utilizan RoPE. Gemma 2 usa un híbrido (RoPE en la mayoría de las capas, atención local de ventana deslizante en otras).

Knob 3: SwiGLU

El MLP de GPT-2 es x -> gelu(xW1 + b1) -> (...)W2 + b2. SwiGLU (Shazeer 2020) reemplaza la activación con un producto controlado (gated product):

SwiGLU(x) = (xW1) * sigmoid(xW1) * xV

Dos proyecciones en paralelo en lugar de una, controladas por la activación Swish. Empíricamente más robusto en perplejidad por parámetro. Llama 2 lo adoptó y todos lo siguieron. El tamaño oculto (hidden size) del MLP generalmente se establece de modo que el número total de parámetros coincida con el MLP denso original: si GPT-2 usaba ff_dim = 4 * hidden, SwiGLU usa ff_dim = (2/3) * 4 * hidden = 8/3 * hidden.

Knob 4: Compartición de Cabezas de Atención

GPT-2 utilizaba Multi-Head Attention (MHA): cada cabeza tiene su propia proyección Q, K, V.

Multi-Query Attention (MQA, Shazeer 2019) comparte una clave (K) y un valor (V) entre todas las cabezas. Reduce el KV cache según el número de cabezas (num_heads), lo que representa una reducción de 12x a 32x en un modelo típico. La precisión cae ligeramente en evaluaciones complejas.

Grouped-Query Attention (GQA, Ainslie et al. 2023) es el término medio: G grupos de cabezas Q comparten una clave (K) y un valor (V). Llama 3 8B utiliza GQA con 32 cabezas Q y 8 cabezas KV (G=8), por lo que el KV cache se reduce 4x en comparación con MHA completo.

Multi-Head Latent Attention (MLA, DeepSeek 2024) comprime K y V en una representación latente compartida de bajo rango (low-rank), proyectándolos de vuelta por cabeza. Reduce aún más el KV cache al tiempo que preserva la expresividad de cada cabeza. DeepSeek-V2 y V3 dependen de esto para su rendimiento en contextos largos.

Esquema Cabezas KV KV Cache Precisión
MHA num_heads completo mejor
GQA num_groups (G < num_heads) reducción de num_heads / G cercano a MHA
MQA 1 reducción de num_heads pequeño impacto
MLA descompresión latente por cabeza menor que MQA cercano a MHA

Para cualquier modelo superior a ~13B de parámetros, GQA o MLA es prácticamente obligatorio. MHA completo a gran escala es un desastre para el KV cache.

Knob 5: Mixture of Experts

Un MLP denso activa todos sus parámetros para cada token. Un MLP MoE tiene K expertos por bloque y un enrutador que elige los mejores $k$ expertos por token (típicamente top-2). Solo los pesos de esos expertos pasan por una etapa de propagación hacia adelante (forward pass) para ese token.

router_logits = xW_r
indices, weights = top_k(router_logits, k=2)
output = sum_i weights[i] * expert[indices[i]](x)

El atractivo: puedes tener 64 expertos de tamaño 7B cada uno (por lo que el número total de parámetros es enorme) mientras ejecutas solo 2 de ellos por token (por lo que el cómputo por token corresponde a un modelo denso de 7B). Mixtral 8x7B tiene 47B parámetros en total, pero activa solo 13B por token. DeepSeek-V3 tiene 671B parámetros en total, pero activa solo 37B por token.

graph LR
    I["Token hidden state"] --> R["Router\n(linear -> softmax)"]
    R --> T["Top-k selection"]
    T --> E1["Expert 1\n(MLP)"]
    T --> E2["Expert 2\n(MLP)"]
    T --> EN["Expert 64\n(MLP, unused)"]
    E1 --> S["Weighted sum"]
    E2 --> S
    S --> O["Output"]

    style EN fill:#eeeeee,stroke:#999,color:#999
    style E1 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style E2 fill:#1a1a2e,stroke:#51cf66,color:#fff
    style R fill:#1a1a2e,stroke:#e94560,color:#fff

Pros: mismo cómputo, más parámetros, mejor capacidad. Contras: la memoria de los expertos aún debe vivir en algún lugar (por lo que el servicio necesita más VRAM que un equivalente denso), equilibrar la carga del enrutador es difícil y ajustar el enrutador durante el alineamiento es su propia área de investigación.

Knob 6: La Pre-normalización Permanece

El transformer original aplicaba la normalización de capa después de cada subcapa. Cada modelo abierto desde GPT-2 la coloca antes de cada subcapa. La pre-normalización es estrictamente más fácil de trenar en profundidad. No hay debate aquí.

Diff Modelo a Modelo

Aquí está la tabla que hace tangible todo esto.

Modelo Año Parámetros Totales Parámetros Activos Norm Activación Posición Atención MoE Contexto
GPT-2 Small 2019 124M 124M LayerNorm GELU Aprendida MHA (12 cabezas) no 1k
Llama 3 8B 2024 8B 8B RMSNorm SwiGLU RoPE GQA (32/8) no 128k
Llama 3 70B 2024 70B 70B RMSNorm SwiGLU RoPE GQA (64/8) no 128k
Llama 3 405B 2024 405B 405B RMSNorm SwiGLU RoPE GQA (128/16) no 128k
Mistral 7B 2023 7.2B 7.2B RMSNorm SwiGLU RoPE GQA no 32k
Mixtral 8x7B 2023 47B 13B RMSNorm SwiGLU RoPE GQA sí (8 exp., top-2) 32k
Gemma 2 9B 2024 9B 9B RMSNorm (pre+post) GeGLU RoPE + deslizante GQA no 8k
Qwen 2.5 72B 2024 72B 72B RMSNorm SwiGLU RoPE (YaRN) GQA (64/8) no 128k
DeepSeek V2 236B 2024 236B 21B RMSNorm SwiGLU RoPE MLA sí (160 exp., top-6) 128k
DeepSeek V3 2024 671B 37B RMSNorm SwiGLU RoPE MLA sí (256 exp., top-8) 128k

Revisa las columnas. RMSNorm es universal. SwiGLU o su equivalente GeGLU es universal. RoPE es universal. GQA es universal por encima de 7B, excepto cuando se reemplaza por MLA. MoE es el diferenciador en el extremo superior.

Leyendo un config.json

Configuración de Llama 3 8B:

{
  "hidden_size": 4096,
  "intermediate_size": 14336,
  "num_hidden_layers": 32,
  "num_attention_heads": 32,
  "num_key_value_heads": 8,
  "max_position_embeddings": 131072,
  "rope_theta": 500000.0,
  "rms_norm_eps": 1e-5,
  "vocab_size": 128256
}

Cada campo corresponde a algo que ya has implementado.

  • hidden_size: dimensión de incorporación (embedding).
  • intermediate_size: tamaño oculto del MLP (3.5x el tamaño oculto — matemática de SwiGLU).
  • num_hidden_layers: profundidad de la pila.
  • num_attention_heads: cabezas Q.
  • num_key_value_heads: cabezas KV (GQA).
  • max_position_embeddings: longitud del contexto de entrenamiento.
  • rope_theta: frecuencia base de RoPE. Meta lo escaló del estándar de 10k a 500k para extrapolación de contexto largo.
  • rms_norm_eps: estabilidad numérica.
  • vocab_size: tokens.

A partir de esto únicamente puedes calcular los parámetros totales, el KV cache y el pico de memoria de activación. Consulta code/main.py para ver las fórmulas exactas.

Presupuesto de memoria de activación

Las activaciones dominan la memoria de entrenamiento por encima de unos pocos miles de millones de parámetros. La regla general para el preentrenamiento (con checkpointing de gradientes):

activation_mem ~ batch_size * seq_len * hidden_size * num_layers * bytes_per_element

Para Llama 3 8B con lote (batch) 1, secuencia 8192, BF16, 32 capas, hidden 4096: aproximadamente 8 GB solo para activaciones con checkpointing, 40 GB sin él. Es por esto que flash-attention y ring-attention importan: reescriben el cálculo de atención para que las activaciones quepan.

Presupuesto del KV Cache

Para inferencia en el contexto máximo:

kv_cache = 2 * num_layers * num_kv_heads * head_dim * max_seq_len * bytes_per_element

Llama 3 8B con contexto de 128k, BF16, head_dim = hidden / num_heads = 128: 2 * 32 * 8 * 128 * 131072 * 2 = 17.2 GB por secuencia.

Los pesos de 8B son 16 GB en BF16. El KV cache para una sola secuencia de 128k es mayor que los pesos. Esta es la presión de memoria que impulsa la investigación en GQA, MLA y cuantización del KV cache.

Cuándo Gana Cada Modelo

  • Una sola GPU de 80GB, sin MoE: Llama 3 8B, Mistral 7B, Gemma 2 9B. Fácil de servir, amplia compatibilidad de herramientas.
  • Nodo único (8x80GB), gran capacidad: Llama 3 70B, Qwen 2.5 72B. Mayor capacidad densa de código abierto.
  • Mayor capacidad abierta, aceptando la complejidad de MoE: DeepSeek V3, Mixtral 8x22B. Mejor capacidad por FLOP activo.
  • Necesidades de contexto largo: Llama 3 (128k con escalado RoPE), DeepSeek (ventaja de MLA).
  • Servicio de baja latencia: Gemma 2 9B (la ventana deslizante reduce el cómputo en contexto largo).

Constrúyelo

El código de la lección es una calculadora. Dada cualquier configuración config.json, imprime el número de parámetros por componente, el KV cache en el contexto máximo, la relación SwiGLU MLP y un veredicto corto sobre la arquitectura (denso / GQA / MLA / MoE).

config = {
    "hidden_size": 4096, "intermediate_size": 14336,
    "num_hidden_layers": 32, "num_attention_heads": 32,
    "num_key_value_heads": 8, "vocab_size": 128256,
    "max_position_embeddings": 131072,
}

El script recorre la arquitectura campo por campo, calcula el número de parámetros para incorporación, atención (con reducción GQA), MLP (con expansión SwiGLU), layernorms y la cabeza. Luego calcula el KV cache en la longitud de contexto indicada e imprime un resumen.

Consulta code/main.py para ver la implementación.

Úsalo

Ejecuta la calculadora en las configuraciones de Llama 3 8B, Mistral 7B, Mixtral 8x7B y DeepSeek V3 incluidas en el script. Compara los desgloces de parámetros. Observa que los modelos MoE tienen un número total de parámetros que eclipsa a los modelos densos, pero un número de parámetros activos que a menudo es menor. Observa que el KV cache de DeepSeek V3 es menor que el de Llama 3 405B a pesar de tener más parámetros totales — eso es MLA en acción.

Luego, conecta una configuración para cualquier modelo que tengas localmente, lee el resumen y decide si cabe en tu GPU.

Envíalo

Esta lección produce outputs/skill-open-model-picker.md. Dado un objetivo de implementación (tipo de GPU, VRAM, longitud de contexto, presupuesto de latencia) y un perfil de tarea (chat, código, razonamiento, contexto largo), recomienda un modelo abierto, un esquema de cuantización de la Lección 11 y una pila de inferencia de la Lección 12, con un razonamiento explícito sobre las seis perillas arquitectónicas.

Ejercicios

  1. Lee la configuración de Qwen 2.5 72B en HuggingFace. Calcula los parámetros totales desde cero. Compáralo con el valor reportado por HF e identifica de dónde proviene cualquier diferencia (arredondamiento de la dimensión de la cabeza, factor de compartición de KV, etc.).

  2. DeepSeek V3 utiliza 256 expertos con enrutamiento top-8. Calcula la proporción de expertos activados respecto al total de expertos y compárala con el top-2 de 8 de Mixtral 8x7B. ¿Qué implica el cambio de esparso (25%) a esparso más denso (3%) sobre la capacidad por FLOP?

  3. Calcula el KV cache para Llama 3 405B con un contexto de 128k en FP8 y BF16. En FP8 es la mitad del número en BF16. ¿Cuántas secuencias paralelas puedes servir en un solo nodo 8xH100 (80GB cada uno = 640GB en total, menos la memoria de los pesos)?

  4. Gemma 2 alterna capas de atención completa y atención de ventana deslizante. Escribe la matemática para el KV cache cuando la mitad de las capas usan una ventana deslizante de 4096 tokens en lugar del contexto completo. ¿Cuánta memoria ahorra eso en un contexto total de 8k?

  5. Encuentra un modelo abierto de frontera reciente que haya sido lanzado después de escribir esta lección. Identifica cuál de las seis perillas eligió y si introdujo una séptima perilla. El plan de estudios se sentirá desactualizado en el momento en que se lance una nueva arquitectura — el objetivo es actualizar tu tabla sin reconstruir tu modelo mental.

Términos Clave

Término Lo que la gente dice Lo que realmente significa
RMSNorm "LayerNorm sin la media" Normaliza solo por la raíz de la media cuadrática (root mean square), con una escala aprendida — más barato y comparable a LayerNorm
RoPE "Posiciones rotativas" Rota cada vector Q y K en parejas 2D por un ángulo que depende de la posición — extrapola más allá de la longitud de entrenamiento con trucos de escalado
SwiGLU "La nueva activación de MLP" Unidad lineal controlada (gated linear unit) con Swish: (xW1) * sigmoid(xW1) * xV — estándar en todos los modelos abiertos de 2024+
GQA "Atención de término medio" Grouped-Query Attention: G grupos de cabezas Q comparten una cabeza K y una cabeza V — reduce el KV cache sin la pérdida de precisión de MQA
MLA "Atención de DeepSeek" Multi-Head Latent Attention: comprime K/V en una representación latente de bajo rango compartida, descomprimiendo por cabeza — el KV cache más pequeño para modelos grandes
MoE "Expertos esparsos" Mixture of Experts: N MLPs por bloque, el enrutador elige los top-k por token — enormes parámetros totales, pequeños parámetros activos
Enrutamiento top-k "Elige k expertos por token" El enrutador calcula una puntuación por experto y activa los k más altos — el k típico es de 2 (Mixtral) a 8 (DeepSeek)
YaRN "Estirar RoPE" Yet another RoPE extension — interpola ángulos rotatorios para extend el contexto de 8k a más de 128k en tiempo de inferencia
Atención de ventana deslizante "No atiendas a todo" Cada token atiende solo a los últimos W tokens — limita el costo de atención a O(W) por token, usado en Gemma 2 y los primeros Mistral
Parâmetros activos "Lo que se ejecuta por token" Para los modelos MoE, el número de parámetros que experimentan un paso hacia adelante por token (mucho menor que los parámetros totales) — gobierna los FLOPs por token

Lecturas Recomendadas

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).