Skip to content

4.4 数据工程全流程

大语言模型的能力上限,在很大程度上由训练数据的质量决定。业界的一句经验总结——"Garbage in, garbage out"——在大模型时代尤其深刻。人们常说模型"在整个互联网上训练",但这是一个巨大的误解:原始互联网数据充斥着噪声、垃圾信息、重复内容和有害文本,直接用于训练不仅效率低下,还会严重损害模型性能。从数 PB 的原始网页中提炼出几百 GB 到几 TB 的高质量文本,需要一条精心设计的数据工程流水线。本节将完整介绍这一流程的五个核心阶段:数据来源、数据清洗、数据去重、质量分类,以及面向后训练阶段的数据准备。

4.4.1 数据来源

构建预训练语料库的第一步是从多元化的来源收集原始数据。来源的多样性直接决定模型能力的覆盖面——训练数据中包含代码,模型才能生成代码;包含多语言文本,模型才具备多语言能力。主流的数据来源可分为三大类。

网络爬取数据。 Common Crawl 是最核心的来源。这一非营利组织每月或每两月发布一次互联网快照,每次包含数十亿网页、压缩后达数百 TB,以 WARC(Web ARChive)格式存储完整的 HTTP 事务。Common Crawl 的优势在于覆盖面极广,包含多种语言、领域和文体;缺点是原始数据质量极差,混杂着 HTML 标签、JavaScript 代码、导航栏、广告、垃圾邮件和有害内容。因此 Common Crawl 是"原矿"而非"成品",必须经过后续的提纯流程。FineWeb、RefinedWeb 和 C4 等知名数据集,本质上都是从 Common Crawl 中经过不同清洗策略提炼而来的。

百科与知识库。 Wikipedia 是质量最高的公开文本来源之一。其内容经过社区审核,覆盖数百种语言,结构清晰且事实密度高。在实践中,Wikipedia 通常被作为质量分类器训练的正样本来源——以 Wikipedia 文章代表"高质量文本",以 Common Crawl 随机样本代表"低质量文本",从而训练出能区分文本质量的分类器。

书籍与学术语料。 书籍(如 Project Gutenberg、Books3)提供长文本和连贯的叙事结构,有助于模型学习长距离依赖和复杂推理。学术论文(如 arXiv、PubMed Central)和代码(如 GitHub 的 The Stack)则为模型提供专业领域的知识和严谨的逻辑表达能力。

在实际训练中,不同来源的数据按照精心设计的比例混合。高质量来源(如 Wikipedia、书籍)通常被过采样(在训练中出现多次),而低质量来源(如过滤后的 Common Crawl)则被欠采样。这一混合比例是影响模型最终能力的重要超参数。

数据清洗流水线示意图:从原始网页到高质量文本的多阶段过滤

图 4-13:数据清洗流水线。原始网页数据经过文本提取、隐私过滤、NSFW 检测和语言识别等多阶段处理,最终得到可用于训练的高质量文本。

4.4.2 数据清洗

原始数据的格式和内容复杂多样,数据清洗的目标是将其转化为干净的纯文本。这一阶段包含四个核心步骤。

文本提取。 原始网页以 HTML 格式存储,包含大量与正文无关的标签、脚本和样式信息。文本提取的任务是从 HTML 中精确剥离出正文内容,去除导航栏、页脚、广告等"样板文件"(boilerplate)。常用的工具包括 trafilatura 和 Resiliparse。以 Resiliparse 为例,它先检测字符编码,再调用 extract_plain_text 函数从 HTML 中提取纯文本。对于 PDF 和 LaTeX 等其他格式,则使用对应的解析工具(如 GROBID、Pandoc)进行转换。

隐私信息过滤。 互联网文本中包含大量个人隐私信息(PII),如电子邮箱地址、电话号码和 IP 地址。这些信息不仅存在法律风险,还可能导致模型在推理时泄露隐私。过滤的标准做法是使用正则表达式进行模式匹配,将检测到的隐私信息替换为占位符(如 |||EMAIL_ADDRESS|||)。例如,电子邮箱可通过模式 [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} 匹配;IP 地址可通过匹配四组 0-255 的数字来识别。

NSFW 与有毒内容检测。 色情、暴力、仇恨言论等有害内容需要在训练数据中被识别并过滤。实践中通常使用基于 fastText 的轻量级分类器完成这一任务:加载预训练的 NSFW 检测模型或仇恨言论检测模型,对每段文本给出分类标签和置信度分数,超过阈值的文本将被移除。fastText 的优势在于推理速度极快,能够高效处理数十亿级别的文档。

语言识别。 语言模型通常需要特定语言的训练数据,因此需要对文档进行语言识别并筛选目标语言。fastText 的 lid.176.bin 模型支持 176 种语言的识别,输入文本后返回语言代码和置信度。在处理时需注意将文本中的换行符替换为空格,因为 fastText 一次只能处理单行输入。

4.4.3 数据去重

大规模语料库中存在着大量重复内容,这些冗余会导致模型对特定样本过拟合,损害泛化能力。研究表明,去重是提升模型性能最有效的单一数据处理步骤之一。去重分为精确去重和模糊去重两个层次。

精确去重(Hash-based Exact Deduplication)。 最直接的方法是对每行或每个文档计算哈希值,哈希值完全相同则判定为重复。实现上,先遍历所有文档统计每行出现的次数,再保留仅出现一次的行。精确去重计算开销小,适合作为流水线的第一步快速去除完全相同的副本。但它无法处理"几乎相同但有微小差异"的文档——例如仅在页眉页脚上不同的同一篇文章。

模糊去重(MinHash + LSH)。 模糊去重旨在识别内容高度相似但不完全相同的文档对。其核心思想是:先为每个文档计算一个紧凑的"签名"来近似其内容,再通过局部敏感哈希(LSH)快速找到可能相似的候选对,最后对候选对进行精确验证。整个算法分为以下几个阶段。

阶段一:文本预处理与 Shingling。 对原始文本进行标准化(小写化、删除标点、规范空白、去除重音、NFD Unicode 规范化),然后提取字符级 n-gram(称为 shingle)。例如,对文本 "hello world" 取 n=3 的 shingle 得到集合 {"hel", "ell", "llo", "lo ", "o w", " wo", "wor", "orl", "rld"}。每个文档由此被表示为一个 shingle 集合。

阶段二:MinHash 签名生成。 MinHash 的目标是将每个文档的 shingle 集合压缩为一个固定长度的签名向量,使得签名之间的匹配率近似于原始集合之间的 Jaccard 相似度。算法如下:

算法:MinHash 签名生成
输入:文档集合 D = {d_1, ..., d_n},每个文档对应 shingle 集合 S_i
      K 个独立哈希函数 h_1, h_2, ..., h_K
输出:签名矩阵 SIG,其中 SIG[i][k] 为文档 d_i 在第 k 个哈希函数下的最小哈希值

1. 初始化:对所有文档 d_i 和所有哈希函数 h_k,
   令 SIG[i][k] = +∞
2. 对于全局 shingle 集合中的每一个 shingle s:
     计算 K 个哈希值:v_k = h_k(s),k = 1, ..., K
     对于每个文档 d_i:
       如果 s ∈ S_i:
         对于 k = 1, ..., K:
           SIG[i][k] = min(SIG[i][k], v_k)
3. 返回 SIG

签名生成完成后,两个文档之间的 Jaccard 相似度可通过签名匹配率来估计:J^(A,B)=|{k:SIG[A][k]=SIG[B][k]}|KK 越大,估计越精确,但计算和存储开销也越大。

阶段三:局部敏感哈希(LSH)分桶。 直接比较所有文档对的签名的时间复杂度为 O(n2),在数十亿文档的场景下不可行。LSH 通过一种巧妙的分段策略将复杂度降至近似线性。具体做法是将长度为 K 的签名向量切分为 b 个"带"(band),每个带包含 r=K/b 个哈希值。对每个带,将其内容作为 key 映射到桶中。只要两个文档在任意一个带上落入同一个桶,就将它们标记为候选对。

算法:LSH 分桶
输入:签名矩阵 SIG,带数 b,每带行数 r = K / b
输出:候选相似文档对集合 C

1. 初始化 C = ∅
2. 对于每个带 j = 1, ..., b:
     初始化空桶表 buckets = {}
     对于每个文档 d_i:
       提取签名片段 band_j(i) = SIG[i][(j-1)*r+1 : j*r]
       将 band_j(i) 作为 key,将 d_i 加入 buckets[key]
     对于 buckets 中每个包含 ≥ 2 个文档的桶:
       将桶内所有文档对加入 C
3. 返回 C

LSH 的核心参数 br 控制着相似度检测的灵敏度。两个 Jaccard 相似度为 J 的文档成为候选对的概率为 P=1(1Jr)b。通过调节 br,可以在召回率和误报率之间取得平衡。

阶段四:候选验证与集群合并。 对 LSH 产生的每个候选对,从签名矩阵中计算估计的 Jaccard 相似度,超过阈值(如 0.8)的判定为真正重复。所有重复对构成一个图,通过连通分量分析将重复文档聚类,每个集群只保留一个代表文档(通常按字典序选取第一个),其余删除。

4.4.4 质量分类

数据质量分级过滤

图 4-14:数据质量分级过滤流程。启发式规则过滤低质量文档后,基于模型的质量分类器进一步区分文档等级。

经过清洗和去重后的数据仍然良莠不齐,需要进一步区分文档的质量等级。质量分类通常采用两层策略:基于规则的启发式过滤和基于模型的质量评分。

启发式质量规则(Gopher Rules)。 DeepMind 在构建 Gopher 模型的训练数据时提出了一组广泛采用的启发式过滤规则,主要检查以下维度:

规则阈值过滤目标
文档词数50-100,000过短(无信息量)或过长(异常文档)
平均词长3-10 个字符乱码或非自然语言文本
省略号结尾行占比< 30%SEO 垃圾和列表型低质量页面
含字母单词占比> 80%数据表格、编码序列等非文本内容

表 4-4:Gopher 启发式质量规则的核心指标及其过滤目标。

这些规则计算开销极低,适合在流水线早期阶段快速过滤掉明显的低质量文档。

KenLM 困惑度评分。 KenLM 是一个高效的 n-gram 语言模型工具。其核心思想是:在高质量语料(如 Wikipedia)上训练一个语言模型,然后用该模型计算待评估文档的困惑度(perplexity)。困惑度越低,说明文档的语言风格越接近高质量参考语料;困惑度异常高则意味着文本包含乱码、非自然语言或低质量内容。CCNet 流水线即采用 KenLM 困惑度将文档分为高、中、低三个质量档次,只保留困惑度处于合理区间的文档。

fastText 质量分类器。 相比于 KenLM 仅能给出困惑度评分,fastText 分类器能直接输出"高质量"或"低质量"的二分类判断。训练流程如下:

  1. 正样本构建:从 Wikipedia 提取文章文本,经隐私脱敏和 Gopher 规则过滤后,标记为 __label__hq
  2. 负样本构建:从 Common Crawl 的 WARC 文件中随机抽取网页,经文本提取和隐私脱敏(但不做质量过滤)后,标记为 __label__lq
  3. 模型训练:将正负样本合并、打乱,按 9:1 划分训练集和验证集,使用 fastText 的 train_supervised 接口训练分类器(典型参数:学习率 0.1、25 轮迭代、bi-gram 特征、100 维词向量)。
  4. 推理应用:对待评估文档调用分类器,根据返回的标签和置信度决定保留或丢弃。

fastText 分类器的推理速度可达每秒数十万条文档,是大规模数据处理中质量过滤的主力工具。

4.4.5 后训练数据准备

预训练数据解决的是"模型见过什么"的问题,而后训练(post-training)数据则决定"模型如何响应用户"。后训练阶段的数据工程同样需要精心设计。

指令数据合成。 高质量的人工标注指令数据成本高昂且难以规模化。一种高效的替代方案是利用已有的强模型(如 GPT-4)来生成指令-响应对。典型做法包括:Self-Instruct 方法从少量种子指令出发,让模型自动生成新指令和对应的回答;Evol-Instruct 则通过对已有指令进行"进化"(增加约束、提升复杂度、改变视角)来扩充数据多样性。合成数据需要经过严格的质量控制,包括格式检查、答案正确性验证和多样性去重。

偏好数据质量控制。 RLHF(基于人类反馈的强化学习)需要偏好数据,即对同一指令的多个回答进行排序。偏好数据的质量直接影响奖励模型的准确性。关键的质量控制措施包括:标注者间一致性检查(Cohen's Kappa 系数)、模糊样本的多人标注与投票、以及通过对比模型预测与人工标注来发现系统性偏差。在实践中,高质量的偏好数据往往比数量更重要——几千条精心标注的样本可能比数万条噪声样本更有效。

数据飞轮示意图:模型部署、用户反馈、数据标注和模型更新的正反馈循环

图 4-15:数据飞轮。模型部署后收集用户交互数据,筛选有价值的样本补充训练集,重新训练后部署更新模型,形成持续改进的正反馈循环。

数据飞轮(Data Flywheel)。 成熟的大模型系统会建立一个持续改进的数据循环:模型部署后收集用户交互数据 从中筛选出有价值的失败案例和边界场景 补充标注后加入训练集 重新训练或微调模型 部署更新后的模型继续收集数据。这一飞轮效应使得模型能力与数据质量形成正反馈循环。数据飞轮的核心挑战在于如何从海量用户交互中高效地识别出对模型改进最有价值的样本,常用的策略包括基于不确定性的采样、基于用户反馈(点赞/点踩)的筛选,以及专门针对模型弱点领域的定向数据收集。

本节小结

本节完整介绍了大语言模型数据工程的五个核心阶段:

  • 数据来源的多样性决定模型能力的覆盖面。Common Crawl 提供规模,Wikipedia 和书籍提供质量,代码和学术语料提供专业深度,不同来源按精心设计的比例混合。
  • 数据清洗是将"原矿"转化为"可用素材"的过程,包括从 HTML 中提取纯文本、过滤隐私信息(邮箱/电话/IP)、检测并移除 NSFW 和有毒内容,以及语言识别。
  • 数据去重是提升模型性能最有效的单一步骤。精确去重基于哈希匹配处理完全相同的副本;模糊去重通过 MinHash 生成文档签名、LSH 快速定位候选对、Jaccard 阈值验证,高效处理"几乎相同"的文档。
  • 质量分类采用两层策略:Gopher 启发式规则快速过滤明显低质量文档,KenLM 困惑度和 fastText 分类器进一步对剩余文档进行精细质量评分。
  • 后训练数据准备包括指令数据合成(Self-Instruct、Evol-Instruct)、偏好数据的质量控制(标注一致性、多人投票),以及通过数据飞轮实现模型与数据的持续共同进化。

从数 PB 的原始互联网快照到最终数 TB 的高质量训练语料,数据量的压缩比往往超过 100 倍。这一提纯过程的质量,在很大程度上决定了模型的最终能力上限。