ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

大模型pre-pre-training规则系统:数据清洗与课程学习指南

大模型pre-pre-training规则系统:数据清洗与课程学习指南 如果你最近在跟大模型训练、数据处理相关的东西打交道应该已经注意到一个趋势圈子里讨论的重点正在从模型结构向数据侧大规模转移。不管是开源社区的RedPajama、FineWeb还是各家内部的训练管线都会反复提到一个词——pre-pre-training。第一次看到这个词我也愣了一下心想这不就是数据处理吗怎么还单独起个名字。后来深入看下来才明白这个阶段确实值得被单独拎出来讲。pre-pre-training简单说就是“正式预训练之前的准备阶段”。它不是一个有梯度更新的训练循环而是决定模型最终底色的数据筛选、清洗、配比和排序策略集合。你在预训练阶段看到的每一条样本都是这个阶段用一套“规则系统”筛出来的。规则系统的好坏直接决定了同样算力下模型的loss能压多低、知识密度能有多高、对话质量的底线在哪。这篇文章我就围绕“pre-pre-training的规则系统”展开把目前业界实践中真正在用的规则体系做一个系统梳理。我会按硬规则、软规则、元规则三个层面去拆解把每类规则的核心思路、实现要点和阈值经验都讲透。无论你是准备自己从零清洗一份数据集还是想理解DeepSeek、Llama这类模型的数据配方里到底做了哪些操作这篇文章应该都能给你一个比较完整的框架。1. 先理解“pre-pre-training”到底是什么阶段1.1 从数据到模型中间的“隐形训练阶段”一个标准的大模型训练流程通常是原始数据收集 → 预处理 → token化 → 预训练 → SFT → RLHF。pre-pre-training这个说法对应的就是“预处理”到“预训练”之间的那段地带但它的内涵比简单的“清洗”要广得多。传统意义上的数据清洗关注的是“脏数据怎么去掉”比如乱码、重复、格式错误。但pre-pre-training关注的问题更上层在把数据送进模型之前怎么通过规则系统设计一套“数据配方”让模型在有限的算力预算下学到更高的知识密度、更强的推理能力和更好的语言覆盖度。我把这个阶段理解为一个“隐形训练阶段”原因在于虽然这里没有梯度计算但规则系统的设计逻辑本质上就是在做“训练导向的数据工程”。同样是1TB文本A方案直接喂进去B方案先过滤、去重、排序再喂进去训练出来的模型能力可能差出一个代际。这个差距不是模型结构带来的而是pre-pre-training阶段规则系统的差距。1.2 为什么这个阶段需要“规则系统”可能有人会问直接用模型做数据筛选不行吗比如用一个小模型打分质量低的扔掉。这个思路确实存在但实际工程中你会发现纯模型打分有两个硬伤一是计算成本太高数TB数据全部过一遍小模型耗费的时间和算力往往比预训练本身还可观二是模型打分存在盲区比如对于“高质量但小众领域”的文本、对于“交叉学科”内容评分模型的表现往往不稳定。所以业界的共识是用一套可解释、可配置、可迭代的规则系统来做第一层和第二层筛选模型打分作为其中的一个“软规则”嵌入整体流程。规则系统的核心价值在于快速、廉价、确定性高。它能在单位算力成本极低的情况下把数据从“原始”变成“合格”。1.3 规则系统的总体分类框架综合目前公开的技术报告和开源社区实践我习惯把pre-pre-training的规则系统分成三大类硬规则Hard Rules确定性过滤要么通过要么丢弃。典型包括格式校验、语言识别、黑名单匹配、PII检测、长度过滤等。这类规则速度快、可解释性强适合流水线的最前端。软规则Soft Rules打分与排序不直接丢弃数据而是给每条样本打个分分数低的排在后面或用阈值截断。典型包括困惑度打分、统计特征打分、质量分类器输出等。这类规则决定了“数据的好与更好”。元规则Meta Rules编排与调度管的是数据以什么顺序、什么比例进入训练。典型包括课程学习顺序、领域混合配比、难度阶梯调度、动态数据源切换。这类规则是pre-pre-training阶段独有的也是很多人忽略的维度。后面几个章节我逐层展开这三个层面各有各的门道。2. 数据准入硬规则第一道闸门怎么设计2.1 格式清洗与编码纠错规则硬规则里最基础也最好理解的是格式清洗。这里说的格式不只是“去掉HTML标签”这种显性的清理还包括字符编码层面的纠错。我在实际处理大规模爬取语料时发现编码问题是最容易翻车的环节。很多爬虫抓回来的网页看着是正常的UTF-8文本但里面夹杂着大量非法字符、乱码字节、以及不同编码体系混用比如GBK和UTF-8字节混在一起。如果不做编码检测和纠错这些字节会被tokenizer切成奇怪的token序列不仅浪费上下文窗口还会引入噪声。这一层规则通常包含检测文本原始编码统一转为UTF-8。过滤非法Unicode字符保留常见语言字符集。合并被错误切分的中文文本比如引号、括号被独立成行。移除控制字符除了换行符和制表符。2.2 语言识别与PII过滤规则语言识别在pre-pre-training阶段几乎是必做的硬规则。如果不做语言过滤你会得到大量低质量的混合语言文本、机器翻译痕迹明显的伪双语文本甚至OCR识别错误导致的乱码。这些数据对模型的负面影响比想象的更大它会让模型的语言边界变得模糊在生成时出现中英混杂、语码转换失控的现象。语言识别这一层我常用的方案是fastText的lid.176模型在文本段级别上做语言分类然后按置信度阈值过滤。比如要求目标语言置信度0.8低于这个值的就直接丢弃或单独分流到多语言数据集。PII个人隐私信息过滤也是硬规则中不可跳过的一环。这个不只是合规要求对模型自身也有好处——如果模型在训练中见过大量身份证号、手机号、邮箱地址它在生成时会有一定概率“背出来”那就是严重的事故。PII过滤规则在实现上分为两个层面针对结构化PII身份证、手机号、银行卡号用正则校验位算法做高精度匹配。针对非结构化PII人名、地址、职业信息用命名实体识别模型辅助标注然后做脱敏或移除。2.3 启发式过滤规则的阈值经验在格式清洗、语言识别之外还有一批基于统计特征的硬规则我习惯称它们为“启发式过滤器”。这些规则虽然朴素但在大批量处理时极其高效。下面是我实际使用中积累的一部分阈值经验可以直接作为初始配置参考规则项常见阈值说明文本长度小于100字符丢弃过短文本信息密度低且容易引入碎片化噪声重复字符率超过30%丢弃检测“aaaaaa”类噪声文本重复n-gram比例超过50%丢弃检测重复段落、洗稿文本平均句长超过400字符或低于5字符异常句长通常说明格式问题标点密度低于3%或高于30%标点异常说明文本可能是乱码或纯符号堆砌分词后未知词比例超过10%丢弃用tokenizer初步统计过高说明语料严重跨语言或乱码URL占比超过20%丢弃大量URL说明是标题列表页而非正文弹幕/评论特征词命中命中3个以上丢弃过滤社交媒体低质内容这些数字不是拍脑袋定的而是基于对多份公开数据集的统计复盘。比如C4数据集公开的过滤标准里有“英文占比必须大于0.99”这一条RedPajama则要求“文档中70%以上的单词是英文停用词列表中的词”。我上面列的这些阈值是一个相对通用的起点具体调参时要结合自己数据源的实际情况来做。注意硬规则不是越严格越好。你会发现指标设得太高确实把脏数据过滤掉了但同时也把很多“长相难看但内容有价值”的文本误杀了。尤其是代码、数学公式、方言文本它们的统计特征和规范文本差异极大需要单独设置规则分支而不是用一套通用规则一刀切。3. 去重规则系统精确去重与模糊去重的配合3.1 为什么去重是pre-pre-training的“送分题”数据去重是学界和业界都高度一致认可的规则方向。在训练集中重复数据会让模型倾向于背诵而不是泛化。更严重的是大规模重复数据会显著延长训练收敛时间等于变相浪费算力。对于这个问题有个比较具体的经验在同规模参数下训练集去重后模型的困惑度往往能显著低于未去重版本。原因也很直观——模型在每个token上看到的“信息量”更大了同一份训练预算买到了更多的有效经验。去重规则按粒度可以分好几层实际工程中这几层通常一起上URL去重在抓取层面同一个URL只保留一次不同URL但内容相同的情况交给下一层处理。文档级精确去重对整个文档做哈希哈希相同的直接丢弃一份。文档级模糊去重内容基本相似但有个别字符修改的用概率数据结构识别。段落级去重文档内部或跨文档的重复段落检测防止多篇文档共享同一大段模板文字。3.2 精确去重规则Hash与布隆过滤器精确去重的实现非常直白对每个文档算一个哈希值放入哈希集合中遇到重复哈希就丢弃。但在pre-pre-training的场景里数据量大到要用“技巧”来实现高效精确去重。实际处理TB级数据时我做的第一版精确去重用的是“分片哈希布隆过滤器”。思路很简单将文档按固定大小分片比如每个分片64MB。对每个文档里的每一行文本做SHA-256哈希。把哈希值写入一个布隆过滤器布隆过滤器判“可能存在”的再回查哈希集合做二次确认。布隆过滤器在这里的价值是大幅降低内存占用。如果直接存所有文档哈希到一个Python set里几亿篇文档会直接吃光内存。但布隆过滤器以牺牲极小的误判率为代价把内存占用降到可以接受的量级。还有一点值得注意精确去重最好在文档被截断之前做。如果先截断再哈希两篇内容相同但长度不同的文本哈希值就不同精确去重就失效了。3.3 模糊去重MinHash LSH与SimHash模糊去重要解决的问题是两篇文档意思相同但表述略有出入——比如换了几个词、调换了段落顺序、或者插入了无关广告词。这种内容哈希值完全不同但信息量冗余。如果不去除模型会把同一知识的多种改写形式都背下来压缩信息密度。业界用得最多的模糊去重方案有两个MinHash LSH把文档转换成shingle集合比如5-gram或10-gram通过多个随机哈希函数给集合打签名再用局部敏感哈希把签名相近的文档分到同一个桶里。这样相似文档会被分到同一个候选桶再做精确的Jaccard相似度计算。这套方案适合“检测重叠度高的文档”比如文本转载、洗稿。SimHash把文档的每个特征词可以带权重哈希成64位向量按位加权累加最后得到文档的64位指纹。两个文档的汉明距离小于等于3就可以视为重复。SimHash的优点是计算速度快、内存占用小缺点是它更擅长“整体相似”的检测对于局部重复比如只有一段相同不如MinHash好用。在实际工程中我通常把两套方案结合使用SimHash跑全局粗筛MinHash LSH跑候选集精确判定。3.4 跨语言和改写去重规则还容易漏掉的一个去重场景是跨语言去重。同一篇文章被机器翻译成多种语言后内容本质是同一条信息。如果多语言语料里大量存在这种互译关系模型在一个语言上学到的知识会“无谓地”在另一种语言里被重复强化挤压其他知识的容量。跨语言去重的实现思路不算复杂先在语义层面做embedding再用向量相似度聚类。考虑到预处理阶段算力有限一个实用做法是只对多语言样本中标题、关键句做embedding然后做全局向量近邻搜索。命中相似度大于阈值的文档保留质量较高的一篇即可。还有一类“改写去重”问题模型生成的文本加入了训练集中导致原始文本和模型改写文本同时存在。这类数据会对模型产生一个不良影响——让模型倾向于“绕弯子”表达而不是直接给出答案。处理方式是在去重流水线中增加一个“模型文本检测”规则分支比如用perplexity区分机器生成文本和人类文本机器生成文本单独存放或降低采样权重。4. 质量打分软规则从“能留不能留”到“谁排前面”4.1 为什么要用“打分”而不是“过滤”硬规则解决的是“能不能留”的问题但pre-pre-training阶段更精细的问题其实是“好不好、有多好”。在算力有限时我们不可能把全部合格数据都喂给模型这时就需要对数据做优先级排序。排序的依据就是质量打分。打分可以把“合格”数据进一步区分为“优质”“普通”“低质”让训练器在有限的步数里先看到信息量最大的数据。这也是pre-pre-training和传统“数据清洗”最大的区别——它不只是做减法还做排序和调度。4.2 统计启发式打分维度统计启发式打分不依赖模型只依赖文本本身的统计特征。它速度快、成本低适合作为质量打分的第一层。我常用的一组统计打分特征包括标点符号分布均匀度正常文本的标点分布相对均匀过长无标点段落通常说明结构异常。停用词比例中英文各有高比例停用词如果停用词比例异常说明文本可能是关键词堆砌或机器生成。句子长度方差优秀文本的句子长短有变化如果所有句子长度几乎一致可能是模板化文本。语法结构多样性近似统计从句连接词、并列结构的出现频率多样性高的文本更可能是人工书写。命名实体密度高质量的百科、新闻文本中实体密度相对高低质量的日志、聊天文本实体密度低。关键词分布标题中的关键词应该在正文中有合理分布如果全文堆砌同一个关键词价值通常较低。这些特征可以加权合成一个0到1的分数。每个特征的具体权重通常需要用一小批人工标注数据来校准。比如先人工标注1000篇文档为“优质/普通/低质”然后用逻辑回归或XGBoost学习权重。4.3 基于困惑度的规则过滤困惑度PerplexityPPL是pre-pre-training阶段最常用的模型打分指标之一。做法是用一个已训练好的小语言模型比如GPT-2或Llama系列的7B版本都行对候选文本计算PPL。PPL背后的直觉是如果一个文本是高概率的“正常文本”模型预测起来会比较容易PPL就低如果文本是乱序、多语言混杂、代码与自然语言混排、或者使用了模型不熟悉的表达PPL就高。以英文语料为例GPT-2计算的PPL大约分布在15到500之间。我通常把PPL大于200的文本判定为低质候选PPL低于30的文本视为高质候选。但要注意这个阈值跟模型能力和语料领域强相关换一个基础模型就要重新校准。PPL规则有个有意思的用法它是“硬规则误杀”的最佳补偿器。比如数学推导文本在统计特征上可能标点比例偏低、句子长度偏长被硬规则判死但PPL反而很低——因为语言模型的概率分布认为它是自然连贯的文本。所以在工程上PPL通常在硬规则之后做“拯救”而不是继续“砍杀”。4.4 多规则加权融合与动态阈值单一的软规则往往有偏科实际应用时一般做“多规则融合”。比如最终质量分 0.3×统计质量分 0.4×PPL归一化分 0.3×质量分类器分。融合之后还需要设置动态阈值。动态阈值的含义是不固定死一个分数线而是按数据量的分位数来截断。比如设定“本轮只保留质量分前70%的样本”而不是“质量分高于0.6的样本”。这样做的优势在于不同批次的原始数据质量有波动固定阈值会导致某些批次过滤过狠、某些批次过滤不足分位数截断则自适应能力强很多。5. 课程学习与数据调度规则pre-pre-training阶段怎么“喂数据”5.1 课程学习规则由易到难的核心思路数据筛选是pre-pre-training的“面”课程学习是pre-pre-training的“序”。同一个数据集按不同顺序喂给模型训练效率和最终效果有明显差异。课程学习的基本规则是把数据按难度排序先让模型学习简单、清晰的文本建立稳定的语言表征再逐步引入复杂、模糊甚至带噪声的文本。我举一个实际案例。早期我在做领域预训练时尝试过两种数据顺序第一种是随机打乱、直接全部喂给模型第二种是把教科书、百科、技术文档放在前面把社交媒体、论坛讨论放在后面。训练相同的步数之后第二种方案的验证集PPL明显更低下游Benchmark上的指标也普遍高出1到3个百分点。这个现象背后的原理是模型在早期阶段对数据的“归纳偏置”极其敏感如果一开始就看到大量噪声和混乱句式模型会花费大量capacity去适应异常模式而不是先构建稳定的语法和语义骨架。课程学习相当于给模型一个“先骨架后细节”的学习路径。5.2 难度度量与课程阶梯设计要设计课程学习规则第一步是给数据定义“难度”。在实际工程中我用的难度度量是复合指标句法复杂度平均句长、从句数量。词汇复杂度罕见词占比、专业术语密度。抽象程度通过实体密度间接估计实体密度越低文本越抽象。PPL值作为综合难度信号。有了难度分数之后课程阶梯就比较好设计了。常用的是“多级阶梯”式规则第一级只使用难度最低的前20%数据第二级加入前40%以此类推。每一级训练一定的步数或经过一次loss平台期后再进入下一级。这个“进度控制规则”是这个系统的核心它决定了什么时候进下一个stage。我在实践中喜欢用“loss下降速度”作为切换信号当当前难度级别的验证loss超过N步不再下降时自动引入下一级更难的数据。这种方式比固定步数切换更稳因为不同数据源的学习曲线差异太大了。5.3 领域混合与配比规则课程学习只解决“难易顺序”还有一个维度是“领域配比”。pre-pre-training阶段如果不做领域混合规则默认会完全由原始数据比例决定——比如网络爬虫数据占99%百科数据占0.5%代码数据占0.01%那么模型会被“话语权”最大的网络数据主导。业界常用的领域配比规则有几种形式固定配比按人工设定的比例混合各领域数据比如“网页60%、百科15%、书籍10%、代码10%、学术5%”。按信息量配比对每个领域估算独特n-gram比例信息量高的领域给更高权重。动态配比训练中定期评估各领域loss对于loss异常高的领域动态增加采样权重。从我实践来看动态配比规则最值得深入研究它本质上是“在训练中自动发现模型短板然后用数据规则去补”。但这个实现复杂度比较高小规模项目可以直接用固定配比起步。5.4 在线反馈与重采样规则课程学习和配比规则最好是“在线”的而不是“离线”跑一次就固定下来。原因在于模型的弱点在训练中期和后期会快速变化一套固定的课程阶梯很难始终匹配模型当前的接受能力。这里要引入一个在线规则的闭环定期比如每500步或每2000步跑一次小范围评测观察模型在不同数据子集上的loss表现然后根据这个反馈动态调整数据采样器里各数据源的权重。实现上可以把这个闭环做成一个简单的规则引擎数据采样器从各领域数据集中抽样 → 训练一小段 → 计算每个领域的平均loss → 如果某个领域的loss持续偏高就提升该领域的采样权重如果持续偏低就降低或提升更难的子集。需要注意的是规则更新不能太激进要保持权重平滑变化。我的经验是每个调度周期内单个数据源的权重变化不超过20%比较安全改动太大会导致训练剧烈震荡反而打乱已有的学习状态。6. 规则系统的工程落地与工具选项6.1 规则引擎怎么搭可配置化优先前面几章讲的是规则有哪些这一章集中讲规则系统怎么在工程上落地。我强烈建议pre-pre-training阶段的规则系统一定要做“可配置化”不要写成一堆硬编码if-else。原因很简单数据规则需要持续迭代每次改一个阈值都重新编译、发版迭代速度太慢了。而且规则与规则之间的组合关系很复杂写死在代码里既难调试也难复用。我偏好的架构是规则引擎 配置描述。每一条规则都是独立的处理单元接收一个文档对象输出保留、丢弃或打分。规则之间通过一个配置文件描述执行顺序和组合方式。6.2 规则优先级、短路与组合策略多规则执行时规则优先级设计直接影响性能和结果。最常见的方式是“短路执行”如果一个硬规则判定文档丢弃直接终止后续规则不再执行打分。以我处理一次中文互联网语料为例约40%的文档会在编码检测、语言识别、长度过滤这几个前置硬规则被淘汰这意味着后面的PPL打分、质量分类器只需要处理60%的文档整体算力开销直接节省了可观的一部分。对于“组合规则”我习惯分为三类AND关系多条同时满足才保留。OR关系满足任一条件即处理。WEIGHTED关系多条软规则加权汇总成最终分数。配置示例简化版{ rules: [ { name: language_filter, type: hard, params: { target_lang: zh, min_confidence: 0.8 } }, { name: length_filter, type: hard, params: { min_chars: 100, max_chars: 50000 } }, { name: ppl_scorer, type: soft, weight: 0.4, params: { model: gpt2, max_ppl: 200 } }, { name: stat_scorer, type: soft, weight: 0.3, params: { stopword_ratio_range: [0.05, 0.6], punctuation_range: [0.03, 0.3] } } ] }6.3 规则效果怎么评估离线回放与线上监控规则系统需要持续优化那么怎么评估“这次规则改动是变好了还是变坏了”离线评估的方法主要有两种留存集PPL对比固定一个验证集分别用旧规则和新规则处理出来的训练子集做短周期小规模训练对比验证集PPL。这种评估成本不算太高但能直接反映“规则改动能影响多少训练效果”。人工抽检打分从新规则产出的数据中随机抽样让人工标注每一批数据的合格率。这个办法费人力但能发现很多评测指标看不到的规律——比如一些评分不够客观的文本被保留了。线上监控则关注规则系统本身的运行状态。我在生产环境里至少监控这些指标每个规则的处理量和淘汰率能看出数据源的波动。质量分的分布变化分布异常往往说明上游爬虫策略变了或新数据源混入异常格式。进入训练队列的数据量防止某个规则突然把大量数据打成低分导致训练数据断供。6.4 常见问题与排查技巧实录我在搭建和维护pre-pre-training规则系统的过程中踩过不少坑挑几个典型的写出来应该能帮你少走弯路。问题一规则调完下游效果反而变差排查思路先检查淘汰率变化。很多时候调高阈值会误杀大量有领域价值的文本而单纯看“数据干净度”指标是发现不了的。处理方式是在规则集里增加“保护列表”比如代码文件、数学文本、古文、方言文本这些特殊类型需要单独的逻辑分支避免走通用过滤规则被误判。问题二模糊去重误伤率高排查思路SimHash对汉明距离的阈值非常敏感。距离设置为3时某些短文档会被错误聚类成重复。我实测的优化方式是把文档按长度分段处理——短文档用更高的相似度门槛长文档用低一点的门槛。另一个补充手段是对聚类结果做一次“重复片段占比”二次确认只有当重复片段超过全文60%时才判定为重复。问题三PPL打分对代码和数学文本极不友好排查思路PPL模型通常是在自然语言语料上训练的看到代码时会给出异常高的PPL。这个问题的本质是“评分模型偏差”而不是“数据质量差”。解决办法是在打分之前先用分类模型把数据分成“自然语言”和“代码/数学”两个主类各自用不同的评分模型和阈值体系来评估。问题四课程学习导致训练早期数据量不足排查思路如果第一级课程只保留10%的数据训练器可能因为数据多样性不足而过早过拟合。我的做法是课程阶梯的起步level不要设得太低至少保留30%的数据量同时每一级之间要有数据重叠不能是“完全替换”而是“逐渐扩增”。7. 我在实践中的几点体会规则系统做到最后你会意识到它本质上是一门“权衡的艺术”。规则少了脏数据污染模型规则多了误杀优质数据、模型学到的信息量不足。更麻烦的是同一个规则集在一种数据源上表现很好换一个数据源可能完全不适用。所以我现在的习惯是一切以“小规模训练评估”为准不迷信任何公开的阈值和公式。如果你刚起步我的建议是先搭一个最小可用的硬规则流水线把语言过滤、格式清洗、精确去重这几件事做扎实。这一步的投入产出比最高。再逐步加入PPL打分、MinHash模糊去重、课程学习这些更复杂的规则。千万不要一开始就追求大而全规则系统本身也是一个需要慢慢迭代打磨的工程组件。另外规则系统的实验记录必须做好。我在实践中有个习惯每次改动规则集都会完整记录变更内容、产生数据的规模、训练曲线的变化甚至保留一份修改前的数据快照。在这个领域“数据配方”的每一个细节都可能成为下一次优化的线索。最后说一个小技巧你可以把“规则处理后的数据”和“未处理的数据”各训练一个对照模型用下游任务来验证规则系统的真实效果。这比单独看数据统计指标可靠得多。pre-pre-training的规则系统归根到底是要为下游训练服务的它的好坏最终只能由模型的表现来回答。
返回列表