资讯动态

LLM预训练数据配比消融实验:去重、过滤与领域比例的边际收益分析

发布时间:2026/10/8 3:51:02 来源:尧图企业网站定制
很多人问我的一个问题公开的开源数据大家拿到的大差不差为什么最后训出来的模型效果能差出一截早期我归因到模型结构和训练框架后来做多了才发现真正的差距多半藏在训练数据的“配方”里。这篇我拿去重强度、质量过滤和领域比例三件事在同一套模型和训练条件下做了一轮完整的消融实验。结论比较直接这三个开关都不是有就行的关系各自存在收益递减的区间配比错了会直接吃掉你几个百分点的下游分数。文章会给出我实际用到的基线设计、实验矩阵、处理管线和踩坑记录适合正在做预训练数据Pipeline、或者打算调整自有数据配比的团队参考。1. 为什么数据配比值得专门做一轮消融实验1.1 数据配方才是真正拉开差距的杠杆做LLM训练的人都知道一句老话模型结构决定上限数据决定你能摸到多高的上限。但真到实操里大部分团队在模型结构上的讨论投入远高于数据配比。PyTorch版本、张量并行、序列长度、学习率调度这些能调的都调了个遍唯独数据配比经常拍脑袋看某个开源模型报告里写了“代码数据占12%效果好”自己也照着切12%听说“去重阈值0.8不错”自己也写死0.8。这种抄作业式做法之所以不靠谱是因为不同团队的原始语料构成、数据源头、清洗深度都不同。同样0.8的MinHash阈值别人数据里是干净爬虫文本你数据里全是半生不熟的HTML转文本过滤后的效果自然天差地别。我这次做消融实验的动机很简单想用可复现的实验量化同一批原始语料在不同去重强度、不同质量过滤策略、不同领域配比下的模型性能变化让后续数据迭代有据可依。1.2 消融实验的边界先弄清它回答什么问题消融实验不是万能药。它最适合回答“单因子变化对结果的边际影响”这类问题样本是“把去重阈值从0.8抬到0.95模型在HumanEval上到底涨还是跌”。但它回答不了“整体最佳数据配方是什么”这种全局优化问题因为因子之间本身有交互作用比如强去重加严格过滤会让语料量骤减这时还硬要保持固定的总token数就必然得引入更多重复遍历或人工混合数据干扰项就进来了。所以我这轮实验的设计原则是一次只动一个变量其余全部锁死先看边际方向再看量级。方向比绝对值更重要——你不需要精确知道代码比例从12%调到16%涨了多少分但你必须知道它是正收益还是负收益以及它的收益是否已经进入平台期。2. 消融实验的基线设计与评估体系2.1 固定基线模型、数据、训练参数一锤定音我先把这次消融实验的公共底座列出来后续所有实验组都在这个基础上改数据配方其他什么都不动固定项设置模型规模1.8B参数decoder-only标准Transformer序列长度4096优化器AdamW学习率峰值3e-4余弦衰减训练总token固定约100B按预处理后的净token计原始语料同一批清洗前的数据中文网页约55%、英文网页约25%、代码仓库约14%、数学类约4%、其他多语种约2%评估集MMLU、C-Eval、CMMLU、HumanEval、GSM8K加上中文文本困惑度统计这里有一个容易忽略的细节训练总token必须固定。如果不固定某个实验组因为过滤太狠导致token变少你很难分清下游分数变化是因为配比变了还是因为模型根本没训够。所以我在数据处理时就做了“token预算对齐”每个实验组把处理后的语料按比例抽样或过采样到同一个总量。2.2 评估维度不止是benchmark分数只看五个benchmark的平均分会掩盖很多问题。比如强过滤可能让MMLU的常识类分数微涨但生成类任务或代码任务掉得厉害。所以我的评估分三层看多任务benchmarkMMLU、C-Eval衡量通用知识HumanEval、GSM8K衡量代码和数学推理CMMLU衡量中文深度理解。文本统计指标中文和英文的分领域perplexity用来观察模型在特定语料分布上的拟合程度。针对性样例检查从生成结果里抽样检查多样性和重复度防止模型“分数漂亮但开口复读机”。这类检查很费时间但只有把三层叠在一起看才能知道数据配比的改动到底改在了哪里。2.3 预算规划用1/10数据跑预筛用全套验证训练100B token的1.8B模型也不是免费的如果每个实验组都跑满全套一轮消融下来成本非常难看。我采用的策略是两阶段第一阶段先用原始语料的1/10量级约10B token训练同一个模型跑完所有消融组合。这个量级下模型还没完全收敛但相对差异的排序已经具备参考价值。第二阶段只挑第一阶段里差异最明显的两三组用完整的100B token再训一次做确认。实践下来这个“小规模筛选、大规模确认”的流程能把消融成本控制在直接全套做实验的1/4左右而且排序稳定性在多数任务上足够可靠。3. 去重强度怎么消融MinHash阈值与去重粒度的实际影响3.1 去重强度和保留率之间的量化关系去重环节我用的是MinHash加LSH的经典方案。核心参数是Jaccard相似度阈值两个文档的MinHash签名相似度超过阈值就判定为重复保留先出现的丢弃后出现的。阈值越低去重越激进留下的token越少。为了把阈值换算成“保留率”我在同一批原始语料上做了测试MinHash阈值处理后保留token比例说明0.95约91%几乎只去掉完全重复或轻微改写0.85约82%常规推荐区间去掉较大片段重复0.8约76%我线上常用的起点0.7约69%明显更激进文档级相似就会被去0.5约58%很激进大面积模板化的文本基本被清掉阈值0.8到0.85之间通常是最甜区。低于0.7后保留率快速下滑但token质量并没有同比例提升反而开始出现误伤——一些内容不同但结构相似的文档被当成重复删掉比如多个教程都有的“前置知识”段落。3.2 三档阈值下的实验结果拆解我把去重强度拆成三档做消融弱去重阈值0.95、中等去重阈值0.8、强去重阈值0.5。其他配置全部保持基线质量过滤用同一档规则。实验组MMLUC-EvalHumanEvalGSM8K基线阈值0.845.845.124.926.7弱去重0.9543.943.223.125.2强去重0.546.245.424.126.1结果很有代表性。弱去重时语料里大量重复模板会让模型在训练后期陷入记忆式学习MMLU直接掉了近2分强去重时代码和数学任务不升反降因为代码仓库里很多问题描述相似但解法不同激进去重会把一部分带有微妙差异的样本误删模型在HumanEval上掉了0.8分。这类结构性差异只有把通用任务和代码任务分开看才看得出来。3.3 去重粒度文档级、段落级还是句子级除了阈值去重粒度也值得消融。文档级去重实现简单但粒度太粗两个网页共享一段版权声明或“相关阅读”列表就会被整体判重丢弃。段落级和句子级去重能更精细化地清理重复片段但对Pipeline的工程要求高很多。我这次对比了“文档级0.8”和“文档级0.8加句子级0.9”组合。后者在中英文通用任务上比前者高约0.4分在困惑度指标上也有改善。句子级去重的主要贡献是清掉了那些长文档内部反复出现的样板句——比如产品页的“点击购买”“支持多平台”这类高频句子。正式跑大规模训练前强烈建议至少上一层句子级去重。4. 质量过滤的消融从启发式规则到分类器再到困惑度4.1 过滤层级的拆解Light / Medium / Heavy质量过滤不是单点操作而是层层递进的多级管线。我做消融时把它拆成三档Light纯启发式规则只看长度、符号占比、乱码率、重复字符占比。Medium在Light基础上加一个fastText质量分类器。分类器用“高质量百科/新闻语料为正例、低质广告/垃圾文本为负例”训练输出每个样本属于高质量类的概率概率低于阈值的样本丢弃。Heavy在Medium基础上加困惑度过滤。用一个小型语言模型计算每个文档的平均Perplexity过滤掉那些PPL异常高或异常低的文本。异常高说明内容可能驴唇不对马嘴异常低说明可能是一段重复的模板。三档过滤的token留存情况过滤档位留存token比例中文PPLMMLUC-EvalGSM8KLight约88%8.6244.143.525.3Medium约76%8.3145.845.126.7Heavy约67%8.1645.345.826.24.2 过滤强度的边际收益数据最直接的体现是Light到Medium的提升非常显著MMLU和C-Eval分别上涨1.7分和1.6分这笔收益几乎白捡因为fastText训练成本很低推理也只占整个Pipeline的一道工序。但Medium到Heavy就进入平台期了MMLU反而微跌GSM8K也降了0.5分。原因是困惑度过滤对复杂推理型文本不友好。数学题的逻辑推理部分因为省略了很多自然语言连接词PPL天然偏高代码文件里变量命名紧凑PPL分布也跟新闻语料差很多。直接用统一PPL阈值过滤会误伤数学和代码语料。后来的修正做法是分领域各算各的PPL分布再按分位数过滤比全局一刀切靠谱很多。4.3 一个容易踩的坑过滤太狠导致领域塌陷过滤有一个隐蔽风险就是“领域塌陷”。比如原始语料里数学内容只占4%如果质量过滤时把大量数学格式文本判定为低质数学语料可能直接缩到2%。表面上看总token还够但模型在数学任务上的表现会明显滑坡。所以我在每次调过滤强度之后都会先按领域统计一遍留存比例确认没有某个领域被结构性误杀。Medium这档在这个环节表现比较均衡Heavy则需要逐领域校准阈值。5. 领域比例的消融代码、数学与通用语料的棋盘5.1 先行结论代码和数学是两个收益最陡的杠杆在去重和质量过滤都用基线配置的前提下我重点调了代码和数学两类数据的占比实验组代码占比数学占比通用占比MMLUHumanEvalGSM8K基线12%4%84%45.824.926.7代码提升20%4%76%45.527.427.1数学提升12%8%80%45.125.629.5双提升20%8%72%44.728.230.1代码和数学占比分别上调8个点和4个点后HumanEval和GSM8K分别涨了3.3分和3.4分这个幅度在1.8B模型上已经非常可观。代价是MMLU掉1分左右这是典型的通用知识迁移损失。如果你核心场景就是代码生成和数学推理这个兑换非常划算如果做的是通用助手就得谨慎了。5.2 配比曲线的收益递减现象为了看清楚“往上加到什么时候就该停”我额外跑了两组一组代码占比30%另一组数学占比16%。试验结果很直白——代码占比从20%顶到30%HumanEval基本没再涨GSM8K也原地踏步数学占比从8%顶到16%GSM8K反而掉了约0.6分因为数学语料大量挤占通用语料后模型在其他任务上的负向迁移开始盖过数学受益。结论是代码和数学的收益曲线都是先陡后平的形状。代码在12%到20%区间收益明显超过20%看不太出差价数学在4%到8%区间收益显著超过10%后可能反向。这类结论跟模型规模、基础数据质量都有关系换到更大规模时可能需要再测一轮但“先上升、后平台、再下降”这个基本形态是稳定的。5.3 比例调整如何影响不同语言的迁移领域配比不只有代码和数学多语种配比也值得一提。我把中英配比从60:25调整到50:35英文语料增加后MMLU上涨约0.6分中文的CMMLU和C-Eval则下滑约1分。这符合直觉数据里英文占比高英文知识覆盖就更足但中文空间的拟合密度被稀释。如果你的产品主打中文与其盲目提高英文通用语料不如先稳住中文核心领域数据再小幅引入英文高质量知识类语料做补充。那种“中英各一半”的做法在通用场景未必最优。6. 完整实操流程从原始语料到结论表6.1 数据处理流水线的搭建我这次的Pipeline完全跑在Spark集群上按“清洗、去重、过滤、配比”四步走写成可复现的离线任务。清洗阶段先把HTML标签剥离、做Unicode规范化、统一标点这步很基本但千万别省。去重阶段用datasketch库实现MinHash和LSH分片处理千万级文档时要调整好band数避免单个分片数据倾斜。# 去重阶段构建MinHash并做LSH查询 from datasketch import MinHash, MinHashLSH def build_minhash(text, num_perm128, shingle_size8): m MinHash(num_permnum_perm) for i in range(len(text) - shingle_size 1): m.update(text[i:ishingle_size].encode(utf-8)) return m lsh MinHashLSH(threshold0.8, num_perm128) for doc_id, text in corpus: m build_minhash(text) candidates lsh.query(m) if not candidates: lsh.insert(doc_id, m) keep_doc(doc_id, text)质量过滤阶段分类器部分我用fastText训练迭代很快一份几万条的标注样本就够启动。# 分类器训练与预测 import fasttext model fasttext.train_supervised(quality_labels.tsv, lr1.0, epoch25, dim128) for doc_id, text in corpus: label, prob model.predict(preprocess(text)) if label __label__good and prob 0.55: emit(doc_id, text)配比阶段按最终需要的领域比例做采抽样。注意代码和数学语料本身占比小提高配比靠的是对这些语料做多轮重复过采样而不是凭空造数据。6.2 六组消融实验的矩阵设计与运行我最终跑了六组算是把三件事的关键档位都覆盖到了实验组去重阈值过滤档位代码比例数学比例训练量级E0 基线0.8Medium12%4%10B 100B确认E1 弱去重0.95Medium12%4%10BE2 强去重0.5Medium12%4%10BE3 重过滤0.8Heavy12%4%10BE4 代码优先0.8Medium20%4%10B 100B确认E5 数学优先0.8Medium12%8%10B 100B确认每组先在10B量级上训练统一用8块A10080GB跑两天左右记录checkpoint并评估。特别地我会在训练中段30%和70%各存一个checkpoint观察不同配比的收益曲线方向是否一致。6.3 结果汇总与边际收益分析综合全部实验我的最终结论可以用一个简单排序表达去重从“弱”调到“中等”收益最大成本最低几乎是稳赚。去重从“中等”调到“强”收益很小风险上升谨慎操作。质量过滤从“Light”调到“Medium”收益明显建议默认启用。质量过滤从“Medium”调到“Heavy”收益趋近于零还需关注领域误伤。代码和数学比例从基线调高收益大但有上限且会换掉部分通用分数。7. 踩坑实录数据消融实验里最容易被低估的五个问题7.1 波动大实验跑不出信噪比消融实验最大的敌人不是成本是噪声。1.8B模型在不同随机种子下同一份数据训出来的MMLU能差1到2分。如果你改一个变量只带来0.3分变化很可能直接被随机性淹没。我的对策有两个一是固定训练种子让所有实验组从同一个起点开始二是小规模筛选阶段每个实验组跑两个不同种子取平均虽然多花一倍时间但结论可靠性明显提升。7.2 token总量对不齐很多时候不是故意不对齐而是处理管线天然会改变token总量。强过滤后语料少了为了凑到训练预算只能过采样那这个过采样本身又引入重复叠加回数据里。这个问题没有完美解法只能靠集中在报告里说明清楚不要掩盖。我习惯在每个实验组数据表后面单独注明“有效token中重复遍历占比”方便后续分析时扣除这部分干扰。7.3 只看一个checkpoint就下结论预训练不同阶段的表现排序可能反转。E3重过滤那组在小规模上下文中期曾短暂领先但跑到后期被E0超回去。如果只取最后一步对比有些规律会失真。所以至少取三个检查点比如30%、70%、100%看趋势不要只盯最终分数。7.4 单一benchmark迷信MMLU涨了不代表模型整体变好。那组“数学优先”的配置GSM8K很好看但CMMLU和C-Eval都掉了1分上下说明数学语料挤占了中文通用知识空间。做数据配比决策时一定把业务目标排在benchmark前面。如果我只做对话助手MMLU和CMMLU的优先级远高于GSM8K。7.5 过滤后语料欠拟合这个坑很反直觉过滤最狠的实验组训练loss反而下降更慢。原因不是语料质量不够而是语料总量骤减后模型只能反复看同一批样本泛化能力被削弱。如果你在用强过滤必须同步检查训练loss和下游任务得分两个指标一旦出现“loss其实已经收敛但benchmark还在往下掉”的现象大概率是数据多样性不足了。跑完这一轮我个人最大的体会是数据配比调优不是“找到最优值然后不再变”的静态问题。语料来源会变、业务目标会变、模型规模也会变。与其追求一个万能配方不如把这套消融实验的方法固化下来每当数据组成有较大变化时花一周时间重新跑一遍用结论指导数据迭代。后续我打算再把“数据配比与模型规模的联动关系”单独拉出来做一轮实验看看在3B、7B规模上这些结论的迁移程度等到结果整理清楚再回来更新。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑