Skip to main content

Synthetic Data Generation

Introduction

L195 (Data Quality, Coverage & Quantity) said quantity has a floor you must clear, and L196 (Sourcing & Annotating Data) said hand-writing examples is slow and expensive. Synthetic data is how you square that circle — and in 2026 it's the default scaling primitive for fine-tuning: model-generated training data that amplifies a small real seed into a large, diverse set, cheaply.

But synthetic data is a loaded gun. Done well, a handful of seed examples becomes thousands of varied, challenging ones. Done badly, you get a model that's confidently mediocre — because the teacher echoed itself and the data collapsed into sameness. This lesson is the craft that separates the two: the seed → teacher → judge pipeline, the generation methods (Self-Instruct, Evol-Instruct, personas, Magpie), the collapse failure mode and its antidotes, and the legal line you can't cross with a frontier teacher.

An infographic titled 'Synthetic Data Generation', the third lesson of section three on dataset engineering, covering the default scaling primitive for fine-tuning in 2026: model-generated training data that augments scarce, expensive, or privacy-sensitive human data. The canonical pipeline is consistent: a small real seed anchors the distribution, a frontier teacher model expands it ten to a hundred times, an LLM judge filters out the bottom ten to twenty percent, and the result is shippable JSONL into TRL or Unsloth. The single most important step is the judge, because an unfiltered synthetic dataset is worse than a smaller filtered one. The generation methods form a ladder. Self-Instruct bootstraps new instruction-output pairs from the seed and gives breadth but often shallow, easy examples. Evol-Instruct evolves examples to be harder through in-depth evolving, which adds constraints, reasoning, and complexity, and more varied through in-breadth evolving, which mutates topics. Persona-driven generation conditions on many personas for maximum diversity, and Magpie extracts instruction data from an aligned model without any seed, which is broad but can drift off the target distribution. The defining danger is model collapse: repeatedly training on synthetic data amplifies existing biases and narrows the output distribution, because the teacher echoes itself and the diversity degrades across batches. The antidotes are diversity-preserving choices, multi-source generation across several teachers and personas, anchoring with real seed data kept in the mix, and verification, plus aggressive judging and deduplication. A legal layer is distinct from privacy: frontier providers attach anti-competitive distillation clauses to their terms, so you generally cannot use their outputs to build a competing model, and the vendor-blessed path is an official distillation API. Synthetic data generation, learning from generated examples, is also distinct from model distillation, compressing a teacher into a student, which is the next lesson. The takeaway is that synthetic data is a force-multiplier on a good seed: generate broad and hard, filter ruthlessly, and guard diversity, or the distribution collapses.

The Pipeline: Seed → Teacher → Judge → Dataset

Almost every synthetic-data recipe in 2026 is the same four steps — internalize this and you understand the whole field:

  1. Small real seed. ~150–1,000 real, high-quality examples (from L196) that anchor the distribution — the style, format, and kind of task you want. The synthetic set can only be as good as what the seed points at.
  2. Teacher expands 10–100×. A capable (often frontier) model generates the bulk, conditioned on the seed. This is where quantity comes from cheaply.
  3. Judge filters the bottom 10–20%. An LLM-as-judge (plus heuristics) scores every example and drops the worst. This is the single most important step — we'll see why below.
  4. Ship JSONL into your trainer (TRL / Unsloth).

The mental model: synthetic data is a force-multiplier on a good seed. It amplifies the signal that's already there — it can't invent signal that isn't. Garbage seed → garbage at scale. Everything else in this lesson is about making the teacher generate well and the judge filter hard.

Generation Methods: A Ladder of Sophistication

How the teacher generates is the lever on breadth and difficulty. The methods form a ladder:

  • Self-Instruct — few-shot the teacher with seed examples and ask for new ones. Great for breadth/coverage, but the samples tend to be simple — it rarely produces genuinely hard examples.
  • Evol-Instructevolve existing examples to fix that. Two directions:
    • In-depth evolving — add a constraint, deepen the reasoning, concretize, or complicate the input → harder examples.
    • In-breadth evolvingmutate into new but related topics → wider coverage.
  • Persona-driven (e.g. PersonaHub's 1M personas) — condition each generation on a different personamaximum diversity (varied users, tones, contexts). The strongest antidote to collapse.
  • Magpie — extract instructions from an aligned model without any seed (clever prompting). Cheap and broad, but can drift off your target distribution.
  • CoT-Self-Instruct — have the teacher reason/plan first, then generate a same-quality example → higher quality for reasoning tasks.

The practical recipe: Self-Instruct for breadth + Evol-Instruct in-depth for difficulty + personas for diversity. You're trying to fill the L195 coverage map with examples that are both varied and hard enough.

The Judge: Filter Ruthlessly

Here's the line to tattoo on your wall: an unfiltered synthetic dataset is worse than a smaller filtered one. Teachers hallucinate, repeat themselves, drift off-task, and produce duplicates — and remember the L195 mirror: the student imitates every bad example you keep.

So the judge is non-negotiable:

  • LLM-as-judge scores each example on correctness, difficulty, and task-fitdrop the bottom 10–20%.
  • Heuristic screens — grammar/format validators, length bounds, schema checks catch the obvious junk cheaply.
  • Deduplication — near-duplicates add tokens, not signal (and can leak between train and eval). Dedup hard (the full pass is L199 — Cleaning, Dedup & Formatting).

One caveat that bites people: if you filter only by "difficulty" or only keep the judge's favorites, you can shrink diversity — you keep a narrow band of "perfect" examples and lose the useful variety. Filter for quality, but watch the diversity meter as you do (you'll feel this trade-off directly in the lab).

The Big Danger: Model Collapse

The defining risk of synthetic data has a name: model collapse. When you generate too much from a fixed seed (or train on synthetic data repeatedly, generation after generation), two things happen:

  • Bias amplification — whatever the teacher leans toward gets reinforced and exaggerated.
  • Diversity degradation — the output distribution narrows; the teacher starts echoing itself, and the variety that made the data useful drains away batch over batch.

The mirror compounds it: a slightly narrow teacher produces a narrower student, which produces a narrower one still. The antidotes are all about preserving diversity:

  • Multi-source generation — blend several teachers / personas / temperatures. Multi-source synthetic data is the most effective at maintaining output diversity (ACL 2026).
  • Anchor with real data — keep real seed examples in the mix and verify synthetic against reality; don't let the set become 100% model-generated.
  • Filter + dedup — the judge and dedup pass actively fight the narrowing.

Watch for it in the lab: crank expansion with a narrow seed and the guards off, and you'll see the task-space scatter collapse toward a single blob. Turn on personas / multi-source / real-anchor and it spreads back out.

In Code: Generating (Self-Instruct + Evol)

The generation step is just prompting a teacher — but the prompt encodes the method. Here's Self-Instruct for breadth and Evol-Instruct for depth/diversity:

# SEED -> TEACHER. Few-shot the teacher with real seed examples; ask for NEW ones.
SELF_INSTRUCT = '''You generate training data for a support classifier.
Here are {k} real examples:\n{seed_examples}
Write {n} NEW, varied tickets in the same JSON format. Vary topic, length, and tone.
Do NOT copy the seeds.'''

# EVOL-INSTRUCT: make an example HARDER (in-depth) or NEW-TOPIC (in-breadth).
EVOL_IN_DEPTH   = 'Rewrite this ticket to be harder: add a constraint or a second \
intent or an ambiguous detail - WITHOUT changing the correct label.\n\n{ex}'
EVOL_IN_BREADTH = 'Write a brand-new ticket on a DIFFERENT topic than this one, \
same format and difficulty.\n\n{ex}'

# Persona-driven diversity: condition each batch on a different persona + high temp.
gen = teacher(SELF_INSTRUCT.format(k=8, n=20, seed_examples=sample(seed, 8)),
              system=f'You are writing as: {persona}', temperature=1.0)

In Code: Judging & Guarding Diversity

Then filter — and anchor the result in real data so it doesn't collapse:

# The JUDGE is the most important step. Score, threshold, dedup, keep the top.
JUDGE = '''Rate this training example 1-5 on correctness, difficulty, and task-fit.
Reply JSON {{"score": int, "reason": str}}.\n\nExample: {ex}'''

scored = [(ex, judge(JUDGE.format(ex=ex)).score) for ex in generated]
kept   = [ex for ex, s in scored if s >= 4]          # drop the bottom ~10-20%
kept   = dedup(kept, threshold=0.9)                  # near-dupes add tokens, not signal

# GUARD diversity: blend multiple teachers/personas AND keep REAL data in the mix,
# or the distribution collapses across batches (model collapse).
final = mix(kept, real_seed, real_ratio=0.15)        # anchor ~15% real
write_jsonl(final, 'train.jsonl')                    # -> TRL / Unsloth

The Legal Layer: Teacher Terms & the Distillation Line

This is a different legal issue from L196's PII — it's about the teacher you generate with. Frontier providers (OpenAI, Anthropic, Mistral, xAI) attach anti-competitive distillation clauses to their terms: you generally may not use their outputs to build a competing model. You may own your outputs, but using them to train models is restricted — read the teacher's terms before you generate.

  • The blessed path: official distillation APIs (e.g., OpenAI's) are a vendor-sanctioned way to train a smaller model on a frontier teacher — they resolve the ToS question.
  • The legal status is contested but ToS still binds you: distillation copies behavior, not text, and AI outputs largely aren't copyrightable (Thaler v. Perlmutter) — but a contract (the ToS) is a contract regardless.
  • Open-weight teachers (Llama, Qwen, Mistral-open) sidestep much of this — check their license, but they're often far more permissive for generating training data.

Note the boundary with the next lesson: synthetic data generation = learn from generated examples; L198 (Model Distillation) = a student mimics a teacher's outputs/logits to compress a big model into a small one. Related, but different goals.

See It: The Synthetic Data Factory

Run the pipeline and watch diversity live. Start with a narrow seed, Self-Instruct, and crank expansion to ×100 with the guards off — watch the scatter collapse into a blob and the collapse-risk go red. Now fix it: switch to Persona-driven or Evol in-breadth, turn on multi-source and real-anchor, and watch it spread back out. Then play with the judge — loosen it to 100% and quality drops (junk gets in); tighten it and quality climbs. The verdict always names the binding constraint.

Interactive: the Synthetic Data Factory. The user operates the seed-to-teacher-to-judge pipeline and watches a task-space scatter of the generated examples either spread out, meaning diverse and healthy, or cluster into sameness, meaning collapse. Six controls drive it: the generation method, from Self-Instruct to Evol-Instruct in-depth and in-breadth to persona-driven to seedless Magpie; the seed richness, narrow versus rich; the expansion factor from two to a hundred times; how aggressively the LLM judge keeps the top fraction; and two collapse mitigations, multi-source generation and a real-data anchor. The scatter plots topic breadth against difficulty, showing which points the judge keeps and which it filters out, and over-expanding a fixed seed without the mitigations visibly pulls the points toward the mean, collapsing the distribution. Live metrics for diversity, quality, quantity, and collapse risk, plus a binding-constraint verdict, name what to fix, whether that is collapsed diversity, an unfiltered set, too little data, samples that are too easy, or off-distribution drift. A pipeline strip with arrow connectors shows seed to teacher to judge to dataset with the live numbers.

The lesson you can see: scale without diversity guards = collapse. A great synthetic set is broad, hard, filtered, and anchored — never just big.

Why This Matters

Synthetic data is the difference between a fine-tuning project that's bottlenecked on human labeling and one that scales to thousands of curated examples in an afternoon. It's how small teams compete: a sharp seed + a frontier teacher + a ruthless judge can produce a dataset that used to take a labeling vendor months. But it's also the easiest way to quietly poison a model — collapse and bias amplification are invisible until your model is bland and skewed in production. Knowing the pipeline, the methods, and (above all) the judge + diversity guards is what makes synthetic data a superpower instead of a footgun. Next, L198 (Model Distillation) takes the teacher–student idea one step further.

🧪 Try It Yourself

Cause and then cure a collapse in the Synthetic Data Factory:

  1. Cause it. Narrow seed, Self-Instruct, expansion ×100, guards off. What happens to the scatter and the collapse-risk meter, and why (in terms of the teacher echoing itself)?
  2. Cure it. Without lowering expansion, get collapse risk back to Low. Which three controls did you use, and which gave the biggest jump in diversity?
  3. The judge trade-off. Set the judge to keep 100% — what happens to quality? Now tighten to ~80%. Why is "an unfiltered set worse than a smaller filtered one"?

Bonus: you want to generate a training set from GPT-class outputs to ship a commercial model. What's the legal risk, and what's the vendor-blessed way to do it?

Mental-Model Corrections

  • "More synthetic data is always better." Past a point, expanding a fixed seed collapses diversity. Scale with diversity guards (multi-source, personas, real anchor), not without.
  • "Synthetic data can create new capability." It amplifies the seed/teacher's signal — it can't invent signal that isn't there. Garbage seed → garbage at scale.
  • "Generate, then just train on it." No — the judge filter is the most important step. An unfiltered set is worse than a smaller filtered one.
  • "Self-Instruct is enough." It gives breadth but easy examples. Add Evol-Instruct in-depth for difficulty.
  • "I own the model's outputs, so I can train anything on them." Frontier ToS forbid building competing models from their outputs — use an open-weight teacher or an official distillation API.

Key Takeaways

  • The pipeline: small real seed → teacher expands 10–100× → judge filters bottom 10–20% → JSONL. Synthetic data is a force-multiplier on a good seed.
  • Methods ladder: Self-Instruct (breadth, easy) → Evol-Instruct (in-depth = harder, in-breadth = wider) → personas (diversity) → Magpie (no seed, can drift). Blend them.
  • The judge is the most important step: an unfiltered set is worse than a smaller filtered one — LLM-as-judge + heuristics + dedup.
  • Beware model collapse: over-generating narrows diversity and amplifies bias. Guard it with multi-source + personas + a real-data anchor.
  • Mind the law: frontier ToS forbid competing-model distillation — use open-weight teachers or official distillation APIs.

Next: L198 — Model Distillation — the teacher–student technique for compressing a big model's capability into a small, cheap one.