Distillation
Train a small model to imitate a large one.
Create a free account Try part of it here
Why it matters
Many of the fast, cheap models you use learned partly by copying bigger ones. This copying is called distillation. It's how a lab turns an expensive model into an affordable one. It's how reasoning skills passed from DeepSeek-R1 to much smaller models. And it's how a company can turn a prompted frontier model into a small model that does one job well. It also shows that a model's outputs are valuable training data in their own right, and that has legal consequences.
What you'll be able to do
- Explain knowledge distillation: training a small student on a large teacher's outputs
- Use temperature to expose the information in a teacher's full probability distribution
- Train a student with soft targets and compare it with training on hard labels
- Distinguish logit distillation from training on generated text, and know the legal limits
What it covers
- More than the right answer
- Turning up the temperature
- How the student is scored
- Worked example: scoring one student guess
- Distilling a smaller GPT
- Distillation for language models in practice
More than the right answer
Picture two teachers marking the same quiz question. The first writes "wrong, the answer is B." The second writes "B is right. C was a fair guess, almost as good. D makes no sense at all." Both give you the right answer. The second also tells you how close the other options were, so you learn more from one question.
Training a language model normally works like the first teacher. Each example says only which token came next in the text. That single right answer is called a hard label.
A trained model can act like the second teacher. Its prediction is a full list of chances, one for every token in its vocabulary. It says which other tokens were plausible, and how plausible.
Distillation uses that richer signal. Two models are involved:
- The teacher: a large, trained model.
- The student: a smaller model you want to train.
The student learns to match the teacher's full list of chances. Those lists are called soft targets. Geoffrey Hinton and colleagues (2015) called the extra information in them "dark knowledge." They showed that a small student learns better from a big teacher's soft targets than from hard labels alone.
Show the answer
It gives a probability for every option, including how plausible the wrong-but-close ones are
A hard label names one token. A full list of chances holds the teacher's judgment of every alternative, like the second teacher's notes on options C and D.
Turning up the temperature
A confident teacher has a problem. It might give the top token 99% and spread the last 1% thinly over everything else. Those tiny chances still hold knowledge, but they're too small for the student to notice.
Temperature fixes this. You met it in the sampling lesson. A model's raw scores, before they become chances, are called logits. Divide every logit by a number , the temperature, before the softmax. When is bigger than 1, the scores move closer together. So the chances come out flatter, and the small ones grow big enough to learn from.
Here is the softmax with a temperature. Number the options 1, 2, 3 and so on. Write for the logit of option number i, and for the chance it ends up with:
The top line raises (about 2.718) to the power of one option's scaled logit. The bottom line does the same for every option and adds them all up. The sign means "add up."
In plain words: shrink every score by dividing it by T. Then turn the scores into chances that add up to 1, as the softmax always does. A bigger T gives a flatter, less certain list. The order of the options never changes.
A worked example. Take three logits: 3, 1 and 0.
- At , the chances are about 0.84, 0.11 and 0.04.
- At , the logits become 1.5, 0.5 and 0. The chances are about 0.63, 0.23 and 0.14.
The top option is still on top. But the last option's share more than triples, from 4% to 14%. (The first row adds up to 0.99 only because of rounding.) The same sum as a loop:
import math logits = [3.0, 1.0, 0.0] for T in (1, 2): exps = [math.exp(z / T) for z in logits] total = sum(exps) print(T, [round(e / total, 2) for e in exps])
It prints 1 [0.84, 0.11, 0.04] and then 2 [0.63, 0.23, 0.14].
Now try it on a real teacher. The cell below loads the course's pretrained tiny GPT. It shows the teacher's top five next tokens for two prompts, at and at :
import torch from tinygpt import load_pretrained teacher, tok = load_pretrained("tiny-gpt") # the base model, as a teacher for prompt in ["Our Kestrel tent is made from", "It is light and"]: with torch.no_grad(): logits = teacher(torch.tensor([tok.encode(prompt)]))[0, -1] print(prompt) for T in (1, 2): top = torch.softmax(logits / T, dim=-1).topk(5) print(f" T={T}: " + ", ".join(f"{tok.vocab[i]} {p:.2f}" for p, i in zip(top.values.tolist(), top.indices.tolist())))
In the catalog text, "Our Kestrel tent is made from" has exactly one next word. But the teacher knows that tents come in silnylon and recycled ripstop nylon, nearly 50/50. A hard label teaches half of that. The soft target teaches all of it. At , the teacher's small chances become visible too, such as waxed canvas at 3%.
import math def soft(a, b, t): ea, eb = math.exp(a / t), math.exp(b / t) return round(ea / (ea + eb), 2) print(soft(2, 0, 1) > soft(2, 0, 4))
Show the answer
True
At temperature 1, soft gives about 0.88, and at temperature 4, about 0.62. 0.88 is larger, so it prints True. A higher temperature evens out the probabilities, which reveals what the teacher thinks of the runners-up.
At temperature 1, the teacher looks certain. Raise the temperature and its hidden knowledge appears: a cat is much more like a dog than like a car.
Show the answer
2 and 1
Each logit is divided by T: 4 / 2 = 2 and 2 / 2 = 1. The gap shrinks from 2 to 1, so the two chances come out closer together. The first token is still on top.
How the student is scored
The student also produces logits, and they're softened with the same temperature. Training then compares two lists of chances: the teacher's and the student's. The score is the cross-entropy you met in Phase 2, with the teacher's list in place of a single right answer.
Write for the teacher's softened chance for option . Write for the student's softened chance for the same option. The loss for one position is:
Here is the natural log, as in the cross-entropy lesson. The factor is the temperature times itself.
In plain words: for every option, take the log of the student's chance and weight it by the teacher's chance. Add those up and flip the sign. The loss is small when the student puts high chances where the teacher does. Then multiply by T times T. In training, this is averaged over every position in the batch.
With a hard label, the teacher's list is 1 for the true token and 0 for the rest. Then the sum keeps only one term. At , that's ordinary cross-entropy again.
Go deeper Why multiply by T squared?
Softening makes both lists flatter, so the student's mistakes look smaller. Hinton's team showed that the push the student gets from soft targets shrinks by about . Multiplying the loss by undoes that. So the training signal keeps a similar strength whichever temperature you choose. This matters when you mix the soft loss with an ordinary hard-label loss, as many recipes do.
Worked example: scoring one student guess
Three possible next words: silnylon, ripstop and canvas. The teacher's softened list is 0.5, 0.4 and 0.1. The student's softened guess is 0.8, 0.1 and 0.1. The true word in the text was silnylon, and . Compare the hard-label loss with the soft loss. To keep the numbers small, use the same student guess for both. (In real training, the hard-label loss uses the student's unsoftened chances.)
import math teacher = [0.5, 0.4, 0.1] # silnylon, ripstop, canvas: the softened target student = [0.8, 0.1, 0.1] # the student's softened guess T = 2 hard = -math.log(student[0]) # the true word was silnylon soft = -sum(q * math.log(p) for q, p in zip(teacher, student)) print(round(hard, 3), round(soft, 3), round(soft * T * T, 3)) copy = -sum(q * math.log(q) for q in teacher) # a student that matches the teacher print(round(copy, 3))
It prints 0.223, 1.263 and 5.051, then 0.943. The hard label calls the student nearly right: it gave silnylon 80%, so the loss is only 0.223. The soft loss is much bigger, 1.263. It notices that the student gave ripstop only 10% when the teacher gave it 40%. Times , that's 5.051.
The last line scores a student whose guess matches the teacher exactly. Its soft loss is 0.943, not 0. That's the teacher's own entropy, the lowest the soft loss can go. Training pushes the student toward that floor.
Show the answer
The entropy of the teacher's list, the lowest value the loss can reach
Cross-entropy is smallest when the two lists match, and then it equals the entropy of the target list. In the worked example that was 0.943, not 0.
Distilling a smaller GPT
Now the real experiment. The teacher is the course's tiny GPT. The student has about a quarter of the teacher's parameters. It has one layer of width 16 instead of two layers of width 32. (Width is the length of the list of numbers that stands for each token inside the model.)
The student sees only 800 tokens of catalog text, about 25 product descriptions. Two students train on that same text:
- One trains on the hard labels: the true next token.
- One trains on the teacher's soft targets, at temperature 2.
The teacher's soft targets are computed once, up front. Offline distillation usually works this way: run the teacher over the data first, store its outputs, then train the student.
Both students are then tested on descriptions they never saw. The test uses ordinary cross-entropy against the true next tokens, and lower is better. The cell takes a while to run. The Run button counts the seconds.
import requests import torch import torch.nn.functional as F from tinygpt import GPT, load_pretrained teacher, tok = load_pretrained("tiny-gpt") data = torch.tensor(tok.encode(requests.get("https://api.gradient.test/v1/corpus").json()["text"])) train, held_out = data[:800], data[int(0.9 * len(data)):] # the student sees 800 tokens V, T = len(tok), 2.0 windows = torch.stack([train[i:i + 33] for i in range(len(train) - 33)]) # every 32-token window + next token with torch.no_grad(): soft_targets = torch.softmax(teacher(windows[:, :-1]) / T, dim=-1) # the teacher's view, computed once @torch.no_grad() def held_out_loss(model): torch.manual_seed(123) losses = [] for _ in range(8): starts = torch.randint(0, len(held_out) - 33, (32,)).tolist() x = torch.stack([held_out[i:i + 32] for i in starts]) y = torch.stack([held_out[i + 1:i + 33] for i in starts]) losses.append(F.cross_entropy(model(x).reshape(-1, V), y.reshape(-1)).item()) return sum(losses) / len(losses) def train_student(soft, steps=300): torch.manual_seed(0) student = GPT(V, context=64, d=16, n_layers=1, n_heads=2) opt = torch.optim.AdamW(student.parameters(), lr=3e-3, weight_decay=0.01) torch.manual_seed(1) for step in range(steps): b = torch.randint(0, len(windows), (16,)) logits = student(windows[b, :-1]) if soft: # match the teacher's softened distribution loss = -(soft_targets[b] * torch.log_softmax(logits / T, dim=-1)).sum(dim=-1).mean() * T * T else: # match the one true next token loss = F.cross_entropy(logits.reshape(-1, V), windows[b, 1:].reshape(-1)) opt.zero_grad() loss.backward() opt.step() return student count = lambda m: sum(p.numel() for p in m.parameters()) hard, soft = train_student(soft=False), train_student(soft=True) print(f"teacher: {count(teacher):,} parameters; each student: {count(hard):,}") print(f"student trained on hard labels: held-out loss {held_out_loss(hard):.3f}") print(f"student trained on teacher (T=2): held-out loss {held_out_loss(soft):.3f}")
The line starting loss = -(soft_targets[b] ... is the formula from above, written in PyTorch.
From the same 800 tokens, the distilled student does noticeably better on new text. Each example carries the teacher's view of what else could have come next, and the teacher learned that view from the whole catalog.
With plenty of data, the gap narrows. In testing, with nearly ten times as much text, the two students were nearly tied. That matches practice: distillation helps most when the student can't see everything the teacher learned from. (torch here is the course's in-browser PyTorch subset.)
Distillation for language models in practice
There are two main kinds, and they need different access to the teacher.
- Logit distillation is what the cell did. It needs the teacher's full lists of chances, and both models must use the same tokenizer. So it's used when one organization owns both models. Google, for example, trained its smaller Gemma 2 models with distillation from a larger model. DistilBERT (2019) kept about 97% of BERT's performance while being 40% smaller and 60% faster.
- Sequence-level distillation trains the student with SFT on text the teacher generated. You ask the big model thousands of questions and fine-tune the small one on its answers. This needs no access to the chances, only the teacher's text. Stanford's Alpaca (2023) did this with 52,000 answers from an OpenAI model. DeepSeek fine-tuned small Qwen and Llama models on about 800,000 samples from R1, and got strong small reasoning models.
Show the answer
It needs the teacher's full lists of chances, and the API only returns text
With only the text, you can still train on the outputs, but that's the other kind of distillation.
A common business pattern works like this:
- Prototype with a frontier model and a careful prompt.
- Collect its outputs on real inputs, and have people review them.
- Fine-tune a small model on the approved outputs for the high-volume job.
- Keep evaluating the small model against the big one.
Know the terms. Many commercial providers' terms of service ban using their models' outputs to build competing models. They generally allow narrower internal uses. Open-model licenses vary too. Check the teacher's terms before you distill. Also check the license of any dataset that was itself generated by a model.
Know the limits. In general, a student can't beat its teacher on the teacher's own tasks. It copies the teacher's mistakes along with its skills. And a small model distilled on a narrow task can lose general abilities it had before.
For marketers: say a big model writes good product descriptions, but it costs too much at catalog scale. Generate a few thousand, have editors approve them, and fine-tune a small model on the approved set. Check first that your provider's terms allow it.
Show the answer
The student repeats the same mistake
A student copies its teacher's mistakes along with its skills. That's why the business pattern has people review the teacher's outputs before training.
Practice what you just read
- 4 code examples you can edit and run
- a practice exercise that checks your code
- a 5-question quiz
- 5 review cards for spaced repetition
Try a quiz question
What does raising the distillation temperature T do to the teacher's distribution?