同样的输入,模型输出不稳定怎么办?

进阶高频实践约 6 分钟读完

一句话回答

不稳定主要来自三方面:采样随机性(temperature、top-p 越高越发散)、推理服务层面的数值差异(服务端批处理、GPU 浮点运算顺序不同,所以即使 temperature 为 0 也不保证完全一致)、模型版本变化。应对思路是"减少随机、约束输出、容忍差异":降低 temperature 并设置 seed(同样不保证完全一致),写更明确的指令和示例,用结构化输出和后处理校验,关键判断多次采样投票,固定模型版本,上线前做回归测试。

详细解析

随机性从哪来

  1. 采样参数:temperature、top-p 越高,越可能选到概率较低的 token,原理见 temperature 和 top-p
  2. 推理服务的数值差异:服务端会把多个用户的请求拼成批次一起计算,批次大小随负载变化,计算的分块和累加顺序也随之变化。浮点加法不满足结合律,顺序不同,结果就会有极小的差异。两个候选 token 的概率非常接近时,这点差异就可能让贪心解码选中不同的 token,之后的内容沿着不同的分支展开
  3. 模型版本变化:使用会自动指向新版本的模型别名时,厂商升级后行为可能悄悄改变
  4. 看起来相同、实际不同的输入:Prompt 里带了当前时间、顺序不固定的检索结果、多余的空格,模型看到的其实是不同的输入
  5. 指令本身含糊:多种回答都"说得通"时,概率分散在多个方向上,随机性被放大

应对手段

手段 作用 局限
降低 temperature 分类、抽取等任务设为 0 或接近 0,减少采样随机性 消除不了服务端的数值差异;创作类任务需要多样性
设置 seed 部分接口支持,尽量复现相同的采样结果 通常只承诺尽力而为,服务端配置变化后结果也会不同
更明确的指令和示例 让正确答案更唯一,从源头减少发散 需要反复迭代和测试
结构化输出、枚举值 把开放的回答变成有限的选项,见 怎么让大模型稳定地输出 JSON 只约束格式,不约束内容对错
后处理归一化和校验 统一大小写、同义词、日期格式;不合格就重试 只能处理预料到的差异
多次采样投票 取多数结果,分歧大时转人工,见 Self-Consistency 成本随次数成倍增加
固定模型版本 用带版本号的模型标识,避免被动升级 旧版本会下线,迁移前要做回归测试
缓存结果 完全相同的输入直接返回之前的结果 只适合答案可以复用的场景

把不稳定当成常态来设计

  • 测试断言输出的性质,而不是逐字比较:JSON 合法、字段齐全、分类正确、包含关键信息
  • 评测时多跑几次:同一个用例跑多次,看通过率和结果的分布,而不是只看一次的结果
  • 回归测试:改 Prompt、换模型前后,用同一个评测集对比,重点看变差的样本,见 回归测试
  • 线上监控:关注格式错误率、分类结果分布的变化,模型升级后尤其要留意
  • 把分歧当作信号:多次采样的结果不一致,说明模型对这个输入没把握,可以交给更强的模型或人工处理

代码示例

TypeScript
// 需要稳定结果的调用。参数名是通用写法,各家 SDK 不同
const res = await llm.chat({
  model: 'model-name-with-version', // 用带版本号的固定标识,不用会自动更新的别名
  temperature: 0,
  seed: 42, // 部分接口支持,只是尽量复现
  responseFormat: { type: 'json_schema', schema: LabelSchema }, // 输出限定为固定的枚举值
  messages,
})

// 上线前的稳定性检查:每个用例跑多次,统计通过率和不同结果的数量
async function stabilityCheck(cases: { input: string; expected: string }[], runs = 5) {
  for (const c of cases) {
    const outputs = await Promise.all(Array.from({ length: runs }, () => classify(c.input)))
    const passRate = outputs.filter((o) => o === c.expected).length / runs
    if (passRate < 1) {
      console.log(`不稳定的用例:${c.input}`, { passRate, distinct: new Set(outputs).size, outputs })
    }
  }
}

面试官可能追问

创作类任务需要多样性,又要质量稳定,怎么平衡?

保留适中的 temperature,让表达有变化,但用指令和结构约束框架,比如固定大纲、风格要求、长度范围。还可以一次生成多个候选,再用规则或模型按标准挑出最好的一个。

用户点"重新生成",得到完全不同的答案,算问题吗?

看场景。开放式的写作、头脑风暴,不同的答案正是用户想要的。事实类问答如果每次结论都不一样,说明模型缺少依据或指令含糊,要补充资料(RAG)、把指令写明确,并降低 temperature。

怎么在自动化测试里断言模型的输出?

用规则断言性质:JSON 能解析、字段符合 Schema、包含或不包含某些内容、长度在范围内。开放式的输出用模型按评分标准打分。每个用例跑多次,用通过率而不是单次结果判断是否合格。

模型厂商升级了模型,输出风格变了,怎么及早发现?

固定模型版本,主动迁移而不是被动升级;迁移前用评测集对比新旧版本;上线后监控格式错误率、用户反馈等指标,见 上线后怎么发现模型效果变差。

易错点

  • 以为 temperature 为 0 再加上 seed,就能完全复现
  • 测试用逐字比较,导致测试本身就不稳定
  • 使用会自动更新的模型别名,行为在不知不觉中改变
  • 指令含糊时只降低 temperature,结果只是稳定地输出同一个可能错误的答案

AI 模拟面试官

用自己的话回答,AI 对照参考答案打分、指出遗漏,再追问,最多 3 轮

登录后就可以和 AI 面试官对练,面试记录也会保存下来。登录

这道题你掌握了吗?

选一个最接近的状态,没掌握的题会出现在"我的进度 · 待复习"里。

学习记录暂存在本机浏览器。登录后自动同步到账号,换设备也能看到。