The Transformer Architecture
Attention, add, normalise, feed-forward, add, normalise — stacked. Switch the residuals off and watch a deep stack stop working.
Overview
Quick Context
The previous modules built the parts: query, key and value, self-attention, multiple heads, positional encoding. This module assembles them.
The surprise, when you finally see the block written out, is how little there is. Two sublayers, each wrapped in the same two-line pattern, repeated N times.
Model
multiple of d_model
One Block
× 6Gradient Reaching Each Layer
Relative gradient reaching each layer, counting back from the output. 1 means it arrives intact.
Health
Parameters
The Transformer Architecture: A Practical Guide
How the pieces are assembled into a block, and which of them are load-bearing.
The block
Every transformer block is these four lines:
x = LayerNorm( x + MultiHeadAttention(x) )
x = LayerNorm( x + FeedForward(x) )
That is the entire thing. Two sublayers, and each is wrapped identically: run the sublayer, add the input back, then normalise. The pattern is called Add & Norm, and it is applied so uniformly that the block is easier to remember as "sublayer, add, norm" repeated twice than as a diagram.
What each piece is for
- Attention moves information between positions. It is the only part of the block that lets one token see another.
- The feed-forward network processes each position independently — the same small two-layer MLP applied to every token separately. It is where the model does per-token computation on whatever attention just gathered.
- The residual connection gives the gradient a path that skips the sublayer entirely.
- Layer normalisation keeps the activations at a stable scale as depth grows.
The division of labour between the first two is worth holding on to: attention mixes across tokens, the FFN thinks about each token. A transformer alternates between the two, over and over.
The block, repeated
A transformer is one block stacked many times. The block has two sublayers, each wrapped in a residual connection and a normalisation:
x → LayerNorm → Multi-head attention → (+x)
x → LayerNorm → Feed-forward → (+x)
Attention moves information between positions. Each token gathers a content-weighted mix of the others.
The feed-forward network processes each position independently. It expands to four times the model dimension, applies a non-linearity, and projects back. This is where most of the parameters live — roughly two thirds of them in a typical model — and it is a common misconception that attention does all the work.
Residual connections give gradients a path back through dozens of blocks. LayerNorm keeps activations stable, and placing it before each sublayer rather than after is what makes 80-layer stacks trainable.
Everything else about a transformer is the arrangement of these blocks and what goes in and out.
Three arrangements, three jobs
| Family | Blocks used | Attention | Good at |
|---|---|---|---|
| Encoder-only (BERT) | Encoder stack | Bidirectional | Classification, retrieval, tagging |
| Decoder-only (GPT) | Decoder stack | Causal | Generation, chat, anything open-ended |
| Encoder-decoder (T5, original) | Both, with cross-attention | Both | Translation, summarisation |
Encoder-only models see the whole input at once, so every token's representation is informed by both directions. That makes them excellent at understanding and useless at generating — there is no notion of "next".
Decoder-only models mask future positions, so each token depends only on what precedes it. That constraint is what makes generation possible, and it turned out to scale so well that most current large models are decoder-only.
Encoder-decoder models encode the source, then decode while attending to it through cross-attention. Natural for translation, where input and output are distinct sequences.
The full input path
Following a sentence through a decoder-only model:
- Tokenise — text becomes integer ids.
- Embed — each id looks up a vector from the embedding table.
- Add positional information — sinusoidal, learned, or rotary applied inside attention.
- N transformer blocks — each refining the representation.
- Final LayerNorm.
- Output projection to vocabulary size, giving one logit per possible next token.
- Softmax (inside the loss during training; explicitly at generation time).
Step 6 is often tied to the embedding table — the same matrix used in reverse. That saves a large number of parameters and usually improves quality slightly.
The shape of the tensors flowing through: (batch, sequence, model_dim) from step 2 onwards, unchanged by every block. That constancy is what makes the stack composable.
A whole block, run end to end
A transformer block is attention, a feed-forward network, two residual connections and two layer norms. All of it is here, followed by the parameter count that explains where the compute actually goes.
Try it yourself
- Take the residuals away. Untick Residual Connections and set the Number of Layers slider to 24. Watch the gradient curve decay toward zero and Trainable flip to no. Each sublayer shrinks what passes through it, and twenty-four of those in a row leave nothing to learn from.
- Put them back. Tick Residual Connections with the depth still at 24. The gradient holds at 1 all the way back to layer 1. This is the single change that makes deep stacks trainable at all.
- Take normalisation away instead. Untick Layer Normalisation with residuals on and depth at 24. Now the opposite failure: with nothing rescaling between layers the gradient compounds instead of decaying, and a deep stack becomes unstable rather than dead.
- Find where the parameters are. With Feed-Forward Width at 4, read FFN Share. Roughly two thirds of every block sits in the feed-forward network, not in attention — which surprises most people, since attention is the part that gets all the attention.
- Change the width. Set the Feed-Forward Width slider to 1 and watch FFN Share collapse, then to 8 and watch it dominate. The 4× default is a convention, not a law.
- Scale it up. Set the Model Dimension slider to its maximum and watch the total. Parameters grow with the square of the dimension but only linearly with depth, which is why widening is so much more expensive than deepening.
Why residuals matter so much
Without a residual connection, the gradient reaching layer 1 has to pass back through every layer above it, being multiplied at each step. Multiply twenty-four numbers smaller than one and you get approximately zero — the vanishing gradient problem, arriving from a different direction.
The residual gives the gradient a route that skips the sublayer, so it reaches the early layers essentially intact. That is why the same trick appears in ResNets, and why almost every deep architecture built since 2015 has some version of it. It is not an optimisation detail; without it, "deep" is not available.
Pre-norm and post-norm
The original paper put normalisation after the addition — LayerNorm(x + Sublayer(x)), which is what the diagram above shows. Almost every model since does the opposite, x + Sublayer(LayerNorm(x)), called pre-norm.
The reason is practical: with post-norm the residual path itself gets normalised at every layer, which weakens it, and deep post-norm models need a careful learning-rate warmup to train at all. Pre-norm leaves the residual path clean from input to output and trains far more forgivingly. If you read the 2017 paper and then read a modern implementation, this is the difference you will notice first.
Where this goes wrong
- Thinking the FFN is the small part. It is about two thirds of the block. Most of a transformer's parameters do per-token computation, not attention.
- Forgetting the FFN is position-wise. It has no view of other tokens at all. Every bit of cross-token information arrived through attention.
- Mixing up pre-norm and post-norm. Implementing the paper's post-norm without warmup and wondering why a deep model will not converge is a rite of passage.
- Expecting depth to be free. Layers add parameters linearly but add sequential compute too; width adds parameters quadratically but parallelises well. The trade is why model shapes look the way they do.
In one line
A transformer block is two sublayers, each wrapped in the same add-and-normalise pattern: attention moves information between positions, and a position-wise feed-forward network processes each token on its own. The residual connection is what makes depth possible, giving the gradient a path that skips each sublayer — remove it and a deep stack stops training entirely — while layer normalisation holds the activation scale steady as layers accumulate. About two thirds of the parameters live in the feed-forward network rather than in attention, and parameters grow with the square of the model dimension but only linearly with depth.
Why it replaced recurrent networks
Two properties, both structural.
Parallelism. An RNN must compute position t before t+1. A transformer computes all positions simultaneously as one matrix multiplication, which is what a GPU is built for. That alone made training on far more data feasible.
Constant path length. Any two positions are one attention step apart. In an RNN the path grows with the distance, and gradients decay along it — which is why long-range dependencies were the central difficulty.
The cost of those wins is quadratic attention: doubling the sequence length quadruples the work. That is the trade the architecture makes, and it is why long context required years of engineering (FlashAttention, sparse patterns, KV caching) rather than being free.
Note that recurrent architectures have not disappeared — state-space models such as Mamba revisit the idea with linear scaling, and are competitive on long sequences.
Scaling, and what changes with size
The same block, repeated more times and made wider:
| Model | Layers | Model dim | Parameters |
|---|---|---|---|
| BERT-base | 12 | 768 | 110M |
| GPT-2 | 48 | 1600 | 1.5B |
| Llama-2 7B | 32 | 4096 | 7B |
| Large frontier models | 80+ | 8192+ | 100B+ |
Nothing about the block changes. What changes is depth, width, vocabulary, context length and the amount of data.
The scaling laws that emerged from studying this — performance improving predictably with compute, parameters and data together — are why the field spent several years mostly making the same architecture bigger. The Chinchilla result refined it: for a given compute budget, most early large models were under-trained on too little data relative to their size.
Practical consequences of size: Adam's optimiser state is twice the model, so large-scale training needs sharding (ZeRO, FSDP); inference needs KV caching and quantisation; and fine-tuning uses parameter-efficient methods such as LoRA rather than updating every weight.
Questions people ask
Why is the feed-forward layer four times wider? Convention from the original paper, and it works. Some modern models use different ratios, and gated variants (SwiGLU) with a smaller expansion.
What is the difference between BERT and GPT? Bidirectional encoder trained on masked tokens, versus causal decoder trained on next-token prediction. Understanding versus generation.
Do transformers understand language? They model statistical structure in text extremely well. Whether that constitutes understanding is a genuine open question, not a settled one in either direction.
Why pre-norm rather than post-norm? It leaves the residual path clean, so gradients flow back unimpeded. Post-norm needs careful warm-up beyond about 12 layers.
How long can the context be? Architecturally unlimited; practically bounded by quadratic cost and by how far the positional scheme generalises. Current models reach hundreds of thousands of tokens.
Are transformers only for text? No — vision transformers treat image patches as tokens, and the architecture is used for audio, protein structure, video and time series.
Recap in one screen
- One block: attention to move information between positions, a feed-forward network to process each position, both wrapped in residual connections and LayerNorm.
- Most parameters are in the feed-forward layers, not in attention.
- Encoder-only for understanding, decoder-only for generation, encoder-decoder for sequence-to-sequence.
- Parallelism and constant path length are why it replaced RNNs; quadratic attention is what it costs.
- Scaling changes depth, width and data — not the block.