从0训练LLM · 现代大模型体系 阅读 + 实验 ≈ 30 分钟 页内实验 ×2
C7 数据:从哪来、怎么洗、怎么配 第 5 课

高质量数据用完了怎么办?

数据墙:重复与合成
两条朴素出路:同一份数据多训几遍——4 遍以内几乎等于新数据,再往后越来越不值;让模型自己生成数据喂自己——在三国演义的真实字频上重采样,只出现一次的字每代丢掉约 37%,丢了就回不来。现代做法是改写真实文本、与真实数据混合。
❓

本课一问:质量分类器删掉了 90% 以上的数据,配比又把小而精的数据上采样好几遍。高质量数据不够用了,怎么办?

这一课先不碰:最好的数据在训练的哪个阶段喂(第 6 课);后训练里的合成数据与蒸馏(C12)。

从已有出发

从已有出发 · 累计数据流 点已学环节看形状与参数
解码层

模型这条流水线上,本章始终停在最左边的「文字」一格;把这一格展开,就是下面这条数据管线:

从已有出发 · 数据管线 本课其他环节点环节看它做什么、真实数字

贯穿任务里,我们其实早就撞上了这堵墙:整部《三國志演義》的训练集只有 501,615 个 token,而项目的基线模型训练 400 步,已经把它过了 6.5 遍。前沿模型面对的是同一个问题的放大版:筛完只剩 1.3T 的高质量数据,却要训十几 T token。

先自己设计:同一份数据多训几遍

  1. ① 朴素方案
  2. ② 它在哪失败
  3. ③ 改进方案
朴素方案数据不够,就把同一份数据多训几遍

项目的真实日志:和基线完全相同的配置,只把步数拉到 1,500 步(约 24.5 个 epoch)。

  • val loss:第 300 步(4.9 个 epoch)到最低 4.771,之后一路升到 6.906;
  • 训练窗口上的 loss 降到 0.704——模型在背书:训练集越来越熟,没见过的后文越来越差。
重复数据的有效量(Muennighoff et al. 2023 式 5)
= + U · · (1 − )
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
代入:训 4 遍(R = 3)相当于 3.73 份新数据,折合 93%;训 16 遍相当于 10.58 份,折合 66%;训 40 遍相当于 15.17 份,折合 38%(下面的计算器实时算)。
计算器 + 项目真实日志 · 重复多少遍还值
论文公式:重复 E 遍,相当于多少份新数据?
我们的项目:同一份 50 万 token,反复训
val loss(1,500 步)训练窗口 loss(1,500 步)val loss(400 步基线)

🎯

试三件事:① 把 epoch 拖到 4、16、40,读「折合 %」和「第 E 遍里的一个 token 值多少」;② 看右图蓝线的最低点在 4.9 个 epoch,再看绿色虚线(400 步的基线)在 6.5 个 epoch 时反而更低——读图下的说明,想想为什么「最佳 epoch」不能直接从这条曲线读出来;③ 注意两张图的横轴都是 epoch,但左边是论文在大规模上的拟合,右边是我们 3.7M 参数的小模型:只比形状,不比数值。

朴素方案二:让模型自己生成数据

另一条路更诱人:训好的模型能写出无穷多的文本,拿它的输出当新数据,是不是就没有数据墙了?

Shumailov 等人把这个循环做成了实验:用上一代模型生成的数据训练下一代,如此递归。在高斯混合模型、VAE 和 OPT-125m 上都看到同一件事——原始分布的尾部先消失,最后收敛到一个方差很小的分布,他们叫它 model collapse 。

为什么是尾部?用我们自己的语料就能算。训练集里有 4,072 个不同的字,其中 610 个只出现过 1 次。把「模型」简化成最极端的情况——模型就是上一代数据的字频,生成就是按字频抽样。一个只出现 1 次的字,在下一代 534,276 次抽样里一次都没被抽到的概率是 (1 − 1/534,276)534,276 = 0.3679,约等于 1/e;一旦某一代它的计数变成 0,之后的每一代它的概率都是 0,永远回不来 。

算法模拟器 · 在三国演义的真实字频上逐代自我采样(种子固定)
每代采样 每代混入真实数据

🎯

试三件事:① 默认设置下读统计条:第 1 代实际丢了多少个只出现 1 次的字,和公式期望的 224 个比一比;② 把代数拖到 30,看右图的尾巴一路往左缩,而最常见的那些字几乎不动——崩溃先发生在尾部;③ 点「每代混入真实数据 50%」,红线和绿线分开:只要真实数据一直在,尾巴就保得住。

改进:改写真实文本,与真实数据混合

崩溃的根源是用生成数据替代真实数据。现代做法反过来:让模型改写或扩写真实文本,再和真实数据混在一起。

来源占训练 token唯一 token走几遍
| 网页 | 15% | 1.3T | 1.2 | | 网页改写 | 15% | 290B | 5.2 | | 合成数据 | 40% | 290B | 13.8 | | 代码 | 20% | 820B | 2.4 | | 定向采购的来源 | 10% | 580B | 1.7 |

合成数据占 40%,但它的唯一 token 只有 290B,被重复了 13.8 遍——远超第一节说的「4 遍」。这说明「4 遍」是在 Muennighoff 的数据与模型上拟合出的经验结论,不是物理定律;Phi-4 认为高质量合成数据经得起多遍重复,这是它们的实验选择,不是共识。

预训练数据的演进:每一代都被上一代的某个真数字逼出来
  1. 起点 有多少用多少:原始网页直接进训练 Common Crawl 原始快照
    解决了量几乎无限:Common Crawl 定期抓取全网,FineWeb 用了 96 个快照。
    卡在WET 纯文本里样板和菜单太多(FineWeb §3.2);我们的原始文件不还原硬换行就跑 C4 句末规则,整本书只剩 17.02% 的字。
  2. 第一代 让人当过滤器:只取被点过赞的链接 GPT-2 WebText,2019
    解决了Reddit 上至少 3 karma 的外链,4,500 万个链接,清洗后约 800 万文档、40 GB。
    卡在量太小:C6 算出的需求是十几 T token;而且只覆盖被分享过的那一小部分网页。
  3. 第二代 只看长相的规则过滤 C4 2019 · Gopher 2021
    解决了句末标点、词数、平均词长、停用词、重复行……便宜,能在全网快照上跑。
    卡在绑语言、绑求值单位:英文原版在整本《三國志演義》3,697 段上通过 0 段;C4 句末标点规则删掉约 30% 的 token,FineWeb 最后没用它。
  4. 第二代 近重复去重:MinHash + 分桶 Broder 1997 → Lee 2021 → FineWeb 2024
    解决了C4 里一句话重复 61,036 次;去重后模型复述训练文本的频率降到 1/10。MinHash 把两两比较变成查桶。
    卡在去得越狠未必越好:跨 96 个快照全局去重只剩 4T,训不出更好的模型;每快照独立去重留 20T,才追平 RefinedWeb。
  5. 第三代 让模型给数据打分 CCNet 2019 · GPT-3 2020 → FineWeb-Edu、DCLM 2024
    解决了判断「有没有营养」:FineWeb-Edu 让 Llama-3-70B 标 46 万页、蒸馏成分类器,MMLU 33% → 37%。
    卡在参考语料的困惑度偏向「像参考」:我们模型写的胡话困惑度 93.417,低于真原文 273.209;阈值 3 删掉 92%,长程训练不够用。
  6. 第四代 配比:从手工权重到代理模型搜索 The Pile 2020 → DoReMi 2023
    解决了DoReMi 用 280M 代理模型搜域权重,8B 模型下游平均 +6.5 个点,达到基线快 2.6 倍。
    卡在权重一变就要重复:按 DoReMi 的权重花完 The Pile 的有效体量,YouTube 字幕要走约 16.9 遍(按字节近似 token,只看量级)。
  7. 第五代 数据墙:重复与合成 Muennighoff 2023 · WRAP 2024 · Phi-4 2024 你在这里
    解决了重复 4 遍以内几乎等于新数据;改写真实网页(WRAP)预训练约快 3 倍;Phi-4 约 10T token 里合成占 40%。
    卡在让模型只吃自己生成的数据,分布的尾巴一代代消失:在三国演义真实字频上重采样,只出现 1 次的字每一代有约 36.8% 的概率丢掉,丢了就回不来。
  8. 第六代 按时机投放:退火 → mid-training MiniCPM、Llama 3 2024 → OLMo 2、Qwen3、GLM-5
    解决了最好的数据放到学习率衰减段(C5 的 WSD)加量;再发展成独立阶段,顺便拉长上下文。
    卡在同名不同方:Qwen3 的高质量阶段占 13.9%,Llama 3 的退火只占 2.6e-6;收益与学习率调度缠在一起,很难单独归因。
数字口径:我们语料上的数字由 gen_c07_corpus.py 在《三國志演義》上实算(c07-*.json);FineWeb、GPT-2 数字出自本地 PDF;DoReMi、Muennighoff、WRAP、Phi-4、Qwen3、Llama 3 出自原文(核实记录见设计卡);「约 16.9 遍」「36.8%」「13.9%」在构建时现算。
⚠

常见误解一:「重复数据一定有害。」4 个 epoch 以内,重复和新数据几乎一样好(Muennighoff 2023);有害的是无节制地重复:我们的项目在约 5 遍之后 val loss 开始回升,训到 24.5 遍时升到 6.906。第 2 课删的是「网页上无意的上万次重复」,不是「有意多喂几遍好数据」。

常见误解二:「合成数据会导致模型崩溃,所以不能用。」崩溃来自「用生成数据替代真实数据、一代代递归」。混入真实数据、改写真实文本、由更强的模型生成给更弱的模型用,都不在那个设定里;Phi-4 与 Nemotron-CC 都靠合成数据取得了收益。

常见误解三:「合成数据能带来新知识。」改写只换说法,事实还是原文里的;凭空生成的数据最多包含生成模型已有的知识,还会带上它的错误。合成数据扩充的是表达与练习,不是知识的边界。

🔍 人类写的文本到底还够用多久?

Epoch AI 在 2024 年的报告《Will we run out of data?》估算了人类公开文本的存量,以及按当时的训练规模增长趋势,什么时候会被用完;它也讨论了重复、合成与多模态数据能把这堵墙推后多少。报告的具体年份区间依赖于它的假设,这里不转述数字,读原文时注意它给的是区间而不是一个点。epoch.ai/publications/will-we-run-out-of-data-limits-of-llm-scaling-based-on-human-generated-data(2024-06-06,需联网)。

证据三问

问本课的回答
① 它解决什么问题?高质量数据不够训练预算时,用重复、改写与合成把训练 token 补上
② 数学上为什么可能有效 / 失效?重复的收益递减没有证明,是拟合;纯自我采样丢失尾部可以严格说明(计数为 0 是吸收态)
③ 实验上为什么选了它?重复:Muennighoff 的数百个模型;改写:WRAP 快约 3 倍;合成:Phi-4、Nemotron-CC 的消融

一句话

📌

数据墙前面有两条路:把真数据多喂几遍(约 4 遍以内几乎不亏),或让模型改写真数据来扩充;纯靠模型生成再喂自己,分布的尾巴会一代代消失。

🚦

先停在这里:记住三个数——4 遍、上限约 16 份新数据、只出现一次的字每代丢约 37%。
再深一层:在崩溃模拟里把每代样本量改成「1 万字」,看尾巴消失得有多快;想一想:为什么小样本的递归训练更危险?

下一个缺口

数据够了,最好的那部分什么时候喂? → 第 6 课:最好的数据什么时候喂?

先记下本课右图里那个没解释完的现象:同样的数据,400 步的基线在 6.5 遍时比 1,500 步的 run 在 4.9 遍时还好。区别在学习率——第 6 课兑现。

你可能会问