帮你快速理解、总结文档立即下载
文档中心>弹性 MapReduce>TCRL 模型微调服务>COOKBOOK>Evaluation(评测)>Customizing Benchmarks(自定义基准测试)

Customizing Benchmarks(自定义基准测试)

最近更新时间:2026-10-19 21:38:00
我的收藏

共享的 Env 抽象

基准测试复用与 RL 训练相同的 Env 协议。两者的联系是直接的——BenchmarkBuilder.make_envs() 返回的 Env 实例与 RLDataset 中使用的完全一致:
RL Training Benchmark Evaluation
─────────── ────────────────────
RLDataset BenchmarkBuilder
└── EnvGroupBuilder └── make_envs()
└── make_envs() → list[Env] └── list[Env]
└── Env.step() → reward └── Env.step() → reward
两条路径都使用 EnvFromMessageEnv 把消息级环境适配到 token 级的 Env 接口。同一个 MessageEnv 实现可以同时驱动训练和评测——只需在任一场景下用 EnvFromMessageEnv 包装它。rollout 基础设施也是共享的:run_benchmark() 内部会调用 RL 模块中的 do_single_rollout()。
关于实现并注册基于 MessageEnv 的基准测试的完整示例,参见 添加新的基准测试。

系统提示词

提示词如何解析

每个基准测试都定义了一个能提升得分的 recommended_system_prompt(例如,数学基准测试会指示模型使用 \\boxed{})。运行器按以下顺序解析提示词:
1. BenchmarkConfig.system_prompt:如果设置了,始终优先
2. BenchmarkBuilder.recommended_system_prompt:当没有设置覆盖值时自动应用
3. 无系统提示词:如果两者都没有设置

按模型覆盖

不同模型可能需要不同的提示词策略。可以在配置层面覆盖:
# Thinking model — needs explicit formatting instruction
thinking_config = BenchmarkConfig.for_model(
"Qwen/Qwen3.6-35B-A3B",
system_prompt="Think step by step. Put your final answer in \\\\boxed{}.",
)

result = await run_benchmark("gsm8k", client, renderer, thinking_config)
print(f"thinking: {result.score:.1%}")

内置的推荐提示词

基准测试
recommended_system_prompt
gsm8k
"Put your final answer in \\boxed{}."
math500
"Put your final answer in \\boxed{}."
aime*, hmmt*
"Put your final answer in \\boxed{}."
mmlu_pro, gpqa, supergpqa
无(选择题格式说明放在用户提示词中)
ifeval
无
其他大多数
无

答案解析与评分

内置抽取工具

框架在 tinker_cookbook.eval.benchmarks._common 中提供了常用的答案抽取函数:
函数
用途
extract_boxed(text)
从 \\boxed{...} 中抽取内容(支持嵌套花括号)
extract_gsm8k_answer(text)
抽取数值答案——依次尝试 \\boxed{}、####、answer is,最后取最后一个数字
extract_mcq_answer(text)
抽取选择题选项字母(A/B/C/D)
extract_python_code(text)
从围栏代码块中抽取 Python 代码
check_gsm8k(response, expected)
带容差的浮点数比较
每个基准测试的 MessageEnv.step() 都使用这些函数来评分。抽取出的答案和预期答案会存入 logs 以便查看。

自定义评分函数

BenchmarkConfig.grade_fn 可以在不修改 Env 的情况下覆盖内置评分逻辑。运行器会在 rollout 完成后调用它,替换奖励值:
def my_grader(response: str, logs: Logs) -> float:
"""Custom grading function.

Args:
response: Last assistant turn (thinking stripped).
logs: Benchmark-specific fields — e.g., "expected", "input", "extracted".

Returns:
Reward value (typically 0.0 or 1.0).
"""
expected = logs["expected"]
# Use your own extraction logic
extracted = my_custom_extract(response)
return 1.0 if extracted == expected else 0.0

config = BenchmarkConfig(grade_fn=my_grader)
result = await run_benchmark("gsm8k", sampling_client, renderer, config)
这在以下情况下很有用:
内置抽取逻辑漏掉了你的模型使用的某种合法答案格式
你想要更宽松或更严格的评分标准
你需要特定领域的解析逻辑

无需重跑的重新评分

regrade_trajectories() 会用一个新评分函数处理已保存的轨迹——不需要再做模型推理:
from tinker_cookbook.eval.benchmarks import regrade_trajectories

# Try a more lenient grader on existing results
def lenient_grader(response: str, logs: Logs) -> float:
expected = logs["expected"]
# Accept answers with or without \\boxed{}
return 1.0 if expected in response else 0.0

regraded = regrade_trajectories("evals/run_01", "gsm8k", grade_fn=lenient_grader)
print(f"Original: {original.score:.1%}, Regraded: {regraded.score:.1%}")

裁判模型

像 arena_hard 这样的基准测试使用 LLM 裁判来评分。裁判与候选模型完全独立——不同的模型、不同的渲染器、不同的规模。

配置裁判

# Candidate model: the model being evaluated
candidate_client = await sc.create_sampling_client_async(model_path="tinker://run-abc/weights/final")
candidate_renderer = get_renderer("qwen3_5", candidate_tokenizer)

# Judge model: a separate, typically stronger model
judge_client = await sc.create_sampling_client_async(base_model="Qwen/Qwen3.5-397B-A17B")
judge_renderer = get_renderer("qwen3_5", judge_tokenizer)

config = BenchmarkConfig(
judge_sampling_client=judge_client,
judge_renderer=judge_renderer,
)

result = await run_benchmark("arena_hard", candidate_client, candidate_renderer, config)

评分如何工作

对于 arena_hard,流程如下:
1. 候选模型针对基准测试问题生成回答
2. 裁判模型接收问题与回答并打分(1-10)
3. 得分 >= 7 被判为正确
如果没有显式设置,裁判渲染器默认使用候选渲染器。

更换裁判

比较不同裁判对同一个模型的评分:
for judge_name, judge_client in judges.items():
config = BenchmarkConfig(
judge_sampling_client=judge_client,
judge_renderer=judge_renderer,
)
result = await run_benchmark("arena_hard", candidate_client, candidate_renderer, config)
print(f"Judge={judge_name}: {result.score:.1%}")

了解更多

评测概览:可用的基准测试与整体架构
基准测试指南:配置、存储、pass@k
RL 环境:与基准测试共享的 Env 协议