数据工程 — 从原始网页到训练料的提纯流水线
这一章讲三件事: 收来的数据按什么分类、各类管什么能力(书的 份额小,却管长文本); 三道清洗工序各自的阈值怎么定(0.1% 的重复数据就能让模型折半); 以及最后两步——文本怎么切成 token、各种料按什么比例和顺序下锅。 主走查: 一篇论坛帖子从 Common Crawl 的矿里被捞上来,走完四道工序变成训练数据的全过程。
1. 顶层全景:五步把矿石炼成燃料
第 03 章说过,原始网页的清洗存留率约 1.38%——网页是矿石不是燃料。这一章就是那座冶炼厂的内部构造。原书把预训练数据的准备讲成五步1:
① 收集 ② 清洗(三道工序) ③ 切分 ④ 配比与排序 ⑤ 下锅训练
通用文本 ──→ 质量过滤(低质的扔) ──→ 切成 token ──→ 定比例、定顺序 ──→ 喂给模型
专用文本 敏感过滤(有毒的、隐私的扔)
去重(重复的扔)
图说:②③④ 是本章的三个主角;每一步都有自己的阈值,阈值定在哪,就是质量和数量的取舍线画在哪。
先交代两个贯穿全章的词。阈值:一条分数线——分类器(自动给文本分类的小模型, 比如「这篇是垃圾页/正常页」)给每篇文档打个分,高过线就留、低过线就扔; 线画高了漏掉毒药,画低了误杀好料,全章的取舍都绕不开它。配比:各种数据源在训练料里各占多少, 比如网页八成、代码半成——第 02 章讲「数据要配平」说的是总量,这里说的是内部结构。
2. 收集:通用文本管广度,专用文本管特长
原书把预训练数据分两大类2。通用文本(网页、书、日常对话)是主料,胜在量大、样多、易得; 专用文本是为特定能力补的料,三种各管一件事3。表里两个词先说掉:序列,即按顺序排列的一串符号,蛋白序列、时间序列都是。
另一个词:语义,即文本里的含义。
| 料 | 管什么 | 一个具体的数 |
|---|---|---|
| 多语文本 | 翻译、跨语言问答 | BLOOM 用 46 种语言、PaLM 用 122 种4 |
| 科学文本 | 科学问答与推理 | 含公式、蛋白序列(按顺序排列的一串符号),切分要专门处理5 |
| 代码 | 结构化语义(文本里的含义)与逻辑推理;函数调用(代码里「谁调用谁」的关系)关系还帮助工具使用 | 01 章的 Codex 换挡就是它的效果6 |
通用文本里有一个反直觉的角色:书。按份量它是小头(LLaMA 配方里只占 4.5%,见 §6), 但原书专门指出,书的文本更正式、篇幅更长,管的是长程语义关联——模型要能记住 几百页之前埋的伏笔,靠的就是这种长文本7。网页管「见多识广」,书管「记得住上下文」, 两者补的不是同一种能力。这也解释了第 03 章那个张力:数据要越多越好,而最大的来源(网页)恰恰最脏。
3. 清洗前两道:质量过滤与敏感过滤
3.1 质量过滤:两道工序,一粗一精
第一道要解决的是:网页里混着大量机器生成的广告页、模板页。原书给出两类方法8。
启发式(凭经验定的规矩,不保证最优但管用)方法——人写规则,机器照执行。 原书从 Dolma、RefinedWeb 这些真实数据集的清洗方案里抄了一串规则9:
| 规则 | 出处 |
|---|---|
| 含超过 100 个重复词或句的网页文档,删 | Dolma |
| 符号与词的比例超过 0.1 的,删 | Gopher |
| 论坛里点赞不到 3 的用户评论,删 | Dolma |
| 维基百科不足 25 个词的页面,删 | Dolma |
| 不含 the/be/to/of/and/that/have/with 任何一个的英文网页,删 | Gopher |
| 删掉 HTML 标签 | RefinedWeb |
还可以用困惑度来筛:让一个现成的语言模型给文档打分, 它觉得「这话不像人话」的程度就是困惑度,分数太高的句子删掉10。 另一类是分类 器方法——先人工标一批好料坏料,训一个自动判质的分类器(给文本分好坏类别的模型), 再让它给全部语料打分。常用的分三档:fastText 最轻快但精度(判得准的程度)中等;微调过的 BERT 更准;直接拿大模型当裁判最准, 但给几十亿篇文档逐篇判一遍,成本高到一般不这么干11。
分类器有个必须知道的副作用:它可能误杀高质量的小众文本——原书举的例子是文言文, 在分类器眼里它太「怪」了,容易被当成低质文本删掉。原书建议数据工程师建立保留机制, 或用多个分类器联合投票降低误杀12。实战策略是两道配合:启发式先粗筛(快,几十亿篇也跑得动), 分类器再精筛(准,但只处理粗筛剩下的)13。
3.2 敏感过滤:毒性与隐私,各有各的阈值
第二道管两件事。毒性过滤:用 Jigsaw 数据集(约 16 万条论坛评论,人工逐条标了 「有毒/严重威胁/侮辱」等六类标签)训一个毒性分类器,按阈值删14。 阈值怎么定是这笔账的核心:Dolma 团队发现阈值高了毒性漏网、下游任务成绩受损, 阈值低了误杀太多、数据集急剧缩水;他们最后选了偏高的阈值—— 仅凭这一步就滤掉了 Common Crawl 约 30% 的数据15。 (对照第 03 章的 1.38%:那 98.6% 里,相当一块是在这一步被扔的。)
隐私过滤:训练料里有真人名、电话、邮箱。不处理会怎样?2023 年 11 月有人发现,
让 ChatGPT 不停重复一个词(「poem poem poem……」),它重复着重复着会突然背出
训练数据里的真人信息——姓名、头衔、邮箱、电话号码一字不差16。
Dolma 的对策是一条带梯度(这里指按严重程度分档处理,不是数学里的导数)的规则:检测到邮箱/电话/IP 地址,
一篇里少于 5 处就替换成占位符(如 |||EMAIL_ADDRESS|||),6 处以上整篇删除17。
4. 清洗第三道:去重,和「0.1% 毁掉一半」的实验
第三道工序回答一个问题:同 一篇文章在网上被转载了一千次,要不要留一千份? 答案是不但要删,而且不删的代价可以精确量化。原书引用的实验: 把 0.1% 的语料重复 100 次喂进去,一个 800M 参数的模型会退化到 400M 的水平—— 千分之一的脏数据,废掉了模型一半的参数18。机制是语言模型记性太好: 重复出现的模式会被背下来(过拟合——把训练数据死记硬背,而不是学会规律), 表现为输出复读、训练损失忽上忽下地震荡;重复数据还会削弱上下文学习的泛化能力19。
去重怎么做到几十亿篇的规模?两个维度: 粒度分句级、文档级、数据集级(比如多个网址指向同一页,文档级一次删掉)20; 匹配方法分精确匹配(逐字符相同才算)和近似匹配(差不多像就算)。
近似匹配的主力算法叫 MinHash:哈希(把任意长文本压成一个固定长度的数)先把每篇文档压成一组数——「最小哈希值」,取每个集合里哈希值最小的那个当代表; 两篇文档的「最小哈希」有多少比例相同,就估计它们有多相似。 这样不必两两比对全文,只比几个数,几十亿篇也跑得动21。 RefinedWeb 的搭配是:文档级用近似匹配(省算力),句子级用精确匹配(保准头)22。
顺带说清洗不净的另一种后果:数据污染——评测用的考题混进了训练料。 原书给的极端数字:如果整个测试集泄漏进训练数据,一个 1.3B 的小模型在受污染任务上 能超过正常评测的 65B 大模型23。这等于考试前发了答案,分数不再说明能力。 这件事是第 15 章(评估)的常驻背景,也是作者团队自己发过论文警告的问题(见第 16 章)。
5. 切分:文本怎么变成 token
第 01 章说 token 是模型读写文本的最小单位,这一节讲它是怎么切出来的。 为什么不直接按词切?按词切词表会爆炸,低频词没出现过就不认识 (这叫未登录词问题,英文缩写 OOV);按单个字符切又太碎,一个英文单词碎成五六个单位, 句子变得很长。
现在的主流是折中的子词:常见词整个算一个 token, 生僻词拆成几个常见碎片——「unbelievable」切成「un+believe+able」,每个碎片都常见24。
三种子词切法,原书各给了一句话的机理:
-
BPE(字节(计算机存文本的最小单位,一个英文字母 占一个字节,一个汉字通常占三个)对编码): 1994 年原本是个数据压缩算法。做法是从单个字符起步, 反复把语料里出现次数最多的相邻对合并成一个新 token,直到词表够大。 GPT-2/LLaMA 用的是它的字节级版本:基础符号是 256 个字节, 任何语言文字都能拆到字节,所以永不缺字。GPT-2 的词表 50,257 = 256 个基础字节 + 1 个文本结束符 + 50,000 次合并学来的碎片25。
-
WordPiece:思路和 BPE 一样,合并标准不同——不选「最频繁」的对, 而选「合并分」最高的对:合并分 = 这对同现的次数 ÷(第一个的出现次数 × 第二个的出现次数), 专挑「彼此特别有缘分」的组合(两个各自常见但凑一起更罕见的对,分数更高)。BERT 用的就是它26。
-
Unigram:方向反过来——先准备一个超大的词表,逐步往里删, 每轮删掉「删了之后语料似然(这份语料在当前切法下出现的总可能性)降得最少」的 token—— 降得少,说明这个 token 可有可无。T5 用的这种27。