合成数据

返回数据工程

使用算法、模型或仿真生成的数据,而非从真实世界采集。当真实数据稀缺、标注昂贵、或涉及隐私时,合成数据是绕过数据瓶颈的关键手段。


合成数据的价值

场景真实数据问题合成数据方案
医疗影像隐私合规限制共享GAN 生成患者影像
罕见场景真实事件极少发生仿真生成极端情况
指令微调人工标注成本高LLM 批量生成指令对
代码数据特定语言/框架样本少模板+规则生成
对话数据真实对话难收集模型自我对话

主要生成方式

基于 LLM 的文本合成

用大模型生成训练数据,是目前最主流的方式:

import anthropic
 
client = anthropic.Anthropic()
 
def generate_instruction_pairs(topic: str, n: int = 100) -> list[dict]:
    """生成指令微调数据对"""
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=4096,
        messages=[{
            "role": "user",
            "content": f"""生成 {n} 条关于"{topic}"的指令-回答对,用于微调语言模型。
要求:
1. 指令多样,覆盖解释、比较、计算、分析等不同类型
2. 回答准确、完整、有教育价值
3. 输出 JSON 数组格式:[{{"instruction": "...", "output": "..."}}]
只输出 JSON,不要其他文字。"""
        }]
    )
    import json
    return json.loads(response.content[0].text)

Self-Instruct / Alpaca 方法

用种子指令 + LLM 自动扩展,生成大规模指令数据:

1. 人工准备 175 条种子指令(覆盖多种任务类型)
2. 随机从种子中采样 3-5 条作为示例
3. 让 GPT/Claude 生成新的指令
4. 过滤低质量(重复、太短、无意义)
5. 重复直到达到目标数量

代表数据集:Alpaca(52K)、Dolly(15K)、OpenHermes

基于模板和规则

适合结构化数据:

import random
 
def generate_sql_training_data(schema: dict, n: int = 1000) -> list[dict]:
    """根据数据库 schema 生成 NL → SQL 训练对"""
    templates = [
        ("查询{table}中所有{field}大于{value}的记录",
         "SELECT * FROM {table} WHERE {field} > {value}"),
        ("统计{table}中每个{group_by}的数量",
         "SELECT {group_by}, COUNT(*) FROM {table} GROUP BY {group_by}"),
    ]
    pairs = []
    for _ in range(n):
        template_nl, template_sql = random.choice(templates)
        # 填充真实的表名、字段名
        ...
        pairs.append({"question": nl, "sql": sql})
    return pairs

GAN / 扩散模型合成图像

# 使用 diffusers 生成图像数据
from diffusers import StableDiffusionPipeline
 
pipe = StableDiffusionPipeline.from_pretrained("stabilityai/stable-diffusion-2-1")
pipe = pipe.to("cuda")
 
prompts = [
    "a photo of a cat sitting on a sofa, realistic, high quality",
    "a dog running in the park, daylight, photorealistic",
]
 
for i, prompt in enumerate(prompts * 50):
    image = pipe(prompt).images[0]
    image.save(f"synthetic_dataset/image_{i}.jpg")

质量控制

过滤策略

def filter_synthetic_data(samples: list[dict]) -> list[dict]:
    filtered = []
    seen = set()
 
    for s in samples:
        text = s["instruction"] + s["output"]
 
        # 1. 去重(相似度过高)
        if text[:50] in seen:
            continue
        seen.add(text[:50])
 
        # 2. 长度过滤
        if len(s["output"]) < 50 or len(s["output"]) > 2000:
            continue
 
        # 3. 质量评分(用小模型打分)
        score = quality_score(s)
        if score < 0.7:
            continue
 
        filtered.append(s)
 
    return filtered

数据多样性检查

from sentence_transformers import SentenceTransformer
import numpy as np
 
def diversity_score(texts: list[str]) -> float:
    """评估合成数据的语义多样性"""
    model = SentenceTransformer("all-MiniLM-L6-v2")
    embeddings = model.encode(texts)
    
    # 计算平均成对距离(越大越多样)
    n = len(embeddings)
    distances = []
    for i in range(min(n, 500)):
        for j in range(i + 1, min(n, 500)):
            dist = 1 - np.dot(embeddings[i], embeddings[j])
            distances.append(dist)
    
    return np.mean(distances)

注意事项

风险说明对策
模型坍缩用合成数据训练的模型再生成合成数据,质量递减始终混入真实数据锚点
偏见放大生成模型的偏见被固化到训练数据多样化提示词,人工审查样本
幻觉传播LLM 生成的错误事实混入训练集对事实性内容做验证或限制使用场景
版权问题合成数据可能复现训练数据中的受版权内容过滤已知文本,法律评估

相关文档