一篇论文给我印象很深,它直接挑战了一个常见的认知:我们以为 LLM 排行榜比的是模型能力,实际上很大程度上比的是“评测配置”。论文给出的例子很极端:同样是那个模型(材料里记为 gemma4-31b 的实例),在不同评测配置下,得分可以从 31% 一路波动到 89%。
这个现象不是“评测有误差”这么简单。它意味着,如果换一套提示词、换一组采样参数、换一种题目格式,同一个模型的排名可能从腰部直接冲到头部,也可能从头部掉到末尾。换句话说,很多公开排行榜的单次名次,参考价值没有想象中高。
这篇文章就结合论文的结论,拆解以下内容:评测配置到底是什么、哪些旋钮影响最大、31% 和 89% 是怎么形成的、排行榜应该怎么读、以及如果你想自己做模型评测,怎么设计才能减少这种波动。
1. 核心现象速览
| 信息项 | 内容 |
|---|---|
| 论文核心观点 | LLM 排行榜名次受评测配置影响非常大,甚至超过模型真实能力差异 |
| 实例现象 | 同一待评模型在多种评测配置下得分可在 31% 到 89% 之间大幅波动 |
| 主要变量 | 提示词措辞、采样参数、任务指令格式、少样本示例、评分标准、输出约束 |
| 受影响环节 | 知识问答、代码生成、数学推理、指令遵循等所有评测维度 |
| 最大风险 | 评测结果失真、榜单被“刷分”、模型选型决策被误导 |
| 可借鉴方向 | 评测环境标准化、多次运行取区间、报告评测配置细节 |
| 适用读者 | LLM 选型工程师、跑榜玩家、评测工具开发者、AI 产品负责人 |
这个现象提醒开发者:跑一次评测就对比两份模型得分,很多时候统计上并不稳固。一个模型得 60 分,另一个模型得 65 分,如果评测配置不同,这个 5 分差距基本没有意义。
2. 为什么评测配置能大幅影响榜单位次
先建立一个大前提:LLM 评测不是“把题目丢给模型、模型吐出答案、比对对错”那么简单。一次推理包含非常多的中间环节,而每一个环节里都有人为设定。
从评测题目进入模型开始,至少经过这些步骤:
- 评测集构造:题目如何从原始数据变成模型输入,需不需要加前缀、加说明、加示例。
- 提示词模板:模型看到的完整文本是什么,不同模板可能改变模型对任务的解读。
- 采样参数:
temperature、top_p、max_tokens,这些参数影响输出的确定性。 - 解码与停止条件:模型何时停止输出,输出长度上限是多少。
- 答案抽取:从模型输出里提取答案,用正则、用规则、还是用另一个模型抽取。
- 评分方式:是精确匹配、模糊匹配、关键字匹配,还是用 LLM 当裁判打分。
- 数据预处理:是否清理了特殊符号、是否统一格式、是否排除了难以解析的样本。
论文指出,很多排行榜在公布分数时,并不会把这些配置全部公开。于是评测结果看起来客观,其实是建立在大量隐藏假设之上。
31% 到 89% 的差异不是“模型偶尔发挥失常”,而是评测系统在多个环节上对模型不友好或友好的叠加效果。比如:
- 模型本身不是通过“直接给出简短答案”的方式训练的,评测却要求它必须严格只输出
A/B/C/D; - 模型习惯在回答前生成思考过程,评测系统却只截取最后一段,甚至因为输出过长被判错;
- 模型对英文指令更敏感,评测却用了它不擅长的表达风格;
- 采样参数设置了一个不利于这类任务的随机度,导致相同问题跑两次结果都不一样。
所以,一个真正值得讨论的问题不是“这个模型排第几”,而是“这个模型在什么条件下排第几”。
3. 评测配置中容易被忽略的变量
好,回到工程视角。控制评测配置,实际上是控制下面这些变量。每个变量都能影响最终分数,而多数排行榜不会完整披露。
3.1 提示词模板差异
同样是“解答这道数学题”,至少有这几种写法:
- 只给题目:
What is 17 * 23? - 要求步骤:
Please solve the problem step by step. - 给角色设定:
You are a helpful math tutor. Solve the problem. - 约束输出格式:
Only output the final answer as a number.
不同模型对不同写法的响应差异很大。某些模型对复杂指令更敏感,某些模型在简单指令下表现更好。论文中 31% 到 89% 的波动区间,提示词模板变化是主要贡献者之一。
3.2 采样参数
常用采样参数包括:
| 参数 | 作用 | 对评测分数的影响 |
|---|---|---|
| temperature | 控制随机性 | 过高容易答偏,过低可能重复 |
| top_p | 控制候选词累积概率 | 配合 temperature 影响输出多样性 |
| max_tokens | 限制最长输出 | 太短会导致答案截断 |
| stop | 自定义停止词 | 停止词不匹配可能产生多余输出 |
| seed | 随机种子 | 部分推理后端支持,影响可复现性 |
排行榜如果固定了 temperature,那相当于固定了一种“模型行为模式”。这本身没问题,但没写出来就有问题。
3.3 few-shot 示例的选取
少样本示例能显著影响输出风格。给出一个高质量示例,模型可能模仿它的推理过程;给一个错误方向的示例,模型可能被带偏。甚至示例的顺序都会产生影响。论文评测如果要公平,需要明确说明使用了多少示例、示例来自哪里、排序规则是什么。
3.4 答案抽取与评分规则
这是最隐蔽的环节。很多评测集不是选择题,而是开放式问答。模型输出一段完整回答后,评测脚本需要从中找到“正确答案”。
如果脚本只是精确匹配关键词,模型用同义词改写就可能被判错;如果脚本用规则抽取消极表达,模型遇到复杂句式也可能抽取失败;如果脚本用另一个 LLM 来评分,评分模型自身的性能又成为新的变量。
一个典型的例子是:让模型输出“答案是:21”。如果评测脚本只提取“21”,而模型输出的是“21 个苹果”,可能因为格式问题被判错。这不是模型不会做,是解析器没接住。
3.5 指令语言和措辞
论文实验里常常发现,某些开源模型在英文指令模板下表现更好,换成本地化措辞后,任务理解变差。如果评测集是英文题目,但提示词中出现非英文指令排序,有些模型的回答质量会下降。这个结果不反映“模型的真实推理能力”,只反映“模型在该评测配置下的指令遵循能力”。
4. 31% 到 89% 的波动区间说明什么
从材料看,这个 31% 是“较不利配置下的结果”,89% 是“较友好配置下的结果”。两者相差 58 个百分点。这是什么概念?
在很多知名榜单上,排名前列的模型之间不过相差零点几个百分点。如果评测配置能让一个模型跨 58 个百分点的区间波动,那榜单上几个点的差异根本说明不了模型能力差别。
这是一个非常严重的测量学问题。我把它拆成三层:
- 观测值不等于真值:我们看到的分数是模型在特定管道下的表现,不是唯一表现。
- 分数既要看均值也要看分布:只看一次运行结果会忽略方差。同一个模型在同一配置下跑 5 次,可能分数波动几个点。
- 模型差异的置信区间:两个模型如果各自分数误差区间叠加后包含对方,那么它们的高低关系在统计上不显著。
所以,评估一个模型不能只拿“排行榜分数”说话。真正靠谱的流程应该是:固定评测脚本、多次运行、观察分数分布、记录完整配置。否则你选型选到的可能不是你需要的模型,而是一个恰好适配了某套提示词模板的模型。
5. 评测配置如何影响你的模型选型决策
对普通开发者来说,读排行榜很容易做错决定。
比如你看到两个模型在某个 Leaderboard 上排名差距明显。模型 A 排第 8,模型 B 排第 20。如果你直接选模型 A,可能进入一个误区:这个榜单的评测配置偏好模型 A 的输出风格,而你的业务场景与这个评测配置并不一致。
更实际的决策方法是:
- 先确定你的任务类型。
- 再准备你业务里的真实测试样本。
- 然后固定一套统一评测配置,例如相同的提示词模板、相同的采样参数。
- 最后跑 2 到 3 次,观察两个模型的结果差异和稳定性。
这个思路不只是为了公平对比,更是为了降低“排名幻觉”带来的误导。
另外还要注意,论文材料里提到的模型名称可能来自研究总结,如果要在实际环境中复现,需要注意模型具体版本、参数规模和来源,尽量使用与业务环境一致的推理后端。
6. 如何设计一套相对稳健的评测流程
论文给出的是现象分析,实际操作中我们可以把评测做“保守化”处理:不是追求让模型得分最高,而是追求让自己的判断不容易被配置带偏。
6.1 固定并记录配置
评测脚本需要包含一份完整配置记录。配置可以分成模型参数、推理参数、评测参数和环境参数四类。
一个参考配置文件示例:
{ "model": { "name": "your-model-id", "revision": "commit-or-version", "backend": "vllm-or-transformers" }, "inference": { "temperature": 0.2, "top_p": 0.9, "max_tokens": 2048, "stop": ["\n\n", "<|endoftext|>"], "seed": 42 }, "evaluation": { "prompt_template": "./templates/chat_v1.txt", "few_shot_count": 5, "answer_extraction": "llm-judge", "scoring_metric": "exact_match" }, "environment": { "gpu_count": 1, "cuda_version": "12.1", "backend_version": "0.4.2" } }把这份配置文件和评测代码一起提交,任何一个后来者都能复现结果。
6.2 多次运行取区间
单次评测结果不构成决策依据。建议至少用这种策略:
- 同一配置下跑 3 次,记录每次分数、平均分、最高最低分。
- 两个模型对比时,看区间是否重叠。
- 如果区间重叠较大,就用更多样本或更稳定的参数重新测。
6.3 设置多组提示词模板
不要只用一套提示词模板。因为单套模板可能对某个模型更有利。设计三组模板:
# 模板清单示例 templates/ ├── prompt_v1_brief.txt ├── prompt_v2_detailed.txt └── prompt_v3_role_play.txt然后使用同一个评测集分别评测,取综合结果。这样能降低单一模板偏好带来的排名波动。
6.4 抽样检查人工复核
在自动评分之外,人工抽看 50 到 100 条模型输出,检查是否是“评分规则误判”导致假的高分或低分。这种做法不能完全取代自动评测,但它能帮你判断自动评分的可信度。
7. 评测环境准备与本地复现思路
如果你想自己跑一个小的评测实验,围绕“不同评测配置导致分数波动”进行验证,下面给出一套通用的本地复现思路。注意,以下示例是通用流程,具体路径、端口、模型名需要根据你的实际项目替换。
7.1 基础环境检查
建议先确认以下几项:
- Python 3.10 以上版本。
- 一个可用的推理后端,比如 vLLM、Transformers、Ollama 或 OpenAI 兼容服务。
- 准备一批测试问题,建议 30 到 200 条,不需要太大规模。
- 磁盘空间要足够放下模型权重。
- GPU 显存取决于模型规模,参数量越大占用越高,实际需要以你的模型版本为准。
7.2 启动模型服务
如果使用 OpenAI 兼容服务,启动方式通常类似:
python -m vllm.entrypoints.openai.api_server \ --model /path/to/your/model \ --port 8000 \ --max-model-len 8192 \ --gpu-memory-utilization 0.9实际命令取决于你选择的推理框架。如果没有 vLLM,也可以用其他后端,只要能对外提供接口就行。
7.3 编写评测脚本
用 Python 编写调用评测脚本。下面是一个通用模板,用来在不同配置下给同一模型打分对比:
import requests import json def chat_completion(prompt: str, temperature: float = 0.2, top_p: float = 0.9): url = "http://127.0.0.1:8000/v1/chat/completions" payload = { "model": "your-model-id", "messages": [{"role": "user", "content": prompt}], "temperature": temperature, "top_p": top_p, "max_tokens": 2048, "seed": 42 } resp = requests.post(url, json=payload, timeout=120) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"] def run_eval(prompt_template: str, temperature: float): questions = [ "Explain the concept of overfitting.", "Write a Python function to calculate Fibonacci numbers.", "What are the main causes of climate change?", "If a train travels 60 km in 1.5 hours, what is its average speed?" ] results = [] for q in questions: full_prompt = prompt_template.replace("{question}", q) output = chat_completion(full_prompt, temperature=temperature) results.append({"question": q, "output": output}) return results if __name__ == "__main__": brief_prompt = "{question}" detailed_prompt = "Please answer the following question carefully and provide a clear explanation:\n\n{question}" results_brief = run_eval(brief_prompt, 0.2) results_detailed = run_eval(detailed_prompt, 0.2) with open("results_brief.json", "w", encoding="utf-8") as f: json.dump(results_brief, f, ensure_ascii=False, indent=2) with open("results_detailed.json", "w", encoding="utf-8") as f: json.dump(results_detailed, f, ensure_ascii=False, indent=2)这个脚本不直接完成自动评分,但能提供两组原始输出,方便你观察同一模型在不同提示词下的回答差异。
7.4 人工评分对比
得到输出后,可以按“正确性、完整性、格式合规”三档人工打分,也可以接入评分模型。评分时建议不保留“哪个提示词模板”的信息,做盲评,减少主观偏差。
8. 评测结果观察:如何判断配置是否在起副作用
评测配置是很中性的东西,没有什么“万能最优配置”。同一套配置可能让一个模型表现很好,同时严重压制另一个模型。关键是从评测结果中识别出“配置副作用”。
下面这些信号可以作为参考:
8.1 输出长度截断
如果很多模型输出恰好等于max_tokens上限,说明max_tokens设置可能限制了模型完整回答。尤其在代码生成和长文本推理题里,这会让分数失真。
8.2 解析失败率偏高
评测日志中大量样本被判为“格式错误”“无法解析”,这种情况大概率是抽取器规则太严或停止条件不对。建议先检查模型原始输出,如果输出里有正确答案但被判定格式不符,则需要修正抽取逻辑。
8.3 多次运行分数波动大
如果同一个模型在同一配置下跑 3 次,分数差距超过 5 个百分点,说明采样参数偏大或评测集样本量太小。这时应该调低temperature,或扩大测试集。
8.4 一个极端结果拉高平均分
如果一个模型总体的平均分不错,但最小分数特别低,检查是否存在系统层面“上下文崩坏”情况。这种情况通常不是因为模型不会做题,而是因为长上下文输入后模型输出质量急剧下降。
9. LLM 评测常见问题与排查方法
自己搭建评测流程时,容易踩不少坑。下面按现象给出一张排查表,很多是我在实际折腾评测流程时遇到的问题。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 同一模型同一配置分数忽高忽低 | 采样随机性,temperature过高 | 固定 seed,调低 temperature | 设置temperature=0.2,多次运行取平均 |
| 模型输出质量好但评分很低 | 答案抽取规则过于严格或匹配方式不合理 | 查看原始输出,看是否包含正确内容 | 改用 LLM Judge 评分,或增加正则容错 |
| 换一套提示词后分数大幅变化 | 模型对指令措辞敏感 | 用多组提示词模板分别评测 | 综合报告多模板结果,不只取单次记录 |
| 批量评测到一半卡住 | 接口超时、显存溢出或请求频率过高 | 查看后端日志 | 增加超时时间,减小 batch,加入失败重试 |
max_tokens耗尽导致答案不完整 | 生成长度上限设置过低 | 检查输出是否恰好等于截断长度 | 按任务增加生成长度上限,如设 2048 或 4096 |
| 模型输出有额外说明文字 | 提示词未约束输出格式 | 在提示词中加入“只输出最终答案” | 用停止词或格式约束减少解析负担 |
| 排行榜显示 A 优于 B,本地实测相反 | 评测集或评测配置差异 | 对比双方使用的评测集与采集参数 | 使用自己的业务样本做小范围人工评测 |
10. 回归到论文本身:读榜单时要多一步思考
这篇论文的做法和很多严谨评测研究一致:不要问“谁更强”,要问“在什么配置上谁更强”。
论文揭示的核心风险是:如果各个评测项目没有统一约定提示词模板、采样参数、多少示例、如何抽取答案,那榜单分数里混入了大量配置噪声。而配置噪声可能导致开源社区形成错误的“模型强弱印象”。
接下来,如果你也在做模型评测或者正在挑模型,建议按下面的顺序调整:
- 先确定“评测配置”的定义,不要只记分数,要记录完整参数。
- 使用至少 3 组不同提示词模板。
- 对模型做多次采样,得到分数区间。
- 在自动评分后做小规模人工抽查。
- 对照你的真实业务,不要完全依赖别人的榜。
如果你觉得现在直接手写评测流程太慢,也可以考虑先用现成的评测框架或评测集,然后在其基础上增加自定义模板变量。这样能快速建立起一套属于自己的可信评估流程。
11. 最佳实践:如何向团队或社区报告模型评测结果
最后一条很实际:无论是写技术总结还是给团队汇报,都不要只给一个排名表。一份可信的评测报告至少要包含以下内容。
- 模型信息:模型名称、权重来源版本、量化方式(如果有)、推理后端。
- 评测集信息:题目数量、来源、语言、难度分布。
- 提示词模板:完整模板文本,最好随仓库发布。
- 推理参数:temperature、top_p、max_tokens、seed、停止词。
- 运行次数与分布:多次运行后得到的均分、最高分、最低分。
- 抽取和评分代码:可以复现的打分逻辑。
- 已知局限:哪些任务是评测集覆盖不到的,哪些评分规则可能产生偏差。
把这些信息公开以后,别人才能判断你的评测是否可信,也才能在自己的环境里继续复现。
12. 总结与下一步
LLM 排行榜本身不是没有价值,它的价值在于提供一个大规模、低成本、可横向对比的参考坐标。但论文用 31% 到 89% 的极端波动提醒我们:评测配置不是一个可以忽略的细节,它是评测结果的一部分。你想比较模型能力,就必须把配置固定下来,并且公开出来。
对于经常跑模型评测、在排行榜上选型的人,这篇文章最值得记住的一点是:不要无条件相信某个单一榜单;至少用你自己的任务样本,在一套固定配置下跑一遍,并多做几次,看分数的分布情况。记录 prompt 模板、采样参数、抽取规则,把这些和最终分数一起保存。这样你的选型判断就稳定得多。如果以后再看到某个模型“分数暴涨”,别急着惊叹,先翻一下它用的评测配置是不是刚好适合那个模型的输出风格,再下结论。