Reference

Glossary

Every symbol, operator and term the course uses, 113 in all, in the order you meet them. Each card says how to read it, what it means, and where it first appears. New to the maths? Start with section 1.0, which introduces scalars, vectors, matrices and tensors.

Module 0 · Start Here: What an LLM Does

∣V∣|V|

Read "the size of V". Single bars around a set mean "how many items it has", so |V| is the number of tokens in the vocabulary.

VV is the vocabulary: the fixed list of tokens the tokenizer can produce. ∣V∣|V| counts them. It is 50,257 for GPT-2, 32,000 for LLaMA-2 and 256,000 for Gemma.

Do not confuse it with two similar notations. ∥v∥\|\mathbf{v}\| (double bars) is the length of a vector. ∣x∣|x| on a single number is its absolute value, so ∣−3∣=3|-3| = 3.

Example
V={the,cat,sat}  ⟹  ∣V∣=3V = \{\text{the}, \text{cat}, \text{sat}\} \;\Longrightarrow\; |V| = 3

A toy vocabulary of three tokens.

θ←θ−η∇θL\theta \leftarrow \theta - \eta \nabla_\theta \mathcal{L}

Training

Concept

The process that sets a model's weights. It shows the model examples, measures how wrong it is with the loss, and nudges every weight to make the loss smaller. Repeated millions of times.

Each step runs a batch through the model (the forward pass), computes the loss, works out how the loss changes with each weight (backpropagation, section 2.5), and moves every weight a small step downhill. The step size is the learning rate η\eta.

Using a trained model without changing it is called inference. Sections 10.2 and 21.5 cover how large models are trained.

Example
w=0.50,  ∂L∂w=2.0,  η=0.1  ⟹  w←0.50−0.1⋅2.0=0.30w = 0.50,\; \frac{\partial \mathcal{L}}{\partial w} = 2.0,\; \eta = 0.1 \;\Longrightarrow\; w \leftarrow 0.50 - 0.1 \cdot 2.0 = 0.30

One weight, one step. The loss would rise if w grew, so w shrinks.

eze^{z}

Read "e to the z" (also written exp(z)). It raises e ≈ 2.718 to the power z. The result is always positive: e⁰ = 1, and it shrinks toward 0 as z becomes very negative.

Two facts explain how the course uses it:

  • ez>0e^{z} > 0 for every real zz. So softmax can never output a negative probability.
  • ea+b=eaebe^{a+b} = e^a e^b. So subtracting the same constant from every input of a softmax multiplies the top and bottom of the fraction by the same factor, and it cancels exactly.

As zz goes to −∞-\infty, eze^{z} goes to 00. That is how the causal mask works: a score of −∞-\infty becomes a weight of exactly zero.

Example
e0=1,e1≈2.718,e−5≈0.0067e^{0} = 1, \quad e^{1} \approx 2.718, \quad e^{-5} \approx 0.0067

Positive in every case; large negative inputs give tiny positive outputs.

log⁡\log

Logarithm

Function

Read "log of x". It undoes the exponential: log(eᶻ) = z. It turns products into sums, which is why loss functions use it.

log⁡(ab)=log⁡a+log⁡b\log(ab) = \log a + \log b. A sentence's probability is a product of hundreds of small numbers. Multiplied directly in floating point, the result gets so small it rounds to zero (called underflow). Taking the log turns the product into a sum of moderate negative numbers, which computers handle easily.

ln⁡\ln is the natural log, the log to base ee. In machine learning, log⁡\log almost always means ln⁡\ln as well. A probability is at most 1, so its log is zero or negative. That is why losses put a minus sign in front: it makes the loss a positive number to minimize.

Example
log⁡(0.5×0.1)=log⁡0.5+log⁡0.1≈−0.69+(−2.30)≈−3.00\log(0.5 \times 0.1) = \log 0.5 + \log 0.1 \approx -0.69 + (-2.30) \approx -3.00

Natural log. A product of probabilities becomes a sum of their logs.

∑\sum

∑ — sum

Operator

Read "the sum of". The big sigma is a loop that adds: the counter starts at the value below it and stops at the value above it.

∑i=1dxi\sum_{i=1}^{d} x_i means: set ii to 1 and take x1x_1, set ii to 2 and take x2x_2, and so on up to xdx_d, then add them all.

In Python it is sum(x[i] for i in range(1, d + 1)). When there is a set or condition below instead of a start value, such as ∑i∈S\sum_{i \in S}, it means "add one term for every member of SS". A bare ∑i\sum_i means "over every value of ii".

Example
∑i=14i2=1+4+9+16=30\sum_{i=1}^{4} i^2 = 1 + 4 + 9 + 16 = 30

The counter i takes the values 1, 2, 3, 4; each is squared, then the four results are added.

xix_i

Read x_i as "x sub i" or "x i". A small lowered letter picks out one item: the i-th entry of a vector, or the i-th vector in a sequence.

Which of the two depends on the letter's font. xix_i (plain) is one number inside a vector; xi\mathbf{x}_i (bold) is the whole vector for token ii. Two subscripts pick an entry of a matrix: MijM_{ij} is the entry in row ii, column jj.

By habit, ii and jj count features or positions, tt counts time steps, ll counts layers, and mm and nn are positions in RoPE. Some subscripts are names rather than counters, such as the "model" in dmodeld_{\text{model}}.

Example
M=[5729]  ⟹  M12=7M = \begin{bmatrix} 5 & 7 \\ 2 & 9 \end{bmatrix} \;\Longrightarrow\; M_{12} = 7

Row 1, column 2.

dmodeld_{\text{model}}

Read "d model". It is how many numbers represent one token inside the network: 768 for GPT-2 small, 4096 for LLaMA-3 8B.

It is the one size that stays the same through every layer. Every vector in the residual stream, and every sub-layer's input and output, has dmodeld_{\text{model}} numbers. That is what lets the residual addition x+SubLayer⁡(x)\mathbf{x} + \operatorname{SubLayer}(\mathbf{x}) work at every layer: you can only add two vectors of the same length.

The weight matrices in each layer are roughly dmodel×dmodeld_{\text{model}} \times d_{\text{model}} in size, so a layer's parameter count grows with dmodel2d_{\text{model}}^2. Doubling the width roughly quadruples it.

L\mathcal{L}

Read "L" or "the loss". The curly L is the single number that measures how wrong the model is. Training adjusts the weights to make it small.

L(θ)\mathcal{L}(\theta) is a function of the model's parameters θ\theta: plug in the current weights and get back a score for how wrong the model is on the training data. Training runs gradient descent on this number, repeatedly nudging the weights in the direction that lowers it.

A subscript names which loss: LNLL\mathcal{L}_{\text{NLL}} (negative log-likelihood), LCTC\mathcal{L}_{\text{CTC}} (a loss for speech alignment), Laux\mathcal{L}_{\text{aux}} (the extra balancing term in mixture-of-experts). A model's total loss is often a weighted sum of several of these.

Example
L=−log⁡0.8≈0.22\mathcal{L} = -\log 0.8 \approx 0.22

If the model gave the correct next token probability 0.8, the negative log-likelihood for that token is about 0.22. Probability 1 would give a loss of 0.

Module 1 · Shapes and Linear Algebra

X∈Rm×nX \in \mathbb{R}^{m \times n}

A rectangular table of numbers, with two axes: rows and columns. An m×n matrix has m rows and n columns. Written as a capital letter, such as W.

A matrix has two axes, so two indices pick one entry: XijX_{ij} is row ii, column jj. Its shape is always said rows first: R3×4\mathbb{R}^{3 \times 4} is 3 rows by 4 columns, 12 numbers in all.

Matrices play two roles in a transformer:

  • Data. A sentence of NN tokens, each a vector of width dmodeld_{\text{model}}, is stacked into an N×dmodelN \times d_{\text{model}} matrix, one token per row.
  • Weights. A learned WW turns vectors of one width into another by matrix multiplication.

In PyTorch a 3×4 matrix has shape (3, 4).

Example
X=[102531040221]∈R3×4  ⟹  X23=0X = \begin{bmatrix} 1 & 0 & 2 & 5 \\ 3 & 1 & 0 & 4 \\ 0 & 2 & 2 & 1 \end{bmatrix} \in \mathbb{R}^{3 \times 4} \;\Longrightarrow\; X_{23} = 0

Row 2, column 3. Each row could be one token's vector.

Rd\mathbb{R}^{d}

Read "R d" or "R to the d". It is the set of all lists of d real numbers, so "x ∈ ℝ^d" says x is a vector of d numbers.

The raised dd is the length of the list, not a power. R768\mathbb{R}^{768} is every possible vector of 768 numbers. Writing x∈R768\mathbf{x} \in \mathbb{R}^{768} tells you the shape of x\mathbf{x} (768 numbers) and nothing about what those numbers are.

When the raised part has two sizes joined by ×\times, it describes a matrix: Rm×n\mathbb{R}^{m \times n} is every table with mm rows and nn columns. The course states every tensor shape this way.

Example
x∈R4  ⟹  x=[0.2, −1.7, 3.0, 0.5]\mathbf{x} \in \mathbb{R}^{4} \;\Longrightarrow\; \mathbf{x} = [0.2,\, -1.7,\, 3.0,\, 0.5]

Four slots, each holding any real number. In PyTorch this is a tensor of shape (4,).

R\mathbb{R}

Read "R" or "the reals". It is the set of all ordinary numbers: whole, negative, fractions and decimals.

The double-struck R\mathbb{R} ("blackboard bold") is the set of real numbers, such as −3-3, 00, 17\tfrac{1}{7}, π\pi and 2.718…2.718\ldots. It does not include complex numbers. Every weight and activation in a model is a real number; a computer's floating-point numbers are a finite approximation of them.

Related sets you will meet: N\mathbb{N} (counting numbers 0,1,2,…0, 1, 2, \dots or 1,2,3,…1, 2, 3, \dots depending on the author), Z\mathbb{Z} (all integers, including negatives), and {0,1}\{0,1\} (only zero and one, as in a one-hot vector).

Example
w∈Rw \in \mathbb{R}

w is a single real number, such as 0.37 or -12.

∈\in

Read "is in" or "belongs to". The thing on the left is a member of the set on the right.

a∈Sa \in S says that aa is one of the things in the set SS. In this course it mostly does one job: stating a shape. q∈R64\mathbf{q} \in \mathbb{R}^{64} means "q\mathbf{q} is a vector of 64 real numbers", like a type annotation in code.

It is also used with a written-out set: i∈{0,1,…,∣V∣−1}i \in \{0, 1, \dots, |V|-1\} says ii is one of the whole numbers in that range.

Example
i∈{0,1,…,∣V∣−1}i \in \{0, 1, \dots, |V|-1\}

i is a token id: a whole number from 0 up to one less than the vocabulary size.

(2, 3, 4)(2,\, 3,\, 4)

A tensor's shape lists the size of each axis, in order. (2, 3, 4) has three axes of sizes 2, 3 and 4. Checking shapes is the quickest way to follow a formula.

An axis is one direction you can step along: along a vector, down the rows of a matrix, across its columns. The shape records how many steps each axis has. The course writes a shape in the exponent of R\mathbb{R}, as in R2×3×4\mathbb{R}^{2 \times 3 \times 4}, and PyTorch prints it as torch.Size([2, 3, 4]).

Most operations have a shape rule. Adding two tensors needs the same shape and keeps it. Multiplying an m×nm \times n matrix by an n×pn \times p one needs the inner sizes to agree and gives m×pm \times p. When a formula confuses you, write the shape under each term; a mismatch usually shows where you misread it.

Example
X⏟3×4  W⏟4×2=Y⏟3×2\underbrace{X}_{3 \times 4}\;\underbrace{W}_{4 \times 2} = \underbrace{Y}_{3 \times 2}

The shared 4 disappears; the outer sizes remain.

x∈Rx \in \mathbb{R}

A single number, with no axes. The loss, the learning rate and the temperature are scalars. Written as a plain italic letter, such as x.

A scalar has no axes: there is nothing to index, because there is only one value. Writing x∈Rx \in \mathbb{R} says xx is one real number.

In PyTorch a scalar is a tensor of shape (), an empty shape. Multiplying a vector or matrix by a scalar scales every entry by the same amount.

Example
T=0.7η=0.001L=2.31T = 0.7 \quad \eta = 0.001 \quad \mathcal{L} = 2.31

A temperature, a learning rate and a loss: each is one number.

x∈Rn\mathbf{x} \in \mathbb{R}^{n}

An ordered list of numbers, with one axis. One index picks out one entry. Each token becomes a vector before the model can compute with it.

A vector has one axis, and its length is how many numbers it holds. x∈R4\mathbf{x} \in \mathbb{R}^{4} is a vector of 4 numbers, and x2x_2 is its second entry.

The course writes vectors in bold and, following most transformer code, as rows: a token vector sits on the left of a matrix, as in xW\mathbf{x} W. Geometrically a vector is an arrow from the origin, which is what gives it a length and a direction (section 1.5).

In PyTorch a vector of 4 numbers has shape (4,).

Example
x=[0.2, −1.7, 3.0, 0.5]  ⟹  x3=3.0\mathbf{x} = [0.2,\, -1.7,\, 3.0,\, 0.5] \;\Longrightarrow\; x_3 = 3.0

One axis of length 4. The third entry is 3.0.

x\mathbf{x}

A bold lowercase letter, like x in bold, is a vector (a list of numbers). A plain italic letter is one number. A capital letter is a matrix.

The font tells you what kind of object a letter is:

  • xx: a scalar, which means one number
  • x\mathbf{x}: a vector, a list of numbers
  • XX or WW: a matrix, a 2-D table of numbers

This matters for subscripts. xi\mathbf{x}_i is the whole vector for token ii. xix_i is the ii-th number inside a vector. Only the boldness tells the two apart.

Example
x=[4,7,1]  ⟹  x2=7\mathbf{x} = [4, 7, 1] \;\Longrightarrow\; x_2 = 7

Bold x is the whole list; plain x with subscript 2 is one entry of it (counting from 1 here).

[abcd]\begin{bmatrix} a & b \\ c & d \end{bmatrix}

Square brackets around a grid of numbers show a matrix entry by entry. Each line is a row; each position across a line is a column.

Read a matrix by its shape first: count the rows, then the columns, and say "rows by columns". A matrix with 4 rows and 2 columns is "4 by 2", written 4×24 \times 2. As a weight matrix acting on a row vector, a 4×24 \times 2 matrix turns a 4-number input into a 2-number output. Often the shape is all you need to follow the argument.

(In the LaTeX source, & separates columns and \\ starts a new row.)

Example
[102503]∈R3×2\begin{bmatrix} 1 & 0 \\ 2 & 5 \\ 0 & 3 \end{bmatrix} \in \mathbb{R}^{3 \times 2}

Three rows, two columns: a 3×2 matrix.

Q,K,VQ, K, V

Three learned versions of each token's vector. The query is what the token is looking for, the key is what it offers to others, and the value is what it passes on. W^Q is read "W Q", the matrix that makes queries.

One vector would have to serve as a search term, a search label and the content itself, and those roles would get in each other's way. So the model learns three separate weight matrices and makes three versions of each token:

  • qi=xiWQ\mathbf{q}_i = \mathbf{x}_i W^Q: what am I looking for?
  • ki=xiWK\mathbf{k}_i = \mathbf{x}_i W^K: what do I offer?
  • vi=xiWV\mathbf{v}_i = \mathbf{x}_i W^V: what do I contribute if chosen?

Attention compares every query with every key to get scores, then mixes the values using those scores. The raised QQ, KK, VV are labels, not powers. A fourth matrix, WOW^O, maps the mixed result back to the model's width.

ABAB

Two matrices written side by side, like AB, are multiplied. Each entry of the result is a row of A dotted with a column of B. An (m×n) times an (n×p) gives an (m×p).

Entry (i,j)(i,j) of ABAB is the dot product of row ii of AA with column jj of BB. For that to work, a row of AA must be as long as a column of BB, so the inner sizes must match. Two things to remember:

  • Shapes tell you what happens. xWQ\mathbf{x}W^Q, with x\mathbf{x} of width dmodeld_{\text{model}} and WQW^Q of shape dmodel×dkd_{\text{model}} \times d_k, produces a query of width dkd_k. The shared middle size disappears.
  • Order matters. ABAB and BABA are usually different, and one of them may not even be defined.

Every "projection" in the course is one matrix multiplication. In PyTorch it is A @ B.

Example
[12][3041]=[1⋅3+2⋅41⋅0+2⋅1]=[112]\begin{bmatrix} 1 & 2 \end{bmatrix} \begin{bmatrix} 3 & 0 \\ 4 & 1 \end{bmatrix} = \begin{bmatrix} 1{\cdot}3 + 2{\cdot}4 & 1{\cdot}0 + 2{\cdot}1 \end{bmatrix} = \begin{bmatrix} 11 & 2 \end{bmatrix}

A 1×2 times a 2×2 gives a 1×2.

BB

A group of examples processed at the same time. It adds one axis, of size B, at the front of every tensor. Every example in the batch goes through the same computation.

Hardware is fastest when it does many identical computations at once, so models process several sequences together. A batch of BB sentences, each NN tokens of width dmodeld_{\text{model}}, is one tensor of shape B×N×dmodelB \times N \times d_{\text{model}}.

The examples in a batch never mix, which is why most formulas in the course leave the batch axis out and describe one sequence. In training, each gradient step averages the loss over one batch (section 2.5).

Example
B=8,  N=1024,  dmodel=768  ⟹  8×1024×768B = 8,\; N = 1024,\; d_{\text{model}} = 768 \;\Longrightarrow\; 8 \times 1024 \times 768

Eight sequences of 1,024 tokens, each token a vector of 768 numbers.

RB×N×d\mathbb{R}^{B \times N \times d}

An array of numbers with any number of axes. In code every array is called a tensor: a scalar has 0 axes, a vector 1, a matrix 2. In prose the word usually means 3 or more.

Each extra axis is one more index. A stack of matrices is a 3-axis tensor: a batch of BB sentences, each NN tokens by dmodeld_{\text{model}} numbers, has shape B×N×dmodelB \times N \times d_{\text{model}}. A color image is another: height by width by 3 color channels (section 25.2).

Multiply the sizes to count the numbers: a 2×3×42 \times 3 \times 4 tensor holds 24.

Two meanings of rank. Some texts call the number of axes a tensor's rank or order. Section 20.2 uses rank for something else, the number of independent directions in a matrix. This course says "number of axes" to keep them apart; PyTorch calls it ndim.

Example
X∈R2×3×4  ⟹  2⋅3⋅4=24 numbers\mathcal{X} \in \mathbb{R}^{2 \times 3 \times 4} \;\Longrightarrow\; 2 \cdot 3 \cdot 4 = 24 \text{ numbers}

Two sentences, three tokens each, four numbers per token. PyTorch shape (2, 3, 4).

⊙\odot

Read "a times b, element-wise". Multiply two same-shaped vectors or matrices position by position. This is not matrix multiplication.

(a⊙b)i=aibi(\mathbf{a} \odot \mathbf{b})_i = a_i b_i. The output has the same shape as the inputs. In NumPy and PyTorch it is a * b, while matrix multiplication is a @ b. It is also called the Hadamard product.

It appears wherever each feature gets its own scale: the learned gain γ\boldsymbol{\gamma} in LayerNorm and RMSNorm, and the gate in SwiGLU, where one branch scales the other entry by entry. Some texts write ⊗\otimes for the same thing, though ⊗\otimes can also mean other kinds of product.

Example
[1,2,3]⊙[4,5,6]=[4,10,18][1, 2, 3] \odot [4, 5, 6] = [4, 10, 18]

First times first, second times second, third times third.

dk,dv,dheadd_k, d_v, d_{\text{head}}

Read "d k" and "d v". They are the number of entries in one attention head's key and value vectors, usually d_model divided by the number of heads.

With dmodel=512d_{\text{model}} = 512 and h=8h = 8 heads, dk=dv=512/8=64d_k = d_v = 512 / 8 = 64. Splitting the width this way means multi-head attention costs about the same as one full-width head, while each head can learn to focus on a different kind of relationship.

dkd_k is the width of queries and keys, which must match because they are dotted together. dvd_v is the width of the values. They are usually equal but do not have to be. dheadd_{\text{head}} is another name for the same per-head width.

Example
dk=dmodelh=5128=64d_k = \frac{d_{\text{model}}}{h} = \frac{512}{8} = 64

The original Transformer's sizes.

⊤^\top

Transpose

Operator

Read "A transpose". The raised T flips a matrix so its rows become its columns. On a vector it turns a column into a row.

Entry by entry, (A⊤)ij=Aji(A^\top)_{ij} = A_{ji}: the number in row ii, column jj of A⊤A^\top is the number in row jj, column ii of AA. A 3×53 \times 5 matrix becomes 5×35 \times 3.

In this course its main job is making shapes fit so a multiplication is allowed. QK⊤QK^\top works because QQ is N×dkN \times d_k and K⊤K^\top is dk×Md_k \times M, giving the N×MN \times M matrix of scores: one row per query, one column per key. In self-attention M=NM = N, so it is square. QKQK without the transpose would not be a valid product.

u⊤v\mathbf{u}^\top \mathbf{v} is the dot product written as a matrix product: a 1×d1 \times d row times a d×1d \times 1 column gives one number.

Example
[123456]⊤=[142536]\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}^\top = \begin{bmatrix} 1 & 4 \\ 2 & 5 \\ 3 & 6 \end{bmatrix}

The first row (1, 2, 3) becomes the first column. A 2×3 matrix becomes 3×2.

rank⁡\operatorname{rank}

Read "rank of W". It is the number of truly independent directions a matrix can produce, which equals its number of nonzero singular values.

A 4096×40964096 \times 4096 matrix stores about 16.8 million numbers, but its rank can be as low as 8: every output it produces is then a mix of just 8 directions. Low rank means the matrix can be stored much more compactly, as two thin matrices.

LoRA assumes that the change a fine-tune makes to the weights has low rank, even though the weights themselves do not. So the change can be learned as two thin matrices.

Example
rank⁡[1224]=1\operatorname{rank}\begin{bmatrix} 1 & 2 \\ 2 & 4 \end{bmatrix} = 1

The second row is twice the first, so there is only one independent direction.

⟨u,v⟩\langle \mathbf{u}, \mathbf{v} \rangle

Read "the dot product of u and v". Multiply the two vectors entry by entry and add the results. You get one number, which is large when the vectors point the same way.

⟨u,v⟩=∑iuivi\langle \mathbf{u}, \mathbf{v}\rangle = \sum_i u_i v_i. It also equals ∥u∥ ∥v∥cos⁡θ\|\mathbf{u}\|\,\|\mathbf{v}\|\cos\theta, where θ\theta is the angle between the vectors. The second form is why attention uses it: the dot product is large and positive when two vectors point the same way, near zero when they are perpendicular, and negative when they point apart.

Angle brackets ⟨u,v⟩\langle \mathbf{u}, \mathbf{v}\rangle, u⊤v\mathbf{u}^\top\mathbf{v} and u⋅v\mathbf{u}\cdot\mathbf{v} are three ways of writing the same operation.

Example
⟨[1,2,3], [4,0,−1]⟩=1⋅4+2⋅0+3⋅(−1)=1\langle [1, 2, 3],\, [4, 0, -1] \rangle = 1{\cdot}4 + 2{\cdot}0 + 3{\cdot}(-1) = 1

Only slightly positive compared with the vectors' lengths (about 3.7 and 4.1), so they are close to perpendicular.

∥x∥2\|\mathbf{x}\|_2

Read "the norm of x". Double bars mean the length of a vector: square each entry, add them up, and take the square root.

∥x∥2=∑ixi2\|\mathbf{x}\|_2 = \sqrt{\sum_i x_i^2}. This is Pythagoras' theorem with dd sides instead of two. The small subscript says which kind of length:

  • ∥⋅∥2\|\cdot\|_2: ordinary (Euclidean) length, the default
  • ∥⋅∥F\|\cdot\|_F: the Frobenius norm, the same formula applied to every entry of a matrix
  • ∥⋅∥1\|\cdot\|_1: the sum of the absolute values of the entries

Dividing a vector by its norm gives a vector of length 1 (a unit vector). Cosine similarity does this to both vectors before taking their dot product.

Example
∥[3,4]∥2=9+16=5\|[3, 4]\|_2 = \sqrt{9 + 16} = 5

The 3–4–5 right triangle: the vector's length is the hypotenuse.

θ\theta

Read "theta". Usually it stands for every learnable weight in the model at once. In some sections it is an angle or a setting instead; the sentence around it tells you which.

Pθ(wt∣⋅)P_\theta(w_t \mid \cdot) means "the probability that this model, with its current weights θ\theta, gives to wtw_t". The subscript is a reminder that the probabilities change as training changes the weights.

θ\theta has several meanings in this course. In Module 1 it is the angle between two vectors. In RoPE (Module 15) it is a rotation frequency. In the repetition penalty (Module 8) it is a single number you choose, such as 1.15. Read the surrounding sentence to know which.

cat→3797\text{cat} \to 3797

Token

Concept

One piece of text the model reads or writes: a word, part of a word, or a punctuation mark. Each token has a whole-number ID in the vocabulary.

A tokenizer splits text into tokens and looks each one up in the vocabulary, giving a whole number. The model then replaces each number with a vector from its embedding matrix (section 1.5). Common words are usually one token; rare words are split into several (section 9.2).

A sentence of NN tokens therefore becomes NN vectors, stacked as the rows of an N×dmodelN \times d_{\text{model}} matrix.

Example
unbelievable→[un,  believ,  able]\text{unbelievable} \to [\text{un},\; \text{believ},\; \text{able}]

One word, three tokens (illustrative split; each tokenizer splits differently).

ei\mathbf{e}_i

Read "e i". It is a vector with a 1 in position i and 0 everywhere else: token number i, written as a vector.

ei∈{0,1}∣V∣\mathbf{e}_i \in \{0,1\}^{|V|} has ∣V∣|V| entries and a single 1, at position ii. Multiplying it by a matrix picks out row ii of that matrix: ei⊤WE=WE[i,:]\mathbf{e}_i^\top W_E = W_E[i,:].

No real implementation does that multiplication; it just reads row ii from memory (nn.Embedding in PyTorch). Writing it as a multiplication shows that the embedding step is an ordinary matrix product like every other layer. It also makes the gradient easy to see: only row ii of WEW_E gets updated.

Example
∣V∣=4,  i=2  ⟹  e2=[0,0,1,0]|V| = 4,\; i = 2 \;\Longrightarrow\; \mathbf{e}_2 = [0, 0, 1, 0]

Positions are counted from 0 here, so position 2 is the third slot.

WEW_E

Read "W E". It is a learned table with one row per token in the vocabulary; each row is that token's vector of d_model numbers.

WE∈R∣V∣×dmodelW_E \in \mathbb{R}^{|V| \times d_{\text{model}}}: ∣V∣|V| rows, each dmodeld_{\text{model}} numbers wide. Row ii is the vector the model uses for token ii. It is trained like any other weight.

Many models tie this matrix to the output layer: they reuse it (transposed) to turn the final hidden vector back into one score per vocabulary token. That saves a whole ∣V∣×dmodel|V| \times d_{\text{model}} block of parameters, which is a large share of a small model.

Example
∣V∣=50,257,  dmodel=768  ⟹  WE has about 38.6M numbers|V| = 50{,}257,\; d_{\text{model}} = 768 \;\Longrightarrow\; W_E \text{ has about } 38.6\text{M numbers}

GPT-2 small.

O(⋅)\mathcal{O}(\cdot)

Read "order of" or "big O of". It describes how cost grows as the input gets bigger, ignoring constant factors. O(N²) means doubling N roughly quadruples the work.

  • O(1)\mathcal{O}(1): constant, the same at any size.
  • O(N)\mathcal{O}(N): linear, double the input and double the work.
  • O(N2)\mathcal{O}(N^2): quadratic, like building the N×NN \times N attention matrix.
  • O(N3)\mathcal{O}(N^3): cubic, like generating NN tokens while recomputing all attention from scratch each step, with no KV cache.

Constant factors are dropped on purpose, so big-O answers "how does this scale?" and not "how fast is it?". At real sizes, a well-optimized O(N2)\mathcal{O}(N^2) method can beat a poorly written O(Nlog⁡N)\mathcal{O}(N\log N) one.

Example
∑t=1TO(t2)=O(T3)\sum_{t=1}^{T}\mathcal{O}(t^2) = \mathcal{O}(T^3)

Recomputing the full t×t attention matrix at every step t of generation, for T steps, costs cubic time overall.

WW

The numbers a model learns in training: the entries of its weight matrices and vectors. A model's size is counted in weights, such as 124 million for GPT-2 Small.

Everything else a model computes is derived from its input and its weights. The weights are fixed while the model runs and change only during training. The words weights and parameters mean the same thing; θ\theta stands for all of them at once.

Memory is weights times bytes per number: 124 million weights stored as 16-bit numbers take about 248 MB.

Example
WQ∈R768×64  ⟹  768⋅64=49,152 weightsW^Q \in \mathbb{R}^{768 \times 64} \;\Longrightarrow\; 768 \cdot 64 = 49{,}152 \text{ weights}

One small matrix of one attention head in GPT-2 Small.

fp32, bf16, int8\text{fp32},\ \text{bf16},\ \text{int8}

The format each number in a tensor is stored in, which sets its size in bytes and its precision. fp32 uses 4 bytes, bf16 and fp16 use 2, int8 uses 1.

A computer cannot store an arbitrary real number, so each entry is rounded to a fixed format. Floating-point formats keep a sign, an exponent (the range) and a mantissa (the precision): fp32 is standard, while bf16 and fp16 halve the memory. Integer formats such as int8 store whole numbers plus a shared scale, the subject of section 24.2.

The memory of a tensor is its number of entries times the bytes per entry. That is why the same model can need 4, 2 or 1 byte per weight depending on its data type.

Example
50,257×768=38,597,376 numbers×4 bytes≈154 MB50{,}257 \times 768 = 38{,}597{,}376 \text{ numbers} \times 4 \text{ bytes} \approx 154 \text{ MB}

GPT-2's token embedding matrix in fp32. In bf16 it is about 77 MB.

h\mathbf{h}

The numbers a model computes as it runs: every intermediate vector between the input and the output. Unlike weights, they change with every input.

Weights are what the model knows; activations are what it is thinking about this input. They are tensors too, usually of shape B×N×dmodelB \times N \times d_{\text{model}} between layers. Training keeps them in memory so backpropagation can use them, which is why a long sequence costs memory even when the model is small. Section 24.2 shows why activations are harder to quantize than weights.

Do not confuse this with an activation function such as GELU, the nonlinearity applied inside the feed-forward network.

Example
X∈RN×dmodel  →  block1  →  h(1)  →  block2  →  ⋯X \in \mathbb{R}^{N \times d_{\text{model}}} \;\to\; \text{block}_1 \;\to\; \mathbf{h}^{(1)} \;\to\; \text{block}_2 \;\to\; \cdots

Each block reads activations and writes new ones of the same shape.

Module 2 · Calculus and Optimization

lim⁡\lim

Read "the limit as T goes to 0". It is the value a quantity gets closer and closer to as something is pushed toward an extreme, even if that extreme can't be plugged in directly.

lim⁡T→0+pi\lim_{T \to 0^+} p_i asks what the softmax probabilities approach as the temperature TT shrinks toward zero from above (the +^+ means "from the positive side"). The answer is that all probability goes to the largest logit. This describes greedy decoding, even though setting T=0T = 0 directly would mean dividing by zero.

Limits let a formula describe its own edge cases.

Example
lim⁡x→∞1x=0\lim_{x \to \infty} \frac{1}{x} = 0

1/x gets as close to 0 as you like, though it never equals 0.

→\to

An arrow means either "approaches" (in a limit), "is changed to" (a new value), or, pointing left, "is set to" (like = in code).

pj→0p_j \to 0 means "pjp_j approaches zero". θbase=10,000⟶500,000\theta_{\text{base}} = 10{,}000 \longrightarrow 500{,}000 means the constant was changed from 10,000 to 500,000. zi⟵…z_i \longleftarrow \dots is an assignment: replace ziz_i with the right-hand side, like z[i] = ... in code.

An arrow with a condition written under it, such as →T−t→∞\xrightarrow[T-t\to\infty]{}, says what the quantity approaches and what change drives it there.

≈\approx

≈ reads "approximately equals". ∼ reads "is distributed as" or "is roughly of the order of". ∝ reads "is proportional to".

≈\approx usually marks a deliberate approximation, such as the tanh formula for GELU or a rounded parameter count. x^≈x\hat{x} \approx x after quantization admits that the scheme introduces some error.

X∼N(0,1)X \sim \mathcal{N}(0,1) reads "XX is drawn from a normal distribution with mean 0 and variance 1". y∝xy \propto x means y=c xy = c\,x for some fixed constant cc.

Example
π≈3.14,pi∝ezi\pi \approx 3.14, \qquad p_i \propto e^{z_i}

The second says softmax probabilities equal e to the z times a shared constant (one over the sum).

Δ\Delta

Read "delta". Capital delta means "the change in", so ΔW is the amount W changes by.

ΔW\Delta W is one object, the update to WW, not Δ\Delta multiplied by WW. In LoRA, the fine-tuned weights are W0+ΔWW_0 + \Delta W, where ΔW\Delta W is the learned correction.

Example
W=5→5.3  ⟹  ΔW=0.3W = 5 \to 5.3 \;\Longrightarrow\; \Delta W = 0.3

New value minus old value.

∂\partial

Read "partial L by partial θ". It is how much the top quantity changes when you nudge the bottom one slightly, keeping every other input fixed.

∂L∂θ\frac{\partial \mathcal{L}}{\partial \theta} is the slope of the loss with respect to one parameter. Its sign tells training which way to move that parameter, and its size tells how much the loss cares. The curly ∂\partial (instead of the dd in dydx\frac{dy}{dx}) signals that the function has several inputs and all the others are held still.

When the top and bottom are both vectors, the result is a matrix holding the slope of every output with respect to every input. That matrix is called a Jacobian.

Example
∂pi∂zj=pi(δij−pj)\frac{\partial p_i}{\partial z_j} = p_i(\delta_{ij} - p_j)

The softmax Jacobian. Every output p_i depends on every input z_j, because all outputs share the same denominator.

∇\nabla

Read "nabla" or "the gradient of". It is the list of every partial derivative at once, and it points in the direction that increases the function fastest.

∇θL\nabla_\theta \mathcal{L} collects ∂L/∂θk\partial\mathcal{L}/\partial\theta_k for every parameter θk\theta_k into one vector, the same shape as the parameters. Training takes a small step in the opposite direction, θ←θ−η ∇θL\theta \leftarrow \theta - \eta\,\nabla_\theta \mathcal{L} with a small step size η\eta, because the fastest way uphill, reversed, is the fastest way down.

Example
L=a2+3b  ⟹  ∇L=[∂L∂a, ∂L∂b]=[2a, 3]\mathcal{L} = a^2 + 3b \;\Longrightarrow\; \nabla \mathcal{L} = \left[\tfrac{\partial \mathcal{L}}{\partial a},\, \tfrac{\partial \mathcal{L}}{\partial b}\right] = [2a,\, 3]

One partial derivative per parameter, stacked into a vector.

η\eta

Read "eta". The learning rate: how big a step gradient descent takes against the gradient on each update.

In θ←θ−η ∇θL\theta \leftarrow \theta - \eta \, \nabla_\theta \mathcal{L}, the gradient says which way to move and η\eta says how far. Too small and training crawls; too large and every step overshoots. Large models do not hold it fixed: section 10.2 raises it during a warmup and then lowers it along a schedule.

Example
θ=0,  ∇=−6,  η=0.1  ⟹  θ=0.6\theta = 0, \; \nabla = -6, \; \eta = 0.1 \;\Longrightarrow\; \theta = 0.6

One step of gradient descent on (θ − 3)², from section 2.5.

Module 3 · Probability and Information

σ\sigma

Read "sigma". Usually it is the standard deviation: a typical distance of values from their average. With a numbered subscript (section 20.2) it is a singular value, and written as a function, σ(z), it is the sigmoid.

σ=Var⁡\sigma = \sqrt{\operatorname{Var}}. Taking the square root puts the spread back in the same units as the data, so you can compare it with the values themselves. σ2\sigma^2 is the variance.

In Section 20.2 the same letter is used for singular values σ1≥σ2≥…\sigma_1 \ge \sigma_2 \ge \dots, which say how strongly a matrix stretches along each of its main directions. The two meanings are unrelated; a numbered subscript (σ1\sigma_1, σi\sigma_i) usually means a singular value.

Written as a function, σ(z)=11+e−z\sigma(z) = \frac{1}{1 + e^{-z}} is the sigmoid, which squashes any number into the range 0 to 1. That is its meaning in Swish, z⋅σ(βz)z \cdot \sigma(\beta z), in section 15.4: the sigmoid acts as a soft on/off switch on zz.

Example
{2,4,6}:  μ=4,  σ2=4+0+43≈2.67,  σ≈1.63\{2, 4, 6\}: \; \mu = 4, \; \sigma^2 = \tfrac{4+0+4}{3} \approx 2.67, \; \sigma \approx 1.63

Square the distances from the mean, average them to get the variance, then take the square root.

μ\mu

Read "mu". It is the mean (the ordinary average) of a set of numbers: add them up and divide by how many there are.

In LayerNorm, μ=1d∑ixi\mu = \frac{1}{d}\sum_i x_i is the average of the dd numbers in one token's vector, not an average across the tokens in a batch. Subtracting it shifts that token's values so they average to zero.

RMSNorm skips this subtraction, on the argument that it costs compute without helping much.

Example
x=[1,2,6]  ⟹  μ=1+2+63=3\mathbf{x} = [1, 2, 6] \;\Longrightarrow\; \mu = \tfrac{1+2+6}{3} = 3

Subtracting the mean gives [-2, -1, 3], which averages to zero.

  \sqrt{\;}

Read "the square root of". It is the non-negative number that, multiplied by itself, gives the number inside: √9 = 3.

In this course it mostly undoes a squaring. Variance is measured in squared units, so Var⁡\sqrt{\operatorname{Var}} brings the spread back to the scale of the data. That is why attention divides by dk\sqrt{d_k} and not by dkd_k: the score's variance is dkd_k, so its typical size is dk\sqrt{d_k}.

Example
64=8\sqrt{64} = 8

Because 8 × 8 = 64.

E[⋅]\mathbb{E}[\cdot]

Read "the expected value of X". It is the average value a random quantity takes if you draw it many, many times.

E[X]\mathbb{E}[X] is what XX averages out to over a very large number of draws. Two rules are used in the course:

  • It is linear, always: E[aX+bY]=aE[X]+bE[Y]\mathbb{E}[aX + bY] = a\mathbb{E}[X] + b\mathbb{E}[Y].
  • For independent quantities (knowing one tells you nothing about the other), the expected value of a product splits: E[XY]=E[X] E[Y]\mathbb{E}[XY] = \mathbb{E}[X]\,\mathbb{E}[Y].

The second rule only holds under independence, and the proof behind the dk\sqrt{d_k} scaling depends on it.

Example
E[die roll]=1+2+3+4+5+66=3.5\mathbb{E}[\text{die roll}] = \tfrac{1+2+3+4+5+6}{6} = 3.5

No single roll is 3.5, but the average over many rolls approaches it.

Var⁡(⋅)\operatorname{Var}(\cdot)

Read "the variance of X". It measures how spread out a random quantity is around its average. Its square root is the standard deviation.

Var⁡(X)=E[X2]−(E[X])2\operatorname{Var}(X) = \mathbb{E}[X^2] - (\mathbb{E}[X])^2: the average squared distance from the mean. Two rules are used repeatedly in the course:

  • For independent quantities, variances add: Var⁡(X+Y)=Var⁡(X)+Var⁡(Y)\operatorname{Var}(X + Y) = \operatorname{Var}(X) + \operatorname{Var}(Y).
  • Scaling by a number cc scales the variance by c2c^2: Var⁡(cX)=c2Var⁡(X)\operatorname{Var}(cX) = c^2 \operatorname{Var}(X).

If the entries of q\mathbf{q} and k\mathbf{k} are independent with mean 0 and variance 1, each product qikiq_i k_i has variance 1, so the first rule gives Var⁡(q⊤k)=dk\operatorname{Var}(\mathbf{q}^\top\mathbf{k}) = d_k. The second rule then shows that dividing by dk\sqrt{d_k} brings it back to 1.

Example
X∈{−1,+1} equally likely  ⟹  Var⁡(X)=1−02=1X \in \{-1, +1\} \text{ equally likely} \;\Longrightarrow\; \operatorname{Var}(X) = 1 - 0^2 = 1

The mean is 0 and X² is always 1.

P(a∣b)P(a \mid b)

The vertical bar reads "given". P(a | b) is "the probability of a given b": how likely a is when you already know b is true.

P(wt∣w1,…,wt−1)P(w_t \mid w_1, \dots, w_{t-1}) is the whole job of a language model: the probability of each possible next token, given all the tokens so far. It is a full list of probabilities, one for every token in the vocabulary, not a single word. Sampling picks one token from that list.

w<tw_{<t} is shorthand for the same list of earlier tokens, w1,…,wt−1w_1, \dots, w_{t-1}.

Example
P(mat∣the cat sat on the)=0.4P(\text{mat} \mid \text{the cat sat on the}) = 0.4

Read: the probability that the next word is "mat", given the words so far, is 0.4. (Made-up number.)

P(w1…wT)=∏tP(wt∣w<t)P(w_1 \dots w_T) = \prod_t P(w_t \mid w_{<t})

The probability of a whole sentence equals the probability of each word given the words before it, all multiplied together.

This is exact, not an approximation. It is the chain rule of probability applied from left to right. Its consequence shapes the whole architecture: a model that can predict one next token can score or generate text of any length by repeating that step. A model that works this way is called autoregressive.

Example
P(the cat)=P(the)×P(cat∣the)P(\text{the cat}) = P(\text{the}) \times P(\text{cat} \mid \text{the})

Two words, two factors. A sentence of T words has T factors.

MaximumlikelihoodMaximum likelihood

Choosing a model's parameters to make the observed data as probable as possible, in practice by minimizing the negative log-likelihood.

For a coin, the maximum-likelihood estimate is the observed frequency of heads (section 3.4).

EntropyEntropy

The average surprise of a distribution, H(p) = −Σ p log p: zero if one outcome is certain, largest when all outcomes are equally likely.

Measured in bits with log base 2 (section 3.5). It is the floor that cross-entropy can never go below.

Cross−entropyCross-entropy

The average surprise when the truth is p but you predict with q. Against a one-hot target it is minus the log of the probability given to the correct class.

Minimizing it is the same as maximizing likelihood (sections 3.4 and 3.5). It is the loss of every classifier and language model in the course.

KL⁡(P ∥ Q)\operatorname{KL}(P \,\|\, Q)

How different two probability distributions are: zero when they agree, larger the more they differ. It is not symmetric, so KL(P‖Q) and KL(Q‖P) differ.

KL⁡(P ∥ Q)=∑xP(x)log⁡P(x)Q(x)\operatorname{KL}(P \,\|\, Q) = \sum_x P(x) \log \frac{P(x)}{Q(x)}. In RLHF (section 21.5) it measures how far the trained model has drifted from the model it started from, and the objective subtracts it as a penalty so the model stays fluent while it chases reward.

Example
P=[0.5,0.5],  Q=[0.9,0.1]  ⟹  KL⁡(P ∥ Q)≈0.51P = [0.5, 0.5], \; Q = [0.9, 0.1] \;\Longrightarrow\; \operatorname{KL}(P \,\|\, Q) \approx 0.51

0.5 ln(0.5/0.9) + 0.5 ln(0.5/0.1) ≈ −0.29 + 0.80.

PerplexityPerplexity

The exponential of the average negative log-likelihood per token. A perplexity of 20 means the model is as unsure as if choosing uniformly among 20 tokens.

Lower is better. It is per token, so it cannot be compared across tokenizers; bits per byte can (section 13.1).

SigmoidSigmoid

σ(z) = 1 / (1 + e^(−z)): maps any real number into the range 0 to 1, with σ(0) = 0.5.

It is the two-class softmax, and the Bradley–Terry model of preferences uses it on a difference of scores (section 3.6).

RewardReward

A number saying how good an outcome was. For a chat response it comes from a learned reward model; for maths or code it can come from a checker.

Section 21.4 trains a reward model from pairwise human preferences; section 22.3 uses verifiable rewards.

Module 4 · How a Model Learns From Data

Self−supervisedlearningSelf-supervised learning

Training in which the labels come from the data itself, such as predicting the next token of a text. No one has to annotate anything.

A language model is trained on next-token prediction: hide the next token, predict it from the ones before. Every position of every text is a labelled example for free, which is why the training signal grows with the supply of text (section 4.1). Masked-token prediction (BERT) and autoencoders are other self-supervised tasks.

NeuronNeuron

The smallest unit of a neural network: a weighted sum of its inputs plus a bias, passed through a fixed nonlinear function.

A layer is many neurons reading the same input, which is one matrix multiplication followed by the activation function applied entry by entry (section 4.2).

ActivationfunctionActivation function

The fixed nonlinear function applied after a layer's weighted sums, such as ReLU, tanh, GELU or Swish.

Without it, stacked linear layers collapse into a single linear layer, so depth would add nothing (section 4.2).

MLPMLP

A chain of layers, each a matrix multiplication followed by an activation function. The feed-forward network in every transformer block is an MLP with one hidden layer.

Hidden layers sit between input and output; their size is the network's width (section 4.2).

ziz_i

The raw scores a model produces before softmax turns them into probabilities. There is one per vocabulary entry. They can be any real number, negative or positive.

The last layer of a language model outputs a vector z\mathbf{z} with one entry per token in the vocabulary. A larger logit means that token is more likely to come next, but logits are not probabilities: they do not add to 1 and can be negative. Softmax converts them (section 4.3), and temperature divides them first to sharpen or flatten the result.

Example
z=[2.0,  1.0,  −1.0]  →softmax  [0.71,  0.26,  0.04]\mathbf{z} = [2.0,\; 1.0,\; -1.0] \;\xrightarrow{\text{softmax}}\; [0.71,\; 0.26,\; 0.04]

Order is kept; the scores become shares that add to 1 (0.705 + 0.259 + 0.035).

Softmax⁡\operatorname{Softmax}

Softmax

Function

Read "softmax of z". It turns any list of numbers into probabilities: every output is positive and they add up to 1. Bigger inputs get bigger shares.

Softmax⁡(z)i=ezi/∑jezj\operatorname{Softmax}(\mathbf{z})_i = e^{z_i} / \sum_j e^{z_j}. Taking ee to the power of each input makes every value positive. Dividing by the total makes them add up to 1.

It is called soft because it does not just pick the largest input (that would be a "hard" max). Larger inputs get a larger share, but every entry keeps some probability above zero. Only the differences between inputs matter: adding the same constant to every input leaves the output unchanged.

Example
Softmax⁡([2, 1, 0])≈[0.665, 0.245, 0.090]\operatorname{Softmax}([2,\, 1,\, 0]) \approx [0.665,\, 0.245,\, 0.090]

A difference of 1 between two inputs becomes a ratio of e ≈ 2.7 between their probabilities: 0.665 / 0.245 ≈ 2.7.

∞\infty

Read "infinity". It is not an ordinary number. It means "grows without limit", and in an attention mask, −∞ means "never allowed".

The attention mask uses −∞-\infty because adding it to any score makes the result −∞-\infty, and e−∞=0e^{-\infty} = 0: the position gets zero weight. Code uses a large finite negative number instead, because true infinities cause NaN ("not a number") in some arithmetic, such as ∞−∞\infty - \infty or 0×∞0 \times \infty. For example, a row where every position is masked with −∞-\infty would give NaN.

Example
e 3+(−∞)=e−∞=0e^{\,3 + (-\infty)} = e^{-\infty} = 0

Whatever the original score, a masked position ends with weight zero.

zi/Tz_i / T

Read "z i over T". Each logit is divided by the temperature T before softmax. T below 1 makes the distribution sharper; T above 1 makes it flatter.

Dividing by T<1T < 1 makes the gaps between logits bigger, so softmax puts more probability on the top tokens: safer, more repetitive text. T>1T > 1 makes the gaps smaller, pushing toward equal probabilities: more varied text, and eventually nonsense.

The division happens before the exponential. So the ratio between any two probabilities, pi/pj=e(zi−zj)/Tp_i / p_j = e^{(z_i - z_j)/T}, gets raised to the power 1/T1/T. The effect is a power on probability ratios, not a simple shift of the probabilities.

Example
[2,1,0]0.5=[4,2,0]  →softmax  [0.867, 0.117, 0.016]\frac{[2, 1, 0]}{0.5} = [4, 2, 0] \;\xrightarrow{\text{softmax}}\; [0.867,\, 0.117,\, 0.016]

At T = 1 the same logits give [0.665, 0.245, 0.090]. Halving T sharpens the distribution.

arg⁡max⁡\arg\max

Read "arg max". It gives the position (index) of the largest value, not the largest value itself.

max⁡kzk\max_k z_k is the biggest logit. arg⁡max⁡kzk\arg\max_k z_k is which token has it. Greedy decoding outputs the arg⁡max⁡\arg\max token at every step.

The difference shows up in the safe softmax too: there you subtract max⁡kzk\max_k z_k, the largest value, from every logit to prevent overflow.

Example
z=[0.1, 3.2, 1.5]:max⁡kzk=3.2,arg⁡max⁡kzk=2\mathbf{z} = [0.1,\, 3.2,\, 1.5]: \quad \max_k z_k = 3.2, \quad \arg\max_k z_k = 2

Counting positions from 1. The largest value is 3.2; it sits at position 2.

{aif …botherwise\begin{cases} a & \text{if } \dots \\ b & \text{otherwise} \end{cases}

A large left brace with several lines is an if/else written vertically. Read each line as "this value, if this condition holds" and use the line whose condition is true.

Each row has a value, then a condition. Exactly one condition should be true for any input. It is if / elif / else in maths notation. The causal mask, the repetition penalty and the multimodal label mask are written this way.

Example
∣x∣={x,if x≥0−x,if x<0|x| = \begin{cases} x, & \text{if } x \ge 0 \\ -x, & \text{if } x < 0 \end{cases}

Absolute value: for x = -3 the second line applies, giving 3.

δij\delta_{ij}

Read "delta i j". It equals 1 when i and j are the same number and 0 when they differ. It is an if-statement written as a number.

δij=1\delta_{ij} = 1 if i=ji = j, and 00 otherwise. It lets one formula cover two cases. In the softmax Jacobian, pi(δij−pj)p_i(\delta_{ij} - p_j) becomes pi(1−pi)p_i(1 - p_i) when i=ji = j and −pipj-p_i p_j when i≠ji \ne j.

Written as a table over all ii and jj, it is exactly the identity matrix.

Example
δ22=1,δ23=0\delta_{22} = 1, \quad \delta_{23} = 0

Same index gives 1; different indices give 0.

1dk\frac{1}{\sqrt{d_k}}

Read "one over root d k". Attention divides its scores by the square root of the head width so they keep a spread of about 1, however wide the head is.

Suppose the entries of q\mathbf{q} and k\mathbf{k} are independent, with mean 0 and variance 1. Their dot product adds dkd_k such products, so its variance is dkd_k and its standard deviation is dk\sqrt{d_k}. At dk=64d_k = 64 that is 8. Scores that far apart push softmax to its extremes: one weight near 1 and the rest near 0. There its slope, of the form p(1−p)p(1-p), is close to zero, so learning stalls.

Dividing by dk\sqrt{d_k} brings the variance back to 1, keeping the weights spread out and the gradients useful.

Example
dk=64:Var⁡(q⊤k)=64  ⟹  Var⁡ ⁣(q⊤k8)=6464=1d_k = 64: \quad \operatorname{Var}(\mathbf{q}^\top \mathbf{k}) = 64 \;\Longrightarrow\; \operatorname{Var}\!\left(\tfrac{\mathbf{q}^\top \mathbf{k}}{8}\right) = \tfrac{64}{64} = 1

Dividing by √64 = 8 divides the variance by 8² = 64.

GeneralizationGeneralization

Performing well on new data from the same source as the training data, not only on the training examples themselves.

Measured on a held-out validation or test set (section 4.4). A model that memorizes its training examples fits them perfectly and generalizes badly.

HyperparameterHyperparameter

A setting fixed before training rather than learned: the learning rate, batch size, number of layers, weight decay, dropout rate and so on.

Chosen by comparing validation loss across candidate values (section 4.5).

Module 5 · Sequences Before Transformers

∂hT∂ht\frac{\partial \mathbf{h}_T}{\partial \mathbf{h}_t}

How much the state at the last step T depends on the state at an earlier step t. The chain rule makes it a product of one factor per step, which is why RNN gradients vanish or explode.

The chain rule says the derivative through a sequence of functions is the product of each function's derivative. Across T−tT - t recurrent steps, that is T−tT - t matrices multiplied together.

If each factor shrinks things (roughly, a size λ<1\lambda < 1), the product shrinks like λT−t\lambda^{T-t}. The gradient reaching step tt is then effectively zero, and the model cannot learn that step tt affected step TT. If each factor is above 1, the product grows without limit instead. Keeping every factor near exactly 1 over long sequences is very hard. This is a main reason attention replaced recurrence: attention connects any two positions in a single step.

Example
0.950≈0.005,1.150≈1170.9^{50} \approx 0.005, \qquad 1.1^{50} \approx 117

Fifty steps with a factor slightly below or above 1.

∏\prod

Read "the product of". The big pi works like ∑, but it multiplies the terms instead of adding them.

∏t=1Tat=a1×a2×⋯×aT\prod_{t=1}^{T} a_t = a_1 \times a_2 \times \cdots \times a_T.

It appears in two places in the course. First, chaining probabilities: a sentence's probability is the product of each token's probability given the tokens before it. Second, chaining derivatives through many steps. This is why RNN gradients vanish: multiply TT numbers that are each below 1 and the result shrinks toward zero, faster the larger TT is.

Example
∏t=130.5=0.5×0.5×0.5=0.125\prod_{t=1}^{3} 0.5 = 0.5 \times 0.5 \times 0.5 = 0.125

Three factors of one half already give one eighth; fifty would give about 0.000000000000001.

α\alpha

Read "alpha". The course reuses it, each time as in the original paper: the LoRA scale (1.3), the load-balancing weight (5.3), the SmoothQuant exponent (4.7), and the CTC forward table (7.2).

None of these meanings carries over to the next. In LoRA, αr\frac{\alpha}{r} scales the low-rank update. In mixture-of-experts training, α\alpha (often 0.01) sets how much the balancing loss counts. In SmoothQuant, α\alpha (usually 0.5) splits an outlier's size between activations and weights. In CTC, αt(s)\alpha_t(s) is a running total of path probabilities. The sentence around the symbol always says which one is meant.

Module 6 · Attention

Attention⁡(Q,K,V)\operatorname{Attention}(Q,K,V)

Each token scores every other token, turns the scores into weights that add up to 1, and takes the weighted average of their value vectors.

Attention⁡(Q,K,V)=Softmax⁡ ⁣(QK⊤dk+M)V\operatorname{Attention}(Q,K,V) = \operatorname{Softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}} + M\right)V

Read it step by step, with NN tokens:

  1. QK⊤QK^\top is an N×NN \times N table: how well each token's query matches each token's key. (In cross-attention the keys come from a different sequence of length MM, and the table is N×MN \times M.)
  2. Divide by dk\sqrt{d_k} so the scores stay in a range where softmax still responds to differences.
  3. Add the mask MM to block positions a token must not see.
  4. Softmax each row, so each token's weights add up to 1.
  5. Multiply by VV: each token gets a weighted blend of the value vectors.
MM

A matrix of 0s and −∞ (minus infinity) added to the attention scores before softmax. A 0 leaves a position allowed; −∞ blocks it.

Adding −∞-\infty to a score before softmax removes that option. Since e−∞=0e^{-\infty} = 0, that position gets exactly zero weight, contributes nothing, and receives no gradient.

The causal mask sets Mij=−∞M_{ij} = -\infty whenever j>ij > i, so token ii cannot look at later tokens. In code, a large negative number such as −109-10^9 is used in place of −∞-\infty to avoid arithmetic with true infinities.

Example
M=[0−∞−∞00−∞000]M = \begin{bmatrix} 0 & -\infty & -\infty \\ 0 & 0 & -\infty \\ 0 & 0 & 0 \end{bmatrix}

Causal mask for 3 tokens: row i may see columns up to i and nothing after.

[a;b][\mathbf{a}; \mathbf{b}]

Read "a joined with b". A semicolon between items in square brackets means: join them end to end into one longer vector, or stack them as rows into one longer sequence.

[head⁡1;… ;head⁡h][\operatorname{head}_1; \dots; \operatorname{head}_h] places hh vectors, each dvd_v wide, side by side into one vector h dvh\,d_v wide. That is why WOW^O has h dvh\,d_v rows: one for each number in the joined vector.

When the items are matrices whose rows are tokens, the semicolon stacks their rows: [Ximg;Xtext][\mathbf{X}_{\text{img}}; \mathbf{X}_{\text{text}}] is the image rows followed by the text rows, one sequence. The same notation adds a new row to the KV cache and inserts image patches among text tokens in a multimodal sequence. In PyTorch it is torch.cat.

Example
[[1,2]; [3,4,5]]=[1,2,3,4,5][[1, 2];\, [3, 4, 5]] = [1, 2, 3, 4, 5]

A length-2 and a length-3 vector join into a length-5 vector.

N,T,LN, T, L

The number of tokens in the sequence. Different modules call it N, T or L. N² ("N squared") is how attention's cost grows with it.

The course uses NN in the attention chapters, TT for time steps in generation, and LL for context length in the KV-cache calculations. All three mean the same thing; the different letters come from the original papers.

It is the number that appears squared in attention's cost, so many of the optimizations in Module 15 aim to reduce what it costs.

Watch the letters. In section 8.5, LL counts layers, not tokens. When a formula has both, read the sentence around it to see which is which.

Example
N=1000  ⟹  N×N=1,000,000 attention scoresN = 1000 \;\Longrightarrow\; N \times N = 1{,}000{,}000 \text{ attention scores}

Double N to 2000 and there are four million.

Module 7 · The Block and the Full Model

xl+1=xl+…\mathbf{x}_{l+1} = \mathbf{x}_l + \dots

The next vector is the current vector plus what the sub-layer computed. Each sub-layer adds a change instead of replacing its input. The subscript l counts sub-layers.

Because each block adds to the stream instead of overwriting it, both information and gradients have a direct path from the first layer to the last.

Where the normalization sits is the Pre-LN versus Post-LN question. Normalizing inside the branch, before the sub-layer, leaves the direct path untouched. Normalizing after the addition puts a normalization on that path at every layer, and deep models built that way usually need a learning-rate warmup to train.

In the Post-LN form, xl+1=LayerNorm⁡(xl+Sublayer⁡(xl))\mathbf{x}_{l+1} = \operatorname{LayerNorm}(\mathbf{x}_l + \operatorname{Sublayer}(\mathbf{x}_l)), the residual addition is still there; it is just normalized afterwards.

Example
xl+1=[1,2]+[0.1,−0.3]=[1.1,1.7]\mathbf{x}_{l+1} = [1, 2] + [0.1, -0.3] = [1.1, 1.7]

The sub-layer's output is a small edit to the vector, not a replacement.

β\beta

Read "beta". LayerNorm's learned shift (4.2), Swish's slope (4.3), Adam's averaging factors β1 and β2 (3.6), the drift penalty in RLHF and DPO (3.7), and the write strength of the delta rule (5.4).

These are unrelated uses that follow each paper's own notation. With a subscript number, β1\beta_1 and β2\beta_2 are Adam's; bold β\boldsymbol{\beta} is LayerNorm's shift vector; with a time subscript, βt\beta_t is the delta rule's write strength. In RLHF and DPO, β\beta sets how far the trained model may move from the reference model.

LayerNorm⁡\operatorname{LayerNorm}

Read "layer norm". It shifts and rescales each token's vector to have mean 0 and variance 1, then applies a learned scale and shift.

LayerNorm⁡(x)=x−μσ2+ϵ⊙γ+β\operatorname{LayerNorm}(\mathbf{x}) = \frac{\mathbf{x} - \mu}{\sqrt{\sigma^2 + \epsilon}} \odot \boldsymbol{\gamma} + \boldsymbol{\beta}. Here μ\mu and σ2\sigma^2 are the mean and variance of the numbers within one token's vector. So the result for one token does not depend on the other examples in the batch, unlike BatchNorm. γ\boldsymbol{\gamma} (gain) and β\boldsymbol{\beta} (bias) are learned per feature.

It keeps activations in a steady range as layers stack up. Whether it is placed before the sub-layer (Pre-LN) or after the residual addition (Post-LN) affects whether deep models need a learning-rate warmup to train.

Example
[1,2,6]  →  [−2,−1,3]14/3≈[−0.93, −0.46, 1.39][1, 2, 6] \;\to\; \frac{[-2, -1, 3]}{\sqrt{14/3}} \approx [-0.93,\, -0.46,\, 1.39]

Mean 3, variance 14/3 (ignoring ε, with γ = 1 and β = 0).

ϵ\epsilon

Read "epsilon". It is a very small number added to a denominator so the division can never be by zero. In CTC (section 27.2) the same letter means something else: the blank symbol, "no character here".

Typical values are 10−510^{-5} or 10−610^{-6}. In σ2+ϵ\sqrt{\sigma^2 + \epsilon} it is a safeguard: if all of a token's values happen to be equal, then σ2=0\sigma^2 = 0 and dividing by 0\sqrt{0} would give infinity or NaN ("not a number"). ϵ\epsilon is small enough to have no visible effect normally and large enough to prevent that.

A second meaning. In CTC speech and text recognition (section 27.2), ϵ\epsilon is not a number at all. It is the blank label a frame outputs when it adds no new character. It lets the model say "nothing here" and separates doubled letters, so c ε c a t reads as "ccat" while c c a t collapses to "cat".

Example
00+10−5=0instead of00=NaN\frac{0}{\sqrt{0 + 10^{-5}}} = 0 \quad\text{instead of}\quad \frac{0}{\sqrt{0}} = \text{NaN}

A token whose values are all equal becomes all zeros rather than breaking the computation.

FFN⁡(x)\operatorname{FFN}(\mathbf{x})

Read "F F N of x". It is a small two-layer neural network applied to each token's vector on its own, with the same weights for every token.

In the original Transformer paper, FFN⁡(x)=max⁡(0,xW1+b1)W2+b2\operatorname{FFN}(\mathbf{x}) = \max(0, \mathbf{x}W_1 + \mathbf{b}_1)W_2 + \mathbf{b}_2: multiply, add a bias, set negatives to zero, then multiply and add a bias again. Modern models replace the max⁡(0,⋅)\max(0, \cdot) with GELU or SwiGLU.

It is called position-wise because tokens do not exchange information here. Attention moves information between tokens; the FFN transforms each token by itself. The nonlinearity in the middle is essential: without it, W1W_1 followed by W2W_2 would be the same as a single matrix W1W2W_1 W_2, and the extra layer would add nothing.

GELU⁡\operatorname{GELU}

The nonlinearity applied inside the feed-forward block. ReLU sets negative numbers to zero; GELU and Swish do almost the same but with a smooth curve.

ReLU⁡(z)=max⁡(0,z)\operatorname{ReLU}(z) = \max(0, z) has a sharp corner at zero and is completely flat below it, so negative inputs get no gradient. GELU⁡(z)=z⋅Φ(z)\operatorname{GELU}(z) = z \cdot \Phi(z), where Φ(z)\Phi(z) is the probability that a standard normal random number is less than zz. The result is a smooth curve that lets small negative values through. Gradients behave better, at a little more compute.

Swish, z⋅sigmoid⁡(z)z \cdot \operatorname{sigmoid}(z), has a very similar shape. SwiGLU uses two branches: one passes through Swish, the other stays linear, and the two are multiplied entry by entry, so one branch gates (scales up or down) the other.

Example
ReLU⁡(−1)=0,GELU⁡(−1)≈−0.16,GELU⁡(2)≈1.95\operatorname{ReLU}(-1) = 0, \quad \operatorname{GELU}(-1) \approx -0.16, \quad \operatorname{GELU}(2) \approx 1.95

GELU lets a small negative value through; large positive inputs pass almost unchanged.

Module 8 · Three Families: Encoder, Encoder-Decoder, Decoder

∀\forall

∀ (an upside-down A) reads "for all" or "for every". ∃ (a backwards E) reads "there exists", meaning at least one.

⋯=0  ∀j>i\dots = 0 \;\forall j > i says the statement holds for every index jj larger than ii, with no exceptions. That is the guarantee a causal mask must give: no token receives any weight from a later token.

Example
x2≥0    ∀x∈Rx^2 \ge 0 \;\; \forall x \in \mathbb{R}

Read: x squared is at least zero for every real number x.

  ⟹  \implies

Read "implies" or "therefore". If the left side is true, the right side follows.

A  ⟹  BA \implies B says that whenever AA holds, BB holds too. It does not work backwards: BB being true does not by itself make AA true.

Example
θ=90∘  ⟹  cos⁡θ=0\theta = 90^\circ \implies \cos\theta = 0

Perpendicular vectors therefore have a dot product of zero.

II

Read "I" or "the identity". It is a square matrix with 1s on the diagonal and 0s elsewhere. Multiplying by it leaves a vector unchanged.

In the residual stream, ∂xL∂x0=I+∑(… )\frac{\partial \mathbf{x}_L}{\partial \mathbf{x}_0} = I + \sum(\dots). The II comes from the skip connections. It means that even if every learned term contributed nothing, the gradient would still reach the early layers at full strength through the II. This direct route is sometimes called the "gradient highway".

Example
[1001][37]=[37]\begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \begin{bmatrix} 3 \\ 7 \end{bmatrix} = \begin{bmatrix} 3 \\ 7 \end{bmatrix}

The 2×2 identity returns its input.

Module 10 · Pretraining

x^\hat{x}

Read x̂ as "x hat" and x̃ as "x tilde". Both mark a changed copy of x: most often an estimate or a rounded version (hat), or a transformed version (tilde).

x^\hat{x} is what you get back after quantizing and then dequantizing xx. z^\hat{\mathbf{z}} is a codec's reconstruction of z\mathbf{z}. w^\hat{w} is a rounded weight. The gap between x^\hat{x} and xx is the error the method has to keep small.

The convention is loose, so read the surrounding sentence: in section 24.2 X^\hat{X} and W^\hat{W} are simply the rescaled matrices, not estimates. A tilde is used in a similar way for "the altered version of", such as q~\tilde{\mathbf{q}} for a query after RoPE has rotated it.

Example
x=0.137  →  x^=0.14x = 0.137 \;\to\; \hat{x} = 0.14

The stored value after rounding to two decimal places. The error is 0.003.

λ\lambda

Read "lambda". In AdamW (section 10.2) it is the weight-decay strength that pulls weights toward zero. In section 15.1 it is how many times longer a stretched context is.

The two uses are unrelated. In the AdamW update, λθ\lambda \theta shrinks every weight a little at each step; a typical value is 0.10.1. In NTK-aware scaling, λ\lambda is the new context length divided by the trained one, so going from 8k to 64k tokens means λ=8\lambda = 8.

Module 11 · Training Across Many GPUs

All−reduceAll-reduce

A collective operation in which every GPU contributes a tensor and every GPU receives the sum (or average) of all of them.

Data parallelism uses it to average gradients; tensor parallelism uses it inside every layer (sections 11.2 and 11.4).

Module 12 · Generation

PrefillanddecodePrefill and decode

Prefill processes the whole prompt in one parallel, compute-bound pass; decode then generates one token per step and is limited by memory reads.

This difference drives most serving optimizations (section 23.2).

KcacheK_{\text{cache}}

Read "K cache" and "V cache". They store the keys and values of earlier tokens during generation, so each is computed once instead of again at every step.

During generation, the keys and values of earlier tokens never change; each step only adds one new row. Storing them cuts the attention work at step tt from O(t2)\mathcal{O}(t^2) to O(t)\mathcal{O}(t), so generating TT tokens costs O(T2)\mathcal{O}(T^2) instead of O(T3)\mathcal{O}(T^3).

The cost is memory. The cache grows in proportion to context length and batch size, and for long contexts or large batches it can take more memory than the model's weights. Reducing it is the main motivation for grouped-query attention (GQA), multi-query attention (MQA) and paged attention.

x(t)x^{(t)}

Read x^(t) as "x at step t". A raised number or letter in parentheses is a label, such as a time step. It is never a power.

Kcache(t)K^{(t)}_{\text{cache}} is the cache as it stands at step tt, not the cache raised to the power tt. The parentheses are there to make that clear.

The same convention appears in xp(1)\mathbf{x}_p^{(1)} (the first image patch) and V(p)V^{(p)} (the set of tokens kept by nucleus sampling at threshold pp).

Example
x(3)  (the value at step 3)vsx3=x⋅x⋅xx^{(3)} \;\text{(the value at step 3)} \quad\text{vs}\quad x^3 = x \cdot x \cdot x

With parentheses it is a label; without, a power.

Module 14 · What the Model Learns

InductionheadInduction head

A two-layer attention circuit that, at the current token, finds an earlier occurrence of it and predicts the token that followed.

It explains how trained models copy patterns from their own context, and is thought to underlie much of in-context learning (section 14.3).

SuperpositionSuperposition

Representing many more features than there are dimensions by giving each a nearly perpendicular direction, which works because only a few features are active at once.

A cost is that single neurons respond to several unrelated features (section 14.5).

Module 15 · The LLaMA Block

RΘ,mR_{\Theta, m}

Read "R theta m". It rotates a query or key vector by an angle that grows with the token's position m, so position is stored as an amount of rotation.

RoPE (rotary position embedding) splits the vector into d/2d/2 pairs of numbers and rotates each pair, like a point on a plane, by the angle mθim\theta_i. Here mm is the position and θi=10000−2(i−1)/d\theta_i = 10000^{-2(i-1)/d} is that pair's frequency. Fast-turning pairs distinguish nearby positions; slow-turning pairs distinguish distant ones.

Two rotations combine neatly: Rm⊤Rn=Rn−mR_m^\top R_n = R_{n-m}. So the score between a query at position mm and a key at position nn depends only on the distance n−mn - m. Each token is rotated by its own absolute position, yet attention only sees relative positions, and nothing is added to the embeddings.

Example
Rm=[cos⁡mθ−sin⁡mθsin⁡mθcos⁡mθ]R_{m} = \begin{bmatrix} \cos m\theta & -\sin m\theta \\ \sin m\theta & \cos m\theta \end{bmatrix}

The rotation for one pair of numbers at position m.

{  }\{\;\}

Curly braces list the members of a set: a collection of values with no order and no repeats. Read {0, 1} as "the set of 0 and 1".

{0,1}\{0, 1\} is the set that contains exactly zero and one. A raised size after it works like Rd\mathbb{R}^d: {0,1}∣V∣\{0, 1\}^{|V|} is every vector of length ∣V∣|V| whose entries are each 00 or 11. A one-hot vector is one of these.

The …\dots inside braces means "continue the obvious pattern": {1,2,…,d/2}\{1, 2, \dots, d/2\} is every whole number from 1 to d/2d/2.

Example
{1,2,…,5}={1,2,3,4,5}\{1, 2, \dots, 5\} = \{1, 2, 3, 4, 5\}

The dots fill in the missing numbers.

R⊤R=IR^\top R = I

A matrix that only rotates (or mirrors) vectors: it keeps every length and every angle, and its transpose undoes it. R^⊤R = I says exactly that.

Because R⊤=R−1R^\top = R^{-1} (the transpose is the inverse), the RoPE identity Rm⊤Rn=Rn−mR_m^\top R_n = R_{n-m} follows in one line: undo a rotation by mm, then apply a rotation by nn, and the net rotation is by n−mn - m. And because rotations keep lengths, RoPE cannot make a query or key longer or shorter. It only turns it, so position is encoded without changing the vector's size.

Example
R=[0−110]:  R[3,4]⊤=[−4,3]⊤R = \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}: \; R[3, 4]^\top = [-4, 3]^\top

A 90° rotation. Both vectors have length 5.

RMSNorm⁡\operatorname{RMSNorm}

Read "R M S norm". It is LayerNorm without the mean subtraction and without the shift (β): divide each vector by its root mean square, then apply a learned scale.

Root mean square means: square each entry, take the mean, then the square root. RMS⁡(x)=1d∑ixi2+ϵ\operatorname{RMS}(\mathbf{x}) = \sqrt{\frac{1}{d}\sum_i x_i^2 + \epsilon}, and the layer outputs xRMS⁡(x)⊙γ\frac{\mathbf{x}}{\operatorname{RMS}(\mathbf{x})} \odot \boldsymbol{\gamma}.

Skipping the mean saves one pass over the vector. In practice it works about as well as LayerNorm, which suggests the rescaling does the useful work, not the re-centring. Gemma, LLaMA and Qwen all use it.

Example
RMS⁡([3,4])=9+162≈3.54  ⟹  [0.85, 1.13]\operatorname{RMS}([3, 4]) = \sqrt{\tfrac{9 + 16}{2}} \approx 3.54 \;\Longrightarrow\; [0.85,\, 1.13]

Ignoring ε, with γ = 1. The mean is not subtracted.

dffd_{\text{ff}}

Read "d f f". It is the width of the hidden layer inside the feed-forward block: traditionally 4 × d_model, and about 8/3 × d_model in gated versions like SwiGLU.

The feed-forward block widens each token's vector to dffd_{\text{ff}} numbers, applies a nonlinearity, and narrows it back to dmodeld_{\text{model}}. These two large matrices hold most of a transformer's parameters.

SwiGLU uses three matrices instead of two. To keep the parameter count the same, dffd_{\text{ff}} is cut to about 83dmodel\frac{8}{3}d_{\text{model}}: three matrices of width 83d\frac{8}{3}d hold as many numbers as two of width 4d4d. This keeps comparisons between the two designs fair.

Example
dmodel=768  ⟹  dff=4×768=3072d_{\text{model}} = 768 \;\Longrightarrow\; d_{\text{ff}} = 4 \times 768 = 3072

GPT-2 small.

Module 17 · Mixture of Experts

TopK⁡(G(x))\operatorname{TopK}(\mathcal{G}(\mathbf{x}))

A small gate network scores every expert for a token, only the K highest-scoring experts run, and their outputs are combined using the gate's weights.

G(x)\mathcal{G}(\mathbf{x}) (curly G, the gate) gives one score per expert. TopK⁡\operatorname{TopK} keeps the KK best, for example 8 of 64 in a fine-grained design, or 2 of 16 in a coarser one. gi(x)g_i(\mathbf{x}) is the weight for chosen expert ii's output. NEN_E is the total number of experts. The parameter count grows with the number of experts, but the compute per token grows only with KK.

The difficulty is balance. Left alone, the gate tends to send most tokens to a few favorite experts. The auxiliary loss Laux\mathcal{L}_{\text{aux}} sums fiPif_i P_i over experts, where fif_i is the fraction of tokens sent to expert ii and PiP_i its average gate probability. That sum is smallest when tokens are spread evenly.

⌈x⌉\lceil x \rceil

⌈x⌉ reads "ceiling of x" and rounds up. ⌊x⌋ reads "floor of x" and rounds down. The mixed ⌊x⌉ rounds to the nearest whole number.

Brackets with the hooks at the top on both sides round up; hooks at the bottom on both sides round down; one of each rounds to nearest.

Expert capacity in mixture-of-experts uses a ceiling because an expert cannot have a fraction of a token slot. Because capacity is a hard whole-number limit, tokens routed to an expert beyond it are dropped.

Example
⌈2.3⌉=3,⌊2.7⌋=2,⌊2.7⌉=3\lceil 2.3 \rceil = 3, \quad \lfloor 2.7 \rfloor = 2, \quad \lfloor 2.7 \rceil = 3

Round up, round down, round to nearest.

Module 20 · Adaptation: Fine-Tuning, LoRA, Distillation

W=UΣV⊤W = U\Sigma V^\top

Read "W equals U Sigma V transpose". Any matrix can be split into three steps: a rotation, a stretch along each axis, and another rotation.

UU and VV are orthogonal matrices, whose columns are perpendicular unit-length directions; each acts as a rotation (possibly with a mirror flip). Σ\Sigma (capital sigma) is diagonal: zero except on its diagonal, which holds the singular values σ1≥σ2≥⋯≥0\sigma_1 \ge \sigma_2 \ge \dots \ge 0. Each one says how strongly WW stretches along one direction.

The Eckart–Young–Mirsky theorem gives the payoff: keeping only the kk largest singular values and their directions gives the best possible approximation of WW with rank kk. That result justifies low-rank compression and motivates LoRA. LoRA adds its own bet, which the theorem does not prove but which holds well in practice: that the change fine-tuning makes to a weight matrix is close to low-rank.

W0+αrBAW_0 + \frac{\alpha}{r}BA

Read "W zero plus alpha over r, B A". Keep the pretrained weights W₀ frozen and learn a small low-rank correction BA to add to them.

B∈Rd×rB \in \mathbb{R}^{d \times r} and A∈Rr×kA \in \mathbb{R}^{r \times k}, with rr much smaller than dd (written r≪dr \ll d). Their product BABA has the same d×kd \times k shape as W0W_0 but needs only r(d+k)r(d + k) numbers. The factor α/r\alpha/r scales the correction so that changing rr does not require retuning the learning rate.

BB starts at all zeros, so ΔW=BA=0\Delta W = BA = 0 at the first step and training begins from exactly the pretrained model. After training, BABA can be added into W0W_0 once, so running the model costs nothing extra.

Example
d=k=4096,  r=8:8×(4096+4096)=65,536 vs 40962≈16.8Md = k = 4096,\; r = 8: \quad 8 \times (4096 + 4096) = 65{,}536 \text{ vs } 4096^2 \approx 16.8\text{M}

The correction trains about 0.4% as many numbers as the full matrix.

DistillationDistillation

Training a smaller student model to match a larger teacher's output distribution, or to imitate text the teacher generated.

The teacher's full distribution carries more information than a one-hot label (section 20.4).

Module 22 · Reasoning Models

Chain−of−thoughtChain-of-thought

Generating intermediate reasoning before the final answer. Each written token buys another pass of computation and becomes working memory for later tokens.

Reasoning models are trained to produce long chains with reinforcement learning on checkable problems (Module 22).

Module 24 · Quantization and Number Formats

q=clamp⁡(⌊x/s⌉+z)q = \operatorname{clamp}(\lfloor x/s \rceil + z)

Converts a real number x into a small integer q: divide by a scale s, round to the nearest integer, add a zero-point z, and clip to the allowed range.

The scale ss is how much real value one integer step stands for. The zero-point zz is the integer that stands for exactly 0.0. It must be exact, or every zero in the tensor (including padding) would come back slightly off.

The mixed brackets ⌊⋅⌉\lfloor \cdot \rceil mean round to the nearest integer. clamp⁡\operatorname{clamp} clips the result into the range the integer type can hold, from qmin⁡q_{\min} to qmax⁡q_{\max} (for example −128-128 to 127127 for 8-bit). To convert back, x^=s(q−z)\hat{x} = s(q - z). In general x^≠x\hat{x} \ne x, and keeping that error small is the whole design problem.

Example
x=0.37,  s=0.1,  z=0:q=⌊3.7⌉=4,x^=0.1×4=0.4x = 0.37,\; s = 0.1,\; z = 0: \quad q = \lfloor 3.7 \rceil = 4, \quad \hat{x} = 0.1 \times 4 = 0.4

The round trip loses 0.03.

Module 25 · Vision Transformers and Contrastive Learning

ConvolutionConvolution

Sliding a small grid of weights across an image (or sequence) and taking a dot product at each position, so the same pattern detector is reused everywhere.

Networks built from convolutions dominated computer vision before the Vision Transformer (section 25.1).

ContrastivelearningContrastive learning

Training two encoders so that matching pairs (an image and its caption) score higher than every mismatched pair in the batch.

CLIP uses a softmax over the batch; SigLIP an independent sigmoid per pair (section 25.3).

Module 28 · Generating Audio: Codecs and TTS

AutoencoderAutoencoder

A network with an encoder that compresses its input into a small latent vector and a decoder trained to reconstruct the input from it.

A neural audio codec is an autoencoder for sound (section 28.2).

Not yet used in the text

OverfittingOverfitting

When a model keeps improving on its training data while getting worse on held-out data, because it has started fitting accidents of the particular examples.

Visible as training and validation loss curves that separate (section 4.4). Remedies include more data, weight decay, dropout, a smaller model and early stopping.

EpochEpoch

One complete pass over the training data. With n examples and batch size B, an epoch is n / B steps.

Large language models usually train for about one epoch over a huge dataset and count progress in tokens instead (section 4.5).

PolicyPolicy

In reinforcement learning, a probability distribution over actions given the current state. A language model is a policy over next tokens.

The goal of RL is to change the policy to maximize expected reward (section 21.1).

AdvantageAdvantage

How much better a response scored than a typical response, R − b. Policy gradients weighted by the advantage are far less noisy than those weighted by the raw reward.

PPO gets the baseline from a value model; GRPO from the average of a group of sampled responses (sections 21.2, 21.3 and 22.3).