EvalScope 离线评测部署简记(华为910B ARM + OpenAI 兼容接口)
背景
需要在华为 910B (ARM64) 断网服务器上跑 EvalScope 评测框架,Mac 端预先拉 ARM 镜像和数据集,打包后 scp 到 910B 加载即可。覆盖通用知识、数学推理、代码、Agent/工具调用四个维度,共八个数据集。
评测框架
[EvalScope](https://github.com/modelscope/evalscope) 是 ModelScope 社区的一站式 LLM 评测框架,一条命令启动,支持模型能力评测、推理性能压测、结果可视化,内置 40+ 标准 Benchmark。本文使用 **v1.7.1**。
一、覆盖维度与数据集
| 维度 | 数据集 | 说明 |
|---|---|---|
| 通用知识 | MMLU | 57个学科多选,few-shot=5 |
| 通用知识 | C-Eval | 中文多学科多选,few-shot=5 |
| 通用知识 | GPQA Diamond | 研究生级物理/化学/生物难题 |
| 数学推理 | Minerva-Math | 数学解题,few-shot=0 |
| 长文本推理 | LongBench-v2 | 长上下文推理,取short子集 |
| 代码 | HumanEval | Python函数补全,pass@1 |
| 代码 | SWE-bench-mini | 真实GitHub issue修复,需Docker |
| Agent/工具调用 | BFCL-v4 | 函数调用评测(多语言/多轮) |
| Agent | tau_bench | 多轮Agent交互评测 |
数据通过 ModelScope Hub 下载,本地缓存在 `modelscope_cache/`,总计约 718MB。
二、ARM64 离线镜像构建
2.1 依赖
在 Intel Mac 上通过 QEMU user 仿真构建 ARM64 镜像:
# 启动 ARM64 容器
docker run -d --name evalscope-build --platform linux/arm64 \
-v $PWD:/workspace python:3.10-slim-bookworm sleep 7200
# 系统依赖
docker exec evalscope-build apt-get install -y build-essential ca-certificates \
curl docker.io git git-lfs jq patch tini
# Python 依赖
docker exec evalscope-build pip install \
'evalscope[swe-bench,bfcl]==1.7.1' \
modelscope datasets bfcl-eval swebench \
'git+https://github.com/sierra-research/tau-bench'
# commit & 导出
docker commit evalscope-build evalscope-offline:arm64
docker save evalscope-offline:arm64 | gzip > evalscope-offline-arm64.tar.gz
最终镜像 9.96GB(压缩后 6.2GB),含 torch 和相关 CUDA stub 库,不影响 910B 运行。
2.2 数据集预下载
python3 download_datasets.py --cache-dir modelscope_cache
python3 download_datasets.py --cache-dir modelscope_cacheModelScope 数据集 ID 映射:
| 数据集 | ModelScope ID |
|---|---|
| MMLU | `cais/mmlu` |
| C-Eval | `evalscope/ceval` |
| GPQA Diamond | `AI-ModelScope/gpqa_diamond` |
| LongBench-v2 | `ZhipuAI/LongBench-v2` |
| Minerva-Math | `knoveleng/Minerva-Math` |
| HumanEval | `opencompass/humaneval` |
| SWE-bench-mini | `evalscope/swe-bench-verified-mini` |
三、910B 离线部署
3.1 导入
scp evalscope-offline-arm64.tar.gz modelscope_cache/ user@910b:/data/eval/
# 在 910B 上
docker load -i /data/eval/evalscope-offline-arm64.tar.gz
3.2 前提:模型推理服务
scp evalscope-offline-arm64.tar.gz modelscope_cache/ user@910b:/data/eval/
# 在 910B 上
docker load -i /data/eval/evalscope-offline-arm64.tar.gz910B 上需运行一个 **OpenAI 兼容** 的 `/v1` API,例如 vLLM / SGLang / 自定义服务。格式要求:
- Endpoint: `http://127.0.0.1:8000/v1`
- 支持两个路由:
- `GET /v1/models` → 返回模型列表
- `POST /v1/chat/completions` → 标准 Chat Completions
- API Key 可任意填(如 ***),EvalScope 不校验但必传
3.3 运行评测
#### 通用/数学/代码 核心评测
docker run --rm --network host \
-e MODEL=你的模型名 \
-e API_URL=http://127.0.0.1:8000/v1 \
-e DATASETS="mmlu ceval gpqa_diamond longbench_v2 minerva_math humaneval" \
-e LIMIT=10 \
-v $PWD/modelscope_cache:/workspace/cache/modelscope \
-v $PWD/reports:/workspace/reports \
evalscope-offline:arm64 \
evalscope eval \
--model $MODEL \
--api-url $API_URL \
--api-key "***" \
--eval-type openai_api \
--dataset-hub modelscope \
--dataset-dir /workspace/cache/modelscope/datasets \
--datasets $DATASETS \
--limit $LIMIT \
--generation-config '{"temperature":0,"max_tokens":2048,"timeout":120,"retries":2}'
#### 单独跑某个数据集
# 只跑 MMLU
docker run ... --datasets mmlu --limit 10 ...
# 只跑 HumanEval
docker run ... --datasets humaneval --limit 10 ...
# 只跑 GPQA Diamond
docker run ... --datasets gpqa_diamond --limit 10 ...
#### SWE-bench(需要 Docker socket)
docker run --rm --network host \
-e MODEL=你的模型名 \
-e API_URL=http://127.0.0.1:8000/v1 \
-e LIMIT=1 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $PWD/modelscope_cache:/workspace/cache/modelscope \
-v $PWD/reports:/workspace/reports \
evalscope-offline:arm64 \
evalscope eval \
--model $MODEL \
--api-url $API_URL \
--api-key "***" \
--eval-type openai_api \
--dataset-hub modelscope \
--dataset-dir /workspace/cache/modelscope/datasets \
--datasets swe_bench_verified_mini \
--limit $LIMIT \
--dataset-args '{"swe_bench_verified_mini":{"extra_params":{"force_arch":"arm64"}}}' \
--generation-config '{"temperature":0,"max_tokens":4096,"timeout":300,"retries":1}'
#### BFCL-v4 工具调用
docker run --rm --network host \
-e MODEL=你的模型名 \
-e API_URL=http://127.0.0.1:8000/v1 \
-e LIMIT=3 \
-v $PWD/modelscope_cache:/workspace/cache/modelscope \
-v $PWD/reports:/workspace/reports \
evalscope-offline:arm64 \
evalscope eval \
--model $MODEL \
--api-url $API_URL \
--api-key "***" \
--eval-type openai_api \
--dataset-hub modelscope \
--dataset-dir /workspace/cache/modelscope/datasets \
--datasets bfcl_v4 \
--limit $LIMIT \
--dataset-args '{"bfcl_v4":{"subset_list":["simple_python","simple_java","simple_javascript","multiple","parallel","parallel_multiple","irrelevance","multi_turn_base"],"extra_params":{"underscore_to_dot":true,"is_fc_model":true}}}' \
--generation-config '{"temperature":0,"max_tokens":2048,"timeout":180,"retries":2}'
#### tau_bench Agent
docker run ... --datasets tau_bench \
--dataset-args '{"tau_bench":{"extra_params":{"user_model":"你的模型名","api_key":"***","api_base":"http://127.0.0.1:8000/v1"}}}' \
--limit 3 ...
四、OpenAI 标准接口适配
EvalScope `openai_api` 模式要求的接口格式:
GET /v1/models
{
"object": "list",
"data": [{"id": "your-model", "object": "model"}]
}
POST /v1/chat/completions
{
"object": "list",
"data": [{"id": "your-model", "object": "model"}]
}请求格式(EvalScope 发送的格式):
{
"model": "your-model",
"messages": [
{"role": "system", "content": "..."},
{"role": "user", "content": "..."}
],
"temperature": 0,
"max_tokens": 2048
}
BFCL 工具调用时会额外发 `tools` 字段:
{
"model": "your-model",
"messages": [...],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "...",
"parameters": {...}
}
}
],
"tool_choice": "auto"
}
返回格式:
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"model": "your-model",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "回答内容"
},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 100, "completion_tokens": 50, "total_tokens": 150}
}
工具调用返回时,content 为 null,改为 tool_calls:
{
"choices": [{
"message": {
"role": "assistant",
"content": null,
"tool_calls": [{
"id": "call_xxx",
"type": "function",
"function": {"name": "get_weather", "arguments": "{\"city\":\"Beijing\"}"}
}]
},
"finish_reason": "tool_calls"
}]
}
如果你的模型服务不是标准 OpenAI 格式,最简单的办法是写一个适配层(FastAPI/Flask),把标准格式翻译成你的模型格式。Mock 适配示例:
from fastapi import FastAPI
import httpx
app = FastAPI()
@app.get("/v1/models")
async def models():
return {"object": "list", "data": [{"id": "my-model", "object": "model"}]}
@app.post("/v1/chat/completions")
async def chat(req: dict):
# 翻译成你的 910B 模型实际格式
your_payload = {
"prompt": req["messages"][-1]["content"],
"max_new_tokens": req.get("max_tokens", 2048),
"temperature": req.get("temperature", 0),
}
async with httpx.AsyncClient() as client:
resp = await client.post("http://127.0.0.1:9090/generate", json=your_payload)
result = resp.json()
return {
"id": "chatcmpl-xxx",
"object": "chat.completion",
"model": req["model"],
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": result["text"]},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0}
}
五、关键参数说明
| 参数 | 含义 | 建议值 |
|---|---|---|
| `--limit` | 每个数据集跑几条 | 测试用 3-10,正式跑不设 |
| `--temperature` | 生成温度,影响确定性 | 评测用 0 |
| `--max-tokens` | 最大输出 token 数 | 2048(代码类 4096) |
| `--timeout` | 单条请求超时秒数 | 120-300,视模型速度定 |
| `--retries` | 失败重试次数 | 2 |
| `--few_shot_num` | MMLU/C-Eval 的 few-shot 示例数 | 5 |
| `--subset_list` | 只跑指定子集 | BFCL 必设,否则极慢 |
六、注意事项
1. **断网环境**: 镜像和数据都已预烘焙,`HF_HUB_OFFLINE=1` 确保不走网络
2. **SWE-bench 需要 Docker**: 910B 上要有 Docker daemon,运行时 `-v /var/run/docker.sock:/var/run/docker.sock`
3. **BFCL 排除 web_search**: 离线环境无 SERPAPI key,跳过 `web_search_*` 子集
4. **torch/NVIDIA 包**: 镜像自带 torch-2.12.0 ARM64 CPU 版本和 CUDA stub,体积大但不影响运行——EvalScope 通过 HTTP API 调用模型,不走本地 GPU 推理
5. **内存**: 10GB 镜像 + 数据集加载,建议 910B 节点 >= 32GB 内存
简记。







