Synthetic data & curation pipelines
Use a strong model to write training data, use a checker to throw away the bad part, and train a smaller model on what survives. The generator is the easy bit. The checker, the diversity and the bookkeeping decide whether the result is any good.
Start here (no maths needed)
Instead of collecting more writing from people, you ask a clever AI to write practice examples, check them, keep only the good ones, and use those to teach a smaller AI.
Think of it like this
Imagine a teacher making a revision book. She writes lots of maths questions and asks a strong student to solve each one, showing the working. Then she checks every answer with the answer key. Wrong ones go in the bin. Right ones go in the book. A younger student then studies from the book. The book is only as good as the checking. If the teacher's answer key has mistakes, wrong working ends up in the book, and the younger student learns those mistakes too.
How it works
- Make questions: start with a few examples and ask a big AI to invent many more, harder and more varied ones.
- Make answers: the big AI answers each question several times, showing its working.
- Check: a checker (a calculator, a test, or another AI) marks each answer right or wrong.
- Clean up: throw out wrong answers, near-copies, and anything that leaks the test questions.
- Teach: train a smaller AI on the answers that survived, then test it on questions it has never seen.
Why robots care
Robots have the same problem with even less data: nobody has millions of hours of robot videos. So engineers make "synthetic" robot data in computer simulations, or let a robot try a task many times and keep only the attempts that worked. It's the same recipe: make lots, check, keep the good ones.
Try it
- Roll two dice 20 times and write each pair as a multiplication question. A friend answers each one in two seconds. You check with a calculator and keep only the right ones. Now play again, but this time the "checker" is a third friend who checks just by looking and sometimes says "looks fine". How many wrong answers sneak into the kept pile?
- In the demo below, set Generator pass rate low (like 10%) and move Verifier false-pass rate from 0% to 10%. Watch how quickly the share of wrong examples in your kept data climbs.
Words to know
- Synthetic data
- Training examples written by a computer, not collected from people.
- Verifier
- A checker that says whether an answer is right.
- Rejection sampling
- Make many attempts, throw away the ones that fail the check.
- Trace
- The step-by-step working that leads to an answer.
- Model collapse
- When models trained on other models' output slowly lose variety and rare knowledge.
Going deeper: everything below is the full version. On a first read, skim the headings, try the demo, and read the reality check.
1. What this stage covers
TL;DR
A synthetic-data pipeline has four parts: prompts (where the questions come from and how diverse they are), generation (a stronger model writes answers or reasoning traces, usually several per prompt), filtering (a verifier, a judge model, dedup and decontamination) and training (SFT on the survivors, then honest evaluation). The core maths is simple base-rate arithmetic. The fraction of wrong examples in your kept data depends on the generator's pass rate and the verifier's false-pass rate, and it gets worse fast when the generator is weak. Where answers can be checked exactly (maths, code, logic), this works very well. Where they can't, quality depends on judge models with their own biases.
- Learn: Self-Instruct, evolutionary prompting (Evol-Instruct), rejection sampling, and using frontier models to generate and filter training data.
- Practice: generate 50,000 complex logic traces with a strong reasoning model, filter them with a verifier, and train a smaller model on the survivors.
- Why (the post's claim): high-quality human text is running out, so curating synthetic data is "the ultimate moat". Section 4 tests that claim.
2. Concepts, explained
Self-Instruct: bootstrapping instructions from a seed set
Self-Instruct (Wang et al., 2022) starts from a small pool of human-written seed tasks (175 in the paper). Each round, it samples a few tasks from the pool as in-context examples and asks the model for new instructions, then for inputs and outputs. Before a new task joins the pool, filters remove invalid outputs and near-duplicates: a new instruction is rejected if its ROUGE-L overlap with any existing one is too high. The pool grows, and later rounds draw on generated tasks too. Fine-tuning vanilla GPT-3 on the result gave a 33% absolute gain on Super-NaturalInstructions, close to InstructGPT-001.
pool = seed_tasks
repeat:
examples = sample(pool, k) # mix of seed and generated
new_tasks = LM("write new tasks like these", examples)
new_tasks = [t for t in new_tasks
if valid(t) and max_rougeL(t, pool) < threshold]
pool += new_tasks
The lesson that carries over: diversity filtering is part of generation. Without the similarity check, the pool fills with paraphrases of the seeds.
Evolutionary prompting: Evol-Instruct
Self-Instruct's tasks tend to be easy. Evol-Instruct (Xu et al., 2023, the WizardLM paper) "evolves" each instruction by asking an LLM to rewrite it. In-depth evolution makes it harder: add a constraint, require more reasoning steps, make the input more complex. In-breadth evolution writes a new instruction on a related but different topic. An elimination step discards evolutions that failed (for example, the rewrite didn't add anything, or the model couldn't answer it). Repeating this for several rounds produces a mix of difficulty levels. The authors fine-tuned LLaMA on the mix and, in their human evaluations, preferred its outputs on the hardest instructions over ChatGPT's.
The general idea is a genetic algorithm over prompts: mutate, test, keep the fit ones. "Fit" here means the instruction is still well-posed and answerable, not just longer.
Rejection sampling: STaR and RFT
For tasks with a checkable answer, sample several solutions per problem and keep only the correct ones.
- STaR (Zelikman et al., 2022): the model writes a rationale and answer for each question. Keep rationales that reach the right answer. For questions it gets wrong, show it the correct answer and ask it to write a rationale that leads there ("rationalisation"). Fine-tune on all kept rationales and repeat.
- Rejection-sampling fine-tuning (RFT) (Yuan et al., 2023): sample many reasoning paths from a supervised model on maths problems, keep the correct ones, deduplicate, and fine-tune on them. They found that more distinct correct reasoning paths helped more than more copies of similar ones.
The arithmetic of a filter. Let p be the generator's pass rate, TPR the chance the verifier accepts a correct trace, and FPR the chance it accepts a wrong one:
yield = p·TPR + (1 − p)·FPR # fraction of generations you keep
precision = p·TPR / yield # fraction of kept data that is correct
generations needed for N survivors = N / yield
example: p = 0.10, TPR = 0.90, FPR = 0.05
yield = 0.09 + 0.045 = 0.135 precision = 0.09 / 0.135 ≈ 0.67 → one kept trace in three is wrong
That's the base-rate trap. A verifier that looks "95% accurate" still lets lots of garbage through when most generations are wrong. Two fixes: make the verifier stricter (exact checks, unit tests), or make the generator better on the problems you pick (don't feed it problems far above its level).
Interactive: rejection-sampling yield vs. verifier quality
x axis: generator pass rate p. Solid (accent): precision, the share of kept traces that are actually correct. Dashed (muted): yield, the share of generations kept. The dot marks your chosen p. Target: 50,000 survivors, as in the post.
Using frontier models to generate and filter
The most common pipeline in 2026 is distillation through data: a large "teacher" writes answers or reasoning traces, a filter keeps the good ones, a smaller "student" is fine-tuned on them. Three levers matter:
- What you ask for. phi-1 (Gunasekar et al., 2023) trained a 1.3B code model on about 6B tokens of filtered "textbook quality" web data plus about 1B tokens of synthetic textbooks and exercises written by GPT-3.5, and reached 50.6% pass@1 on HumanEval. The point: carefully designed synthetic data can stand in for a lot of raw web data, for a narrow domain.
- How you filter when there's no exact checker. An LLM judge scores helpfulness, correctness or style. Judges have known biases (length, position, self-preference), so calibrate them against a few hundred human labels first. Module 01 covers judge calibration.
- Curation beyond correctness. Near-duplicate removal (MinHash or embeddings), diversity sampling across topics and difficulty, and decontamination: drop anything with heavy n-gram overlap with your evaluation sets. Synthetic data generated by a model that saw the benchmark can leak it.
The risk: model collapse. Shumailov et al. (2023) showed that training each generation of model on the previous generation's output makes the tails of the original distribution disappear: rare facts, unusual styles, minority cases. The practical defences are to keep real data in the mix, filter for diversity, and avoid training repeatedly on your own model's unfiltered output.
3. The practice project
(a) Laptop / Colab version: verified logic traces for a 0.5B student
Pick a task where the verifier is exact and free, so you can study the pipeline without arguing about judges. Programmatically generated puzzles are ideal: you know the answer by construction.
- Problems: write a generator for multi-step puzzles with a known answer, with a difficulty knob (e.g. chained arithmetic with 3–8 steps, or "who sits where" constraint puzzles solved by brute force). Make 3,000 train and 500 held-out test problems, with different random seeds.
- Teacher: a 1.5–7B instruct model on Colab (with a fast inference library), or a modest API budget for a few thousand calls to a stronger model. Sample k = 4 traces per problem at temperature ~0.8, asking for working then a final line
ANSWER: …. - Verify and curate: parse the final answer, check it exactly, drop traces with no parsable answer, deduplicate identical traces, cap at 2 kept traces per problem.
- Student: fine-tune a ~0.5B model (LoRA is fine) on the survivors. Train a second student on unfiltered traces with the same token budget as the control.
- Measure: yield per difficulty level; held-out accuracy of the base student, the unfiltered student and the filtered student; accuracy by difficulty level. Report all three numbers, not just the best one.
import random, re
def make_problem(rng, steps):
x = rng.randint(1, 20); text = f"Start with {x}."
for _ in range(steps):
op, n = rng.choice("+-*"), rng.randint(2, 9)
text += f" Then {'add' if op == '+' else 'subtract' if op == '-' else 'multiply by'} {n}."
x = x + n if op == "+" else x - n if op == "-" else x * n
return {"q": text + " What is the result?", "a": x, "steps": steps}
def verify(trace, answer):
m = re.search(r"ANSWER:\s*(-?\d+)", trace)
return m is not None and int(m.group(1)) == answer
def curate(problems, sample, k=4, keep=2):
out, stats = [], {"gen": 0, "kept": 0}
for p in problems:
traces = {sample(p["q"]) for _ in range(k)} # set = exact dedup
stats["gen"] += k
good = [t for t in traces if verify(t, p["a"])][:keep]
stats["kept"] += len(good)
out += [{"prompt": p["q"], "completion": t, "steps": p["steps"]} for t in good]
return out, stats
rng = random.Random(0)
train = [make_problem(rng, rng.randint(3, 8)) for _ in range(3000)]
What to expect: the yield will fall as the number of steps grows, so the kept data will be skewed toward easy problems. That skew is the most useful thing to notice. If the filtered student improves mostly on easy problems, try oversampling hard problems (larger k) or the STaR-style "rationalise from the correct answer" trick for the ones that never pass.
(b) The full version from the post
50,000 complex logic traces from a heavy reasoning model, verified, then used to train a smaller model. Points to plan for:
- Generation cost is dominated by trace length. Reasoning traces are often thousands of tokens. At, say, 3,000 output tokens per attempt and a 30% yield, 50,000 survivors needs about 167,000 attempts and about 500M output tokens. Multiply by your provider's output price before you start, or plan for days of a multi-GPU node with an open reasoning model.
- The verifier is the project. "Logic traces" only works at scale if the final answer is machine-checkable (puzzles with unique solutions, maths with numeric answers, code with tests). If you rely on an LLM judge, measure its false-pass rate on a labelled sample, then use the demo's arithmetic.
- Student training: LoRA/QLoRA fine-tuning of a ~7B student on 50k traces fits on one 80 GB GPU. Full fine-tuning needs several. Long traces mean long sequences, so watch memory.
- Terms of use: some model providers restrict using their outputs to train competing models. Check before you build on one.
(c) Pitfalls
- Easy-problem bias. Rejection sampling keeps what the teacher already does well. Track yield per difficulty bucket.
- Right answer, wrong reasoning. An outcome check passes traces that guess or get lucky. Multiple-choice tasks are the worst case. Prefer answers with a large space of possible values.
- Contamination. If your problems resemble a public benchmark, run an n-gram overlap check before reporting results on it.
- Duplicates. Near-identical traces inflate the dataset without adding information. RFT found distinct reasoning paths matter more than count.
- No control. Without the unfiltered-trace baseline and the base model, you can't tell whether filtering helped or the extra training did.
4. Reality check
The post's claim: human text is running out, so curating synthetic data is "the ultimate moat". Directionally right, overstated.
- True: Villalobos et al. (2022) projected that, if trends continue, training sets would reach the size of the public stock of human text between about 2026 and 2032. Synthetic data is now a standard part of post-training and increasingly of pre-training.
- True: where answers are verifiable, synthetic data plus a good verifier works very well. That's why reasoning gains have been biggest in maths and code.
- Overstated: "mathematically curate" makes it sound solved. The maths of filtering is simple; the hard parts are building a verifier for open-ended tasks, keeping diversity, and avoiding collapse.
- "Ultimate moat" is debatable. Many recipes and datasets are public, and a pipeline built on a third-party teacher is only as unique as your prompts and verifiers. The durable advantages tend to be proprietary verifiers, real user or robot data, and the evaluation discipline to tell what helped.
5. In this course
- Module 04 · teacher → student: distilling a big model into a small one, the same pipeline shape as this stage.
- Module 04 · evaluation that doesn't fool you and its pitfalls: honest splits and leakage checks for your student.
- Module 07 · SFT and RLVR verifiers: where synthetic traces enter post-training, and how verifiers also drive RL.
- Module 01 · LLM evals & calibration: calibrating an LLM judge before you trust it as a filter.
- Module 05 · length: Kimi K3 synthesises long-context tasks that can only be solved by combining scattered information.
- 06 Day 25 · Scaling laws: why data, not just parameters, limits scaling.
6. Why it matters for robotics
- Simulation is robotics' synthetic data. Randomised sim scenes, objects and physics produce training data no one could collect by hand. The same questions apply: is it diverse enough, and how far is it from the real distribution?
- Rejection sampling = keeping successful rollouts. Run a policy (or a scripted planner) many times, keep only episodes a success detector accepts, and train on those. The success detector is the verifier, and its false positives poison the data exactly as in the demo.
- Frontier models as labellers. Vision-language models can write instructions or captions for robot episodes, which turns unlabelled logs into language-conditioned training data. Treat their labels like a judge's: check a sample.
- Collapse has a robot version. Training only on your own policy's filtered successes narrows behaviour to what it already does. Keep human demonstrations in the mix.
7. Self-check
Why does Self-Instruct reject new instructions with high ROUGE-L overlap with the pool?
To keep diversity. Without it the pool fills with paraphrases of the seed tasks, and the fine-tuned model sees many copies of the same few skills.
Generator pass rate 0.1, verifier TPR 0.9, FPR 0.05. What fraction of kept traces is wrong?
Yield = 0.1·0.9 + 0.9·0.05 = 0.135. Correct kept = 0.09. Precision ≈ 0.67, so about one in three kept traces is wrong.
What does STaR do with questions the model gets wrong?
It gives the model the correct answer as a hint and asks for a rationale that reaches it ("rationalisation"), then trains on rationales that lead to the right answer, so hard questions aren't simply dropped.
Why is rejection sampling biased toward easy problems, and what can you do about it?
Easy problems pass more often, so they contribute more survivors. Track yield by difficulty, sample more attempts for hard problems, cap survivors per problem, or use hints/rationalisation for problems that never pass.
What is model collapse, and how do you guard against it?
Repeatedly training on generated data loses the tails of the original distribution. Keep real data in the mix, filter for diversity, and avoid recursive training on unfiltered self-generated output.
Why is an exact verifier worth more than a bigger teacher?
An exact verifier drives the false-pass rate to zero, so kept data is clean whatever the teacher's pass rate. A bigger teacher only raises the pass rate, and a leaky verifier still lets errors through.
8. Courses & content
| Resource | Type | Use it for |
|---|---|---|
| Hugging Face smol-course · Synthetic Data unit | Course (free) | Generating synthetic datasets for a domain |
| Cosmopedia: how to create large-scale synthetic data | Case study | Prompt design, diversity and dedup for a large synthetic pre-training set |
| distilabel | Library + docs | Pipelines for generating, judging and filtering synthetic data |
| Karpathy · nanochat | Code (free) | How synthetic and curated data feed the later training stages |
Start with the smol-course synthetic data unit: it's short, hands-on and sized for small models, which matches the laptop project. Read Cosmopedia next for how diversity is handled at scale.
9. Papers & docs
- Wang et al. (2022), Self-Instruct: Aligning Language Models with Self-Generated Instructions
- Xu et al. (2023), WizardLM: Empowering Large Pre-Trained Language Models to Follow Complex Instructions (Evol-Instruct)
- Zelikman, Wu, Mu & Goodman (2022), STaR: Bootstrapping Reasoning With Reasoning
- Yuan et al. (2023), Scaling Relationship on Learning Mathematical Reasoning with Large Language Models (RFT)
- Gunasekar et al. (2023), Textbooks Are All You Need (phi-1)
- Shumailov et al. (2023), The Curse of Recursion: Training on Generated Data Makes Models Forget
- Villalobos et al. (2022), Will we run out of data? Limits of LLM scaling based on human-generated data
- distilabel documentation