2363 字
约 7 分钟
19
S22-A14 · 模型切换的成本:换一个模型要改多少

一个系统最初用某个模型跑分类任务,后来因为成本上涨要换成更便宜的小模型。评估阶段只看了一件事:准确率掉了两个百分点,能不能接受。结论是能接受,于是准备切换。真正开始改的时候,发现提示词里有一堆为该模型调过的措辞、输出格式的解析依赖它的某种习惯、错误重试策略按它的超时特性设计——改动量远超预期。

模型不是可替换的组件,它更像一个行为特性未知的外部服务:同样的接口,行为不同。所以"换模型"这件事的成本,主要不在接口层,而在那些围绕旧模型行为建立的隐性适配。


1. 切换的三种范围

范围 改动 风险
单点替换(同一提示词换模型) 只改配置 中(行为差异未测)
适配替换(改提示与解析) 提示词、解析、重试 高
架构替换(改流程与分工) 拆成多步、换调用结构 最高

判断自己在做哪一种,有个很直接的检查:把模型名换成另一个字符串,看有多少处需要改。只有一处(配置),是第一种;超过三处,说明适配已经分散在代码里。

多数团队以为自己在做第一种,实际上做的是第二种——因为提示词、解析代码、重试参数都是围绕旧模型写的,而它们散落在代码里,不在"模型配置"这个可见的位置。

2. 提示词里的隐性绑定

绑定形态 例子
措辞习惯 "请用简洁的短句回答"(某模型需要,另一个会过度省略)
格式诱导 "只输出 JSON,不要有其它文字"(某模型能遵守,另一个会加前缀)
示例数量 给三个示例才稳定(换模型可能一个就够,或更多)
分隔符偏好 用 ### 分段
拒绝触发词 某些措辞会触发额外审查

第二项最容易造成线上故障:解析器假设"输出是纯 JSON",而新模型在 JSON 前加了一句"好的",整个链路解析失败。这类失败在测试集上可能只出现一两次,上线后放大到几个百分点。

这三项验证可以写成一个小脚本,跑两百次调用统计分布:

// 换模型前的分布验证:格式、长度、失败率
for i in $(seq 200); do
  curl -s "$API" -d "{\"prompt\": \"$PROMPT\"}" | jq -r '.text' >> out.txt
done
grep -c '^{' out.txt           // 纯 JSON 的行数
awk '{print length}' out.txt | sort -n | awk '{a[NR]=$1} END {print "p50:",a[int(NR/2)],"p99:",a[int(NR*0.99)]}'
grep -c '^$' out.txt           // 空输出数量
// 换模型前必须验证的三件事
1. 输出格式的稳定性:连续 200 次调用里,纯 JSON 的比例是多少
2. 长度分布:输出长度的分布是否与旧模型接近(影响下游截断)
3. 失败模式:超时、截断、空输出的比例分别是多少

3. 重试与超时参数需要重估

参数 旧模型下合理 换模型后可能失效
超时 按旧模型的 P99 设 新模型更慢则频繁超时
重试次数 按旧模型的抖动设 新模型限流更严则无意义
并发上限 按旧模型配额设 新模型配额更小
退避策略 按旧模型的错误码设 错误码含义可能不同

第一项最实际:超时值是围绕旧模型的响应分布设的,换模型后这个分布变了,超时值就变成了随机丢弃请求的装置。

// 换模型时参数要重新标定,而不是沿用
model:
  name: "MODEL_NEW"
  timeout_ms: 12000          // 按新模型 P99 × 1.3 重算,不要沿用旧值
  max_concurrency: 8         // 按新模型配额上限的 70%
  retry:
    max_attempts: 2
    backoff_ms: [300, 900]   // 按新模型的限流响应调整

4. 成本账要按"任务"算而不是按"token"算

计价方式 容易忽略的部分
按 token 重试与失败调用的 token 也算钱
按任务 需要成功率才能折算
按成功任务 最接近真实成本

第三种最有用:同样完成一个任务,不同模型需要的步数与重试次数不同,按 token 单价比较会得出错误结论。一个单价更低但需要两次重试的模型,实际成本可能更高。

// 单任务成本的三项
成本 = (首次调用 token 成本 + 重试 token 成本 + 工具/检索成本) / 成功率
// 只比较第一项,会系统性低估"不稳定但便宜"的模型

切换时间点的选择也有讲究:不要与其它变更同期做。模型切换会同时改变延迟、格式与成本三个维度,如果同时上线了别的功能,任何异常都无法归因。

5. 灰度切换的方式

方式 作用 风险
按流量比例分流 对比两模型表现 需要双份配额
按任务类型分流 低风险任务先切 效果代表性有限
影子调用(只记录不采用) 收集差异样本 成本翻倍
直接切换 快 无退路

影子调用还有一个副产品:差异样本本身就是回归测试集。把影子期间发现的典型差异保存下来,下次换模型时直接用这套样本做验收,比重新设计测试集可靠得多。

第三种在"不确定差异在哪"时最有用:两个模型都调用,只用旧模型的输出,同时记录两者的差异。跑几天就能拿到真实的差异分布,而不是靠离线测试集。

6. 排错:五种"换了模型效果变差"

现象 成因 处理方向
解析失败率上升 输出格式不稳定 加宽容解析或强格式约束
延迟变高 超时与并发参数未重估 按新模型分布重设
成本没降 重试次数增加 按成功任务成本重算
某些任务变好、某些变差 任务类型差异 按类型分流
输出内容风格变了 提示词绑定旧模型 重写提示并复测

分类型评估的最小做法是给每个子类单独设阈值,而不是共用一个总分:

// 子类评估表:只有全部子类达标才允许切换
category        old_acc   new_acc   threshold   pass
退款咨询        0.92      0.90      ≥0.88       yes
物流查询        0.88      0.94      ≥0.88       yes
投诉升级        0.85      0.71      ≥0.85       NO      ← 平均被掩盖的下降
整体            0.89      0.88

第四项常被忽略:整体准确率没变,不代表每个子类都没变。某个子类可能大幅改善,另一个大幅下降,平均下来互相抵消。所以切换评估要按子类看,而不只看总分。

7. 边界:什么情况可以简单替换

场景 为什么 做法
结构化抽取(格式约束强) 行为差异小 直接替换 + 抽样验证
内部试验、无外部用户 失败代价低 直接换
已有严格输出校验与重试 差异被兜住 换后观察错误率
任务极简(分类、路由) 对模型能力要求低 用小模型,成本优先

还有一条与组织有关的边界:切换决策应当由"承担失败后果的人"签字。评估者往往看到的是准确率,而承担后果的是客服、是业务方。让后者确认"这个子类的下降我能接受",比让前者解释平均分更有意义。

判断口径一句话:围绕旧模型的行为,我写了多少适配代码。几乎没有,替换是配置问题;写了不少,替换就是一次改造项目。


8. 自测

  1. 为什么说模型"不是可替换的组件"?成本主要落在哪一层?
  2. 提示词里的隐性绑定有哪五种形态?哪一项最容易造成线上故障?
  3. 超时值为什么必须在换模型后重算?沿用的后果是什么?
  4. 为什么按 token 单价比较会系统性低估某些模型?单任务成本的三项是什么?
  5. 影子调用解决了什么评估问题?它的代价是什么?
  6. "整体准确率没变"为什么可能掩盖严重问题?评估应该按什么维度看?
S22-A14 · 模型切换的成本:换一个模型要改多少
https://www.clxhxhhr.top/posts/6423/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。