Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path →
Textbooks are
all you need.
The reigning wisdom was blunt: bigger models, more data, better results. Then a 1.3-billion-parameter model — a tenth the size of its rivals — matched them on coding, not by being cleverer but by being fed better. Not more internet, but curated, textbook-quality examples. The lesson landed hard: what a model learns depends less on how many tokens it sees than on how much of each token actually teaches. Here's the data-quality argument, made quantitative.
What changes against Chinchilla: the axis it never measured
Rung 5 answers "how many tokens" and is silent on "which tokens". Its curves are fitted over a fixed corpus, so data is a scalar — a count. This rung's claim is that the count is not the whole story: that curating and synthesising higher-quality training data changes the loss-versus-compute picture enough to matter, and it argues the case in the most awkward possible way — by training a model far off Chinchilla-optimal and doing well anyway.
In the ladder's units, this is the smallest model on it since rung 1: 1.3B parameters, trained on about 7B unique tokens of filtered and synthetically generated "textbook-quality" material, seen about 50B times over. That is only about 5 unique tokens per parameter (about 38 seen, with heavy repetition), far below rung 5's ~20:1 in unique data — a configuration rung 5 would call data-starved — and it reports roughly 50% pass@1 on HumanEval, in the neighbourhood of models an order of magnitude larger.
Read against rung 5, the two are not in conflict so much as orthogonal: Chinchilla tells you how to spend a budget on a given corpus, and this rung says the corpus is a variable you were treating as a constant.
Scale vs quality
The scaling laws gave the field a simple, powerful recipe: capability rises predictably with model size, data, and compute. Bigger, trained on more, is better. It worked so well it became the default strategy — pour in web-scale data, grow the parameter count, watch benchmarks climb.
But that framing quietly assumes all tokens are equal. Web data is not: it's a mix of the brilliant and the banal, the correct and the wrong, the novel and the thousandth near-duplicate. Phi's question was whether the composition of the data — its quality — is a lever as powerful as its sheer quantity. If you could feed a model only the good stuff, how small could the model, and the dataset, be?
What teaches a model is useful signal, not raw tokens — so a small model on curated, high-quality data can match a much larger one trained on noisy web text.
Textbook-quality data
Phi's core move is to treat data quality as the primary design variable. It built a training set of what the authors call textbook-quality data — clear, correct, self-contained, pedagogically structured examples, the way a good textbook explains a concept rather than the way a random forum post does. Two ingredients:
The formalization is simple. Not every token carries useful learning signal; if a fraction q (the quality) does, the effective signal in a dataset of N tokens is N·q. Web data is enormous N with tiny q; textbook data is small N with q near 1 — and the product can favor the small clean set.
Forty times fewer raw tokens, more actual teaching — because the curated set wastes almost nothing. The runnable version below computes this trade and the compute a smaller model saves.
Why quality wins
Why should clean data be so much more efficient? A few reasons stack up. Redundancy: web corpora repeat the same easy patterns endlessly, so most tokens teach nothing new — the model has already learned them. Noise: incorrect or low-quality examples actively mislead, spending capacity on things you'd rather the model not learn. Density: a textbook introduces concepts deliberately, in a logical order, with worked examples — a far higher rate of genuinely new, correct information per token.
Put together, curated data means the model spends every parameter and every gradient step on signal instead of drowning it in noise and repetition. That's why a small model can keep up: it isn't wasting its limited capacity memorizing junk. Quality doesn't add a constant bonus — it changes the exchange rate between tokens and learning.
How phi-1's data and training were built, step by step
The model in "Textbooks Are All You Need" is ordinary; the method is the data pipeline, and two stronger OpenAI models do most of the work in it. The paper's thesis is that capability depends less on model size than on how instructive each training token is, and this pipeline is its working definition of instructive. In order:
- Start from deduplicated public code. The Python subset of The Stack plus StackOverflow: about 35M files and samples, more than 35B tokens.
- Label a small sample with GPT-4. About 100k samples were shown to GPT-4 with a prompt asking it to judge each snippet's educational value for a student whose goal is to learn basic coding concepts.
- Train a cheap filter and run it everywhere. A random-forest classifier learns to predict GPT-4's judgment from the snippet's output embedding under a pretrained CodeGen model. Running that classifier, not GPT-4, over the full corpus is what makes filtering 35B tokens affordable. About 6B tokens survive.
- Generate synthetic textbooks. GPT-3.5 writes under 1B tokens of Python textbook text, explanations interleaved with code. To stop the samples repeating each other, generation is steered by constraints on topic and target audience; the authors point out that diversity, not just correctness, is the hard part of synthetic data.
- Pre-train phi-1-base on CodeTextbook. Filtered code plus synthetic textbooks, about 7B tokens. The model is a 1.3B-parameter decoder-only Transformer: 24 layers, hidden size 2,048, 32 attention heads of size 64, rotary position embeddings and FlashAttention, with attention and MLP blocks run in parallel as in CodeGen and GPT-J, and CodeGen's tokenizer. Training uses AdamW with an effective batch of 1,024 sequences of 2,048 tokens. The released base checkpoint is the one at 24,000 steps: about eight passes over the data and a little over 50B tokens seen. It scores 29% on HumanEval.
- Generate CodeExercises. GPT-3.5 writes about 180M tokens of exercises, each a function signature and docstring to complete, followed by a solution. Diversity again comes from constraints, this time on the function names in the prompts.
- Fine-tune into phi-1. Continue training phi-1-base on CodeExercises with the same next-token loss in a short run at a lower learning rate, keeping the best checkpoint. HumanEval pass@1 rises from 29% to 50.6%, and MBPP reaches 55.5%. The paper puts the whole training at about four days on eight A100 GPUs.
- Repeat at 350M. phi-1-small goes through the same pipeline and reaches 45% on HumanEval.
Two claims the recipe makes
First, that filtering and synthesis change what each token is worth: the paper trains the same model sizes on the unfiltered Stack and StackOverflow data and scores markedly lower on HumanEval. Second, that a small fine-tune can unlock more than it contains. After CodeExercises, phi-1 became noticeably better at things the exercises never covered, such as using libraries like Pygame and Tkinter, which the authors read as fine-tuning reorganizing knowledge learned in pre-training rather than adding new knowledge.
The filter, the objective and the token budget
φCodeGen(x)— the embedding of snippet x from a pretrained CodeGen model;f— the random forest;y^GPT-4— GPT-4's educational-value judgment on the labeled sample.L— ordinary next-token cross-entropy. Nothing in the objective is new; the novelty is entirely in which x get sampled.Dseen— tokens seen, not unique tokens: about 50B seen from about 7B unique, roughly 38 per parameter. That is above Chinchilla's ~20, even though the unique-token ratio is only about 5.C— about 3.9 × 10^20 FLOPs for N = 1.3 × 10^9, roughly 800 times less than GPT-3's 3.14 × 10^23.
At the extremes: a classifier that keeps everything reproduces the unfiltered baseline, which the paper shows scoring markedly lower; one that keeps almost nothing leaves too few unique tokens, so the same data repeats more and more often within a fixed budget.
What phi-1 was compared against, and what held up
Evaluation is pass@1 on HumanEval and MBPP, Python function-completion benchmarks checked by unit tests, against code models from a few hundred million to hundreds of billions of parameters.
| Model | Parameters | Training tokens | HumanEval pass@1 |
|---|---|---|---|
| phi-1-base, no fine-tune | 1.3B | ~50B seen, ~7B unique | 29% |
| phi-1 | 1.3B | plus ~180M of exercises | 50.6% (MBPP 55.5%) |
| phi-1-small | 350M | same pipeline | 45% |
| StarCoder, as reported in the paper | 15.5B | 1T | 33.6% |
| GPT-3.5, as reported in the paper | not disclosed | not disclosed | 47% |
phi-1 matched or beat models roughly an order of magnitude larger, though not all of them: WizardCoder, about 12 times larger, still scored higher on HumanEval in the paper's own comparison. The gain compounds at deployment, because a forward pass costs about 2 FLOPs per parameter per token, so a 1.3B model is about ten times cheaper per token than a 13B one. The follow-ups, phi-1.5, phi-2 and the phi-3 family, carried the recipe from code to general reasoning.
Ablations and checks
Training the same model sizes on the unfiltered Stack and StackOverflow data scored markedly lower, and the CodeExercises fine-tune was the largest single step, from 29% to 50.6%. Because those exercises resemble HumanEval, the authors searched them for problems similar to the benchmark using n-gram overlap and embedding and syntax-tree similarity, pruned everything flagged, more than 40% of CodeExercises at the strictest setting, and retrained: the pruned model still outperformed StarCoder. They also wrote new problems designed to be unlike anything online and graded solutions with GPT-4. The paper notes phi-1's limits plainly: it is specialized to Python, and less robust than larger models to stylistic variation or errors in the prompt.
What the authors admit, and what happened next
The paper is upfront that its model is narrow: it is trained for Python code and is not a general-purpose model, so the headline benchmark result should not be read as general capability. It also notes the obvious dependency — a large part of the training data is generated by a stronger model, so the recipe presupposes access to one.
The serious external objection is contamination, and it should be stated plainly because it goes to the heart of the claim: when a substantial fraction of training data is synthesised by a model that has itself seen benchmark-adjacent material, a benchmark score is a weaker measurement than usual. Independent analyses raised this about this line of work, the authors have engaged with it, and it has not been settled to everyone's satisfaction. The right posture for a reader is that the direction is well supported and the specific benchmark margin is not the part to quote.
How it held up: data curation and synthetic data became standard, which is the durable result — every frontier training mix since is a designed artefact rather than a scrape, and small models trained on heavily curated data are now a normal product category rather than a curiosity. What remains genuinely open is how far the effect goes, and whether benchmark numbers on synthetically-trained models measure what they appear to.
Effective signal, not raw tokens
The data-quality thesis is a product you can compute. This models effective signal as tokens × quality and shows a curated 7-billion-token set at 90% quality (6.3B signal) beating a 300-billion-token web set at 2% quality (6.0B signal) — forty times fewer tokens, more teaching. It then prices inference at ~2×params FLOPs per token, making a 1.3B model ten times cheaper than a 13B one, and shows how many raw tokens each quality level needs to hit a signal budget. Change the quality or sizes and watch which dataset wins.
Write the body of compute_ratio. Everything else in the file is
already written; this is the function the paper is about. Press ▶ Run to check it against
the 5 assertions below — they start red.
- Effective signal = tokens * quality
- Curated-clean beats huge-noisy on far fewer tokens
- Inference FLOPs per token = 2 * params
- A 10x smaller model is 10x cheaper per token
- Higher quality needs fewer tokens for the same signal
The caveats
The result was influential and also debated. Two honest cautions travel with it:
| Caveat | What to watch |
|---|---|
| Benchmark contamination | When training data is synthetic and targeted, it may resemble evaluation tasks. Strong scores must be checked for leakage between train and test. |
| Narrow vs general | Great numbers on Python coding don't prove broad capability; the recipe had to be re-validated as phi expanded to general reasoning. |
| Quality is hard to define | "Textbook-quality" is judged by a classifier and a generator model — quality is itself model-dependent and imperfect. |
| Synthetic-data risks | Generating training data with a stronger model can inherit its blind spots and biases. |
None of these overturned the central finding — that data quality is a first-class lever — but they are why the community treated the specific benchmark numbers with care while embracing the broader thesis. Measuring quality, and guarding against contamination, became active areas precisely because phi made quality matter.
What it started
Phi helped shift the field's attention from "scale everything" to "curate ruthlessly." The small language model movement — capable models in the 1–4B range that run on a laptop or a phone — owes much to the demonstration that careful data can substitute for raw size. Data curation, filtering, and synthetic generation became central research topics, not afterthoughts, and "data-centric" work gained the status the scaling laws had given model-centric work.
Its lasting idea complements, rather than contradicts, scaling. The scaling laws describe how capability grows with size for a fixed data quality; phi showed that quality is another axis entirely, one you can push to buy the same capability at a fraction of the size and cost. Both are true — and the practical frontier is to scale and curate, spending compute where it teaches most.
The efficiency of curated data also reshapes the Chinchilla view: compute-optimal token counts assume a fixed data quality, so higher-quality tokens can shift the optimal balance — fewer, better tokens doing the work of many.
Questions people ask about Textbooks Are All You Need
How was phi-1's synthetic training data generated?
Two synthetic sets were written by GPT-3.5. The first is under 1 billion tokens of Python textbook text, explanations interleaved with code, used in pre-training alongside about 6 billion tokens of filtered web code. The second, CodeExercises, is about 180 million tokens of exercises, each a function signature with a docstring followed by its solution, used only for fine-tuning. The main difficulty the paper describes is diversity: asked repeatedly for textbook content, a language model produces near-duplicates, so generation was steered with randomized constraints, topics and target audiences for the textbooks and function names for the exercises. The synthetic datasets themselves were not released with the paper.
What is the CodeExercises dataset?
CodeExercises is the fine-tuning set behind phi-1: about 180 million tokens of Python exercises generated by GPT-3.5. Each sample is a function's signature and a docstring describing what it should do, followed by a working implementation, and diversity came mainly from constraining the function names used in the prompts. Fine-tuning phi-1-base on it lifted HumanEval pass@1 from 29% to 50.6%, by far the largest single step in the paper. Because the format closely resembles HumanEval, the authors tested for contamination: they removed every exercise flagged as similar to a HumanEval problem by n-gram, embedding or syntax-tree comparison, more than 40% of the set, retrained, and still outperformed StarCoder.
How did phi-1 decide which code counted as textbook quality?
With a two-stage filter. GPT-4 was shown about 100,000 snippets from The Stack and StackOverflow and asked to judge each one's educational value for a student learning basic coding concepts. Those judgments became labels for a random-forest classifier whose input is the snippet's embedding from a pretrained CodeGen model. The cheap classifier, not GPT-4, then scored the full corpus of about 35 billion tokens, keeping about 6 billion. Quality is therefore whatever GPT-4 considered instructive: self-contained, clearly explained code tends to score high, and code that depends on context outside the snippet tends to score low. The filter inherits a stronger model's judgment, blind spots included.
How many tokens did phi-1 train on, and was it Chinchilla-optimal?
Its pre-training corpus was about 7 billion unique tokens, but the released base checkpoint had passed over it about eight times, a little over 50 billion tokens seen, followed by a fine-tune on about 180 million tokens of exercises. For a 1.3-billion-parameter model, 50 billion tokens is about 38 tokens per parameter, above the roughly 20 that the Chinchilla analysis calls compute-optimal. What is far below 20 is the count of unique tokens, about 5 per parameter. So phi-1 is better described as heavily repeating a small, curated corpus than as under-trained, and its result says more about the value of each token than about the Chinchilla ratio.
Was phi-1's HumanEval score inflated by contamination?
The authors tested the concern directly. They searched CodeExercises for exercises resembling HumanEval problems using n-gram overlap and embedding and syntax-tree similarity, pruned everything flagged, more than 40% of the dataset at the strictest setting, and retrained; the new model still outperformed StarCoder, a much larger model. They also wrote new problems designed to be unlike anything online and graded the solutions with GPT-4. Similarity search can only find near-copies, so it cannot rule out subtler leakage from a generator model that has itself seen benchmark-adjacent code. The direction of the result is better supported than its exact margin.
4 questions to test what you just read
Work each one out before you open it — a number, a prediction or a reason, not a definition. Producing the answer is what makes it stick. Your progress is kept on this device.
phi-1-base saw about 50B tokens with 1.3B parameters. Is that above or below Chinchilla's ratio, and what does the unique-token ratio say?
Show answer
50 / 1.3 ≈ 38 tokens per parameter seen, almost twice Chinchilla's ~20. Unique tokens: about 7 / 1.3 ≈ 5 per parameter. By Chinchilla's measure the model is not under-trained; it is repeating a small corpus about eight times.
Using C ≈ 6ND, how much training compute did phi-1-base use, and how does that compare with GPT-3?
Show answer
6 × 1.3 × 10^9 × 5.0 × 10^10 ≈ 3.9 × 10^20 FLOPs, about 800× less than GPT-3's 3.14 × 10^23. The fine-tune on ~180M tokens adds well under 1% on top.
Roughly what fraction of the 35B-token source survives the filter, and why use a random forest instead of asking GPT-4 about every file?
Show answer
About 6 / 35 ≈ 17%. Labeling 35B tokens with GPT-4 would cost far too much; labeling ~100k samples and training a small classifier on CodeGen embeddings costs a tiny fraction, and the classifier then runs over the whole corpus.
Fine-tuning on ~180M tokens, under 0.4% of the tokens seen in pre-training, moved HumanEval from 29% to 50.6%. Which two explanations fit, and which one do the authors favor?
Show answer
(1) Format alignment: CodeExercises looks like HumanEval, a docstring in and a function out, so the fine-tune teaches the test format, which is also why contamination was checked. (2) Reorganization: the fine-tune unlocks skills learned in pre-training. The authors favor the second, citing gains on tasks absent from the exercises, such as using Pygame and Tkinter.
Pre-training, and the scaling laws
The ladder where rung 5 overturns rung 4. Read `scaling-laws` before `chinchilla` — the second measures the same axis in the same units and gets a different answer.
- 1BERT2019
- 2T52020
- 3GPT-32020
- 4Scaling Laws2020
- 5Chinchilla2022
- 6Textbooks Are All You Need2023
- 7Muon2024
Explore the topic
See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.
More Paper Breakdowns
- Attention Is All You NeedThe paper that introduced the Transformer — the architecture underneath GPT, BERT, Claude, and Gemini. Self-attention, Query/Key/Value, multi-head attention, positional encoding, and the real BLEU results, explained in depth with analogies and animated visuals, not just equations.Read →
- BERTThe paper that made "pre-train once, fine-tune anywhere" the default for NLP. Bidirectional context, masked language modeling, next-sentence prediction, the [CLS]/[SEP] tokens, and the GLUE sweep — explained with analogies, not just equations.Read →
- Chain-of-Thought PromptingShow a model a few worked examples with their reasoning and it starts solving problems it used to fail. Why reasoning emerges only at scale, the GSM8K jump, zero-shot "Let's think step by step", and how CoT seeded modern reasoning models.Read →
- LoRAThe paper that made fine-tuning affordable. Freeze the giant pretrained model and train two tiny low-rank matrices instead — up to 10,000x fewer trainable parameters, no extra inference latency, and swappable per-task adapters. The road to QLoRA and PEFT.Read →
- Direct Preference OptimizationRLHF without the RL. Align a model to human preference pairs with one simple classification-style loss — no separate reward model, no unstable reinforcement learning. Why "your LM is secretly a reward model", and how DPO became the default alignment method.Read →
- ChinchillaThe compute-optimal scaling law that said models were too big. Parameters and training tokens should scale together — ~20 tokens per parameter — so a 70B model trained on 1.4T tokens beat the 280B giants. Why every model since trains on trillions of tokens.Read →