模型选型别只看准确率:用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 来算结果和线上表现差很远。原因很简单公开集的分布和你的业务分布不一样。比如你做电商客服意图识别公开集里可能全是标准问法但线上用户会夹杂错别字、方言、中英混输、甚至表情符号。这些“脏输入”才是拉低成功率的主力。所以评测集的设计原则是从真实日志里采样按业务分布分层。具体操作上我会这样做从最近一个月的线上请求里随机采样去掉明显异常和重复。按任务类型、输入长度、语言风格、是否含特殊字符等维度分层。每层至少保留 50 到 100 条保证统计显著性。留出一部分作为“压力集”专门放那些边界 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 (802412)/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 最大的价值不是算出一个精确数字而是逼着团队把“成功”定义清楚把隐性成本摆到台面上。很多选型争议一旦把重试、后处理、人工兜底都算进去答案往往就清晰了。另外一个小技巧评测时不妨故意把重试次数设得保守一点比如只允许一次这样能更快暴露模型的稳定性差异等选出候选后再用真实重试策略复测效率更高。