CodexQA

Industry & PracticeTools & Frameworks

Inspect 提前停止:按已有分数跳过样本和轮次

CodexQA 团队3 min read

提前停止在每个样本开跑前决定跳不跳。跳过的样本记进日志,评测结束后可以审计。示例里的随机停止只为演示,原文保留未补全的 TODO。

提前停止

UK AI Security Institute。Early Stopping。文档页无单独发布日期(检索于 2026-11-03)。许可证:MIT License,Copyright (c) 2024 UK AI Security Institute。

概述

提前停止(early stopping,根据已经看到的结果,不再跑剩下的样本或轮次)让你在评测过程中,依据到目前为止观察到的结果,跳过样本或轮次(epoch,同一道题再跑的一次)。这对实现自适应测试算法(按前面的表现动态决定接下来测什么)有用:它根据先前表现动态决定跑哪些样本,有可能省下大量计算时间,同时保住评测质量。

常见用途包括:

  • 结果已经稳定就停掉一个样本:如果一个样本在多个轮次里都答对(或都答错),跳过剩下的轮次。
  • 自适应难度:把评测时间集中在靠近模型能力边界的样本上。
  • 资源优化:跳过不太可能再提供额外信号的样本。

说明:Optstop 包

Optstop 包提供自适应最优停止算法的完整实现,用来高效判断已经收集到的数据是否够做出可靠推断。

EarlyStopping 协议

要实现提前停止,写一个实现 EarlyStopping 协议(protocol,规定必须有哪些方法的接口)的类,并把它传给 Task 的 early_stopping 参数:

from inspect_ai import Task, task
from inspect_ai.util import EarlyStopping, EarlyStop

@task
def my_task():
    return Task(
        dataset=my_dataset,
        solver=my_solver,
        scorer=my_scorer,
        early_stopping=MyEarlyStopping(),
        epochs=5,
    )

EarlyStopping 协议定义四个异步方法:

方法说明
start_task()在一次评测开始时调用,用来登记任务元数据。
schedule_sample()在每个样本运行前调用;返回 EarlyStop 就跳过它。
complete_sample()在一个样本完成时调用,并带上它的分数。
complete_task()在任务完成时调用;返回要写入日志的元数据。

示例实现

下面是一个简单例子,随机提前停掉一些样本(只为演示):

from pydantic import JsonValue
from typing_extensions import override

from inspect_ai.dataset import Sample
from inspect_ai.log import EvalSpec
from inspect_ai.scorer import SampleScore
from inspect_ai.util import EarlyStopping, EarlyStop

class RandomEarlyStopping(EarlyStopping):
    @override
    async def start_task(
        self, task: EvalSpec, samples: list[Sample], epochs: int
    ) -> str:
        """Task initialization."""

        # TODO: create a structure to track all of the samples/epochs
        # this will generally be updated w/ scores in complete_sample() 

        # return task name
        return "random"

    @override
    async def schedule_sample(
        self, id: str | int, epoch: int
    ) -> EarlyStop | None:
        """Return EarlyStop to skip this sample, or None to run it."""

        # TODO: determine whether the given sample has been run based
        # on the previously accumulated samples scores.

        # randomly stop some samples
        if random() < 0.5:
            return EarlyStop(id=id, epoch=epoch, reason="random stop")

        return None

    @override
    async def complete_sample(
        self, id: str | int, epoch: int, scores: dict[str, SampleScore]
    ) -> None:
        """Process results from a completed sample."""

        # TODO: track scored samples and use this to determine the
        # appropriate return value for calls to schedule_sample()

        pass

    @override
    async def complete_task(self) -> dict[str, JsonValue]:
        """Return custom metadata to record in the eval log."""

        # TODO: return any custom data about the early stopping output
        # (will be written to the log and displayed in the viewer)

        return {}

EarlyStop

当 schedule_sample() 返回一个 EarlyStop 时,这个样本被跳过。EarlyStop 类包括:

字段类型说明
idstr int`
epochint样本的轮次。
reasonstr None`
metadatadict[str, JsonValue] None`

日志输出

提前停止的信息记在评测日志里,类型是 EarlyStoppingSummary,其中包括:

  • 提前停止管理器的名字
  • 所有被提前停掉的样本的列表
  • complete_task() 返回的任何元数据

这样就可以在评测完成后,分析和审计提前停止的行为。

出处:UK AI Security Institute,Early Stopping,文档页无单独发布日期(检索于 2026-11-03),https://inspect.aisi.org.uk/early-stopping.html ,MIT License(Copyright (c) 2024 UK AI Security Institute)。

Found it useful? Pass it on

WeChat

Scan with WeChat to open it on your phone and forward it.

Subscribe via RSS

Submit a correction