CS336 Lecture Notes 7
本文为本人学习相关开源课程过程中,整理的个人学习笔记及作业解答,核心目的仅用于记录个人学习轨迹、巩固所学知识、梳理学习思路,全程为个人自主学习使用,不具备任何商业用途,也不构成任何形式的课程辅导或标准答案参考。
需特别说明的是,由于本人学习进度及知识储备有限,笔记内容及作业解答中可能存在大量纰漏、思路偏差甚至错误,仅代表本人当时的学习理解,不具备权威性和准确性。
在此郑重提醒:请勿将本文中的任何作业解答复制粘贴,作为自身所修课程的提交答案。任何因抄袭本文内容导致的课程成绩问题、学术诚信问题,均由抄袭者自行承担全部责任,本人不承担任何相关连带责任。
同时,本文所分享的内容均基于开源课程的公开内容整理,尊重原课程创作者的知识产权,若涉及相关内容的版权问题,请及时联系本人,本人将第一时间进行调整或删除。
感谢各位读者的理解与支持,也欢迎大家针对笔记及解答中的问题提出宝贵建议,共同交流学习、共同进步。
- 课程网站: https://cs336.stanford.edu/
- Lec0_ 资料: lecture_0x.py
- Lec0_ 资料: lecture_0x.pdf
Data (Part I)
引言:数据的重要性
核心观点:数据是训练语言模型最关键的要素。
开放权重模型(如 Llama 3)对架构和训练流程完全透明,但几乎不披露任何数据信息。原因包括:(i) 竞争动态 (ii) 版权责任风险。
训练阶段划分:
- 预训练 (Pre-training):在原始文本上训练(如网络文档)
- 中期训练 (Mid-training):在高质量数据上继续训练以增强能力
- 后训练 (Post-training):在指令跟随数据上微调(或强化学习)
基本思路是从「大量低质量数据」过渡到「少量高质量数据」。
数据对象类型
- 在线服务:如 Reddit
- 原始快照:通过爬取、API 或数据转存获取
- 处理后的文本:经过过滤和转换
- 聚合数据集:如 Dolma、The Pile
早期预训练数据集
BERT (2019)
- BooksCorpus:来自 Smashwords 的自出版免费电子书(7K本书,已被下架)
- Wikipedia:免费在线百科全书(62M文章,329种语言)
- 重要特点:序列是文档而非句子
GPT-2 WebText (2019)
- 收集 Reddit 上 karma ≥ 3 的帖子外链页面
- 8M页面,40GB文本
- OpenWebTextCorpus 是其开源复现版本
Common Crawl
非营利组织,2007年成立,每月执行网络爬取。
- 截至2025年已有约100次爬取(2008-2025)
- 格式:WARC(原始HTTP响应)和 WET(转换为文本)
- HTML转文本工具:trafilatura、resiliparse(转换质量影响下游任务性能)
基于规则的过滤方法
CCNet (2019)
目标:自动构建高质量预训练数据集,特别关注低资源语言。 组件:
- 埻重:基于轻量标准化移除重复段落
- 语言识别:fastText 分类器保留目标语言
- 质量过滤:KenLM 5-gram 模型筛选 Wikipedia 风格文档
T5 C4 (2019)
Colossal Clean Crawled Corpus,从 Common Crawl(1.4T tokens)出发:
- 保留以标点结尾且 ≥5 词的行
- 移除 <3 句子的页面
- 移除含「脏词」、代码(
{)、lorem ipsum、terms of use 的页面 - 仅保留英文(langdetect 概率 0.99)
- 最终:806GB(156B tokens)
GPT-3 数据集 (2020)
- 处理后的 Common Crawl + WebText2 + Books1/Books2 + Wikipedia
- 共 570GB(400B tokens)
- Common Crawl 处理:训练质量分类器(以 WebText/Wikipedia/Books 为正例),埚模糊去重
The Pile (2021)
应对 GPT-3 的开源努力,22个高质量领域:
- 825GB(~275B tokens)
- 包含:Pile-CC、PubMed Central、arXiv、Enron邮件、Project Gutenberg、Books3、StackExchange、GitHub 等
重要子集:
- Project Gutenberg:1971年启动,75K公有领域书籍
- Books3:196K书籍(来自 Bibliotik 影子图书馆,已因版权被下架)
- StackExchange:Q&A 格式接近指令微调需求
- The Stack:137M GitHub 仓库,保留宽松许可(MIT/Apache),去重后 3.1TB
MassiveText / Gopher (2021)
组件:MassiveWeb + C4 + Books + News + GitHub + Wikipedia
- MassiveWeb 过滤:英文保留、去重、质量规则(如80%词含字母)、Google SafeSearch 过滤毒性
- 结果:10.5TB(但 Gopher 仅用 300B tokens)
LLaMA 数据集 (2022)
- Common Crawl(CCNet处理,按 Wikipedia 引用分类)
- C4(多样性)
- GitHub(宽松许可 + 规则过滤)
- Wikipedia(20种语言)
- Project Gutenberg + Books3
- arXiv(移除注释、展开宏)
- Stack Exchange(按分数排序答案)
- 共 1.2T tokens
- 复现版本:RedPajama v1、SlimPajama(627B tokens)
RefinedWeb (2023)
观点:Web 数据足矣。
- trafilatura 提取 HTML 内容(用 WARC而非 WET)
- Gopher 规则过滤,避免 ML 过滤以防偏差
- MinHash 5-gram 模糊去重
- 发布 600B(共5T)tokens
FineWeb:改进版,95个 Common Crawl dumps,15T tokens,包含 PII 匿名化
Dolma (2024)
- Reddit(Pushshift 项目)
- PeS2o(40M 学术论文)
- C4、Project Gutenberg、Wikipedia
- Common Crawl 处理:语言识别 + Gopher/C4 规则 + 毒性过滤 + Bloom filter 埻重
- 共 3T tokens
DCLM (2024)
目标:定义标准数据集以评估数据处理算法。
- DCLM-pool:240T tokens
- DCLM-baseline:使用质量分类器过滤至 3.8T tokens
- 分类器正例:OpenHermes-2.5(GPT-4 生成)、ELI5(Reddit问答)
- 分类器负例:RefinedWeb
- 该质量分类器优于其他过滤方法
Nemotron-CC (2024)
问题:FineWebEdu 和 DCLM 过滤太激进(移除90%数据)
- 使用 jusText(而非 trafilatura)提取更多 tokens
- 分类器集成:教育价值评分 + DCLM 分类器
- 合成数据重述:高质量数据重述低质量数据,低质量数据生成问答任务
- 结果:6.3T tokens(高质量子集 1.1T)
版权问题
版权法基础:
- 目标:激励智力产品创作
- 1709年英国《安妮法令》起源
- 美国版权法(1976):保护「固定在任何有形媒介上的原创作品」
- 保护表达而非思想(如快速排序算法不受版权保护)
- 有效期75年后进入公有领域
使用版权作品的方式:
- 获取许可证
- 依赖合理使用条款
许可证:
- Creative Commons:免费分发版权作品(Wikipedia、Khan Academy 等)
- 模型开发者与数据平台签约:Google-Reddit、OpenAI-Shutterstock、OpenAI-StackExchange
合理使用(Section 107)四要素:
- 使用目的和性质(教育优于商业,转换性优于复制性)
- 版权作品性质(事实优于虚构)
- 使用部分的量和实质性
- 对原作品市场的影响
影子图书馆:LibGen、Sci-Hub、Z-Library 等,忽视版权和付费墙。
- Meta 曾在 LibGen 上训练模型(引发诉讼)
总结要点
- 关键教训:数据不会从天上掉下来,需要努力获取
- 数据管道:在线服务 → 原始数据 → 处理数据(转换、过滤、去重)
- 数据是区分语言模型的关键因素
- 存在法律和伦理问题(版权、隐私)
- 大部分管道是启发式的,有大量改进机会
Data (Part II)
本节深入探讨数据处理的具体机制:过滤算法、过滤应用和去重技术。
过滤算法
核心问题:给定目标数据 T 和大量原始数据 R,找到 R 中与 T 相似的子集 T’。
算法设计要求:
- 从目标数据泛化(希望 T 和 T’ 有差异)
- 极高效率(需要在海量 R 上运行)
KenLM:N-gram 语言模型
Kneser-Ney 平滑的 N-gram 模型,KenLM 是快速实现,源自机器翻译领域。
最大似然估计:
问题:N-gram 稀疏(大量组合计数为0) 解决:Kneser-Ney 平滑,利用低阶 N-gram 信息。
使用方式:
- 计算文档的 log p(content)
- 用困惑度(perplexity)标准化,避免偏向短文档
CCNet 应用:
- 按段落困惑度排序,保留前 1/3
- 用于 LLaMA 数据处理
fastText 分类器
fastText 设计目标:快速文本分类,性能接近神经网络但更高效。
结构:
- 词袋嵌入(Bag of word embeddings): 参数
- 对词向量取平均,线性投影到类别
Bag of N-grams:
- 使用哈希技巧(hashing trick)处理无界 N-gram 数量
- 实际用约 10M bins
质量过滤场景下 (好/坏),fastText 即线性分类器。
DSIR:重要性重采样
Data Selection for Language Models via Importance Resampling。
思路:建模分布而非分类。
重要性采样原理:
- 目标分布 (希望从中采样)
- 提议分布 (已有样本)
- 权重 ,按权重重采样
DSIR 实现:
- 使用哈希 N-gram 建模分布
- 学习 unigram 概率模型
- score(x) =
结果:在 GLUE 基准上略优于 fastText 启发式分类。
算法对比总结
| 方法 | score(x) | 保留策略 |
|---|---|---|
| KenLM(生成模型) | score ≥ threshold | |
| fastText(判别分类) | score ≥ threshold | |
| DSIR(重要性重采样) | 按概率重采样 |
过滤应用
语言识别
为何不直接多语言?
- 数据:难以对任意语言做高质量筛选
- 计算:计算受限时,每种语言分到的算力更少
fastText 语言识别:
- 支持 176 种语言
- 训练数据:Wikipedia、Tatoeba、SETimes
- Dolma 使用:保留 p(English) ≥ 0.5 的页面
注意事项:
- 短序列困难
- 低资源语言困难
- 可能误滤方言(如英语方言)
- 相似语言难分(Malay/Indonesian)
- 代码切换(Code-switching)难以定义
OpenMathText 案例:
- 规则过滤 + KenLM(ProofPile 训练,困惑度 < 15000)+ fastText 数学分类
- 产出 14.7B tokens,1.4B 模型优于用 20x 数据训练的模型
质量过滤
基于规则(不使用模型):C4、Gopher、RefinedWeb、FineWeb、Dolma 基于模型(成为主流):GPT-3、LLaMA、DCLM
GPT-3:
- 正例:Wikipedia、WebText2、Books
- 负例:Common Crawl
- 线性分类器 + Pareto 分布随机保留
LLaMA/RedPajama:
- 正例:被 Wikipedia 引用的页面
- 负例:Common Crawl
- 直接保留分类为正的文档
phi-1:
- 哲学:高质量数据(教科书)训练小模型
- 用 GPT-4 评估教育价值,训练随机森林分类器
- HumanEval:1.3B 模型用筛选数据 36K 步达到 17.68%,优于原始数据 96K 步的 12.19%
毒性过滤
Jigsaw Toxic Comments 数据集:
- Wikipedia 讨论页评论
- 标签:toxic、severe_toxic、obscene、threat、insult、identity_hate
Dolma 实现:
- 训练两个 fastText 分类器:
- hate:正例 = {unlabeled, obscene}
- NSFW:正例 = {obscene}
去重(Deduplication)
去重的必要性
重复类型:
- 精确重复:镜像站点、GitHub forks
- 近似重复:许可证文本、模板生成内容、格式差异
C4 案例:某产品描述重复 61,036 次
去重收益:
- 训练效率更高(更少 tokens)
- 避免记忆化(缓解版权、隐私问题)
设计空间
- 粒度:句子、段落、文档
- 匹配方式:精确匹配、子项存在、子项比例
- 操作:全部删除、保留一个
核心挑战:需要线性时间算法(避免 pairwise 比较)
哈希函数
- 映射 item 到 hash value(远小于 item)
- SHA-256:抗碰撞,慢(加密用途)
- MurmurHash、CityHash:不抗碰撞,快(哈希表用途)
- 本文使用 MurmurHash (mmh3)
精确去重
简单方法:
- 计算 hash → 按 hash 分组 → 每组保留一个
- 可 MapReduce 并行化
C4:
- Item = 3-sentence spans
- 精确匹配去重
- 注意:中间删除 span 可能破坏文档连贯性
Bloom Filter
目标:高效的近似集合成员检测。
特点:
- 内存高效
- 可插入,不可删除
- 返回「否」则必定否
- 返回「是」则大概率是(小概率假阳性)
- 增加计算可指数级降低假阳性率
原理:
- 使用 k 个哈希函数,m 个 bins
- 插入时,所有哈希位置设为 1
- 查询时,所有哈希位置均为 1 则返回「是」
假阳性率分析:
最优 k 值:(此时 )
Dolma 应用:
- 设置假阳性率 1e-15
- Item = 段落
Jaccard 相似度与 MinHash
Jaccard 相似度:
定义:两文档 Jaccard ≥ threshold 为「近似重复」。
MinHash:
- 随机哈希函数 h
- 性质:
原理:哈希函数诱导 item 随机排列,取最小值(首个元素),碰撞概率即 Jaccard。
局部敏感哈希(LSH)
问题:单个 MinHash 碰撞概率 = Jaccard,过于随机。
目标:Jaccard > threshold 时碰撞,否则不碰撞。
方案:n 个哈希函数,分为 b 个 band,每个 band r 个哈希函数。
碰撞条件:某个 band 内所有哈希函数都碰撞。
碰撞概率:
- 增大 r:threshold 更尖锐,曲线右移(更难匹配)
- 增大 b:曲线左移(更易匹配)
threshold 估算(phase transition 点):
示例设置:n=9000, b=20, r=450,threshold ≈ 0.8
总结要点
- 算法工具:N-gram 模型(KenLM)、分类器(fastText)、重要性重采样(DSIR)
- 应用场景:语言识别、质量过滤、毒性过滤
- 去重技术:哈希函数支持大规模模糊匹配(Bloom Filter、MinHash、LSH)
- 掌握了这些工具(机制),接下来需要花时间理解数据(直觉)
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!