准备预训练数据,要同时考虑来源、许可、去重、质量筛选和混合比例。任何一步改变,都可能影响模型接触到的知识与表达方式。这里把重点放在可追溯的数据处理流程,并讨论继续预训练时怎样选取领域数据。
数据管道全景:六个车间
原始网页语料到训练语料的完整流水线,每个环节都有量化标准:
原始语料(CommonCrawl/书籍/代码/论文)
→ ① 语言识别与过滤(留中文+英文,fasttext 语言模型)
→ ② 质量过滤(启发式规则 + 质量分类器)
→ ③ 去重(精确 + MinHash 模糊去重)
→ ④ 隐私脱敏(PII:手机号/邮箱/身份证)
→ ⑤ 毒性过滤(安全与合规)
→ ⑥ 配比混合(domain mixing)
→ 训练语料
①② 质量过滤:比想象得重要
「垃圾进垃圾出」的量化证据:用过滤后的高质量子集训练,等算力下效果超过全量数据——质量过滤本质是在提升算力效率。
启发式规则的第一刀(过滤掉 60~80% 原始网页):
def is_low_quality(text: str) -> bool:
words = text.split()
if len(words) < 50: return True # 太短
if len(set(words)) / len(words) < 0.3: return True # 重复度高
if sum(c.isalpha() for c in text) / len(text) < 0.6: return True # 符号占比高
if "lorem ipsum" in text.lower(): return True
return False
第二刀是质量分类器:用「维基百科/教科书 = 高质量,评论区 = 低质量」训一个小模型(fasttext 就够)给全量语料打分,取头部。这本质是「用 ML 选 ML 的教材」。
③ 去重:MinHash 近似最近邻
精确去重(哈希)只能去完全相同的文档,网页上大量「近乎相同」(多个采集源、模板噪声)的文档需要模糊去重。MinHash 把 Jaccard 相似度估计变成常数时间:
from datasketch import MinHash, MinHashLSH
lsh = MinHashLSH(threshold=0.8, num_perm=128)
for doc_id, text in docs:
m = MinHash(num_perm=128)
for shingle in shingles(text, k=5): # 5-gram 字符切片
m.update(shingle.encode())
lsh.insert(doc_id, m) # 相似文档自动聚桶
# 查询每桶内只留一篇,其余丢弃
去重的价值不止省 token:重复的测试集内容混进训练集 = 基准污染(评测篇的污染源之一)。对 benchmark 语料做专门去污染是严肃训练的标配。
⑥ 配比:数据里的「 curriculum」
不同领域数据(网页/代码/数学/书籍)按什么比例混,直接影响能力结构。DoReMi 等方法用小模型扫描配比再找最优;实践中的经验:
- 代码数据提升推理(即使非代码任务),5~15% 是常见区间;
- 数学/学术文本对推理能力性价比最高;
- 中文场景中英文混比常见 1:1 到 1:2(英文数据质量池更深);
- 配比是实验变量不是先验:训小模型扫几组配比,用 eval 集选,放大。
继续预训练:小团队的主战场
从头预训练是千万美元游戏,但在开源底座上继续预训练(领域适配)是几万块的事:医疗、法律、金融语料喂给 Qwen/Llama 底座,领域能力显著提升。实战要点:
- 数据量:领域语料 1B~10B token 是有效区间;太少(<100M)不如直接 SFT。
- 混通用数据:纯领域数据继续预训练会灾难性遗忘——领域 : 通用 ≈ 7:3 到 5:5。
- 学习率:比从头训练低一个量级(1e-5 附近),warmup 短。
- 何时不该做:只需要「领域风格/格式」→ SFT 就够;只需要「领域知识问答」→ RAG 更便宜。继续预训练解决的是「领域语言理解本身」(术语密集、语体特殊)。
数据文档:Datasheet 纪律
每份训练数据应该有「数据卡」:来源、时间范围、清洗规则版本、去重率、许可证状态、PII 处理记录。三个月后「这版模型为什么比上版差」的答案 90% 藏在数据变更里——没有数据卡,排查无从下手。
踩坑排查
| 现象 | 原因 | 解法 |
|---|---|---|
| 训练后 benchmark 虚高 | 测试集混入训练数据 | 对 benchmark 做 n-gram 去污染 |
| 继续预训练后通用能力崩 | 没混通用数据/lr 太大 | 混 30~50% 通用语料,降 lr |
| MinHash 去重误杀正常文档 | 阈值过低/模板页眉干扰 | 阈值 0.8+,先剥离模板 |
| 质量分类器把好数据也滤了 | 高质量锚点太单一 | 多源高质量样本训练分类器 |
| 小语种能力掉 | 配比里被英文挤压 | 温度采样提升小语种占比 |
练习
- 实现文中的启发式过滤,跑在 1000 篇真实网页文本上,人工抽检 50 条被判「低质」的——误杀率多少?
- 用 datasketch 对 1 万篇文档做 MinHash 去重,统计去重率,抽查几个被合并的文档对确认它们真的相似。
- 设计配比实验:同一小模型分别在「纯网页」「网页+10%代码」「网页+10%数学」上继续训练,在推理 eval 集上对比。
- 给你的领域数据写一份数据卡:来源、清洗规则、去重率、许可证——体验文档化的价值。
面试常问
Q:为什么数据质量过滤能提升算力效率? 低质数据(乱码、模板、机器生成垃圾)不提供有效学习信号却消耗梯度更新。过滤后相同算力下模型看到的「有效信息密度」更高。实证:多个工作(C4、RefinedWeb、FineWeb)显示过滤子集上训练的效果超过全量——数据规模换质量的拐点比直觉来得早。
Q:MinHash 的原理? 对集合的多个哈希函数取最小值,两个集合 MinHash 相等的概率 ≈ 它们的 Jaccard 相似度。128 个哈希(num_perm)把相似度估计方差压低;LSH 分桶把 O(n²) 的两两比较变成近似 O(n)。k-shingle(字符/词片段)的 k 选择:太小误报多,太大漏掉局部改写,5~10 是常用区间。
Q:继续预训练 vs SFT vs RAG 怎么选? 看缺什么:缺「领域语言的理解能力」(术语、文体、隐含知识)→ 继续预训练;缺「任务执行格式与风格」→ SFT;缺「事实性知识」(实时、私有、可溯源)→ RAG。三者成本差两个数量级,能 RAG 不训练、能 SFT 不预训练是预算铁律。
Q:数据配比怎么科学确定? DoReMi 路线:训一个小代理模型,用 Group DRO 优化各域权重使验证损失最小;简化版:网格扫 3~5 组配比在小模型上比 eval。关键认识:配比效果可迁移性有限(小模型最优配比 ≠ 大模型最优),但方向通常一致。
Q:代码数据为什么提升非代码推理? 假设:代码是高度结构化、逻辑严密、长程依赖强的文本——训练它强化了模型的「状态追踪」和「多步推理」能力,这些能力迁移到自然语言推理任务。另一个因素是代码注释/文档字符串提供了「意图→实现」的对齐信号。实证上多个实验室观察到 5~15% 代码配比的正迁移。
相关阅读
- 自监督学习入门——预训练任务的本质
- LLM 对齐:SFT、RLHF 与 DPO——数据工程的下游
- LLM 评测体系——数据污染的检测
- LLM 微调:LoRA 与 QLoRA——轻量适配路线
- 分布式训练入门——预训练规模的工程
「给模型吃什么」比「给模型用什么架构」更接近大模型竞争的本质。数据工程师是这个时代被低估的角色——他们决定模型的天花板,算法工程师只是在天花板上跳舞。
💬 评论
这套方案在哪一步卡住了?也欢迎补充你的实现方式或踩坑经验。