TAI BUI
Back to curriculum
LearnPython

Open Models: Architecture Walkthroughs

You built a GPT-2 Small from scratch in Lesson 04. Frontier open models in 2026 are the same family with five or six concrete changes: RMSNorm instead of LayerNorm, SwiGLU instead of GELU, RoPE instead of learned positions, GQA or MLA instead of full MHA, and Mixture-of-Experts at scale. The math you already know covers most of what's in them. This lesson reads Llama 3, DeepSeek-V3, Mixtral, Qwen, and Gemma side by side and points to where each one diverges.

TIME: ~45 minutesPREREQUISITES: Phase 10, Lessons 04, 05, 12 (Pre-training, Scaling, Inference)

Learning Objectives

  • Read the config.json of Llama 3, Mistral, Mixtral, Gemma 2, Qwen 2.5, and DeepSeek-V3 and explain every field
  • Name the specific architectural change each model made versus GPT-2 Small and justify it from first principles
  • Compute parameter count, KV cache size, and activation memory for any open model from its config alone
  • Pick the right open model for a deployment target given latency, memory, and capability constraints

The Problem

In Lesson 04 you wrote 350 lines of numpy and had a GPT-2-shaped model. Llama 3 405B has a 200-page technical report, and it's tempting to think the two are different beasts. They aren't. The report describes the same object with five or six well-motivated modifications, plus a thousand implementation details about scaling. The skeleton (embedding, transformer blocks, attention, MLP, norm, head) is unchanged.

This lesson is a diff. For each major open model family I list what changed from GPT-2, why, and what it cost. By the end you can read a fresh model card and translate it back to the GPT-2 baseline in your head.

The payoff comes when Meta releases Llama 5 or DeepSeek releases V4. You won't need a new mental model. You look at the config, see which of the well-known knobs moved, and work out what that means downstream. The 2026 architectures are a finite toolbox, and each new model picks a different subset.

Warm-up0/3
1. During autoregressive decoding, what does the KV cache store?Warm-up
Five earlier token boxes, tok 1 through tok 5, with an arrow from a new tok 6 box back toward them. Below, a dashed box marks a store kept at every layer, labelled with a question mark. A question asks what this store holds so attention does not redo work for the earlier tokens.
Setup only, from the stem; what the store holds is the question.
2. In a decoder-only transformer trained for next-token prediction, what does the causal mask do?Warm-up
Five position boxes, pos 1 through pos 5, trained for next-token prediction, with pos 3 highlighted. Dashed lines connect pos 3 to every other position, each marked with a question mark. A question asks what rule decides which of the other positions pos 3 may read.
The five positions are the setup; the rule that decides visibility is the question.
3. A model has 8 billion parameters stored in BF16 (2 bytes each). Roughly how much memory do the weights alone need?Warm-up
A multiplication laid out left to right: 8 billion parameters, times a blank bytes-per-parameter box for BF16 storage, equals a blank total box. A question asks roughly how much memory the weights alone need.
The parameter count and the storage format are the stem's own numbers; the byte size and total are the question.

The Concept

The Invariant Core

The autoregressive open models in this lesson share:

  • Token embedding matrix (vocab_size x hidden_dim).
  • Stack of N decoder blocks: norm, self-attention, residual, norm, MLP, residual.
  • Final norm and linear head projecting to vocab_size (often weight-tied with embeddings).
  • Causal mask, next-token cross-entropy loss.

That is the shape. The rest is knobs.

The Six Knobs That Actually Move

Across the 2024-2026 frontier open models, the same six design choices get picked again and again:

  1. Normalization. LayerNorm -> RMSNorm.
  2. Positional encoding. Learned absolute -> RoPE (plus variants: YaRN, NTK).
  3. Activation. GELU -> SwiGLU (or GeGLU).
  4. Attention head sharing. MHA -> GQA -> MQA -> MLA.
  5. Dense vs sparse MLP. Dense -> Mixture-of-Experts.
  6. Pre-norm placement. Pre-norm stays. Post-norm is gone.

Everything else (learning rate schedule, data mix, batch size, context length) lives in the training config, not the architecture. That leaves six knobs.

Knob 1: RMSNorm

LayerNorm subtracts mean, divides by std, scales, and shifts. RMSNorm keeps only the scale:

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

No mean subtraction. No bias. One matmul fewer per token. Zhang and Sennrich (2019) argued it matched LayerNorm on machine translation while being 10% faster. The open models in the table below run it.

The cost is nothing I know of. You get a small throughput win and simpler code.

Knob 2: RoPE

Learned position embeddings were a 1024-slot lookup table in GPT-2. Context 1025 is off the end of the table, so a model with learned positions has no way to extrapolate past its training length.

Rotary Position Embedding (RoPE, Su et al. 2021) injects position by rotating each Q and K vector in pairs before the attention dot product. The angle of rotation is a deterministic function of position, so there is nothing learned and nothing to run out of. With scaling tricks (NTK-aware interpolation, YaRN), a model trained on 8k context can stretch to 128k at inference with modest accuracy loss.

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

The Llama, Mistral, Qwen, DeepSeek, and Gemma models in the table all use RoPE. Gemma 2 uses a hybrid (RoPE on most layers, local sliding-window attention on others).

Knob 3: SwiGLU

GPT-2's MLP is x -> gelu(xW1 + b1) -> (...)W2 + b2. SwiGLU (Shazeer 2020) replaces the activation with a gated product:

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

Two projections in parallel instead of one, gated by the Swish activation. In practice it gives lower perplexity per parameter. Llama 2 adopted it and the other families followed. The MLP's hidden size is usually set so that total parameter count matches the original dense MLP: if GPT-2 used ff_dim = 4 * hidden, SwiGLU uses ff_dim = (2/3) * 4 * hidden = 8/3 * hidden.

Knob 4: Attention Head Sharing

GPT-2 used Multi-Head Attention (MHA): every head has its own Q, K, V projection.

Multi-Query Attention (MQA, Shazeer 2019) shares one K and one V across all heads. That cuts the KV cache by a factor of num_heads, a 12x to 32x reduction on a typical model, at the price of a slight accuracy drop on hard benchmarks.

Grouped-Query Attention (GQA, Ainslie et al. 2023) is the middle ground: G groups of Q heads share one K and one V. Llama 3 8B uses GQA with 32 Q heads and 8 KV heads (G=8), so the KV cache shrinks 4x versus full MHA.

Multi-Head Latent Attention (MLA, DeepSeek 2024) compresses K and V into a shared low-rank latent, projecting them back up per head. This shrinks the KV cache further while keeping per-head expressiveness. DeepSeek-V2 and V3 rely on it for long-context performance.

SchemeKV HeadsKV CacheAccuracy
MHAnum_headsfullbest
GQAnum_groups (G < num_heads)num_heads / G reductionnear-MHA
MQA1num_heads reductionsmall hit
MLAlatent, per-head decompressionsmaller than MQAnear-MHA

Above roughly 13B parameters, the models in the table use GQA or MLA. Full MHA at that scale makes the KV cache a serious problem.

Knob 5: Mixture of Experts

A dense MLP activates all its parameters for every token. An MoE MLP has K experts per block and a router that picks the top-k experts per token (typically top-2). Only those experts' weights see a forward pass for that token.

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

The appeal is that you can have 64 experts of size 7B each, which makes the total parameter count huge, while running only 2 of them per token, so per-token compute matches a dense 7B model. Mixtral 8x7B has 47B total parameters but activates only 13B per token. DeepSeek-V3 has 671B total parameters but activates only 37B per token.

Mermaid diagram

The upside is more parameters and capacity for the same compute. The downsides: the expert memory still has to live somewhere, so serving needs more VRAM than a dense equivalent. Load-balancing the router is hard. Fine-tuning the router during alignment is its own research area.

Knob 6: Pre-norm stays

The original transformer applied layer norm after each sublayer. The open models in the table put a norm before each sublayer instead (Gemma 2 adds one after as well). Pre-norm is easier to train at depth. Nothing to argue about.

Model-by-Model Diff

This table makes the six knobs concrete.

ModelYearTotal ParamsActive ParamsNormActivationPositionAttentionMoEContext
GPT-2 Small2019124M124MLayerNormGELULearnedMHA (12 heads)no1k
Llama 3 8B20248B8BRMSNormSwiGLURoPEGQA (32/8)no128k
Llama 3 70B202470B70BRMSNormSwiGLURoPEGQA (64/8)no128k
Llama 3 405B2024405B405BRMSNormSwiGLURoPEGQA (128/16)no128k
Mistral 7B20237.2B7.2BRMSNormSwiGLURoPEGQAno32k
Mixtral 8x7B202347B13BRMSNormSwiGLURoPEGQAyes (8 experts, top-2)32k
Gemma 2 9B20249B9BRMSNorm (pre+post)GeGLURoPE + slidingGQAno8k
Qwen 2.5 72B202472B72BRMSNormSwiGLURoPE (YaRN)GQA (64/8)no128k
DeepSeek V2 236B2024236B21BRMSNormSwiGLURoPEMLAyes (160 experts, top-6)128k
DeepSeek V32024671B37BRMSNormSwiGLURoPEMLAyes (256 experts, top-8)128k

Scan the columns. Past GPT-2, the rows agree on RMSNorm, on SwiGLU or its GeGLU cousin, and on RoPE. Above 7B the attention column reads GQA unless MLA replaced it. MoE is what separates the top end.

Reading a config.json

Llama 3 8B config:

{
  "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
}

Most of these fields map to something you have already implemented.

  • hidden_size: embedding dimension.
  • intermediate_size: MLP hidden size (3.5x hidden, a bit above the 8/3 rule of thumb).
  • num_hidden_layers: stack depth.
  • num_attention_heads: Q heads.
  • num_key_value_heads: KV heads (GQA).
  • max_position_embeddings: training context length.
  • rope_theta: RoPE base frequency. Meta scaled it from the default 10k to 500k for long-context extrapolation.
  • rms_norm_eps: numerical stability.
  • vocab_size: tokens.

From these alone you compute total parameters, KV cache, and peak activation memory. See code/main.py for the exact formulas.

Activation memory budget

Above a few billion parameters, activations dominate training memory. A rule of thumb for pre-training with gradient checkpointing:

activation_mem ~ batch_size * seq_len * hidden_size * num_layers * bytes_per_element

For Llama 3 8B at batch 1, seq 8192, BF16, 32 layers, hidden 4096: the formula gives 8192 * 4096 * 32 * 2 bytes = 2.1 GB with checkpointing, which keeps about one hidden-sized tensor per layer. Without it each layer holds roughly 17 such tensors, about 36 GB. That 17 comes from Korthikanti et al. (2022), who count about 34 bytes per sequence-batch-hidden element per layer for a GPT-style block in 16-bit precision. It leaves out the attention-score term and is only a rough guide for Llama's SwiGLU and GQA layers. This is why flash-attention and ring-attention matter: they rewrite the attention computation so activations fit.

KV Cache budget

For inference at max context:

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

Llama 3 8B at 128k context, BF16, head_dim = hidden / num_heads = 128: 2 * 32 * 8 * 128 * 131072 * 2 = 17.2 GB per sequence. That is 16 GiB, which is why main.py prints 16.0GB for this config: it divides by 1024 per step instead of 1000.

The 8B weights are 16 GB in BF16, so the KV cache for a single 128k sequence is larger than the weights. That memory pressure is what drives GQA, MLA, and KV cache quantization research.

When Each Model Wins

  • Single 80GB GPU, no MoE: Llama 3 8B, Mistral 7B, Gemma 2 9B. They are easy to serve and have wide tooling.
  • Single node (8x80GB), big capacity: Llama 3 70B, Qwen 2.5 72B. The strongest dense open capability in this list.
  • Biggest open capability, accept MoE complexity: DeepSeek V3, Mixtral 8x22B. The best capability per active FLOP.
  • Long-context needs: Llama 3 (128k with RoPE scaling), DeepSeek (MLA advantage).
  • Low-latency serving: Gemma 2 9B (sliding window cuts long-context compute).
Check: The Concept0/28
1. Which pieces do GPT-2 and the open models in this lesson share, whatever knobs each one picks?Define
Two cards of five knob values each, GPT-2 Small (LayerNorm, learned positions, GELU, MHA, dense MLP) and a generic open model here (RMSNorm, RoPE, SwiGLU, GQA or MLA, dense or MoE). Below both, a dashed box marked with a question mark stands for whatever lies outside those five rows. A question asks what stays the same shape in every model despite those five differences.
The five knob values on each side come from the lesson's own table; what is common outside them is the question.
2. What does RMSNorm do to an activation vector compared with LayerNorm?Define
A term card reading RMSNorm. Context note: Context: compared with LayerNorm, applied to one activation vector. A question asks: What does it do differently?
The term as the lesson names it; its mechanism is the question.
3. How does RoPE inject position information into attention?Define
A term card reading RoPE. Context note: Context: injecting position into the attention score between a query and a key. A question asks: How does it inject position information?
The term as the lesson names it; its mechanism is the question.
4. What is YaRN used for?Define
A term card reading YaRN. Context note: Context: a RoPE extension, named as one specific technique in the lesson. A question asks: What is it used for?
The term as the lesson names it; its mechanism is the question.
5. Which formula replaces GPT-2's single-projection GELU MLP in the open models of this lesson?Define
GPT-2's MLP formula, gelu(xW1+b1)W2+b2, shown as given, above a dashed box marked with a question mark and the note a gated two-projection formula, representing its replacement in the open models. A question asks which formula that replacement is.
GPT-2's own formula is quoted from the lesson; its replacement is the question.
6. What is Grouped-Query Attention (GQA)?Define
A term card reading Grouped-Query Attention (GQA). Context note: Context: a scheme between full multi-head attention and a single shared head. A question asks: What is it?
The term as the lesson names it; its mechanism is the question.
7. What is Multi-Head Latent Attention (MLA)?Define
A term card reading Multi-Head Latent Attention (MLA). Context note: Context: DeepSeek's attention scheme, named in the lesson. A question asks: What is it?
The term as the lesson names it; its mechanism is the question.
8. What is a Mixture-of-Experts (MoE) MLP block?Define
A term card reading a Mixture-of-Experts (MoE) MLP block. Context note: Context: replacing a block's single dense MLP. A question asks: What is it?
The term as the lesson names it; its mechanism is the question.
9. How does top-k routing choose which experts handle a token?Define
A term card reading Top-k routing. Context note: Context: how an MoE block's router picks which experts run a token. A question asks: How does it choose?
The term as the lesson names it; its mechanism is the question.
10. What does 'active parameters' mean for an MoE model?Define
A term card reading Active parameters. Context note: Context: a figure reported alongside total parameters for an MoE model. A question asks: What does the term mean?
The term as the lesson names it; its mechanism is the question.
11. Where do the open models in the lesson place their normalization layers?Define
A term card reading Normalization placement. Context note: Context: the original transformer normalized after each sublayer (post-norm). A question asks: Where do the open models in this lesson put it instead?
The term as the lesson names it; its mechanism is the question.
12. What does sliding-window attention do?Define
A term card reading Sliding-window attention. Context note: Context: an alternative to letting every token attend to the full sequence. A question asks: What does it do?
The term as the lesson names it; its mechanism is the question.
13. GPT-2 Small uses a learned position table with 1024 slots. Why does a 1025-token context break it?Explain
A learned position table drawn as row 0, row 1, row 2, an ellipsis, and row 1023, with nothing shown past the last row. A separate marker for the token at position 1025 sits below with a dashed line up toward the table and a question mark, resolving nothing. A question asks what happens for position 1025 given the table only has rows 0 through 1023.
The table's size (1024 rows) is the stem's own number; what happens past it is the question.
14. Which pairing of a GPT-2 component and its replacement in the open models is correct?Explain
A column of five GPT-2 components, learned positions, LayerNorm, GELU activation, multi-head attention, and dense MLP, each with an arrow to a blank box marked with a question mark. A question asks which single pairing below correctly matches one component to its replacement.
The five GPT-2-side components are named in the lesson; each one's specific replacement is left blank, and the question is which pairing is correct.
15. What intermediate_size does a SwiGLU MLP typically use relative to hidden size, and why?Explain
A field card listing the GELU MLP's two matrices and ff_dim of 4 times hidden, next to SwiGLU's three matrices with its ff_dim left blank. A question asks what ff_dim keeps SwiGLU's total parameters close to the GELU MLP's.
The matrix counts and GELU's ff_dim are given; SwiGLU's ff_dim multiplier is the question.
16. The Llama 3 8B config has rope_theta of 500000.0. Why was it raised from the default 10k?Explain
An excerpt of the Llama 3 8B config.json showing hidden_size 4096, num_attention_heads 32, rope_theta 500000.0, and the default rope_theta of 10000.0 for comparison. A question asks why rope_theta was raised fifty times above the default.
The config values are quoted from the lesson's own config.json excerpt; the reason for the change is the question.
17. In the Llama 3 8B config, num_attention_heads is 32 and num_key_value_heads is 8. What do the two fields tell you?Explain
An excerpt of the Llama 3 8B config.json showing only num_attention_heads at 32 and num_key_value_heads at 8. A question asks what these two field values tell you about this model's attention.
Both numbers are quoted directly from the lesson's own config.json excerpt; what they mean together is the question.
18. Why can an MoE model hold far more total parameters than a dense model without a matching rise in per-token compute?Explain
A field card with Mixtral 8x7B's own two numbers from the lesson text, 47B total parameters and 13B active parameters per token. A question asks why the much larger total parameter count does not drive a matching rise in per-token compute.
Both figures are the lesson's own stated numbers for this model; the reason for the gap is the question.
19. How does gradient checkpointing change activation memory for pre-training Llama 3 8B at batch 1, seq 8192, BF16?Explain
The activation memory formula from the lesson, batch times sequence length times hidden size times number of layers times bytes, with the same stem numbers (batch 1, sequence 8192, hidden 4096, 32 layers, BF16) and two blank results, one with gradient checkpointing and one without. A question asks how turning checkpointing on changes the estimate.
The formula and every input number are the lesson's own; the two resulting estimates are the question.
20. At 128k context in BF16, Llama 3 8B needs about 17.2 GB of KV cache per sequence. How does that compare to the model's own weights?Explain
A field card with two given figures for Llama 3 8B in BF16 at 128k context: 16 GB of weights and 17.2 GB of KV cache for one sequence at max context. A question asks how the two figures compare.
Both figures are the lesson's own stated numbers; the comparison is the question.
21. Llama 3 8B uses GQA with 32 Q heads and 8 KV heads. What KV cache reduction factor does that give versus full MHA?Apply
The same two Llama 3 8B field values as given in the stem, 32 query heads and 8 KV heads. A question asks what KV cache reduction factor this gives versus full multi-head attention.
The two head counts are the stem's own numbers; the reduction factor is the question.
22. A model card lists MLA attention with 256 experts and top-8 routing. Which model in the Model-by-Model Diff table matches?Apply
A model card with its name blanked out, showing MLA attention, 256 experts, and top-8 routing. A question asks which model in the lesson's table matches this card.
The architecture fields are the stem's own description; the model name is the question.
23. You plan to serve Llama 3 8B in BF16 on one 80 GB GPU with 128k-context requests. Using the 16 GB weights and 17.2 GB KV cache per sequence, how many full-length sequences fit?Apply
Three given figures for serving Llama 3 8B: an 80 GB GPU, 16 GB of fixed weight memory, and 17.2 GB of KV cache per sequence. A question asks how many full-length 128k sequences fit alongside the weights.
All three figures are the stem's own numbers; the sequence count is the question.
24. You serve Llama 3 8B in BF16 on an 80 GB GPU. The weights load fine, but the server runs out of memory when four users each send 128k-token prompts. What is the cause?Analyze
A field card for serving Llama 3 8B: 16 GB of weights loading fine, 4 concurrent users each sending a 128k-token prompt, and a KV cache of 17.2 GB for one such sequence. A question asks what ran out of memory and why.
All three figures and the user count are the stem's own numbers; the cause is the question.
25. A teammate says Mixtral 8x7B needs only about as much GPU memory as a dense 13B model, since only 13B parameters are active per token. What is wrong with that claim?Analyze
A quoted claim that Mixtral 8x7B only needs about 13B active parameters worth of GPU memory, next to the model's own 47B total and 13B active parameter figures. A question asks what is wrong with the claim.
The claim and both figures are given; what the claim gets wrong is the question.
26. You must serve long prompts at low latency on a single 80 GB GPU and want to avoid MoE complexity. Which open model fits best?Design
A deployment constraint card: one 80 GB GPU, a workload of long prompts needing low latency, a constraint to avoid MoE complexity, and the model itself left blank. A question asks which open model in the lesson fits this target best.
The hardware, workload and constraint are the stem's own description; the model is the question.
27. You have one node with 8x80 GB GPUs and want the strongest dense open model without taking on MoE complexity. Which pick fits?Design
A deployment constraint card: one node with 8 by 80 GB GPUs, a goal of the strongest dense open capability, a constraint to avoid MoE complexity, and the model itself left blank. A question asks which open model in the lesson fits this target best.
The hardware, goal and constraint are the stem's own description; the model is the question.
28. A team has a RoPE model trained on 8k context and must serve 128k prompts without pre-training a new model. Which approach fits?Design
A context-extension card: a RoPE-based model trained at 8k context, a target of serving 128k at inference with no new pre-training, and the approach itself left blank. A question asks which approach fits without pre-training a new model.
The position scheme and the two context lengths are the stem's own description; the approach is the question.

Build It

main.py is a calculator. Given a config dict in the shape of a HuggingFace config.json, it prints parameter counts by component, KV cache at max context, the MLP ratio, and a short verdict on the architecture (MHA, GQA, MLA, MoE).

python
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,
}

The script walks the config field by field and counts parameters for the embedding, attention (with the GQA reduction), the MLP (with SwiGLU's extra projection), and the norms. It treats the output head as tied to the embedding, so the head is not counted a second time. It then computes the KV cache at the stated context length and prints a summary.

See code/main.py for the implementation.

Check: Build It0/8
1. The calculator's attention_scheme function receives the GPT-2 Small config, with 12 attention heads, 12 KV heads and no 'attention' key. What does it return?Apply
The real attention_scheme function source from main.py, alongside GPT-2 Small's config fields: num_attention_heads 12, num_key_value_heads 12, and no 'attention' key. A question asks what the function returns for this config.
The function body is quoted from main.py; tracing it for this config is the question.
2. With hidden_size 4096, intermediate_size 14336 and activation 'swiglu', how many MLP parameters per layer does mlp_params compute for Llama 3 8B?Apply
The real mlp_params function source from main.py, alongside Llama 3 8B's config fields: hidden_size 4096, intermediate_size 14336, activation swiglu. A question asks how many MLP parameters per layer this returns.
The function body is quoted from main.py; computing it for this config is the question.
3. The Mistral 7B config has 32 layers, 8 KV heads, hidden_size 4096 with 32 heads, and 32768 context. What KV cache per sequence does the calculator print for BF16?Apply
The real KV cache branch of analyze from main.py, alongside Mistral 7B's config fields: hidden_size 4096 over 32 attention heads, 8 KV heads, 32 layers, and a 32768 max position. A question asks what KV cache per sequence the calculator prints in BF16.
The formula is quoted from main.py; computing it for Mistral 7B's config is the question.
4. In the deepseek-v3 config, num_hidden_layers is 61 and first_dense_layers is 3. How many layers does analyze treat as MoE blocks?Apply
The real two-line calculation from the MoE branch of analyze in main.py, alongside deepseek-v3's config fields: num_hidden_layers 61 and first_dense_layers 3. A question asks how many layers analyze treats as MoE blocks.
The subtraction is quoted from main.py; computing it for this config is the question.
5. The deepseek-v3 config has kv_lora_rank 512, hidden_size 7168 and 128 heads. If the calculator used its non-MLA formula with 128 KV heads, how many times larger would the cached entries per token and layer be than MLA's latent?Apply
The real MLA-vs-non-MLA branch of the KV cache calculation from main.py, alongside deepseek-v3's config fields: kv_lora_rank 512, hidden_size 7168, num_attention_heads 128. A question asks how many times larger the non-MLA cached entries would be than MLA's latent, if the non-MLA formula used 128 KV heads here.
The branch is quoted from main.py; computing the ratio for this config is the question.
6. The deepseek-v3 config sets num_key_value_heads equal to num_attention_heads (128 each), which the head-count rule alone would label MHA. Yet the calculator reports MLA. Why?Analyze
The real attention_scheme function source from main.py, alongside deepseek-v3's config fields showing num_attention_heads and num_key_value_heads both at 128, and an attention field set to mla. A question asks why the function returns MLA even though the equal head counts alone would say MHA.
The function body is quoted from main.py; why the equal-heads case never reaches the MHA line is the question.
7. The calculator prints ff/h = 0.29 for DeepSeek V3 even though its dense intermediate_size of 18432 would give 2.57. What explains 0.29?Analyze
The real mlp_ratio branch of analyze from main.py, alongside deepseek-v3's config fields: hidden_size 7168, intermediate_size 18432, moe_intermediate_size 2048, and moe true. A question asks why the calculator prints 0.29 rather than the 2.57 that intermediate_size over hidden_size would give.
The branch is quoted from main.py; which field it divides for an MoE config is the question.
8. The calculator prints 7.5B for Llama 3 8B, but the model card says 8B. Which counting choice in the calculator is the first place to look?Analyze
The real total-parameter formula for a dense model from main.py, listing embedding, attention, MLP and norm terms across the layers plus a final norm, with no separate term for an output head. Below it, Llama 3 8B's two reported totals: 7.5B from the calculator and 8B from the model card. A question asks which counting choice is the first place to look for the gap.
The formula is quoted from main.py exactly as written; which counted (or uncounted) term explains the gap is the question.

Use It

Run the calculator on the configs bundled in the script: GPT-2 Small, Mistral 7B, Llama 3 8B and 70B, Mixtral 8x7B, Qwen 2.5 72B, and DeepSeek V3. Compare the parameter breakdowns. The MoE models have a total parameter count far above their active count. Mixtral's active share is about a quarter of its total, and DeepSeek V3's is about 5%. DeepSeek V3's KV cache is also smaller than Llama 3 70B's (15.2 GB against 40.0 GB) despite roughly ten times the total parameters, and it is smaller than Llama 3 405B's too, though that config is not bundled. That is MLA at work.

Then plug in a config for any model you have locally, read the summary, and decide whether it fits your GPU.

Check: Use It0/2
1. Why is DeepSeek V3's KV cache (15.2 GB) smaller than Llama 3 70B's (40.0 GB) despite roughly ten times the total parameters?Explain
Two field cards side by side: DeepSeek V3 at about 671B total parameters and a 15.2 GB KV cache per sequence, and Llama 3 70B at 70B total parameters and a 40.0 GB KV cache per sequence, both at 128k context in BF16. A question asks why DeepSeek V3's cache is smaller despite roughly ten times the parameters.
Both models' parameter counts and KV cache figures are the lesson's own stated numbers; the reason is the question.
2. Mixtral 8x7B has 47B total parameters and activates 13B per token. About what share of its weights does one token use?Apply
A field card with Mixtral 8x7B's own two numbers from the lesson text, 47B total parameters and 13B active parameters per token. A question asks about what share of its weights one token uses.
Both figures are the lesson's own stated numbers; the share is the question.

Ship It

This lesson produces outputs/skill-open-model-picker.md. Given a deployment target (GPU type, VRAM, context length, latency budget) and a task profile (chat, code, reasoning, long-context), it recommends an open model, a quantization scheme from Lesson 11, and an inference stack from Lesson 12, with explicit reasoning about the six architectural knobs.

Author's Note

I'd run main.py and read the headline ratios at the bottom first. DeepSeek V3 prints at about 666B total and 32B active, while the table above says 671B and 37B. That gap comes from the calculator. Its MLA attention formula is a simplification, and it leaves out parts of the real model, so it undercounts. I find the mismatch useful, because it shows which numbers a back-of-envelope formula gets right and which it only approximates.

The KV cache line is the one I'd reuse. DeepSeek V3 prints 15.2 GB per sequence at max context, against 40.0 GB for Llama 3 70B (the script reports binary gigabytes), even though DeepSeek has nearly ten times the parameters. Change num_key_value_heads in a config and watch that number move. Cutting it is how GQA saves memory, and the script makes the saving visible.

One caveat before you trust the totals. The script treats the output head as tied to the embedding and doesn't count it again. Llama 3 8B prints 7.5B here, and the head is the first place I'd look for the difference from the 8B on the model card.

Exercises

  1. Read the Qwen 2.5 72B config from HuggingFace. Compute total parameters from scratch. Compare to the HF-reported value and identify where any delta comes from (head dim rounding, KV sharing factor, etc.).

  2. DeepSeek V3 uses 256 experts with top-8 routing. Compute the ratio of activated experts to total experts and compare to Mixtral 8x7B's top-2 of 8. What does the shift from 25% of experts active to about 3% imply about capacity per FLOP?

  3. Compute the KV cache for Llama 3 405B at 128k context in FP8 and BF16. At FP8 it is half the BF16 number. How many parallel sequences can you serve on a single 8xH100 node (80GB each = 640GB total, minus weight memory)?

  4. Gemma 2 alternates full-attention and sliding-window-attention layers. Write the math for the KV cache when half the layers use a 4096-token sliding window instead of full context. How much memory does that save at 8k total context?

  5. Find a recent frontier open model that was released after this lesson was written. Identify which of the six knobs it picked and whether it introduced a seventh knob. The curriculum will feel out of date the moment a new architecture ships. The goal is to update your table without rebuilding your mental model.

Key Terms

TermWhat people sayWhat it actually means
RMSNorm"LayerNorm without the mean"Normalize by root mean square only, with a learned scale. Cheaper and comparable to LayerNorm
RoPE"Rotary positions"Rotate each Q and K vector in 2D pairs by an angle that depends on position. Extrapolates beyond training length with scaling tricks
SwiGLU"The new MLP activation"Gated linear unit with Swish: (xW1) * sigmoid(xW1) * xV. Standard in the 2024+ open models in the table
GQA"Middle ground attention"Grouped-Query Attention: G groups of Q heads share one K and one V head. Shrinks KV cache without MQA's accuracy hit
MLA"DeepSeek's attention"Multi-Head Latent Attention: compress K/V into a shared low-rank latent, decompress per head. Smallest KV cache for large models
MoE"Sparse experts"Mixture of Experts: N MLPs per block, router picks top-k per token. Huge total params, small active params
Top-k routing"Pick k experts per token"The router computes a score per expert and activates the k highest. Typical k is 2 (Mixtral) to 8 (DeepSeek)
YaRN"Stretch RoPE"Yet another RoPE extension that interpolates rotary angles to extend context from 8k to 128k+ at inference time
Sliding-window attention"Don't attend to everything"Each token attends only to the last W tokens, which caps attention cost at O(W) per token, used in Gemma 2 and early Mistral
Active params"What runs per token"For MoE models, the parameter count that sees a forward pass per token (much smaller than total params). Governs per-token FLOPs

Further Reading

Code

Ships With