The MLP (multi-layer perceptron, or feed-forward network) is the second sublayer in every transformer block. It contains ~⅔ of the model’s parameters and operates position-wise: each token’s residual stream vector is processed independently.
This post defines the MLP, derives the key-value memory interpretation (Geva et al., 2021) that underlies most modern MLP interpretability, covers neuron archetypes and superposition, and connects the framework to factual editing (ROME/MEMIT) and sparse autoencoders.
Demo: neuron activations
An MLP block has two linear layers with a non-linearity between them. The intermediate dimension is huge, typically 4× the hidden size. So in distilGPT2, each block has 3,072 MLP neurons. Each one is a tiny pattern detector. Click a neuron below to see what it fires on and what it writes back to the stream.
Why MLPs as "key-value memories"
Geva et al. (2021) showed that you can read the up-projection rows as keys (patterns the neuron looks for in the residual stream) and the down-projection columns as values (vectors the neuron writes into the stream when it fires). That decomposition turns each neuron into a key-value pair: "if you see X, write Y." It's the cleanest way to think about MLPs that exists. Bricken et al. (2023) extended this with sparse autoencoders to handle the messy fact that real neurons mix many features in superposition, but the key-value framing is still the foundation.
Cycle through neurons. Some are monosemantic (Python keywords, capital letters, France-related contexts). Some are polysemantic, firing on multiple unrelated concepts. The polysemantic case is explained by superposition (below).
Definition
For input $x \in \mathbb{R}^{d_\text{model}}$ at one position, a transformer MLP computes:
\[\text{MLP}(x) = W_\text{out}\, \sigma(W_\text{in}\, x + b_\text{in}) + b_\text{out}\]where:
- $W_\text{in} \in \mathbb{R}^{d_\text{ffn} \times d_\text{model}}$
- $W_\text{out} \in \mathbb{R}^{d_\text{model} \times d_\text{ffn}}$
- $\sigma$ is a non-linearity (GeLU, ReLU, or in modern models SwiGLU)
- $d_\text{ffn} = 4 \cdot d_\text{model}$ is the standard ratio
Sizes:
| Model | $d_\text{model}$ | $d_\text{ffn}$ | Neurons per block |
|---|---|---|---|
| GPT-2 small | 768 | 3,072 | 3,072 |
| GPT-2 XL | 1,600 | 6,400 | 6,400 |
| Llama 3 8B | 4,096 | 14,336 | 14,336 |
| GPT-3 175B | 12,288 | 49,152 | 49,152 |
Three properties:
- Position-wise. No mixing across token positions. Operates in parallel on each token’s residual vector.
- Up-projection then down-projection. Hidden width $4\times$ wider than the residual stream. Storage capacity scales with $d_\text{ffn}$.
- Non-linearity is essential. Without $\sigma$, two stacked linear layers collapse to one and the MLP cannot represent any nonlinear pattern.
Key-value memory interpretation
Decompose $W_\text{in}$ row-wise and $W_\text{out}$ column-wise:
- Row $n$ of $W_\text{in}$, written $k_n^\top$, is a vector in $\mathbb{R}^{d_\text{model}}$: the key of neuron $n$.
- Column $n$ of $W_\text{out}$, written $v_n$, is a vector in $\mathbb{R}^{d_\text{model}}$: the value of neuron $n$.
Then:
\[\text{MLP}(x) = \sum_{n=1}^{d_\text{ffn}} \sigma(k_n^\top x + b_n)\, v_n\]The MLP is a sum of $d_\text{ffn}$ scaled value-vectors, where each scaling coefficient is a non-linearly gated dot product of $x$ with the corresponding key.
Equivalently:
- The key $k_n$ tests whether $x$ matches a specific pattern (large $k_n^\top x$ ⇒ match).
- The non-linearity gates: only neurons whose match exceeds threshold contribute.
- Each contributing neuron writes its value $v_n$ to the residual stream, scaled by activation.
This is a soft, sparse key-value lookup over a learned database of $d_\text{ffn}$ entries per block. (Geva et al., 2021)
Neuron archetypes
Empirically, MLP neurons fall into recurring categories:
Surface-feature neurons (early layers)
Fire on lexical patterns: capital letters, punctuation, specific morphemes, code-syntax tokens. Their values write tags downstream blocks consume.
Syntactic neurons (mid layers)
Fire after grammatical patterns: possessives, definite articles, sentence-initial positions. Values bias the next-token distribution toward syntactically valid continuations.
Factual-recall neurons (mid-to-late layers)
Encode specific facts. Meng et al. (2022, ROME) demonstrated that “the Eiffel Tower is in Paris” can be located to a small set of neurons in mid layers and surgically edited (so the model claims the Eiffel Tower is in Rome) by modifying $W_\text{out}$ columns at those positions.
Abstract / semantic neurons (late layers)
Fire on higher-level patterns: sentiment, sarcasm, discourse markers. Harder to characterize from top-activating examples alone.
Uninterpretable from top examples
A non-trivial fraction of neurons have no clean concept-level description. Often these are polysemantic.
Polysemanticity and superposition
Most real neurons are polysemantic: top-activating contexts span multiple unrelated concepts.
Elhage et al. (2022, “Toy Models of Superposition”) explain why. When features are sparse (most off most of the time), a $d$-dimensional space can represent ~$d / \log d$ features by overlapping them at non-orthogonal angles. The non-linearity in the MLP allows partial recovery: only one feature in a superposed pair is typically active in any given input, so interference is bounded.
Consequences:
- The “real” interpretable features are directions (linear combinations of neurons), not single neurons.
- Reading individual neuron activations gives a tangled, polysemantic picture.
- To recover monosemantic features, train an overcomplete dictionary on cached activations: a sparse autoencoder (SAE).
Bricken et al. (2023, “Towards Monosemanticity”) and Templeton et al. (2024, “Scaling Monosemanticity”) trained SAEs on Claude 3 Sonnet and recovered millions of monosemantic features ranging from “the Golden Gate Bridge” to “code with security vulnerabilities.”
A neural network has fewer dimensions than concepts. To survive, it packs many features into the same space at near-orthogonal angles. The trick: only a few features are active at once, so they barely interfere. Toggle features on and off and watch the residual vector form. Then read it back out.
What you're seeing: 8 feature directions packed into 2 dimensions. Each active feature contributes its direction (faded amber arrow); the residual is their sum (dark amber). Below: dot products of the residual with each feature direction, the model's "readout." When few features are on the readout is clean. Turn on too many and they start to interfere. This is why neurons can be polysemantic and why sparse autoencoders work.
Direct logit attribution for MLPs
Because each neuron’s contribution to the residual stream is $\sigma(k_n^\top x) v_n$, its contribution to the final logit of token $w$ is:
\[\Delta\text{logit}_n(w) = \sigma(k_n^\top x)\, v_n^\top W_U[:, w]\]| Sort neurons by $ | \Delta\text{logit}_n(w) | $ to identify which neurons drove the prediction. This is MLP-level DLA. |
# in TransformerLens
mlp_act = cache["post", layer, "mlp"] # [seq, d_ffn]
W_out = model.W_out[layer] # [d_ffn, d_model]
W_U = model.W_U[:, answer_id] # [d_model]
neuron_dla = mlp_act[-1] * (W_out @ W_U) # [d_ffn]
top_neurons = neuron_dla.argsort(descending=True)[:10]
Why MLPs hold the knowledge
Three lines of evidence support the claim that factual knowledge lives in MLPs:
- Parameter share. MLPs are ~⅔ of total parameters. Most learned content is statistically there.
- Editing. ROME and MEMIT edit specific facts by modifying MLP weights at specific layers (typically mid-layers, around layer 5–8 in GPT-2 medium). Editing attention weights does not produce the same effect.
- Causal tracing. Meng et al. (2022) corrupt subject tokens, then restore individual layers’ activations one at a time and measure which restoration recovers the correct prediction. The signal localizes to mid-layer MLPs.
A clean operational summary: attention moves information; MLPs add new information. Both contribute additively to the residual stream. Their roles are complementary.
Pick a fact. Pick the new answer you want the model to insist on. Drag the edit slider from 0 to 1 to apply a rank-one update to one MLP layer's weights, simulating what the ROME paper does. Watch the prediction shift, and watch a related question to see if your edit generalizes correctly.
What ROME actually does: the model encodes facts as (key, value) pairs in mid-layer MLPs. ROME locates the layer where the subject's representation peaks, then computes a rank-one update to W_out that swaps the value while preserving the key. The edit propagates to paraphrases of the same fact (the consistency check) without destroying unrelated knowledge. Numbers shown are illustrative; real ROME edits typically achieve 95%+ post-edit probability.
Activation functions in modern models
| Model | Non-linearity | Form |
|---|---|---|
| GPT-2 / GPT-3 | GeLU | $x \cdot \Phi(x)$ |
| Original Transformer | ReLU | $\max(0, x)$ |
| PaLM, Llama, Mistral | SwiGLU | $\text{Swish}(W_g x) \odot (W_\text{in} x)$ |
SwiGLU adds a gating branch:
\[\text{MLP}_\text{SwiGLU}(x) = W_\text{out}\, (\text{Swish}(W_g x) \odot W_\text{in} x)\]This requires three matrices instead of two, but the key-value interpretation extends: each neuron’s “key” is now a (gate, input) pair, and the value is still the corresponding $W_\text{out}$ column. Most MLP interpretability tooling generalizes with minor modification.
What we have so far
| Component | Role | Reads | Writes |
|---|---|---|---|
| Embedding | Token → vector | token IDs | residual stream |
| Attention | Cross-position routing | residual stream (all positions) | residual stream (current position) |
| MLP | Stored knowledge / transforms | residual stream (current position) | residual stream (current position) |
| Unembedding | Vector → logits | residual stream (last position) | output distribution |
All four components communicate exclusively via the residual stream. Every interpretability tool in this series operates on that interface.
The next post runs a full forward pass through GPT-2 small, end-to-end, with concrete numbers at every stage.
Resources
Foundational papers
- Transformer Feed-Forward Layers Are Key-Value Memories
- Locating and Editing Factual Associations in GPT (ROME)
- Mass-Editing Memory in a Transformer (MEMIT)
- Toy Models of Superposition
- Towards Monosemanticity
- Scaling Monosemanticity
- GLU Variants Improve Transformer