前前后后折腾了两个月,手上这个27B模型的后训练总算收尾了。三个核心基准——GPQA、MMLU、LCB全部站上90分,同时把基座模型那套动不动上千字的思考链压缩了大半。发布版本已经挂出去,这篇文章就把整个流程拆开写一遍,从评估指标到训练策略,再到思考量压缩的思路和踩坑记录,希望给正在做类似工作的同学一个能抄作业的参考。
先说清楚这套方案解决的是什么问题。27B这个量级的模型,基座本身的推理能力已经不弱,但直接用基座做复杂任务有两个痛点:一是回答格式不稳定,尤其是数学和代码场景,容易输出无效内容;二是思考链过长,每个问题都要生成大段推理文本,实际部署时首字延迟高、吞吐上不去。所以这次后训练的目标很明确:在不掉性能的前提下,把无效思考压掉,让模型回答又快又准。
1. 项目定位与核心思路拆解
1.1 为什么盯上27B这个量级
过去半年社区里有个趋势,大家都在往小参数模型上灌推理能力。7B、14B打磨得再狠,面对真正的复杂推理题目,天花板还是明显存在。72B甚至更大的模型性能确实好,但部署成本和推理延迟不是每个团队都扛得住。27B正好卡在一个甜点位:单卡或者双卡能跑,显存压力可控,同时参数量足够支撑复杂的多步推理。
这套方案的定位不是从零训一个基座,而是基于某个开源的27B基座模型做后训练。基座本身在MMLU这类常识问答上已经不错,但在GPQA这类研究生级别科学问题上,基座直接输出的准确率往往只有六成左右。后训练需要做的事情,是把基座已经学会的知识“调度”出来,让它在面对难题时知道如何一步步推导,在简单问题上则不浪费算力。
1.2 三个基准指标各自代表什么
GPQA、MMLU、LCB三个缩写覆盖了三类不同的能力平面。
GPQA是一个出题门槛很高的科学问答集,题目涉及物理、化学、生物等领域的专业推理,标签来自相关领域的博士生,且经过交叉验证确保“专家也可能答错”的难度。这个指标是检验“对知识做深层推理”的试金石,基座模型靠记忆很难命中,必须真正理解题目中的逻辑链条。
MMLU是大家最熟悉的多任务语言理解基准,覆盖人文、社科、理工等几十个子任务。它考察的是知识覆盖面和常识推理的稳定性。这个基准的分数通常被当作模型“通识水平”的参考线,也和易用性直接挂钩——一个模型如果MMLU不行,日常对话和历史百科问答都会翻车。
LCB是代码能力基准,全称涉及人工收集的真实编程题目和修复场景。它测试的不是“能不能写出Hello World”,而是“面对一段残缺代码能不能定位Bug、补全功能、满足隐藏测试用例”。代码指标很多时候比文本推理更能反映模型的综合能力,因为代码本身是一种严格的结构化语言,对逻辑一致性要求极高。
这次的目标是三个基准同时过90。关键是“同时”——有些模型通过数据筛选能单点刷爆某一个基准,但另外两项就会出现明显滑坡。真正的后训练目标应该是均衡提升,而不是在某一个榜单上自嗨。
1.3 降低思考量这件事为什么重要
“思考量”换成实际指标就是模型在Answer阶段输出的token数量。原版基座模型在处理问题时,无论问题难易,都倾向于生成大段推理文本。从用户体验角度,用户问一个半小时后就要召开的会议时间换算问题,模型不应该输出一篇议论文;从工程角度,输出token数量直接决定延迟和成本。
更关键的是,过度思考有时候反而有害。模型在简单问题上生成了冗长的推理链,推理链越长,中途“想偏”的概率越高。这类错误不是知识不足导致的,而是注意力在长文本中发散导致的。所以大幅降低思考量不是牺牲性能换效率,而是同时优化精度、延迟、成本三个维度。
2. 后训练全程设计与数据工程
2.1 整体训练流程架构
整个后训练流程分四步走。
第一步是SFT阶段,用高质量思维链数据做监督微调,让模型“学会”结构化的推理和输出格式。第二步是偏好优化阶段,用DPO对齐人类偏好(完整、简洁、诚实)。第三步是思考量压缩蒸馏,这是这次训练的一个重头戏,走的是“教师模型生成标准答案 + 拒绝采样 + 长度惩罚”的路线。第四步是评测迭代,三个基准连同若干内部安全集同时跑,观察性能回退点。
训练框架选的是社区主流的分布式训练方案。序列长度控制在8192,全局batch size从128起步,学习率用余弦衰减,峰值设置在5e-6。为了控制显存占用,梯度检查点全开,混合精度用BF16。
2.2 数据配比和数据清洗细则
后训练的数据质量远比数据数量重要。整个SFT阶段大约用了十多万条精选样本。配比上,通用问答占四成,代码生成和修复占三成,数学推理占两成,剩下的留给工具调用和安全拒答模板。
清洗步骤是很多人忽略的重灾区。根据经验,最值得注意的清洗项有这几个:文本去重使用MinHash,去除和基座预训练语料高度重复的片段;编号连续性检查,有些公开数据里会让模型回答“题目2”但前面根本没有题目1,这类样本删掉;答案可验证性过滤,代码类样本必须实际编译跑过,数学类样本用规则检查答案一致性,纯文本类样本则人工抽检。
数据这部分最容易出现的错误是比例失衡。比如某个子领域数据特别多,模型会在该领域“过拟合”到分数虚高,但换一批同分布问题就露馅。这次专门控制每个子领域不超过总数据量的百分之五。
2.3 长度控制和格式约束的预处理
为什么思考量能大幅降低?很大一部分功劳来自数据预处理阶段就把“长答案”和“短答案”边界划清楚了。
具体做法是给每一条训练样本标注难度分级。简单样本要求模型直接给出答案,中间不要加推理过程;中等难度的样本允许简要推理,但限制在三步以内;复杂样本才允许完整的推理链。这个分级信号直接注入到训练样本的指令前缀里。模型在学到这个模式后,会自动对“问题难度”做出判断。
对于输出格式,统一规定思考过程放在特定标记之内,最终答案单独抽出。这样后期做推理长度压缩和评测时,可以准确统计“思考部分”的长度,而不是把回答整体当作一个字符串。
3. 训练过程与关键环节实现
3.1 SFT阶段超参配置和训练曲线
SFT阶段共跑约三个epoch,全量参数微调,没有用LoRA。因为目标是做能力增强,LoRA在这种复杂度下容易欠拟合。
训练超参数具体为:学习率5e-6,warmup比例3%,使用AdamW优化器,权重衰减系数0.05。batch size设为128,但通过梯度累积实现,单卡能跑通的场景下也更稳。显存峰值大约在110GB左右,用两张卡勉强放下,配合序列切分后训练过程没有出现OOM。
训练曲线上最需要关注的信号是loss的下降平滑度。如果出现“阶梯状下降”,大概率是数据批次里混入了大量相似难度的数据,导致模型在某个阶段突然学习某个规律。稳妥的办法是数据shuffle时加入随机种子,并且让不同难度样本在batch内均匀分布。
3.2 偏好优化如何不牺牲推理能力
DPO阶段的数据构造比SFT更繁琐。每个样本需要一组偏好对:一条理想的简洁回答,一条虽准确但冗长的回答(或包含轻微幻觉的回答)。
DPO的关键超参是beta值,用来控制模型对偏好差异的敏感程度。这次从0.1起步试,最终选定0.25。为什么不是更大?因为beta过高会让模型为了迎合偏好格式而丢失部分推理细节。观察到beta调到0.5以上时,GPQA得分出现两分左右的回退,这个代价非常不值得。
DPO数据构造有一个容易被忽略的坑:两条回答的“长度差距”不能太大。如果SFT阶段数据让模型学会“被选中的回答永远比被拒绝的回答短很多”,模型会走捷径——少说一点保平安。结果是测试集上思考量确实降了,但推理准确率也悄悄掉了。这次对长度差距做了约束,最长回答和最短回答的长度比不超过三比一。
3.3 思考量压缩:模型蒸馏和拒绝采样的组合用法
这里直接说核心操作流程。
先基于SFT版本模型做推理采样,针对每个评测问题生成N组回答。执行拒绝采样:把答案和基准答案对比,保留那些正确且长度在预期范围内的输出。这些“短而准”的回答重新作为训练样本,做第二轮微调。
具体流程是:
- 用SFT模型对全部训练问题采样,温度设为0.8,采样次数在8到16次。
- 对每个问题,用规则+评测器筛选出正确答案。规则部分覆盖代码运行、数学答案匹配;评测器用于开放式问答的语义比对。
- 在正确样本中,按长度从短到长排序,挑选前40%的样本作为下一轮微调数据。
- 第二轮微调之后重复采样和筛选。这个循环做两轮,基本能把“如何把答案说短”的技能固化到模型行为里。
这里需要特别提醒:第二次迭代采样时,模型会开始“模仿自己”的短答模式,如果第一轮筛选出的“短答”里存在语义缺陷,第二轮会被放大。所以在第二轮的评测器过滤中需要把阈值往上提,宁可丢掉一部分样本也不引入错误模式。
3.4 训练中如何守住三个基准的平衡
三个基准的平衡本质是一个多任务冲突问题。有时候模型代码能力涨了3分,但GPQA跌了1.5分,这种拉锯非常常见。
实操中用了两招来控制平衡。第一招是数据配比动态调整:每隔两三百步抽样看一次子集指标,如果某个子任务的相对准确率明显偏离目标线,就临时对该子任务的数据做几倍过采样。第二招是loss加权调制:给训练损失函数按任务类型加权——代码类任务权重设为1.2,科学推理设为1.1,通用问答设为0.9——让更难的任务获得更多优化压力。
有同学问过能不能直接用multi-task loss的权重网格搜索。这次没有用,原因是网格搜索在这三个任务上成本太高。每次完整评测需要跑几个小时,网格搜几十组不现实。动态调整配合经验判断,基本上在一轮训练内就能把平衡调到可接受范围。
4. 评测方法论与指标解读实录
4.1 三个基准的评测细节和实现方式
GPQA评测用的是固定题集,但这里有个关键细节:带CoT提示词和无CoT提示词的结果差异。后训练模型在无CoT设置下直接作答,能更真实反映模型“直觉推理”的水平;但是基准数据本身存在“被污染”的风险,即题目的官方答案和过程可能已经在预训练语料里出现过。所以评测时采用了一个保险做法:对同一题目做三次提示词变体,取最低分作为最终引用值。
MMLU评测则用的是5-shot标准格式,相对简单。唯一需要注意的是部分子集存在中文/英文混杂,需要统一处理为英文输入。LCB评测不能用纯生成模式,必须执行代码来验证输出通过哪些隐藏测试。这里的技巧是把代码补全任务和Bug修复任务分开统计,分开看分项分数。
4.2 如何判断“思考量确实降了”而不是模型变笨了
降低思考量后最让人担心的是:模型是不是通过“回避难题”来缩短回答?
排查手段有两个。第一个手段是看难度分层准确率。把所有测试问题按难度分为三档,统计各档的准确率。如果简单档准确率提升、复杂档准确率持平,说明压缩思考量的策略有效——模型优先砍掉了简单问题上的冗余推理。如果复杂档准确率也下降,就要警惕长推理能力受损。
第二个手段是看答案分布的熵值。正常情况下,压缩思考量后,模型在正确答案上的概率集中度会上升,在错误答案上的概率会更分散。如果熵值异常低且集中在某个错误选项上,模型可能产生了“盲目的自信”,这也是过度压缩的危险信号。
从这次实际数据看,思考量平均每问题下降了57%,但困难档准确率只掉了0.3分,基本在噪声范围内。这个结果可以接受。
4.3 训练过程中的指标波动和回归防线
训练中会频繁出现单个基准回升、另一个基准回退的现象。所以在训练流程中设了三条防线。
防线一是每250步做一次“快速评测”。快速评测不用全量测试集,每个子集抽两百个样本就能跑出趋势,发现某个指标连续两次下滑就暂停训练,检查数据配比。
防线二是参数检查点保留。每保存一个checkpoint就保留一个对应的评测记录。如果最终发布的版本有问题,可以迅速回退到之前某个指标均衡的版本,而不需要重新训练。
防线三是一个“特殊保留集”。专门构造了两百条“模型曾经犯错但方向正确的题目”,在每次完整评测时同时跑。如果这个集合的准确率突然上升很多,反而要提高警惕——一种可能性是模型记住了这些题目的答案而不是真的掌握了隐藏规律。这种情况下需要额外做一次把题目改写后再评测的对照。
5. 常见问题与排查技巧实录
5.1 训练显存溢出和收敛异常排查
27B全参微调的显存压力相当大。最容易踩的坑是设置了过大的batch size,导致前向传播中途OOM。建议的做法是先把batch size设为1,测出单卡能承受的最大序列长度,再按梯度累积步数反推全局batch size,而不是一上来就填一个大数值。另一个排查项是激活函数带来的额外显存开销——某些注意力实现会在长序列下申请超大临时张量。
收敛异常有两种常见表现。loss不降且震荡,通常说明学习率偏大或者数据噪声过高;loss降得很快但评测指标不动,则往往是模型在“死记硬背”训练集中的表面模式——这时候需要检查数据多样性,而不是继续加训练轮数。
5.2 评测结果和训练指标不一致怎么处理
训练loss和评测分数存在“脱钩”是后训练中的普遍现象。最典型的是SFT阶段:loss已经降到很低,但GPQA分数停在原地甚至倒退。原因多半是数据太简单,模型学到的只是输出格式而非推理逻辑。
处理方式是把SFT数据重新分层。每次从全部训练数据中抽取20%最难的样本,单独做一次微调。这个方法几乎每次都能把评测分数拉回上升通道。另一个办法是检查评测时是否关闭了采样随机性——如果评测时温度过高,或者开启随机采样,成绩会明显低于贪婪解码。评测统一设置温度为零。
5.3 多版本模型的管理和回归测试经验
跑过多轮训练后,手上可能会有几十份模型权重。如果不做管理,很快会搞混不同版本对应的训练参数。这里建议在保存checkpoint时同步保存一份完整的训练配置JSON,记录数据配比、超参、评测分数、采样参数。版本命名按“日期-阶段-评分”三位信息标记。
即使测试完的版本,也不要急着删除。有时候已经在更高版本上出现了某个问题,翻阅旧版本时能找到问题是从哪个中间版本引入的。保留每个阶段“最后一个成功的checkpoint”以及“踩坑失败的checkpoint”,对排查很有价值。磁盘压力允许的话,中段checkpoint间隔两个epoch各存一个即可。
6 最终成果的经验总结
整个项目下来,最有价值的体会是:降低思考量这件事一定和应用场景绑定来评估。脱离场景说“把思考量砍半”,其实是个伪命题。有些任务就是需要长推理,比如复杂数学证明题,你用压缩后的模型硬上,分数一定会掉。经得起考验的方式是让模型学会“按需分配”推理长度,而不是不分青红皂白地“一刀切”。
我自己后面再做类似的后训练项目,会把更多的精力放在思考量分配的调控粒度上。比如按任务类别给出不同的长度约束,或者让用户显式控制期望的详细程度。这个方向目前开源的案例还不多,但效果潜力很大。
最后再分享一个小技巧:训练完成后的最终版本发布前,别只看基准分数。拿二三十个真实业务场景的prompt过一遍,把模型回答逐条读一遍,有时候会发现基准上看不出来的问题——比如语调生硬、重复啰嗦、或者对否定形式的理解偏差。机器评测能给你一个及格分,但只有人的阅读才能告诉你这个模型“顺不顺”。