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/агента (интерфейс инструментов + цикл) и песочницу (docker, e2b, daytona, gke, …), позволяя свободно комбинировать их. Это делает его естественным выбором для RL: один и тот же набор задач можно обучать с различными интерфейсами инструментов на любом предпочитаемом бэкенде песочницы.

В этом руководстве описано, как интегрировать 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, не затрагиваются.

Песочница (sandbox backend) также должна быть установлена и доступна во время обучения. 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: возвращает вызываемый объект без аргументов, создающий новый экземпляр HarborEnv для каждого rollout. При вызове reset(task_dir) запускается песочница Harbor для задачи и возвращается её инструкция; методы инструментов выполняют команды внутри песочницы; env.reward запускает верификатор один раз после завершения rollout.
  3. spec.reward_funcs: итоговая награда, которая считывает скаляр Harbor verifier для каждого rollout.

Набор данных

dataset — это либо идентификатор репозитория датасета Hugging Face, содержащего дерево задач Harbor, либо локальный путь, включающий поддерево 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

Агенты: внешние и установленные

Harbor поддерживает два способа, которыми агент выполняет задачу, и это различие определяет, что можно обучать с помощью RL:

  • Внешние агенты работают вне песочницы и сами управляют циклом, отправляя команды в контейнер через интерфейс окружения Harbor («как правило, выполняя bash-команды с помощью метода exec»). Агент принимает решение о каждом действии и интерпретирует каждый результат; песочница лишь выполняет команды.
  • Установленные агенты устанавливаются в образ контейнера и выполняются в нём как автономный подпроцесс без графического интерфейса (наследуют BaseInstalledAgent). Harbor запускает агента внутри песочницы, а затем анализирует его файл траектории (populate_context_post_run); агент работает автономно, используя собственную инференс-логику.

Интеграция TRL использует паттерн внешнего агента, и на данный момент поддерживается только он. Обучение с подкреплением требует, чтобы тренер управлял развёрткой по ходу каждого хода: обучаемая модель политики генерирует каждый ход, а TRL захватывает её токены и лог-вероятности и применяет маску среды — именно то, что обеспечивает environment_factory поверх «чёрного ящика» rollout_func. Установленный агент непрозрачен для этого процесса: он работает внутри контейнера со своей моделью и выдаёт траекторию только постфактум, поэтому у тренера нет токенов политики или лог-вероятностей для оптимизации, а обучаемая модель никогда не вызывается. Таким образом, HarborEnv является внешним агентом: его методы инструментов exec выполняются в песочнице, но цикл и обучаемая модель остаются в TRL.

Выбор базового агента (harness)

Базовый агент — это каркас, определяющий, какие методы инструментов предоставляет среда и как агент отправляет запросы. Выберите его с помощью 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" harness (HarborBashEnv) предоставляет один инструмент bash и отправляет ответ, записывая его в /workdir/answer.txt. Два более функциональных harnessa поставляются в качестве примеров — каждый в отдельной папке с README, перечисляющим его инструменты, — в examples/grpo_harbor/harnesses/:

  • jupyter/ (JupyterEnv) — ядро Python с состоянием (переменные сохраняются между ячейками) + инструмент для работы с оболочкой.
  • 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 (используется для построения схемы инструмента). Вспомогательные методы начинайте с подчёркивания. Используйте 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 остаются выделенными под политику, и можно запускать множество rollouts одновременно.

Функции вознаграждения

spec.reward_funcs по умолчанию использует вознаграждение за результат — для каждого rollout он считывает скаляр Harbor verifier (env.reward), который вычисляется один раз после rollout путём запуска верификатора tests/ задачи в песочнице. Для пользовательского вознаграждения напишите обычную функцию вознаграждения TRL:

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

API

класс 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, содержащего дерево задач Harbor (например, "AdithyaSK/data_agent_rl_environment_train"), или локальный путь к каталогу, содержащему поддерево tasks/. Каждая задача представляет собой каталог с instruction.md / task.toml / environment/ / tests/.
  • agent (str или type, необязательный, по умолчанию "bash") — Базовый агент / каркас, то есть набор инструментов, который предоставляет окружение. Одно из: встроенное имя ("bash"), путь импорта "package.module:ClassName", путь к файлу "path/to/file.py:ClassName" или непосредственно подкласс HarborEnv.
  • environment_type (str, необязательный, по умолчанию "docker") — Бэкенд песочницы Harbor, передаваемый в 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.

класс trl.experimental.harbor.HarborEnv

< >

( environment_type: str = 'docker' )

Параметры

  • environment_type (str, необязательный, по умолчанию "docker") — Бэкенд песочницы Harbor, передаваемый в Harbor ("docker", "e2b", "daytona", …).

Базовое окружение TRL, работающее на базе песочницы Harbor и верификатора.

Подклассы определяют методы инструментов (обвязку). Жизненный цикл, который TRL управляет для каждого rollout: reset(task_dir) (запуск песочницы задачи, возврат её инструкции) -> методы инструментов (выполнение команд в песочнице) -> reward (однократный запуск верификатора, лениво, после rollout).

класс trl.experimental.harbor.HarborBashEnv

< >

( environment_type: str = 'docker' )

Обёртка с единственным инструментом bash; отправьте ответ, записав его в /workdir/answer.txt.

bash

< >

( command: str )

Параметры

  • command — Команда оболочки для выполнения.

Выполните команду оболочки в песочнице и верните её объединённый вывод stdout+stderr. Оболочка не сохраняет состояние между вызовами. Используйте её для просмотра файлов (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 в собственном цикле; в результате provisioning песочниц в рамках генерационной партии происходит последовательно (облачные бэкенды, такие как e2b, снижают стоимость на каждую песочницу).
  • Один объект HarborSpec описывает один набор задач и один harness; обучение на нескольких наборах задач пока не поддерживается.

Справочник

Update on GitHub