LLaMA-Factory 自定义评估指标:一份能直接落地的实践笔记

LLaMA-Factory 自定义评估指标:一份能直接落地的实践笔记 LLaMA-Factory 自定义评估指标一份能直接落地的实践笔记【免费下载链接】LlamaFactoryUnified Efficient Fine-Tuning of 100 LLMs VLMs (ACL 2024)项目地址: https://gitcode.com/GitHub_Trending/ll/LlamaFactory你刚用 LLaMA-Factory 微调完模型想验证它在自己的任务上表现如何可现成的评测基准只给你一个叫准确率的数——任务不是选择题的时候就卡住了。这篇聊聊怎么基于 LLaMA-Factory 的评估框架扩展自定义评估指标并直接上手。为什么值得折腾自己评估模型很痛。直接跑公开基准拿到的是一个和业务场景好不好无关的准确率自己写打分脚本又要重新实现一遍仓库里已有的东西few-shot 样本格式化、chat template 编码、batch padding、再算分全是重复劳动。LLaMA-Factory 的评估框架把这条链路封装好了EvalTemplate负责 prompt 格式化含 few-shot 示例拼接Evaluator负责推理和算分参数由EvaluationArguments统一管。关键是这条链路是可插拔的——改模板注册函数、或者子类化评估器就能长出你自己的评估流程。还有个前提要知道这套框架的打分方式是直接取模型在 A/B/C/D 答案 token 上的概率不做文本生成。记住这一点后面自定义的流程就好理解了。核心机制一张图看懂整个评估模块就三样东西各在一个文件里EvaluationArguments→src/llamafactory/hparams/evaluation_args.py一次评估的参数容器。定义task基准名格式为task_split、n_shotfew-shot 示例数默认 5、lang模板语言、save_dir结果保存路径等字段。EvalTemplate→src/llamafactory/eval/template.py评估 prompt 的模板。system、choice、answer三个字段分别控制系统提示、选项行格式和答案引导语。Evaluator→src/llamafactory/eval/evaluator.py执行器。依次加载数据集、格式化、批量推理最后按学科类别算准确率写入results.json和results.log。最值得盯着看的是Evaluator里的打分部分只有几行却是整个指标体系的锚点# src/llamafactory/eval/evaluator.py简化 logits self.model(**batch_input).logits word_probs logits[range(batch), lengths - 1] # 每个样本最后一个有效 token choice_probs softmax(word_probs[:, choice_inputs]) # A/B/C/D 的概率 preds argmax(choice_probs) # 概率最大的字母即预测答案说白了它不是让模型写出答案而是问模型接下来最想吐 A、B、C、D 哪个取概率最高者。所以指标就是outputs labels的字符比较快且稳定——但也意味着想换指标就得改这里或者在它后面加。走一遍从配置到出结果用注册新评估模板 加自定义指标打分走一遍全流程。数据侧遵循框架约定每条样本是带question和 A/B/C/D/answer字段的 dict任务目录里还要有mapping.json声明学科名和类别格式与 CEval、MMLU 一致具体以仓库官方数据为准。先注册模板。在src/llamafactory/eval/template.py末尾调一次注册函数即可_register_eval_template( namemytask, # 对应 lang 参数取值 systemYou are answering questions about {subject}.\n\n, # {subject} 是学科占位符 choice\n{choice}. {content}, answer\nAnswer:, )这段只是告诉框架当 langmytask 时prompt 该怎么拼。{choice}和{content}分别填充选项字母和选项内容现成的en、zh两个模板就是这么注册的。然后跑一次默认评估确认链路通了。Evaluator的构造函数接收一个参数 dict字段对应hparams里的各 dataclass具体以最新文档为准from llamafactory.eval.evaluator import Evaluator Evaluator({ model_name_or_path: your-finetuned-model, # 待评估模型 task: my_benchmark_val, # 任务名必须是 task_split 形式 task_dir: evaluation, # 数据集位置 n_shot: 5, # few-shot 示例数 lang: mytask, # 刚注册的模板 save_dir: ./eval_out/mytask, }).eval()这段跑完就是完整流程加载模型、用mytask模板格式化、批量推理把results.log分类别准确率和results.json每个样本的预测字母写进save_dir。看到这两个文件说明链路通了剩下的只是换怎么算分。加自定义指标推荐走子类化。_save_results是评估流程末尾的回调拿到的两个参数——分类别对错数组和逐样本预测——就是天然的扩展点class MyEvaluator(Evaluator): def _save_results(self, category_corrects, results): super()._save_results(category_corrects, results) # 先照旧保存准确率 # 你的自定义指标用 category_corrects分类别对错数组 # 和 results逐样本预测计算比如分类别加权分、严格匹配率 # 算完按需追加写入 save_dir 下的结果文件改完后实例化MyEvaluator跑同一组参数结果目录里就同时有原准确率和你的自定义指标。这几个坑大概率会踩llamafactory-cli eval直接抛NotImplementedError: Evaluation will be deprecated in the future.→ CLI 入口已标记弃用但 eval 模块本身还在维护 → 改在 Python 里直接调Evaluator(args).eval()。启动时报ValueError: save_dir already exists→EvaluationArguments的__post_init__明确禁止覆盖已存在目录 → 换个新目录或先清掉旧结果再跑。指标为 0 或低得离谱 → 准确率是outputs labels的单字符比较answer 字段写成正确答案是B或带空格就永远不等 → 确认 answer 字段是 A-D 单个字母。IndexError: list index out of range→ 任务名按_拆成 task 和 split如mmlu_val只给名字没有第二段 → 永远用task_split形式写task。收个尾把自定义评估指标的扩展点收拢一下模板扩展点在src/llamafactory/eval/template.py末尾的_register_eval_template四个参数写完即注册。指标扩展点在Evaluator的算分环节之后最实用的钩子是_save_results。参数集中在EvaluationArgumentstask必须task_split形式save_dir不能已存在。评估机制和参数的最新状态以项目官方文档为准具体以最新仓库代码为准。有指标扩展的想法欢迎到项目仓库提 issue 或 PR。下一篇可以接着聊 few-shot 示例的选择与评测集构造。【免费下载链接】LlamaFactoryUnified Efficient Fine-Tuning of 100 LLMs VLMs (ACL 2024)项目地址: https://gitcode.com/GitHub_Trending/ll/LlamaFactory创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考