Vocabulary for this course

The terms the chapters assume, in plain words. You can open this from any chapter.

attention
A weighted blend of value rows, with weights decided by how well each query matches each key.
attention map
The table of scores showing how much each position attended to every other position.
causal mask
A rule that blocks each position from seeing later positions, so predictions can only use the past.
dimension
One axis of a list or grid of numbers; its length is how many values fit along that axis.
distribution
The pattern of how often each possible value appears, or how likely each one is.
dot product
Multiply matching numbers in two lists and add the results; a large total means the lists point the same way.
embedding
A learned list of numbers that stands for a token, with similar tokens placed near each other.
GPU
A processor built for many small calculations at once, which is why matrix work runs well on it.
gradient
A list of slopes, one per number, saying how much each nudge changes the result.
hard pointer
A choice that sends all the weight to one position, instead of spreading it across several.
head
One parallel slice of attention, with its own projections; a layer runs many so it can track different relations at once.
key
What a position advertises it can offer, compared against every query to decide who receives attention.
key axis
The direction in the key vectors whose width decides how far the scores are divided down.
layer
One stage of a model that reads the running vector, transforms it and passes it on.
layer norm
A per-position rescale that keeps the residual stream at a steady size before the next block.
logits
The raw scores a model produces before softmax turns them into probabilities.
matrix
A grid of numbers arranged in rows and columns, used to transform a list into another list.
negative infinity
A value smaller than every real number, used to mark a score that must never be chosen.
one-hot
A vector with a single one and zeros elsewhere, meaning all the weight sits on one choice.
output projection
The learned matrix applied after attention, which turns the mixed values back into the model's width.
parameter
A number inside a model that training adjusts, rather than an input it reads.
positional encoding
Extra numbers added to token embeddings so the model can tell which position each one came from.
projection
A learned matrix that turns a list of numbers into a different list, often shorter.
query
What a position is looking for, compared against every key to decide where to take information from.
residual stream
The running vector each block reads from and adds its output back into.
retrieval layer
A layer whose job is to pull specific stored information into the current position.
saturating
A score so large that the softmax gives almost all the weight to one position.
scale
The step that divides the scores by the square root of the key width, so they stay in a workable range.
score matrix
The grid holding every query's score against every key, one row per position.
soft alignment
Matching by degree rather than by a single choice, so several positions can contribute a little.
softmax
A rule that turns a list of scores into positive weights that sum to one.
token
A chunk of text — a word, part of a word, or a character — that the model treats as one unit.
value
The content a position passes on when attention selects it.
variance
The average squared distance of values from their average, so a spread-out set scores higher.
vector
An ordered list of numbers, where each position is one measured property.
weighted sum
Adding values together with different shares, where the shares come from the attention scores.
weights
The numbers a model multiplies inputs by before adding the results together.

Transformers from the ground up

Capstone: a tiny attention block

One block, end to end: layer norm, causal multi-head attention, residual, layer norm, feed-forward, residual. Run it on three tokens and check that the first position cannot see the third.

Part 10 of 10

Advanced18 min readBack to Courses

The block in one diagram

A transformer block is two sublayers, each with a residual connection around it. A residual connection adds a sublayer’s output back to its input. The first sublayer normalises the stream, runs multi-head self-attention and adds the result back. The second normalises the updated stream, runs the feed-forward network and adds that result back. The output has the same shape as the input. The block can therefore be stacked without any reshaping.

The capstone builds exactly that. It uses four-dimensional tokens, two heads of width two, a hidden layer of width eight and a causal mask. The numbers are small enough to print and check by hand. The structure is the same one that appears in a model with a hundred layers and a width of thousands. Only the sizes and a few details change.

The two residual adds are not decoration. The first keeps the token’s identity while attention writes context onto it. The second keeps the context while the feed-forward block transforms it. Remove either and the block becomes a replacement, not an update. A replacement is much harder to stack and much easier to destabilise. The normalisation before each branch keeps the update at a workable scale without touching the stream itself.

What to verify, not only run

A block that runs is not necessarily correct. Three checks catch most mistakes. The output shape must equal the input shape. A causal model must give the same first-position output when only a later token changes. The residual stream should also preserve a path for the input. The output should therefore not be at a wildly different scale from the input, unless the updates are large.

The first check catches a projection with the wrong width. The second catches a mask applied after the softmax, or not at all. The third catches a missing residual or a normalisation on the wrong axis. None of these checks needs a trained model. They belong in a test, not in a training run.

The same block, stacked

from torch import nn

layer = nn.TransformerEncoderLayer(
    d_model=64,
    nhead=4,
    dim_feedforward=256,
    batch_first=True,
    norm_first=True,
)
encoder = nn.TransformerEncoder(layer, num_layers=6)
out = encoder(x)
print(out.shape)  # (batch, tokens, 64)

One block, end to end

Run the block on three tokens, then change the third input row and confirm the first output row is unchanged because of the causal mask.

Output
Click "Run" to execute your code

Reading the output

The block returns a vector per token, not a prediction. To turn it into a language model, apply a final layer norm. A linear head then maps each vector to vocabulary logits. The last position’s logits are the distribution for the next token. During training, every position’s logits are compared with the shifted targets.

The block is also not a model until its weights are trained. Random projections produce a valid tensor and no useful language. The capstone shows the plumbing: shapes, masks, residuals and normalisation. The learning is a separate loop. It adjusts the numbers while the plumbing stays fixed.

The final norm matters more than it looks. The residual stream can grow with depth, and the output head expects a vector at a consistent scale. A missing final norm produces logits that are too large. The softmax then becomes nearly one-hot. The model looks confident before it has learned anything useful. The head itself is usually a single matrix, sometimes tied to the input embeddings. It is the only part that knows the vocabulary size.

Keep a causal test in the repository. Change the last token of a fixed input, run the block, and assert that every earlier position is unchanged. It is fast, needs no labels, and fails loudly when someone edits the mask.

Where the real model differs

Production models stack dozens of these blocks. They widen the stream, replace learned positions with RoPE and often replace the feed-forward with a gated variant. They use grouped-query attention to shrink the inference cache. They use mixed precision to fit the weights, and dropout or weight decay to regularise. Those are changes to the parts, not to the skeleton.

The skeleton is what makes the rest legible. Trace a token through one block and a stack becomes repetition. A training run is that repetition plus a loss and an optimiser. The details matter. They are easier to place when the small version is already in your head.

The same skeleton explains why architecture changes are often small in code and large in effect. Swapping the activation, moving the norm or changing the head count touches a few lines. It changes the training landscape and the inference cost. The capstone is a place to make those changes and watch the shapes and the causality test. A training run would hide the mistake in a loss curve.

A test that catches a leak

Run both sequences with and without the mask, then change the second token and confirm the first output still cannot move.

Output
Click "Run" to execute your code

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

In a pre-norm block, what happens first?