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

实验课:把《三國志演義》当成一次网页快照,完整跑一遍数据管线

实验课:整条数据管线跑一遍
不讲新概念:把项目的原始文件从头到尾过一遍前六课的管线——去声明、拼段落、规则、去重、困惑度过滤、分词——每一级都看进来多少、出去多少、删掉的是谁;再把每个决策和它的实测数字记进项目的决策表。
🧪

这一课不讲新概念。前六课每一课都在同一份语料上多做了一步;这里把它们串起来,从项目的原始文件 pg23950.txt 一路走到训练用的 token。所有数字都来自 gen_c07_corpus.py 在整本书上的实算与项目的真实导出;每一级都能改一个决策,看后面怎么变。

从已有出发

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

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

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

项目真正做过的只有前三步:去掉声明与 CRLF、拼回段落、在训练集上训分词器。规则、去重、困惑度过滤这三步,项目没有施加——下面的漏斗是在回答:如果施加了,会发生什么。

整条管线

真数据 · 整本《三國志演義》逐级漏斗
规则:
    🎯

    试三件事:① 默认设置(中文改写 + 文言虚词、最少 50 字)下,读第 ④ 级保住的字数比例(88.0%),展开它删掉的回目、诗与那两处误植字母的段落;② 勾上「反例:先跑句末标点规则,再拼回段落」,漏斗在第 ③′ 级就只剩 17.02% 的字;再依次点「中文改写 + 现代虚词」「Gopher/C4 英文原版」,第 ④ 级分别剩 61.8% 和 0;③ 把困惑度阈值拖到 1,000,第 ⑥ 级删掉验证集 21 段——看被删的是诗,不是垃圾。

    读漏斗:三个观察

    1. 最大的一刀来自顺序,而不是规则。同一条句末标点规则,在还原段落之前跑,整本书只剩 17.02% 的字;之后跑,剩 94.27%。
    2. 精选语料不需要去重,但分词器要防模板。3,697 段里 Jaccard ≥ 0.75 的段落对为 0;可是章末套话「且看下文分解」已经成了分词器里最长的 token(第 2 课)。如果语料里混进每回一份的许可声明,1,791 次合并里 1,034 次会被它占掉。
    3. 过滤器删掉的往往是「不像大多数」的好内容。长度规则删回目和诗,困惑度过滤先删诗;网页上被这两类过滤器误伤的,就是那些格式特殊、用词少见的好页面。

    项目决策表(对应章首页的里程碑)

    把本章的每个决策和它的实测数字记下来。这张表的每个数字都能在上面的漏斗或前六课的组件里复现。

    决策我们的选择实测依据 → 验收
    1. 抽取还原与规则的顺序先去声明、拼段落,再跑任何逐行规则顺序反过来只剩 17.02% 的字 → 在清洗结果上跑句末标点规则,段落保留率 91.24% ≥ 90% ✓
    2. 规则集按字计长 + 中文句末 + 文言虚词;「不含 ASCII 字母」改成人工修字四条规则合用时,现代虚词表删 49.5% 的段,文言虚词表删 20.9% → 每条规则在整本书上的删除率都已算出;删除率 > 10% 的规则写明理由
    3. 去重的单位与参数段落;5 字 shingle;14 × 8Jaccard ≥ 0.75 的对:0;LSH 候选:0 → 报告最像的一对(J = 0.5833),LSH 与精确枚举一致 ✓
    4. 分词器训练语料干净的训练集,不带任何声明带 107 份声明时 1,034 / 1,791 次合并变成英文 → 干净条件的合并表与项目 tokenizer.json 逐条一致 ✓
    5. 同一份语料训几遍按 val loss 最低点定步数,同时控制学习率调度1,500 步 run 的最低点在第 300 步,之后 val 升到 6.906 → 指出最低点所在 epoch;与学习率调度解耦后再定(第 6 课)
    6. 要不要加现代白话 / 英文待实验— → 用 val_bpb 比较,并报告分词器压缩率变化(计划实验)
    📋

    还没做的实验(需要实验 agent 在 04-实践项目里增补):① 决策 6 的配比实验:加入不同比例的现代白话后,重训分词器与模型,比较 val_bpb;② 决策 5 的解耦实验:同样的 epoch 数、不同的学习率调度(cosine / WSD)各跑一次;③ 第 6 课的退火实验:WSD 衰减段上采样某个子集(例如验证集困惑度最低的那类段落),和不上采样对比。三组都只改一项,差值小于噪声底线(C14:同配置 5 次重跑极差 0.016,3σ ≈ 0.020)不下结论。

    🔍 为什么困惑度过滤只在验证集上做?

    第 3 课的语言模型是在训练集上统计的。拿它给训练集打分,每一段都「见过自己」,困惑度会系统性地偏低——相当于让考生自己批自己的卷子。所以漏斗的第 ⑥ 级只作用在模型没见过的验证集上。真实的数据管线里也有同样的问题:用来训练质量分类器的样本,不能和被打分的数据重叠,否则分数会虚高。

    带走

    下一章:数据和配方都齐了,模型放大以后,为什么训练会炸? → C8 稳定性