大模型微调综述 评估微调的性能与效果

模型与算力

给做微调的研究者一套可落地的评测指标与方法体系,讲清评什么、怎么测、什么情况下结论不成立。

微调跑完之后最容易犯的错,是只看 loss 曲线下降就宣布成功,或者拿一份自己随手写的测试集算出个漂亮分数就上线。真实场景里卡住的地方通常是:不知道该看哪些指标、测试集和训练集串了味、指标涨了但人用起来还是不行。这篇把评测拆成可执行的动作顺序:先定评测目标,再选指标组合,最后做人工与线上校验,顺带说清哪些结论在什么条件下不成立。

微调跑完的那一刻,很多人第一反应是看 loss 曲线——降了就当成功,没降就继续加数据。但 loss 只能说明模型在训练分布上拟合得更紧了,它不回答「用户拿去用会不会满意」这个问题。评测这件事必须提前设计,而不是训完再补。

这篇不重复讲微调方法本身,只聚焦一件事:微调完之后,怎么用一套可执行的指标和方法体系,判断这次微调到底有没有用、有多大用、在什么条件下结论不成立。先说结论:评测目标定不清,后面算多少指标都是浪费算力。

先定评测目标,再谈指标

很多研究者拿到微调任务就开始选指标,这是倒过来的。第一步应该把微调目标拆成三类:能力对齐(模型会不会做这件事)、格式服从(输出结构、字段、语言对不对)、边界收敛(该拒答的时候能不能拒答)。三类目标对应完全不同的指标组合,如果混成一个总分,涨的那部分会掩盖崩的那部分。

定目标的同时必须定基线。基座模型的原始输出、纯提示词工程版本、RAG 版本,都应该在同一个测试集上跑一遍。没有基线,你说「提升了」就没有参照物,这类结论在评审或上线评审时基本站不住。

  • 能力对齐类任务:重点是任务指标(分类召回、字段准确率、编译通过率),不是困惑度
  • 格式服从类任务:重点是结构化输出的字段级校验,别只看整体语义相似度
  • 边界收敛类任务:拒答率和过度拒答率要分开看,混在一起会得出完全相反的结论
  • 什么情况下不适用:任务答案不唯一(开放文案、主观问答)时,不要拿精确匹配类指标做主判据,它会把合理变体判成错

指标分三层:自动指标、任务指标、行为指标

自动指标是最省事的一层,困惑度、BLEU/ROUGE 类 n-gram 重叠度、句向量语义相似度都属于这层。它们跑得快,适合做回归筛。但这层的共同问题是:在长文本和生成式任务上,它们和人工评价的相关性偏弱,分数接近时根本分不出好坏。所以自动指标只能当快速回归用,不能当最终结论。

任务指标必须落到具体动作上。分类任务看混淆矩阵和各个类的召回,抽取任务看字段级准确率和漏抽率,代码任务看能不能过编译和单测,客服任务看是否命中正确的知识条目。这层指标算起来麻烦,但它才是离业务最近的一层。

指标层典型指标适用场景不适用的情形
自动指标困惑度、重叠度、语义相似度训练回归、快速筛选版本长文本生成、开放问答做主判据
任务指标字段准确率、各类召回、编译/单测通过率有明确输入输出的任务答案不唯一的主观任务
行为指标拒答率、过度拒答率、长度漂移、语言漂移上线前必测、安全场景只测单轮短输入时容易漏掉

行为指标是最容易被忽略的一层。拒答率、过度拒答率、输出长度漂移、重复率、语言漂移,这些不在常规评测表里,但微调之后经常出问题——比如该答中文的时候突然答英文,或者简单问题也触发拒答。这层要单独测,并和基线对比。

每类指标都要记两个数:全量集的均值,以及最差子集的表现。均值漂亮但某个子集崩掉,是微调最常见的翻车方式,只看均值会完全看不见。具体同类项目的指标口径可以到站内 /benchmarks/registry 对照当时的记录。

测试集卫生:不干净的话后面全是白算

测试集泄了,后面算出来的所有指标都不可信。去重要做两遍:一遍在测试集内部去重,一遍在训练集和测试集之间去重。而且要做近似去重而不是只做完全匹配——数据改写过的样本同样算泄漏,只靠字符串完全匹配抓不出来。

  1. 第一遍:测试集内部近似去重用相似度阈值筛一遍,把语义上等价的样本合并。验证方式:抽几条合并前后的样本人工看,确认它们确实是同一个问题而非只是表述接近。
  2. 第二遍:训练集与测试集交叉去重对每条测试样本在训练集里做近邻搜索,超过阈值的直接标记出来。验证方式:把命中列表打印出来人工审一遍,不要盲目全删,有些相似但答案不同的样本可以保留。
  3. 第三遍:来源分层留一部分和训练数据来源不同、写法风格也不同的样本做域外测试集,专门测泛化。验证方式:对比同分布测试集和域外测试集的指标差距,差距过大说明模型在背训练数据。
  4. 第四遍:锁定测试集一旦测试集定稿,不要再拿它调提示词或调超参,否则它就变成验证集了。验证方式:给测试集文件打上只读标记,需要调参时另开一份验证集。

规模和分布要匹配判断用途。想看趋势,几十到上百条就能看出方向;想下结论说某个配置更好,就需要更多样本,具体条数按任务方差来定,同类项目常用口径可以到 /stacks/fine-tuning 参考。测试集数量不够时,指标之间的差异可能只是噪声,这种时候不要下「谁更好」的结论。

人工评估与线上验证怎么补位

自动指标和任务指标都没问题,人用起来还是不满意——这种情况非常常见。人工评估要解决的是「可用性」这个维度。做法上至少要双人标注并算标注者一致性,只有一个人打分的结论只能算个人印象,写进报告会被质疑。

  • 评分表拆细:把「事实错误」「格式错误」「可用但需修改」「可直接用」分开打,别用一个笼统的五分制
  • 盲评是对比方案的唯一可信做法:把基座、微调、提示词版本打乱顺序去掉标识再评
  • 评的人如果知道哪个是自己训的,评分会系统性偏乐观,这不是主观态度问题,是已知的偏倚
  • 线上先看行为代理指标:采纳率、修改率、二次追问率、人工接管率,这些比主观好评更早暴露问题
  • 什么情况下人工评估不适用:如果评测者不是真实目标用户,结论只能说明「外行看不出问题」,不能说明任务成功率达标

人工评估不能替代线上验证,两者看的东西不一样。人工评估看单条输出质量,线上验证看整条链路里模型是不是真的被用上了、被采纳了。上线后的行为信号建议固定周期回看,具体的行为指标监控口径可以到 /tools/speed-test 一类站内工具页了解当时的做法。

回归清单与发布判定

每次微调版本都要跑一份固定不变的「不退化测试集」,覆盖通用能力、安全拒答、多语言、长输入这些维度。这份测试集的目的不是看提升,而是盯有没有把原来的本事练废——也就是灾难性遗忘。很多微调版本在一个任务上分数涨了,但在通用问答上明显变差,问题就出在没跑这份回归集。

发布判定的顺序建议是:先过不退化测试集,再看任务指标是否超过基线,再核对行为指标无异常,最后才看人工评分。顺序不能反,反过来会出现「人工评分不错但通用能力崩了」的情况还被放上线。

判定环节看什么不通过怎么办
不退化测试集通用能力、安全拒答、多语言、长输入是否明显掉直接打回,不进入下一环节
任务指标 vs 基线目标任务的指标是否超过基线和提示词版本调整数据构成或训练配置重跑
行为指标拒答率、过度拒答率、长度漂移、语言漂移定位是数据问题还是训练问题
人工评分双人盲评的可用性分布只有前三项都通过才看这步

实验记录也要跟上。每次微调结果对数据构成极其敏感,没有数据版本和训练配置的记录,后面出了问题既无法复现也无法归因。建议把数据快照、配置、评测结果绑定成一条记录存档。具体基准数字和训练配置口径,到站内 /benchmarks 与 /training 看当时的记录。

单次跑分峰值、个别案例的惊艳输出、训练 loss 的下降曲线,这三样都不能作为发布依据。

最后补一句判断标准:如果一次微调的结论无法在另一份从未看过的测试集上复现,那这个结论就只是对当前测试集过拟合的结果,不要写进正式报告。评测的价值不在于算出一个好看的数,而在于告诉你这个数在什么条件下会失效。

下一步把评测目标、指标组合和回归清单落成一张团队模板,再对照站内同类项目的指标口径校准一遍。

常见问题

微调效果好不好,光看 loss 曲线行不行?

不行。loss 下降只说明模型在你给的数据分布上拟合得更紧,和实际任务表现没有稳定对应关系,过拟合时 loss 还在降但泛化已经在退化。正确做法是把 loss 当训练监控信号,最终判断放到独立测试集的任务指标加人工盲评上。

测试集要多大规模才够下结论?

没有统一答案,取决于任务方差和你要区分的差距。判断思路是:先跑一遍看指标波动范围,波动大就需要更多样本,想区分很小的差距需要的样本量会成倍上升。具体同类项目的常用口径可以去站内 /benchmarks/registry 和 /stacks/fine-tuning 对照。

微调后通用能力变差了怎么办?

这是灾难性遗忘,属于预期内的代价,关键是有没有提前设好底线。建议固定一份覆盖通用问答、安全拒答、多语言、长输入的不退化测试集,每次训练都用同样方式跑,一旦某项跌破你能接受的水平就回退,同时考虑降低学习率、减少训练轮次或混入一部分通用数据。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。