- Allow --dataset swe_bench_verified,swe_bench_lite to pre-pull multiple SWE-bench variants in one run. - Validate dataset keys before loading. - Update myread.md with multi-dataset example.
23 KiB
EvalScope 评测手册(DeepSeek-V4-Flash-INT8 no-thinking)
本手册记录基于 EvalScope 对 DeepSeek-V4-Flash-INT8(no-thinking 模式)进行能力评测的完整流程,包括代码/数据/镜像下载、环境搭建、benchmark 选择、参数配置、Docker 一键评测和结果收集。
1. 项目结构
/data1/sora/evalscope/
├── bash/ # Python 评测入口脚本
│ ├── run.py # 唯一主入口
│ ├── collect_results.py # 结果汇总成 Excel/CSV
│ ├── perf_backup.py # 断点续跑的 perf 持久化备份
│ └── pull_swe_bench_images.py # 预拉 SWE-bench 实例镜像
├── scripts/ # Shell 辅助脚本
│ ├── run_docker_full.sh
│ ├── run_docker_lite.sh
│ └── run_docker_group.sh
├── config/ # 评测参数配置文件
│ └── dpv4-int8_nothinking.yaml
├── evalscope/ # EvalScope 源码(pip install -e .)
├── datasets/ # 评测数据缓存
├── output/ # 默认输出目录
├── docker/ # Docker 镜像/数据根目录
│ ├── images/ # Docker data-root
│ └── containerd/ # containerd root
├── scritps -> bash/ # 兼容旧路径的软链接
└── tools/docker/ # Docker 镜像构建相关
目录职责
| 目录 | 作用 |
|---|---|
bash/ |
可直接执行的 Python 入口脚本。run.py 是统一评测入口,collect_results.py 用于结果汇总,perf_backup.py 维护断点续跑的持久化备份,pull_swe_bench_images.py 用于预拉 SWE-bench 镜像。 |
scripts/ |
Shell 辅助脚本,例如宿主机一键启动 Docker 容器。 |
config/ |
YAML 配置文件,集中管理各 benchmark 的 max_tokens、temperature 等参数。 |
evalscope/ |
EvalScope 源码,通过 pip install -e . 安装。 |
datasets/ |
评测数据缓存目录。 |
output/ |
默认评测结果输出目录。 |
docker/images/ |
Docker data-root,存放所有拉取的镜像层。 |
docker/containerd/ |
containerd root,存放镜像元数据。 |
注意:
scritps是历史遗留的目录名(拼写错误),已通过软链接指向bash/。请统一使用bash/run.py。
2. 资源准备
评测前需要准备四类资源:代码、数据、Docker 环境镜像、Docker 执行镜像。下面分别说明下载/加载方式。
2.1 Code(评测入口与配置)
- 仓库地址:
https://git.meta-stone.net/sora/evalstone.git - 推荐版本:
798c3d06ab298d7d6b7ed69915d9b01736653bc7 - 本地路径:
/data1/sora/evalscope
# 若已克隆,更新到指定 commit
cd /data1/sora/evalscope
git fetch origin
git checkout 798c3d06ab298d7d6b7ed69915d9b01736653bc7
# 若首次克隆
git clone https://git.meta-stone.net/sora/evalstone.git /data1/sora/evalscope
cd /data1/sora/evalscope
git checkout 798c3d06ab298d7d6b7ed69915d9b01736653bc7
该 commit 之后可能有新提交。建议先用
git log --oneline -5查看最新状态;如无特殊说明,默认使用上述版本。
2.2 Data(评测数据集)
数据集托管在 ModelScope:SoraAmami/evalscope-datasets
pip install modelscope
modelscope login --token ms-3d554a39-6e07-496d-8022-0b0ee64a6389
python3 -c "
from modelscope.hub.snapshot_download import snapshot_download
snapshot_download(
'SoraAmami/evalscope-datasets',
repo_type='dataset',
cache_dir='/data1/sora/evalscope',
local_dir='/data1/sora/evalscope'
)
"
下载完成后目录结构:
/data1/sora/evalscope/
├── datasets/ # benchmark 数据
│ ├── AI-ModelScope_gsm8k-*/
│ └── ...
└── ...
不要把
dataset_dir指向已经包含datasets/子目录的路径(例如/data1/sora/evalscope/datasets),否则 evalscope 会到datasets/datasets/下重新查找/下载,造成数据重复。应指向父目录/data1/sora/evalscope。也不要直接用
MsDataset.load()加载整个数据集,因为不同 benchmark 的 schema 不同,会报CastError: column names don't match。
2.3 Docker 环境镜像(evalscope-complete-py312)
该镜像包含 Python 3.12 + EvalScope 全部依赖,是主要运行环境。
方式一:从本地 tar.gz 加载(离线/已拷贝)
docker load -i /data1/sora/evalscope/docker/evalscope-complete-py312.tar.gz
docker images | grep evalscope-complete-py312
方式二:从 ModelScope 下载
pip install modelscope
modelscope login --token ms-3d554a39-6e07-496d-8022-0b0ee64a6389
python3 -c "
from modelscope.hub.file_download import model_file_download
model_file_download(
model_id='SoraAmami/evalscope-docker',
file_path='evalscope-complete-py312.tar.gz',
local_dir='/data1/sora/evalscope/docker'
)
"
docker load -i /data1/sora/evalscope/docker/evalscope-complete-py312.tar.gz
docker images | grep evalscope-complete-py312
方式三:离线 tar.gz 拷贝
如果目标机器无法访问 ModelScope:
# 在源机器导出
# docker save -o evalscope-complete-py312.tar.gz evalscope-complete-py312:latest
# 在目标机器加载
docker load -i /path/to/docker/evalscope-complete-py312.tar.gz
docker images | grep evalscope-complete-py312
此方式只拷贝 evalscope 运行环境,数据集仍需单独拷贝或下载。
2.4 Docker 执行镜像(代码 sandbox 与 SWE-bench)
这些镜像用于在容器内执行被测代码,主要包括:
| 镜像 | 用途 |
|---|---|
bigcodebench/bigcodebench-evaluate:latest |
bigcodebench / humaneval 官方 sandbox |
bigcodebench-sandbox:latest |
基于官方镜像构建的守护态 sandbox |
python:3.11-slim |
通用代码执行环境 |
swebench/sweb.eval.x86_64.* |
SWE-bench 每个样本一个实例镜像 |
2.4.1 配置 Docker(国内镜像加速 + 大容量存储路径)
SWE-bench 镜像数量多、体积大,建议把 Docker data-root 和 containerd root 都迁移到 /data1 大容量盘:
# 1. 停止 Docker
systemctl stop docker.socket
systemctl stop docker
systemctl stop containerd
# 2. 创建新的数据目录
mkdir -p /data1/sora/evalscope/docker/images
mkdir -p /data1/sora/evalscope/docker/containerd
# 3. 配置国内镜像加速(多填几个,自动轮询)
cat > /etc/docker/daemon.json <<'EOF'
{
"data-root": "/data1/sora/evalscope/docker/images",
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1ms.run",
"https://docker.1panel.live",
"https://hub.rat.dev",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://dockerproxy.com",
"https://docker.mirrors.aliyun.com",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.nju.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://docker.mirrors.tuna.tsinghua.edu.cn"
]
}
EOF
# 4. 配置 containerd 数据目录
cat > /etc/containerd/config.toml <<'EOF'
root = "/data1/sora/evalscope/docker/containerd"
state = "/run/containerd"
EOF
# 5. 重启
systemctl reset-failed docker.service
systemctl start containerd
systemctl start docker
2.4.2 拉取/构建代码执行镜像
# bigcodebench 官方镜像
docker pull bigcodebench/bigcodebench-evaluate:latest
# 构建守护态 sandbox
docker build -t bigcodebench-sandbox:latest -f - . <<'EOF'
FROM bigcodebench/bigcodebench-evaluate:latest
ENTRYPOINT []
CMD ["tail", "-f", "/dev/null"]
EOF
# 通用 Python 执行环境
docker pull python:3.11-slim
验证:
docker images | grep -E 'evalscope-complete-py312|bigcodebench|python:3.11-slim'
2.4.3 预拉 SWE-bench 实例镜像(可选,强烈建议)
SWE-bench 每个样本一个独立 Docker 镜像,评测时再拉会极慢,且容易触发限流。建议提前批量预拉:
cd /data1/sora/evalscope
export USE_MODELSCOPE_HUB=1
export HF_ENDPOINT=https://hf-mirror.com
export PYTHONUNBUFFERED=1
# 推荐单 worker,避免触发限流
python bash/pull_swe_bench_images.py \
--dataset swe_bench_verified \
--max-workers 1
# 也可以同时预拉多个数据集(逗号分隔)
python bash/pull_swe_bench_images.py \
--dataset swe_bench_verified,swe_bench_lite \
--max-workers 1
脚本特性:
- 断点续传:状态文件
output/.swe_bench_pull_state.json,中断后再次运行会自动跳过已成功的镜像。 - 本地已有镜像自动跳过。
- 单 worker 模式稳定,减少限流概率;若网络非常好,可适当提高
--max-workers。 --dataset支持逗号分隔的多个数据集。
镜像会存到 Docker data-root 配置的路径:
/data1/sora/evalscope/docker/images/
如果拉取过程中频繁失败,可尝试:
- 换一个 registry-mirror;
- 降低
--max-workers到 1;- 使用
tmux挂后台运行,避免 SSH 断连导致中断。
3. 环境准备
3.1 方式一:本地 Conda 环境
conda create -n evalscope python=3.12 -y
conda activate evalscope
cd /data1/sora/evalscope
cd evalscope && pip install -e . && cd ..
# 关键依赖
pip install 'evalscope[terminal_bench,swe_bench,openai_mrcr]'
pip install git+https://github.com/sierra-research/tau2-bench@v0.2.0
pip install openpyxl # 用于结果汇总
3.2 方式二:Docker 一键环境(推荐多机复用)
除 swe_bench 系列外,其他 benchmark 均可直接运行。
运行容器:
mkdir -p /data1/sora/evalscope/output
docker run -it --rm \
--network host \
-v /data1/sora/evalscope:/opt/evalscope \
-v /data1/models:/opt/models \
-v /var/run/docker.sock:/var/run/docker.sock \
evalscope-complete-py312:latest \
bash
# 容器内
cd /opt/evalscope
python bash/run.py --help
数据集路径注意:evalscope 会在
--dataset-dir后自动拼接datasets/子目录查找数据。若数据在/data1/sora/evalscope/datasets/,则--dataset-dir应填/data1/sora/evalscope,不要填/data1/sora/evalscope/datasets。
4. 统一入口:bash/run.py
所有评测都通过这一个脚本启动,全部参数均可通过命令行控制。
4.1 常用示例
cd /data1/sora/evalscope
# 1) Full 全量评测(约 75h,CSV 实测完整时间,已含 multi-run)
python bash/run.py \
--model DeepSeek-V4-Flash-Int8 \
--api-url http://localhost:30000/v1 \
--dataset-dir /data1/sora/evalscope \
--output-dir /data1/sora/evalscope/output \
--suite full \
--limit none
# 2) Lite 快速冒烟(约 5h)
python bash/run.py --suite lite --limit none
# 3) Lite 自己选 benchmark
python bash/run.py \
--datasets humaneval,aime24,gsm8k,arc,longbench_v2,general_fc \
--limit 20
# 4) 只跑某几个 benchmark
python bash/run.py --datasets aime24,gsm8k --limit none
# 5) 多机分组:group1 / group2 / group3
python bash/run.py --suite group1 --limit none
python bash/run.py --suite group2 --limit none
python bash/run.py --suite group3 --limit none
# 6) 从某个 suite 中排除特定 benchmark
python bash/run.py --suite full --exclude hle,trivia_qa --limit none
# 7) 开启 thinking 模式
python bash/run.py --suite lite --thinking
# 8) 换模型或 API 地址
python bash/run.py --model MyModel --api-url http://10.0.0.5:30000/v1
4.2 参数说明
| 参数 | 默认值 | 说明 |
|---|---|---|
--model |
DeepSeek-V4-Flash-Int8 |
模型名,会传给 OpenAI API 的 model 字段 |
--api-url |
http://localhost:30000/v1 |
模型服务地址 |
--dataset-dir |
/data1/sora/evalscope |
数据集父目录,evalscope 会自动找其下的 datasets/ |
--output-dir |
/data1/sora/evalscope/output |
评测输出根目录 |
--config |
config/dpv4-int8_nothinking.yaml |
各 benchmark 的 max_tokens / temperature 等配置 |
--tokenizer-path |
/data1/models/DeepSeek-V4-Flash-INT8 |
本地 tokenizer 路径,用于长文本 middle-truncation |
--suite |
full |
预置套件:full / lite / mid / group1 / group2 / group3 |
--datasets / --benchmarks |
None |
逗号分隔自定义 benchmark 列表,会覆盖 --suite |
--exclude |
None |
从当前 suite 中排除的 benchmark |
--limit |
None |
每数据集最多跑几条;none / all 表示全量 |
--seed |
42 |
随机种子 |
--batch-size |
4 |
评测并发 |
--thinking |
False |
开启 sglang thinking 模式 |
--no-thinking |
False |
关闭 thinking 模式(默认) |
--judge-model |
DeepSeek/DeepSeek-V4-Pro |
裁判模型名(LLM-as-judge) |
--judge-api-url |
Vectron 地址 | 裁判模型 API 地址 |
--judge-api-key |
内置 key | 裁判模型 API key |
--judge-max-tokens |
10240 |
裁判模型最大输出长度 |
--truncation-tokens |
131072 |
长文本 middle-truncation token 上限 |
--no-summary |
False |
禁止每次 benchmark 后自动写汇总表 |
汇总表文件名由模型名自动派生,例如
--model DeepSeek-V4-Flash-Int8→<safe_model_name>.csv/.xlsx。
4.3 套件详情
| 套件 | 覆盖 benchmark | 预计时间 | 说明 |
|---|---|---|---|
full |
全部 | 约 75h | CSV 实测完整时间,已含 multi-run |
lite |
各领域代表作 | 约 5h | 快速冒烟,覆盖代码/数学/知识/长文本/Agent |
mid |
较全子集 | 约 25h | 平衡速度与覆盖 |
group1 |
代码 + 数学/推理 | 约 22h | 多机组 1 |
group2 |
重知识 | 约 26h | 多机组 2 |
group3 |
长文本 + Agent + 知识 | 约 27h | 多机组 3 |
分组时间说明
CSV 中记录的是完整评测时间(已包含 multi-run),总约 75h。因此分组直接按 CSV 实测时间平衡:Group1 ~22h、Group2 ~26h、Group3 ~27h,合计 ~75h。
4.4 Multi-run 配置
以下 benchmark 会重复跑多次,再取平均:
| Benchmark | 次数 | 目的 |
|---|---|---|
aime24 / aime25 / aime26 / hmmt26 |
12 | 样本少(各 30 题),多次采样稳定结果 |
live_code_bench |
5 | 约 100 样本,多次采样 |
imo_answerbench |
4 | 约 120 样本 |
humaneval |
3 | 约 164 样本 |
gpqa_diamond |
2 | 约 198 样本 |
multi-run 次数在 bash/run.py 的 MULTI_RUN_CONFIG 中固定,暂不提供命令行覆盖。
5. 配置文件
路径:config/dpv4-int8_nothinking.yaml
每个 benchmark 可独立配置:
aime24:
generation_config:
temperature: 1.0 # 多次采样用 1.0
top_p: 1.0
stream: true
max_tokens: 32768
longbench_v2:
generation_config:
temperature: 0.0 # 长文本贪心
top_p: 1.0
stream: true
max_tokens: 8192
dataset_args:
subset_list:
- short
- medium
- long
如需换模型,通常只需改 bash/run.py 的命令行参数,不需要改 YAML。
6. 长文本截断
longbench_v2 和 openai_mrcr 默认启用 middle-truncation,上限由 --truncation-tokens 控制(默认 128k)。
- 对
longbench_v2:保留 context 头部和尾部,截断中间。 - 对
openai_mrcr:保留对话头尾及 needle 附近窗口,并限制单条消息长度。
如需关闭截断:
python bash/run.py --suite full --truncation-tokens 0
7. 结果汇总:bash/collect_results.py
跑完 benchmark 后,自动或手动汇总分数到 Excel/CSV。
7.1 自动汇总(run.py 每次跑完都会更新)
run.py 会在每个 benchmark 结束后自动调用 collect_results.py,在按模型名分目录的位置生成:
<output-dir>/
└── <safe_model_name>/ # 按模型名分目录,目录和文件名均由 --model 自动派生
├── <safe_model_name>.xlsx
└── <safe_model_name>.csv
例:--model DeepSeek-V4-Flash-Int8 → /data1/sora/evalscope/output/DeepSeek-V4-Flash-Int8/DeepSeek-V4-Flash-Int8.csv。
7.2 手动汇总
# 汇总所有已跑完的 benchmark(默认行为)
python bash/collect_results.py \
--output-dir /data1/sora/evalscope/output \
--model DeepSeek-V4-Flash-Int8
# 只汇总指定 benchmark(推荐,跟 run.py 自动汇总行为一致)
python bash/collect_results.py \
--output-dir /data1/sora/evalscope/output \
--model DeepSeek-V4-Flash-Int8 \
--include aime24,gsm8k,arc,longbench_v2
# 可选:--out-name 自定义文件名(默认就是 safe model name)
7.3 汇总规则
- 只统计本次实际跑的 benchmark:
run.py会维护一个白名单,只把当前这次运行涉及的 benchmark 传给汇总脚本。因此,如果本次只跑了aime24,gsm8k,arc,汇总表里也只会出现这 3 个,不会把 output 目录里以前跑的其它 benchmark 一起拉进来。 - 对同一个 benchmark 的多个 seed/run,分数取平均。
- 性能指标(latency、TTFT、TPOT、TPS 等)从所有 run 的原始
predictions/*.jsonl重新聚合,避免断点续跑时从 0 重置。 - 输出格式与
/data1/sora/evalscope/P800模型能力评测结果 - DS4-Flash-INT8-NO-Thinking-2.0-FULL.csv保持一致。
7.4 断点续跑统计修复
问题:evalscope 在运行时会把所有样本的累计统计写入 reports/*.json 里的 perf_metrics.summary(旧版本会写到独立的 perf_stats.json),并在 predictions/*.jsonl 里记录每条样本的原始 perf 数据。如果一次 benchmark 需要跑很久,中间断点续跑时这个累计 summary 会被重新初始化(只反映本次重启之后的样本),导致汇总表里 latency / TTFT / TPOT / 总 tokens / 总耗时全部从 0 开始重新计算,出现严重低估。
修复思路:保留 report.json 里的累计 summary,但额外维护两份独立于 evalscope 的持久化文件:
| 文件 | 内容 | 用途 |
|---|---|---|
perf_stats_backup/<benchmark>__<model>.json |
最近一次完整跑完的 perf_metrics.summary |
累计 summary 的稳定副本,避免被重启覆盖 |
predictions_archive/<benchmark>__<model>.jsonl |
历次 run 所有样本的原始记录,按 index 去重 |
重建 latency / TTFT / TPOT 的真实分布(含 P90/P99) |
每次 run_task() 完成后,run.py 会自动调用 bash/perf_backup.py:
- 把当前
reports/<model>/<benchmark>.json里的perf_metrics.summary复制到perf_stats_backup/<benchmark>__<model>.json。如果 backup 的n_samples已经大于新 summary(即检测到 reset),则保留旧 backup,避免覆盖。 - 把当前
predictions/<model>/*.jsonl的每条样本按index去重追加到predictions_archive/<benchmark>__<model>.jsonl,支持多次断点的样本累积。
每次下一个 run 开始前,run.py 会调用 restore_from_backup():如果 backup 存在,就把 archive 还原回 predictions/<model>/ 并把 summary 还原回 report.json 的 perf_metrics.summary,让 evalscope 的 use_cache resume 机制能从更大的历史状态继续。
collect_results.py 读取汇总时的优先级:
- 优先读
predictions_archive/<benchmark>__<model>.jsonl,按index去重得到所有历史样本,从原始 perf_metrics 重新计算 latency / TTFT / TPOT 的 mean、P90、P99、QPS、TPS、总 tokens。 - 没有 archive 时,读
predictions/<model>/*.jsonl(当前 predictions)。 - 都没有时,回退到
perf_stats_backup/<benchmark>__<model>.json的 summary。 - summary 里
n_samples比 backup 大就用 summary,否则用 backup 里的累计值。
7.5 验证断点续跑确实能恢复
# 1. 模拟 report.json 被重置(n_samples 改成 2)
# 2. 不动 predictions 和 archive
# 3. 跑 collect_results
# 期望:汇总表仍显示 30 个样本的真实指标
实际验证结果:把 aime24/report.json 的 n_samples 改成 2 后再汇总,得分仍是 0.6167、耗时 1.22h、TTFT/TPOT 正常值,证明 archive 修复确实生效。
8. 输出目录结构
<output-dir>/
├── <benchmark_name>/
│ ├── seed_<seed>/
│ │ ├── reports/<model_name>/<benchmark_name>.json
│ │ ├── predictions/<model_name>/<benchmark_name>.jsonl
│ │ └── logs/eval_log.log
│ └── seed_<seed>_run_<idx>/ # multi-run 额外目录
├── perf_stats_backup/ # 累计 summary 持久化(断点恢复)
│ └── <benchmark>__<model>.json
├── predictions_archive/ # 原始每条样本归档(断点恢复)
│ └── <benchmark>__<model>.jsonl
└── <safe_model_name>/ # 汇总表(按模型名)
├── <safe_model_name>.xlsx
└── <safe_model_name>.csv
查看分数
# 单个 benchmark
cat output/aime24/seed_42/reports/DeepSeek-V4-Flash-Int8/aime24.json
# 汇总所有分数
python3 -c "
import json, glob
for f in sorted(glob.glob('output/*/seed_*/reports/*/*.json')):
data = json.load(open(f))
score = data.get('score', data.get('mean_acc', 'N/A'))
print(f'{f}: {score}')
"
9. 最终 Benchmark 集合
| 能力域 | Benchmark |
|---|---|
| 代码生成 | humaneval, live_code_bench, bigcodebench |
| 推理/数学 | aime24, aime25, aime26, hmmt26, imo_answerbench, gsm8k, competition_math, bbh, drop |
| 知识 | gpqa_diamond, hle, mmlu_pro, simple_qa, super_gpqa, mmlu, cmmlu, arc, hellaswag, trivia_qa, winogrande |
| 长上下文 | longbench_v2, openai_mrcr |
| 智能体/工具 | tau2_bench, general_fc, bfcl_v3 |
未纳入标准流程的:
swe_bench_pro/swe_bench_verified/swe_bench_multilingual_agentic:每个样本需独立 Docker 镜像,建议按 2.4.3 预拉后单独运行。browsecomp/mcp_atlas:需要外部 MCP 搜索工具。terminal_bench_v2:镜像兼容性问题。
10. 常见问题
Q1: Docker 里找不到 datasets?
确保 --dataset-dir 指向包含 datasets/ 的父目录,而不是 datasets/ 本身。
Q2: bigcodebench 或 humaneval 报 sandbox 错误?
检查是否已准备镜像:
docker images | grep -E 'bigcodebench-sandbox|python:3.11-slim'
Q3: 只想跑某个 benchmark 怎么办?
python bash/run.py --datasets aime24 --limit none
Q4: 想换 judge model?
python bash/run.py \
--judge-model deepseek-v4-pro \
--judge-api-url https://api.deepseek.com/v1 \
--judge-api-key sk-xxx
Q5: 断点续跑后 perf 指标被重置?
run.py 会在每次 benchmark 后把 perf_metrics.summary 和 predictions 备份到 output/perf_stats_backup/ 和 output/predictions_archive/;汇总时优先从 archive 重新计算,因此断点重启不会导致指标被低估。同时汇总表只包含本次运行实际跑的 benchmark。
Q6: SWE-bench 镜像拉取慢/被限流?
- 按 2.4.1 配置多 mirror;
- 使用
--max-workers 1单 worker 拉取; - 用
tmux或nohup挂后台,避免 SSH 断连; - 若某个 mirror 完全不可用,从
daemon.json中移除,避免无效重试。