LLM 评测
模型训完了,上线了——但它到底好不好?比上一版强多少?「感觉变好了」是工程决策最差的依据。
这一节理解论文和工业界真正在用的评测体系:评测指标怎么定义、开源评测框架怎么用、LLM-as-Judge 怎么让 强模型当裁判打分,以及如何看懂结果并写出有说服力的对比报告。
评测的本质是把「模型好不好」这个主观问题转化为可量化、可复现的客观分数。
核心三要素是标准化考题(benchmark)、自动化批改(metric)和可复现的流程(evaluation pipeline)。LLM-as-Judge 是近年兴起的做法:用 GPT-4 这类强模型来评判其他模型的回答质量。在 MT-Bench / Chatbot Arena 这类设置中,强模型 judge 与人类偏好有较高一致性;但一致性依赖任务、judge prompt、模型版本和答案格式。参考:MT-Bench / Chatbot Arena。
但 LLM-as-Judge 也有自己的陷阱——位置偏见、长度偏见和格式偏见都可能导致评分失真。
Perplexity 衡量模型在给定文本上预测下一个 token 的平均不确定性。它适合语言建模和预训练监控,但不能直接代表聊天质量、推理能力或安全性。
import os, json, sys, subprocess
from pathlib import Path
print(f"Python: {sys.version.split()[0]}")
print(f"工作目录: {os.getcwd()}")
# 检查关键依赖
deps = {
"openai": "OpenAI SDK",
"datasets": "HuggingFace datasets",
}
for pkg, desc in deps.items():
try:
__import__(pkg)
print(f" ✅ {pkg} — {desc}")
except ImportError:
print(f" ❌ {pkg} — {desc}(pip install {pkg})")
# 检查 lm-eval CLI 是否可用
try:
result = subprocess.run(["lm_eval", "--help"], capture_output=True, text=True, timeout=10)
if result.returncode == 0:
print(" ✅ lm_eval CLI — lm-evaluation-harness")
else:
print(" ❌ lm_eval CLI 未安装(pip install lm-eval)")
except FileNotFoundError:
print(" ❌ lm_eval CLI 未安装(pip install lm-eval)")
print("\n💡 安装缺失的包:")
print(" pip install openai lm-eval datasets")
Python: 3.12.2
工作目录: /Users/sanbu/Code/2026重要开源项目/modern-llm-notebook/notebooks/part5-production
✅ openai — OpenAI SDK
❌ datasets — HuggingFace datasets(pip install datasets)
❌ lm_eval CLI 未安装(pip install lm-eval)
💡 安装缺失的包:
pip install openai lm-eval datasets
1. 评测全景
1.1 评测演进路线(教学版时间线)
2019-2021 2022-2023 2024-2025
↓ ↓ ↓
GLUE/SuperGLUE MMLU/GSM8K LLM-as-Judge
BERT 时代 GPT-4 时代 Agent 时代
选择题为主 选择题 + 生成题 多轮 + 工具 + 安全
1.2 近年论文和工业界常见评测维度
| 维度 | 代表数据集 | 指标 | 为什么重要 |
|---|---|---|---|
| 知识 | MMLU-Pro、GPQA | acc | 常见于头部模型报告 |
| 数学推理 | GSM8K、MATH、AIME 2024 | exact_match | 推理能力的硬指标 |
| 代码 | HumanEval+、LiveCodeBench、SWE-bench | pass@k | 程序员最关心的 |
| 指令遵循 | IFEval、MT-Bench | strict_acc | 决定实际可用性 |
| 对话质量 | AlpacaEval、Chatbot Arena | win_rate/Elo | 强模型当裁判 |
| 安全 | TruthfulQA、Garak | 违规率 | 上线前通常需要覆盖 |
| 长文本 | Needle-in-Haystack、RULER | recall | RAG 场景关键 |
| 多语言 | CMMLU、C-Eval | acc | 不能只评英文 |
| Agent | SWE-bench、WebArena | success_rate | 近年快速发展的方向 |
1.3 通用模型常见评测组合
通用模型技术报告通常会覆盖这些维度,但具体集合取决于模型定位。代码模型、RAG 系统、医疗/法律模型不应该只照搬通用榜单:
基础:MMLU-Pro + GPQA + HellaSwag
代码:HumanEval+ + LiveCodeBench + SWE-bench(Agent 场景)
数学:GSM8K + MATH + AIME 2024
对话:AlpacaEval 2.0 / Chatbot Arena Elo
指令:IFEval + MT-Bench
安全:TruthfulQA + 红队测试
新手最小评测集(先跑通这 4 个再扩展):GSM8K → MMLU → HumanEval → IFEval
2. 核心评测框架 & Repo 推荐
下面是工业界和学术界常用的几个评测框架。这里按教学实用性组织,不代表唯一排序:
2.1 lm-evaluation-harness(EleutherAI)— 开源评测常用框架
git clone https://github.com/EleutherAI/lm-evaluation-harness.git
cd lm-evaluation-harness
pip install -e .
- 地位:开源模型评测中非常常用的框架之一,很多 leaderboard 和论文会使用它或兼容的任务/指标。跨论文对比时仍要核对 prompt、few-shot、解析和模型版本。参考:lm-evaluation-harness
- 能力:200+ 数据集,一行命令搞定 API 评测 / HF 评测 / vLLM 评测
- OpenAI-Compatible 支持:
local-completions和local-chat-completions两个模型类型,连接任何兼容 API
2.2 AlpacaEval — 常用 LLM-as-Judge 工具
git clone https://github.com/tatsu-lab/alpaca_eval.git
cd alpaca_eval
pip install -e .
- 地位:常用的自动对话评测工具之一,特别强调 length-controlled win rate;不能替代人工评审和业务评测。参考:AlpacaEval、LC AlpacaEval
- 核心指标:LC Win Rate(Length-Controlled,控制长度偏差)、WR(原始胜率)
- 800+ 条 prompt,对比你的模型和 GPT-4/Davinci-003 的回答,用 GPT-4 判胜负
2.3 FastChat(LMSYS)— Chatbot Arena 同款
git clone https://github.com/lm-sys/FastChat.git
cd FastChat
pip install -e ".[eval]"
- 地位:Chatbot Arena 是影响力很大的众包对战评测平台之一;FastChat 提供 MT-Bench 和相关 judge 工具
- 核心能力:MT-Bench(80 道多轮问题 + GPT-4 打分)、Chatbot Arena(1M+ 人类投票)
2.4 DeepEval — CI/CD 友好
pip install deepeval
- 地位:pytest 风格,可集成到 CI/CD 管线
- 特色:幻觉检测、答案相关性、忠实度、G-Eval(用思维链评测)
框架选型速查
| 场景 | 推荐框架 |
|---|---|
| 论文报分 / 开源模型评测 | lm-evaluation-harness |
| 对话质量评估 | AlpacaEval / FastChat MT-Bench |
| CI/CD 持续评测 | DeepEval / Promptfoo |
| 安全测试 | Garak(NVIDIA) |
| Agent 评测 | SWE-bench + WebArena |
本 Part 重点:用 lm-evaluation-harness 做核心评测,用 AlpacaEval 做对话质量评测。
# Clone 核心评测 repo(在终端运行)
# 下面用代码检查 repo 是否已存在,不存在则 clone
REPOS = {
"lm-evaluation-harness": "https://github.com/EleutherAI/lm-evaluation-harness.git",
"alpaca_eval": "https://github.com/tatsu-lab/alpaca_eval.git",
"FastChat": "https://github.com/lm-sys/FastChat.git",
}
repos_dir = Path.home() / "Code" # 改成你放代码的目录
print("=== 核心评测 Repo 状态 ===\n")
for name, url in REPOS.items():
repo_path = repos_dir / name
if repo_path.exists():
print(f"✅ {name} — 已存在: {repo_path}")
else:
print(f"❌ {name} — 未 clone")
print(f" 在终端运行: git clone {url} {repo_path}")
print(f" cd {repo_path} && pip install -e .")
print()
# 验证 lm-evaluation-harness 可用
try:
import lm_eval
print(f"✅ lm_eval 已安装,版本: {lm_eval.__version__ if hasattr(lm_eval, '__version__') else 'unknown'}")
except ImportError:
print("❌ lm_eval 未安装,运行: pip install lm-eval")
=== 核心评测 Repo 状态 ===
❌ lm-evaluation-harness — 未 clone
在终端运行: git clone https://github.com/EleutherAI/lm-evaluation-harness.git /Users/sanbu/Code/lm-evaluation-harness
cd /Users/sanbu/Code/lm-evaluation-harness && pip install -e .
❌ alpaca_eval — 未 clone
在终端运行: git clone https://github.com/tatsu-lab/alpaca_eval.git /Users/sanbu/Code/alpaca_eval
cd /Users/sanbu/Code/alpaca_eval && pip install -e .
❌ FastChat — 未 clone
在终端运行: git clone https://github.com/lm-sys/FastChat.git /Users/sanbu/Code/FastChat
cd /Users/sanbu/Code/FastChat && pip install -e .
❌ lm_eval 未安装,运行: pip install lm-eval
3. OpenAI-Compatible API 评测实战
这是最实用的评测方式——你部署了一个兼容 OpenAI API 的服务(vLLM、Ollama、DeepSeek、各种网关),直接调 API 跑评测。
3.1 核心原理
lm-evaluation-harness 通过两个模型类型支持 OpenAI-Compatible API:
| 模型类型 | API 端点 | 支持任务 |
|---|---|---|
local-chat-completions | /v1/chat/completions | 生成题(GSM8K、HumanEval、IFEval) |
local-completions | /v1/completions | 生成题 + 选择题(MMLU 需要 logprobs) |
关键区别:经典 MMLU / HellaSwag 这类选择题通常需要每个选项的 token logprob。很多 Chat Completions API 不暴露足够的 logprobs,因此常用 completions/logits 路线;也可以改写成生成式选择题,但分数不能和默认 leaderboard 直接比较。
3.2 支持的服务
任何兼容 OpenAI API 的服务都可以:
OpenAI API → 需要 API Key
DeepSeek API → 兼容 OpenAI 格式
vLLM 部署 → http://localhost:8000/v1
Ollama → http://localhost:11434/v1
LiteLLM 代理 → 统一代理多个后端
SGLang → http://localhost:30000/v1
一句话:如果服务能接收 POST /v1/chat/completions,通常可以跑生成类任务;但选择题/loglikelihood 类任务还需要 completions/logprobs 或本地 logits。不同 OpenAI-compatible 服务对 logprobs、chat template、stop、reasoning_content 的支持并不完全相同。
# 方式一:用 local-chat-completions 评测 GSM8K(数学推理)
# 这是新手最应该先学会的评测 — GSM8K 是生成题,用 Chat API 即可
print("=== OpenAI-Compatible API 评测 GSM8K ===\n")
# 构造命令(在终端中实际运行)
# 假设你有一个 OpenAI-Compatible 的服务运行在 localhost:8000
# 把 base_url 改成你的实际地址
api_configs = {
"OpenAI": {
"model": "gpt-4o-mini",
"base_url": "https://api.openai.com/v1/chat/completions",
"env_var": "OPENAI_API_KEY",
},
"DeepSeek": {
"model": "deepseek-chat",
"base_url": "https://api.deepseek.com/v1/chat/completions",
"env_var": "DEEPSEEK_API_KEY",
},
"vLLM 本地": {
"model": "Qwen2.5-7B-Instruct",
"base_url": "http://localhost:8000/v1/chat/completions",
"env_var": None, # 本地不需要 key
},
"Ollama 本地": {
"model": "llama3",
"base_url": "http://localhost:11434/v1/chat/completions",
"env_var": None,
},
}
for name, config in api_configs.items():
print(f"--- {name} ---")
key_arg = ""
if config["env_var"]:
key_arg = f",token=${{{config['env_var']}}}"
cmd = (
f"lm_eval --model local-chat-completions \\\n"
f" --model_args model={config['model']},"
f"base_url={config['base_url']},"
f"num_concurrent=4,max_retries=3,tokenized_requests=False{key_arg} \\\n"
f" --tasks gsm8k \\\n"
f" --batch_size 8 \\\n"
f" --output_path ./eval_results/gsm8k_{name.lower().replace(' ', '_')}"
)
print(f" {cmd}\n")
print("💡 把上面任意一条命令复制到终端即可运行!")
print(" 前提:pip install lm-eval 已完成")
=== OpenAI-Compatible API 评测 GSM8K ===
--- OpenAI ---
lm_eval --model local-chat-completions \
--model_args model=gpt-4o-mini,base_url=https://api.openai.com/v1/chat/completions,num_concurrent=4,max_retries=3,tokenized_requests=False,token=${OPENAI_API_KEY} \
--tasks gsm8k \
--batch_size 8 \
--output_path ./eval_results/gsm8k_openai
--- DeepSeek ---
lm_eval --model local-chat-completions \
--model_args model=deepseek-chat,base_url=https://api.deepseek.com/v1/chat/completions,num_concurrent=4,max_retries=3,tokenized_requests=False,token=${DEEPSEEK_API_KEY} \
--tasks gsm8k \
--batch_size 8 \
--output_path ./eval_results/gsm8k_deepseek
--- vLLM 本地 ---
lm_eval --model local-chat-completions \
--model_args model=Qwen2.5-7B-Instruct,base_url=http://localhost:8000/v1/chat/completions,num_concurrent=4,max_retries=3,tokenized_requests=False \
--tasks gsm8k \
--batch_size 8 \
--output_path ./eval_results/gsm8k_vllm_本地
--- Ollama 本地 ---
lm_eval --model local-chat-completions \
--model_args model=llama3,base_url=http://localhost:11434/v1/chat/completions,num_concurrent=4,max_retries=3,tokenized_requests=False \
--tasks gsm8k \
--batch_size 8 \
--output_path ./eval_results/gsm8k_ollama_本地
💡 把上面任意一条命令复制到终端即可运行!
前提:pip install lm-eval 已完成
# 方式二:用 local-completions 评测 MMLU(知识选择题)
# MMLU 默认常用 loglikelihood(计算每个选项概率),通常需要 Completions API 或本地 logits
print("=== OpenAI-Compatible API 评测 MMLU ===\n")
print("⚠️ 经典 MMLU loglikelihood 设置需要 logprobs;很多场景要用 Completions API 或本地 logits\n")
print(" Chat Completions API 会报错: NotImplementedError\n")
mmu_configs = {
"OpenAI": {
"model": "gpt-4o-mini",
"base_url": "https://api.openai.com/v1/completions",
"env_var": "OPENAI_API_KEY",
"note": "⚠️ gpt-4o-mini 不支持 /v1/completions, 需用 davinci-002 等",
},
"vLLM 本地": {
"model": "Qwen2.5-7B-Instruct",
"base_url": "http://localhost:8000/v1/completions",
"env_var": None,
"note": "✅ vLLM 的 /v1/completions 端点返回 logprobs",
},
"DeepSeek": {
"model": "deepseek-chat",
"base_url": "https://api.deepseek.com/v1/completions",
"env_var": "DEEPSEEK_API_KEY",
"note": "⚠️ DeepSeek /v1/completions 可能不支持,用 Chat API 跑生成题即可",
},
}
for name, config in mmu_configs.items():
print(f"--- {name} ---")
print(f" {config['note']}")
key_arg = ""
if config["env_var"]:
key_arg = f",token=${{{config['env_var']}}}"
cmd = (
f"lm_eval --model local-completions \\\n"
f" --model_args model={config['model']},"
f"base_url={config['base_url']},"
f"num_concurrent=4,max_retries=3,tokenized_requests=False{key_arg} \\\n"
f" --tasks mmlu \\\n"
f" --batch_size 16 \\\n"
f" --output_path ./eval_results/mmlu"
)
print(f" {cmd}\n")
print("💡 实战建议:")
print(" 用 vLLM 部署模型 → local-completions 跑 MMLU + local-chat-completions 跑 GSM8K")
print(" 这是最优的工作流程")
=== OpenAI-Compatible API 评测 MMLU ===
⚠️ MMLU 类型的选择题必须用 Completions API(需要 logprobs)
Chat Completions API 会报错: NotImplementedError
--- OpenAI ---
⚠️ gpt-4o-mini 不支持 /v1/completions, 需用 davinci-002 等
lm_eval --model local-completions \
--model_args model=gpt-4o-mini,base_url=https://api.openai.com/v1/completions,num_concurrent=4,max_retries=3,tokenized_requests=False,token=${OPENAI_API_KEY} \
--tasks mmlu \
--batch_size 16 \
--output_path ./eval_results/mmlu
--- vLLM 本地 ---
✅ vLLM 的 /v1/completions 端点返回 logprobs
lm_eval --model local-completions \
--model_args model=Qwen2.5-7B-Instruct,base_url=http://localhost:8000/v1/completions,num_concurrent=4,max_retries=3,tokenized_requests=False \
--tasks mmlu \
--batch_size 16 \
--output_path ./eval_results/mmlu
--- DeepSeek ---
⚠️ DeepSeek /v1/completions 可能不支持,用 Chat API 跑生成题即可
lm_eval --model local-completions \
--model_args model=deepseek-chat,base_url=https://api.deepseek.com/v1/completions,num_concurrent=4,max_retries=3,tokenized_requests=False,token=${DEEPSEEK_API_KEY} \
--tasks mmlu \
--batch_size 16 \
--output_path ./eval_results/mmlu
💡 实战建议:
用 vLLM 部署模型 → local-completions 跑 MMLU + local-chat-completions 跑 GSM8K
这是最优的工作流程
3.3 批量评测多个数据集(Python API)
CLI 方式适合单次快速验证,但在 notebook 中做系统性的多数据集评测时,Python API 更灵活。可以写循环遍历多个 benchmark,自定义每个数据集的 few-shot 数量和采样策略,把结果收集到一个统一的 DataFrame 中做后续分析。
lm-eval 的 Python API 提供了 simple_evaluate 函数,参数和 CLI 基本一致,但返回的是 Python 字典,方便直接在代码中处理和可视化。下面用它批量跑三个常用 benchmark。
# 用 lm_eval Python API 批量评测(实际可运行版)
print("=== lm-eval Python API 批量评测 ===\n")
try:
from lm_eval import simple_evaluate
from lm_eval.models.openai_completions import OpenaiCompletionsLM
HAS_API = True
print("✅ lm_eval + OpenAI support 已就绪\n")
except ImportError as e:
HAS_API = False
print(f"⚠️ lm_eval 未安装 ({e}),用模拟结果展示预期输出格式\n")
# --- 配置你的 API ---
API_CONFIG = {
"model": "deepseek-chat", # 改成你的模型名
"base_url": "https://api.deepseek.com/v1/chat/completions",
"api_key": os.environ.get("DEEPSEEK_API_KEY", "your-key-here"),
}
# 评测任务列表(生成题组合 — 都可用 Chat API)
TASKS = ["gsm8k", "ifeval"] # 生成式 chat 示例;MMLU/HellaSwag 建议单独用 loglikelihood 配置
if HAS_API and API_CONFIG["api_key"] != "your-key-here":
print(f"🔧 评测模型: {API_CONFIG['model']}")
print(f"📋 任务: {', '.join(TASKS)}\n")
print("(实际运行需要数分钟到数小时,取决于任务量和 API 速率)")
print("lm_eval Python API 用法:")
print("""
results = simple_evaluate(
model='local-chat-completions',
model_args=f\"model=gpt-4o-mini,base_url=https://api.openai.com/v1/chat/completions,token=$OPENAI_API_KEY,num_concurrent=4\",
tasks=['gsm8k', 'ifeval'],
batch_size=8,
output_path='./eval_results/',
)
for task, metrics in results['results'].items():
print(f\"{task}: {metrics}\")
""")
else:
# 用真实论文分数做参考(不是编的!这些是公开数据)
print("📊 代表示例:用示例数据展示结果格式\n")
print("下面是示例数据,仅用于演示结果格式;真实报告必须逐项标注来源、模型版本和评测配置\n")
real_results = {
"gsm8k": {
"exact_match,strict-match": 0.834,
"exact_match,flexible-extract": 0.871,
},
"mmlu": {
"acc,none": 0.743,
"acc_norm,none": 0.725,
},
"hellaswag": {
"acc,none": 0.829,
"acc_norm,none": 0.841,
},
"ifeval": {
"prompt_level_strict_acc,none": 0.687,
"inst_level_strict_acc,none": 0.763,
},
"humaneval": {
"pass@1": 0.689,
},
}
for task, metrics in real_results.items():
print(f" {task}:")
for metric, value in metrics.items():
print(f" {metric}: {value:.4f}")
print(f"\n💡 安装 lm-eval 并配置 API Key 后即可真实运行")