Introduction
By the end of this chapter you will be able to draw the whole pipeline of a language model on a whiteboard, say what every box does, count its parameters, and explain why a machine that only predicts the next token can hold a conversation.
Type a half-finished sentence into a modern language model and it finishes it. Ask it a question and it answers in fluent paragraphs. How can a program do that? There is no grammar table inside, no dictionary of facts, no list of rules. What is actually running?
Here is the honest answer, and it is smaller than most people expect. A large language model is a single mathematical function. It takes a sequence of tokens (pieces of text) and outputs one probability distribution: what comes next? That is the whole job.
Everything else, the essays, the code, the conversations, comes from calling that function over and over. Predict the next token, pick one, glue it on, predict again. This loop is called autoregression, and it is the first idea to get into your bones. The rest of this course is about what happens inside the function.
Think of the model as a very well-read person playing "guess the next word" on a text they have never seen. They do not need to know what the whole essay will say. They only ever need to answer: given everything so far, what is the most plausible next piece? Do that a thousand times and you have written an essay.
The one function that does everything
Let's make the claim precise. Write the tokens seen so far as $x_1, x_2, \dots, x_t$. The model is a function $f_\theta$ with parameters $\theta$ (millions or billions of numbers that were learned from data). Here is what it computes:
$$p(x_{t+1} \mid x_1, \dots, x_t) = f_\theta(x_1, \dots, x_t)$$Read it as: "the probability of each possible next token, given the tokens so far, is whatever $f_\theta$ outputs." The output is a vector with one entry per token in the vocabulary, all entries non-negative and summing to one. Nothing about the sentence's meaning is stored anywhere explicitly. Meaning is whatever the parameters need to encode in order to be good at this guessing game.
Why is this one question enough? Because the probability of a whole sequence factorises into a product of next-token probabilities. This is just the chain rule of probability, nothing deep:
$$p(x_1, x_2, \dots, x_T) = \prod_{t=1}^{T} p(x_t \mid x_1, \dots, x_{t-1})$$So a model that can answer "what comes next?" perfectly is, in principle, a model that assigns the right probability to every possible text. Being a good next-token predictor is the same thing as being a good model of language. That is why this humble objective scales to such surprising behaviour.
Suppose the vocabulary is just five tokens: the, cat, sat, on, mat. The prompt so far is "the cat". A model might output $p(\text{sat}) = 0.7$, $p(\text{on}) = 0.1$, $p(\text{the}) = 0.1$, $p(\text{cat}) = 0.05$, $p(\text{mat}) = 0.05$. We sample sat. Now the input is "the cat sat" and we ask again; this time on gets most of the mass. Three more calls and we have "the cat sat on the mat". The model never planned the sentence. It just kept answering one question well.
Autoregression: the loop that writes
The function on its own produces nothing readable. It is the loop around it that writes text. Here is the loop in full, and it really is this short:
Symbols
$x_{1..t}$ = tokens so far$V$ = vocabulary size
$\theta$ = the model's parameters
$p \in \mathbb{R}^V$ = next-token distribution
Predict
Run $f_\theta$ on the tokens so far. Get a probability for every one of the $V$ tokens.Choose
Pick one token from that distribution: the most likely one (greedy) or a random draw (sampling).Append
Add the chosen token to the end of the sequence. It is now part of the input.Repeat
Go back to Step 1 until a stop token appears or a length limit is hit.Two things in that loop matter more than they look. First, the model's own output becomes its next input. That is why it can go off the rails: one unlucky token early on changes everything after it. Second, the choice in Step 2 is where "creativity" lives. Always picking the most likely token gives dull, repetitive text; sampling with a bit of randomness gives variety. The Learning to Predict chapter and code/lumen/sampling.py cover temperature, top-k and top-p in detail.
Try the loop yourself. The model below is deliberately tiny: fifteen tokens and a hand-written table of "how often does token B follow token A" (a bigram table, with a couple of three-token overrides). It is not a neural network. But the loop around it is exactly the loop around GPT-4, and watching it run makes autoregression concrete.
Each press shows the model's probability bars for the next token, picks one, and appends it. Lower the temperature to make it greedy; raise it to make it random.
"The model predicts the next word." Not quite. It predicts the next token, which may be a word, part of a word, a punctuation mark, or a few bytes of an emoji. This distinction causes a surprising number of real quirks (why models struggle to count letters, for example). The Tokenization chapter is entirely about it.
The whole pipeline on one whiteboard
Now let's open the function. What happens between "a string of text goes in" and "a probability for every token comes out"? There are seven stages. Each one gets its own chapter in this part of the course; here we only need the shape.
Stage 1: text → tokens
Neural networks eat numbers, not letters. A tokenizer chops the input string into pieces from a fixed vocabulary (GPT-2's has 50,257 entries) and replaces each piece with its integer id. "the cat sat" might become [464, 3797, 3332]. The pieces are learned by a compression-like algorithm called byte-pair encoding, and the choices it makes leak into model behaviour in odd ways. All of that is the Tokenization chapter.
Stage 2: tokens → embeddings (+ position)
An integer id is not something you can do calculus with. So the model keeps a big table with one row of $d_{model}$ numbers per vocabulary entry (768 numbers for GPT-2 small) and looks up the row for each token. These learned rows are embeddings. The model also needs to know where each token sits, because "dog bites man" and "man bites dog" contain the same tokens. Position information is added to the embedding. The Embedding Layer and Positional Encoding chapters cover both.
Stage 3: N transformer blocks
Now every token is a vector of $d_{model}$ numbers. The stack of transformer blocks refines those vectors, one block at a time, so that by the end the vector at position $t$ contains everything needed to predict token $t+1$. Every block has two halves. Attention lets each token look at the others and pull in relevant information ("I am 'sat', and there is a 'cat' two places back, so the subject is an animal"). The MLP then processes each token vector on its own, which is where a lot of factual knowledge seems to live. Both halves add their result to the vector rather than replacing it, so early information survives to the end. That is the residual connection, and it is the reason deep stacks train at all. Attention is the Attention chapter; the MLP, normalisation and residual stream are the Layers of Understanding chapter.
Stage 4: unembedding
After the last block, the vector at the final position is multiplied by a $V \times d_{model}$ matrix to give one raw score per vocabulary entry. These scores are called logits. Often this matrix is literally the same table used for embedding in stage 2, read in the other direction; that trick is called weight tying, and the Embedding Layer chapter explains when it helps.
Stage 5: softmax over the vocabulary
Logits can be any real numbers. To turn them into probabilities we exponentiate each one and divide by the total, so the result is positive and sums to one. This is the softmax function, and it appears again inside attention, so it is worth knowing well:
$$p_i = \frac{e^{z_i}}{\sum_{j=1}^{V} e^{z_j}}$$Here $z_i$ is the logit for token $i$ and $p_i$ is its probability. Bigger logits get exponentially more mass, so softmax is a "soft" version of picking the maximum, hence the name. With logits $[2, 1, 0]$: $e^2 \approx 7.39$, $e^1 \approx 2.72$, $e^0 = 1$, total $11.11$, probabilities $[0.67, 0.24, 0.09]$. Check that they sum to one.
Stage 6: sample
Pick a token from the distribution. Greedy decoding always takes the top one. Sampling draws at random in proportion to the probabilities, often after sharpening or flattening them with a temperature. The Learning to Predict chapter and code/lumen/sampling.py go through temperature, top-k and top-p.
Stage 7: append and repeat
The chosen token joins the input and the whole thing runs again. Naively this recomputes everything from scratch each step; in practice the model caches the intermediate results for earlier tokens (the "KV cache"), which is what makes generation fast enough to use. That is the Inference chapter and code/lumen/kv_cache.py.
Every stage above operates on all positions at once. If the input has 500 tokens, there are 500 vectors flowing through the blocks in parallel, and the model produces 500 next-token distributions (one for each prefix). During generation we only use the last one. During training we use all of them, which is a big part of why transformers train efficiently.
A short history: how we got here
Predicting the next word is an old idea. What changed is the machinery that does the predicting. Knowing the lineage helps, because each step was a response to a concrete failure of the previous one.
n-grams: counting
The simplest next-token predictor is a table. Count how often each word follows each pair of previous words in a big corpus, and predict by looking up the counts. These n-gram models powered speech recognition and machine translation for decades. Their problem is sparsity: with a 50,000-word vocabulary there are $50000^3 \approx 10^{14}$ possible trigrams, and almost all of them never appear in any corpus. The table has no idea that "the cat sat" and "the dog sat" are related, because it has never seen either. Our toy interactive above is an n-gram model, which is why it can only ever say things we wrote into its table.
Neural language models: similarity
Bengio et al. (2003) proposed replacing the table with a neural network that first maps each word to a learned vector (an embedding), then predicts from the vectors. Now "cat" and "dog" can end up with similar vectors, so evidence about one transfers to the other. This is the ancestor of stage 2 in our pipeline. It fixed sparsity but still looked at a fixed window of a few previous words.
RNNs and LSTMs: memory, one step at a time
Recurrent neural networks read the sequence one token at a time, carrying a hidden state vector forward as a summary of everything read so far. In principle the summary can hold arbitrarily long context. In practice two things broke. First, gradients flowing back through many steps either vanish or explode, so the network forgets; the LSTM (Hochreiter & Schmidhuber, 1997) added gates to fix this and worked much better, but a fixed-size state still had to squeeze a whole paragraph into a few hundred numbers. Second, and decisively, the computation is sequential: token 500 cannot be processed until token 499 is done. GPUs are good at doing a million things at once and bad at doing one thing a million times in a row, so RNNs could not use the hardware that was becoming available.
Transformers: attention, in parallel
Vaswani et al. (2017) threw away recurrence. Instead of a summary state, every token gets to look directly at every earlier token and pull in what it needs, through a mechanism called attention (which had earlier been bolted onto RNNs for translation by Bahdanau et al., 2014). Because each position's computation depends only on the input, not on a previous position's result, all positions are computed in one big matrix multiplication, which is exactly what GPUs are built for. Long-range dependencies are one hop away instead of hundreds. The paper's title, "Attention Is All You Need", was a claim that the recurrent part was unnecessary, and it turned out to be right.
Vaswani et al. (2017), "Attention Is All You Need", was a machine-translation paper. The architecture it introduced had an encoder and a decoder; the models in this course use only the decoder half, which is the part that predicts next tokens.
GPT-1, GPT-2, GPT-3: the same recipe, bigger
Radford et al. (2018) at OpenAI took the decoder, trained it as a plain next-token predictor on books, and showed that this "pre-training" gave a model that could be fine-tuned to many tasks. GPT-2 (2019) scaled the same recipe to 1.5 billion parameters and web text, and found that the model could do tasks nobody trained it for, just by being prompted. GPT-3 (Brown et al., 2020) scaled to 175 billion and made that "in-context learning" the main event. The architecture barely changed between these three; the discovery was that performance keeps improving predictably with more parameters, more data and more compute, a relationship studied as scaling laws (Kaplan et al., 2020; Hoffmann et al., 2022) that the Scaling Laws chapter covers.
Instruction-tuned assistants
A raw next-token predictor does not answer questions; it continues text. Ask it "What is the capital of France?" and it may well continue with "What is the capital of Germany?" because that is what a list of quiz questions looks like. Ouyang et al. (2022) showed how to take such a model and teach it to be helpful by fine-tuning on examples of good responses and then on human preferences (InstructGPT, the direct ancestor of ChatGPT). That post-training stage is the subject of the Instruction Tuning and RLHF chapter and the whole Post-Training part of the course.
What "parameters" are and where they live
You keep hearing "124 million parameters" or "70 billion parameters". What is being counted? A parameter is one number inside the model that was set by training rather than by the programmer. Almost all of them live in matrices: the embedding table, and the weight matrices inside attention and the MLP of every block. When you download a model, you are downloading these numbers.
The best way to understand parameter counts is to do one by hand. Let's take GPT-2 small, the model you will build in the GPT-2 from Scratch chapter. Its shape is: vocabulary $V = 50257$, width $d = 768$, context length $L = 1024$, $N = 12$ blocks, MLP hidden width $4d = 3072$.
| Component | Shape | Parameters | Share |
|---|---|---|---|
| Token embedding | $V \times d$ = 50257 × 768 | 38,597,376 | 31.0% |
| Position embedding | $L \times d$ = 1024 × 768 | 786,432 | 0.6% |
| Attention, per block | $4d^2 + 4d$ (Q, K, V, output projections + biases) | 2,362,368 | |
| Attention, all 12 blocks | 28,348,416 | 22.8% | |
| MLP, per block | $8d^2 + 5d$ (up-projection $d\to4d$, down-projection $4d \to d$, biases) | 4,722,432 | |
| MLP, all 12 blocks | 56,669,184 | 45.5% | |
| LayerNorms (2 per block + final) | 25 × 2d | 38,400 | 0.03% |
| Unembedding | tied to token embedding | 0 | |
| Total | 124,439,808 | 100% |
Three things to notice. The MLPs hold nearly half the parameters, more than attention, even though attention gets all the press. The embedding table is a third of this small model, but it does not grow with depth, so in bigger models it becomes a small fraction. And the number of attention heads does not appear anywhere: splitting $d = 768$ into 12 heads of 64 or 6 heads of 128 uses the same matrices, just sliced differently.
Explore this yourself. The sliders below let you change every dimension and watch where the parameters go. Try the presets: GPT-2 small, medium, large and XL share one recipe and differ only in $d$, $N$ and head count.
Watch how the split between embeddings, attention and MLP shifts as the model gets wider or deeper. Notice that the head count changes nothing.
Those are the numbers in the GPT-2 release. The explorer reproduces them exactly because the formula above is the real one: for GPT-2 the only ingredients are $V$, $d$, $L$, $N$, and the fact that the MLP is four times wider than $d$. Modern models change the details (no biases, a different MLP shape, grouped-query attention) but the bookkeeping is identical.
Training versus inference
The same function is used in two very different ways, and confusing them causes real misunderstandings. Training is how the parameters get their values. Inference is using the model with its parameters frozen. Here is the split.
Training
Feed in a chunk of real text. At every position, compare the model's predicted distribution with the token that actually came next. Measure the mismatch with a loss (cross-entropy: how surprised was the model?). Compute the gradient of that loss with respect to every parameter, and nudge every parameter a tiny bit in the direction that reduces the surprise. Repeat for trillions of tokens.
Every position is scored in parallel, since the true next token is already known. No sampling happens. Costs roughly three times the compute of a forward pass, because of the backward pass.
Inference
Feed in a prompt. Run the forward pass, take the distribution at the last position, choose a token, append, repeat. Parameters never change. The model has no memory of previous conversations; every request starts from the parameters as they were saved.
Sequential by nature (each token depends on the previous choice), so the engineering problem is different: keep the weights in fast memory, cache what you can, batch many users together. That is the Inference part of the course.
"The model learns from my conversation." During inference, nothing is learned: the parameters are read-only. What looks like learning within a chat is the model conditioning on the earlier tokens in its context window, which vanishes when the conversation ends. Actual learning only happens when someone runs a training job and saves new parameters.
The three phases of a modern LLM's life
A model you can chat with has been through three distinct stages, each with its own data, objective and cost profile. This course is organised around them.
Pre-training
Take a randomly initialised transformer and train it on as much text as you can get, with the plain next-token objective. This is where the model learns grammar, facts, code, and (implicitly) a great deal about how the world works, because predicting text well requires it. It is by far the most expensive phase: GPT-3 was trained on roughly 300 billion tokens; Llama 3 models on around 15 trillion (Dubey et al., 2024). The result, often called a base model, is a superb autocomplete and a poor assistant. The Pre-Training part of the course, starting with its overview, is all about this phase.
Post-training
Take the base model and shape its behaviour. Supervised fine-tuning on example conversations teaches the format of an assistant. Preference optimisation (RLHF, DPO and relatives) teaches it to prefer responses that people rate highly. Further stages can teach tool use, refusals, and reasoning. This uses a tiny fraction of the pre-training compute but has an outsized effect on how the model feels to use. Instruction Tuning and RLHF is the introduction; the Post-Training part goes deep.
Deployment
Freeze the weights and serve them. The problems now are speed, memory and cost: how to run a 70-billion-parameter model fast enough to feel interactive, for thousands of users at once. This drives a separate body of techniques (KV caching, batching, quantisation, speculative decoding) that the Inference part covers.
What this part of the course will build
Over the next eight chapters we open each box in Figure 1 and then assemble them into a working GPT-2 that loads OpenAI's released weights and generates text. Here is the route, so you know where every piece fits:
| Chapter | Box in Figure 1 | The problem it solves |
|---|---|---|
| Tokenization | text → tokens | Text is not numbers; which pieces should the model see? |
| The Embedding Layer | tokens → vectors | Ids have no notion of similarity; vectors do. |
| Positional Encoding | + position | Attention cannot tell order without help. |
| Attention | tokens talk | Each token needs information from the others. |
| Layers of Understanding | MLP, norms, residuals | Deep stacks need to be trainable and expressive. |
| Learning to Predict | softmax, loss, sampling | How the numbers get learned and how text gets chosen. |
| Instruction Tuning and RLHF | the whole model, reshaped | A predictor is not an assistant. |
| GPT-2 from Scratch | everything | Put it together and load real weights. |
Each chapter has companion code in code/lumen/. The pieces compose: tokenizer.py feeds embeddings.py, which feeds attention.py and block.py, which gpt2.py stacks. By the end you will have written every line of a language model yourself.
Practice
Write the autoregression loop from the symbol strip as a Python function generate(model, tokens, n) that takes any callable model(tokens) -> probs (a list of $V$ probabilities) and returns tokens extended by n sampled tokens. Test it with a model that returns a fixed distribution, then with a bigram table like the one in the interactive. Compare greedy and sampled outputs over 20 runs. You will reuse this function with the real model in code/lumen/sampling.py.
Solution sketch
import random
def generate(model, tokens, n, greedy=False):
tokens = list(tokens)
for _ in range(n):
probs = model(tokens) # STEP 1: predict
if greedy:
nxt = max(range(len(probs)), key=probs.__getitem__)
else:
nxt = random.choices(range(len(probs)), weights=probs)[0] # STEP 2: choose
tokens.append(nxt) # STEP 3: append
return tokens # STEP 4 is the for-loop
A bigram model is lambda toks: table[toks[-1]] where each row of table sums to one. Greedy runs are identical every time; sampled runs differ, and with a bigram table you will see loops like "the cat sat on the mat . the cat…" because the model has no memory beyond one token.
Llama-style models drop the biases, use no learned positional table (they use RoPE, see the positional encoding chapter), and use a "gated" MLP with three matrices of shape $d \times d_{ff}$ instead of two. Write down the parameter formula for such a model, then plug in $d = 4096$, $d_{ff} = 14336$, $N = 32$, $V = 128256$ with an untied output layer. Compare to the reported size of Llama 3 8B. (Ignore the small reduction from grouped-query attention for now; then read about it in the attention chapter and redo the count.)
Solution sketch
Embedding: $128256 \times 4096 \approx 525\text{M}$. Untied output: another $525\text{M}$. Per block attention with full multi-head: $4d^2 \approx 67.1\text{M}$; per block MLP: $3 \times d \times d_{ff} \approx 176.2\text{M}$; per block total $\approx 243\text{M}$, times 32 $\approx 7.79\text{B}$. Add the two embedding matrices: $\approx 8.84\text{B}$. Llama 3 8B actually uses grouped-query attention with 8 key/value heads instead of 32, which shrinks the K and V projections to $d \times 1024$ each and brings the total to the reported $\approx 8.03\text{B}$. The MLP is still about 70% of the model.
The chain rule says $p(x_1, \dots, x_T) = \prod_t p(x_t \mid x_{<t})$. Suppose instead you tried to model $p(x_1, \dots, x_T)$ directly as a table for sequences of length $T = 10$ over a vocabulary of $V = 50000$. How many entries would the table have? Now count the number of outputs a next-token model needs to produce for a sequence of length 10. Explain in one sentence why this makes next-token prediction the practical choice.
Solution sketch
A direct table needs $V^T = 50000^{10} \approx 10^{47}$ entries, more than the number of atoms in the Earth. A next-token model produces $T \times V = 500{,}000$ numbers for the same sequence and shares its parameters across all positions. The factorisation turns an impossible joint distribution into a sequence of ordinary classification problems, each of which a neural network can handle.
Key takeaways
- A language model is one function: tokens in, a probability for every possible next token out. Text comes from calling it in a loop (autoregression).
- The chain rule of probability makes next-token prediction equivalent to modelling whole sequences, which is why such a simple objective goes so far.
- The pipeline is tokenize → embed (+position) → N blocks of attention and MLP with residual adds → unembed → softmax → sample → append.
- Parameters are the learned numbers in the matrices. For GPT-2 small: 124M, roughly 31% embeddings, 23% attention, 45% MLP. Head count does not affect the total.
- Training updates parameters from known text in parallel; inference generates with frozen parameters, one token per pass.
- A modern model lives three lives: pre-training (knowledge), post-training (behaviour), deployment (speed and cost).
Further reading
- Vaswani et al. (2017). Attention Is All You Need. The transformer paper; short and readable once you finish this part of the course.
- Radford et al. (2019). Language Models are Unsupervised Multitask Learners. The GPT-2 report, and the model you will rebuild.
- Brown et al. (2020). Language Models are Few-Shot Learners. GPT-3 and in-context learning.
- Bengio et al. (2003). A Neural Probabilistic Language Model. Where learned word embeddings for language modelling began.
- Ouyang et al. (2022). Training language models to follow instructions with human feedback. InstructGPT: how a predictor becomes an assistant.
- Kaplan et al. (2020). Scaling Laws for Neural Language Models. Why "just make it bigger" was a rational strategy.
- Karpathy. nanoGPT. A minimal GPT-2 implementation; a good thing to read alongside
code/lumen/gpt2.py.