跳到主要内容

Shadow Replay 会惩罚那些本可以改变对话走向的模型

· 阅读需 11 分钟
Tian Pan
Software Engineer

我在上季度合作的一个团队将一个新模型部署到了影子回放(shadow replay)中,结果发现其针对现有模型的胜率仅为 47%。同样的提示词,同样的检索,而该模型在厂商自带的评估中明显排名更高。影子测试框架获取了上周的生产流量,将其通过候选模型运行,把两者的响应都交给 LLM 裁判进行打分,最后宣布这次升级基本上就像掷硬币一样。团队当时差一点当场就回滚了。

问题不在于模型。问题在于回放中的每一条用户消息都已经受限于旧模型的上一轮对话。候选模型在第一轮写出了更好的回答,但日志中的用户是针对一个已不再存在的不同回答做出的回应,从第二轮开始,裁判评估的其实是一段根本没有发生的对话。一个真正更好的、能够改变用户后续行为的模型,是无法与已有的基准真相(ground truth)进行对比评分的。回放机制在潜移默化中奖励了那些停留在旧轨迹上的行为。

这并不是一个新问题。推荐系统社区已经在“离线策略评估”(off-policy evaluation)的名义下为此苦恼了十五年。现在的 LLM 团队在没有查阅相关文献的情况下正在重新发现这一点,并因此从他们的影子仪表盘中得出了错误的结论。

每一个回放测试框架中的沉默假设

影子回放的宣传极具诱惑力。你已经拥有了流量,拥有了延迟数据、Token 成本以及用户反应。既然你可以在凌晨三点花点推理费重走一遍历史,为什么还要冒着风险运行线上实验、支付将真实用户路由到新模型的成本,并等待两周来观察统计显著性呢?

这里隐藏的假设是:记录的用户行为是请求本身的属性,而非对话的属性。这个假设仅在一种情况下成立:即每个请求都是独立的,且模型的输出不会影响接下来的输入。垃圾邮件分类器、单次翻译、针对固定语料库的内容审核调用——这些都可以被真实地回放,因为下一个输入不受当前输出的影响。无论模型说了什么,标签(label)都是真实的。

任何具有交互性的应用都会打破这一点。比如一个编程助手,它的第一个建议会决定用户接下来打开哪个文件;一个客服代理,它的澄清式提问决定了第二轮对话是进一步跟进还是挫败后的重复;或者一个搜索优化循环,用户下一次的查询反映了上一次的结果集。在这些例子中,记录的第二轮对话都是旧模型第一轮输出的函数。替换掉第一轮,第二轮就变成了过时的残骸。你正在根据数据中根本不存在的“反事实”(counterfactual)场景对候选模型进行评分。

这正是导致 LLM 裁判结果产生误导的原因。裁判正在将候选模型的响应与一段已经失去意义的已记录用户回复进行对比。如果候选模型提出了一个更敏锐的澄清问题,那么记录中的“是的,选方案 B”就变成了噪音。裁判看到了不匹配,从而给候选模型打了低分。在旧模型从未真正做对的一轮对话中,裁判却给旧模型加了一分。

多轮对话是数学失效的地方

单轮回放存在偏差,多轮回放则完全崩塌。

一个合理的单轮案例是这样的:用户输入一个问题,模型回答,用户点赞或发起一个新的工单。如果候选模型生成了不同的答案,你不知道用户是否还会点赞,但至少下一个请求完全来自一段不同的对话。偏差受限于响应塑造下一个问题的频率,对于事务性流量,这个界限是很小的。

多轮对话摧毁了这一界限。一旦候选模型的第一轮对话与日志不同,追踪记录中的后续每一轮都是从一个不存在的分布中采样的。日志中的用户当时是在对另一个模型做出反应。他们的第二轮对话无法在候选模型上回放,除非你做出以下两个糟糕的选择之一:要么给候选模型喂入旧助手的回答(但这在当前运行中从未发生,所以你测量的是不连贯的东西);要么让候选模型生成自己的第二轮回复,并重新提示已记录的用户消息(但这现在已经不再匹配,因为第一轮已经分叉了)。

模仿学习中的协变量偏移(covariate shift)问题描述的正是这种动态。轨迹开始时的微小误差会不断累积,状态分布偏离训练分布,而新区域的行为是无法测量的。回放评估是离线评估的镜像:即使有一个完美的候选模型,一旦你离开记录的轨迹,你就没有可以评分的标签了。研究智能体展开(agent rollouts)的研究人员现在花费大量精力缓存执行前缀,并在“行为显著”的决策点进行分支,只是为了让多轮评估变得可行。如果你在没有这些机制的情况下运行多轮回放,你不是在做离线评估——你是在针对无关数据进行“凭感觉测试”(vibes check)。

坦白说:任何候选模型在第一轮就与原记录不同的多轮回放,都只是带额外噪音的单轮评估。请以此类推。

重放究竟能很好地衡量什么

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates