合成数据:方法论、Scaling 边界、Model Collapse¶
更新日期:2026-04-26
一、为什么需要合成数据¶
2024-2026 的核心事实:高质量人类文本即将耗尽。Epoch AI 预测互联网高质量文本将在 2026-2028 年耗尽。合成数据是唯一可扩展的出路。参考 Synthetic Data Scaling Study (2025)。
flowchart LR
real["真实数据池<br/>~50T tokens"]
wall["2026-2028<br/>枯竭点"]
synth["合成数据<br/>(无限上限)"]
train["训练<br/>(混合 30/70)"]
real --> wall
real --> train
synth --> train
classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
classDef warn fill:#f5f3eb,stroke:#cc785c,color:#1a1a1a;
class real,synth,train stage
class wall warn
主流模型训练 token 增速 vs 公开互联网增量:模型每年 3-5×,互联网增量每年 ~10%。叉点就在 2027 前后。这就是合成数据从 nice-to-have 变 must-have 的根因。
二、合成数据的分类¶
| 类型 | 描述 | 质量 | 可 Scaling | 风险 | 实践建议 |
|---|---|---|---|---|---|
| Rephrasing | 强模型(GPT-4 / Claude)改写真实文本为教科书 / 百科风格 | 高 | 是(受限于原始数据量) | 低 | 改写保留分布与事实,不引入幻觉;Phi 系列与 Cosmopedia 的核心方法 |
| Textbook 生成 | LLM 从零生成教科书风格内容,无真实数据锚定 | 中高 | 有限(多样性递减) | 高(collapse) | 模型倾向"平均化"内容,长尾知识逐代丢失;必须混入真实数据 |
| Self-Instruct | 模型从种子指令出发自己生成新指令和回答 | 中 | 有限(多样性饱和) | 中 | 生成质量受限于模型自身能力 |
| Evol-Instruct | 迭代让模型把简单指令变复杂(加约束、加边界) | 高 | 有限(约 5 轮后收益递减) | 中 | 比 Self-Instruct 多样性更好;WizardLM 的核心方法 |
| Magpie | 利用 SFT 模型 chat template,从空 <user> 自回归生成完整对话 |
中高 | 是(不需要种子) | 中 | 巧用模型内化对话分布,零成本启动;分布受源模型偏差 |
| 可验证任务(题库) | 程序化生成数学 / 代码题 + 自动验证器 | 取决于验证器 | 是!真正无限 | 低 | 验证器保证答案正确性,RLVR 黄金搭配;唯一可无限 scaling 的类型 |
| Tool Use 数据 | 模拟 Agent 调用 API / 工具的完整轨迹 | 中 | 是(工具组合空间大) | 中 | sandbox 与真实 API 行为有差异 |
实践笔记:2025-2026 主流做法是混合 — Rephrasing 做预训练增强,Evol-Instruct 做 SFT,可验证任务做 RL。单一方法都有瓶颈。
三、各方法深入¶
3.1 Rephrasing(最安全)¶
# 用强模型改写网页文本, 提高质量和多样性
def rephrase_web_data(raw_text, strong_model):
styles = [
"rewrite this as a high-quality Wikipedia article",
"rewrite this as a clear technical explanation",
"rewrite this as a textbook chapter",
"summarize the key points and rewrite concisely",
]
rephrased = []
for style in styles:
new_text = strong_model.generate(f"{style}:\n{raw_text}")
rephrased.append(new_text)
return rephrased
# 关键发现: 30% 比例的 rephrased 数据是最优
# 训练速度比纯真实数据快 5-10 倍达到同样 loss
# 参考: Cosmopedia (HuggingFace), Phi 系列 (Microsoft)
3.2 Self-Instruct & Evol-Instruct¶
# Self-Instruct (Wang et al. 2022)
def self_instruct(seed_tasks, model, n_iters=10):
task_pool = seed_tasks.copy()
for _ in range(n_iters):
examples = sample(task_pool, 8)
new_task = model.generate(f"""
Based on these examples, generate a new, creative task:
{examples}
New task:""")
answer = model.generate(new_task)
if quality_check(new_task, answer):
task_pool.append((new_task, answer))
return task_pool
# Evol-Instruct: 迭代增加复杂度 (WizardLM)
def evol_instruct(instructions, model, n_rounds=5):
for _ in range(n_rounds):
for i, inst in enumerate(instructions):
harder = model.generate(f"""
Make this instruction more complex by adding constraints,
edge cases, or deeper reasoning requirements:
Original: {inst}
More complex:""")
instructions[i] = harder
return instructions
3.3 Magpie(2024)¶
巧妙之处:利用 LLM 的自回归本质,不需要任何种子指令。参考 Magpie (Xu et al., 2024)。
def magpie(instruct_model, n_samples=10000):
"""SFT 模型天然能从'空' chat prefix 生成 user prompt"""
data = []
for _ in range(n_samples):
# Step 1: 让模型生成一个 user prompt
chat_prefix = "<|user|>"
question = instruct_model.generate(chat_prefix, stop="<|assistant|>")
# Step 2: 让模型回答
full_prefix = chat_prefix + question + "<|assistant|>"
answer = instruct_model.generate(full_prefix, stop="<|user|>")
data.append({"instruction": question, "response": answer})
return data
# 优势: 不需要种子, 数据分布自然, 大规模生成
# Magpie 数据训出的模型 ≥ 人工数据训的效果
3.4 可验证任务生成¶
RLVR 的黄金方向:生成无限的题目 + 验证器对。这是唯一可无限 scaling 的合成数据类型。
import sympy, random
x = sympy.Symbol('x')
def generate_math_problem():
topic = random.choice(['algebra', 'geometry', 'calculus'])
if topic == 'algebra':
degree = random.choice([2, 3, 4])
coeffs = [random.randint(-10, 10) for _ in range(degree + 1)]
poly = sum(c * x**i for i, c in enumerate(coeffs))
answer = sympy.solve(poly, x)
return {
'question': f"Solve {poly} = 0",
'answer': answer,
'verifier': lambda ans: set(ans) == set(answer),
}
def generate_code_problem():
base = random.choice(leetcode_problems)
variations = [
"change the input constraints",
"add edge cases",
"require optimization",
"change the data structure",
]
variation = random.choice(variations)
new_problem = llm.generate(f"Modify: {variation}\n{base}")
new_tests = llm.generate(f"Generate 10 tests for: {new_problem}")
return {
'problem': new_problem,
'tests': new_tests,
'verifier': lambda code: run_tests(code, new_tests),
}
四、Model Collapse¶
4.1 什么是 Model Collapse¶
当模型 M1 用自己生成的数据训练 M2,M2 再生成数据训练 M3... N 代后,模型逐渐"遗忘"真实数据分布的低频部分,变得越来越同质化。参考 The Curse of Recursion (Shumailov et al., 2024)。
flowchart LR
real["真实分布<br/>(长尾完整)"]
m1["M1<br/>(完整 fit)"]
g1["M1 生成<br/>数据"]
m2["M2<br/>(尾部丢失)"]
g2["M2 生成<br/>数据"]
m3["M3<br/>(主峰窄化)"]
real --> m1 --> g1 --> m2 --> g2 --> m3
classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
class real,m1,g1,m2,g2,m3 stage
每代生成都是一次"低频信息蒸发"。直接表现:
- 第 1-3 代:长尾事实 / 罕见词组消失
- 第 5+ 代:主峰开始窄化,输出越来越像 majority
- 第 10+ 代:完全 collapse 到几个 mode
4.2 为什么会 Collapse¶
三个层面的根因:
- 统计 floor:有限样本 N 估计长尾概率有方差。低频事件采样次数少 → 估计偏 0 → 下一代生成时几乎不出现。
- 函数族近似误差:模型表达能力有限,对真实分布只能近似。每次 fit + sample → 误差累积。
- 训练 KL 偏置:max-likelihood 训练对低概率事件容忍度低 → 系统性向 mode 偏移。
数学:[Shumailov 2024 paper §3] 给出迭代 KL 散度发散的形式证明。
4.3 预防 Model Collapse¶
| 策略 | 效果 | 备注 |
|---|---|---|
| 混入真实数据 ≥50% | 强 | 最有效;anchor 长尾分布 |
| 多模型生成 | 中 | 不同模型 collapse 方向不同,互相补 |
| 验证器筛过 | 强 | 过滤错误 / 同质化样本 |
| Diversity reward | 中 | RL 中加 entropy bonus |
| Embedding-space dedup | 弱 | 表面去重,深层分布仍同质 |
核心策略:始终混入真实数据,合成数据比例不要超过 30-50%。
4.4 实验数据(来自 Shumailov 2024 + 后续复现)¶
| 实验 | Setup | 第 N 代崩塌 | 备注 |
|---|---|---|---|
| GPT-2 small 自我循环 | 100% 合成 | N=5 | Wikipedia 长尾词消失 |
| LLaMA-7B 30% 合成 + 70% 真实 | 混合 | 未崩塌 | 即使 10 代仍稳定 |
| Image diffusion 自循环 | 100% 合成 | N=3 | 图像质量 + 多样性都跌 |
| 加 verifier 筛 | 100% 合成 + 筛 | 未崩塌 | RLVR 路径 |
→ 结论:(a) 真实数据比例 + (b) 验证器,任一都能阻止 collapse;纯生成无验证最危险。
五、合成数据能 Scaling 吗¶
flowchart LR
rep["Rephrasing<br/>线性 (×N)"]
sg["Self-Generation<br/>对数 (饱和)"]
ver["Verifiable<br/>无限"]
rep --> rep_lim["上限 = 真实数据 × 改写次数<br/>3-5 次后边际递减"]
sg --> sg_lim["上限 = 模型容量<br/>I(in;out) ≤ params"]
ver --> ver_lim["上限 = 计算成本<br/>题目空间组合爆炸"]
classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
classDef lim fill:#f5f3eb,stroke:#bdb9ab,color:#1a1a1a;
class rep,sg,ver stage
class rep_lim,sg_lim,ver_lim lim
| 类型 | Scaling | 理由 | 上限来源 |
|---|---|---|---|
| Rephrasing | 线性(上限 = 真实 × 改写次数) | 受限真实数据量 × rephrase 次数(3-5 次后递减) | 改写不创造新知识,只增多样性 |
| Self-Generation | 对数 / 饱和 | 模型能力上限就是合成上限 | 信息论:互信息 I(in; out) ≤ 模型容量 |
| Verifiable | 指数 / 无限 | 题目可程序化生成(组合空间指数) | 验证器提供外部真值,打破 collapse 循环 |
六、生产级合成数据 Pipeline¶
flowchart LR
seed["种子<br/>真实数据"]
gen["多模型<br/>生成"]
qf["质量<br/>分类器"]
dedup["MinHash<br/>去重"]
div["embedding<br/>多样性"]
rev["人工抽审<br/>1%"]
mix["混合 30/70<br/>合成 + 真实"]
seed --> gen --> qf --> dedup --> div --> rev --> mix
classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
class seed,gen,qf,dedup,div,rev,mix stage
class SyntheticDataPipeline:
def generate_batch(self, n_samples):
# 1. 多模型生成(避免单一模型偏差)
raw = []
for model in [gpt4, claude, llama]:
raw.extend(model.generate(n_samples // 3))
# 2. 质量过滤
filtered = [s for s in raw if quality_classifier(s) > 0.7]
# 3. 去重
unique = minhash_dedup(filtered, threshold=0.9)
# 4. 多样性检查(embedding 空间分散)
diverse = maximize_diversity(unique)
# 5. 人工抽样审查(1%)
sample = random.sample(diverse, len(diverse) // 100)
reviewed = human_review(sample)
# 6. 与真实数据混合(合成 30%,真实 70%)
real_data = sample_real_data(len(diverse) * 7 // 3)
return diverse + real_data
参考文献¶
- Shumailov et al. The Curse of Recursion: Training on Generated Data Makes Models Forget. 2024. arXiv:2305.17493
- Demystifying Synthetic Data in LLM Pre-training. 2025. arXiv html
- Beyond Model Collapse: Scaling Up with Synthesized Data Requires Verification. OpenReview
- Wang et al. Self-Instruct. 2022. arXiv:2212.10560
- Xu et al. Evol-Instruct / WizardLM. 2023. arXiv:2304.12244
- Xu et al. Magpie. 2024. arXiv:2406.08464
- Cosmopedia (HuggingFace). HuggingFace
- Gunasekar et al. Textbooks Are All You Need (Phi-1). 2023. arXiv:2306.11644
↑ 上级 · B. 数据工程