第 13 讲:Data Processing(上)
本讲是数据处理模块的第一部分,聚焦于 pre-training 数据的获取、清洗和过滤。对于大型语言模型来说,数据质量往往比模型架构更加重要 — "Garbage in, garbage out" 在 LLM 领域体现得尤为明显。
核心观点
Scaling Laws 告诉我们,模型性能同时取决于参数量和训练数据量。但更重要的是,数据的质量和多样性往往比单纯的数量更加关键。许多研究表明,用更少但更高质量的数据训练,效果反而优于使用海量低质量数据。
1. 预训练数据的重要性
大型语言模型的能力本质上来源于训练数据。模型在 pre-training 阶段通过 next token prediction 从海量文本中学习语言模式、世界知识和推理能力。因此,训练数据的选择和处理直接决定了模型的上限。
1.1 数据如何影响模型表现
数据对模型的影响体现在多个维度:
- 知识覆盖:模型只能"知道"训练数据中出现过的信息。如果训练集缺少某个领域的文本,模型在该领域的表现就会很差。
- 语言能力:语法、风格、多语言能力等都依赖于训练数据中相应文本的比例和质量。
- 偏见与毒性:训练数据中的偏见和有害内容会被模型学习和放大。
- 推理能力:高质量的数学、代码、科学文本有助于提升模型的推理能力。
1.2 经典案例:数据决定性能
多个研究证实了数据质量的重要性:
- LLaMA (Meta, 2023):使用精心策划的 1.4T token 数据集,13B 参数的 LLaMA 在多项 benchmark 上超越了 175B 参数的 GPT-3。这说明数据质量可以弥补参数量的不足。
- Phi-1 (Microsoft, 2023):使用高质量"教科书级"数据训练的 1.3B 参数模型,在代码生成任务上超越了许多大得多的模型。
- DCLM (DataComp for Language Models):一个专门研究数据对 LLM 性能影响的 benchmark,证实了数据筛选策略的巨大影响。
2. 数据来源概览
Pre-training 数据通常来自多个来源的混合。每种来源有其独特的特点和价值:
| 数据来源 | 规模 | 质量 | 特点 |
|---|---|---|---|
| Common Crawl | PB 级 | 参差不齐 | 网页爬取,覆盖面广,需大量清洗 |
| Wikipedia | ~20GB | 高 | 结构化百科知识,多语言 |
| GitHub | TB 级 | 中等 | 代码数据,提升推理和编程能力 |
| Books | ~100GB | 高 | 长文本,连贯叙事,丰富知识 |
| ArXiv | ~100GB | 高 | 学术论文,科学知识,LaTeX 格式 |
| StackExchange | ~50GB | 中高 | 问答格式,技术知识 |
2.1 Common Crawl
Common Crawl 是目前最大的公开可用网页数据集,由 Common Crawl 非营利组织维护。它定期爬取互联网上的网页,每月生成一个新的 "crawl",每个 crawl 包含数十亿个网页。
Common Crawl 的关键特点:
- 始于 2008 年,持续至今,累计数据量达 PB 级别
- 每个 crawl 包含 20-30 亿个网页
- 覆盖多种语言,但英语占比最大
- 数据存储在 Amazon S3 上,可免费访问
- 几乎所有开源 LLM 的预训练数据都以 Common Crawl 为基础
2.2 其他高质量来源
Wikipedia 提供了高质量的百科全书式知识。它的文本经过社区审核,事实准确性较高,覆盖面广泛。在 pre-training 数据中,Wikipedia 通常会被 upsampled(重复使用多次),因为其质量远高于一般网页文本。
GitHub 代码是提升模型编程和逻辑推理能力的关键数据源。研究表明,包含代码数据的模型不仅编程能力更强,在其他推理任务上也有提升("code helps reasoning")。
Books 提供了长距离依赖的训练信号,帮助模型学习长文本的连贯性和叙事结构。但 Books 数据也面临严重的版权争议。
ArXiv 论文包含大量科学知识和数学推导,是训练模型科学推理能力的重要来源。但需要处理 LaTeX 格式的转换问题。
3. Common Crawl 数据结构
理解 Common Crawl 的数据格式是处理网页数据的基础。Common Crawl 使用三种标准格式存储数据:
3.1 WARC (Web ARChive) 格式
WARC 是 Common Crawl 的原始数据格式,包含完整的 HTTP 请求和响应信息:
- HTTP Response Header:状态码、Content-Type、服务器信息等
- HTML 源码:完整的网页 HTML,包含所有标签、脚本和样式
- 元数据:抓取时间、URL、IP 地址等
WARC/1.0
WARC-Type: response
WARC-Date: 2024-01-15T10:23:47Z
WARC-Target-URI: https://example.com/article
Content-Type: application/http; msgtype=response
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
<!DOCTYPE html>
<html>
<head><title>Example Article</title></head>
<body>...</body>
</html>
3.2 WET (WARC Extracted Text) 格式
WET 文件是从 WARC 文件中提取的纯文本版本。Common Crawl 已经做了基本的 HTML 到文本的转换,但质量往往不够好:
- 包含从 HTML 中提取的纯文本
- 保留了基本的文本结构
- 但可能包含导航菜单、广告文本等噪声
- 文件大小约为 WARC 的 1/5 到 1/10
3.3 WAT (Web Archive Transformation) 格式
WAT 文件包含从 WARC 记录中提取的元数据信息(JSON 格式):
- HTTP 头信息
- HTML 中的链接信息
- 页面元数据(title, description 等)
- 对于过滤和分析非常有用,无需解析完整 HTML
实践建议
在实际的数据处理 pipeline 中,通常直接使用 WARC 文件而非 WET 文件,因为自定义的 HTML 到文本转换工具(如 trafilatura)效果远好于 Common Crawl 默认的提取。WAT 文件则用于预筛选,例如通过 URL pattern 过滤某些域名。
4. HTML 到文本的转换
从原始 HTML 中提取有意义的正文文本是数据处理 pipeline 的第一步,也是最关键的一步。这个任务看似简单,实际上充满挑战。
4.1 挑战
HTML 到文本转换面临的主要问题:
- Boilerplate 去除:网页中大量内容是导航栏、侧边栏、页脚、广告等非正文内容。正文可能只占页面 HTML 的很小一部分。
- 格式多样性:不同网站的 HTML 结构千差万别,没有统一标准。
- 动态内容:许多网页依赖 JavaScript 渲染内容,静态 HTML 中可能缺少关键信息。
- 多媒体处理:表格、列表、图片 alt text 等需要特殊处理。
4.2 Trafilatura
Trafilatura 是一个专门用于 web scraping 和文本提取的 Python 库,在 LLM 数据处理中广泛使用:
import trafilatura
# Download and extract text from a URL
downloaded = trafilatura.fetch_url("https://example.com/article")
text = trafilatura.extract(downloaded)
# Or extract from raw HTML
text = trafilatura.extract(html_content,
include_comments=False,
include_tables=True,
favor_precision=True) # Higher precision, possibly lower recall
Trafilatura 的优点:
- 使用多种启发式方法结合 DOM 结构分析来识别正文区域
- 内置 fallback 机制:如果主算法失败,会尝试其他提取策略
- 支持多种输出格式(纯文本、XML、JSON)
- 处理速度相对较快,适合大规模数据处理
4.3 Resiliparse
Resiliparse 是另一个常用的 HTML 文本提取工具,由 Chatnoir 团队开发,专门针对 Common Crawl 数据优化:
from resiliparse.extract.html2text import extract_plain_text
from resiliparse.parse.html import HTMLTree
tree = HTMLTree.parse(html_content)
text = extract_plain_text(tree,
main_content=True, # Only extract main content area
alt_texts=True, # Include image alt texts
preserve_formatting=True # Keep basic formatting
)
Resiliparse 的特点是速度极快(使用 C++ 实现),特别适合处理 Common Crawl 级别的数据量。在 DCLM 项目中,Resiliparse 被作为默认的文本提取工具。
4.4 提取质量对比
不同工具在 precision 和 recall 之间有不同的 trade-off:
- Trafilatura(favor_precision 模式):高 precision,可能遗漏一些正文段落
- Trafilatura(默认模式):在 precision 和 recall 之间取得较好平衡
- Resiliparse:速度最快,recall 较高,但可能引入少量噪声
- BeautifulSoup + 自定义规则:灵活但需要大量人工调优
5. 文本质量过滤
从 HTML 中提取出文本后,需要进行多层质量过滤。网页文本中包含大量低质量内容,如 spam、自动生成的文本、错误页面等。质量过滤的目标是保留有意义的、高质量的文本。
5.1 语言检测
第一步通常是语言检测,确保文本属于目标语言:
import fasttext
# FastText language identification model
model = fasttext.load_model("lid.176.bin")
def detect_language(text):
predictions = model.predict(text.replace("\n", " "), k=1)
lang = predictions[0][0].replace("__label__", "")
confidence = predictions[1][0]
return lang, confidence
# Filter: only keep English text with high confidence
lang, conf = detect_language(document_text)
if lang == "en" and conf > 0.65:
keep_document(document_text)
FastText 的语言检测模型(lid.176.bin)支持 176 种语言,速度极快且准确率很高。在实际处理中,通常设置一个置信度阈值(如 0.65),低于该阈值的文档被过滤掉。
5.2 Perplexity Filter
Perplexity filter 使用一个预训练的语言模型来评估文本的"正常程度"。其核心思想是:高质量的自然语言文本应该有相对较低的 perplexity(模型容易预测),而乱码、重复文本或非自然语言内容的 perplexity 会很高。
典型做法是使用一个在 Wikipedia 等高质量语料上训练的 KenLM n-gram 模型:
import kenlm
model = kenlm.Model("wikipedia_en.arpa")
def compute_perplexity(text):
# KenLM returns log probability
log_prob = model.score(text, bos=True, eos=True)
num_words = len(text.split())
perplexity = 10 ** (-log_prob / num_words)
return perplexity
# Filter: remove documents with very high or very low perplexity
ppl = compute_perplexity(document_text)
if 50 < ppl < 10000: # Typical range for quality text
keep_document(document_text)
注意:perplexity 过低也可能有问题 — 这通常表示文本是高度重复的模板化内容。
5.3 基于规则的过滤
除了统计方法,还有大量基于规则的启发式过滤器:
| 过滤规则 | 目的 | 典型阈值 |
|---|---|---|
| 文档最小长度 | 过滤过短的无意义文本 | >= 100 个 word |
| 平均句子长度 | 过滤非自然文本 | 5-100 个 word |
| 特殊字符比例 | 过滤乱码或代码垃圾 | < 20% |
| 重复行比例 | 过滤模板化内容 | < 30% |
| 停用词比例 | 确认是自然语言 | > 某个阈值 |
| 大写字母比例 | 过滤全大写或异常文本 | < 70% |
| URL/Email 密度 | 过滤 spam 内容 | < 某个比例 |
| "Lorem ipsum" 等标志词 | 过滤占位文本 | 出现即过滤 |
C4 数据集的过滤策略
Google 的 C4 (Colossal Clean Crawled Corpus) 使用了一套经典的过滤规则:删除包含 "bad words" 的页面、删除代码较多的页面(通过花括号 { 检测)、只保留以句号/问号/感叹号结尾的句子、删除少于 3 个句子的文档等。这些规则虽然简单,但效果显著。
6. 有害内容检测与过滤
互联网上充斥着大量有害内容,包括仇恨言论、暴力内容、色情内容、虚假信息等。如果这些内容被模型学习,会导致模型生成类似的有害输出。
6.1 基于词表的过滤
最基本的方法是使用 "blocklist"(黑名单词表)进行过滤:
- 维护一个包含有害词汇和短语的列表
- 如果文档中出现这些词汇,整个文档被移除或标记
- 优点:简单高效,容易实现
- 缺点:误杀率高(如医学文本中讨论性健康的内容可能被错误过滤),且无法捕捉上下文
6.2 基于分类器的过滤
更先进的方法是训练专门的文本分类器来检测有害内容:
- 使用标注数据训练 binary classifier(有害 vs 无害)
- 可以使用 FastText 训练轻量级分类器,适合大规模数据处理
- 也可以使用 BERT-based 模型获得更高准确率,但速度较慢
- Jigsaw Toxic Comment Classification 数据集是常用的训练数据来源
6.3 URL-based 过滤
除了内容层面的过滤,还可以在 URL 层面进行过滤:
- 维护已知有害网站的域名 blocklist(如 UT1 Blocklist)
- 根据 URL pattern 过滤特定类型的页面
- 这种方法速度极快,可以在下载数据之前就进行过滤
7. PII (Personally Identifiable Information) 移除
Pre-training 数据中可能包含个人身份信息(PII),如姓名、电话号码、邮箱地址、身份证号、信用卡号等。将这些信息保留在训练数据中会导致模型记忆并可能在推理时泄露这些隐私信息。
7.1 常见的 PII 类型
- Email 地址:使用正则表达式检测(准确率很高)
- 电话号码:各国格式不同,检测难度较大
- IP 地址:IPv4 和 IPv6 格式
- 物理地址:检测难度很高,容易误判
- 身份证号 / SSN:格式相对固定,但数字串容易与其他数据混淆
- 信用卡号:可以通过 Luhn 算法验证
7.2 PII 处理方法
import re
# Simple regex-based PII detection
EMAIL_PATTERN = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
PHONE_PATTERN = r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b'
IP_PATTERN = r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b'
def remove_pii(text):
text = re.sub(EMAIL_PATTERN, '{{EMAIL}}', text)
text = re.sub(PHONE_PATTERN, '{{PHONE}}', text)
text = re.sub(IP_PATTERN, '{{IP}}', text)
return text
更先进的方法使用 NER (Named Entity Recognition) 模型来检测人名、地址等难以用正则表达式捕捉的 PII。例如 Microsoft 的 Presidio 工具就提供了一套完整的 PII 检测和匿名化框架。
实际权衡
PII 移除存在 precision vs recall 的 trade-off。过于激进的移除会破坏文本的自然性(如将所有数字串都替换),而过于保守则可能遗漏真正的隐私信息。在实践中,通常采用分层策略:先用高 precision 的正则表达式处理明确的 PII 类型(如 email),再用 NER 模型处理较模糊的类型(如人名),并设置较高的置信度阈值。
8. 版权与法律考量
使用网页数据训练 LLM 涉及复杂的法律问题,这也是当前 AI 行业面临的最重要挑战之一。
8.1 版权争议的核心问题
- Fair Use 辩论:训练 AI 模型是否属于 "fair use"(合理使用)?这在美国法律中尚无明确判例。Transformative use 原则可能适用,但争议很大。
- Opt-out 机制:robots.txt 是否具有法律约束力?网站通过 robots.txt 明确拒绝爬取,但这在技术上很容易绕过。
- 记忆与再现:如果模型能逐字再现训练数据中的版权内容,这是否构成侵权?研究表明,大型模型确实会"记忆"训练数据的片段。
8.2 当前的法律诉讼
多起针对 AI 公司的版权诉讼正在进行中:
- New York Times vs OpenAI / Microsoft
- 作家群体(Authors Guild)vs OpenAI
- Getty Images vs Stability AI
- 多位音乐人 vs AI 音乐生成服务
8.3 应对策略
在数据处理 pipeline 中,常见的应对策略包括:
- 尊重 robots.txt:虽然法律效力不确定,但这是基本的道德底线
- Opt-out 支持:提供机制让内容创作者移除其数据
- 版权内容过滤:尽量识别和移除明确受版权保护的内容(如完整的书籍、文章)
- 来源追溯:记录每条训练数据的来源,便于后续审计和移除
- 使用开放许可数据:优先使用 Creative Commons、Public Domain 等开放许可的数据
重要提醒
版权法在全球各地不同,且 AI 相关的法律还在快速演变中。作为研究者和工程师,了解这些法律问题非常重要。在构建数据处理 pipeline 时,应该内建足够的 traceability(可追溯性)和 opt-out 机制。
本讲小结
本讲介绍了 LLM pre-training 数据处理的前半部分,核心内容包括:
- 数据重要性:数据质量往往比模型架构更重要,"数据决定模型的上限"
- 数据来源:Common Crawl 是最主要的来源,辅以 Wikipedia、GitHub、Books 等高质量数据
- Common Crawl 格式:WARC(原始 HTML)、WET(提取文本)、WAT(元数据),实践中通常直接处理 WARC
- HTML 到文本转换:trafilatura 和 resiliparse 是两个主流工具
- 质量过滤:语言检测、perplexity filter、基于规则的过滤形成多层防线
- 安全与合规:有害内容过滤、PII 移除和版权考量是不可忽视的环节
下一讲将继续数据处理的下半部分,重点讨论 deduplication(去重)和数据混合策略。