What exactly the model learned — and how to measure it with a single number, without relying on anecdotes.
GPT-2 was never taught to answer questions, summarize texts, translate or write code. It was trained on a single task, repeated billions of times:
This is called causal language modeling (CLM). Formally, the model learns the probability of an entire sequence, decomposed by the chain rule:
To predict the next word well in arbitrary texts from the internet, the model is forced to learn, as a side effect: spelling, grammar, agreement, facts about the world, the structure of arguments, code formats, and even rudiments of reasoning.
Think of completing "The capital of Japan is ____". There is no statistical shortcut: to get it right, you have to know. The training objective is trivial; the pressure it exerts is not. That was the big bet of the GPT-2 paper — and it won.
Each sequence of
One sequence, many examples:
input The capital of France is
target capital of France is Paris
^ ^ ^ ^ ^
5 predictions, 5 losses, 1 pass through the model
Alignment in code: logits[:, :-1] against labels[:, 1:]
(drops the last prediction, which has no target, and the first
token, which is predicted by nobody)
How is a mistake punished? With the negative logarithm of the probability assigned to the correct token:
Three reasons, and all three are worth understanding:
The loss is useful but not very intuitive. Perplexity is simply its exponential:
And it has a direct and very useful reading:
Perplexity is the effective number of options the model is hesitating between, at each word.
PPL = 1 → absolute certainty, always. PPL = 25 → it is as if, at each word, the model were choosing randomly among 25 equally likely candidates. PPL = 50,257 → the model learned nothing; it is guessing uniformly over the entire vocabulary.
Lower is better. Always.
| Situation | Approximate PPL |
|---|---|
| Uniform guess over the vocabulary | 50,257 |
| Trigram model (1990s) | ~150 |
| GPT-2 small, English text | ~25–30 |
| GPT-2 XL, English text | ~15–18 |
| GPT-3 (175 B) | ~10 |
| Frontier models, 2026 | < 8 |
| Estimate for a human | ~10–12 |
This is the most common trap, and it invalidates many published comparisons. Perplexity is measured per token. If model A uses a tokenizer that breaks the text into 100 tokens and model B uses one that breaks it into 150, model B looks better just because it is predicting smaller, easier pieces.
The whole GPT-2 family shares the same tokenizer, so comparing them against each other is legitimate. Comparing the PPL of a GPT-2 with that of a Llama is comparing different things — unless you normalize per character or per byte (the bits-per-character and bits-per-byte metrics exist precisely for that).
This also explains why GPT-2's PPL in Portuguese will look high: besides the model not knowing the language well, each word is being broken into more tokens.
| Item | Detail |
|---|---|
| Corpus | WebText: ~8 million pages, ~40 GB of text. Built by scraping every outbound link posted on Reddit with at least 3 karma — a cheap and ingenious quality filter, using already-existing human curation. |
| Filtering | Wikipedia was removed on purpose, to avoid contaminating evaluations. Duplicates removed. |
| Objective | Pure CLM. No instructions, no RLHF, no chat. GPT-2 is not an assistant — it is a text completer. |
| Context | 1024 tokens. Documents separated by <|endoftext|>. |
| Optimizer | Adam, with learning-rate warmup and cosine decay. |
| Epochs | Approximately 1. The model saw each text essentially once. |
If you write "What is the capital of France?", GPT-2 will not answer. It will continue the text, and the most likely continuation of a question on the internet is… another question. It may return "What is the capital of Germany? What is the capital of Italy?".
This is not a failure of the model — it is the model working exactly as trained. The distance between GPT-2 and ChatGPT is not mainly size: it is instruction fine-tuning and RLHF, which came later and teach the model to treat the text as a request to be fulfilled rather than a passage to be continued.
Practical consequence: with GPT-2, write prompts in the form of a beginning of a text, not a question. "The capital of France is" works; "What is the capital of France?" does not.
# perplexity of a text, the right way import torch from transformers import AutoTokenizer, AutoModelForCausalLM tok = AutoTokenizer.from_pretrained("openai-community/gpt2") mod = AutoModelForCausalLM.from_pretrained("openai-community/gpt2").eval() def perplexidade(texto): ids = tok(texto, return_tensors="pt", truncation=True, max_length=1024) # by passing labels=input_ids, transformers already does the # 1-position shift and computes the mean cross-entropy. with torch.no_grad(): perda = mod(**ids, labels=ids["input_ids"]).loss return torch.exp(perda).item() print(perplexidade("The capital of France is Paris.")) # low print(perplexidade("Colorless green ideas sleep furiously.")) # high
.venv\Scripts\python.exe lab\08_perplexity.py
| Model | Parameters | PPL | Compared to the previous one |
|---|---|---|---|
openai-gpt | 117 M | 46.07 | — |
gpt2 | 124 M | 21.70 | improved |
gpt2-medium | 355 M | 16.04 | improved |
gpt2-large | 774 M | 14.30 | improved |
gpt2-xl | 1558 M | 12.93 | improved |
Monotonic at every step. No inversion, no surprise. Compare with chapter 06, where large "missed" a question that medium "got right".
The models are the same in both experiments. What changed was the metric. A single sample measures noise; perplexity measures the distribution. Keep this pair of results — it is the best methodology lesson in this course.
Also note the jump GPT-1 → GPT-2: from 46 to 21.7 with practically the same number of parameters (117 M vs 124 M). That was not scale. It was the better corpus, the better tokenizer and Pre-LN. It is the subject of the next chapter.
| Text | PPL |
|---|---|
| Famous cliché: "It was the best of times…" | 5.8 |
| Python code | 8.6 |
| Natural English | 21.7 |
| Natural Portuguese | 413.1 |
| Random characters | 469.4 |
| English with shuffled words | 3,874.0 |
| Chomsky: "Colorless green ideas sleep furiously" | 6,413.3 |
Pure noise comes out eight times cheaper than shuffled English, and thirteen times cheaper than Chomsky's sentence. This seems strange until you understand what perplexity really measures.
After the first few random characters, the model enters a "this is noise" regime and starts expecting more noise — which it does reasonably well. The distribution becomes flat, but correct.
Shuffled text, on the other hand, activates all of the model's grammatical expectations and then violates them, one by one. Each violation is expensive. Chomsky's sentence does the same at the semantic level: impeccable syntax, impossible meaning.
Useful corollary: perplexity is not a measure of text quality. A text can have a very low PPL because it is generic and memorized (see the cliché, at 5.8). Using PPL as a proxy for "quality" is a common mistake.
Methodological caveat: Chomsky's sentence has only 7 tokens. Averages over tiny samples are unstable, and a single improbable token dominates the result. Treat that number as illustrative. General rule: distrust perplexity computed on short texts.
The primary sources for the concepts in this chapter. The numbers in the text were measured in the lab; the ideas come from here.
Technical terms here carry their machine-learning meaning. The course glossary shows that meaning next to the others the same words have in IT.
End of Part II. You understand the entire GPT family: how it is assembled, how it chooses words, and how it is measured.
Part III crosses over to the other branch of the tree — and chapter 09 first settles the account with GPT-1.