Module 01 · Part I · Foundations
Shapes and Linear Algebra
Scalars to Tensors, Matrix Multiplication by Hand, the Matrix Toolkit, Dot Products, Embeddings, Projections, and How Numbers Are Stored
By the end you can read any shape in the course, multiply matrices by hand, and explain what a projection keeps and throws away.
Check yourself ▸
Before you start, can you already…
- ☐describe in one paragraph what happens between typing a prompt and seeing the next word, and know how to use the course. (Module 0)
If any is shaky, the linked module teaches it.
A transformer is arithmetic on tables of numbers. This module gives you the toolkit to follow it: read a symbol such as and know what it holds, multiply matrices by hand, and say what a multiplication keeps and what it throws away.
1.1 Scalars, Vectors, Matrices, and TensorsRun this section
Everything a transformer reads, stores and produces comes in one of four arrangements, which differ in their number of : directions you can step along from one number to the next. Know a symbol's arrangement and the length of each axis, and you can follow most formulas before you know what they compute.
Scalar: One Number
A is a single number. It has no axes, because there is nothing to step along. The temperature that sets how random a model's output is (section 4.3), the step size used in training (section 2.4) and the loss that measures a model's error are all scalars. The course writes a scalar as a plain italic letter, and writes " is one real number" as .
Vector: A List
A is a list of numbers in a fixed order. It has one axis, and its length is how many numbers it holds:
Vectors are written in bold. The raised is the length of the list, not a power. One index picks one entry: is the third number. The entry is written plain rather than bold because it is a scalar. Section 1.5 shows how every token of text becomes a vector like this one, only hundreds or thousands of numbers long.
Matrix: A Table
A matrix is a table of numbers with two axes, rows and columns. Take the three tokens of "the cat sat", give each a vector of four numbers, and stack the vectors as rows:
A matrix's size is said rows first, so this is a "3 by 4" matrix holding 12 numbers. Matrices are written as capital letters. Two indices pick one entry, row first: is row 2, column 3. Row 2 on its own is the vector for "cat".
Some matrices hold data, like , one row per token. Others hold learned numbers, like the of section 1.6.
Tensor: A Stack of Tables
Add a third axis and you have a stack of matrices. A model processes several sentences at once, a , so the data entering a layer is a stack of matrices like , one per sentence:
Here is the number of sentences in the batch, the number of tokens in each, and the length of each token's vector. An array with any number of axes is called a tensor. Two sentences of three tokens with four numbers each make a 2 by 3 by 4 tensor, and multiplying the sizes gives the 24 numbers it holds. A color image is a tensor too: height by width by three color channels (section 25.2).
In code, torch.Tensor holds all four arrangements (a scalar has zero axes). In prose, "tensor" usually means three axes or more.
Choose how many axes the data has, change the sizes, and click any entry to see the indices that pick it out. In a stack, click a table’s edge or its b label to bring it forward.
A batch of 2 sentences, each 3 tokens long, each token 4 numbers. How many indices do you need to pick out one single number, and how many numbers does the whole tensor hold?
In words. The figure draws one boxed number, a row of boxes, a grid, and a stack of grids like sheets of paper; the depth of the stack is the third axis. Clicking a box shows the indices that reach it (none, one, two or three), and the readout multiplies the axis lengths to count the numbers.
Reading a Shape
The list of axis lengths is the shape. The course writes it as the raised part of , and PyTorch prints it as a tuple from x.shape. Here are the four arrangements with sizes from GPT-2 Small, whose tokens are vectors of 768 numbers:
| arrangement | axes | example | written | PyTorch shape |
|---|---|---|---|---|
| scalar | 0 | the loss | () | |
| vector | 1 | one token | (768,) | |
| matrix | 2 | a sentence of tokens | (N, 768) | |
| tensor | 3 | a batch of sentences | (B, N, 768) |
Sentences in a batch go through the same computation and never mix, so the course drops the batch axis and follows one sequence: attention in Module 6 works on an matrix, and the code puts in front of every shape.
The course counts indices from 1, as mathematics does. PyTorch counts from 0, so is x[2] in code and is X[1, 2].
Some texts call the number of axes a tensor's "rank". This course reserves rank for something else (section 1.3) and says "number of axes".
1.2 Matrix Multiplication, Done by HandRun this section
Almost every line of a transformer is a matrix multiplication, so do one by hand until the rule is automatic.
Row of and column of , multiplied entry by entry and summed, give entry of . With the shared length:
The ("sum") lets run from to and adds one term for each value. The row and column must pair up entry for entry, which is why the inner sizes have to agree.
Worked example. Multiply a 2 by 3 matrix by a 3 by 2 matrix: , . Entry is row 1 of with column 1 of : . Entry is row 1 with column 2: . Entry is , and entry is . So , a 2 by 2 matrix.
Point at an entry of AB to see which row of A and which column of B make it. Edit any number in A or B and the product updates.
In the figure, before hovering, decide which row of and which column of produce the bottom-right entry of the result. Then check whether changing a number in the first row of can ever change the bottom row of the result.
In words. The figure shows two small editable matrices and their product. Pointing at an entry of the product highlights the row and column that produce it and spells out the sum.
Two facts follow. Order matters: and usually differ, and often only one exists. And each row of depends on one row of only, so multiplying a one-token-per-row matrix by transforms every token separately, with the same .
What Operations Do to Shapes
Checking the shape of each output is the quickest way to follow a formula.
- Entry by entry. Adding two tensors, or multiplying them entry by entry (), needs the same shape and keeps it.
- By a scalar. Multiplying by a scalar scales every entry and keeps the shape.
- Dot product. Two vectors of the same length give one scalar (section 1.4).
- Along an axis. Summing or averaging along an axis removes it: the average of each row of is a vector of 3 numbers. Softmax (section 4.3) keeps the shape but also works along one axis, turning each row into probabilities separately.
- Matrix multiplication. An by matrix times an by matrix needs the two inner sizes to agree, and gives an by matrix:
The shared disappears: every token's numbers become numbers. That is the shape of every projection in section 1.6.
Worked example. Multiply the 3 by 4 matrix above by a 4 by 2 matrix . The inner sizes are both 4, so the product exists, and it is 3 by 2: three tokens, two numbers each. times is not defined at all, because a row of holds 2 numbers and a column of holds 3.
1.3 The Matrix ToolkitRun this section
These operations recur throughout the course; later sections use them without stopping.
Transpose
The swaps rows and columns: row of becomes column of , so a 3 by 2 matrix becomes 2 by 3, and . A row vector transposed is a column vector. One rule is used repeatedly: the transpose of a product reverses the order, .
Identity and Diagonal Matrices
The identity matrix is square, with 1 on its diagonal (top-left to bottom-right) and 0 elsewhere. Like the number 1, it changes nothing: .
A diagonal matrix has the entries of on its diagonal and zeros elsewhere. On the right it scales each column of a matrix by one entry of ; on the left, each row. doubles a vector's first entry and triples its second.
Inverse
The inverse of a square matrix undoes it: . A matrix that squashes some direction to zero has none, because that information is gone. A diagonal matrix with no zeros is easy to invert: divide instead of multiply, so . Sections 24.3 and 24.4 use this.
Element-Wise Product
The element-wise product multiplies entries in matching positions, so both matrices must have the same shape and the result does too. It is not matrix multiplication: . Some papers write it .
Outer Product
For column vectors (length ) and (length ), the outer product is the by matrix with entry . Every row is a multiple of , so it is the simplest possible matrix. The reverse order, , is 1 by 1: the dot product. Sections 18.1 and 20.2 build matrices from sums of outer products.
Independent Directions and Rank
Vectors are linearly independent when none can be made by scaling and adding the others: and are, but adds no new direction, being their sum. The of a matrix is the number of independent directions among its rows (equivalently, its columns), at most the smaller of its two sizes. Section 1.6 uses it to say how much of a token vector a projection keeps.
The Row-Vector Convention
This course writes a token's vector as a row (a 1 by matrix), so a weight matrix multiplies it from the right: . PyTorch's nn.Linear stores the matrix transposed and computes , the same thing. Sections 15.1 and 18.1 switch to column vectors, , to match their papers, and say so.
1.4 Dot Products, Length, and AngleRun this section
Geometric Meaning of the Dot Product
The model compares two vectors with the (or inner product): multiply entry by entry and add. The same number is the product of the two lengths times the cosine of the angle between them.
is the length of (the square root of the sum of its squared entries) and the angle between the vectors, which makes sense in any number of dimensions.
In words. Vectors pointing the same way score high, perpendicular vectors score zero, and opposite vectors score negative. The angle sets the sign; the lengths set the size.
Perpendicular vectors are called orthogonal: neither has any component along the other.
Cosine Similarity vs. Unnormalized Dot Product
Divide out both lengths and only direction remains: cosine similarity, between and .
Attention uses the raw dot product, so a longer vector produces larger scores. Length becomes a second learned signal alongside direction, for example to make one token's scores sharper than another's. The cost is that raw dot products have no fixed range, which is why Module 2 scales them down.
1.5 Embeddings: From a Token to a VectorRun this section
A model cannot do arithmetic on text, so each (a word, part of a word, or a punctuation mark) becomes a vector of fixed length:
The length is the model's width: in GPT-2 Small, in LLaMA-3 8B and in GPT-3 175B, according to their published descriptions. Section 19.1 compares current models.
From Text to Vectors: The Embedding Lookup Walk-through
How "cat" becomes a vector of length :
- Tokenization. A fixed dictionary, the , gives every token a whole-number ID from to , where is the number of entries. Say
"cat"gets ID . - One-hot encoding. On paper, the ID can be written as a : a vector of length that is at position and everywhere else.
- Row lookup. The has one row per vocabulary entry and columns (). The one-hot row times picks out row , because every other row is multiplied by zero.
Real code skips the multiplication and reads row straight from memory, which costs the same however large the vocabulary: , read "order one", meaning the cost does not grow with input size. In PyTorch this is nn.Embedding(vocab_size, d_model). The rows start random and are learned in , which nudges the model's numbers, its (or parameters), to make fewer mistakes on example text.
1.6 Linear Projections: One Vector Into ThreeRun this section
In attention, each token plays three roles: it looks for other tokens, it is found by them, and it hands information to those that find it. Rather than make one vector do all three jobs, the transformer makes three vectors from each token with three learned matrices:
is the query, the key and the value of token . Each matrix reads numbers and writes or , usually far fewer. Multiplying by such a matrix is a linear projection.
In words. One token vector, three learned matrices: the query is what the token looks for, the key what it is matched on, and the value what it passes on.
Concrete Numerical Toy Example of Q, K, V Projections
Take , , two tokens and , and these learned matrices:
Each output entry is the dot product of the input vector with one column of the matrix.
- Query for token 1. The first column of is and the second is :
- Key for token 2. The first column of is and the second is :
- Raw score. Take the dot product of the query and the key:
The raw embeddings have dot product , but the query-key score is : the score depends on the learned matrices. Training adjusts and until tokens that should attend to each other score high.
Rank and Projection Subspaces
A matrix has rank at most when is smaller (section 1.3), so each projection keeps only a -dimensional slice of the token vector, and each matrix can learn a different slice:
- the query holds the features token is searching for;
- the key holds the features token can be found by;
- the score is high when the two sets of features line up.
Module 6 turns these scores into attention.
Six token vectors, projected by two different matrices. Each keeps only the part of every vector that lies along its own direction; the strip under each plot is everything that survives.
Two tokens sit far apart in the plane. Can a projection onto a line ever put them on top of each other? Try to find a line that does it before you turn the controls.
In words. The figure projects six two-dimensional token vectors onto a query line and a key line. Each projection keeps only the part along its line, so distant tokens can land close together. Turning a line changes which tokens end up near each other, as training does when it adjusts W Q and W K.
1.7 How Numbers Are StoredRun this section
Each entry of a tensor has a . The standard is 32-bit floating point (fp32), 4 bytes per number. Large models usually train in 16-bit formats (bf16 or fp16, 2 bytes) and are often served in 8 bits or fewer (Module 24). A tensor's memory is entries times bytes per entry. GPT-2's token embedding matrix has 50,257 rows and 768 columns, which is 38,597,376 numbers: about 154 MB in fp32 and 77 MB in bf16.
Two kinds of tensor fill memory: the learned matrices, fixed while the model runs, and the , computed fresh from each input.
Every symbol and term is collected in the glossary.
Exercises
What is the shape of when and ? And is defined?
Compute entry of for and .
Compute the cosine similarity of and .
A projection matrix has shape . What is the largest rank it can have?
Use to write for a row vector , and say what shape it has when is and is .
An embedding table has 32,000 rows and 4,096 columns, stored in bf16 (2 bytes per number). How many megabytes (millions of bytes) does it take?
Explain, using the row-by-column rule, why multiplying a matrix of token vectors (one token per row) by a weight matrix never mixes information between tokens. Which operation in a transformer must therefore be responsible for moving information between tokens?
Core Academic References
- Strang (2016): Introduction to Linear Algebra (5th ed.). Wellesley-Cambridge Press.
- Golub & Van Loan (2013): Matrix Computations (4th ed.). Johns Hopkins University Press.
- Mikolov et al. (2013): Efficient Estimation of Word Representations in Vector Space (word2vec). arXiv:1301.3781
Measured labs
These labs test what this module says by running real code. Each card states the idea, what the experiment found, and what it does not prove. The numbers come from experiments/results.json, the output of running experiments/run_all.sh on the tiny-transformers reference code at version 137f7ef. The project checks fail if a measured number in the module text stops matching that file.
Lab 1a — how big the reference model is
What the module says
Module 1 explains that a token embedding is a table lookup: each token id picks one row, a vector of numbers. It also quotes parameter counts for large production models.
What the experiment found
The reference model has 112,323 parameters, which take 438.8 KiB when each is stored as a 32-bit float (fp32). That is small enough to inspect every weight yourself, which is the reason to study a model this size.
- total parameters
- 112,323
- size on disk in fp32
- 438.8 KiB
- vocabulary size
- 67
- position table parameters
- 4,096
- characters of training text
- 1,059,620
2 blocks, , feed-forward width , 2 attention heads
each token is one character, not a word piece
learned during training, not the fixed sine waves of section 7.1
What this does not prove
The two embedding tables (tokens and positions) hold 8,384 of the 112,323 parameters, about 7.5%. This lab counts parameters; it does not measure how the share changes in larger models, where the vocabulary and width are both far bigger.
Run it yourself
cd tiny-transformers && .venv/bin/python experiments/parameter_count.pyThe code being tested