ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

模型选型别只看准确率:用cost-per-success算总账

模型选型别只看准确率:用cost-per-success算总账

模型选型这件事,我踩过的坑比调过的参还多。早些年团队做推理服务上线,大家习惯性盯着准确率、F1、AUC 这些离线指标拍板,结果模型一上生产,账单跑得比推理速度还快——有的模型单次调用便宜但重试率高,有的模型贵得离谱却一次就过,最后算总账,离线指标最好的那个反而是最烧钱的。后来我们换了个思路,不看单次调用价格,也不看单纯的准确率,而是看“每成功完成一次任务要花多少钱”,也就是cost-per-success。这个指标一出来,很多之前的“优等生”模型立刻现了原形。这篇就围绕这个思路,把模型选型评测从“看分数”拉到“算总账”的实操层面,聊聊怎么设计、怎么算、怎么避坑。不管你是刚接触模型评测的新手,还是已经在做推理成本优化的老手,这套方法都能直接抄作业。

1. 为什么单看准确率或单价都会选错模型

1.1 离线指标与真实成本的错位

先说一个很常见的场景。假设你手上有三个候选模型,任务是把用户的一段自然语言需求转成结构化字段。离线评测集上,模型 A 准确率 92%,模型 B 88%,模型 C 85%。按传统逻辑,A 直接胜出。但上线之后你会发现,A 虽然准,但它对格式的遵循度差,经常输出多余解释文字,后处理脚本要反复清洗,清洗失败还得重试;B 准确率低一点,但输出极其规整,几乎不需要后处理;C 最便宜,但经常漏字段,重试两次才能成功。

这时候你算一笔账:A 单次调用 0.02 元,平均 1.8 次才成功一次,单次成功成本约 0.036 元;B 单次 0.015 元,平均 1.05 次成功,单次成功成本约 0.0158 元;C 单次 0.005 元,平均 2.5 次成功,单次成功成本约 0.0125 元。结果 C 最便宜,B 次之,A 最贵。离线准确率最高的 A,在真实成本维度上垫底。这就是cost-per-success要解决的核心问题:它把“失败重试”和“后处理开销”这些隐性成本显性化,让选型回归业务本质。

1.2 cost-per-success 的定义与拆解

cost-per-success 的字面意思是“每次成功完成的平均成本”。它的计算不复杂,但拆解开来有几个关键因子:

  • 单次调用成本:模型 API 的输入输出 token 计费,或者自部署时的单次推理算力折算成本。
  • 成功率:在给定任务定义下,一次调用就达到可接受结果的比例。注意这里说的是“可接受”,不是“完美”。
  • 重试次数期望:成功率越低,期望重试次数越高。如果每次重试是独立事件,期望尝试次数 = 1 / 成功率。
  • 后处理与人工介入成本:有些模型输出需要额外清洗、校验,甚至人工兜底,这部分也要摊到每次成功上。

用公式表达就是:

cost-per-success = (单次调用成本 × 期望尝试次数 + 单次后处理成本 × 期望尝试次数 + 人工介入成本) / 1

简化一下,如果后处理和人工成本可以按次估算,那么:

cost-per-success = (单次调用成本 + 单次后处理成本) / 成功率 + 单次人工介入成本 × 人工介入率

这个公式看起来简单,但每个因子的测量都有讲究,后面会逐一展开。

1.3 什么场景下这个指标最值得用

不是所有任务都适合用 cost-per-success。它最适合以下几类场景:

  • 任务结果有明确成功/失败判定:比如结构化抽取、分类、代码生成后能否通过测试、翻译后能否通过回译校验。
  • 失败可重试且重试成本可接受:如果一次失败就造成不可逆损失,那重试没意义,得看别的指标。
  • 调用量大、成本敏感:量小的时候人工兜底更划算,量大之后必须算总账。
  • 多模型候选、差异明显:候选模型在价格和成功率上各有优劣,需要统一标尺。

反过来,如果任务本身是开放式的、成功标准模糊,或者失败代价极高不允许重试,那 cost-per-success 的参考价值就有限,得结合其他指标一起看。

2. 评测集与成功判定的设计细节

2.1 评测集要贴近真实分布

cost-per-success 的准确性高度依赖评测集的质量。我见过不少团队直接拿公开 benchmark 来算,结果和线上表现差很远。原因很简单:公开集的分布和你的业务分布不一样。比如你做电商客服意图识别,公开集里可能全是标准问法,但线上用户会夹杂错别字、方言、中英混输、甚至表情符号。这些“脏输入”才是拉低成功率的主力。

所以评测集的设计原则是:从真实日志里采样,按业务分布分层。具体操作上,我会这样做:

  1. 从最近一个月的线上请求里随机采样,去掉明显异常和重复。
  2. 按任务类型、输入长度、语言风格、是否含特殊字符等维度分层。
  3. 每层至少保留 50 到 100 条,保证统计显著性。
  4. 留出一部分作为“压力集”,专门放那些边界 case,比如超长输入、多意图混合、格式极不规范。

这样算出来的成功率才有代表性。如果实在拿不到线上数据,退而求其次用业务方提供的典型样本,但一定要标注清楚这是“理想分布”,实际成本可能更高。

2.2 成功判定要可自动化、可复现

成功判定是 cost-per-success 里最容易扯皮的地方。如果判定靠人工,那成本本身就上去了,而且不同人标准不一。我的经验是:能自动判定的绝不人工,必须人工的也要定死规则。

自动判定常见手段包括:

  • 结构化校验:输出能否被 JSON 解析、字段是否齐全、类型是否正确。
  • 规则匹配:关键字段是否命中预期值,或者是否在允许的枚举范围内。
  • 回译校验:翻译任务里,把输出再翻译回去,看和原文的相似度是否超过阈值。
  • 执行校验:代码生成任务里,直接跑测试用例,通过即成功。
  • 模型辅助判定:用一个轻量裁判模型判断输出是否满足要求,但裁判模型本身也要评测过,避免引入偏差。

这里有个坑:判定标准不能太严,也不能太松。太严会导致成功率普遍偏低,所有模型看起来都很差;太松则区分度不够,选不出真正好的。我一般会先用一批样本做校准,让成功率落在 60% 到 95% 之间,这样不同模型之间的差异才明显。

2.3 重试策略对成功率的影响

成功率不是固定值,它和重试策略强相关。同样一个模型,允许重试三次和只允许一次,最终成功率完全不同。所以在评测时,必须明确重试策略,并且所有候选模型用同一套策略。

常见的重试策略有:

  • 不重试:一次调用定生死,成功率最低,但成本最可控。
  • 固定次数重试:比如最多重试两次,超过就判失败。
  • 条件重试:只在特定错误类型上重试,比如超时重试、格式错误重试,语义错误不重试。
  • 升级重试:第一次用便宜模型,失败后升级到贵模型,这种混合策略的成本要单独算。

我实测下来,条件重试在多数场景下性价比最高。因为有些失败是随机抖动,重试就能过;有些失败是模型能力不足,重试多少次都没用,反而烧钱。区分这两类失败,需要分析错误日志,看失败是否集中在特定输入模式上。

3. 成本因子的测量与计算实操

3.1 单次调用成本的精确折算

单次调用成本看起来简单,其实有不少细节。如果是调用外部 API,成本就是输入 token 数乘以输入单价,加上输出 token 数乘以输出单价。但要注意:

  • 输入 token 是否包含系统提示词:很多模型按总输入计费,系统提示词越长,单次成本越高。
  • 输出 token 的波动:同一个任务,不同模型输出长度差异很大,有的啰嗦有的简洁,这直接影响成本。
  • 缓存命中:部分平台对重复前缀有缓存折扣,如果评测时没模拟缓存,算出来的成本会偏高。

如果是自部署模型,成本折算更复杂,要摊算力、显存、电费、运维。我一般用一个简化模型:

单次推理成本 = (GPU 小时成本 / 每小时推理次数) × 平均推理时长占比

比如一张卡每小时成本 10 元,每小时能跑 3600 次,那单次约 0.0028 元。但实际中会有排队、冷启动、批处理效率等问题,所以这个值要乘一个 1.2 到 1.5 的修正系数。

3.2 后处理成本的估算方法

后处理成本经常被忽略,但它可能是大头。后处理包括:

  • 格式清洗:去掉多余文字、补全缺失括号、修正转义字符。
  • 字段校验:检查必填字段、类型转换、枚举映射。
  • 兜底逻辑:校验失败后走默认值或转人工。

估算后处理成本,我通常按“每次调用的平均后处理耗时 × 人力或算力单价”来算。如果是脚本自动处理,耗时可忽略,但开发维护成本要摊到总调用量上。如果是人工兜底,那成本就高了,必须把人工介入率单独统计。

这里有个经验:后处理成本高的模型,往往不是因为它差,而是因为它“不稳定”。稳定输出固定格式的模型,即使准确率略低,后处理成本也低,总账反而更优。

3.3 一个完整的计算示例

假设某结构化抽取任务,候选模型 X 和 Y,评测集 500 条,重试策略为最多重试两次(即最多调用三次),后处理为自动脚本,人工介入率按 2% 算,人工单次成本 1 元。

指标模型 X模型 Y
单次调用成本0.02 元0.008 元
一次成功率80%65%
二次累计成功率92%85%
三次累计成功率96%92%
平均尝试次数1.121.28
单次后处理成本0.001 元0.003 元
人工介入率4%8%

平均尝试次数怎么算?可以用加权:一次成功占 80%,两次成功占 12%(92%-80%),三次成功占 4%(96%-92%),失败占 4%。期望尝试次数 = 1×0.8 + 2×0.12 + 3×0.04 + 3×0.04 = 0.8 + 0.24 + 0.12 + 0.12 = 1.28。但这里失败也算了三次,所以更准确的是按成功样本算:成功样本里,一次成功的占 80/96,两次的占 12/96,三次的占 4/96,期望尝试次数 = (1×80 + 2×12 + 3×4) / 96 = (80+24+12)/96 = 116/96 ≈ 1.21。

模型 X 的 cost-per-success = (0.02 + 0.001) × 1.21 + 1 × 0.04 ≈ 0.0254 + 0.04 = 0.0654 元。模型 Y 的 cost-per-success = (0.008 + 0.003) × 1.28 + 1 × 0.08 ≈ 0.0141 + 0.08 = 0.0941 元。虽然 Y 单次便宜,但成功率和稳定性拖累,总账反而更贵。这个例子说明,单价低不等于总成本低。

4. 多模型横向评测的执行流程

4.1 评测前的准备工作

正式跑评测之前,有几件事必须先定下来,否则跑出来的数据没法比。第一,统一任务定义和输入格式。所有模型用同一套提示词模板,同一套输入字段,不能这个模型给详细说明,那个模型只给一句话。第二,统一输出解析逻辑。解析器要能兼容不同模型的输出风格,但判定标准一致。第三,统一重试和超时策略。超时时间、重试次数、退避策略都要一致。第四,记录完整日志。每次调用的输入、输出、耗时、token 数、是否成功、失败原因都要落库,方便后续分析。

我一般会先跑一个小规模预热,每个模型跑 20 条,检查解析器是否正常工作,判定逻辑是否有误。预热通过后再跑全量。

4.2 执行过程中的监控要点

跑评测不是提交完就等结果,中间有几个指标要盯着:

  • 调用失败率:如果某个模型大量超时或报错,可能是限流或服务不稳定,要单独标注。
  • 输出长度分布:突然变长或变短都可能是异常信号。
  • 成功率随时间的漂移:如果评测跑得久,模型服务可能有波动,最好分批跑并记录时间戳。
  • 成本累计:实时看账单,避免评测本身烧太多钱。

这里有个实操技巧:把评测任务做成可断点续跑的。因为大评测集跑起来可能几小时,中间网络抖动或服务限流很常见,能续跑就不用从头再来。

4.3 结果汇总与可视化

跑完之后,结果不能只看一个总数。我习惯按以下维度拆解:

  • 按输入类型分层:看模型在短输入、长输入、含特殊字符输入上的成功率差异。
  • 按失败原因分类:格式错误、语义错误、超时、空输出各占多少。
  • 成本构成拆解:调用成本、后处理成本、人工成本各占比例。
  • 性价比排序:用 cost-per-success 排序,同时标注成功率,避免选到“便宜但不可用”的模型。

可视化上,散点图很好用:横轴是成功率,纵轴是 cost-per-success,每个点是一个模型,越靠右下越好。这样一眼就能看出哪些模型值得进一步考虑。

5. 常见误区与避坑经验

5.1 把成功率当成固定值

很多人算 cost-per-success 时,直接拿一个历史成功率代入,忽略了成功率和输入分布、重试策略、判定标准的关系。实际上,成功率是条件概率,换个评测集、换个判定阈值,结果可能差很多。所以每次选型都要重新测,不能复用旧数据。

5.2 忽略长尾失败的成本

平均成本会掩盖长尾问题。有些模型大部分时候很便宜,但偶尔会输出超长内容,导致单次成本飙升。或者某些输入会触发无限重试,把成本拉爆。所以除了平均值,还要看P95、P99 成本,以及最大单次成本。如果长尾太离谱,即使平均值好看,也要谨慎。

5.3 评测集泄露与过拟合

如果评测集和提示词调优用的是同一批数据,那成功率会虚高。我见过团队反复在同一个测试集上调提示词,调到 95% 成功率,上线后掉到 70%。正确做法是:调优用一批数据,评测用另一批从未见过的数据,最好还有一批线上灰度数据做最终验证。

5.4 只看钱不看体验

cost-per-success 是成本指标,不是体验指标。有些模型虽然便宜,但响应慢、输出质量差,用户体感不好。所以选型时要结合延迟、输出可读性、稳定性一起看。我的做法是:先用 cost-per-success 筛出性价比达标的候选,再在这些候选里比体验指标,最后综合决策。

6. 把评测结果落到选型决策上

6.1 单模型 vs 混合策略

评测完不一定只选一个模型。常见策略是混合路由:简单输入走便宜模型,复杂输入走贵模型。这时候 cost-per-success 要按路由后的加权成本算。比如 70% 流量走便宜模型,30% 走贵模型,那整体 cost-per-success 是两者的加权平均。混合策略的关键是路由准确率,如果路由本身判断错了,把复杂输入发给便宜模型,失败重试的成本可能比直接发贵模型还高。

6.2 动态切换与灰度验证

选型不是一锤子买卖。模型服务会更新,价格会调整,业务分布会变化。我建议每季度重跑一次评测,或者当成本出现异常波动时触发重评。上线新模型时,先灰度 5% 到 10% 流量,对比 cost-per-success 和体验指标,确认无误再逐步放量。

6.3 建立成本监控看板

最后,把 cost-per-success 做成日常监控指标。看板上至少要有:整体 cost-per-success 趋势、各模型调用占比、成功率变化、失败原因分布、人工介入率。这样一旦成本异常,能快速定位是哪个模型、哪类输入出了问题。

我个人在实际操作中的体会是,cost-per-success 最大的价值不是算出一个精确数字,而是逼着团队把“成功”定义清楚,把隐性成本摆到台面上。很多选型争议,一旦把重试、后处理、人工兜底都算进去,答案往往就清晰了。另外一个小技巧:评测时不妨故意把重试次数设得保守一点,比如只允许一次,这样能更快暴露模型的稳定性差异;等选出候选后再用真实重试策略复测,效率更高。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进