TRL (Transformers Reinforcement Learning)

repository·main·Indexed 12 days ago

https://github.com/huggingface/trl

A library for post-training foundation models using reinforcement learning techniques such as SFT, DPO, GRPO, and KTO. Built on the Hugging Face ecosystem, it supports scalable training via Accelerate, PEFT, and DeepSpeed, and provides specialized trainers including SFTTrainer, GRPOTrainer, DPOTrainer, KTOTrainer, and RewardTrainer.

Tokens
150.2K
Snippets
403
Records
563
Agent score
97%

What's inside TRL

  1. Overview of TRL (Transformers Reinforcement Learning)

    main

    TRL is a full-stack library designed for training transformer language models using various post-training methods. It is deeply integrated with the 🤗 transformers library and provides tools for Supervised Fine-Tuning (SFT), Reinforcement Learning (RL), and Preference Optimization.

    Key capabilities include:

    • Online methods: Training with real-time feedback (e.g., GRPOTrainer, PPO).
    • Offline methods: Training on pre-collected datasets (e.g., SFTTrainer, DPOTrainer, KTOTrainer).
    • Reward modeling: Training models to score outputs (e.g., RewardTrainer).
    • Knowledge distillation: Transferring knowledge from larger models to smaller ones (e.g., GKDTrainer).
  2. Overview of supported dataset formats and types in TRL

    main
    TRL trainers support various dataset formats depending on the training objective (e.g., Language Modeling, Preference Learning, or Unpaired Preference). This guide outlines the specific data structures required for trainers like SFTTrainer, DPOTrainer, and GRPOTrainer to function correctly.
  3. Use the TRL CLI for fine-tuning and serving

    main

    The TRL Command Line Interface (CLI) allows you to launch fine-tuning jobs for various alignment and supervised learning methods without writing boilerplate code. It also provides utilities for system inspection and model serving.

    Training Commands

    • trl sft: Supervised Fine-Tuning (SFT)
    • trl dpo: Direct Preference Optimization (DPO)
    • trl grpo: Group Relative Policy Optimization (GRPO)
    • trl kto: Kahneman-Tversky Optimization (KTO)
    • trl rloo: Reinforcement Learning from Online Optimization (RLOO)
    • trl reward: Training a Reward Model

    Utility Commands

    • trl env: Displays current system information.
    • trl vllm-serve: Serves a model using the vLLM engine.
    # Example of running an SFT training job
    trl sft --help
    
    # Example of serving a model
    trl vllm-serve --model <model_name>
    
    # Check system environment
    trl env
  4. Overview of GRPO (Group Relative Policy Optimization)

    main
    GRPO is a variant of Proximal Policy Optimization (PPO) introduced in the DeepSeekMath paper. It is specifically optimized to enhance mathematical reasoning abilities in language models while concurrently reducing the memory overhead typically associated with PPO. It works by optimizing the policy based on relative rewards within a group of generated completions.
  5. What is the General Online Logit Distillation (GOLD) Trainer?

    main

    The GOLDTrainer (located in trl.experimental.gold) is an extension of SFTTrainer designed for knowledge distillation between student and teacher models. Its primary advantage is supporting cross-tokenizer alignment, allowing you to distill knowledge from a teacher to a student even if they use different tokenizers or belong to different model families (e.g., a LLaMA student with a Qwen teacher).

    Key features include:

    • Cross-tokenizer alignment: It aligns textual spans and merges logits so no completion tokens are lost during distillation.
    • Hybrid ULD loss: When uld_use_hybrid_loss is enabled, it uses exact vocabulary matches where possible and falls back to sorted-probability Universal Logit Distillation (ULD) for unmatched tokens.
    • GKD Integration: It inherits on-policy/off-policy scheduling from GKDTrainer.

    Note: As part of the trl.experimental namespace, the API is subject to change.

  6. What is Sequence Parallelism for long context training

    main

    Sequence Parallelism (also called Context Parallelism) is a technique to enable training with very long sequences by splitting the sequence dimension across multiple GPUs. This allows training with sequences that exceed the memory capacity of a single GPU.

    TRL distinguishes between two types of sequence splitting:

    • Context Parallelism (CP): Implemented as Ring Attention using the FSDP2 backend. It splits sequences across GPUs.
    • Sequence Parallelism (SP): Implemented as ALST/Ulysses using the DeepSpeed backend. It uses attention head parallelism.

    Key Terminology:

    • Global sequence length: The full sequence length before splitting. In TRL, max_seq_length (or max_length) refers to this value.
    • Micro sequence length: The sequence length processed by each individual GPU after splitting.

    Note that these parallelism dimensions multiply. For example, if TP=2 and CP=2, you require 4 GPUs ($2 \times 2$).

  7. What is Self-Distillation Policy Optimization (SDPO)?

    main

    Self-Distillation Policy Optimization (SDPO) is a reinforcement learning method designed for verifiable rewards (RLVR), such as math or code. It converts sparse scalar rewards into dense, token-level signals by using the model itself as a teacher.

    When a model generates a successful completion, that completion (optionally combined with environment feedback) is used to create a 'teacher reprompt'. The teacher's feedback-informed distribution is then distilled back into the student policy. This allows the model to leverage its own ability to identify mistakes in-context, improving sample efficiency in environments where only a binary or scalar outcome is typically provided.

  8. What is Simple Self-Distillation (SSD)?

    main

    Simple Self-Distillation (SSD) is a training method that improves code generation by sampling completions from a model at a specific training-time temperature and truncation configuration, then fine-tuning on those raw, unverified samples using standard cross-entropy loss.

    Unlike reinforcement learning, SSD requires:

    • No reward model
    • No verifier
    • No teacher model
    • Only a set of problem prompts and the model itself.

    Key features in the TRL implementation:

    • Uses temperature, top_k, and top_p for training-time generation.
    • The dataset only requires a prompt column.
    • Empty or single-line stub completions are filtered by default (filter_empty=True).
    • vLLM can be used for faster generation via use_vllm=True.
  9. Use the Harmony response format

    main

    The Harmony format extends conversational datasets to support richer structures like reasoning (thinking), tool calls, and metadata.

    Key components:

    • Developer role: Used for high-level instructions and tool lists (similar to a system prompt).
    • Channels: Separates assistant output into analysis (for thinking), final (for content), and commentary (for tool calls).
    • Reasoning effort: Can be set to "low", "medium", or "high".
    • Model identity: Defines the assistant's persona.

    When using tokenizer.apply_chat_template, you can pass reasoning_effort and model_identity to format the messages correctly for models supporting Harmony.

    from transformers import AutoTokenizer
    
    tokenizer = AutoTokenizer.from_pretrained("openai/gpt-oss-20b")
    
    messages = [
        {"role": "developer", "content": "Use a friendly tone."},
        {"role": "user", "content": "What is the meaning of life?"},
        {"role": "assistant", "thinking": "Deep reflection...", "content": "The final answer is..."},
    ]
    
    print(
        tokenizer.apply_chat_template(
            messages,
            tokenize=False,
            reasoning_effort="low",
            model_identity="You are HuggingGPT, a large language model trained by Hugging Face.",
        )
    )
  10. How multi-environment training works with OpenEnv

    main

    You can train a single model across multiple environments simultaneously by using a meta-environment class and environment routing via the dataset.

    Implementation Steps:

    1. Dataset Routing: Add a column (e.g., "env") to your dataset containing the identifier for the target environment for each sample.
    2. Meta-Environment Class: Create a class that wraps all possible environments. In its reset(**kwargs) method, use kwargs.get("env") to select and initialize the correct environment.
      • Lazy Initialization: Initialize clients inside reset() rather than __init__() to avoid unnecessary connections.
      • Cleanup: Close the previous environment's client before opening a new one to prevent server capacity errors.
      • Tool Exposure: The meta-class should expose all tools from all sub-environments. The model will learn to use the correct ones based on the system prompt.
    3. Per-Environment Reward Functions: Define separate reward functions for each environment. Each function should return None for samples that do not belong to its environment. TRL handles None values using nansum/nanmean, ensuring each sample is only scored by its relevant reward.

    Monitoring

    When training with multiple environments, monitor per-reward-function metrics (e.g., train/reward_func_0, train/reward_func_1) instead of the combined train/reward, as the combined metric will be noisy due to alternating environments.

    # 1. Dataset with routing
    dataset = Dataset.from_dict({
        "prompt": ([[...]] * n) + ([[...]] * n),
        "env": ["wordle"] * n + ["catch"] * n,
    })
    
    # 2. Meta-environment routing
    class MultiEnv:
        def reset(self, **kwargs) -> str | None:
            self.active = kwargs.get("env", "wordle")
            if self.active == "wordle":
                # Initialize wordle client...
                return observation
            elif self.active == "catch":
                # Initialize catch client...
                return observation
    
    # 3. Per-environment rewards
    def wordle_reward(environments, **kwargs) -> list[float | None]:
        return [env.reward if env.active == "wordle" else None for env in environments]
    
    def catch_reward(environments, **kwargs) -> list[float | None]:
        return [env.reward if env.active == "catch" else None for env in environments]
  11. Use environment_factory for stateful agent training

    main

    For stateful training where the environment manages its own state and rewards, use the environment_factory argument. GRPOTrainer creates one environment instance per rollout and exposes its public methods as tools.

    Environment Class Requirements:

    • reset(self, **kwargs) -> str | None (Required): Called at the start of each rollout. If it returns a string, that string becomes the user prompt. It can also receive keyword arguments from the train_dataset rows.
    • get_reward(self) -> float (Optional): Returns a float representing the reward based on the environment's internal state. Called once per completed rollout.
    • Public Methods: Any other public methods defined in the class are automatically exposed to the model as tools.

    Note: environment_factory requires transformers>=5.2.0.

    import random
    from trl import GRPOConfig, GRPOTrainer
    
    class IncrementEnv:
        def reset(self, **kwargs) -> str | None:  # required
            self.counter = 0
            self.target = random.randint(1, 6)
            return f"Increment the counter by {self.target}."
    
        def get_reward(self) -> float:  # optional
            return float(self.counter == self.target)
    
        def increment(self, step: int) -> int:  # exposed as tool
            """
            Increment the internal counter.
    
            Args:
                step: Value to add to the counter.
    
            Returns:
                The updated counter value.
            """
            self.counter += step
            return self.counter
    
    trainer = GRPOTrainer(
        model="Qwen/Qwen3-0.6B",
        args=GRPOConfig(max_steps=1000, chat_template_kwargs={"enable_thinking": False}),
        environment_factory=IncrementEnv,
    )
    trainer.train()