exo 如何用 exo_eval 跑 GPQA Diamond、MMLU Pro、AIME 等质量评测并读取结果?
【免费下载链接】exoRun frontier AI locally.项目地址: https://gitcode.com/GitHub_Trending/exo8/exo
如果你已经用 exo 把模型部署在本地集群上,想用一个标准化的基准来量化它的答题质量——而不是只看聊天效果——可以用 exo 自带的评测脚本 bench/exo_eval.py。该脚本针对 exo 的 OpenAI 兼容 API 发起评测请求,其提示词、温度设置与答案抽取方式对齐 Artificial Analysis 的评测方法。前提是节点已通过uv run exo运行起来(见 README 中 benchmarking 一节的前置要求),API 与 dashboard 在http://localhost:52415/。
exo_eval 支持哪些评测任务
脚本内置 6 个任务,数据集在运行时通过datasets.load_dataset从 HuggingFace 加载(定义见 bench/exo_eval.py 中的BENCHMARKS):
| 任务名 | 数据集 | split | 规模与题型 |
|---|---|---|---|
gpqa_diamond | Idavidrein/gpqa(configgpqa_diamond) | train | 198 题,4 选 1 单选 |
mmlu_pro | TIGER-Lab/MMLU-Pro | test | 12K 题,10 选 1 单选 |
aime_2024 | HuggingFaceH4/aime_2024 | train | 30 题,整数答案 |
aime_2025 | MathArena/aime_2025 | train | 30 题,整数答案 |
humaneval | openai/openai_humaneval | test | 164 题,代码生成 pass@1 |
livecodebench | livecodebench/code_generation_lite | test | 880+ 题,代码生成 pass@1 |
本文聚焦标题中的gpqa_diamond、mmlu_pro、aime_2024/aime_2025;它们都是选择题或整数答案题,评分只靠答案抽取,不执行任何模型生成的代码。
前置条件
- exo 集群在运行:README 明确要求“Nodes should be running with
uv run exobefore benchmarking”。脚本默认连localhost:52415,也可用--host/--port(或环境变量EXO_HOST/EXO_PORT)指向其他机器上的 master,这些公共参数定义在 tools/src/exo_tools/harness.py。 - 脚本依赖:bench/pyproject.toml 声明 Python
>=3.13,依赖包括datasets、math-verify(AIME 答案校验的兜底解析)、human-eval、lm-eval等。 - HuggingFace 登录(视数据集而定):加载数据集时如果遇到需要授权的(gated)数据集,脚本会报错并提示执行
huggingface-cli login。 - 模型可解析:
--model必填,接受模型 short id 或 HuggingFace id。加--force-download时,若/models里没有该模型,脚本会通过 exo 从 HuggingFace 添加并下载——注意这会触发一次模型下载。
执行评测:主路径命令
脚本 docstring 给出的原始用法是uv run python exo_eval.py ...。在仓库根目录下进入bench/后按此执行(脚本就位于 bench/exo_eval.py):
cd bench uv run python exo_eval.py --model <model-id> --tasks gpqa_diamond其中<model-id>是占位符,替换为你集群上要评测的模型 short id 或 HuggingFace id(例如 README 中 benchmark 示例用的Llama-3.2-1B-Instruct-4bit)。跑完 GPQA Diamond 后再换--tasks跑其他任务即可:
# MMLU Pro(12K 题,量大,建议先用 --limit 做小样) uv run python exo_eval.py --model <model-id> --tasks mmlu_pro --limit 100 # AIME 2024 / 2025 各 30 题,可以一次跑完 uv run python exo_eval.py --model <model-id> --tasks aime_2024,aime_2025运行后脚本自动完成一连串编排动作,了解它们有助于判断日志与副作用:
- 解析模型 id,等待集群产出可用 placement(
--settle-timeout默认 60 秒,0表示只试一次);placement 可用--max-nodes(默认 4)、--min-nodes(默认 1)、--sharding、--instance-meta过滤; - 需要时下载模型,完成后日志会打印
Download: Xs; - 评测开始前,脚本会先删除集群中已存在的所有实例以释放资源,再
POST /instance创建新实例并等待 ready。如果你的集群上还有正在服务的实例,先确认这一点; - 逐题向
{host}:{port}/v1/chat/completions发请求(默认并发--num-concurrent 1); - 评测结束后默认删除自己创建的实例;加
--keep-instance可保留实例以串联多次运行,--reuse-instance则优先复用该模型已有的运行中实例。
生成参数如何决定
每题请求的temperature、top_p、max_tokens、top_k、min_p、reasoning_effort、enable_thinking按三级优先级取值:CLI 参数 > bench/eval_configs/models.toml 中的按模型配置 > 回退默认值。
- models.toml 中每个
[[model]]条目用patterns子串匹配 model id,第一个命中的条目生效,且 CLI flag 优先于文件内配置。文件内配置了 Qwen3.5 / Qwen3 / GPT-OSS / DeepSeek / Nemotron / GLM / Kimi / MiniMax / Step / Llama 等系列的推理温度与 max_tokens(取值来源在注释中注明,如模型卡与 generation_config.json)。 - 模型未命中任何条目时的回退默认(models.toml 文件头与脚本常量一致):reasoning 模型
temperature=1.0, max_tokens=131072, reasoning_effort="high";非 reasoning 模型temperature=0.0, max_tokens=16384。此时脚本会告警 “Model ... not found in eval_configs/models.toml. Defaulting to non-reasoning”,你可以用--reasoning或--no-reasoning强制指定。 - 手动覆盖参数:
--temperature、--top-p、--top-k、--min-p、--max-tokens、--reasoning-effort(取值low/medium/high)、--enable-thinking。
可选:快速迭代与并发对比
--limit N:每个 benchmark 最多评测 N 题,docstring 明确其用途是 fast iteration,适合先验证链路;--offset N跳过前 N 题。--num-concurrent N:并发请求数,默认 1。--compare-concurrency 1,4:按多个并发级别各跑一遍,最后输出对比表(每级的 Accuracy、Correct、Total、Comp Tokens、Wall Clock、Avg Gen TPS),并统计两种并发下答案正确性发生变化的题数,用于判断 batch 是否影响质量。docstring 中的示例:uv run python exo_eval.py --model <model-id> --tasks gpqa_diamond --compare-concurrency 1,4。--request-timeout:单请求超时(秒),默认不限时。--force:丢弃已有 checkpoint 从头跑,见下一节。
读取结果
控制台汇总。每个 benchmark 结束后脚本打印(格式见 bench/exo_eval.py 的print_results):
- 准确率行:
<task>: <correct>/<total> (<percent>%); - tokens 行:prompt + completion 总 token 数(含 reasoning token 时附注)、平均生成速度 avg gen tps、累计计算时间 total time 与实际耗时 wall clock;
- 若 API 返回了功耗数据,追加一行平均功率(W)与总能量(J / Wh);
- 出错情况:
API errors: N与No answer extracted: N(抽取不到答案的题目按错误处理)。
JSON 落盘。结果默认写入eval_results/目录(--results-dir可改),路径规则为eval_results/<model_id 中 / 替换为 _>/<task>/c<并发数>_<YYYYmmdd_HHMMSS>.json。文件包含scores(与上面汇总同构的指标)、cluster集群快照,以及每题的明细:prompt、response、extracted_answer、gold_answer、correct、token 数、finish_reason、耗时与功耗。成功信号是日志中的Results saved to <path>——拿到这个路径就表示结果已完整落盘,之后可用jq等工具按results[].correct复核任意一题。
评分逻辑(影响你怎么看结果):GPQA / MMLU Pro 从回答文本中用 8 个正则回退模式抽取选项字母,取文本位置最靠后的匹配(兼容推理中途自我纠正的模型);AIME 从最后的\boxed{...}抽取内容并做整数比对,解析失败时用math-verify兜底。
Checkpoint 断点续跑与实例故障
每个 benchmark 在结果目录下有c<并发数>.checkpoint.jsonl,每完成一题追加一行;整轮成功后 checkpoint 会被自动删除。
- 评测中途中断后,直接重跑同一条命令即可续跑:已完成的题从 checkpoint 读回(日志
Loaded N checkpointed results,对应题目标记(cached)),只补跑剩余题目。 - 若实例整体故障(脚本每 5 秒轮询
/models做健康检查,连续 3 次连接失败后确认实例不可达),会报错Instance failed! Completed X/Y problems. Checkpoint saved — restart to resume remaining problems.,按提示重跑即续传。 - 单题 API 调用本身最多重试 30 次,退避间隔按 2 的指数增长、上限 60 秒;因基础设施故障没拿到响应的题不会写入 checkpoint,续跑时会自动重试。
已知限制与副作用
- 代码类任务会执行模型生成的代码:
humaneval使用官方human_eval包、livecodebench使用 vendored 的 LCBrun_test在子进程中执行,脚本对此有明确警告“Code benchmarks execute model-generated code. Use a sandboxed environment.”。标题涉及的选择题与数学题不涉及执行;如果你要跑这两个任务,请在隔离环境中运行。 --difficulty(easy/medium/hard)与--release-version(如release_v5)仅对livecodebench生效。--danger-delete-downloads会从最小到最大删除集群中已有模型以为新模型腾空间,属破坏性开关,确认含义后再使用。- Nix 构建下同一脚本以
exo-eval包形式提供(见 python/parts.nix),无需手写 uv 命令。 - 集群 API 的完整端点说明可参考 docs/api.md。
【免费下载链接】exoRun frontier AI locally.项目地址: https://gitcode.com/GitHub_Trending/exo8/exo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考