从定义到执行:Evals框架评估全流程解析
引言
你是否在评估大语言模型(LLM)时遇到过流程混乱、指标不统一的问题?本文将带你深入了解Evals框架的核心实现原理,从EvalSpec定义到评估任务执行的完整流程,帮助你轻松掌握LLM评估的关键技术。读完本文后,你将能够:
- 理解Evals框架的核心组件与数据结构
- 掌握评估任务的定义与注册方法
- 熟悉评估执行的全流程与关键步骤
- 学会如何自定义评估指标与报告结果
核心概念:EvalSpec与评估元数据
Evals框架通过一系列数据结构定义评估的元信息,其中最核心的是EvalSpec。在evals/base.py中,EvalSpec类封装了评估的关键信息,包括评估类、参数、注册路径等:
@dataclass
class EvalSpec:
"""Specification for an eval."""
cls: str
registry_path: Path
args: Optional[Dict[str, Any]] = None
key: Optional[str] = None
group: Optional[str] = None
EvalSpec通过YAML配置文件注册在evals/registry/evals目录下,例如:
# 示例:evals/registry/evals/test-match.yaml
test-match:
cls: evals.elsuite.basic.match.Match
args:
samples_jsonl: test-match.jsonl
除了EvalSpec,框架还定义了CompletionFnSpec(完成函数规范)、EvalSetSpec(评估集规范)和RunSpec(运行规范)等数据结构,共同构成评估的元数据体系。
评估执行核心:Eval类与评估流程
评估执行的核心逻辑在evals/eval.py中实现,Eval类是所有评估任务的基类,定义了评估的基本接口:
class Eval(abc.ABC):
@abc.abstractmethod
def eval_sample(self, sample: Any, rng: random.Random):
raise NotImplementedError()
@abc.abstractmethod
def run(self, recorder: RecorderBase) -> Dict[str, float]:
raise NotImplementedError()
评估流程概览
评估执行流程主要包括以下步骤:
- 加载评估样本:通过
get_samples()方法从JSONL文件加载评估数据 - 初始化记录器:创建
RecorderBase实例记录评估过程与结果 - 执行样本评估:调用
eval_all_samples()并行处理所有样本 - 计算评估指标:通过
get_metrics()汇总计算评估结果
关键方法解析
- eval_all_samples():该方法负责并行处理所有样本,支持多线程执行,通过
ThreadPool实现并发评估:
def eval_all_samples(
self,
recorder: RecorderBase,
samples,
show_progress=True,
record_raw_sample=True,
**_kwargs: Any,
):
work_items = _index_samples(samples)
threads = int(os.environ.get("EVALS_THREADS", "10"))
with ThreadPool(threads) as pool:
iter = pool.imap_unordered(eval_sample, work_items)
idx_and_result = list(tqdm(iter, total=len(work_items), disable=not show_progress))
return [r for _, r in sorted(idx_and_result)]
- record_event():记录评估过程中的关键事件,如匹配结果、函数调用等,实现于evals/record.py:
def record_event(self, type, data=None, sample_id=None):
event = self._create_event(type, data, sample_id)
self.events.append(event)
if not self.is_paused():
self.flush_events()
评估任务注册与发现
Evals框架采用插件化设计,通过注册表机制管理所有评估任务。evals/registry.py中的Registry类负责加载和管理评估任务、完成函数等资源:
class Registry:
def __init__(self, registry_paths: Sequence[Union[str, Path]] = DEFAULT_PATHS) -> None:
self.registry_paths = list(registry_paths)
self._completion_fns = None
self._evals = None
# ...其他初始化逻辑
def get_eval(self, name: str) -> Optional[EvalSpec]:
"""获取指定名称的评估规范"""
return self._evals.get(name)
评估任务通过YAML文件注册在evals/registry/evals目录下,例如test-match.yaml定义了一个简单的匹配评估:
test-match:
cls: evals.elsuite.basic.match.Match
args:
samples_jsonl: test-match.jsonl
key: test-match
group: test
评估执行入口:CLI工具
Evals框架提供了oaieval和oaievalset两个命令行工具,分别用于执行单个评估和评估集。以oaieval为例,其实现位于evals/cli/oaieval.py,核心逻辑如下:
def run(args: OaiEvalArguments, registry: Optional[Registry] = None) -> str:
registry = registry or Registry()
completion_fns = [registry.make_completion_fn(fn) for fn in args.completion_fns]
eval_spec = registry.get_eval(args.eval)
run_spec = RunSpec(...)
recorder = build_recorder(args, run_spec, record_path)
eval_class = registry.get_class(eval_spec)
eval_instance = eval_class(completion_fns, eval_spec.registry_path, **eval_spec.args)
result = eval_instance.run(recorder)
return json.dumps(result, indent=2)
执行评估的命令示例:
oaieval gpt-3.5-turbo test-match
该命令会加载test-match评估规范,使用gpt-3.5-turbo模型执行评估,并生成评估报告。
自定义评估开发
开发步骤
- 定义评估类:继承
Eval或SolverEval类,实现eval_sample和run方法 - 准备样本数据:创建JSONL格式的样本文件,存放于
evals/registry/data目录 - 注册评估规范:在
evals/registry/evals目录下创建YAML配置文件 - 测试评估任务:使用
oaieval命令执行评估并验证结果
示例:简单匹配评估
evals/elsuite/basic/match.py实现了一个简单的匹配评估,核心代码如下:
class Match(Eval):
def __init__(self, completion_fns, samples_jsonl, *args, **kwargs):
super().__init__(completion_fns, *args, samples_jsonl=samples_jsonl, **kwargs)
def eval_sample(self, sample, rng):
prompt = sample["prompt"]
result = self.completion_fn(prompt=prompt)
sampled = result.get_completions()[0]
correct = sampled.strip() == sample["expected"]
self.record_match(correct, expected=sample["expected"], picked=sampled)
def run(self, recorder):
samples = self.get_samples()
self.eval_all_samples(recorder, samples)
return {"accuracy": get_accuracy(recorder.get_events("match"))}
评估结果记录与分析
评估过程中的所有事件都由RecorderBase记录,实现于evals/record.py。记录的事件包括样本匹配结果、函数调用、错误信息等。默认情况下,记录会保存为JSONL文件,存放于tmp/evallogs目录。
评估结果的分析工具位于scripts/make_plots.py,可以生成各种可视化图表,帮助理解模型性能。
总结与展望
Evals框架通过清晰的架构设计和灵活的插件机制,为LLM评估提供了全面的解决方案。本文详细介绍了从EvalSpec定义到评估执行的完整流程,包括核心数据结构、评估逻辑、CLI工具和自定义评估开发。未来,Evals框架将继续扩展评估任务库,支持更多复杂场景的LLM评估需求。
要深入了解更多细节,建议参考以下资源:
- 官方文档:docs/run-evals.md
- 核心代码:evals/eval.py
- 评估示例:evals/elsuite/basic/match.py
- 注册规范:evals/registry/evals
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




