评测基准体系 — LLM 能力如何量化
#评测 · #Benchmark · #MMLU · #GSM8K · #MT-Bench · #SWE-bench · #Arena
"这个模型比那个好"——如果没有统一的评测体系,这种判断只是主观感受。本文梳理 LLM 领域的核心评测基准、方法论和自动化框架。
评测基准全景
mermaid
graph TD
subgraph "LLM 评测维度"
KNOWLEDGE["知识 & 理解<br/>MMLU, C-Eval, CMMLU"] --> REPORT["综合报告"]
REASONING["推理 & 数学<br/>GSM8K, MATH, BBH"] --> REPORT
CODE["代码能力<br/>HumanEval, MBPP, SWE-bench"] --> REPORT
CHAT["对话质量<br/>MT-Bench, Chatbot Arena"] --> REPORT
SAFETY["安全性<br/>TruthfulQA, RealToxicity"] --> REPORT
LONGCONTEXT["长上下文<br/>Needle-in-Haystack, RULER"] --> REPORT
end
REPORT --> RANK["排行榜<br/>LMSYS / Open LLM Leaderboard"]知识与理解类基准
MMLU (Massive Multitask Language Understanding)
最权威的通用知识评测。涵盖 57 个学科,从数学到法律到医学,约 14,000 道四选一选择题。
| 指标 | 说明 |
|---|---|
| 题目数 | ~14,000 |
| 学科数 | 57 (STEM + 人文 + 社科 + 其他) |
| 题型 | 4 选 1 单选题 |
| 评分 | Accuracy (5-shot) |
| 权威性 | ⭐⭐⭐⭐⭐ 业界标配 |
典型得分范围:
| 级别 | MMLU 得分 | 代表模型 |
|---|---|---|
| 随机猜测 | 25.0% | — |
| 入门级 | 60-70% | LLaMA-7B (SFT) |
| 可用级 | 70-80% | GPT-3.5, LLaMA-13B |
| 优秀级 | 80-87% | GPT-4, Claude Fable |
| 顶尖级 | 87-90%+ | GPT-5.6, Claude Fable (最新) |
C-Eval / CMMLU — 中文版 MMLU
| 基准 | 题目数 | 学科数 | 特点 |
|---|---|---|---|
| C-Eval | 13,948 | 52 | 中国教育体系,含高等数学/考研政治 |
| CMMLU | 11,528 | 67 | 更细粒度,含中国传统文化 |
| MMLU-Pro | 12,032 | — | MMLU 加强版,选项从 4→10 |
推理与数学类基准
GSM8K (Grade School Math 8K)
小学数学应用题,8500 道训练 + 1000 道测试。衡量模型的多步推理能力。
python
"""
GSM8K 题型示例
"""
gsm8k_example = """
问题: Janet 的鸭子每天下 16 个蛋。她每天早上吃 3 个当早餐,
用 4 个做松饼给朋友。剩下的每天在农贸市场以每个 $2 的价格出售。
如果她在农贸市场卖了 4 天,她赚了多少钱?
解题步骤:
- 每天下蛋: 16 个
- 每天吃掉: 3 + 4 = 7 个
- 每天剩余: 16 - 7 = 9 个
- 每个 $2: 9 × $2 = $18/天
- 4 天: $18 × 4 = $72
答案: $72
"""| 模型 | GSM8K 得分 | 说明 |
|---|---|---|
| GPT-5.6 | 96.5%+ | Few-shot CoT |
| Claude Fable | 95.8%+ | — |
| Qwen4-72B | 93.2% | — |
| LLaMA 4 Scout | 91.7% | — |
| GPT-3.5 | 57.1% | — |
MATH
高中数学竞赛级别,5000 道题,涵盖代数/几何/概率/数论。
| 基准 | 难度 | 题型 | 评分 |
|---|---|---|---|
| GSM8K | 小学数学 | 应用题 | 最终答案匹配 |
| MATH | 高中竞赛 | 证明/计算 | 最终答案匹配 |
| BBH | 多样化 | 23 类推理 | 多种评分 |
BBH (BIG-Bench Hard)
23 个具有挑战性的推理任务,从日期理解到逻辑推理到表格分析。
mermaid
graph LR
BBH["BIG-Bench Hard"] --> LANG["语言理解<br/>消歧义/蕴含"]
BBH --> LOGIC["逻辑推理<br/>逻辑网格/三段论"]
BBH --> MATH_B["数学<br/>多步算术"]
BBH --> ALG["算法<br/>布尔表达式/几何形状"]
BBH --> COMMON["常识<br/>体育理解/因果判断"]代码能力基准
HumanEval
164 道 Python 编程题。模型写函数,用单元测试验证正确性。
pass@k 的数学定义
pass@k:对每个问题生成 k 个答案(通过 temperature > 0 采样获得多样性),只要其中至少有一个通过所有单元测试,该题即算正确。
| 符号 | 含义 | 示例 |
|---|---|---|
| 对每个问题采样的总答案数 | 通常 n=200 | |
| 其中通过测试的答案数 | c ≤ n | |
| 取前 k 个答案 | pass@1, pass@10, pass@100 | |
| k 个答案全部错误的组合数 | 分母越大 pass@k 越低(题越难) | |
| 从 n 个选 k 个的总组合数 | — |
直觉理解:
= 至少一个对的概率。k 越大,pass@k 自然越高(多次尝试机会更多)。
python
"""
pass@k 的计算实现
"""
import math
def pass_at_k(n: int, c: int, k: int) -> float:
"""
计算单道题的 pass@k
Args:
n: 总采样数
c: 通过的采样数
k: 评估时取前 k 个
Returns:
pass@k 概率
>>> pass_at_k(n=200, c=180, k=1)
0.9 # 90% 的样本能一次通过
>>> pass_at_k(n=200, c=180, k=10)
0.9999... # 几乎必然至少有一个通过
"""
if n - c < k:
return 1.0 # 错误样本不够 k 个,必有一个对
return 1.0 - (
math.comb(n - c, k) / math.comb(n, k)
)
def estimate_pass_at_k(
results: list[bool], # 每道题的所有采样结果
k_values: list[int] = [1, 10, 100],
) -> dict:
"""
从原始采样结果估算整体 pass@k
results[i] = [True, False, True, ...] # 第 i 题 n 次采样的结果
"""
scores = {}
for k in k_values:
total = 0
for sample_results in results:
n = len(sample_results)
c = sum(sample_results)
total += pass_at_k(n, c, k)
scores[k] = total / len(results)
return scores| 模型 | HumanEval pass@1 | pass@10 | pass@100 | 说明 |
|---|---|---|---|---|
| GPT-5.6 | 95%+ | 99%+ | ~99.9% | — |
| Claude Fable | 93%+ | 98%+ | ~99.5% | — |
| Qwen4-72B | 88.4% | 95%+ | ~98% | — |
| DeepSeek-R2 | 92.7% | 98%+ | ~99% | 推理增强 |
阅读技巧:pass@1 衡量"一次就写对"的能力——最接近真实使用体验;pass@100 衡量"模型的上限潜力"——给足够多机会后能达到的水平。两者差异大说明模型输出方差大(有时很好有时很差)。
python
"""
HumanEval 题目示例 #0
"""
def has_close_elements(numbers: list[float], threshold: float) -> bool:
"""检查列表中是否存在两个数,其差的绝对值小于 threshold。
>>> has_close_elements([1.0, 2.0, 3.0], 0.5)
False
>>> has_close_elements([1.0, 2.8, 3.0, 4.0, 5.0, 2.0], 0.3)
True
"""
# 模型需要在此处生成代码| 模型 | HumanEval pass@1 | 说明 |
|---|---|---|
| GPT-5.6 | 95%+ | — |
| Claude Fable | 93%+ | — |
| Qwen4-72B | 88.4% | — |
| DeepSeek-R2 | 92.7% | 推理增强 |
SWE-bench
从真实 GitHub Issue 中提取的软件工程任务。不是"写一个函数",而是"修复这个 bug"。
| 指标 | 说明 |
|---|---|
| 任务数 | 2,294 个来自 12 个 Python 项目 |
| 评估方式 | 在 Docker 中运行测试,验证 PR 是否通过 |
| 难度 | 极高——需要理解整个代码库 |
| GPT-5.6 | ~58% (SWE-bench Verified) |
mermaid
graph LR
ISSUE["GitHub Issue<br/>bug 报告"] --> MODEL["模型分析<br/>定位代码+生成 patch"]
MODEL --> TEST["Docker 环境<br/>运行原有测试"]
TEST --> VERDICT{"所有测试通过?"}
VERDICT -->|"是"| PASS["✅ Resolved"]
VERDICT -->|"否"| FAIL["❌ 未解决"]对话质量基准
LMSYS Chatbot Arena
用人类偏好投票替代自动评分。两个匿名模型同时回答用户问题,用户投票选择更好的回答。用 Elo 评分排名。
| 指标 | 说明 |
|---|---|
| 评分方式 | 人类盲评投票 |
| 参与模型 | 100+ |
| 总票数 | 200 万+ |
| 权威性 | ⭐⭐⭐⭐⭐ "AI 界的围棋 Elo" |
MT-Bench
80 个高质量多轮对话问题,覆盖写作、角色扮演、推理、编码等 8 类。GPT-5.6 作为裁判打分(1-10 分)。
python
"""
MT-Bench 题目示例
"""
mt_bench_examples = {
"writing": "写一篇关于全球变暖对海洋生态影响的科技博文",
"coding": "用 Python 实现一个可处理嵌套注释的 JSON 解析器",
"reasoning": "如果所有 A 都是 B,有些 B 是 C,那么有些 A 是 C 是否一定成立?",
"roleplay": "你现在是面试官,模拟一次软件工程师的技术面试",
}长上下文基准
Needle-in-a-Haystack (NIAH)
在长文档中藏一条特定信息("针"),测试模型能否在不同位置找到它。
python
"""
Needle-in-a-Haystack 测试框架
"""
def needle_in_haystack_test(
context_length: int,
needle_position: float, # 0.0=开头, 1.0=结尾
needle_text: str = "秘密密码是 OCEAN123",
haystack: str = "保罗·格雷厄姆的散文 × N..."
):
"""
在不同上下文长度和针的位置上测试召回率
结果通常用热力图展示:
纵轴: 上下文长度 (1K → 200K)
横轴: 针的位置 (0% → 100%)
颜色: 召回准确度 (绿色=完美, 红色=失败)
"""
pass| 模型 | 128K NIAH | 200K NIAH | 1M NIAH |
|---|---|---|---|
| GPT-5.6 | 99% | 99% | 97% |
| Claude Fable | 99% | 99% | 98% |
| Gemini 3 | 99% | 99% | 98% |
自动化评测框架
Harness 与 Open LLM Leaderboard
bash
# LM Evaluation Harness — 评测 LLM 的标准工具
pip install lm-eval
# 一次性跑 MMLU + GSM8K + HumanEval
lm_eval \
--model hf \
--model_args pretrained=Qwen/Qwen4-7B \
--tasks mmlu,gsm8k,hellaswag,arc_challenge,truthfulqa \
--batch_size auto \
--output_path ./results \
--log_samples自建评测流水线
python
"""
轻量级自建评测 Pipeline
"""
import json
from dataclasses import dataclass
from typing import Dict, List
@dataclass
class BenchmarkResult:
model_name: str
task: str
score: float
num_samples: int
latency_ms: float
class SimpleEvaluator:
"""通用评测器"""
def __init__(self, model_fn):
self.model = model_fn
def evaluate(self, test_cases: List[Dict]) -> Dict[str, float]:
"""对一组测试用例评测"""
correct = 0
for case in test_cases:
output = self.model(case["input"])
if self._judge(output, case["expected"]):
correct += 1
return {
"accuracy": correct / len(test_cases),
"total": len(test_cases),
"correct": correct,
}
def _judge(self, output: str, expected: str) -> bool:
"""判断输出是否正确"""
# 不同任务用不同的判断逻辑
# 数学题: 提取最终答案数值比对
# 代码题: 运行单元测试
# 选择题: 匹配选项字母
return expected.lower() in output.lower()
# 使用示例
test_cases = [
{"input": "1+1=?", "expected": "2"},
{"input": "法国的首都是?", "expected": "巴黎"},
]
evaluator = SimpleEvaluator(lambda x: "2" if "1+1" in x else "巴黎")
result = evaluator.evaluate(test_cases)
print(json.dumps(result, indent=2))评测体系总结
| 能力维度 | 核心基准 | 评分方式 | 时效性 |
|---|---|---|---|
| 通用知识 | MMLU, C-Eval | 多选题准确率 | 长期有效 |
| 推理 | GSM8K, MATH, BBH | 答案匹配 | 长期有效 |
| 代码 | HumanEval, SWE-bench | 测试通过率 | 需要防数据泄露 |
| 对话 | MT-Bench, Arena | LLM打分/人类投票 | 持续更新 |
| 长上下文 | NIAH, RULER | 信息召回率 | 随窗口扩展更新 |
| 安全 | TruthfulQA | 真实性 + 无害性 | 长期有效 |
| 多模态 | MMBench, MME | 多选 + 开放式 | 持续更新 |
核心原则:评测分数高 ≠ 模型好用。MMLU 高分但代码能力差的模型不适合编程;Arena Elo 高但成本昂贵的模型不适合批量部署。评测必须匹配使用场景。
参考
- MMLU — Measuring Massive Multitask Language Understanding
- LMSYS Chatbot Arena — 人类偏好排行榜
- Open LLM Leaderboard — HuggingFace
- SWE-bench — 软件工程评测
- LM Evaluation Harness — EleutherAI
- GSM8K — OpenAI
登录后即可发表评论 👇