Attention is one part of a Transformer. This chapter builds the rest (the residual stream, normalization, the feed-forward network, and position) and then counts every parameter and every FLOP of the block that every large model is built from.
The residual stream
Section 4.7 ended with a warning. A stack of pure attention layers loses rank doubly exponentially fast with depth, until every token carries nearly the same vector (Dong et al., 2021). Something has to carry each token's own information up through dozens of layers. You met the fix in §0.8, where it let ResNets train at 152 layers at a time when a plain 56-layer network had a higher training error than a 20-layer one (He et al., 2016). Instead of asking each layer to compute a new representation, ask it to compute a correction and add it to its input, instead of .
Every Transformer since 2017 is built on the same trick. In a Transformer it deserves a better name than "skip connection", because it changes how you should picture the whole model. The vector that gets corrected, layer after layer, is called the residual stream, and the rest of this chapter hangs off it.
Section 0.8 showed why the identity path keeps gradients from vanishing. This section goes further. We will see the stream as a running sum that every sublayer reads from and writes to, split a model's output exactly into per-layer contributions, and find that the same identity path lets gradients explode unless each branch shrinks with depth.
A block computes a correction, not a replacement
Write the token vectors of a sequence as the rows of , as in Chapter 4, where is the model width. A residual layer computes
where is the stream before sublayer and is the sublayer (an attention layer or a feed-forward network, each with its own parameters). The superscript always means "after sublayers". The stream starts as , the token embeddings (plus position information, which we add in §5.4).
In plain words, each sublayer looks at the current state of every token and proposes a change. The change is added, nothing is overwritten.
Two things follow immediately. First, if outputs zeros, the layer is exactly the identity. A deep residual network at initialization (where each is small) behaves like a shallow one, and depth is something the network grows into rather than something it must fight. That is the cure for the 56-layer puzzle. Second, the output of a block is the same shape as its input, , always. That is why you can stack 12, 96, or 128 identical blocks without any glue.
A Transformer block contains two residual sublayers, attention followed by a feed-forward network (§5.3), so a model with blocks has sublayers writing into the stream. In this section we count sublayers and write for their number, so for a Transformer. Attention is the only place where tokens exchange information. The feed-forward network works on each token separately.
Unroll it, and the stream becomes a sum
Apply the update rule times and expand,
In plain words, the final representation of every token is its embedding plus the sum of everything every sublayer ever wrote.
Here is a tiny example you can check by hand. Take and one token with embedding . The first sublayer writes , the second writes , and the third writes . The stream goes . Nothing is lost. You could read off the third layer's write from the difference of two consecutive states, and an earlier write is still sitting in the final vector unless a later layer deliberately subtracts it.
The widget below makes this concrete for a toy model with six sublayers and an 8-dimensional stream. Each dimension's bar is stacked from the contributions of every component that has written so far, colored by who wrote it.
Switching a layer off removes its color and, in this toy, also changes what later layers read, because each later write depends on the stream it sees. The logit change is therefore its direct share plus an indirect effect through later layers. Keep that distinction in mind. It is the difference between direct and total effects, and interpretability researchers fight over it constantly.
Let's build the same thing in NumPy. Each sublayer here is a stand-in (a random matrix and a tanh) rather than real attention, but the bookkeeping is identical.
Run a residual stream and keep the receipts
Write run_stream(X0, blocks) where X0 has shape (T, d) and blocks is a list of functions, each mapping a (T, d) array to a (T, d) write. Return (states, writes), where states has shape (S+1, T, d) with states[0] = X0 and states[l+1] = states[l] + blocks[l](states[l]), and writes has shape (S, T, d). Do not modify X0.
Reading and writing, the stream as a shared channel
Look at what a sublayer actually does with the stream. It never sees "the previous layer's output" as a separate object. It sees the sum. An attention layer reads the stream through its query, key, and value projections and writes back through its output projection . The feed-forward network reads through its first matrix and writes through its second. Every read is a linear projection of the stream (after a normalization, §5.2), and every write is a vector added to it.
Elhage et al. (2021) turned this observation into a way of thinking that has shaped interpretability research ever since. The residual stream is a communication channel. Sublayers do not talk to each other directly. They leave messages in the stream, in some subspace, and later sublayers pick them up by projecting onto that subspace. Three consequences are worth having in your head.
Composition is a product of matrices. Suppose sublayer writes into the stream (with its internal activation) and a later sublayer reads . The part of 's input that came from is . The product is a "virtual weight" that connects the two sublayers directly, even though they may be twenty layers apart. This is how attention heads in different layers cooperate, for example in the induction heads previewed in §4.7.
The direct path is a model too. Set every to zero. What remains is embedding followed by unembedding, logits with the unembedding matrix. That zero-layer model can only use the current token to predict the next, so the best it can learn is bigram statistics. A trained Transformer keeps a version of this bigram table in the product of its embedding and unembedding matrices, and every layer adds refinements on top of it.
Bandwidth is limited. All sublayers share the same dimensions. GPT-2 small has and 24 sublayers, many of which compute far more than 768 internal features. The stream cannot give each feature its own axis, so models store more features than dimensions by packing them into nearly orthogonal directions, the high-dimensional trick from §1.3. This is the setting for superposition, where a model represents more concepts than it has neurons. Elhage et al. also observed sublayers whose writes appear to erase information that is no longer needed, a kind of memory management.
Decomposing the output, exactly
Because the stream is a sum, the final logits are almost a sum too. The "almost" is the final normalization. GPT-style models compute logits as , where for one token
Here are a learned gain and shift, is the all-ones vector, and is a small constant (§5.2 derives all of this properly). The mean subtraction is linear in . The division by is not, but is a single number per token. If we treat as fixed for the token we are explaining, the logit of vocabulary item splits exactly into one term per component of the stream (the embedding and every write),
In plain words, center each write, scale it by the shared and the gain, and project it onto the unembedding column of the token you care about. That number is the write's direct contribution to the logit. This is called direct logit attribution, and it is the first tool people reach for when asking "which layer made the model say Paris?".
The same picture gives the logit lens (nostalgebraist, 2020). Apply the final normalization and the unembedding to an intermediate state instead of , and you get the model's current best guess partway through. In trained models those guesses sharpen layer by layer, and the logit lens has become one of the basic tools for reading a model from the inside.
The two numbers agree to every printed digit. The decomposition is not an approximation once is frozen. What it does not capture is that a write also changes what later layers read, which is the indirect effect you saw in the widget.
Direct logit attribution through a final LayerNorm
Write logit_attribution(parts, gamma, beta, W_U, v, eps=1e-5). parts has shape (C, d) and holds every component of one token's final stream (the embedding first, then each write), so the stream is parts.sum(0). Compute the token's LayerNorm statistics mu and s from that sum, then return (contrib, bias_term) where contrib[c] is component c's direct contribution to logit v (as in the formula above) and bias_term is beta @ W_U[:, v]. The contributions plus the bias term must equal the true logit.
Gradients ride the identity
Now the reason residual networks train at all, redone for a stack of sublayers so that we can see how depth enters. Take one token's stream and the Jacobian of one sublayer, (we use the column convention of §0.2, entry is ). Differentiate the update rule,
Multiply out the product and the first term is . Then come the sums of single Jacobians, then pairs, and so on,
Backpropagation sends the row vector down by multiplying on the right, . So
In plain words, every layer receives the loss gradient at the top, untouched, plus whatever the sublayers above add to it. In a plain network , the gradient is only the last term, a product of Jacobians, and products of many matrices shrink or blow up exponentially.
How fast? Here is a calculation you can do in an interview. Model each Jacobian as a random matrix with independent entries , so it scales a vector by about (formally ). For one residual step,
because the cross term has mean zero. After independent steps the gradient's root-mean-square size is for the residual network and for the plain one.
The plain network vanishes for any and explodes for any . Only the knife edge survives, and real nonlinearities (a ReLU zeroes half its inputs) knock you off it. The residual network can never vanish, since . But look carefully, it can explode, . The way out is to keep each branch small in proportion to depth. With the growth is no matter how deep the model is. Remember that , because it comes back as the GPT-2 initialization rule in §5.7, where gives a factor of .
At 64 layers, the plain network's gradient at is about , numerically dead. The residual network's never drops below 1, but at it is about , which is why nobody trains a deep residual network with full-size branches. At it sits near 1.6, matching the theory.
Backpropagate through a stack, in the right order
You are given the top gradient g_top (a vector of shape (d,)) and the sublayer Jacobians Js, an array of shape (S, d, d) where Js[l] is in the column convention. Write backprop_stack(g_top, Js, residual=True) returning G of shape (S+1, d) with G[S] = g_top and G[l] the gradient with respect to . For a residual stack , and for a plain stack .
Interviewers like this one because it has two classic traps, the order of the loop and the side the vector multiplies on.
The forward signal grows too
The same arithmetic applies on the way up. If each write were a random linear function of the stream, would grow like , exponentially. Real Transformers avoid that by normalizing what each sublayer reads (the pre-LN arrangement of §5.2), so each write has a roughly fixed size no matter how large the stream has become. Then the writes add like independent random vectors and the squared norm grows linearly, for a per-write squared size . Linear growth is survivable, but it has consequences. The later a sublayer sits, the smaller its write is relative to the stream, and the final normalization must divide by a number that grows like . Section 5.2 shows how this shapes the gradients, and §5.7 how initialization keeps it in check.
A residual network is an ensemble of paths
Go back to the expanded product, . Each term corresponds to a path from layer to the top that passes through some subset of the sublayers and skips the rest. With sublayers there are paths, and of them pass through exactly sublayers.
Veit, Wilber & Belongie (2016) took this "unraveled" view seriously. If each sublayer on a path multiplies the gradient by a typical factor , then the total contribution of length- paths is proportional to . Normalizing by (the binomial theorem) gives a distribution over path lengths with mean
∂ Where the mean comes from
Let . Differentiating term by term, . So
This is the mean of a binomial distribution with trials and success probability , which is exactly what the normalized weights are.
In plain words, when sublayers shrink the gradient (), most of the gradient travels along paths that use only a fraction of the layers. Veit et al. measured this in a 110-layer ResNet and found that most of the gradient came from paths only 10 to 34 layers deep. They also found that deleting a single block from a trained ResNet at test time barely hurts accuracy, while deleting a layer from a plain VGG network destroys it. The network behaves less like one very deep function and more like a large ensemble of shallower ones that share weights.
Large language models show a version of the same robustness. Gromov et al. (2024) removed large fractions of the deepest layers of open models with modest loss on question-answering benchmarks after a small amount of fine-tuning. This is an empirical finding, and it is double-edged. It suggests that deep layers in today's pre-LN models are underused, which is part of the motivation for the depth-aware normalization and scaling tricks in §5.2 and §5.7.
The path-length distribution, without overflow
Write path_length_weights(S, alpha) returning (w, mean), where w has shape (S+1,) with w[k] proportional to and summing to 1, and mean is . It must work for S = 2000 and alpha = 1.5, where overflows a float.
In PyTorch
In PyTorch the residual add is one line, and forward hooks let you record every write without touching the model's code. This is how interpretability tooling captures the stream.
Plain, highway, residual
Residual connections were not the only proposal for training deep networks. Highway networks (Srivastava, Greff & Schmidhuber, 2015) came first, with a learned gate that mixes the input and the transformation.
| connection | update | identity at init? | gradient path | used in |
|---|---|---|---|---|
| plain | no | product of Jacobians only | early deep nets, VGG | |
| highway | , gate learned | only if the gate starts closed | identity scaled by | early very deep feedforward nets (2015) |
| residual | yes, if starts small | exact identity plus branches | ResNets, every Transformer | |
| scaled residual | , small or learned | yes | identity plus damped branches | ReZero, DeepNet, GPT-2 init (§5.7) |
| dense | yes | identity via concatenation | DenseNet (width grows with depth) |
The residual form won because the identity path is exact and free. A highway gate can close, and concatenation makes the width grow with every layer, which a 96-layer Transformer cannot afford.
Read more
- He, Zhang, Ren & Sun (2016). Deep Residual Learning for Image Recognition. The degradation problem and the residual fix.
- He, Zhang, Ren & Sun (2016). Identity Mappings in Deep Residual Networks. Why a clean identity path matters, derived from the backward pass.
- Elhage et al. (2021). A Mathematical Framework for Transformer Circuits. The residual stream as a communication channel, virtual weights, and composition.
- Veit, Wilber & Belongie (2016). Residual Networks Behave Like Ensembles of Relatively Shallow Networks. The unraveled view and the lesion experiments.
- nostalgebraist (2020). Interpreting GPT, the logit lens. Reading intermediate residual states with the unembedding.
- Gromov et al. (2024). The Unreasonable Ineffectiveness of the Deeper Layers. Pruning deep layers of LLMs and what it suggests about depth.
- Srivastava, Greff & Schmidhuber (2015). Highway Networks. The gated predecessor of residual connections.