Skip to content

评测基准体系 — 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-Eval13,94852中国教育体系,含高等数学/考研政治
CMMLU11,52867更细粒度,含中国传统文化
MMLU-Pro12,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.696.5%+Few-shot CoT
Claude Fable95.8%+—
Qwen4-72B93.2%—
LLaMA 4 Scout91.7%—
GPT-3.557.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 采样获得多样性),只要其中至少有一个通过所有单元测试,该题即算正确。

pass@k=EProblems⁡[1−(n−ck)(nk)]
符号含义示例
n对每个问题采样的总答案数通常 n=200
c其中通过测试的答案数c ≤ n
k取前 k 个答案pass@1, pass@10, pass@100
(n−ck)k 个答案全部错误的组合数分母越大 pass@k 越低(题越难)
(nk)从 n 个选 k 个的总组合数—

直觉理解:1−全错组合数总组合数 = 至少一个对的概率。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@1pass@10pass@100说明
GPT-5.695%+99%+~99.9%—
Claude Fable93%+98%+~99.5%—
Qwen4-72B88.4%95%+~98%—
DeepSeek-R292.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.695%+—
Claude Fable93%+—
Qwen4-72B88.4%—
DeepSeek-R292.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 NIAH200K NIAH1M NIAH
GPT-5.699%99%97%
Claude Fable99%99%98%
Gemini 399%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, ArenaLLM打分/人类投票持续更新
长上下文NIAH, RULER信息召回率随窗口扩展更新
安全TruthfulQA真实性 + 无害性长期有效
多模态MMBench, MME多选 + 开放式持续更新

核心原则:评测分数高 ≠ 模型好用。MMLU 高分但代码能力差的模型不适合编程;Arena Elo 高但成本昂贵的模型不适合批量部署。评测必须匹配使用场景。


参考 ​

批注模式

💬 文章评论

暂无评论,来说点什么吧 👇

编程学习笔记