大模型推理多候选采样与自一致性投票落地

日期:2026-08-16

一、项目背景

我们把大模型接进一个关键业务判断的环节,用来自动初审一些单据能不能放行。上线前测试准确率不错,我们挺有信心。结果上线头两周,模型把一份明显有问题的单据放过去了,理由是它单次生成的答案恰好很自信,看着像对的。事后复盘,这种自信但错误的输出,单次采样根本发现不了,我们那次追了好几天才把流程补上。

我们意识到,关键判断不能信模型一次作答。人做重要决定还会想两遍,模型也该这样。而且大模型本身有随机性,同一道题采几次可能给出不同答案,单次结果运气成分不小。于是我们上了多候选采样加自一致性投票,让模型对同一问题生成多个答案,看它们是不是一致,不一致的就转人工。

二、落地场景

这个初审场景每天要处理几千份单据,大部分是标准件,模型能直接判,只有少数疑难件需要人看。我们要的是在不拖慢整体的前提下,把那部分模型可能判错的拦下来。

落地方式是:对每一份单据,模型并行采样若干个候选答案,用一致性算法聚合。绝大多数标准件几个候选高度一致,直接自动放行;少数候选分裂、互相矛盾的,标记低一致性,转给人工复核。人工复核的结果我们留着,作为后续评估的样本,也用来回测转人工阈值的合理性。这样人工只接手真正疑难的少部分,整体效率没受太大影响。我们还顺手统计了转人工那部分单据的后续处理时长,平均每个疑难件人工花两分钟就能定,比起之前全量人工初审省了九成以上的审核人力,这笔账业务方算得最清楚。

三、关键技术挑战与解决思路

一致性怎么判定是第一关。我们没有简单用字符串相等,因为模型措辞会变。我们用了一个轻量的语义对齐,把候选答案归到少数几个决策类别里,看各类别的支持票数。票数集中就高一致,票数分散就低一致。这个对齐模型很轻,本身不调大模型,就是个规则或者小分类器,开销可以忽略。

投票的开销和延迟要控制。采样越多越准,但每多采一个就多一份推理成本。我们按单据风险分级,低风险的标准件采三个,高风险或者高金额的采五个,在成本和准确度之间取平衡。我们还加了一个早停,如果前几个候选已经高度一致,后面的就不必再采,省下的算力不算少。

转人工的阈值定在哪里很关键。定太高漏放,定太低人工爆仓。我们用历史人工标注集回测,找到一个让错误放行率降到可接受、同时转人工比例不爆炸的临界点,上线后按实际数据微调。回测时我们发现阈值对高风险单据要更严,所以又按风险分了两档阈值,而不是全场一个值。

这个机制跑了一阵我们发现,采样数不是越多越好,超过五个之后准确率的边际提升很小,但成本线性涨,所以我们把高风险件的采样上限就定在五,不再往上加。人工复核那侧的反馈我们也接回来做了分析,发现转人工的单子里确实大部分是真疑难,说明阈值定得还算准,没把简单件冤枉送上去。我们还把这层判断接进了单据系统的审批流,模型自动放行的单子带上一句一致性分数,审核员一眼就能看出哪些是被模型高置信通过的、哪些走了人工,审计也方便。

四、效果数据

上自一致性之后,关键判断的整体准确率从九成出头提到九成七,看起来涨得不多,但错误放行率直接降了一半多,而这恰恰是最不能出错的指标。转人工的比例控制在总单量的百分之八左右,人工团队能接住,没有爆仓。平均延迟因为多了采样涨了约两百毫秒,业务侧能接受,毕竟关键单据多等零点几秒换来更稳的判断,值。

案例片段(已脱敏): 一致性投票的一段配置(yaml 示意): sampling:  n_candidates: 3  temperature: 0.7  risk_based:    high_amount: 5  early_stop:    consistency: 0.95 consistency:  method: class_vote  pass_threshold: 0.8  fallback: human 线上一周统计:标准件 3 采一致性 0.92,错误放行率由 1.8% 降至 0.8%,转人工占比 8.1%,P95 延迟 +210ms,早停触发节省约 18% 的采样算力。

五、可复用经验总结

关键业务判断这件事,我现在倾向于默认就上多采样投票,单采样看着省,出错一次够你喝一壶。我们那次漏放的单据后来追了好几天才补上流程,代价比多采几次大得多,这个教训印象很深。

转人工阈值别拍脑袋,拿历史标注回测定。我们一开始凭感觉定了个很低的值,人工直接被淹没,回测之后往上调,才找到又拦得住又不压垮人的点。而且高风险单据要单独严一档,不能全场一个阈值。

采样数按风险分级是我比较满意的一招。全量采五个太浪费,全量采三个高风险件又不够稳,分级之后成本和准确度都照顾到了。早停那段是后来加的,省了将近两成算力,建议类似场景都考虑上。