Transformers from the Weights Up/Part 5 of 20
Transformers from the Weights Up, Part 5: MLPs and what the FFN stores
Each FFN hidden unit is a memory slot: gate and up rows are keys, and a down_proj column is the value written back.
4 Nov 2026
Matrix-vector multiplication is a weighted sum of columns: W_down h = Σ hᵢ · W_down[:, i]. So call vᵢ = W_down[:, i] (a [4096] vector in Llama-3-8B) the value of slot i, and aᵢ(x) = hᵢ = SiLU(gᵢ·x) · (uᵢ·x) its coefficient, where gᵢ and uᵢ are row i of gate_proj and up_proj. Nothing has been approximated: this is the same computation as Lesson 3's SwiGLU, regrouped. Image 5's MLP is exactly this picture, 14,336 times over, in each of 32 layers.
Keys, values, and the tensors they live in
| Role | Tensor in the checkpoint | Slice for slot i | Shape |
|---|---|---|---|
| Gate key (does the slot fire?) | model.layers.ℓ.mlp.gate_proj.weight | [i, :] | [4096] |
| Up key (signed strength) | model.layers.ℓ.mlp.up_proj.weight | [i, :] | [4096] |
| Value (what gets written) | model.layers.ℓ.mlp.down_proj.weight | [:, i] | [4096] |
Count the memory. Llama-3-8B has 14,336 slots per layer × 32 layers = 458,752 slots. Each holds 3 × 4096 = 12,288 weights, or 24,576 bytes in bf16. All of them together are 5.64 billion parameters, and at batch-1 decode they are 11.27 GB of the 15.01 GB that Lesson 4 showed must stream through the chip for every token: about 75% of the bandwidth bill is spent reading memories.
- One Llama-3-8B block
- 218,112,000 parameters
- FFN share
- 176.16M = 80.8%
What the evidence says the slots hold
Geva, Schuster, Berant and Levy (2021) took this regrouping literally. For each key they collected the training prefixes that activated it most, and for each value they projected it through the output embedding to see which next tokens it pushes up. Their findings, from the paper's abstract:
- 1
Keys correlate with human-readable input patterns
Top-activating prefixes for a key share something nameable. Lower layers tend to capture shallow patterns, such as a particular word or n-gram ending; upper layers capture more semantic ones, such as a topic.
- 2
Values induce distributions over the vocabulary
Projecting vᵢ through the output embedding concentrates probability on tokens likely to come right after the key's pattern, especially in the upper layers.
- 3
The output is a composition of memories
No single slot decides the prediction. Many fire together, their weighted sum is added to the stream, and later layers refine it through the residual connection.
- 4
Updates promote concepts (Geva et al., 2022)
Viewing each FFN update in vocabulary space, the sub-update from a single value vector often promotes a human-interpretable concept. Scaling chosen sub-updates reduced GPT-2's toxicity by almost 50%, and a simple early-exit rule saved 20% of compute on average.
- Slot 1 coefficient
- 1.725 × 1.00 = 1.725
- Top token after FFN
- Paris (79%)
Facts in the middle layers, and editing them
Meng, Bau, Andonian and Belinkov (2022) asked where a model recalls a fact such as "The Space Needle is in Seattle." Their causal tracing corrupts the subject tokens, then restores one hidden state at a time from a clean run and measures how much of the right answer comes back. The decisive states sit in middle-layer feed-forward modules while the model processes the subject tokens. That fits the key–value reading: the subject, at its last token, is the key; the attribute is written as the value.
If a fact is a key-to-value mapping inside W_down, you can insert a new one with a single rank-one update. That is ROME (Rank-One Model Editing):
k* is the key the subject produces, v* is a value chosen by optimization so that the model outputs the new attribute, and C = KKᵀ is an uncentered covariance of the keys this layer normally sees, estimated from sample text. In ROME's framing the "key" is the whole [14336] activation vector h at the subject's last token, and W_down is a linear associative memory mapping it to a [4096] value: the same matrix, viewed as one memory rather than 14,336 slots. The edit maps k* exactly to v* (check: Ŵk* = Wk* + Λ · (C⁻¹k*)ᵀk* = Wk* + (v* − Wk*) = v*). Every other key k moves by Λ · (C⁻¹k*)ᵀk, which is small when k is unrelated to k* in the metric C defines.
- Edit applied
- 0%
- k1: cos with k*, output drift
- 0.76, 0.000
- k2: cos with k*, output drift
- -0.45, 0.000
- k3: cos with k*, output drift
- -1.00, 0.000
Where the clean picture breaks
| Clean story | What is actually true | Where it comes back |
|---|---|---|
| One slot, one pattern | Many hidden units are polysemantic: one unit fires for several unrelated patterns, because the model stores more features than it has units (superposition). | Lesson 20: sparse autoencoders recover cleaner features from mixtures of units |
| Slots are independent | Coefficients are computed from the same stream, and many slots fire at once; meaning is often in the combination, not one slot. | Lesson 20: circuits |
| Facts live only in FFNs | Attention moves information between positions (it carries the subject's attribute to the last token); FFNs transform it in place. Recall needs both. | Lessons 8–11 |
| The value is the answer | Values are added to a stream that later layers keep rewriting; the logit lens shows a vote, not the final outcome. | Lessons 11–12 |
For engineering, the key–value view still pays its way. It explains why ffn_down is one of the tensors quantization recipes treat most carefully (its 14336-wide input carries the rare large coefficients SwiGLU produces, Lesson 3), why mixture-of-experts models split exactly this block into many smaller banks of slots and pick a few per token (Lesson 19), and why pruning or skipping inactive slots is a recurring inference trick.
Lesson 5: key numbers
- 14,336
- slots per Llama-3-8B layer= d_ff
- 458,752
- slots in the whole model14,336 × 32 layers
- 12,288
- weights per slotgate row + up row + down column; 24 KiB in bf16
- ≈ −0.278
- SiLU minimumat z ≈ −1.28; the gate is nearly off below zero
- 80.8%
- FFN share of a Llama-3-8B block176.2M of 218.1M
- 70.2%
- FFN share of all 8.03B params5.64B; embeddings and lm_head take 13.1%
- ≈ 2/3
- FFN share in GPT-2-style modelsGeva et al. 2021; d_ff = 4d, two matrices
- 11.27 GB
- FFN bytes per bf16 decode step75% of Lesson 4's 15.01 GB
Lesson 5: self-check
1. In Llama-3-8B, which exact slices hold the keys and the value of FFN slot 5000 in layer 20?
2. Why is writing FFN(x) = Σ aᵢ(x)·vᵢ exact rather than an interpretation?
3. A ReLU-FFN slot can never write −vᵢ. A SwiGLU slot can. Why?
4. With C = I, which existing memories does a rank-one edit disturb, and by how much?
5. Why do FFN weights dominate the cost of generating one token at batch 1?
6. Causal tracing finds factual recall in middle-layer FFNs at the subject's last token. Why the subject token and not the final token?
Lesson 5: resources
- Transformer Feed-Forward Layers Are Key-Value MemoriesGeva et al., EMNLP 2021 (arXiv)
- Locating and Editing Factual Associations in GPT (ROME)Meng et al., project page with demos
- How might LLMs store facts (Deep Learning, Chapter 7)3Blue1Brown, YouTube
- Transformer Feed-Forward Layers Build Predictions by Promoting Concepts in the Vocabulary SpaceGeva et al., 2022 (arXiv)