
使用 lm-evaluation-harness 评估 Babilong 长上下文推理基准任务配置、运行方法与源码解析【免费下载链接】lm-evaluation-harnessA framework for few-shot evaluation of language models.项目地址: https://gitcode.com/GitHub_Trending/lm/lm-evaluation-harness导读BABILong 是专为测试大语言模型LLM在超长文档中跨事实推理能力而设计的基准包含 20 类从事实链接、简单归纳/演绎到计数、列表集合处理的推理任务。本指南以 lm_eval/tasks/babilong/README.md 为骨架结合 babilong 任务目录 下的全部 YAML 配置与common_utils.py源码实现系统讲解如何在 lm-evaluation-harness 中加载、运行与定制 Babilong 评估覆盖任务分组、上下文长度控制、few-shot 配置、指标计算与结果解读读者可据此复现长上下文评测并扩展到自定义长度。BABILong 基准概述为何需要草垛中的推理评测随着 LLM 输入上下文长度的急剧增长现有评测方法未能同步跟上无法全面衡量模型处理长上下文时的真实效率。BABILongBABI Long Context基准正是为弥合这一差距而设计其核心目标是在极长文档中检验模型对分散事实的推理能力。其论文为Babilong: Testing the Limits of LLMs with Long Context Reasoning-in-a-HaystackarXiv: 2406.10149作者 Kuratov、Bulatov、Anokhin、Rodkin、Sorokin、Burtsev。论文报告的几项关键发现作为理解该基准设计动机的背景事实包括主流 LLM 实际只能有效利用上下文的 10%-20%且性能随推理复杂度增加而急剧下降检索增强生成RAG在单事实问答上仅能达到约 60% 的准确率且与上下文长度无关在上下文扩展方法中微调后的循环记忆 Transformerrecurrent memory transformers表现最佳可处理最长 5000 万 token 的序列。该基准可扩展到任意长度官方提供了最长达 1000 万 token 长度的 splits。在本仓库的 lm-evaluation-harness 实现中Babilong 任务位于 lm_eval/tasks/babilong/共包含 20 个推理任务qa1–qa20在多种上下文长度下的评估配置。任务分组与任务清单Group 定义README 中声明了两个 groupbabilong0k 上下文长度下的全部 Babilong 任务babilong_longctxqa1–qa5 任务在最长 128k 上下文长度下的评测集合。对应实现分别在 babilong.yaml 与 babilong_longctx.yaml 中babilong.yaml通过task:字段聚合babilong_qa1至babilong_qa20全部 20 个子任务并声明aggregate_metric_list以acc为指标、weight_by_size: True按样本量加权聚合babilong_longctx.yaml仅聚合 qa1–qa5 五个任务仅这五个任务提供 0k–128k 的多种长度 split同样按样本量加权聚合acc。因此命令行中直接指定--tasks babilong或--tasks babilong_longctx即可一次跑完整组评测聚合指标自动计算。20 个推理任务qa1–qa20README 列出的任务清单在仓库中均有独立 YAML 定义如 babilong_qa1.yaml、babilong_qa2.yaml 等任务能力维度qa1单支持事实问答Single supporting fact QAqa2双支持事实问答qa3三支持事实问答qa4双参数关系推理qa5三参数关系推理qa6Yes/No 问答qa7计数qa8列表与集合qa9简单否定qa10不确定知识yes/no/maybeqa11通过时间指代追踪人物qa12合取Conjunctionqa13复合共指Compound coreferenceqa14时间推理qa15基本演绎qa16基本归纳qa17位置推理qa18尺寸推理qa19路径寻找qa20动机演绎基准整体包含 1000 个样本 × 20 个任务 × 多种上下文长度。配置结构从公共 YAML 到各任务 YAML公共配置_babilong_common_yaml所有子任务通过include: _babilong_common_yaml继承公共配置见 _babilong_common_yamldataset_path: RMT-team/babilong-1k-samples output_type: generate_until doc_to_target: {{target}} target_delimiter: num_fewshot: 2 process_results: !function common_utils.process_results metric_list: - metric: acc aggregation: mean higher_is_better: true generation_kwargs: do_sample: false temperature: 0.0 max_gen_toks: 16 until: [] metadata: version: 0.0各字段的语义与作用dataset_pathHugging Face 数据集标识指向RMT-team/babilong-1k-samples每长度 1000 样本的版本。README 提示如需每长度 100 样本、支持最长 10M token 的版本可修改 common_utils.py 中的数据集路径为RMT-team/babilong。output_type: generate_until采用自回归生成方式输出答案而非 loglikelihood 打分契合开放式问答任务。doc_to_target: {{target}}从样本字段target提取标准答案。num_fewshot: 2默认 2-shot具体示例由各任务 YAML 中的fewshot_config提供。process_results: !function common_utils.process_results挂接自定义评分函数详见后文。generation_kwargsdo_sample: falsetemperature: 0.0保证确定性解码贪心max_gen_toks: 16限制生成长度until: []表示无停止词。各任务 YAML以 qa1 为例以 babilong_qa1.yaml 为例include: _babilong_common_yaml task: babilong_qa1 test_split: qa1 custom_dataset: !function common_utils.load_dataset dataset_kwargs: qa_split: qa1 description: I will give you context with the facts about positions ... Always return your answer in the following format: The most recent location of person is location. Do not write anything else after that.\n\n doc_to_text: {{input.strip()}}\n{{question.strip()}} fewshot_config: sampler: first_n samples: - input: Charlie went to the hallway. Judith come back to the kitchen. Charlie travelled to balcony. question: Where is Charlie? target: The most recent location of Charlie is balcony. - input: Alan moved to the garage. Charlie went to the beach. Alan went to the shop. Rouse travelled to balcony. question: Where is Alan? target: The most recent location of Alan is shop.要点解析test_split: qa1指定从数据集中读取名为qa1的 split每个任务对应一个 splitcustom_dataset与dataset_kwargs.qa_split协同生效。description为系统提示词system prompt约束模型输出格式例如 qa1 强制输出 The most recent location of person is location.qa4 要求仅输出一个词——位置qa6 要求仅输出 yes/noqa10 扩展为 yes/no/maybe。doc_to_text将样本的input含噪声的上下文事实文本与question拼接作为 prompt。fewshot_config.sampler: first_n表示从samples列表中取前 N 条作为 in-context 示例配合公共配置num_fewshot: 2即取前两条。每个任务都内置了与其输出格式严格匹配的 few-shot 示例这对保证模型遵循格式输出至关重要。例如 babilong_qa3.yaml 中示例要求格式 Before the $location_1$ the $item$ was in the $location_2$.babilong_qa5.yaml 的示例覆盖谁把苹果给了谁谁给了足球Fred 给了 Bill 什么三种关系形态babilong_qa20.yaml动机演绎则内置了疲惫→去卧室饥饿→去厨房等动机推断示例并额外声明dataset_name: 0k固定使用 0k 长度配置。上下文长度控制max_seq_lengths 机制支持的长度与任务范围README 明确指出本实现为每长度 1000 样本的版本仅 qa1–qa5支持 0k、1、2、4、8、16、32、64、128k token 多种长度qa6–qa20 只有 0k 长度默认最大序列长度为 0k。通过 metadata 指定长度由于一个配置文件同一时刻只承载一种上下文长度需要在运行时通过 metadata 参数动态指定。README 给出的 CLI 示例--metadata {max_seq_lengths:0k,1k,2k,4k,8k,16k,32k,128k}该 metadata 参数同样可以传给 TaskManagermetadata: dict。源码层的传递链路这一机制的底层实现在 lm_eval/api/task.py 的download方法中当配置声明了custom_dataset可调用对象时框架会将 CLI/TaskManager 传入的 metadata 与 YAML 中的dataset_kwargs合并后调用该函数self.dataset self.config.custom_dataset( **(self.config.metadata or {}), **(self.config.dataset_kwargs or {}) )对应地lm_eval/tasks/babilong/common_utils.py 中的load_dataset读取max_seq_lengths默认0k与qa_split并据此调用datasets.load_dataset(RMT-team/babilong-1k-samples, nameconfig_name, splitqa_split)——即把max_seq_lengths作为数据集的nameconfig参数、把任务名作为split参数加载对应长度的数据def load_dataset(**kwargs): config_name kwargs.get(max_seq_lengths, 0k) qa_split kwargs.get(qa_split) dataset datasets.load_dataset( RMT-team/babilong-1k-samples, nameconfig_name, splitqa_split ) return {qa_split: dataset}也就是说上下文长度在这里是数据层面的切分每个长度都对应数据集的一个独立 config0k/1k/2k/.../128k评测时把该长度的长文本作为 prompt 输入模型衡量模型在长上下文中检索并推理分散事实的能力。task.py在检测到 custom_dataset 时还会打印提示说明自定义 kwargs 可通过--metadata控制台 JSON 字符串或 TaskManager 传入。CLI 侧入口在 lm_eval/_cli/run.py--metadata参数接受 JSON 对象如{tokenizer: gpt2, max_seq_lengths: [4096, 8192]}随后在 run.py 中通过cfg.process_tasks(cfg.metadata)传入 TaskManager。一条完整的运行示例lm_eval \ --model hf \ --model_args pretrainedmeta-llama/Llama-3.1-8B-Instruct \ --tasks babilong_longctx \ --num_fewshot 2 \ --batch_size 1 \ --metadata {max_seq_lengths:0k,1k,2k,4k,8k,16k,32k,128k}说明长上下文评测通常需要较小的 batch size 以规避显存/内存溢出--metadata中可列出多个长度框架会按各长度逐一加载对应 config 的数据进行评测。评分逻辑process_results 与后处理common_utils.py 中除load_dataset外还包含三个关键函数get_tokenizer带cache装饰的 tokenizer 工厂基于AutoTokenizer.from_pretrained加载trust_remote_codeTrue用于后续按 token 切分长上下文。postprocess_pred对模型生成结果做规范化——strip()去除首尾空白并将所有不可打印控制字符[\x00-\x1f]替换为换行后再次strip()消除解码产生的杂散字符。process_results核心评分函数。将后处理后的预测与标准答案target做大小写不敏感的子串匹配命中得 1.0 否则 0.0def process_results(doc: dict, results: list[str]) - dict[str, float]: pred postprocess_pred(results) target doc.get(target, ).strip() score 1.0 if target.lower() in pred[0].lower() else 0.0 return {acc: score}这意味着模型输出只要包含标准答案文本例如 qa1 中输出包含 The most recent location of Charlie is balcony.即视为正确具备一定的容错性。每个样本的 acc 分数再由公共配置中的metric_listacc/mean/higher_is_better: true及 group 的aggregate_metric_list按样本量加权汇总为任务级与组级指标。扩展与定制要点切换数据集版本如需每长度 100 样本、支持最长 10M token 的版本将 common_utils.py 中的RMT-team/babilong-1k-samples改为RMT-team/babilong即可README 第 1 条提示。新增评测长度在--metadata {max_seq_lengths: ...}中追加数据集支持的长度即可无需修改配置文件。调整 few-shot 数量公共配置num_fewshot: 2可在任务 YAML 中覆盖或通过 CLI--num_fewshot指定各任务内置的fewshot_config.samples为按first_n采样的固定示例池。复用 qa 任务逻辑新增任务只需复制任一babilong_qaN.yaml修改task、test_split、dataset_kwargs.qa_split、description与fewshot_config.samples即可接入数据集中的对应 split。通过 TaskManager 编程式运行metadata 作为字典传入例如TaskManager(metadata{max_seq_lengths: 0k,4k})与 CLI 的--metadata等价task.py 中两者最终汇合到custom_dataset的调用参数。小结Babilong 在 lm-evaluation-harness 中的实现呈现出清晰的三层结构公共配置 _babilong_common_yaml 统一定义生成式评测与指标20 个任务 YAML 各自定义 prompt 格式与 few-shot 示例common_utils.py 承担数据加载按长度 config 切分与结果后处理/评分。运行时通过--metadata {max_seq_lengths: ...}灵活切换上下文长度配合babilong全 20 任务 0k与babilong_longctxqa1–qa5 ≤128k两个 group 即可完成从短上下文到 128k乃至自定义更长长上下文推理能力的系统评测。【免费下载链接】lm-evaluation-harnessA framework for few-shot evaluation of language models.项目地址: https://gitcode.com/GitHub_Trending/lm/lm-evaluation-harness创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考