直接把网页爬下来就能训练吗?
本课一问:C6 算出 Llama 3 8B 要喂 15T 个 token。最直接的来源是整个互联网——直接把网页爬下来就拿去训练,可以吗?
这一课先不碰:同一段话重复出现怎么办(第 2 课)、「合法但没营养」的文本怎么筛(第 3 课)、各类数据按什么比例混(第 4 课)。
从已有出发
前六章一直在处理流水线的中段:文字怎么切成 token、token 怎么变向量、向量怎么过注意力和 FFN、参数怎么更新、要训多大。流水线最左端那一格「文字」,一直被当成理所当然的输入。
这一章就是在回答那一格从哪来。数据本身也是一条流水线,本课只看它的前四个环节:
先感受一下量级。我们项目的语料是整部《三國志演義》,用项目分词器切出来一共 560,001 个 token(训练集 501,615 + 验证集 58,386)。Llama 3 8B 训了 15T token,相当于把这部书重复约 2.68 × 10⁷ 遍。书、百科这类「干净」文本远远不够,大头只能来自网页。
先自己设计:原始文件直接拿来用
我们手上就有一份和网页一样脏的原始文件:项目语料的原样 pg23950.txt。它有 1,863,656 字节,带 21,682 个 Windows 换行符、782 字节的英文头部声明和 18,551 字节的英文尾部许可证,正文每 38 个字硬换一行,共 17,584 行。
最朴素的清洗是:直接拿它跑一条最常用的规则——C4 数据集的「只留以句末标点结尾的行」(C4 原版的标点是 . ! ? “,这里先替我们换成中文的 。!?」』”…):
- ① 朴素方案
- ② 它在哪失败
- ③ 改进方案
在 17,584 行原始硬换行行上逐行判断:以中文句末标点结尾的留下,其余删掉。
- 留下 4,299 行,占 24.45%;按字数算只留下 17.02%。
- 如果照搬 C4 原版的英文句末标点 . ! ? “,一行都不剩:0 行。
项目的 clean_gutenberg() 先做两件事:只留 *** START OF 与 *** END OF 之间的正文;把以全角空格或「第…回」开头的行当成新段落,其余行接回上一行。17,584 行拼成 3,697 段。
同一条规则在段落上求值:留下 3,373 段,占 91.24%,按字数 94.27%。被删的 324 段主要是回目标题(「第一回:宴桃園……」)和「詞曰:」「後人有詩曰:」这类引出诗词的行——它们以冒号结尾。
网页的「硬换行」叫样板:导航栏、cookie 提示、分享按钮、推荐列表、页脚。Common Crawl 的每个快照同时提供两种格式:WARC 是原始 HTML,WET 是它自带的纯文本版。FineWeb 发现 WET 留下了太多样板和菜单文字,改用 trafilatura 从 WARC 里抽正文;在同样 28B token 的消融里,抽取后的数据训出的模型明显更好 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条1.71B 参数的消融模型、28B token;除了 fastText 英文识别,两边都没做别的过滤和去重。论文只给了曲线,正文没给具体分数。 出处FineWeb §3.2 图 1 ↗ 。下面两个实验把这两件事都放到你手里:
教学构造的小说网站网页(正文是《三國志演義》第一回的真实首段)。浏览器当场用 DOMParser 解析下面这份 HTML。
看 HTML 源码(1,223 个字符)
项目语料 pg23950.txt 的原样:每 38 个字硬换一行(第一回首段拆成了 5 行)。C4 的规则是逐行判断「是否以句末标点结尾」,顺序不同,结果天差地别。
试三件事:① 在「网页」标签下切换两种抽取,读出样板占去标签结果的百分比——这就是 WET 式纯文本的问题;② 看「正文抽取」删掉每个块的理由:按所在区块、按链接占比、按长度,三类理由各对应一条常见启发式;③ 切到「我们的原始文件」,在「不还原」和「先拼回段落」之间来回点,整本书的留存率在 17.02% 和 94.27% 之间跳。
改进一:把「有人觉得值得看」当过滤器
GPT-2 的做法绕开了直接用 Common Crawl:作者只抓取 Reddit 上得到至少 3 karma 的外链,把「有人点过赞」当成质量的代理。4,500 万个链接,抽取正文、去重和启发式清洗后,得到约 800 万篇文档、40 GB 文本,叫 WebText;为了避免和测试集重叠,还删掉了所有维基百科页面 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条报告没有给 karma 阈值的消融,「≥ 3 karma 代表值得看」是作者的启发式假设。 出处GPT-2 报告 §2.1 ↗ 。
它的问题是量:40 GB 文本离 15T token 差几个数量级,而且只覆盖被 Reddit 用户分享过的那一小部分网页。GPT-3 把这个思路反过来用:拿 WebText、维基和书当「好样本」训一个分类器,去 Common Crawl 里捞长得像它们的网页——这是第 3 课的起点。
改进二:只看长相的规则
量要大,就只能从全网快照出发,再用便宜的规则删掉明显的垃圾。两套最常被引用的规则:
- C4(T5 论文,Raffel 2019 §2.2):用 langdetect 只留英文概率 ≥ 0.99 的页;只留以句末标点结尾、至少 5 个词的行;留下的少于 3 句就整页丢掉;含脏词表里任何词的页丢掉;含「Javascript」的行、含「lorem ipsum」的页、含花括号
{的页(代码痕迹)都删;删掉维基式的引用标记,以及提到 terms of use、cookie policy 之类的行;最后对重复出现的三句窗口去重。 - Gopher / MassiveText(Rae 2021 附录 A):文档必须有 50–100,000 个词;平均词长 3–10;「#」或省略号与词数之比不超过 0.1;以项目符号开头的行不超过 90%、以省略号结尾的行不超过 30%;至少 80% 的词含字母;至少出现 2 个英文停用词(the、be、to、of、and、that、have、with)。另有一组重复规则,例如重复行占比超过 0.30 就删 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条阈值是作者按经验定的;论文用它们构建 MassiveWeb,没有给每一条阈值的单独消融。 出处Gopher 附录 A.1.1、表 A1(需联网) ↗需联网 。
这些规则全部是在英文网页上设计、在英文网页上调阈值的。套到我们的书上会怎样?下面的求值器把两套规则逐条跑在三段真实原文、三段标明「教学构造」的网页文本和你输入的文本上;最下面是整本书 3,697 段的结果。
试三件事:① 在英文原版下读整本书那张表:「50–100,000 个词」一条就删掉 3,697 段——中文不用空格,按空白切出来每段最多 2 个「词」;② 切到「本课中文改写」,在「文言虚词表」和「现代虚词表」之间切换,看删除率怎么从 15.5% 跳到 46.1%(整本书「的」只出现 149 次,「之」7,833 次);③ 把最少字数拖到 0 再拖回 50,看被删的是谁:回目、诗、章末套话——再点「按回」,同样的规则按整回求值,几乎全部通过。
它在哪失败
规则本身很便宜,也确实有用:FineWeb 的基础过滤(URL 黑名单、fastText 英文识别、MassiveText 的质量与重复规则)在 96 个快照上留下约 36T token,训出的模型比不过滤的明显更好。但上面的实验暴露了三个问题,前两个是我们在自己语料上实测的,第三个来自 FineWeb 的消融:
- 规则绑着语言和文体。英文原版在整本书上一段不留;改成中文后,虚词表的选择又能让删除率差约 3 倍——现代汉语的高频虚词在文言小说里几乎不出现。
- 规则绑着求值单位。同一条句末标点规则,在硬换行的行上删掉 83% 的字,在段落上只删 6%;同一条「≥ 50 字」规则,按段删 8.8%,按回几乎不删。FineWeb 抽 WARC 而不用 WET,本质上也是在修正「单位」。
- 规则越严不等于越好。C4 的句末标点规则单独用时对 HellaSwag 提升最大,但删掉约 30% 的 token;FineWeb 最后没有用它,只用了其余的 C4 规则(合计删约 7%) 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条在 2019-18 快照上的 1.71B 消融;花括号规则删 2.8%、词长规则删 4.3%,lorem ipsum、javascript、policy 三条各删不到 0.5%。 出处FineWeb §3.5 图 6 ↗ 。
FineWeb 给出的改进是用数据挑阈值:把同一个快照分别做「独立去重」和「全局去重」,当成一份高质量、一份低质量数据(第 2 课会讲为什么全局去重的那份更差),统计 50 多个指标,看哪些指标的分布在两份数据之间差得最多,再在低质量数据更密集的区间下刀。16 个候选里留下 3 条:以标点结尾的行占比 ≤ 0.12 就删(删 10.14% 的 token,C4 那条是 30%)、重复行字符占比 ≥ 0.1 就删(删 12.47%,MassiveText 原阈值是 0.2)、短于 30 字的行占比 ≥ 0.67 就删(删 3.73%);三条合用删约 22%,综合得分涨约 1 个点,并且超过了 C4 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条28B token 的 1.71B 消融;1 个点的提升在这个规模上是显著的,但只是一个快照上的结果。 出处FineWeb §3.6、附录 E.4 表 2 ↗ 。
常见误解一:「规则是通用的,抄来就能用。」Gopher 与 C4 的阈值是在英文网页上定的。原样套在中文上,「按空白数词」这一步就让整本书全军覆没;改成中文后,虚词表、长度门槛、句末标点集合全都要在你自己的数据上重新求值。
常见误解二:「规则越严,数据越干净,模型越好。」C4 的句末标点规则删掉约 30% 的 token,FineWeb 用一条只删 10% 的替代规则反而更好。删掉的不全是垃圾,也有正常内容。
常见误解三:「清洗步骤的先后无所谓。」同一条规则,在还原段落之前跑,整本书留下 17.02% 的字;之后跑,留下 94.27%。抽取与还原必须在任何逐行规则之前。
🔍 「含字母的词 ≥ 80%」为什么全过?
这条规则本来是为了删掉满是数字、符号的页面。它在实现里通常写成「这个词里有没有任何一个字符是字母」,而 Unicode 把汉字归在字母类(Lo)。所以一段中文按空白切成一个「词」,这个词里当然有字母——规则全部通过,但原因和设计者想的完全不同。这是「规则在别的语言上碰巧过」的例子:通过不代表它在检查你以为它在检查的东西。
🔍 我们这部「干净」的书里有没有脏字符?
有。整本书里有 17 处 ASCII 杂字符:大部分是用英文句点打的省略号「…」,还有两处看起来像录入错误的字母——「未知可去否?d憲英曰」「皇后曰:c內廷耳目頗多」,d 和 c 大概本该是「」」和「「」。「不含 ASCII 字母」这条规则会为了一个误植的字母删掉整段;更好的处理是修字,而不是删段。网页数据量太大,只能删;精选语料量小,值得修。
放回演进图里
规则过滤是预训练数据演进的第二代;它的前一代是 GPT-2 那种「让人当过滤器」。整张图在章首页,这里只看本课所在的位置:
- 解决了量几乎无限:Common Crawl 定期抓取全网,FineWeb 用了 96 个快照。卡在WET 纯文本里样板和菜单太多(FineWeb §3.2);我们的原始文件不还原硬换行就跑 C4 句末规则,整本书只剩 17.02% 的字。
- 解决了Reddit 上至少 3 karma 的外链,4,500 万个链接,清洗后约 800 万文档、40 GB。卡在量太小:C6 算出的需求是十几 T token;而且只覆盖被分享过的那一小部分网页。
- 解决了句末标点、词数、平均词长、停用词、重复行……便宜,能在全网快照上跑。卡在绑语言、绑求值单位:英文原版在整本《三國志演義》3,697 段上通过 0 段;C4 句末标点规则删掉约 30% 的 token,FineWeb 最后没用它。
- 解决了C4 里一句话重复 61,036 次;去重后模型复述训练文本的频率降到 1/10。MinHash 把两两比较变成查桶。卡在去得越狠未必越好:跨 96 个快照全局去重只剩 4T,训不出更好的模型;每快照独立去重留 20T,才追平 RefinedWeb。
- 解决了判断「有没有营养」:FineWeb-Edu 让 Llama-3-70B 标 46 万页、蒸馏成分类器,MMLU 33% → 37%。卡在参考语料的困惑度偏向「像参考」:我们模型写的胡话困惑度 93.417,低于真原文 273.209;阈值 3 删掉 92%,长程训练不够用。
- 解决了DoReMi 用 280M 代理模型搜域权重,8B 模型下游平均 +6.5 个点,达到基线快 2.6 倍。卡在权重一变就要重复:按 DoReMi 的权重花完 The Pile 的有效体量,YouTube 字幕要走约 16.9 遍(按字节近似 token,只看量级)。
- 解决了重复 4 遍以内几乎等于新数据;改写真实网页(WRAP)预训练约快 3 倍;Phi-4 约 10T token 里合成占 40%。卡在让模型只吃自己生成的数据,分布的尾巴一代代消失:在三国演义真实字频上重采样,只出现 1 次的字每一代有约 36.8% 的概率丢掉,丢了就回不来。
- 解决了最好的数据放到学习率衰减段(C5 的 WSD)加量;再发展成独立阶段,顺便拉长上下文。卡在同名不同方:Qwen3 的高质量阶段占 13.9%,Llama 3 的退火只占 2.6e-6;收益与学习率调度缠在一起,很难单独归因。
证据三问
| 问 | 本课的回答 |
|---|---|
| ① 它解决什么问题? | 从海量原始网页里,便宜地删掉样板、乱码、非目标语言和明显的垃圾,留下可以训练的正文 |
| ② 数学上为什么可能有效? | 没有数学保证。规则是对「好文本长什么样」的经验描述 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条每条规则背后都有一个直觉(好文本句子完整、词长正常、不重复),但没有任何一条被证明与「训练后模型更好」等价。 出处待补 |
| ③ 实验上为什么最后选了它? | 靠一条条消融:FineWeb 每加一步都比上一步好,也因为消融删掉了 C4 的句末标点规则 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条全部是 1.71B 模型在 28B 或 350B token 上的消融,英文网页;换语言、换规模需要重做。 出处FineWeb §3.3–3.7、图 9 ↗ ;我们的实测只说明「规则在中文书上怎么失效」,不能证明哪条规则让模型更好 |
一句话
规则只看文本的长相:先把网页还原成正文,再在你自己的数据上逐条求值——英文规则原样套在中文上,会把最好的文本删光。
先停在这里:记住「先抽取还原、后跑规则;规则要在自己的数据上求值」。
再深一层:打开 FineWeb 长文的「Developing additional heuristic filters」一节,对照本课的求值器,看它是怎么用两份数据的直方图挑出 0.12 这个阈值的。
下一个缺口
规则留下来的文本里,同一段话可能出现成千上万次,会怎样? → 第 2 课:同一段话在语料里出现几万次,会怎样?
先记下一个线索:FineWeb 挑阈值时用的「低质量数据」,是同一个快照做了全局去重之后的版本。去重怎么会让数据变差?第 2 课兑现。
你可能会问
- 「为什么不只用书和维基百科?」 量不够。我们整部《三國志演義》只有 560,001 个 token;C6 里的 15T 是它的 2.7 × 10⁷ 倍。书和百科会被上采样(多喂几遍,第 4 课),但主体只能是网页。
- 「语言识别是怎么做的?」 用一个很小的分类器(fastText 或 langdetect)给每页打「是英文」的概率,低于阈值就丢:FineWeb 取 ≥ 0.65,C4 取 ≥ 0.99。多语数据集对每种语言各做一遍。阈值本身也是按消融定的。
- 「规则会不会误删好内容?」 会,本课的求值器里就有:回目、诗、章末套话都被「≥ 50 字」删掉。所以 FineWeb 宁可用一条删得少的规则,也不用删得多的那条。