
如果你关注过大模型榜单又亲手在本地复现过某个开源模型的效果多半会遇到一个困惑为什么官方的榜单分数能到 70 分自己跑出来却只有 50 分是显卡不行还是写错了命令最近一篇关于 LLM 评测可靠性的论文给出了一种很有意思的解释同一个模型在不同的评测配置下分数差异可能非常大。论文里被测模型写作 gemma4-31b最高分与最低分之间可以从约 31% 一直波动到约 89%。也就是说排行榜上的名次差异未必代表模型真实能力差异反而像是对“评测配置”的敏感度测试。本文会围绕这个结论展开不堆实验数据而是把“评测配置到底包含什么”“哪些参数对分数影响最大”“如何用开源工具亲手做一次可控的评测”“怎么避免在论文和大模型选型中被榜单误导”这件事拆清楚。无论你是要做开源模型对比、准备论文实验还是给业务挑基座模型都值得花几分钟读完。1. 从论文结论看LLM 评测不只是“跑个准确率”1.1 一个反直觉的现象很多人对模型评测的理解是这样的找一份 benchmark 数据集把模型放上去跑出来的准确率高模型就强。事实上这个“跑”的过程里包含了大量可调因素。不同评测框架对解码的超参数设置不同提示词模板写法不同少样本示例采样方式不同甚至同一个数据集在不同版本下给出的答案格式不同都会影响最后的分数。论文把一个能反映该问题的现象摆在了明面上对于同一个模型在传统固定答案类测试集上只要调整评测配置得分区间可以从 31% 移动到 89%。这两个数字在排名表上分别位于垫底和中上位置。这说明很多时候大家争论“模型 A 是否比模型 B 强”争论的基础本身就不牢靠。如果把配置换一换A 和 B 的顺序完全可能反转。1.2 评测配置到底是什么“评测配置”不是一个单独参数而是整条评测管线的组合。按影响程度从粗到细可以分为几类解码层温度、top-p、top-k、do_sample、max_new_tokens、频率惩罚等提示词层问题模板、选项拼接格式、有无“Lets think step by step”、分隔符使用等少样本层few-shot 数量、示例来源、示例顺序、随机采样种子等模型加载层全精度、半精度、int8、int4、AWQ/GPTQ 量化等评估指标层是否用 token 概率比较、是否只接受单个选项字母、是否有后处理规范框架版本层不同版本的评测工具对生成结果解析逻辑不同可能带来系统性偏差。这些变量原本应该属于“评测说明”里必须交代的内容但在实际排行榜和论文中往往被简化成一行字甚至完全不写。缺少信息的分数很难被复现。1.3 为什么容易忽略这个问题原因是评测工具默认了参数。大多数主流评测框架默认使用 greedy decoding也就是温度等于 0每次生成结果尽量确定。这本身是合理的但问题是不是所有跑分人都知道默认参数存在不是所有框架都强迫用户显式设置解码参数一旦有人使用带采样配置的推理服务接入评测结果就会出现偏差。于是同一个模型权重被下载后在不同人手里可能跑出不同分数。跑分人以为自己是在测模型能力实际是在测配置组合。2. 为什么同一模型分数能出现 31% 到 89% 的巨大波动这一节我们把评测配置拆开来看。理解每个环节的放大效应比背答案更重要。2.1 解码参数从确定性到随机性如果你的评测任务是对“单选题”做输出并且直接用模型生成文本那么解码参数的影响会非常明显。配置模型行为对分数影响temperature0每次选择概率最大的令牌输出稳定波动小相对可复现temperature0.3偏保守但仍有一定随机性可能出现少量答案变化temperature0.7~1.0随机性增强对复杂推理题可能更容易答错do_sample 开启且未设种子每次运行结果不同分数可能在不同运行间跳动对于选择题如果评测逻辑要求模型直接输出某个选项字母那么在采样开启后模型一旦在概率边界附近“摇骰子”就会影响最终正确率。多测几次分数方差会变得非常大。很多评测框架默认关闭采样但当你通过 vLLM、TGI 等推理服务接入评测时服务本身可能有独立的 sampling 参数评测框架未必能完全覆盖。一个粗心配置就会让结果变得不可控。2.2 提示词模板同一个模型两套“人设”提示词的变化对 LLM 输出的影响已经是老话题但在评测中容易被忽略。同样一道数学题问题小明有 3 个苹果给了小红 1 个还剩几个 答案2另一种写法Q: 小明有 3 个苹果给了小红 1 个还剩几个 A:模型对两种格式的敏感程度不同。对某些模型来说中英文提示词差异、是否带“A:”、是否换行都会影响生成 token 的分布。在论文对应的现象中如果测试方使用了和模型训练分布不一致的提示词格式模型可能完全不理解任务意图导致分数跌到接近随机水平。反之如果提示词接近模型训练时的指令风格分数就会回暖。这就是同一个模型分数可以从 31% 提到 89% 的重要原因之一。在实际评测中我建议采用下面策略固定一套提示词模板不要中途修改如果要跑横向对比必须保证所有被测评模型使用完全相同的模板不能因为某个模型在某个模板下表现好就认为它一定比另一个模型强。2.3 少样本示例样例顺序也能改变结果少样本few-shot评测中常见操作是从训练集里抽出几个示例拼在提示词前面。这里的问题在于抽哪些示例示例之间顺序如何抽样的随机种子是否固定。模型本质上是在做模式匹配如果给出的示例恰好覆盖了某种题型接下来遇到类似题型时表现就会更好。不同评测复现时如果采样种子不一致结果会有几个百分点的天然波动。论文里提到的案例并不仅仅是一个配置的简单开关而是多个因素叠加后的效果。当所有“不利配置”叠加在一起模型就可能跌到 31%当所有“有利配置”对齐之后它又能接近 89%。因此单项差异可能没有想象中夸张但累计效应十分惊人。2.4 量化与推理精度另一个容易被忽略的点是权重精度。同一个模型在 A100 上用 BF16 跑和在消费级显卡上用 int4 量化跑输出概率分布会发生变化。量化会损失一部分精度但在某些任务上因为量化带来的隐式正则化分数并不一定下降甚至可能略有上升。如果不记录量化方式只写一句“我们评测了 Qwen2.5-7B 的 MMLU 结果”这个结果其实很难被其他人直接复现。2.5 评价指标与答案解析最后很多评测工具对生成的答案要做解析。比如多选题中模型可能输出这道题的答案是 B因为……如果解析逻辑只判断第一个字母是否为 B结果正确如果判断是否以“B”开头但模型先输出了语气词可能被误判为错误。解析规则的不同造成几分的波动并不奇怪。评测工具越“死板”越容易出现误伤。但换个角度看如果榜单作者没有公开解析规则你便无法判断分数差来自模型能力还是解析逻辑。3. 对实际选型论文和工程落地的影响3.1 别把排行榜当作选型唯一标准对于做模型选型的人而言这个现象的最直接提醒是不要只依赖公开榜单的绝对值。选型时应做到确认榜单方是否公开了完整评测配置在目标业务场景抽取 200~500 条真实数据做小规模评测让相同问题分别用模型和现有规则系统跑一遍人工抽检回答质量观察模型在边界情况下的表现而不是只算及格率对分数结果增加 3~5 次运行看波动区间。一个排行榜分数高 5 个百分点的模型在实际业务中可能只是因为它的提示词模板恰好和榜单一致。到了你的业务中这个优势未必能延续。3.2 复现他人实验结果时需要核对哪些信息复现开源模型分数时如果分数对不上优先核对评测框架是否为同一版本temperature 和 top_p 是否一致few-shot 样例是否固定是否开启同一种量化数据集的提示词模板是否完全一致max_new_tokens 是否足够生成完整答案是否使用相同的答案解析策略。这些信息在论文里通常不会全部出现但作者如果提供了评测仓库或配置文件就能极大减少复现时间。如果论文没有注明可以直接在回复中要求作者补充配置这是学术界越来越常见的要求。3.3 公开榜单的分数也不一定可靠不少第三方榜单会滚动收录不同时间提交的分数。每份提交使用的硬件、量化、解码参数可能不同。把这些分数放在一起排名必然会出现失真。一个理性的榜单阅读方式是判断结果是否来自同一套评测流程只比较同一流程内部的分差。跨流程的绝对分数没有太大意义。4. 用开源工具做一次可控的 LLM 评测下面我们实际操作一次。这里以评测框架 lm-evaluation-harness 为例。它由 EleutherAI 开源支持多种模型加载方式和数据集是目前比较流行的大模型评测工具之一。注意不同版本的 lm-evaluation-harness 在安装命令和参数细节上可能略有差异。本文展示的是常见方式具体环境请以官方文档为准。4.1 准备环境建议使用 Python 3.10 或更高版本创建独立虚拟环境。python -m venv .venv source .venv/bin/activate pip install lm_eval如果你希望用 vLLM 后端加速评测需要额外安装pip install vllm如果下载模型不方便也可以使用已有的本地模型目录。下面的示例中会把模型路径写成/data/models/your-model实际使用时要替换成你的真实路径。4.2 验证基础评测命令下面命令会加载一个 Hugging Face 格式的开源模型并执行 MMLU 数据集的 5-shot 测试。python -m lm_eval \ --model hf \ --model_args pretrained/data/models/your-model,tokenizer/data/models/your-model \ --tasks mmlu \ --num_fewshot 5 \ --batch_size 16 \ --output_path ./results/greedy关键参数含义--model hf使用 Hugging Face transformers 直接加载模型--model_args传递模型路径和 tokenizer 路径--tasks mmlu指定评测数据集--num_fewshot少样本数量MMLU 常设置为 5--batch_size批次大小需要根据显存调整--output_path结果保存目录。如果不额外设置解码参数lm-evaluation-harness 默认使用确定性解码这对复现实验结果更友好。跑完命令后终端会输出类似下面的结果| Tasks |Version|Filter|n-shot| Metric | |Value| |Stderr| |--------------|-------|------|-----|-----------|---|---|---|------| |mmlu | |none |5 |acc |↑ |0.712|± |0.012 |4.3 故意开启采样配置接下来我们故意把 temperature 调高模拟不同评测配置的影响python -m lm_eval \ --model hf \ --model_args pretrained/data/models/your-model,tokenizer/data/models/your-model \ --tasks mmlu \ --num_fewshot 5 \ --batch_size 16 \ --gen_kwargs temperature0.8,top_p0.9,do_sampletrue \ --output_path ./results/sample由于开启采样每次运行生成的答案可能不同。对于 MMLU 这类“固定答案”任务只要输出解析方式不变适当采样不至于让分数从 70 分掉到 30 分。但如果你把自己评测中的提示词模板也换掉差异就会明显放大。我们可以做一个更完整的实验分别记录温度 0.0 和 0.8 的结果固定提示词模板时看两个温度之间的分差再自定义一套不合适的提示词看是否出现大幅度下降这个实验可以帮助团队理解模型评分到底受哪些变量控制。4.4 用脚本多次运行并统计波动手动运行多次会比较麻烦可以用一个简单脚本批量执行。下面是一个核心思路示例不绑定具体框架版本#!/usr/bin/env bash for seed in 42 43 44; do python -m lm_eval \ --model hf \ --model_args pretrained/data/models/your-model,tokenizer/data/models/your-model \ --tasks mmlu \ --num_fewshot 5 \ --batch_size 16 \ --seed $seed \ --output_path ./results/ours_${seed} done注意这里--seed参数不是所有版本都叫这个名字可能需要换成--seed_everything或直接在配置里指定随机种子。脚本本身不重要核心是重复运行把结果记录下来。最终报告分数时不要只抛出一个最高值而应给出多次运行的均值与波动区间。4.5 记录评测配置一次可复现的评测报告至少应包含一个类似下面的配置快照model_name: your-model-name model_path: /data/models/your-model tokenizer_path: /data/models/your-model quantization: none inference_backend: hf decode: do_sample: false temperature: 0.0 top_p: 1.0 top_k: -1 max_new_tokens: 256 task: name: mmlu version: standalone fewshot: 5 fewshot_seed: 42 repeat_times: 3 hardware: 8*A100-80G framework_version: lm-evaluation-harness-0.4.x score: acc_mean: 0.712 acc_min: 0.707 acc_max: 0.716如果你在团队内部复现某个模型这份 YAML 能让所有人少走很多弯路。5. 常见问题与排查思路在跑 LLM 评测时下面几种情况比较常见。我把它们整理成一个速查表。问题现象常见原因解决思路本地复现分数和榜单分数不一致解码参数、提示词模板或少样本种子不同核对所有评测配置用统一框架重跑每次运行分数忽高忽低开启了采样但没有固定随机种子temperature 调成 0 或固定 seed多次运行取均值某个模型 MMLU 分数低于公开值 10 分以上评测框架版本不同或解析逻辑不同先查框架版本再查是否使用官方的 prompt 模板量化模型分数异常低量化精度损坏或任务格式不适配先用全精度模型跑一遍再对比量化模型显存不够导致评测中断batch_size 过大或 max_new_tokens 过长降低 batch_size减少生成长度换更强后端单选题输出“A”却判定错误输出中包含多余格式内容检查解析逻辑允许模型先输出解释不同任务分数趋势矛盾任务难度和模型能力分布不均衡综合多个数据集结果不要只依赖一个任务如果遇到分数无故偏低我建议从下面排查清单开始逐项核对。5.1 排查清单分数对不上的时候是否已经重新加载模型权重而不是使用了缓存中的旧结果是否在同一个 GPU 上运行了多个任务导致显存不足是否设置了 do_sampletrue 且 temperature1.0是否在 prompt 里加入了与数据集不匹配的额外指令是否修改过数据集的默认模板是否使用了和模型 tokenizer 不一致的 tokenizer是否在并行推理时使用了不稳定的随机采样多数情况下排查到前三步就能发现问题。5.2 如何避免分数波动问题最稳的方案是把评测流程固化到仓库中。不管是论文实验还是业务选型统一使用同一个评测配置任何人都可以一键复现。如果有能力可以把多组配置写入脚本然后把日志和配置快照一起输出。这样就算结果异常也能快速追溯是哪个环节引入的偏差。6. 评测实验设计与工程建议6.1 明确评测目标测的是能力还是兼容性不同的评测目标应该采用不同配置思考模型上限用尽量公平的模板、默认确定性解码多个数据集综合对比。模拟线上业务需要在模型部署服务上直接评测temperature 等参数必须与线上正式配置一致。验证模型对提示词的敏感度在固定模型条件下刻意变化模板、few-shot、采样参数观察分数范围。不要把这三类目标混在一起。否则你得到的分差并不能说明任何问题。6.2 报告评测配置的黄金指标在写论文、技术报告或者团队内部汇报时下面信息必须出现模型权重来源与 commit 版本模型加载精度解码参数抽样种子few-shot 示例如何选择提示词模板结构评测数据集名称和版本答案解析方式重复运行次数运行硬件。不要嫌内容多。正是因为缺少这些才导致大量模型分数不可复现。6.3 用区间代替点估计排行榜总喜欢给一个精确到小数点后一位的数字。但在了解了评测配置的敏感性之后我们应该学会用区间表示结果模型 A0.71 ± 0.01 模型 B0.73 ± 0.02两个模型如果差异小于波动区间就不应判定为显著差异。这一判断标准在学术论文中尤为重要。另外在选择基座模型时最好测试目标模型在“低配置”和“高配置”下的分数区间。如果区间过大说明该模型对提示词和采样参数敏感。部署到生产环境前需要额外设计好提示词和温度参数。6.4 评测只是手段不是终点大模型评测里没有“唯一正确分数”。评测配置相当于一个放大镜放大镜的倍数不同看到细节不同但不代表物体本身在改变。如果你要评估模型在业务中的价值最靠谱的不是看它能在某个榜单上排第几而是用业务真实数据构造一套内部评测集并把评测配置固定下来。之后每次升级模型、调整提示词都在同一配置下对比。这样得到的纵向趋势比公开排行榜上的名次更有可信度。回到最开始那篇论文的启示gemma4-31b 在 31% 到 89% 之间的波动本质上不是模型“能高能低”而是评测配置这个变量被放大了。未来的大模型评测应当像传统机器学习实验一样把数据划分、随机种子、预处理流程全部公开。当所有人都能复现同一个分数时排行榜上的名次才有真正的参考价值。