Level 10 · AdvancedLesson 10.2 42 min read 10 question quiz 11 marks of written practice

Transformers: The Architecture Behind Modern AI

Attention is all you need

In June 2017 eight researchers working at Google published "Attention Is All You Need". Their model, the transformer, threw recurrence away completely and built a translator from attention and simple feed-forward layers. It beat the best translation systems of the time while training in a fraction of the time, because every position in a sentence could be processed in parallel.

YearModelWhat it showed
2017TransformerAttention alone beats recurrent networks at translation
2018GPT (OpenAI) and BERT (Google)Pretrain one transformer on huge amounts of text, then adapt it to many tasks
2019GPT-21.5 billion parameters writing convincing paragraphs
2020GPT-3175 billion parameters, learning new tasks from a few examples in the prompt
2020Vision Transformer (ViT)The same architecture classifies images, treating patches as tokens
2021AlphaFold 2Attention-based networks predict the 3D shapes of proteins
2022ChatGPTA transformer tuned to follow instructions reaches an estimated 100 million users in about two months

This lesson takes the architecture apart, piece by piece.

Giving attention a sense of order

Attention compares every token with every other token, but nothing in the calculation knows where a token is. Shuffle the words and every token gets exactly the same weights, so "dog bites man" and "man bites dog" would look identical.

The fix is to add a positional encoding to each token's embedding before the first layer. The original transformer used waves: position p gets a vector whose numbers are sines and cosines of p at different frequencies.

Sinusoidal positional encoding

number 2i of the vector for position p is sin(p ÷ 100002i/d), and number 2i + 1 is cos(p ÷ 100002i/d), where d is the length of the vector

Sinusoidal positional encodingLeft: a grid of 20 rows, positions 0 to 19, by 24 columns, dimensions 0 to 23, coloured blue for minus 1, white for 0 and pink for plus 1. The left-hand columns alternate colour quickly down the rows; the right-hand columns hardly change. Right: four of the columns drawn as waves against position: dimension 0 in pink repeats about every 6 positions, dimension 2 in violet every 13 or so, dimension 4 in blue more slowly, and dimension 8 in teal is almost flat. Together they give every position a different pattern.Sinusoidal positional encoding: a unique wave pattern for every positiondimension →08162305101519position ↓blue −1, white 0, pink +1-101051015positiondimension 0: fastdimension 2dimension 4dimension 8: slow
Like the hands of a clock: fast waves tell nearby positions apart, slow waves tell distant ones apart.

The first numbers oscillate quickly and the later ones slowly, like the second, minute and hour hands of a clock. Every position gets its own pattern, and nearby positions get similar patterns.

GPT-2 took a simpler route and learned a position vector for each of its 1,024 positions. Many recent models use rotary position embeddings (RoPE), which rotate each query and key by an angle that depends on its position, so the score between two tokens depends on how far apart they are.

Inside a transformer block

A transformer is a stack of identical blocks. Each block has two sublayers, and each sublayer is wrapped in a residual connection and a normalisation step:

A transformer blockA tall diagram read from bottom to top. Tokens The, cat, sat enter a blue block, token embeddings, then a positional encoding is added. A dashed violet box marked times N, 12 in GPT-2 small and 96 in GPT-3, contains: multi-head self-attention, where tokens exchange information, about 4 d squared parameters; add and norm; a feed-forward network that processes each token on its own, d to 4d to d, about 8 d squared parameters; and add and norm again. Amber residual connections run around the right side of each sublayer from its input to its add and norm. Above the stack, a linear unembedding layer gives a score for every vocabulary token and a softmax turns the scores into next-token probabilities, shown as bars for on, down and still.Inside a transformer: a stack of identical blocksThecatsatToken embeddings+positional encoding× N12 in GPT-2 small96 in GPT-3Multi-head self-attentionAdd & normFeed-forward networkAdd & normLinear: unembedsoftmaxondownstilla score for every token in the vocabularyprobabilities for the next tokeneach token on its own: d → 4d → dabout 8 × d² parameterstokens exchange informationabout 4 × d² parametersadd the input back, then rescaleone vector of d numbers per tokenresidual connection
Attention, then a feed-forward network, each wrapped in a residual connection and normalisation, stacked N times.
  1. Multi-head self-attention: the tokens exchange information.
  2. Add and normalise: add the sublayer's input back onto its output (the residual connection from Level 8's ResNets), then apply layer normalisation, which rescales each token's vector to a mean of 0 and a standard deviation of 1.
  3. Feed-forward network: the same small two-layer network, applied to every token separately. It widens each vector to 4 × dmodel numbers, applies an activation such as ReLU or GELU, and narrows it back.
  4. Add and normalise again.

The output has exactly the same shape as the input: one vector of dmodel numbers for each token. That is what lets blocks stack. GPT-2 small stacks 12 of them, and GPT-3 stacks 96.

The residual stream

A helpful way to picture a transformer is as a residual stream. Each token has a lane, a vector of dmodel numbers flowing up through the network, and every sublayer reads from the stream and adds its result back in.

The residual streamFour translucent blue lanes rise from the tokens The, cat, sat and on, with dashes flowing upward along each. Two layers cross the lanes. In each, a violet attention band carries curved arrows from earlier lanes to later ones: attention is the only place information moves between lanes. Above each band, every lane passes through its own pink feed-forward box, marked with a plus sign because each sublayer adds its result into the stream. At the top, the lane for the last token, on, leads to the prediction of the next token, the.The residual stream: one lane per token, flowing upwardThecatsatonFF+FF+FF+FF+layer 1FF+FF+FF+FF+layer 2next token: “the”attention: the only placeinformation moves between lanesfeed-forward: each laneprocessed on its own+ every sublayer adds itsresult into the streamthe last lane ends up holdingwhat is needed to predictthe next token
Attention moves information between tokens; feed-forward layers work on each token; everything is added into the stream.
  • Attention is the only place where information moves between lanes, from one token to another.
  • The feed-forward layers work on each lane on its own. Research suggests that much of a model's factual knowledge is stored in their weights.

By the top of the stack, the vector in the last token's lane holds everything needed to predict what comes next.

From vectors to the next word

After the last block, each token's vector is multiplied by an unembedding matrix with one column for every token in the vocabulary. That gives a score, called a logit, for every possible next token, and softmax turns the logits into probabilities, exactly as in Level 9. Many models reuse the embedding matrix here (weight tying), so the same numbers turn tokens into vectors at the bottom and vectors back into tokens at the top.

Here is where every one of GPT-2 small's parameters lives (dmodel = 768, 12 blocks, 50,257 tokens, 1,024 positions):

PartCalculationParameters
Token embeddings50,257 × 76838,597,376
Position embeddings1,024 × 768786,432
Attention, per block4 × 7682 weights + 4 × 768 biases2,362,368
Feed-forward, per block8 × 7682 weights + 5 × 768 biases4,722,432
Two layer norms, per block4 × 7683,072
All 12 blocks12 × 7,087,87285,054,464
Final layer norm2 × 7681,536
Total124,439,808

About two thirds of the parameters are in the blocks, and two thirds of each block is its feed-forward network. Attention moves information around; the feed-forward layers do most of the storing.

Three families of transformer

The same block is used in three different arrangements:

FamilyAttentionTrained toExamplesGood at
Encoder-onlyFull: every token sees every tokenFill in hidden (masked) wordsBERT (2018)Understanding: classifying, searching, tagging
Encoder-decoderEncoder full; decoder masked, plus cross-attentionTurn one sequence into anotherThe 2017 transformer, T5 (2019)Translating, summarising
Decoder-onlyMasked: each token sees only earlier tokensPredict the next tokenThe GPT series and most chatbotsGenerating text, code and conversation
Three families of transformerThree cards. Encoder-only, in blue: a 5 by 5 grid fully coloured, because every token sees every token both ways; trained to fill in hidden words; BERT, 2018; good at understanding tasks such as classifying and searching. Encoder-decoder, in violet: a full encoder grid and a lower-triangle decoder grid joined by an amber cross-attention arc; the 2017 transformer and T5, 2019; good at translating and summarising. Decoder-only, in pink: a lower-triangle grid, the causal mask, where each token sees only earlier tokens; trained to predict the next token; the GPT series and most chatbots; good at generating text and code.Three families built from the same blockEncoder-onlyfull attentionsees every token, both waystrained to fill in hidden wordsBERT (2018)good at understanding:classifying, searchingEncoder-decoderencoderdecodercrossencoder sees everything; thedecoder is masked and looksback with cross-attention2017 transformer, T5 (2019)good at translating, summarisingDecoder-onlycausal maskeach token sees only earliertokens: a causal masktrained to predict the next tokenthe GPT series, most chatbotsgood at generating text and code
The masks are the difference: full attention for understanding, causal attention for generating.

Decoder-only models turned out to be the most general, because almost any task can be written as text in, text out: translation is "Translate into French: …", and classification is "Is this review positive or negative? …".

Why transformers won

  • Parallel training: a whole sequence is processed in one pass of matrix multiplications, which GPUs are built for. An RNN has to go one step at a time.
  • Short paths: any token reaches any other token in one attention step, so long-range connections are easy to learn.
  • They scale: performance kept improving as models, data and computing power grew, as Level 11 explores.
  • One architecture for everything: text, images, audio, protein sequences and robot actions can all be turned into sequences of tokens.

The Vision Transformer shows how far the idea stretches. It cuts an image into square patches and treats each patch as a token:

A Vision TransformerA 12 by 12 pixel picture of an orange cat on a blue background is cut by white lines into a 3 by 3 grid of patches, each 4 by 4 pixels. The nine patches are laid out in a row as tokens, each with its position added, after an extra amber class token. Arrows lead from every token up into a violet transformer encoder, the same kind of blocks used for text, and from the class token's output to the prediction, cat. A real Vision Transformer cuts a 224 by 224 image into 16 by 16 patches, giving 196 tokens.A Vision Transformer reads an image as a sequence of patches12 × 12 pixelscut into 9 patchesclsclass+ pos 1+ pos 2+ pos 3+ pos 4+ pos 5+ pos 6+ pos 7+ pos 8+ pos 9Transformer encoder: the same blocks used for text“cat”predictionA real ViT cuts a 224 × 224 image into 16 × 16 patches: 196 tokens.
Patches play the part of words, so the same architecture reads images.

The weakness is cost. Every token attends to every token, so the attention matrix grows with the square of the number of tokens:

The cost of attentionLeft: three square grids of coloured cells at the same cell size. 4 tokens need a 4 by 4 grid, 16 scores; 8 tokens need 64 scores; 16 tokens need 256 scores. Double the tokens, four times the scores. Right: a curve of the number of scores against context length rising ever more steeply: 8 thousand tokens need about 0.06 billion scores, 32 thousand about 1 billion, and 128 thousand about 16.4 billion, per head, per layer.Attention's cost grows with the square of the number of tokens4 tokens16 scores8 tokens64 scores16 tokens256 scoresDouble the tokens, four times the scores.0510150326496128context length, thousands of tokensbillions of scores8k32k128k8k tokens: 0.06 billion32k tokens: 1 billion128k tokens: 16.4 billionper head, per layer, for every forward pass
This square law is why long contexts are expensive, and why so much research goes into faster attention.

Hands-on: a transformer from scratch

Positional encodings

Python
import math

def positional_encoding(pos, d_model):
    pe = []
    for i in range(d_model // 2):
        angle = pos / 10000 ** (2 * i / d_model)
        pe += [math.sin(angle), math.cos(angle)]
    return pe

print("pos  " + " ".join(f"{'d' + str(i):>5}" for i in range(8)))
for pos in range(6):
    print(f"{pos:3}  " + " ".join(f"{v:5.2f}" for v in positional_encoding(pos, 8)))

print()
here = positional_encoding(10, 16)
for gap in [0, 1, 2, 4, 8, 16]:
    there = positional_encoding(10 + gap, 16)
    sim = sum(a * b for a, b in zip(here, there))
    print(f"position 10 against position {10 + gap:2}: dot product {sim:5.2f}")

Column d0 changes fast and d6 barely moves, like clock hands. The dot product falls as positions get further apart, which is how attention can tell near from far.

A stack of transformer blocks

Each block below is the real recipe: layer norm, masked self-attention, add; layer norm, feed-forward, add. Each block has its own random weights.

Python
import math, random

random.seed(7)
def rand_matrix(rows, cols, scale=0.5):
    return [[random.uniform(-scale, scale) for _ in range(cols)] for _ in range(rows)]
def matmul(A, B):
    return [[sum(a * b for a, b in zip(row, col)) for col in zip(*B)] for row in A]
def add(A, B):
    return [[a + b for a, b in zip(ra, rb)] for ra, rb in zip(A, B)]
def softmax(xs):
    m = max(xs)
    e = [math.exp(x - m) for x in xs]
    return [v / sum(e) for v in e]
def layer_norm(X):
    out = []
    for row in X:
        mean = sum(row) / len(row)
        sd = math.sqrt(sum((v - mean) ** 2 for v in row) / len(row) + 1e-5)
        out.append([(v - mean) / sd for v in row])
    return out
def attention(X, W_Q, W_K, W_V, W_O):
    Q, K, V = matmul(X, W_Q), matmul(X, W_K), matmul(X, W_V)
    d = len(Q[0])
    A = [softmax([sum(q * k for q, k in zip(Q[i], K[j])) / math.sqrt(d) if j <= i else -math.inf
                  for j in range(len(X))]) for i in range(len(X))]
    return matmul(matmul(A, V), W_O)
def feed_forward(X, W1, W2):
    hidden = [[max(0.0, v) for v in row] for row in matmul(X, W1)]   # ReLU
    return matmul(hidden, W2)

d_model, d_ff = 4, 16
def make_block():
    return {"attention": [rand_matrix(d_model, d_model) for _ in range(4)],
            "feed_forward": [rand_matrix(d_model, d_ff), rand_matrix(d_ff, d_model)]}

def block(X, p):
    X = add(X, attention(layer_norm(X), *p["attention"]))        # tokens share information
    X = add(X, feed_forward(layer_norm(X), *p["feed_forward"]))  # each token on its own
    return X

X = rand_matrix(3, d_model, 1.0)        # 3 tokens, 4 numbers each
for n, p in enumerate([make_block() for _ in range(3)], start=1):
    X = block(X, p)
    print(f"after block {n}: {len(X)} tokens x {len(X[0])} numbers, first token",
          [round(v, 2) for v in X[0]])

The shape never changes: 3 tokens of 4 numbers go in, and 3 tokens of 4 numbers come out, which is why the blocks can be stacked as deep as you like.

Counting GPT-2's parameters

Python
def gpt2_parameters(n_layers, d, vocab=50257, context=1024):
    embeddings = vocab * d + context * d
    attention = 4 * d * d + 4 * d          # W_Q, W_K, W_V, W_O and their biases
    feed_forward = 8 * d * d + 5 * d       # d -> 4d -> d, with biases
    norms = 4 * d                          # two layer norms, each a scale and a shift
    return embeddings + n_layers * (attention + feed_forward + norms) + 2 * d

for name, layers, d in [("small", 12, 768), ("medium", 24, 1024),
                        ("large", 36, 1280), ("XL", 48, 1600)]:
    print(f"GPT-2 {name:6} {layers:2} blocks, d = {d:4}: {gpt2_parameters(layers, d):>13,} parameters")

These are exactly the sizes of the four GPT-2 models released in 2019.

Try this

  1. Remove the two add(X, ...) calls in the block, keeping only the sublayer outputs. Stack 12 blocks instead of 3. What happens to the numbers?
  2. GPT-3 has 96 blocks with d = 12,288 and the same 50,257-token vocabulary, with 2,048 positions. Use the function to estimate its size. How close is it to 175 billion?

Level check

  • Explain why attention needs positional encoding, and describe two ways of adding it
  • Draw and label a transformer block, including the residual connections
  • Explain what layer normalisation and the feed-forward network do
  • Describe the residual stream and which sublayer moves information between tokens
  • Count the parameters of a transformer from its sizes
  • Compare encoder-only, encoder-decoder and decoder-only transformers
  • Explain why transformers replaced RNNs, and the cost of long contexts

Key terms you must be able to define

Transformer
A neural network built from stacked blocks of attention and feed-forward layers, introduced in 2017.
Positional encoding
A vector added to each token's embedding that tells the model where the token is.
Transformer block
Multi-head attention and a feed-forward network, each with a residual connection and layer normalisation.
Feed-forward network
Two linear layers with an activation between them, applied to each token separately.
Layer normalisation
Rescaling each token's vector to mean 0 and standard deviation 1, then applying a learned scale and shift.
Residual stream
The per-token vectors flowing up through the network, which every sublayer reads from and adds to.
Logit
The raw score for one vocabulary token, before softmax turns the scores into probabilities.
Weight tying
Reusing the embedding matrix as the unembedding matrix that produces the logits.
Encoder-only
A transformer in which every token sees every other, such as BERT, used for understanding tasks.
Decoder-only
A transformer with masked attention trained to predict the next token, such as GPT.
Vision Transformer (ViT)
A transformer that classifies images by treating patches of pixels as tokens.

Flashcards

DefineTransformer
AnswerA neural network built from stacked blocks of attention and feed-forward layers, introduced in 2017.
DefinePositional encoding
AnswerA vector added to each token's embedding that tells the model where the token is.
DefineTransformer block
AnswerMulti-head attention and a feed-forward network, each with a residual connection and layer normalisation.
DefineFeed-forward network
AnswerTwo linear layers with an activation between them, applied to each token separately.
DefineLayer normalisation
AnswerRescaling each token's vector to mean 0 and standard deviation 1, then applying a learned scale and shift.
DefineResidual stream
AnswerThe per-token vectors flowing up through the network, which every sublayer reads from and adds to.
DefineLogit
AnswerThe raw score for one vocabulary token, before softmax turns the scores into probabilities.
DefineWeight tying
AnswerReusing the embedding matrix as the unembedding matrix that produces the logits.

Go further: notes for future AI engineers

Pre-norm and post-norm

The 2017 transformer normalised after each residual addition (post-norm). Deep post-norm stacks are hard to train without carefully warming up the learning rate, so most modern models normalise the input of each sublayer instead (pre-norm), as the code above does. That leaves the residual stream itself untouched: a clean path for gradients to travel down, exactly as in a ResNet. Many models also swap layer norm for the simpler RMSNorm, and ReLU for GELU or SwiGLU.

The KV cache

When generating, a decoder-only model would naively recompute the keys and values of every earlier token at every step. Because of the mask, those never change, so they are stored in a KV cache and only the newest token's query, key and value are computed. Each new token becomes cheap, but the cache grows with the context and is a large part of the memory needed to serve a model to many users.

Mixture of experts

Some large models replace each feed-forward network with many smaller expert networks and a router that sends each token to just one or two of them. The model can hold far more parameters than it uses on any single token, gaining knowledge without a matching rise in the computation per token.

Misconceptions to avoid

Avoid these
  • Thinking a transformer reads text left to right like an RNN. It processes every position at once; only the mask limits what each position can see.
  • Forgetting positional information. Without it, attention cannot tell "dog bites man" from "man bites dog".
  • Believing every transformer generates text. Encoder-only models such as BERT are built for understanding, not generation.
  • Thinking the feed-forward layers mix information between tokens. They work on each token on its own; only attention moves information between tokens.
  • Assuming long contexts are cheap. The attention matrix grows with the square of the number of tokens.
Fun fact

The 2017 paper "Attention Is All You Need" listed its eight authors with a footnote saying that they had contributed equally and that the order was random. Its title has been borrowed by many later papers, all called something "Is All You Need".

Knowledge check

0 of 10 answered
1What did the 2017 transformer remove that earlier translation models relied on?
2Why does a transformer need positional encoding?
3What does the feed-forward network in a transformer block do?
4What does a residual connection do in a transformer block?
5Why must a block's output have the same shape as its input?
6Which family of transformer does BERT belong to?
7Which kind of transformer is trained to predict the next token using masked attention?
8How does a Vision Transformer read an image?
9A context grows from 1,000 to 4,000 tokens. Roughly how many times bigger does the attention matrix get?
10In GPT-2 small, which part holds the most parameters?
Score 0 / 10

Check you could explain this

11 marks
1Describe the structure of one transformer block.4 marks
Describe

Mark scheme0 / 4
  • LMulti-head self-attention, in which tokens exchange information
  • LA residual connection adds each sublayer's input to its output
  • LLayer normalisation rescales each token's vector
  • LA feed-forward network is applied to each token separately
  • LThe output has the same shape as the input, so blocks can be stacked
Model answer

A transformer block has two sublayers. The first is multi-head self-attention, in which every token gathers information from the other tokens. The second is a feed-forward network, two linear layers with an activation between them, applied to each token's vector separately. Each sublayer is wrapped in a residual connection that adds its input to its output, and in layer normalisation, which rescales each token's vector to mean 0 and standard deviation 1. The output has the same shape as the input, one vector per token, so many identical blocks can be stacked.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.

Think this answer or mark scheme is wrong? Report it

2Explain why transformers replaced recurrent neural networks for language tasks.4 marks
Explain

Mark scheme0 / 4
  • LTransformers process every token in parallel, using matrix multiplications that suit GPUs
  • LRNNs must process tokens one after another, which is slow to train
  • LAttention connects any two tokens directly, in one step
  • LRNNs forget distant words because of vanishing gradients
  • LTransformers keep improving as they are scaled up with more data and computing power
Model answer

An RNN must read a sequence one token after another, because each hidden state depends on the one before, so training cannot be spread across a GPU and is slow. A transformer processes every token at once with large matrix multiplications, which GPUs do extremely quickly, so it can be trained on far more data. Attention also connects any two tokens directly in a single step, whereas in an RNN information from a distant word has to pass through many steps and gradients vanish, so it is forgotten. Because transformers train efficiently, they could be scaled up, and their performance kept improving with size.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.

Think this answer or mark scheme is wrong? Report it

3Compare encoder-only and decoder-only transformers.3 marks
Compare

Mark scheme0 / 3
  • LIn an encoder-only model every token attends to every other token / full attention
  • LEncoder-only models such as BERT are trained to fill in masked words and used for understanding tasks such as classification
  • LDecoder-only models use a causal mask, so each token sees only earlier tokens
  • LDecoder-only models such as GPT are trained to predict the next token and used for generation
Model answer

Both are built from the same transformer blocks. In an encoder-only model such as BERT, every token can attend to every other token, before and after it, and the model is trained by filling in words that have been hidden, so it is suited to understanding tasks such as classifying text or searching. A decoder-only model such as GPT uses a causal mask, so each token sees only the tokens before it, and it is trained to predict the next token, which makes it suited to generating text one token at a time.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.

Think this answer or mark scheme is wrong? Report it

Machine mark 0 / 11