十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

lm-evaluation-harness自定义评估循环实战:从simple_evaluate到全流程定制

lm-evaluation-harness自定义评估循环实战:从simple_evaluate到全流程定制 lm-evaluation-harness自定义评估循环实战从simple_evaluate到全流程定制【免费下载链接】lm-evaluation-harnessA framework for few-shot evaluation of language models.项目地址: https://gitcode.com/GitHub_Trending/lm/lm-evaluation-harness你是否遇到过这样的场景想用自家训练的内部模型跑一次标准评测但模型权重不在HuggingFace上也不方便下载或者团队自研的指标比如回答是否包含指定实体数值误差是否在5%以内在框架自带的指标表里根本找不到再或者你只是想在提交版本前快速用10%的数据验证一遍流程却被迫全量跑上几个小时lm-evaluation-harness的自定义评估循环正是为解决这些问题而生的。它把加载模型—构造请求—推理—算指标—出报告这条链路拆成了可插拔的模块你不需要改框架源码就能替换掉任何一个环节。读完本文你将掌握三件事用simple_evaluate精确控制评估参数、用注册机制注入自己的指标、把非标准模型接入评估流程并拿到一份可直接套用的避坑清单。一、先别急着写死流程三个真实痛点痛点1模型不在HuggingFace上很多公司的内部模型走的是私有推理服务或自定义权重格式。标准教程里--model hf --model_args pretrainedxxx的路子直接走不通于是一批人就手写脚本复刻评估逻辑结果指标口径和社区对不上结果没法横向比较。痛点2指标不够用框架自带acc、acc_norm、exact_match、f1、perplexity等常用指标但业务方往往关心的是容错匹配比如数学题答案写成 42.0 和 42 应当算对。这种差异化的打分逻辑官方指标里没有。痛点3重复建设严重每个任务都写一遍读数据→拼prompt→调模型→算分的胶水代码改一个字段就要动一大片。而框架的评估循环把这些固化成了一套约定你只需要填空。核心思路评估循环是流水线不是黑盒。你要做的是替换流水线上的零件而不是重造整条产线。二、3分钟快速上手最小的自定义评估先克隆仓库并安装依赖建议Python 3.10git clone https://gitcode.com/GitHub_Trending/lm/lm-evaluation-harness cd lm-evaluation-harness pip install -e .然后打开一个Python终端运行下面这段代码——这就是自定义评估循环的最小形态from lm_eval import evaluator results evaluator.simple_evaluate( modelhf, # 模型类型注册名 model_argspretrainedgpt2, # 模型参数传给模型构造函数 tasks[arc_easy], # 任务名来自 lm_eval/tasks/ 下的YAML num_fewshot0, # few-shot 示例数 limit10, # 每个任务只跑10条快速验证 ) print(results[results][arc_easy])如果机器上有GPU加一行devicecuda:0。输出里你会看到每个指标的acc、acc_norm以及对应的stderr标准误差{acc,none: 0.4, acc_stderr,none: 0.1549, acc_norm,none: 0.5, acc_norm_stderr,none: 0.1581}命令行等价写法适合脚本化lm_eval --model hf --model_args pretrainedgpt2 \ --tasks arc_easy --num_fewshot 0 --limit 10到这里你已经跑通了框架的默认流水线。接下来我们要做的是把流水线的每一节都换成自己的。三、黑盒变白盒评估循环内部是如何转起来的三大核心组件Evaluator评估器lm_eval/evaluator.py 中的simple_evaluate负责初始化模型加载任务真正干活的是evaluate函数。LM模型接口lm_eval/api/model.py 中的抽象类LM只规定三个核心方法loglikelihood计算对数似然、loglikelihood_rolling滑动窗口困惑度、generate_until生成到终止符。Task任务定义lm_eval/api/task.py 中的Task类负责读数据→构造请求→算指标。协作流程注册表机制框架的零件仓库框架用一套注册表Registry管理所有可替换零件定义在 lm_eval/api/registry.py注册表存什么常用APImodel_registry模型类register_model/get_modelmetric_registry指标函数register_metric/get_metricaggregation_registry聚合函数register_aggregation/get_aggregationfilter_registry输出过滤器register_filter/get_filter你写的自定义指标、自定义模型本质就是往这些注册表里挂一个名字评估循环按名字查找并调用。这就是为什么你不需要改动 evaluator.py 一行代码。四、分步实战为中文关键词摘要评测定制完整评估流程下面我们围绕一个完整案例评估模型做中文摘要时回答是否覆盖了标准答案中的关键实体。这个指标官方没有我们一步步把它接进评估循环。4.1 注册自定义指标实体命中率指标分两层逐样本打分metric和跨样本聚合aggregation。参照 lm_eval/api/metrics.py 里的写法创建一个my_metrics.pyimport re from lm_eval.api.registry import register_metric, register_aggregation register_aggregation(entity_hit_rate) def entity_hit_rate(items): 对逐样本的命中率列表取均值 return sum(items) / len(items) register_metric( metricentity_hit, higher_is_betterTrue, # 越高越好 output_typegenerate_until, # 适用于生成类任务 aggregationentity_hit_rate, # 关联上面的聚合函数 ) def entity_hit(items): # 逐样本打分items 里是每条样本的 (预测, 参考) 结构 # 具体解包方式由下方任务YAML的 process_results 决定 return items注意register_metric的metric参数是必填的注册名就是你在YAML里引用的名字。higher_is_better若未注册运行时is_higher_better()会打警告。4.2 自定义任务YAML定义数据、提示词与指标在lm_eval/tasks/下新建目录my_summary/写一个my_summary.yaml参考 lm_eval/tasks/arc/arc_easy.yaml 的结构task: my_summary dataset_path: cnn_dailymail # 数据集路径HuggingFace datasets dataset_name: 3.0.0 # 数据集子集名 output_type: generate_until # 生成式任务 test_split: test doc_to_text: 请用一句话概括新闻{{article}} doc_to_target: {{highlights}} generation_kwargs: until: [\n, .] # 生成到换行或句号停止 metric_list: - metric: entity_hit # 引用4.1注册的指标 aggregation: entity_hit_rate higher_is_better: true metadata: version: 1.0同目录放一个_my_summary.py实现逐样本打分逻辑YAML里的process_results通过!function引用def process_results(doc, results): pred results[0] # 模型生成的第一段文本 refs doc[highlights] # 参考摘要 hit 0 for ref in refs: # 简化版实体命中检查预测文本是否包含参考中的非停用词 for token in re.findall(r[\u4e00-\u9fa5]{2,}, ref): if token in pred: hit 1 total max(len(refs), 1) return {entity_hit: hit / total} # 返回 {指标名: 得分}然后在YAML中加入一行让框架加载它process_results: !function _my_summary.process_results运行前建议用--check_integrity校验任务配置是否正确避免跑到一半才发现字段名写错。4.3 接入自定义模型实现LM抽象类如果模型不在HF上实现LM的子类即可。官方示例 examples/transformer-lens.py 演示了如何把TransformerLens模型包一层HF适配器后直接喂给HFLM。更通用的做法是实现三个核心方法from lm_eval.api.model import LM class MyPrivateModel(LM): def __init__(self, endpoint: str, **kwargs): super().__init__() self.endpoint endpoint # 内部推理服务地址 def loglikelihood(self, requests, disable_tqdmFalse): # 输入: requests 列表每个含 (context, continuation) # 输出: 每项返回 (对数似然, 是否是greedy解码结果) return [(0.0, False) for _ in requests] def loglikelihood_rolling(self, requests, disable_tqdmFalse): # 滑动窗口困惑度场景才需要用不到可抛 NotImplementedError raise NotImplementedError def generate_until(self, requests, disable_tqdmFalse): # 输入: requests每个含 (context, gen_kwargs) # 输出: 每项返回生成文本列表 return [self._call_inference(r[0]) for r in requests] def _call_inference(self, prompt: str) - list[str]: # 调用私有服务这里替换成你的HTTP请求逻辑 return [示例输出]把MyPrivateModel实例直接传给simple_evaluate的model参数即可它要求传入LM子类实例results evaluator.simple_evaluate( modelMyPrivateModel(endpointhttp://10.0.0.8:8080/infer), tasks[my_summary], limit20, )4.4 运行与结果解读lm_eval --model hf --model_args pretrainedQwen/Qwen2-1.5B-Instruct \ --tasks my_summary --num_fewshot 0 --limit 50 \ --apply_chat_template --fewshot_as_multiturn注意这里开启了apply_chat_template——如果你的模型是对话模型务必开启否则提示词不带聊天格式loglikelihood/生成结果都会失真框架会在检测到inst/chat字样但未开启时打警告。输出结果中results.my_summary下就会出现我们自定义的entity_hit指标及entity_hit_stderr。五、进阶技巧与避坑清单关键参数速查表参数作用推荐用法limit每任务样本数或比例1为比例联调阶段设0.1上线全量samples精确指定要跑的样本下标如{arc_easy: [0,3,6]}复现某个失败casebatch_sizeauto自动探测 max_batch_size兜底大模型务必设置上限防OOMnum_fewshot覆盖任务默认的少样本数注意YAML里写死0的任务不会被覆盖use_cacheSQLite缓存模型输出路径自动拼_rank{rank}.db反复调参时能省一半时间cache_requests缓存请求构建结果数据集大时显著加速bootstrap_itersstderr计算的bootstrap迭代数设0跳过不关心置信区间时设0提速predict_only只出预测不评分自动换成bypass指标先落盘推理结果后离线分析避坑检查表 ⚠️limit和samples不能同时传同时传会直接抛ValueError。YAML里的转义字符必须用双引号until: [\n]是对的单引号或裸写会解析成字面\n。num_fewshot的覆盖规则任务配置里num_fewshot: 0表示强制0样本此时你传的num_fewshot5会被忽略日志里有提示需要去YAML里改。generate_until任务才接受gen_kwargsloglikelihood类任务传了也会被忽略别指望它生效。多卡分布式时缓存文件按rank分片use_cache会自动拼_rank{rank}.db避免多进程写同一文件。多模态任务与模型必须匹配MULTIMODAL任务配非多模态模型会直接报错目前多模态仅支持hf-multimodal、vllm-vlm等类型。stderr开销很大默认bootstrap_iters100000数据量大时bootstrap会成为主要耗时调试阶段建议设小或设0。常见问题QAQ自定义指标总报 Could not find registered metricA先确认你的my_metrics.py被 import 过了。注册是执行即注册你需要在调用simple_evaluate之前import my_metrics或者把文件放进lm_eval/api/下由框架自动加载。Qoverride_metric和 YAML里的metric_list有什么区别Atask.override_metric(my_metric)是运行时动态替换单个任务的指标框架内部predict_only就是这么干的见 lm_eval/api/task.py而metric_list是声明式配置写在YAML里、可配多个指标。日常优先用metric_list需要临时改指标时再用override_metric。Q模型生成了带多余前缀的文本指标全为0A先检查generation_kwargs.until是否设置合理再考虑加一个Filter如正则提取答案段过滤器在apply_filters阶段生效会直接改写送入指标的filtered_resps。六、延伸与资源想继续深入建议按这条路径走读源码先啃 lm_eval/evaluator.py 的evaluate函数请求构建→推理→评分三段式再看 lm_eval/api/registry.py 的注册表实现。抄作业官方示例 examples/transformer-lens.py 是非标准模型接入的最佳模板任务目录 lm_eval/tasks/ 下有几百个YAML挑一个和你业务形态接近的改。看文档任务配置字段详解见 docs/task_guide.mdPython API说明见 docs/python-api.md模型接入指南见 docs/model_guide.md常见坑合集在 docs/footguns.md。参与社区给新任务提PR时记得跑--check_integrity并遵守任务目录的命名与版本规范。一句话总结自定义评估循环的核心价值是把评估从一次性脚本变成可组合、可复用、可复现的基础设施——你只负责定义测什么、怎么算剩下的流水线交给框架。【免费下载链接】lm-evaluation-harnessA framework for few-shot evaluation of language models.项目地址: https://gitcode.com/GitHub_Trending/lm/lm-evaluation-harness创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表