训练数据集构建
问题
微调的训练数据如何构建?数据质量如何保证?
答案
数据质量是微调成功的第一因素——1000 条高质量数据的效果往往优于 10 万条低质量数据。
一、数据格式
| 格式 | 适用训练类型 | 示例 |
|---|---|---|
| Instruction-Response | SFT | {"instruction": "...", "output": "..."} |
| Multi-turn Chat | 对话 SFT | {"messages": [{role, content}, ...]} |
| Preference Pair | DPO/RLHF | {"prompt": "...", "chosen": "...", "rejected": "..."} |
二、数据来源
LLM 合成数据
SYNTHESIS_PROMPT = """基于以下文档内容,生成 5 组高质量的问答对。
要求:
1. 问题自然多样,不要太简单也不要太复杂
2. 答案准确、完整,基于文档内容
3. 覆盖文档的不同方面
文档内容:
{document}
输出格式(JSON 数组):
[{{"question": "...", "answer": "..."}}]
"""
三、数据质量检查
| 检查项 | 方法 | 说明 |
|---|---|---|
| 格式正确 | Schema 验证 | JSON 格式、字段完整 |
| 长度合理 | 统计分布 | 过短/过长的样本可能有问题 |
| 去重 | 精确+模糊去重 | 重复数据会导致过拟合 |
| 语言质量 | LLM 打分 | 语法、逻辑、流畅度 |
| 答案准确性 | 人工+自动验证 | 错误答案比没有答案更有害 |
import hashlib
from collections import Counter
def deduplicate(dataset: list) -> list:
"""基于内容哈希去重"""
seen = set()
unique = []
for item in dataset:
text_hash = hashlib.md5(item["output"].encode()).hexdigest()
if text_hash not in seen:
seen.add(text_hash)
unique.append(item)
return unique
def check_length_distribution(dataset: list):
"""检查长度分布"""
lengths = [len(item["output"]) for item in dataset]
print(f"平均长度: {sum(lengths)/len(lengths):.0f}")
print(f"最短: {min(lengths)}, 最长: {max(lengths)}")
# 过滤极短(<50字符)和极长(>5000字符)样本
return [item for item in dataset if 50 <= len(item["output"]) <= 5000]
四、数据配比
多种类型数据混合训练时,需要考虑配比:
| 数据类型 | 推荐比例 | 作用 |
|---|---|---|
| 领域数据 | 60-70% | 核心目标 |
| 通用数据 | 20-30% | 防止灾难性遗忘 |
| 安全数据 | 5-10% | 安全对齐 |
常见面试问题
Q1: 合成数据和人工标注数据哪个更好?
答案:
- 质量:同等投入下,人工标注质量更高,尤其是复杂/专业领域
- 成本:合成数据成本可低 10-100 倍
- 最佳实践:用 LLM 批量生成 → 人工抽检校正 → 用高质量种子数据引导生成风格
Q2: 数据量不够怎么办?
答案:
- LLM 合成:用 GPT-4 等强模型生成训练数据
- 数据增强:改写、同义替换、翻译回译
- LoRA + 小数据:LoRA 天然适合小数据场景(正则化效果)
- 蒸馏:用大模型输出作为训练数据