LLM 排行榜名次很大程度由评测配置决定——看到这个结论,很多人第一反应是怀疑,但一篇论文给出了更直观的例子:被评测的 gemma4-31b,得分可以在 31% 到 89% 之间波动。也就是说,同一个模型,面对的可能是同一类能力项,只是因为 prompt 模板、采样参数和答案解析方式不一样,就能从榜单底部冲到榜单顶部。
先说明一句:这个具体模型标识和论文里的详细复现条件,我没有看到足够完整的官方材料,所以这篇内容不把模型本身当成重点去展开。真正值得展开的是它揭示的问题:大多数排行榜上的分数,本质上是“评测配置 + 模型能力”的混合结果,而评测配置这个变量,往往被选型的人忽略了。
如果你平时靠排行榜挑模型,或者正在给自己的业务做模型评测,这篇内容会帮你拆清楚:为什么分数不可比、评测配置到底影响什么、怎么在自己的真实场景里跑出一份可信的评测结果。
1. 为什么排行榜上的名次可能不是“能力排名”
1.1 论文结论最值得先看的一点
这篇论文最直接的贡献,不是告诉你“某个模型很强或很弱”,而是把评测过程变成了受控变量,然后证明:只要评测配置变化,同一个模型的得分区间可以大到让人无法做任何能力判断。
如果不限制评测配置,排行榜上的名次更像“当前评测工程师选择了什么答案格式”,而不是“模型实际能解决什么问题”。
这对两类人影响很大。
第一类是直接用榜单做技术选型的人。看到某个模型在榜单上排在前面,就把它接到 agent、知识库、文档处理或者客服场景里。等上线后发现效果不对,又回头怀疑模型本身有问题。但真正的问题可能出在:榜单任务和你的任务不一样,榜单 prompt 和你的调用方式不一样,榜单的评分标准也没覆盖真实用户说的那些话。
第二类是做大模型应用开发的人。很多团队在多个模型之间做 A/B,但因为评测配置不固定,今天测出的模型 A 高,明天换个 prompt 变成模型 B 高。整个评测过程不仅没法指导选型,还会让团队内部对“谁更好”吵来吵去。
所以这篇内容不是让你彻底不信排行榜,而是告诉你:榜单能看,但要看它的配置边界。
1.2 名次和配置的关系:三个常见误解
第一个误解是“排行榜名次代表真实世界能力”。绝大多数公开榜单都是在固定任务、固定题库、固定 prompt 下跑出来的结果。比如选择题任务只衡量模型选择正确选项的能力,不会衡量它是否能在复杂文档里找到准确信息,也不会衡量它在长对话里的稳定性。真实业务往往比单个 benchmark 复杂得多。
第二个误解是“平均分高的模型综合能力更强”。排行榜为了给出一个直观的大排名,通常会把多个 benchmark 的分数做平均。这个操作会掩盖一种情况:模型 A 在数学任务上极高,在对话任务上很低,但因为平均分排进前十;模型 B 各项比较均衡,平均分略低一点,排在后面。从真实应用看,B 可能更适合大多数场景,但榜单不会告诉你这一层。
第三个误解是“同一份榜单上的分数可以直接互相比较”。即使大家都在同一个榜单页面上看分,也要看榜单使用的评测库版本、数据集版本、few-shot 数量和生成参数有没有变化。有些榜单会持续更新,任务配置可能换过好几轮。旧榜分数和新榜分数混在一起看,比较的基础就不成立。
这三个误解叠加起来,就会出现 31% 到 89% 这样的极端现象:不是模型在该强的时候弱、在该弱的时候强,而是评测配置在替你决定“该用哪种姿势考它”。
2. 拆解评测配置:同一个模型从哪几个环节被拉开差距
2.1 生成参数:temperature、top_p、max_tokens
先看生成阶段。
大多数评测工具默认使用 greedy decoding,也就是把 temperature 设为 0,让模型每次挑概率最高的 token。这个配置的问题是:它只代表一条确定路径,不一定代表模型在真实使用中的表现。真实用户调用时,很多应用会设置 temperature 大于 0,让回答更有变化。
当评测题目是需要精确答案的数学题或代码题时,temperature 一旦上去,模型的随机性会直接拉低准确率。比如一道选择题,温度较低时模型能稳定输出正确答案;温度调到 0.7 以后,连续跑五次可能错两次。对论文里那种“得分在 31% 到 89% 之间”的现象,生成参数只是其中一个变量,不是全部,但单靠它就能造成很大波动。
top_p 和 top_k 也会影响结果。top_p 控制候选 token 的累积概率范围,调小会让输出更保守。top_p 和 temperature 不是独立的,两者一起调整时,模型行为变化会非常明显。
max_tokens 更像一个“隐形杀手”。如果模型生成答案需要 300 个 token,而你只给了 128 个 token 的上限,答案会在中途被截断。解析程序只能从半截内容里找答案,结果自然偏低。评测时设置 max_tokens 太小,模型不是不会做,而是没有机会把答案写完。
2.2 任务模板与少样本示例
任务模板是评测配置里最容易被低估的部分。
同样一道数学题,发给模型时可以是:
- “请回答以下问题:XX 等于多少?”
- “你是一个数学老师,请认真解题并先给出推理过程。”
- “只输出最终数字,不要解释。”
这三种写法会对同一个模型产生完全不同影响。尤其是带有“先给出推理过程再给答案”的提示,对复杂题目通常有正面作用,因为给了模型更多 token 空间做中间推理。但推理过程越长,最后解析最终答案就越困难,一步解析错,整个分就丢了。
少样本示例同样关键。评测任务里加的 few-shot 示例数量,从 0 到 3 到 5,分数可能一路走高。原因是模型可以从示例里学到格式和风格,不一定是学到解题方法。示例选得好,模型输出稳定;示例选得差,反而会带偏模型。
这里还有一个经常踩坑的点:示例本身不能从测试集里来。如果示例和测试题目高度相似,模型能照猫画虎,分数虚高;一旦到了真实输入,没有这种“标准答案模板”,效果立刻下降。评测是为了预判真实效果,不是为了做一份漂亮的验证集报告。
2.3 输出解析与评测集差异
答案解析是整个评测链条里最像“人工后门”的环节。
有些评测直接用规则解析,比如从模型输出里用正则表达式抓“答案是 X”里的 X。模型只要多写了一句话“让我再想想”,正则就可能抓错内容。写解析规则的人如果对 prompt 非常了解,可以设计出专门匹配该模型的规则,从而显著拉高分数。
还有一类评测用另一个模型来打分,也就是所谓的 LLM-as-judge。这种方案把 prompt 模板的差异扩散到了裁判模型身上。裁判模型的格式偏好、长度偏好都成了干扰因素。同一个答案,换一个裁判模型,分数可能完全不同。
评测集本身也需要看。不同题库的难度分布不一样。MMLU 是选择题,测试的是知识覆盖;GSM8K 是小学数学应用题,测试的是多步推理;HumanEval 是代码生成。把哪个任务放进总榜、任务权重怎么配,直接决定了模型总名次。一个在数学任务上表现相对稳定、在通用知识问答上偏弱的模型,如果题库里数学题占比高,就可能排名靠前。
2.4 运行框架和权重精度的隐性影响
同样是模型权重,用 HF transformers 跑、用 vLLM 跑、用推理框架的量化版本跑,结果不一定完全一致。
权重精度是其中最容易忽略的一项。fp16、int8、int4 量化后的模型,在部分任务上差异可能不大,但在需要精确推理、长上下文记忆或代码类任务上,量化带来的信息损失会被放大。评测时如果用 fp16,生产时却用 int4,那么榜单分数和生产体验对不上,几乎是必然的。
框架差异更多体现在采样器的行为上。不同推理框架对 temperature、top_p 的实现细节有差别,甚至同一个框架不同版本之间也可能出现零散差异。对于一些对随机性敏感的任务,这种差异会反映在最终分数上。
还有一个常见干扰是评测批次大小。batch size 不会直接影响单道题的对错,但它可能改变模型内部的 padding 行为、attention mask 组织方式,从而影响输出。实际测试时,如果两轮评测用了完全不同的 batch size,得到不同结果也是有可能的。
3. 在本地把自己的任务跑成可信评测
3.1 先准备一个小而准的业务评测集
要避免被公开榜单误导,最直接的办法不是去造一套完美评测框架,而是先给自己准备一份“业务评测集”。
这份评测集不一定要很大,但一定要贴近真实使用场景。
我建议从这些地方收集题目:
- 线上真实用户问题,去掉可能涉及隐私的信息后直接脱敏使用;
- 你们业务里最高频的几种输入类型,比如客服提问、文档片段、代码注释、表格数据;
- 需要模型输出特定格式的任务,比如 JSON、Markdown、简短的指令;
- 预想到的困难场景,比如长文档、多轮对话、歧义问题。
数量上不用贪多。快速验证阶段 30 到 50 条就够,正式评估可以做到 200 到 300 条。关键是每一条都要有明确的“期望结果”或者“判断标准”。没有标准答案的评测集,只能让人凭感觉打分,很难复现。
这一步的核心价值是:把“榜单上的平均能力”转换成“我业务里的具体能力”。模型在公开榜上多强,和你能不能把它接进现有链路,是两回事。
3.2 固定评测协议的最小流程
有了评测集之后,接下来要做的不是立刻把候选模型全部跑一遍,而是先固定一份评测协议。协议至少应该涵盖这些内容:
- prompt 模板写死;
- 是否使用 system prompt;
- few-shot 示例的条数和具体内容;
- temperature、top_p、max_tokens;
- 答案解析方式;
- 每个模型跑几次,如何取最终分数。
下面是一个最小流程的伪代码。它不能直接复制到你的项目里,但可以帮你理解固定评测协议该怎么做。
# 伪代码:固定评测配置的最小流程 # 实际使用前需要根据模型路径、tokenizer、评测集结构做调整 from transformers import AutoModelForCausalLM, AutoTokenizer model_id = "your_model_path" # 替换成你的模型目录或合法模型标识 model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto") tokenizer = AutoTokenizer.from_pretrained(model_id) SYSTEM_PROMPT = "你是一个严谨的问答助手,请直接给出答案,不要额外解释。" def build_prompt(question, fewshot_examples=None): messages = [{"role": "system", "content": SYSTEM_PROMPT}] if fewshot_examples: for item in fewshot_examples: messages.append({"role": "user", "content": item["question"]}) messages.append({"role": "assistant", "content": item["answer"]}) messages.append({"role": "user", "content": question}) return tokenizer.apply_chat_template(messages, tokenize=False) def run_single_answer(question, fewshot_examples=None, temperature=0.0): prompt = build_prompt(question, fewshot_examples) inputs = tokenizer(prompt, return_tensors="pt").to(model.device) outputs = model.generate( **inputs, max_new_tokens=512, do_sample=temperature > 0, temperature=temperature, top_p=0.9, pad_token_id=tokenizer.eos_token_id, ) generated_ids = outputs[0][inputs.input_ids.shape[1]:] return tokenizer.decode(generated_ids, skip_special_tokens=True)这段伪代码里最需要注意的还是参数部分。temperature 设为 0 时,do_sample 必须为 False;temperature 大于 0 时,又要按需调节 top_p。很多人写评测脚本时直接把 temperature 改成 0.7,但没有打开 do_sample,结果模型还是 greedy 解码,看起来改了参数,实际没生效。
同一个模型可以按统一协议跑多轮。评估时可以取多次结果的平均值,同时记录最低分和最高分。如果一个模型在同一份测试集上两次跑分相差很大,单次分数就没有参考价值。
3.3 判断结果:看均值、方差和坏例
评测结束以后,先不要急着比较平均分。更合理的做法是看三个指标。
第一是整体正确率或达标率,也就是平时说的排行榜分数。第二是多次运行的标准差,标准差大说明模型在该评测配置下不稳定。第三是失败样本的分布。如果模型在一个固定类别上整体失败,平均分再高也不能直接上线。
我在实测中习惯先看 20 条样本的输出原文。这样可以判断模型是真正的懂,还是“碰巧输出对了”。比如有的题目只要求输出选项号,模型输出了一整段文字但结尾包含正确答案,解析器也能拿到正确答案。这算不算过了?如果真实业务只需要最终选项,那可以算过;但如果真实业务需要完整解释,评测只抓关键词就会过度乐观。
失败样例也很有价值。把每个模型的失败样例放到一起,能看出模型差异。很多时候模型 A 和模型 B 平均分差不多,但它们做错的题几乎没有交集。这说明它们适合不同场景,选哪个不取决于分数,而取决于哪些错误你更不能接受。
4. 最容易干扰分数的变量对照表
4.1 关键参数与固定建议表格
下面是我筛选出的对评测结果影响比较大的变量。不是所有项目都需要把每一项都列成流程文档,但至少在你评测报告里要写清楚。
| 变量 | 它对分数的影响 | 固定建议 |
|---|---|---|
| prompt 模板 | 写法变了,模型可能答对也可能答错,影响可以超过 10 个百分点 | 评测前写死,不要中途频繁修改 |
| system prompt | 会改变模型输出的风格长度和格式倾向 | 按真实业务设置;没有业务约束就固定为统一提示 |
| few-shot 示例 | 示例数量和质量会直接拉高或带偏分数 | 固定数量,示例内容要从评测集外准备 |
| temperature | 数值越大,精确任务上错得越多,方差越大 | 需要稳定答案时设为 0,需要多样性时另行轮次测试 |
| top_p | 与 temperature 一起影响候选 token 集合 | 建议固定为 0.9 或 1.0,并写进报告 |
| max_tokens | 太小会让长答案被截断,拉低实际得分 | 根据任务类型预留足够空间,比如 512 或 1024 |
| 答案解析方式 | 正则抓取或 LLM 打分都会引入误差 | 先打印输出原文,再决定解析策略 |
| 权重精度 | 量化程度越高,精确任务越可能出现损失 | 评测精度尽量和生产部署精度保持一致 |
| 推理框架版本 | 采样器和 padding 行为有差异 | 同一轮对比使用同一框架 |
| 评测集版本 | 题库内容变化后新旧分数不可比 | 记录数据集版本号或 commit 信息 |
这张表核心是帮你理解:如果两个模型的评测报告里参数列不完整,仔细比较没有意义。如果那个报告连 temperature、few-shot 数量、prompt 模板都没有写,只能把它当“模型某次跑分记录”,不能当成权威答案。
4.2 不同场景下评测配置怎么选
评测配置的固定,不是要让所有场景用同一套设置,而是要针对场景选择合理设置。
知识问答和客服场景,输出要做到稳定和可预期。评测时建议把 temperature 设为 0,系统提示词直接描述角色和输出格式,比如“你是客服助手,请用简洁中文回答”。这能模拟真实线上调用的状态。
代码生成场景,评测标准通常是有没有通过测试用例。提示词里需要明确语言、函数名和输入输出约束。代码题的答案解析不能只看文本包含什么,更稳妥的是提取出完整代码,再直接跑用例和测试,这样比正则抓代码块更接近真实结果。
文本创作和头脑风暴场景,temperature 可以调高一些,让模型产生更多样化的内容。这时的评测不适合只算一个准确率,最好加人工打分或规则评分,评价维度包括相关性、完整性和格式合规性。
Agent 和工具调用场景,题目往往长得像“用户提出一个任务,模型需要调用什么工具、传什么参数”。评测配置里很重要的一项是工具描述怎么写。工具描述不同,模型选择正确工具的概率就会不同。评测这类模型时,不能只给一个文本模板,要把工具的 JSON Schema 也一起固定下来。
5. 分数复现不了或波动太大时的排查顺序
5.1 从输出先排查,再回到数据和配置
如果你是按论文或其他开源评测脚本复现分数,跑出来和报告中不一致,先不要怀疑模型文件下载错了。我常用的排查顺序是这样的。
第一步,打印原始输出。把模型在测试题目上生成的完整回答打印出来,看它是不是直接被截断、输出为空或输出了一堆重复内容。如果输出本身不完整,后续任何解析都没意义。
第二步,检查 prompt 模板是否完全一致。不少评测卡片只写了“使用 5-shot”,但没有列出 few-shot 的具体内容。示例完全不一样,模型表现就可能差很多。最稳妥的办法是把模板写到报告里,后续别人才能复现。
第三步,检查生成参数。尤其是 temperature、top_p 和 do_sample 是否匹配。有的库在不传 do_sample 时,即使 temperature 是 0.7,也不会真正采样。
第四步,核对评测集版本。同一个任务名,不同版本可能增加或删减了题目,分数没有可比性。
第五步,核对权重精度。如果公开分数用的是 fp16,你本地用的是 int4,相差几个百分点很正常。
第六步,检查解析逻辑。这是最容易“复现成功但方案不对”的环节。如果你用规则解析,可能只适合某一类模型输出风格;换成另一个模型,输出风格变化,解析失败率升高,分数就会莫名下降。
5.2 榜单脚本常见的坑
如果你在复现公开榜单时碰到分数和榜单差异较大,我还可以给你一些常见坑的提醒。
数据集切分是最容易忽视的问题。公开的评测任务包含 train、validation、test 多个集。如果复现脚本不小心用 train 或 validation 做测试,分数会虚高。对比多个模型时,数据泄漏方向如果不同,结论会完全失效。
模板里的“问题编号”和“选项顺序”也可能造成干扰。有些任务选择题,会在题目里加一段“请从 A、B、C、D 中选择”。这个提示看起来很普通,但模型对顺序的敏感度不同,选项顺序变了可能就会改变结果。
评测时模型还没加载完整的 tokenizer 配置,也可能出问题。比如 pad_token 设置不对,模型批量生成时可能出现警告,输出中夹杂大量 pad token。解析时如果没有清理特殊 token,分数会被拉低。
还有一个比较隐蔽的点:batch size 太大时,有些模型会尽量节省显存,行为可能不同于单条推理。如果你先用小 batch 跑通,再加大 batch 复现分数,结果不一致,可以考虑减少 batch 并尽量保持和公开脚本一致。
从这里能看出,复现失败多数不是“模型不行”,而是配置没有对齐。反过来说,如果你要在项目里长期使用评测,最好把评测脚本连同参数一起纳入版本管理。每次评测完除了保留平均分,还要保留一份用于复现的配置文件。
6. 怎么用排行榜指导选型而不被榜单带偏
6.1 三个判断标准
排在第一的判断标准是:看榜单任务覆盖范围,而不是看总名次。
你可以做一张对比表,列清楚每个任务分别考什么能力。如果模型 A 的总分比模型 B 高,但模型 A 的高分来自常识问答,模型 B 的高分来自代码与数学,而你的业务刚好是代码场景,那就应该优先关注模型 B。
第二个标准是看评测配置与实际部署是否接近。榜单如果使用 temperature 为 0 的 greedy 解码,而你的应用为了生成丰富内容把 temperature 设成了 0.8,两者面对的不是同一种模型行为。这时榜单提供的信息有限,你需要用接近线上温度的配置重测一次。
第三个标准是看多次运行的稳定性。没有运行多次的榜单分数,只能代表“某个随机种子抽到的一次结果”。如果评测脚本没有固定随机种子,下一次重新跑可能得到不同名次。挑选模型时,不仅要看平均分排名,还要看不同运行之间的波动。波动大的模型,即使平均分排名靠前,上线排障压力也更大。
6.2 落到真实业务前的最后一步
在没有做真实业务评测之前,不要直接根据榜单纯单确定最终方案。我倾向于把选型流程分成三层。
第一层是快速初筛。用公开榜单把候选模型圈到 2 到 3 个,不要试图在几十个模型里做精测。这层只需要看总分和任务覆盖,不用投入太多精力。
第二层是业务小样本评测。用自己整理的三五十条业务题目,以固定协议快速跑一遍。输出完整答案并人工阅读。这层的主要目的是剔除完全不合适的模型,而不是追求精确排名。
第三层才是正式评测。用 200 条以上的业务评测集,跑多轮,记录平均分、标准差和失败样例。如果条件允许,可以把两个候选模型部署成内部接口,用真实流量做一段小范围 A/B。
到这里你会发现,公开排行榜在整个选型过程中只承担漏斗第一层的角色。它的价值是把大量模型筛选到少数候选,而不是替你决定最终答案。
我见过不少团队在选模型时陷入“高分迷信”,把榜单前十名的模型逐一接入项目测试,每个模型都跑完整流程,最后浪费了大量时间。更务实的做法是先定好自己的评测集,用统一协议快速跑两个最符合任务类型的模型,再针对输出细节做判断。
评测配置影响分数这件事,看起来像一个学术问题,但其实离工程很近。只要你的应用场景不是公开榜单的原场景,你就需要建立自己的评测协议。31% 到 89% 的波动提醒我们:任何单一的排行榜数字,都不应该成为技术决策的唯一依据。真正该做的,是把评测配置写清楚、把评测集贴近业务、把多次运行结果放一起看,然后再决定让哪个模型上线。