lm-evaluation-harness 中的 OpenBookQA 任务:配置解析、评估原理与多语言变体实践
【免费下载链接】lm-evaluation-harnessA framework for few-shot evaluation of language models.项目地址: https://gitcode.com/GitHub_Trending/lm/lm-evaluation-harness
OpenBookQA(Open Book Question Answering)是艾伦人工智能研究所(AI2)于 2018 年发布的常识问答基准,专门考察模型在"开卷考试"场景下综合外部知识进行推理的能力。本文以 lm_eval/tasks/openbookqa/README.md 为核心骨架,结合其同名 YAML 配置 openbookqa.yaml 与框架源码,系统讲解该任务的数据集构成、逐字段配置含义、multiple_choice评测机制、acc/acc_norm指标原理、去污染设置,以及如何用lm-evaluation-harness实际运行评估,并延伸介绍仓库内已有的多语言 OpenBookQA 变体。读完本文,你将掌握一条"从数据集到 YAML 配置再到评测命令"的完整落地链路,并能举一反三地理解同类多项选择任务的实现方式。
一、OpenBookQA 数据集:为什么它是"开卷考试"
1.1 论文与数据集定位
OpenBookQA 对应的论文标题为Can a Suit of Armor Conduct Electricity? A New Dataset for Open Book Question Answering(Mihaylov 等,EMNLP 2018,arXiv 编号 1809.02789),数据集主页为 AI2 的 Open Book QA 页面。按仓库 README 的描述,该数据集模拟人类"开卷考试"的场景来评估对某一学科的理解能力,核心特征包括:
- 共5,957 道小学科学水平的多项选择题,划分为4,957 训练 / 500 开发 / 500 测试三个子集;
- 配套一本由1,326 条核心科学事实构成的"小书"(the book),题目用于检验对这些事实的理解及其在新颖情境下的应用;
- 训练集额外提供"题目 → 该题所考察的核心科学事实"的映射;
- 回答题目所需的常识远超书中内容,属于开放知识;
- 设计上刻意保证:基于检索的算法和基于词共现的算法都无法正确作答。
这些属性使 OpenBookQA 成为检验语言模型"知识运用 + 常识推理"能力的经典任务,也是本项目 lm_eval/tasks/README.md 中对其"需要外部知识与推理的开卷问答任务"定位的直接依据。
1.2 引用信息
在论文或技术报告中引用该数据集时,可直接使用 README 中给出的 BibTeX 条目:
@inproceedings{OpenBookQA2018, title={Can a Suit of Armor Conduct Electricity? A New Dataset for Open Book Question Answering}, author={Todor Mihaylov and Peter Clark and Tushar Khot and Ashish Sabharwal}, booktitle={EMNLP}, year={2018} }二、任务注册与仓库中的组织方式
2.1 任务命名与注册
README 明确指出当前实现的任务名为openbookqa(Groups and Tasks一节),且该任务尚未被归入任何 group("Not part of a group yet")。这意味着你可以直接用任务名openbookqa独立运行评测。
任务注册依赖 YAML 配置顶部的task字段。按照 docs/new_task_guide.md 的说明,位于lm_eval/tasks目录内的 YAML 文件只需声明task名即可被TaskManager自动发现;如需加载自定义路径,可通过--include_path或--tasks /path/to/yaml/file指定。仓库中该任务存放于 lm_eval/tasks/openbookqa/,由README.md与openbookqa.yaml两个文件组成——这正是项目推荐的"每个数据集一个子目录"的组织惯例。
2.2 版本元数据
配置底部携带metadata.version: 1.0。按 docs/task_guide.md 与 docs/new_task_guide.md 的约定,metadata用于记录任意附加信息,其中version键用于标记任务配置的版本号,任何破坏性修改都应递增版本以便结果对比。
三、openbookqa.yaml 逐字段深度解析
任务的完整配置如下(lm_eval/tasks/openbookqa/openbookqa.yaml):
task: openbookqa dataset_path: allenai/openbookqa dataset_name: main output_type: multiple_choice training_split: train validation_split: validation test_split: test doc_to_text: question_stem doc_to_target: "{{choices.label.index(answerKey.lstrip())}}" doc_to_choice: "{{choices.text}}" should_decontaminate: true doc_to_decontamination_query: question_stem metric_list: - metric: acc aggregation: mean higher_is_better: true - metric: acc_norm aggregation: mean higher_is_better: true metadata: version: 1.0下面按功能分组逐字段解读,字段语义可对照 docs/task_guide.md 中的TaskConfig参数说明。
3.1 数据源与切分(Dataset Configuration)
dataset_path: allenai/openbookqa:指定 Hugging Face Hub 上的数据集名称。框架的所有数据下载与管理都通过 HFdatasetsAPI 完成。dataset_name: main:HF 术语中的"数据实例"(data instance)或子配置名,对应datasets.load_dataset的第二个参数。OpenBookQA 使用默认的main配置。training_split: train/validation_split: validation/test_split: test:分别声明训练、验证、测试切分的名称。按框架约定,评测优先使用test_split,不可用时回退到validation_split;few-shot 示例默认按 train → validation → test 的顺序选取(也可用fewshot_split或fewshot_config显式覆盖)。
3.2 提示模板(Prompting)
三项doc_to_*字段共同定义了"把一条数据渲染成模型输入 + 目标输出"的规则:
doc_to_text: question_stem:直接引用数据集中的question_stem字段作为输入文本。数据集字段天然满足需求时,可直接写字段名而不必使用 Jinja2 模板(docs/new_task_guide.md 中称之为 basic prompt 用法)。doc_to_choice: "{{choices.text}}":Jinja2 模板,将数据集中的choices.text(一个长度为 4 的选项文本列表)渲染为候选答案列表。doc_to_target: "{{choices.label.index(answerKey.lstrip())}}":核心逻辑所在——数据集每条记录包含choices.label(形如["A","B","C","D"])和正确答案标识answerKey(如"A")。该模板先将answerKey用lstrip()去除可能的首部空白,再通过choices.label.index(...)求得正确答案在标签列表中的下标。这正是 docs/task_guide.md 中强调的约定:对于multiple_choice任务,doc_to_target应返回正确选项在doc_to_choice列表中的索引,而非文本本身。
提示格式的渲染约定值得注意:框架会在doc_to_text输出与doc_to_target输出之间插入默认的target_delimiter(一个空格),因此实际交给模型比对的完整串为doc_to_text(doc) + " " + doc_to_choice[doc_to_target(doc)](详见 docs/new_task_guide.md 的 multiple choice 格式一节)。这也解释了为什么在多项选择任务中,四个选项会各生成一条候选串与输入拼接,再逐条计算似然。
3.3 输出类型:multiple_choice 的评测机制
output_type: multiple_choice表明该任务属于判别式多项选择类型:模型不是自由生成文本,而是在固定候选集合中通过比较各选项的 loglikelihood 选出最可能的答案。与之并列的框架支持类型还包括generate_until(自由生成)、loglikelihood、loglikelihood_rolling。
在multiple_choice模式下,对每个文档,框架将doc_to_text与每个选项(经target_delimiter拼接)组合成多条"输入+候选续写"对,分别请求模型的 loglikelihood,最后取似然最高的选项作为预测。这种机制不要求模型输出任何文字,只依赖其词元级概率分布,是多项选择评测的标准做法。
3.4 指标配置:acc 与 acc_norm
配置声明了两项指标,均使用mean聚合、higher_is_better: true:
| 指标 | 含义 | 聚合 | 方向 |
|---|---|---|---|
acc | 原始准确率:预测选项是否等于正确答案 | mean | 越大越好 |
acc_norm | 长度归一化准确率(length-normalized accuracy) | mean | 越大越好 |
两者在源码层面的注册可参见 lm_eval/api/metrics.py:acc与acc_norm均注册为output_type=["loglikelihood", "multiple_choice"]、aggregation="mean"的透传指标函数,真正的打分发生在评估器内部——acc_norm在比较各选项时会对 loglikelihood 除以选项词元长度,以削弱长选项天然累积更高负对数似然带来的偏差,这是多项选择评测中的常用修正。对 OpenBookQA 这类选项长度可能不等的任务,同时报告acc与acc_norm有助于更全面地观察模型表现。
3.5 去污染设置(Decontamination)
should_decontaminate: true doc_to_decontamination_query: question_stemshould_decontaminate: true开启测试集与训练语料的重叠检测,doc_to_decontamination_query: question_stem指定以题面文本作为去污染匹配查询。按 docs/task_guide.md 的说明,若该项开启但未指定查询字段,则默认沿用doc_to_text的渲染结果;本任务显式指定了question_stem。该机制可在评测报告中标记可能与预训练语料重叠的样本,从而对分数给出更审慎的解读(相关工具位于 lm_eval/decontamination/)。
四、运行 OpenBookQA 评测
4.1 基础评测命令
以 Hugging Face 模型为例,使用任务名openbookqa运行评测:
lm_eval --model hf \ --model_args pretrained=EleutherAI/pythia-70m \ --tasks openbookqa \ --batch_size auto或使用 Python 模块形式:
python -m lm_eval \ --model hf \ --model_args pretrained=EleutherAI/pythia-70m \ --tasks openbookqa \ --batch_size auto--model hf选择 Hugging Face transformers 后端,--model_args传入模型名等参数(如pretrained=...、dtype=float32、device=cpu);--tasks openbookqa指定要评测的任务(可同时传多个任务名,逗号分隔);--batch_size auto让框架自动探测安全批大小。
评测结束后会打印结果表,其中包含openbookqa行的acc、acc_norm及其标准差(stderr)。由于该任务未挂载到任何 group,结果表中不会有额外的分组聚合行。
4.2 指定 few-shot 与切分
OpenBookQA 的 few-shot 示例默认从train切分选取。显式指定 5-shot 并限制在测试集上:
lm_eval --model hf \ --model_args pretrained=EleutherAI/pythia-70m \ --tasks openbookqa \ --num_fewshot 5 \ --batch_size autonum_fewshot的默认值为 0(见 docs/task_guide.md 的 Runtime configuration 一节)。如需快速验证提示渲染是否符合预期,可使用 scripts/write_out.py 导出实际拼接的 prompt:
python -m scripts.write_out \ --output_base_path /tmp/openbookqa_preview \ --tasks openbookqa \ --sets test \ --num_fewshot 2 \ --num_examples 5该脚本会按--num_fewshot渲染若干条示例,便于人工"目测"(eye test)prompt 格式是否正确(流程说明见 docs/new_task_guide.md 的 "Checking validity" 一节)。
4.3 回归测试佐证
仓库的回归测试数据中包含 tests/testdata/openbookqa-v0-res.json,说明openbookqa任务有对应的评测结果快照用于回归校验,可作为任务配置行为正确的旁证。
五、仓库中的 OpenBookQA 多语言与变体家族
OpenBookQA 的英文主任务之外,本仓库还将其扩展到了多种语言与评测框架,均以同名 YAML 变体形式存在,可作为"复制任务模板"的参考:
- 孟加拉语:bangla_openbookqa.yaml 使用
hishab/openbookqa-bn数据集,其提示模板与主任务不同——显式用 Jinja2 循环把选项渲染成A. .../B. ...列表并追加Answer:,doc_to_choice直接固定为["A", "B", "C", "D"],doc_to_target使用answerKey。可见同一基准在不同语言实现下提示格式可以灵活设计,但输出类型与指标保持一致; - 加泰罗尼亚语:catalan_bench/openbookqa_ca.yaml,归属于 catalan_bench.yaml 这一更大评测组;
- 西班牙语:spanish_bench/openbookqa_es.yaml;
- 加利西亚语:galician_bench/openbookqa_gl.yaml;
- 阿拉伯语方言:aradice/openbookqa/ 下含
openbookqa_eng.yaml、openbookqa_egy.yaml、openbookqa_msa.yaml、openbookqa_lev.yaml等方言变体; - 挪威语:noreval/noropenbookqa/ 下按
nob(书面挪威语)与nno(新挪威语)分别提供p0~p4多个提示模板变体。
这一"主任务 + 多语言/多模板变体"的组织方式,正是 docs/new_task_guide.md 所鼓励的任务演化路径:新增变体时在 README 中注明每个变体新增/评估的内容,并声明其匹配的已发表评测设置。
六、贡献新任务时的 Checklist 实践
README 末尾附带了贡献任务的标准自查清单,这也适用于任何基于 OpenBookQA 增加变体的场景:
- 该任务是否属于文献中已有的基准?是否引用了原始论文?原论文是否提供参考实现,是否已对照参考实现核验并记录运行方式?
- 若同一数据集已有其他任务:主变体("Main" variant)是否被清晰标注?是否在 README 中用一句话说明每个新变体的差异与评估点?是否注明该变体匹配了哪些已发表的评测设置?
建议将填写完毕的 checklist 保留在lm_eval/tasks/<task_dir>/README.md中,并在 lm_eval/tasks/README.md 的任务索引表里登记新任务,方便其他使用者发现与检索。
七、小结
本文围绕 lm_eval/tasks/openbookqa/README.md 展开,完整覆盖了 OpenBookQA 的数据集背景、任务注册方式、openbookqa.yaml 的全部字段语义、multiple_choice评测机制、acc/acc_norm指标的源码注册依据(lm_eval/api/metrics.py)、去污染设置,以及从 CLI 到 few-shot 预览的完整运行流程,并梳理了仓库内丰富的多语言变体。对于任何希望在新数据集上复现"开卷问答"类评估的读者,本任务是一份结构清晰、可直接套用的最小完整范例。
【免费下载链接】lm-evaluation-harnessA framework for few-shot evaluation of language models.项目地址: https://gitcode.com/GitHub_Trending/lm/lm-evaluation-harness
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考