TRL documentation

Harbor 集成:在环境中训练 LLM

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.17.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Harbor 集成:在环境中训练 LLM

Harbor 是一个用于在沙箱中运行智能体任务的框架。它将 任务(指令 + 沙箱镜像 + 验证器)、harness/agent(工具接口 + 循环)和 沙箱(docker、e2b、daytona、gke、……)解耦,使它们可以自由组合。这使其非常适合强化学习:同一套任务可以使用不同的工具接口进行训练,并运行在你偏好的任意沙箱后端上。

本指南介绍了如何将 Harbor 与 TRL 集成。有关 Harbor 本身的信息,请参阅Harbor 文档。

该集成位于 trl.experimental.harbor,并通过 trl[harbor] 附加组件进行控制(采用延迟导入——非用户无需承担任何额外开销)。

何时使用 Harbor 环境

GRPOTrainer 通过 environment_factory 插槽支持基于环境的训练——通用契约请参阅 OpenEnv。如果您希望针对 Harbor 任务套件 进行训练,请使用 Harbor:它是一棵任务目录树,每个任务都是一个自包含的沙箱 + 验证器(例如,一个数据分析智能体套件,其中模型在沙箱中探索文件并写出答案,由评分器进行检查)。

安装

pip install trl[harbor]

Harbor 通过 vLLM 驱动生成,并使用 environment_factory,这需要 vllm 和 transformers>=5.2.0。

pip install vllm

这将安装 harbor 框架(Python >= 3.12)。该集成会延迟导入 harbor 并在进程内运行它,因此未使用 trl.experimental.harbor 的用户不会受到影响。

在训练时,还必须安装并能够访问沙箱后端。Harbor 将云后端置于其自身的 extras 之后,因此请安装您打算使用的那个,并提供其凭据:

pip install "harbor[e2b]"      # E2B cloud sandbox  -> environment_type="e2b",  needs E2B_API_KEY
# docker backend (environment_type="docker", Harbor's default) just needs a reachable Docker daemon

快速入门

HarborSpec 将单个 Harbor 任务套件接入 TRL 训练器的三个插槽——train_dataset、environment_factory、reward_funcs——通过暴露与这些关键字参数名称一一对应的属性来实现:

from trl import GRPOConfig, GRPOTrainer
from trl.experimental.harbor import HarborSpec

spec = HarborSpec("AdithyaSK/data_agent_rl_environment_train", agent="bash", num_tasks=64)

trainer = GRPOTrainer(
    model="Qwen/Qwen3-4B",
    args=GRPOConfig(
        num_generations=8,
        max_steps=50,
        max_tool_calling_iterations=25,
        log_completions=True,
    ),
    train_dataset=spec.train_dataset,
    environment_factory=spec.environment_factory,
    reward_funcs=spec.reward_funcs,
)
trainer.train()

在底层,HarborSpec 会在首次访问时延迟执行以下三项操作:

  1. spec.train_dataset:将任务套件解析为本地任务目录(如有需要则下载 HF 数据集),并构建一个 datasets.Dataset,其中包含 prompt(为空——环境的指令会在 reset 时追加)、task_dir、task_index,以及每个任务的 task.toml 元数据列。
  2. spec.environment_factory:返回一个无参可调用对象,用于生成每个 rollout 的全新 HarborEnv。在调用 reset(task_dir) 时,它会启动该任务的 Harbor 沙箱并返回其指令;工具方法会在沙箱中执行;env.reward 会在 rollout 结束后运行一次验证器。
  3. spec.reward_funcs:一个结果奖励,用于读取 Harbor 验证器针对每次 rollout 的标量值。

数据集

dataset 可以是包含 Harbor 任务树的 Hugging Face 数据集仓库 ID,也可以是包含 tasks/ 子树的本地路径。每个任务都是一个目录:

tasks/<task_id>/
├── instruction.md          # the task prompt (returned by reset)
├── task.toml               # config + metadata (gold answer, difficulty, ...)
├── environment/            # Dockerfile (+ any pre-agent data hooks)
└── tests/                  # test.sh / grader → writes the reward

使用 num_tasks 或 indices(二者互斥)选择一个子集:

spec = HarborSpec("AdithyaSK/data_agent_rl_environment_train", num_tasks=10)        # first 10
spec = HarborSpec("AdithyaSK/data_agent_rl_environment_train", indices=[0, 5, 13])  # specific

Agents:外部与已安装

Harbor 支持两种由智能体驱动任务的方式,这种区别决定了哪些任务可以通过 RL 进行训练:

  • 外部智能体在沙箱外部运行,并自行驱动循环,通过 Harbor 的环境接口向容器下发命令(“通常是通过 exec 方法执行 bash 命令”)。智能体决定每个操作并解释每个结果;沙箱仅负责执行。
  • 已安装的代理 会安装到容器镜像中,并作为无头子进程在其中运行(继承自 BaseInstalledAgent)。Harbor 会在沙箱内启动该代理,并在运行结束后解析其轨迹文件(populate_context_post_run);该代理会自主运行并执行自身的推理。

TRL 的集成采用外部智能体模式,目前仅支持该模式。强化学习训练要求训练器逐轮驱动 rollout:由正在训练的 policy model生成每一轮的内容,TRL 捕获其 token 和 log-probs 并应用环境掩码——这正是 environment_factory 针对黑盒 rollout_func 所提供的功能。已安装的智能体对此是不透明的:它在容器内部运行,使用其自身的模型,且仅在事后输出一条轨迹,因此训练器无法获取用于优化的 policy token 或 log-probs,正在训练的模型也从未被调用。因此,HarborEnv 是一个外部智能体——其工具方法通过 exec 进入沙箱,但循环以及正在训练的模型仍保留在 TRL 中。

选择基础智能体(框架)

基础智能体是框架——它决定了环境暴露哪些工具方法以及智能体如何提交。使用 agent= 进行选择:

HarborSpec(dataset, agent="bash")                          # built-in single-bash-tool harness
HarborSpec(dataset, agent="my_pkg.harnesses:JupyterEnv")   # import path to your HarborEnv subclass
HarborSpec(dataset, agent="path/to/harness.py:JupyterEnv") # file path to your HarborEnv subclass
HarborSpec(dataset, agent=MyHarborEnv)                     # a HarborEnv subclass directly

内置的 "bash" 测试框架(HarborBashEnv)暴露了一个 bash 工具,并通过写入 /workdir/answer.txt 来提交。两个功能更丰富的测试框架作为示例提供——每个都位于自己的文件夹中,并附有列出其工具的 README——位于 examples/grpo_harbor/harnesses/ 下:

  • jupyter/ (JupyterEnv) — 有状态的 Python 内核(变量在单元格之间持久保留)+ 一个 shell 工具。
  • terminal_notes/ (TerminalNotesEnv) — 6 个 shell 工具(包括后台进程)+ 一个包含 4 个工具的持久化笔记工具包。
HarborSpec(dataset, agent="examples/grpo_harbor/harnesses/jupyter/env.py:JupyterEnv")
HarborSpec(dataset, agent="examples/grpo_harbor/harnesses/terminal_notes/env.py:TerminalNotesEnv")

要编写自己的 harness,请继承 HarborEnv 并添加工具方法——每个公开方法都会成为一个工具(TRL 使用 inspect.getmembers 来发现它们),因此请为每个方法提供带类型的签名和 docstring(用于构建工具 schema)。辅助方法请以下划线开头。使用 self._exec(cmd) 在沙箱中运行 shell 命令,并设置 PROMPT_SUFFIX 以将 harness 指导追加到任务指令中:

from trl.experimental.harbor import HarborEnv

class GrepEnv(HarborEnv):
    PROMPT_SUFFIX = "\n\nUse `grep` and `read_file`. Submit by writing /workdir/answer.txt."

    def grep(self, pattern: str, path: str) -> str:
        """Search for `pattern` under `path`.

        Args:
            pattern: The regex to search for.
            path: The file or directory to search.
        """
        return self._exec(f"grep -rn {pattern!r} {path!r}")

沙箱后端

environment_type 会直接传递给 Harbor(TRL 不会对其进行验证):

HarborSpec(dataset, environment_type="e2b")   # cloud sandbox (offloads provisioning), needs E2B_API_KEY
HarborSpec(dataset, environment_type="docker")  # default; needs a local Docker daemon

e2b 推荐用于集群训练:只有 environment.exec 会进入云端沙箱,因此 GPU 可以专用于策略,并且可以并发运行多个 rollout。

奖励函数

spec.reward_funcs 默认使用结果奖励——对于每次 rollout,它会读取 Harbor 验证器的标量值(env.reward),该值在 rollout 结束后通过在沙箱中运行任务的 tests/ 验证器计算一次。若要使用自定义奖励,请编写一个标准的 TRL 奖励函数:

def my_reward(environments, **kwargs) -> list[float]:
    return [env.reward for env in environments]

API

class trl.experimental.harbor.HarborSpec

< >

( dataset: stragent: str | type[HarborEnv] = 'bash'environment_type: str = 'docker'num_tasks: int | None = Noneindices: list[int] | None = Noneinclude_metadata: bool = True )

参数

  • dataset (str) — 一个 Hugging Face 数据集仓库 ID,其中包含 Harbor 任务树(例如 "AdithyaSK/data_agent_rl_environment_train"),或者指向包含 tasks/ 子树的本地目录路径。每个任务是一个目录,包含 instruction.md / task.toml / environment/ / tests/。
  • agent (str 或 type,可选,默认为 "bash") — 基础 agent / harness,即 env 暴露的工具接口。可以是以下之一:内置名称("bash")、导入路径 "package.module:ClassName"、文件路径 "path/to/file.py:ClassName",或直接传入 HarborEnv 的子类。
  • environment_type (str,可选,默认为 "docker") — Harbor 沙箱后端,直接传递给 Harbor(支持其所有后端 — "docker"、"e2b"、"daytona"、 "gke"、"modal"、"runloop" 等)。此处不进行验证,由 Harbor 负责验证。"docker" 是 Harbor 自身的 默认值;选择 "e2b" 可将沙箱功能卸载到云端。
  • num_tasks (int, 可选) — 限制拉取到数据集中的任务数量。None 表示使用树中的所有任务。
  • indices (list[int],可选) — 特定任务的索引(指向排序后的任务列表)。与 num_tasks 互斥。
  • include_metadata (bool,可选,默认为 True) — 将每个任务的 task.toml 元数据(gold_answer、difficulty 等)合并到数据集行中。

单个规格对象,用于将 Harbor 任务套件接入 TRL 训练器。

class trl.experimental.harbor.HarborEnv

< >

( environment_type: str = 'docker' )

参数

  • environment_type (str,可选,默认为 "docker") — Harbor 沙箱后端,直接传递给 Harbor("docker"、"e2b"、"daytona" 等)。

基于 Harbor 沙箱 + 验证器的基础 TRL 环境。

子类定义了工具方法(即测试框架)。TRL 在每次 rollout 中驱动的生命周期为:reset(task_dir)(启动任务的沙箱并返回其指令)-> 工具方法(在沙箱中执行)-> reward(在 rollout 结束后,惰性运行一次验证器)。

class trl.experimental.harbor.HarborBashEnv

< >

( environment_type: str = 'docker' )

单bash工具框架;通过写入/workdir/answer.txt来提交。

bash

< >

( command: str )

参数

  • command — 要运行的 shell 命令。

在沙箱中运行 shell 命令并返回其合并的 stdout+stderr。shell 在多次调用之间是无状态的。使用它来探索文件(ls, head, cat)、运行 Python(python3 -c "...")以及提交答案(echo -n "<value>" > /workdir/answer.txt)。

局限性

  • 该集成位于 trl.experimental 中 — API 可能会发生变化。设置 TRL_EXPERIMENTAL_SILENCE=1 可在 CI 日志中静默该警告。
  • Harbor 的异步沙箱客户端绑定到单个事件循环,因此每个 env 都在其自身的事件循环上同步驱动 start/exec/verify;沙箱的创建在生成批次内是顺序执行的(像 e2b 这样的云后端可以缓解单个沙箱的成本)。
  • 单个 HarborSpec 涵盖一个任务套件和一个测试框架;目前尚不支持多套件训练。

参考

Update on GitHub