3015 字
约 10 分钟
15
S23-A03 · 模型评估与发布:离线分数到线上效果的落差

离线评测涨了 3 个点,上线后用户投诉变多——这几乎是每个模型团队都会遇到一次的落差。它不是"评测做错了",而是离线与线上量的根本不是同一件事。架构视角要做的,是把这个落差拆成可命名的来源,并在发布流程里为每个来源留一道闸。


1. 落差的五个来源

来源 机制 表现
数据分布 评测集来自旧流量或人工编写 新场景、新话术上直接退化
评测集污染 训练数据里混入了评测题 离线分数虚高,线上断崖
指标与业务错位 指标可算,但不是用户在意的东西 分数涨、留存跌
交互效应 多轮对话、上下文、工具返回改变行为 单轮评测无法覆盖
用户适应 用户学会绕过或改写提问 上线一段时间后指标缓慢下滑

五个里只有第二个是"技术错误",其余都是测量设计问题。因此对策不是更努力地调模型,而是让测量本身分层。


2. 评测集的四个要求

要求 具体做法 缺失后果
代表性 从真实流量分层抽样,标注来源与时间 分数与现实脱节
难度分层 简单/中等/困难各占一定比例,分开报 平均分掩盖困难档崩溃
标注一致性 双人标注 + 仲裁,抽检一致率 噪声大到无法判断版本差异
可扩充 按场景标签可持续追加,版本化 上线半年后评测集过期
{"id":"q-001","input":"...","reference":"...","tags":["refund","multi-turn"],"difficulty":"hard","source":"prod-2026-03","split":"golden"}
{"id":"q-002","input":"...","reference":null,"tags":["open-ended"],"difficulty":"medium","source":"synthetic","split":"dev"}

"自己造题自己考"的陷阱:出题人知道模型会怎么答,题目会不自觉地朝模型擅长的方式写。缓解手段是让出题与调优由不同人负责,并把一部分题目锁进只读的 golden 集,任何人不得用于迭代。


3. 指标的适用边界

指标 适用 失效条件
准确率 类别均衡、单标签 类别不平衡时被多数类主导
F1 / Macro-F1 需要兼顾查准查全 类别极多且样本极少时方差巨大
BLEU / ROUGE 参考译文高度相似 开放生成、允许多种正确表达
LLM-as-judge 大规模、开放式 位置偏差、长度偏好、对自家模型偏心
人工评分 小样本、高价值判断 成本高、评分者间一致性难保证

生成任务里 BLEU 类指标与人类判断的相关性通常只在"翻译/摘要且参考唯一"时成立,拿来评对话或创作类任务,等于用错的尺子量。LLM-as-judge 必须做校准:与人工评分比对若干条,确认排序一致再扩大使用;同时固定 judge 的提示与模型版本,否则指标会随 judge 一起漂移。


4. A/B 与灰度在模型场景的特殊性

特殊性 机制 应对
同一用户多次请求不一致 每次请求随机分流,同一人多轮对话被切到两个版本 按用户/会话稳定哈希分流
实验污染 用户看到旧版本输出后再评价新版本 以会话为实验单位,不跨版本续聊
指标延迟 转化、留存类指标要等数天 先看代理指标,再看终局指标
交互反馈 用户行为随界面变化,不是纯模型效果 固定 UI,只变模型
import hashlib
def bucket(user_id: str, salt: str = "exp-2026-11", mod: int = 100) -> int:
    # 稳定分流:同一用户恒定落在同一桶,跨请求一致
    return int(hashlib.sha256(f"{salt}:{user_id}".encode()).hexdigest()[:8], 16) % mod

实验单位的选择决定结论有效性:按请求分流测的是"平均输出质量",按用户分流测的是"体验变化"。两者结论经常不一致,报告里必须写清用的是哪一种。


5. 生成任务的分段评估

无唯一答案的任务,整体打分几乎没有信息量。做法是按维度拆开,各维度独立定义可判定的标准:

维度 判定方式 常见失败
事实正确性 与检索片段比对、可核查引用 看似合理但无据
完整性 是否覆盖必答子问题清单 漏条件、漏例外
格式约束 结构化解析 + 字段校验 JSON 截断、字段缺失
多轮一致性 与前文约束不冲突 自我矛盾、遗忘设定
长文连贯 分段摘要与全文主题比对 前后段落重复或漂移
{"rubric_version":"r3","dims":[
  {"name":"faithfulness","weight":0.4,"check":"every claim has a retrieved span"},
  {"name":"completeness","weight":0.3,"check":"all required_subquestions covered"},
  {"name":"format","weight":0.2,"check":"schema_valid == true"},
  {"name":"consistency","weight":0.1,"check":"no contradiction with prior turns"}
]}

分段评估的额外收益是可定位:总分掉了,能看出是事实性还是完整性,而不是只知道"变差了"。


6. 回归防护:黄金集、版本对比与显著性

三个动作缺一不可:固定黄金集、同条件跑新旧版本、判断差异是否超出噪声。

import random
def bootstrap_ci(a, b, n=2000, alpha=0.05):
    diffs = []
    for _ in range(n):
        sa = [random.choice(a) for _ in a]
        sb = [random.choice(b) for _ in b]
        diffs.append(sum(sb)/len(sb) - sum(sa)/len(sa))
    diffs.sort()
    return diffs[int(n*alpha/2)], diffs[int(n*(1-alpha/2))]   # 区间跨 0 即不显著

小样本上的 1~2 个点差异经常落在置信区间内。没有显著性判断的"提升"只是随机数,把它写进发布说明,会在下一次无法复现时透支团队信任。


7. 发布策略与版本管理

策略 能看到什么 风险
影子流量 真实输入下的输出差异,不影响用户 看不到用户反馈
小流量灰度 真实反馈与业务指标 需要稳定分流与足够样本
全量切换 + 回滚开关 速度最快 回滚窗口短,故障面大
release:
  model: gpt-x@2026-10-01      # 模型快照,不用 "latest"
  prompt: p-2026-11-03-r2      # 提示模板版本
  index: kb-2026-11-05         # 检索索引快照
  rollback_to: {model: gpt-x@2026-09-15, prompt: p-2026-10-20-r1, index: kb-2026-10-28}

可回滚的前提是三元组一起版本化。只回滚模型而索引已更新,等于换了个系统,问题往往依旧。


8. 线上监控看什么

指标 为什么看 异常信号
失败率(含超时、限流) 最先反映依赖与容量 突增且集中某模型/某地域
拒答率 安全策略或上下文缺失 与提示版本变更同步上升
人工介入率 兜底成本 缓慢上升常是先兆
每请求成本 token 与调用次数 提示变长、重试增多
输出长度分布 截断与啰嗦 长度骤降 = 截断,骤升 = 失控
用户行为代理指标 复制、重问、放弃 重问率上升是最可靠的坏信号

8.1 评测的组织成本

评测不是写完脚本就结束的事项。三类隐性成本决定它能否长期存在:

成本 来源 控制手段
标注 双人标注 + 仲裁,困难样本耗时最长 优先标注"模型分歧样本",不平均用力
评测运行 大规模跑分要消耗同等的推理与人工预算 分档运行:dev 集每日、golden 集发版前
维护 场景变化导致题目过期、口径漂移 设题集 owner,按季度复审标签与参考
发版前必跑:golden 集(只读)+ 回归集(近两版失败样本)
日常跑:dev 集(快速反馈,允许噪声)
不跑:把 golden 集塞进每次迭代——它会迅速被"过度拟合"成调优目标

判据只有一条:评测集的使用频率与它的可信度成反比。用得越频繁的集合,越容易被当作优化目标,越早失去测量能力。

9. 三个版本维度的组合爆炸

模型、提示、检索索引各自迭代,组合数是乘积。正交化的做法是一次只动一个维度,其余冻结:

变更 必须冻结 观察重点
换模型 提示、索引 输出长度、格式合规、成本
改提示 模型、索引 拒答率、完整性
重建索引 模型、提示 召回质量、引用准确率

三者同时变更时,任何指标变化都无法归因。发布记录里写明"本次只动了哪一维",比写"整体优化"有用得多。


10. 下线与回滚的判断依据

回滚应当有预设阈值,而不是开会决定:核心指标劣于基线超过置信区间、失败率超过约定上限、成本涨幅超过预算比例、或出现新类别的严重错误(如幻觉引用)。触发即回滚,事后再分析——把"是否回滚"变成判断题,通常会在争论中错过窗口。


排错

现象 常见原因 处理
离线高、线上低 评测集污染或分布不符 换新抽样集复测,检查训练数据是否含题
指标涨但用户不满 指标与业务目标错位 引入行为代理指标,重定优化目标
A/B 结论反复 按请求分流、样本不足 改按用户分流,先算所需样本量
同一用户答案风格突变 分流不稳定 用稳定哈希,锁会话
版本对比无法归因 多维同时变更 冻结其余维度,重跑对照
上线两周后缓慢下滑 用户适应、输入分布漂移 建立周期性重采样与漂移监控

边界

场景 不必做的事 理由
无评测集 直接上线 没有基线就无法判断回归,先建最小黄金集
低频任务(日均个位数) A/B 实验 样本量永远不够,改用人工抽检
内部工具、用户是同事 复杂指标体系 人工抽检 + 反馈渠道更有效
一次性批处理 在线灰度 无在线流量,改为离线对比 + 抽样复核
提示微调(改错别字级) 全量评测 成本高于风险,抽查即可

自测

  1. 五个落差来源里,哪些属于测量设计问题而非模型问题?
  2. 为什么"自己造题自己考"会系统性高估?如何缓解?
  3. BLEU 类指标在什么条件下才与人类判断相关?
  4. 按请求分流与按用户分流,测的分别是什么?
  5. 显著性判断缺失时,1~2 个点的"提升"意味着什么?
  6. 模型、提示、索引三者为何必须一起版本化?
S23-A03 · 模型评估与发布:离线分数到线上效果的落差
https://www.clxhxhhr.top/posts/6071/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。