Synthetic data for evals and fine-tuning

GuideLast reviewed Oct 16, 2026By Himanshu Ramchandani
Short answer

Synthetic data is data generated by a model: questions from your documents for retrieval tests, variations of real inputs, edge cases, attack prompts, or training examples from a larger model. It's useful for coverage and volume when real data is missing, and it drifts from what real users do, so seed it from real data, generate along named dimensions, review samples, and keep a real-data test set as the final judge. A model trained or tested only on data you invented can look good on that data and fail in the real world.

When you need it

You need 500 test questions before launch, and you have no users yet. You need examples of a rare failure, and production has three. You want to fine-tune a small model, and you don't have labelled outputs. Synthetic data fills these gaps.

Generate from structure, not imagination

"Generate 500 customer questions" produces 500 polite, clear, similar questions. Instead, pick real seeds and vary them along dimensions you name:

import itertools
import json

seeds = ["How long do I have to return headphones?", "Can I change my delivery address?"]
dimensions = {
    "persona": ["first-time buyer", "angry repeat customer"],
    "style": ["short with typos", "long and detailed"],
    "twist": ["missing order number", "false premise about a policy"],
}

prompts = []
for seed, combo in itertools.product(seeds, itertools.product(*dimensions.values())):
    spec = dict(zip(dimensions, combo))
    prompts.append({
        "seed": seed,
        **spec,
        "instruction": f"Rewrite the question. Persona: {spec['persona']}. Style: {spec['style']}. Twist: {spec['twist']}. Keep the same intent.",
    })

print(len(prompts), "generation prompts")
print(json.dumps(prompts[5], indent=2))

Each prompt then goes to a model, and the outputs are reviewed before they're used.

Common uses

Use Approach
Retrieval tests Generate questions a passage answers, and keep the passage ID as the label
Edge cases Vary real inputs: typos, other languages, missing details, false premises
Abstention tests Questions just outside the knowledge base
Fine-tuning Teacher model outputs filtered by evals. See distillation
Red teaming Generate attack variants from seed attacks

Keeping it honest

  • Review a sample by hand. Generated data has its own quirks: too polite, too clear, too similar.
  • Filter generated training examples with your evals, so you don't train on the generator's mistakes.
  • Keep the final test set real. Compare pass rates on synthetic and real sets, because a large gap means the synthetic set isn't realistic.
  • Check the provider's terms before training a model on another model's outputs.

Measuring it

The gap between pass rate on the synthetic set and on a real set. A large gap means the synthetic set is measuring something other than your users' experience.

From the floor

When a builder asked whether we could train on pseudo data we created ourselves when real data isn't available, my answer was that it's not the right approach for LLMs on its own: the model may give good results on the data you made up, and then fail when you put it into the real world.

Model Smith, the fourth artifact in AI Engineer HQ, was built around this trade-off: a pipeline that fine-tunes a small model to outperform larger ones on one narrow task, in phases of synthetic data generation, LoRA fine-tuning and a quality gate with an LLM as a judge, using either generated data or existing data from a specific industry, like compliance for healthcare.

Sources