TRL documentation

Integración de Harbor para entrenar LLMs con entornos

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

Integración de Harbor para entrenar LLMs con entornos

Harbor es un framework para ejecutar tareas agénticas en entornos aislados. Separa una tarea (instrucción + imagen de sandbox + verificador), un harness/agent (la superficie de herramientas + bucle) y un sandbox (docker, e2b, daytona, gke, …) para que puedan combinarse libremente. Esto lo convierte en una opción natural para RL: el mismo conjunto de tareas puede entrenarse con diferentes superficies de herramientas, en el backend de sandbox que prefieras.

Esta guía cubre cómo integrar Harbor con TRL. Para más información sobre Harbor, consulte la documentación de Harbor.

La integración se encuentra en trl.experimental.harbor y está condicionada al extra trl[harbor] (importación perezosa: los usuarios que no la utilicen no incurren en ningún coste).

Cuándo usar entornos de Harbor

GRPOTrainer admite el entrenamiento basado en entornos a través del slot environment_factory; consulte OpenEnv para el contrato general. Utilice Harbor cuando desee entrenar contra un Harbor task suite: un árbol de directorios de tareas, donde cada una es un sandbox y un verificador autocontenidos (por ejemplo, un suite de agentes de análisis de datos donde el modelo explora archivos en un sandbox y escribe una respuesta que un corrector verifica).

Instalación

pip install trl[harbor]

Harbor impulsa la generación a través de vLLM y utiliza environment_factory, que requiere vllm y transformers>=5.2.0.

pip install vllm

Esto instala el marco de trabajo harbor (Python >= 3.12). La integración importa harbor de forma perezosa y lo ejecuta en el proceso, por lo que los usuarios que no utilicen trl.experimental.harbor no se verán afectados.

También debe estar instalado y ser accesible en el momento del entrenamiento un backend de sandbox. Harbor mantiene los backends de la nube detrás de sus propios extras, por lo que instale el que pretenda usar y proporcione sus credenciales:

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

Inicio rápido

HarborSpec conecta un único conjunto de tareas de Harbor con los tres espacios del entrenador de TRL — train_dataset, environment_factory, reward_funcs — mediante propiedades que se mapean 1:1 con esos nombres de parámetros:

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()

Por debajo, HarborSpec hace tres cosas, de forma perezosa en el primer acceso:

  1. spec.train_dataset: resuelve la suite de tareas en directorios locales de tareas (descargando el dataset de HF si es necesario) y construye un datasets.Dataset con prompt (vacío: la instrucción del entorno se añade en reset), task_dir, task_index, además de columnas de metadatos por tarea de task.toml.
  2. spec.environment_factory: devuelve un callable sin argumentos que produce una instancia nueva de HarborEnv para cada rollout. En reset(task_dir) inicia el sandbox de Harbor de la tarea y devuelve su instrucción; los métodos de herramientas ejecutan comandos dentro del sandbox; env.reward ejecuta el verificador una vez después del rollout.
  3. spec.reward_funcs: una recompensa de resultado que lee el escalar del verificador de Harbor por despliegue.

El conjunto de datos

dataset es un identificador de repositorio de datos de Hugging Face que contiene un árbol de tareas de Harbor, o una ruta local que contiene un subárbol tasks/. Cada tarea es un directorio:

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

Seleccione un subconjunto con num_tasks o indices (mutuamente excluyentes):

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

Agentes: externos vs. instalados

Harbor admite dos formas en las que un agente dirige una tarea, y esta distinción determina lo que se puede entrenar con RL:

  • Los agentes externos se ejecutan fuera del sandbox y controlan el bucle por sí mismos, emitiendo comandos en el contenedor a través de la interfaz de entorno de Harbor (“típicamente ejecutando comandos bash mediante el método exec”). El agente decide cada acción e interpreta cada resultado; el sandbox solo ejecuta.
  • Los agentes instalados se instalan en la imagen del contenedor y se ejecutan allí como un subproceso sin interfaz (ampliando BaseInstalledAgent). Harbor inicia el agente dentro del sandbox y analiza su archivo de trayectoria después (populate_context_post_run); el agente se ejecuta de forma autónoma con su propia inferencia.

La integración de TRL es el patrón de agente externo, y por ahora solo se admite ese patrón. El entrenamiento con RL requiere que el trainer dirija el rollout turno a turno: el modelo de política en entrenamiento genera cada turno, y TRL captura sus tokens y log-probs y aplica la máscara del entorno, exactamente lo que environment_factory proporciona sobre una rollout_func de caja negra. Un agente instalado es opaco para esto: se ejecuta dentro del contenedor con su propio modelo y solo emite una trayectoria a posteriori, por lo que no hay tokens de política ni log-probs para que el trainer optimice, y el modelo en entrenamiento nunca se invoca. Un HarborEnv es, por tanto, un agente externo: sus métodos de herramienta exec en el sandbox, pero el bucle, y el modelo en entrenamiento, permanecen en TRL.

Seleccionar el agente base (harness)

El agente base es el arnés: qué métodos de herramientas expone el env y cómo los envía. Selecciónalo con 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

El arnés "bash" integrado (HarborBashEnv) expone una herramienta bash y envía la respuesta escribiendo en /workdir/answer.txt. Dos arneses más completos se incluyen como ejemplos, cada uno en su propia carpeta con un README que lista sus herramientas, bajo examples/grpo_harbor/harnesses/:

  • jupyter/ (JupyterEnv) — un kernel de Python con estado (las variables persisten entre celdas) + una herramienta de shell.
  • terminal_notes/ (TerminalNotesEnv) — 6 herramientas de shell (incluidos procesos en segundo plano) + un kit de notas persistente de 4 herramientas.
HarborSpec(dataset, agent="examples/grpo_harbor/harnesses/jupyter/env.py:JupyterEnv")
HarborSpec(dataset, agent="examples/grpo_harbor/harnesses/terminal_notes/env.py:TerminalNotesEnv")

Para escribir tu propio harness, subclasa HarborEnv y añade métodos de herramienta: cada método público se convierte en una herramienta (TRL las descubre con inspect.getmembers), por lo que dale a cada uno una firma tipada y un docstring (se usa para construir el esquema de la herramienta). Mantén los auxiliares con prefijo de guion bajo. Usa self._exec(cmd) para ejecutar comandos de shell en el sandbox, y establece PROMPT_SUFFIX para añadir la guía del harness a la instrucción de la tarea:

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}")

El backend de sandbox

environment_type se pasa directamente a Harbor (TRL no lo valida):

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

Se recomienda e2b para el entrenamiento en clúster: solo environment.exec se ejecuta en el sandbox de la nube, por lo que las GPUs se mantienen dedicadas a la política y se pueden ejecutar muchos rollouts de forma concurrente.

Funciones de recompensa

spec.reward_funcs tiene como valor predeterminado una recompensa de resultado: por cada rollout, lee el escalar del verificador de Harbor (env.reward), calculado una vez después del rollout al ejecutar el verificador de tests/ de la tarea en el sandbox. Para una recompensa personalizada, escribe una función de recompensa regular de TRL:

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

API

clase 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 )

Parámetros

  • dataset (str) — Un identificador de repositorio de dataset de Hugging Face que contiene un árbol de tareas de Harbor (p. ej. "AdithyaSK/data_agent_rl_environment_train"), o una ruta local a un directorio que contiene un subárbol tasks/. Cada tarea es un directorio con instruction.md / task.toml / environment/ / tests/.
  • agent (str o type, opcional, valor predeterminado "bash") — El agente base / harness, es decir, la superficie de herramientas que expone el env. Puede ser: un nombre integrado ("bash"), una ruta de importación "package.module:ClassName", una ruta de archivo "path/to/file.py:ClassName" o una subclase de HarborEnv directamente.
  • environment_type (str, opcional, valor predeterminado "docker") — Backend del sandbox de Harbor, se transmite a Harbor (lo que este soporte — "docker", "e2b", "daytona", "gke", "modal", "runloop", …). No se valida aquí; lo valida Harbor. "docker" es el valor predeterminado propio de Harbor; elige "e2b" para delegar el sandboxing en la nube.
  • num_tasks (int, opcional) — Límite del número de tareas que se incluyen en el conjunto de datos. None utiliza todas las tareas del árbol.
  • indices (list[int], opcional) — Índices de tareas específicas (en la lista de tareas ordenada). Mutuamente excluyente con num_tasks.
  • include_metadata (bool, opcional, valor predeterminado True) — Incorpora los metadatos de task.toml de cada tarea (gold_answer, difficulty, …) en las filas del conjunto de datos.

Objeto de especificación única que conecta una suite de tareas de Harbor con un entrenador de TRL.

clase trl.experimental.harbor.HarborEnv

< >

( environment_type: str = 'docker' )

Parámetros

  • environment_type (str, opcional, valor predeterminado "docker") — Backend del sandbox de Harbor, se transmite a Harbor ("docker", "e2b", "daytona", …).

Entorno base de TRL respaldado por un sandbox de Harbor + verificador.

Las subclases definen los métodos de la herramienta (el andamiaje). El ciclo de vida que TRL dirige por cada despliegue: reset(task_dir) (inicia el entorno aislado de la tarea y devuelve su instrucción) -> métodos de la herramienta (ejecuta en el entorno aislado) -> reward (ejecuta el verificador una vez, de forma perezosa, después del despliegue).

clase trl.experimental.harbor.HarborBashEnv

< >

( environment_type: str = 'docker' )

Arnés de una sola herramienta bash; envía escribiendo en /workdir/answer.txt.

bash

< >

( command: str )

Parámetros

  • command — El comando de shell que se debe ejecutar.

Ejecuta un comando de shell en el sandbox y devuelve su salida combinada de stdout+stderr. El shell no es persistente entre llamadas. Úsalo para explorar archivos (ls, head, cat), ejecutar Python (python3 -c "...") y enviar la respuesta (echo -n "<value>" > /workdir/answer.txt).

Limitaciones

  • La integración está en trl.experimental — las API pueden cambiar. Establece TRL_EXPERIMENTAL_SILENCE=1 para silenciar la advertencia en los registros de CI.
  • El cliente de sandbox asíncrono de Harbor está vinculado a un solo bucle de eventos, por lo que cada env ejecuta start/exec/verify de forma síncrona en su propio bucle; la aprovisionamiento de sandboxes es, por tanto, secuencial en el lote de generación (los backends en la nube como e2b mitigan el coste por sandbox).
  • Un único HarborSpec cubre un conjunto de tareas + un harness; el entrenamiento con múltiples conjuntos de tareas aún no se admite.

Referencia

Update on GitHub