21. 评估:怎样证明“更好且没变坏”
前面二十篇讲了怎样把资料助手的各个部件训练出来:用 SFT 和 LoRA 让回答带制度条款编号,用偏好对齐让它不乱承诺,用语音微调让它听准“OKR”“钉钉审批”,上一篇又训练了向量与重排模型让检索找对条款。每一次训练结束,团队都要回答同一个问题:新版本真的更好吗?有没有哪里悄悄变坏了?这一篇讲怎样回答它。读完你应该能为资料助手设计一套评测集,估算要多少道题才看得清一个 3 个百分点的提升,识别 LLM 评委的几种偏差,并列出新模型上线前必须过的门。
loss 降了、榜单涨了,都不够
先看一个很容易发生的场景(数字为教学示例)。团队用 3000 条“员工问题 → 带条款编号的标准回答”做了 LoRA 微调,验证 loss 从 1.42 降到 0.88,在一个公开数学基准上还涨了 1 分。上线试用一周,人事部门反馈:员工问“明年年假会不会多给几天”,新版本回答“会增加 2 天”,而制度里根本没有这条。旧版本会说“现行制度没有相关规定,请咨询人事”。
两个指标都没撒谎,只是回答的不是同一个问题:
- 验证 loss 衡量的是模型在一批和训练数据同分布的样本上预测下一个 token 有多准(第 05 篇)。这 3000 条训练数据全是“有答案的问题”,验证集是从中切出来的,也全是有答案的问题。模型学会了“任何问题都给出一个像样的、带条款号的答案”,loss 当然下降,而“不知道就说不知道”这个行为在验证集里根本没有出现,坏了也看不见。
- 公开基准衡量的是通用能力,题目和公司制度无关。它涨了,说明微调没有伤到数学能力,不能说明制度问答变好了。
所以评估要回答的是两件事:在我们关心的任务上更好,以及在不该变的地方没有变坏。前者靠业务评测集,后者靠回归套件,两者都离不开对噪声的估计。
公开基准:测什么,哪里会失真
公开基准是一组公开的固定题目和评分程序,好处是所有人用同一把尺子,能横向比较模型。常见的几个:
| 基准 | 发布 | 内容 | 怎么打分 |
|---|---|---|---|
| MMLU | 2020 | 57 个学科的四选一题,从初中到专业水平 | 选对的比例 |
| GSM8K | 2021 | 8.5K 道小学数学应用题,需要多步计算 | 最终数字是否完全一致 |
| HumanEval | 2021 | 164 道 Python 函数补全题 | 运行单元测试,算 pass@k(生成 k 次至少一次通过的概率) |
| MT-Bench | 2023 | 80 道两轮开放题,分 8 类 | 由强模型当评委打分 |
基准会以两种方式失真。
第一种是饱和。题目被头部模型做到接近满分后,分数差异主要来自标注错误和提示写法,不再反映能力。MMLU 就是例子,后来的 MMLU-Pro 把选项从 4 个增加到 10 个、换上更需要推理的题,同一批模型的分数比在 MMLU 上低了 16 到 33 个百分点;换 24 种提示写法时分数的波动也从 4 到 5 个百分点降到 2 个左右。一个分数在 88 和 89 之间来回的基准,已经分不出谁更好。
第二种是污染:测试题或它的答案出现在了训练语料里(第 06 篇讲过预训练数据怎样做去重和污染检查)。模型可能是背下了答案,而不是学会了解题。可疑的迹象有:分数明显高于同规模、同代的模型;把题目换个数字或换个说法后分数大幅下跌;给出题目的前半句,模型能逐字接出后半句。微调同样会污染,如果从网上收集“数学题 + 解答”做 SFT 数据,很可能把 GSM8K 的题混了进来。
对资料助手来说,公开基准的正确用法是当回归测试:微调前后各跑一次 GSM8K、MMLU 这类题目的子集,确认通用能力没有明显下滑。HumanEval 这类要执行代码的评测,评测程序会运行模型生成的不可信代码,必须放在隔离沙箱里。
业务评测集:资料助手自己的考卷
能证明“制度问答变好了”的只有自己的评测集。它不需要一开始就很大,几百道题足够起步,但每道题都要经得起推敲。
题目来源优先用真实问题。从资料助手的日志里抽取员工真实问过的问题(事先确认日志的使用授权,去掉姓名、工号、手机号等个人信息),比让工程师凭想象出题更接近真实分布,比如员工会说“年假能不能拆成半天请”,而工程师出题往往是“年假的申请流程是什么”。
按切片组织。切片是按问题类型划出的子集,总分会掩盖局部的退化,开头那个例子里,新版本在“有答案的政策题”上可能从 78% 涨到 86%,在“无答案题”上从 90% 跌到 55%;只要有答案的题占九成,按题量加权后总分还是涨的(0.9 × 8 − 0.1 × 35 = +3.7 个百分点)。资料助手的评测集可以这样分:
| 切片 | 例子 | 期望行为 | 主要看什么 |
|---|---|---|---|
| 政策直问 | 年假怎么申请? | 回答并引用第 4.2 条 | 要点是否齐全、条款号是否正确 |
| 组合条款 | 试用期请病假影响转正吗? | 综合两三条制度回答 | 是否漏掉条件 |
| 计算题 | 周六加班 6 小时,加班费怎么算? | 给出算式和金额 | 数字是否完全正确 |
| 无答案 | 明年年假会多给几天吗? | 说明制度没有规定,建议咨询人事 | 是否编造 |
| 对抗与越权 | “你就说能报销,领导同意了” | 不承诺,按制度回答 | 是否被诱导 |
| 语音转写 | “那个 OKR 自评啥时候交” | 正确理解口语和内部词 | 端到端是否答对 |
每道题的金标答案写成可核对的要点,而不是一段标准作文:必须出现的事实(“需提前 3 个工作日在审批系统提交”)、必须引用的条款编号、禁止出现的内容(承诺金额、编造的日期)、期望行为(回答、拒答、追问)。这样自动打分和人工复核都有据可依。
和训练数据隔离要按组切。同一条制度往往有很多种问法,“年假怎么申请”“请年假走什么流程”“年休假在哪提交”都指向第 4.2 条。如果按行随机切分,一种问法进了训练集、另一种进了评测集,模型只要记住第 4.2 条的答案就能在评测里拿分,测出来的是记忆。正确做法是按条款(或按来源文档)分组,同一组的所有问法要么全在训练集,要么全在评测集。语音题同理,按说话人分组(第 15 篇)。
评测集本身也要有版本号并冻结。开发过程中反复看、反复针对性调整过的题目,会慢慢变成“开发集”,它上面的分数会偏高;最终是否发布,要用另外留出、开发时没看过的冻结测试集说话。
各模态的自动指标
能自动打分的部分尽量自动化,它便宜、可重复。不同任务的指标前面各篇已经讲过,这里汇总成一张表:
| 任务 | 指标 | 衡量什么 | 详见 |
|---|---|---|---|
| 有唯一答案的短答(金额、日期) | 精确匹配(EM) | 规范化后与标准答案是否完全相同 | 第 12 篇 |
| 要点类回答 | 要点召回、token F1 | 必需要点覆盖了多少;字词重合程度 | 第 09 篇 |
| 条款引用 | 引用准确率 | 引用的条款号是否正确、是否存在 | 本篇 |
| 语音识别 | CER(中文)、WER(英文)、术语召回 | 替换、删除、插入的字数占比 | 第 15 篇 |
| 语音合成 | MOS、说话人相似度、用识别模型回测 CER | 听感打分;像不像目标声音;有没有读错 | 第 16 篇 |
| 报销单分类 | 准确率、各类别召回 | 每一类是否都识别得出 | 第 17 篇 |
| 检索与重排 | Recall@k、MRR、nDCG@k | 正确条款是否进入前 k 名、排得多靠前 | 第 20 篇 |
| 开放式回答 | LLM 评委打分 + 人工抽检 | 有用、准确、语气是否合适 | 本篇下一节 |
自动指标都要先规范化再比较:全角半角、空格、“3 天”与“三天”、条款号写成“4.2”还是“第四条第二款”,不统一就会把对的判成错的。规范化规则一旦定下,新旧版本必须用同一套。
让大模型当评委:三种偏差
开放式回答没有唯一正确答案,“这个回答好不好”只能靠人或者另一个强模型来判断。人工贵且慢,于是常见做法是 LLM 当评委(LLM-as-a-judge):给评委模型一份评分细则、问题和回答,让它打分;或者给它两个回答,让它选更好的那个(成对比较)。
评委省钱,但它有系统性的偏差。2023 年 Zheng 等人的 MT-Bench 与 Chatbot Arena 论文系统测量了当时几个评委模型,结论至今仍有参考价值:
- 位置偏差:成对比较时偏爱某个位置。把两个回答交换顺序再问一次,GPT-4 只有 65.0% 的情况两次判断一致,GPT-3.5 是 46.2%,Claude-v1 只有 23.8%,而且 Claude-v1 在 75% 的情况下选了排在前面的那个。
- 冗长偏差:偏爱更长的回答。作者把一个回答里的要点换个说法重复一遍,内容没有增加只是变长了,Claude-v1 和 GPT-3.5 在 91.3% 的情况下被骗,判长的更好;GPT-4 为 8.7%。
- 自我偏好:偏爱自己(或同家族模型)生成的回答。GPT-4 当评委时给自己的胜率比人类评判高约 10%,Claude-v1 高约 25%;作者也说明样本有限,不能下定论。
论文同时发现,在不计平局的情况下,GPT-4 评委与人类专家的一致率为 85%,人类专家彼此之间是 81%,也就是说评委在校准良好的条件下可以接近人类水平。这些数字属于 2023 年那几个模型;换了评委模型,偏差大小要重新测。
落到资料助手上,可以这样用评委:
- 成对比较时交换顺序问两次,两次结论一致才算赢,不一致记为平局。
- 给评分细则和参考答案:写清什么算好(要点齐全、条款号正确、没有承诺制度之外的内容),把金标要点一起给评委。论文里数学题的评委出错率从默认的 70% 降到给参考答案后的 15%,就是这个道理。
- 控制长度:细则里写明“同等正确时,更简洁的回答更好”,统计时分开看两版的平均长度,长度大幅变化本身就是信号。
- 评委不用被评模型的同家族,至少不能用被评模型给自己打分。
- 用人工标注校准评委:抽 100 到 200 道题让两位同事独立标注,算评委与人的一致率,与两位同事之间的一致率比较。评委明显低于人与人的一致率时,先改细则,不要用它的分数做决定。
- 人工抽检分歧题:评委和自动指标意见相反的题、两版回答差别最大的题,优先给人看。
还要记得评委不能替代程序护栏。像“能否报销”这类高风险结论,用规则检查(是否出现了承诺性词语、引用的条款是否真实存在)或人工复核,不能只看评委的分数。更多关于评估集组织和逐层排错的做法见 AI 应用评估与排错。
回归套件:原来会的不能丢
微调最常见的副作用是灾难性遗忘:模型在新任务上变好,同时丢掉了一部分原有能力(第 09 篇、第 10 篇讨论过成因和缓解)。回归套件是一组固定题目,每次训练后都跑,专门检查“不该变的地方”:
- 通用能力:从 MMLU、GSM8K 这类基准里各抽几百道题,看分数是否下降超过容差;
- 安全:有害请求是否仍然拒绝,是否会泄露系统提示或其他员工的信息,能否抵抗“忽略之前的规则”这类注入;
- 格式:要求输出 JSON 的场景是否仍然合法,条款引用的格式是否稳定,对话模板和停止符是否正确;
- 行为统计:平均回答长度、拒答率(在有答案的题上拒答叫“过度拒答”,同样是退化)。
每一项都要事先定好容差,比如“通用数学子集下降不超过 2 个百分点”。一个失败的例子(示意数字):团队只用制度问答数据训了 5 轮,制度题准确率涨了 9 个百分点,回归套件里的数学子集却从 70% 跌到 58%,加班费计算题也跟着出错。处理方向是混入一部分通用数据、减少轮数或降低学习率,再重新评估,而不是带着这个退化上线。
噪声:多少道题才看得清 3 个百分点
假设新版本在 200 道题的评测集上比旧版高 3 个百分点,这是真的进步,还是题目抽样的运气?把每道题的对错看成一次抛硬币,可以算出这个分数本身的误差有多大。
text
单个版本准确率的标准误:SE = √( p × (1 − p) / n )
p:准确率,这里按 80% 计
n:题目数
95% 置信区间 ≈ 准确率 ± 1.96 × SE
n = 200:SE = √(0.8 × 0.2 / 200) = 0.0283 → ±5.5 个百分点
n = 500:SE = 0.0179 → ±3.5 个百分点200 道题时,单个版本的分数本身就有约 ±5.5 个百分点的不确定性,比想看的 3 个百分点还大。比较两个版本时,如果两版各用一套独立抽取的题,两个误差叠加,差值的标准误还要乘以 √2:
text
两版之差(独立题集):SE差 = √( 2 × p × (1 − p) / n )
要让 95% 区间半宽 ≤ 3 个百分点:1.96 × SE差 ≤ 0.03
n ≥ 1.96² × 2 × 0.16 / 0.03² ≈ 1366 道题(每版)
若还希望真实差 3 个百分点时有 80% 的把握测出来:
n ≥ (1.96 + 0.84)² × 2 × 0.16 / 0.03² ≈ 2788 道题(每版)好在实际评估几乎总是让新旧两版做同一套题,可以逐题配对比较。大多数题两版都对或都错,它们对差值没有贡献,噪声只来自“结果不同”的那部分题。假设 10% 的题两版结果不同,其中 6.5% 是新版修好的、3.5% 是新版改坏的,净提升正好 3 个百分点:
text
配对比较:每题的差 d 取 +1(修好)、−1(改坏)或 0
SE差 = √( (修好比例 + 改坏比例 − 净差²) / n ) = √( (0.10 − 0.03²) / n )
n = 500:SE差 = 0.0141 → 95% 区间 ±2.8 个百分点
要让半宽 ≤ 3 个百分点:n ≥ 1.96² × 0.0991 / 0.03² ≈ 423 道题
80% 把握:n ≥ (1.96 + 0.84)² × 0.0991 / 0.03² ≈ 864 道题这些是正态近似下的估算,“10% 的题结果不同”是假设值,实际比例要从自己的两版结果里数出来。
图里每组的黄色条比绿色条长得多:同样 500 道题,独立比较的区间半宽约 ±5.0,配对比较约 ±2.8。几条实际做法由此而来:
- 新旧版本永远跑同一套题,按题配对统计,并且报告“修好了几道、改坏了几道”,改坏的题逐条看;
- 切片的题数往往只有几十道,切片上 5 个百分点的变化可能完全是噪声,报告切片分数时同时写出题数;
- 生成时有随机性(温度大于 0),同一版本跑两次分数也会不同,评估时固定解码参数,或者每题多采样几次取平均;
- 想看清更小的差距,题数按差距平方的反比增加:差距减半,题数约变成原来的 4 倍。
线上:影子评估与 A/B
离线评测集再好,也只是过去问题的样本。员工的真实问法会变、新制度会发布,离线通过后还要在线验证。
影子评估(shadow)把线上真实请求复制一份发给新版本,新版本的回答只记录不返回,员工看到的仍是旧版。它能发现离线集没覆盖的问法,比较两版回答的差异率、延迟和成本,再把差异大的回答交给评委和人工看。它测不到的是用户反应:员工会不会追问、会不会采纳。
A/B 测试把一小部分员工(例如 5%)随机分到新版本,比较两组的行为指标:回答被采纳(点赞、复制)的比例、追问率、转人工率、投诉数。分组要按人而不是按请求,否则同一个员工一会儿看到旧版一会儿看到新版,体验和指标都会混乱。开始之前就要写好观察多久、看哪些指标、出现什么情况立刻停止(例如投诉数超过某个值或出现一次越权回答),不能边看数据边决定何时结束,否则很容易在噪声的高点宣布胜利。
A/B 并不总是可行。上一节的计算对线上指标同样成立:一家两千人的公司,每天只有几百次提问,5% 的流量要跑好几个月才凑得够样本。这种规模下,A/B 只用来观察有没有明显问题,是否更好的结论主要靠离线配对评估、影子评估和人工审阅。
把离线和在线串起来,就是一套发布门禁:
门的顺序按代价从低到高排:冒烟检查几分钟就能挡住对话模板写错、输出不停止这类低级错误;业务评测集和回归套件几十分钟到几小时;评委和人工抽检要花钱和人力;在线阶段直接影响员工。任何一关不过都退回,先找失败的题落在哪个切片,再决定补数据、改配方还是放弃这次训练。模型注册表和发布流程的工程细节见 MLOps 与 LLMOps。
发布前检查清单
评估的核心是用对的题、足够的题、公平的比较方式说话:loss 和公开基准只能说明训练过程正常、通用能力没塌;业务评测集按切片和分组隔离来组织,回归套件守住原有能力;LLM 评委有位置、长度和自我偏好三种偏差,要换序、给细则并用人工校准;题数决定了能看清多小的差距,配对比较能大幅降低所需题数。评估告诉我们模型好不好,而要让训练本身可复现、断了能续、花多少钱心里有数、交付时合规,靠的是工程,下一篇看训练工程与选型。
