TRL documentation

RLOO Trainer

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

RLOO Trainer

model badge

개요

TRL은 Arash Ahmadian, Chris Cremer, Matthias Gallé, Marzieh Fadaee, Julia Kreutzer, Ahmet Üstün 및 Sara Hooker의 논문 Back to Basics: Revisiting REINFORCE Style Optimization for Learning from Human Feedback in LLMs에 설명된 대로 언어 모델 학습을 위한 RLOO Trainer를 지원합니다.

해당 논문의 초록은 다음과 같습니다:

인간 피드백 기반 강화 학습(Reinforcement Learning from Human Feedback, RLHF) 형태의 AI 정렬은 점점 더 고성능 대규모 언어 모델의 핵심 요소로 간주되고 있습니다. 최근 문헌에서는 근접 정책 최적화(Proximal Policy Optimization, PPO)를 RLHF의 RL 부분에 대한 표준적인 방법으로 제시하고 있습니다. 그러나 PPO는 높은 계산 비용과 민감한 하이퍼파라미터 튜닝을 수반합니다. 우리는 PPO 개발로 이어진 대부분의 동기 부여 원칙이 RLHF에서는 실질적인 우려 사항이 아니라고 주장하며, 성능을 유지하거나 오히려 향상시키면서 계산 비용이 덜 드는 방법을 옹호합니다. 우리는 RL 맥락에서 인간 선호도 기반 정렬의 수식화를 재검토합니다. 단순성을 지침으로 삼아, 우리는 PPO의 많은 구성 요소가 RLHF 맥락에서 불필요하며, PPO와 DPO, RAFT와 같은 신생 “RL-free” 방법론 모두보다 훨씬 단순한 REINFORCE 스타일의 최적화 변형이 더 우수한 성능을 낸다는 것을 보여줍니다. 우리의 연구는 LLM 정렬 특성에 대한 신중한 적응을 통해 낮은 비용으로 온라인 RL 최적화의 이점을 얻을 수 있음을 시사합니다.

이 포스트 트레이닝 방법은 Costa Huang이 기여했으며, 이후 Shirin Yamani가 리팩토링했습니다.

빠른 시작

이 예제는 RLOO 방법을 사용하여 모델을 학습하는 방법을 보여줍니다. DeepMath-103K 데이터셋의 프롬프트를 사용하여 Qwen 0.5B Instruct 모델을 학습합니다. 데이터셋의 데이터는 여기서 확인할 수 있습니다:

아래는 모델을 학습하는 스크립트입니다. accuracy_reward에는 math-verify가 필요하며, pip install trl[math_verify]로 설치할 수 있습니다.

# train_rloo.py
from datasets import load_dataset
from trl import RLOOTrainer
from trl.rewards import accuracy_reward

dataset = load_dataset("trl-lib/DeepMath-103K", split="train")

trainer = RLOOTrainer(
    model="Qwen/Qwen2-0.5B-Instruct",
    reward_funcs=accuracy_reward,
    train_dataset=dataset,
)
trainer.train()

다음 명령을 사용하여 스크립트를 실행합니다:

torchrun --nproc_per_node 8 train_rloo.py

RLOO 방법 자세히 살펴보기

RLOO는 온라인 학습 알고리즘으로, 학습 중에 학습된 모델 자체에서 생성된 데이터를 사용하여 반복적으로 성능을 향상시킵니다. RLOO 목적 함수의 핵심 직관은 모델이 참조 정책(reference policy)에 가깝도록 유지하면서 생성된 completions의 이점을 최대화하는 것입니다. RLOO의 작동 방식을 이해하려면 다음 네 가지 주요 단계로 나눌 수 있습니다: completions 생성, 이점(advantage) 계산, KL 발산 추정, 손실(loss) 계산.

RLOO

완성 결과 생성

각 학습 단계에서 프롬프트 배치(batches)를 샘플링하고 각 프롬프트에 대해 G G 개의 completion을 생성합니다(기호는 oi o_i ).

보상 계산

RLOO에서 보상(reward)은 두 가지 구성 요소로 이루어져 있습니다. 보상 모델(또는 보상 함수)이 제공하는 보상과, 정책(policy)이 고정된 참조 정책(reference policy)에서 너무 벗어나지 않도록 억제하는 KL 페널티입니다.

  1. 각 G G 생성된 시퀀스 oi=(oi,1,…,oi,T) o_i = (o_{i,1}, \dots, o_{i,T}) 에 대해 쿼리 q q , 에 조건부화된 각 시퀀스에 대해 보상 모델 R(oi,q) R(o_i, q) .
  2. 동시에, 현재 정책 πθ \pi_\theta 과 고정된 참조 정책 πref \pi_{\text{ref}} 사이의 시퀀스 전체에 걸친 KL 발산을 추정합니다. 시퀀스 oi o_i 에 대한 KL 추정값은 다음과 같습니다: DKL ⁣[πθ∥πref]=∑t=1Tlog⁡πθ(oi,t∣q,oi,<t)πref(oi,t∣q,oi,<t). \mathbb{D}_{\mathrm{KL}}\!\left[\pi_\theta\|\pi_{\mathrm{ref}}\right] = \sum_{t=1}^T \log \frac{\pi_\theta(o_{i,t} \mid q, o_{i,<t})}{\pi_{\mathrm{ref}}(o_{i,t} \mid q, o_{i,<t})}.

시퀀스에 할당되는 최종 보상 oi o_i 은 다음과 같습니다: ri=R(oi,q)−β DKL ⁣[πθ∥πref], r_i = R(o_i, q) - \beta \, \mathbb{D}_{\mathrm{KL}}\!\left[\pi_\theta \|\pi_{\mathrm{ref}}\right],

여기서 β>0 \beta > 0 KL 패널티의 강도를 제어합니다.

순수 온라인 설정(num_iterations = 1, 기본값)에서는 데이터가 현재 정책(policy)에 의해 생성됩니다. 이 경우 KL 패널티는 현재 정책을 직접 사용하여 계산됩니다.

더 일반적인 설정(예: 배치당 여러 개의 gradient step)에서는 데이터가 이전 스냅샷 πold \pi_{\text{old}} . 이 정책 기준으로 정의된 KL을 사용하여, 벌칙이 샘플링 분포와 일치하도록 합니다:

DKL ⁣[πold ∥ πref]. \mathbb{D}_{\mathrm{KL}}\!\left[\pi_{\text{old}} \,\|\, \pi_{\text{ref}}\right].

동일하게, 샘플링된 시퀀스 o o , 에 대해 Monte Carlo 추정값은 다음과 같습니다:

DKL ⁣[πold∥πref]=∑t=1Tlog⁡πold(oi,t∣q,oi,<t)πref(oi,t∣q,oi,<t). \mathbb{D}_{\mathrm{KL}}\!\left[\pi_{\text{old}} \|\pi_{\mathrm{ref}}\right] = \sum_{t=1}^T \log \frac{\pi_{\text{old}}(o_{i,t} \mid q, o_{i,<t})}{\pi_{\mathrm{ref}}(o_{i,t} \mid q, o_{i,<t})}.

이점(advantage) 계산

각 completion에 대한 보상이 계산되면, 현재 샘플을 제외한 동일한 배치 내 다른 모든 샘플의 평균 보상을 baseline으로 계산합니다. 이 baseline은 정책 기울기 추정치의 분산을 줄이는 데 사용됩니다. 각 completion의 advantage는 해당 completion의 자체 보상에서 이 leave-one-out baseline을 뺀 차이로 구해집니다.

정식적으로, G개의 completion 배치에 대해 completion의 baseline은 다음과 같습니다:bi=1G−1∑j≠irj b_i = \frac{1}{G-1} \sum_{j \neq i} r_j

그리고 각 completion의 advantage는 해당 reward와 baseline의 차이로 계산됩니다: Ai=ri−bi A_i = r_i - b_i

손실 계산

REINFORCE 손실은 다음과 같이 간단히 정의됩니다: LRLOO(θ)=−1G∑i=1GA^i log⁡πθ(oi∣q) \mathcal{L}_{\text{RLOO}}(\theta) = - \frac{1}{G} \sum_{i=1}^G \hat{A}_i \, \log \pi_\theta(o_i \mid q)

실제로 동일한 배치에서 여러 단계의 기울기 업데이트를 수행하면, 현재 파라미터에 대해 동작이 사실상 오프-폴리시(off-policy)가 됩니다. 이를 보정하기 위해 중요도 샘플링(importance sampling) 비율을 도입합니다. 샘플링과 기울기 단계 사이에 정책이 변경될 때 과도하게 큰 업데이트를 방지하기 위해 이 비율을 클리핑(clip)합니다: LRLOO(θ)=−1G∑i=1Gmin⁡(πθ(oi∣q)πθold(oi∣q)A^i, clip(πθ(oi∣q)πθold(oi∣q),1−ϵ,1+ϵ)A^i) \mathcal{L}_{\text{RLOO}}(\theta) = - \frac{1}{G} \sum_{i=1}^G \min \left( \frac{\pi_\theta(o_i \mid q)}{\pi_{\theta_\text{old}}(o_i \mid q)} \hat{A}_i, \, \text{clip}\left(\frac{\pi_\theta(o_i \mid q)}{\pi_{\theta_\text{old}}(o_i \mid q)}, 1-\epsilon, 1+\epsilon\right) \hat{A}_i \right)

완전 온라인, 단일 단계 설정(기본값)에서 πθ(oi∣q)πθold(oi∣q)=1 \frac{\pi_\theta(o_i \mid q)}{\pi_{\theta_\text{old}}(o_i \mid q)} = 1 이는 표준 REINFORCE로 축소됩니다.

GRPO와 달리 RLOO는 KL 항을 통해 기울기를 역전파하지 않습니다. 여기서 KL은 순수하게 보상 성형(reward shaping)에 사용되며, no_grad 아래에서 계산되어 스칼라 보상 ri r_i , 에 포함되며, 이는 분리된(detached) 이점(advantage)이 됩니다. A^i \hat{A}_i .

즉, 정책으로 전달되는 경로의 유일한 경로는 중요도 비율(importance-ratio) 항입니다 πθ(oi∣q)πθold(oi∣q) \frac{\pi_\theta(o_i \mid q)}{\pi_{\theta_\text{old}}(o_i \mid q)} , 그리고 KL 항은 정책으로 역전파되지 않습니다.

반면, GRPO 는 현재 정책 πθ \pi_\theta , 을 통해 실시간으로 계산되는 명시적이고 미분 가능한 KL 항을 목적 함수에 추가하여, 그 기울기가 비율 항과 KL 페널티 양쪽을 통해 흐르도록 합니다.

기록된 지표

학습 및 평가 중에 다음 메트릭을 기록합니다:

  • num_tokens: 프롬프트와 완성 결과를 모두 포함하여 지금까지 처리된 토큰의 총 개수.
  • step_time: 학습 단계당 평균 소요 시간(초 단위, 생성 포함).
  • completions/mean_length: 생성된 completions의 평균 길이.
  • completions/min_length: 생성된 completions의 최소 길이입니다.
  • completions/max_length: 생성된 completions의 최대 길이.
  • completions/mean_terminated_length: EOS로 종료된 생성된 completions의 평균 길이입니다.
  • completions/min_terminated_length: EOS로 종료되는 생성된 completions의 최소 길이입니다.
  • completions/max_terminated_length: EOS로 종료되는 생성된 completions의 최대 길이입니다.
  • completions/clipped_ratio: 잘림(클립)된 completions의 비율.
  • rewards/{reward_func_name}/mean: 특정 보상 함수의 평균 보상입니다.
  • rewards/{reward_func_name}/std: 특정 보상 함수의 보상의 표준편차입니다.
  • reward: 함수 간 보상을 합산한 후(가중치는 reward_weights로 적용) 계산된 전체 평균 보상입니다.
  • reward_std: 함수 전체에 걸쳐 합산된 보상(가중치 reward_weights 적용)의 표준편차로, 전체 배치에 대해 계산됩니다.
  • frac_reward_zero_std: 생성 배치 내에서 보상 표준편차가 0인 샘플의 비율입니다. 이는 해당 프롬프트에 대한 다양성이 적다는 것을 의미하며(모든 답변이 정답이거나 오답임)
  • entropy: 생성된 완성본 전체에 걸친 토큰 예측의 평균 엔트로피입니다. (mask_truncated_completions=True인 경우, 마스킹된 시퀀스의 토큰은 제외됩니다.)
  • aux_loss: Mixture-of-Experts 모델의 로드 밸런싱 보조 손실입니다. router_aux_loss_coef로 스케일링되어 손실에 추가되기 전의 값입니다. 모델이 MoE 모델이고 router_aux_loss_coef가 0이 아닌 경우에만 기록됩니다.
  • kl: 생성된 completions에 대해 모델과 reference model 사이의 평균 KL 발산을 계산한 값입니다. beta가 0이 아닌 경우에만 기록됩니다.
  • clip_ratio/region_mean: RLOO 목적 함수가 신뢰 영역(trust region) 내에 머물도록 클리핑되는 시퀀스 확률의 비율: clip(ri(θ),1−ϵlow,1+ϵhigh) ,ri(θ)=πθ(oi∣q)πθold(oi∣q) \text{clip}\left( r_{i}(\theta), 1 - \epsilon_\mathrm{low}, 1 + \epsilon_\mathrm{high} \right)\,, \quad r_{i}(\theta) = \frac{\pi_\theta(o_{i} \mid q)}{\pi_{\theta_{\text{old}}}(o_{i} \mid q)} . 값이 높을수록 더 많은 샘플이 클리핑되어 정책 πθ\pi_\theta 이 변경될 수 있는 범위가 제한됩니다.
  • clip_ratio/low_mean: trust region의 하한에서 클리핑된 시퀀스 확률의 평균 비율: ri,t(θ)<1−ϵlowr_{i,t}(\theta) < 1 - \epsilon_\mathrm{low}.
  • clip_ratio/low_min: trust region 하한에서 completion별 가장 작은 clip 지표: ri,t(θ)<1−ϵlowr_{i,t}(\theta) < 1 - \epsilon_\mathrm{low}.
  • clip_ratio/high_mean: trust region의 상한에서 클리핑된 시퀀스 확률의 평균 비율: ri,t(θ)>1+ϵhighr_{i,t}(\theta) > 1 + \epsilon_\mathrm{high}.
  • clip_ratio/high_max: trust region의 상한에서 completion별 최대 clip 지표: ri,t(θ)>1+ϵhighr_{i,t}(\theta) > 1 + \epsilon_\mathrm{high}.

커스터마이징

vLLM 기반 생성으로 학습 속도 향상

온라인 방식으로 학습할 때 생성 과정이 주요 병목 현상이 되는 경우가 많습니다. 생성을 가속화하려면 LLM용 고처리량, 저지연 추론 엔진인 vLLM을 사용할 수 있습니다. 이를 활성화하려면 먼저 패키지를 설치해야 합니다.

pip install trl[vllm]

학습 중 vLLM을 사용하는 두 가지 방식을 지원합니다: 서버 모드와 콜로케이트 모드입니다.

옵션 1: Colocate 모드

이 모드에서는 vLLM이 트레이너 프로세스 내에서 실행되며 학습 모델과 GPU 메모리를 공유합니다. 이를 통해 별도의 서버를 시작할 필요가 없으며 GPU 활용도를 높일 수 있지만, 학습 GPU에서 메모리 경쟁이 발생할 수 있습니다. 이 모드가 기본 모드입니다.

from trl import RLOOConfig

training_args = RLOOConfig(
    ...,
    use_vllm=True,  # vllm_mode="colocate" by default
)

옵션 2: 서버 모드

이 모드에서는 vLLM이 별도의 프로세스(그리고 별도의 GPU)에서 실행되며 HTTP를 통해 trainer와 통신합니다. 추론에 전용 GPU가 있는 경우 이상적입니다.

  1. vLLM 서버 시작:

    VLLM_SERVER_DEV_MODE=1 vllm serve <model_name> \
        --weight-transfer-config '{"backend": "nccl"}' \
        --logprobs-mode processed_logprobs \
        --max-logprobs -1
  2. 학습 스크립트에서 서버 모드를 활성화합니다:

    from trl import RLOOConfig
    
    training_args = RLOOConfig(
        ...,
        use_vllm=True,
        vllm_mode="server",
    )

서버가 trainer와 다른 GPU를 사용하도록 확인하세요. 그렇지 않으면 NCCL 오류가 발생할 수 있습니다. 사용할 GPU는 CUDA_VISIBLE_DEVICES 환경 변수로 지정할 수 있습니다.

모델 크기와 학습에 필요한 전체 GPU 메모리 요구 사항에 따라, 리소스 과소 사용 또는 메모리 부족 오류를 방지하기 위해 RLOOConfig의 vllm_gpu_memory_utilization 매개변수를 조정해야 할 수 있습니다.

모델 구성 및 실험 설정에 기반하여 권장 GPU 메모리 사용률을 추정하는 데 도움이 되는 HF Space를 제공합니다. 아래처럼 사용하면 vllm_gpu_memory_utilization 권장 값을 얻을 수 있습니다:

권장 값이 사용자의 환경에서 작동하지 않는 경우, 안정성을 보장하기 위해 권장 값에 작은 버퍼(예: +0.05 또는 +0.1)를 추가하는 것을 권장합니다.

여전히 out-of-memory 오류가 발생하면 vllm_enable_sleep_mode을 True로 설정하세요. 그러면 최적화 단계에서 vllm 매개변수와 캐시가 offload됩니다. 자세한 내용은 vLLM Sleep Mode를 사용한 메모리 사용량 감소를 참조하세요.

기본적으로 RLOO는 vLLM에 대해 MASTER_ADDR=localhost와 MASTER_PORT=12345를 사용하지만, 환경 변수를 적절히 설정하여 이 값들을 덮어쓸 수 있습니다.

자세한 내용은 vLLM을 활용한 학습 속도 향상을 참조하세요.

대규모 RLOO: 여러 노드에서 70B+ 모델 학습

Qwen2.5-72B와 같은 대규모 모델을 학습할 때는 여러 GPU와 노드에 걸쳐 학습을 효율적이고 확장 가능하게 만들기 위해 몇 가지 핵심 최적화가 필요합니다. 여기에는 다음이 포함됩니다:

  • DeepSpeed ZeRO Stage 3: ZeRO는 데이터 병렬성을 활용하여 모델 상태(가중치, 기울기, 옵티마이저 상태)를 여러 GPU와 CPU에 분산 배치하여 각 장치의 메모리 및 계산 요구 사항을 줄입니다. 대규모 모델은 단일 GPU에 적재할 수 없으므로, 이러한 모델을 학습하려면 ZeRO Stage 3 사용이 필수적입니다. 자세한 내용은 DeepSpeed Integration을 참조하세요.
  • torchrun: PyTorch의 런처는 모든 노드에서 GPU당 하나의 프로세스를 시작하고 공통 rendezvous를 통해 연결합니다. 자세한 내용은 학습 분산을 참조하세요.
  • vLLM: 생성 속도를 높이기 위해 vLLM을 사용하는 방법은 이전 섹션을 참고하세요.

아래는 여러 노드에서 RLOO를 사용하여 70B 모델을 학습하기 위한 SLURM 스크립트 예시입니다. 이 스크립트는 4개의 노드에서 모델을 학습하고, 5번째 노드에서는 vLLM 기반 생성을 수행합니다.

#!/bin/bash
#SBATCH --nodes=5
#SBATCH --gres=gpu:8

# Get the list of allocated nodes
NODELIST=($(scontrol show hostnames $SLURM_JOB_NODELIST))

# Assign the first 4 nodes for training and the 5th node for vLLM
TRAIN_NODES="${NODELIST[@]:0:4}"  # Nodes 0, 1, 2, 3 for training
VLLM_NODE="${NODELIST[4]}"  # Node 4 for vLLM

# Run training on the first 4 nodes (Group 1)
srun --nodes=4 --ntasks=4 --nodelist="${NODELIST[@]:0:4}" torchrun \
     --nnodes 4 \
     --nproc_per_node 8 \
     --node_rank $SLURM_PROCID \
     --rdzv_backend c10d \
     --rdzv_endpoint ${NODELIST[0]}:29500 \
     train_rloo.py \
     --server_ip $VLLM_NODE &

# Run vLLM server on the 5th node (Group 2)
srun --nodes=1 --ntasks=1 --nodelist="${NODELIST[4]}" env VLLM_SERVER_DEV_MODE=1 vllm serve Qwen/Qwen2.5-72B --tensor-parallel-size 8 \
    --weight-transfer-config '{"backend": "nccl"}' \
    --logprobs-mode processed_logprobs \
    --max-logprobs -1 &

wait
import argparse

from datasets import load_dataset
from trl import RLOOTrainer, RLOOConfig

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--vllm_server_host", type=str, default="", help="The server IP")
    args = parser.parse_args()

    # Example dataset from TLDR
    dataset = load_dataset("trl-lib/tldr", split="train")

    # Dummy reward function: count the number of unique characters in the completions
    def reward_num_unique_chars(completions, **kwargs):
        return [len(set(c)) for c in completions]

    training_args = RLOOConfig(
        output_dir="Qwen2.5-72B-RLOO",
        per_device_train_batch_size=4,
        bf16=True,
        deepspeed="examples/deepspeed_configs/zero3.json",
        use_vllm=True,
        vllm_mode="server",
        vllm_server_host=args.vllm_server_host.replace("ip-", "").replace("-", "."),  # from ip-X-X-X-X to X.X.X.X
    )

    trainer = RLOOTrainer(model="Qwen/Qwen2.5-72B", args=training_args, reward_funcs=reward_num_unique_chars, train_dataset=dataset)
    trainer.train()

if __name__=="__main__":
    main()

사용자 정의 보상 함수 사용

RLOOTrainer는 밀도 보상 모델 대신 사용자 정의 보상 함수를 사용할 수 있습니다. 호환성을 보장하기 위해 보상 함수는 다음 요구 사항을 충족해야 합니다:

Reward 함수는 동기 Python callable이거나 비동기 async def 코루틴일 수 있습니다. 여러 비동기 reward 함수를 제공하면 asyncio.gather를 통해 병렬로 실행되어 대기되므로, 지연 시간이 겹치게 됩니다.

  1. 입력 인자:

    • 이 함수는 다음을 키워드 인수로 받아야 합니다:

      • prompts(프롬프트를 포함합니다),
      • completions (생성된 completions을 포함),
      • completion_ids (토큰화된 completions을 포함),
      • trainer_state (TrainerState): 트레이너의 현재 상태입니다. 학습 진행도에 따라 보상이 조정되는 커리큘럼 학습과 같은 동적 보상 함수를 구현하는 데 사용할 수 있습니다.
      • log_extra: completions 테이블에 추가 열을 추가하기 위한 callable log_extra(column: str, values: list). 예제 6을 참조하세요.
      • log_metric: kl, entropy 등과 함께 스칼라 메트릭을 플롯으로 기록하기 위한 콜러블 log_metric(name: str, value: float). 예제 6을 참조하세요.
      • 데이터셋에 있을 수 있는 모든 열 이름(prompt 제외). 예를 들어, 데이터셋에 ground_truth라는 이름의 열이 포함된 경우, 해당 함수는 ground_truth를 키워드 인수로 받아 호출됩니다.

      이 요구 사항을 충족하는 가장 쉬운 방법은 함수 시그니처에 **kwargs를 사용하는 것입니다.

    • 데이터셋 형식에 따라 입력이 달라집니다:

      • 표준 형식의 경우, prompts와 completions는 문자열 목록입니다.
      • 대화 형식의 경우, prompts와 completions는 메시지 딕셔너리의 목록입니다.
  2. 반환 값: 함수는 float의 리스트를 반환해야 합니다. 각 float는 단일 completion에 해당하는 보상을 나타냅니다.

예제 1: 더 긴 완성본을 보상

아래는 더 긴 완성본을 보상하는 표준 형식의 보상 함수 예시입니다:

def reward_func(completion_ids, **kwargs):
    """Reward function that assigns higher scores to longer completions (in terms of token count)."""
    return [float(len(ids)) for ids in completion_ids]

다음과 같이 테스트할 수 있습니다:

>>> prompts = ["The sky is", "The sun is"]  # not used in the reward function, but the trainer will pass it
>>> completions = [" blue.", " in the sky."]  # not used in the reward function, but the trainer will pass it
>>> completion_ids = [[6303, 13], [304, 279, 12884, 13]]
>>> reward_func(prompts=prompts, completions=completions, completion_ids=completion_ids)
[2.0, 4.0]

예제 1.1: 더 긴 완성본을 보상합니다 (문자 수 기준)

이전 예제와 동일하지만, 이번에는 보상 함수가 토큰이 아닌 문자 수를 기반으로 합니다.

def reward_func(completions, **kwargs):
    """Reward function that assigns higher scores to longer completions (in terms of character count)."""
    return [float(len(completion)) for completion in completions]

다음과 같이 테스트할 수 있습니다:

>>> prompts = ["The sky is", "The sun is"]
>>> completions = [" blue.", " in the sky."]
>>> completion_ids = [[6303, 13], [304, 279, 12884, 13]]  # not used in the reward function, but the trainer will pass it
>>> reward_func(prompts=prompts, completions=completions, completion_ids=completion_ids)
[6.0, 12.0]

예제 2: 특정 형식으로 보상 완료

아래는 완성물이 특정 형식을 갖는지 확인하는 보상 함수의 예시입니다. 이 예시는 DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 논문에서 사용된 format reward 함수에서 영감을 받았습니다. 프롬프트와 완성물이 구조화된 메시지로 구성된 대화형 형식을 위해 설계되었습니다.

import re

def format_reward_func(completions, **kwargs):
    """Reward function that checks if the completion has a specific format."""
    pattern = r"^<think>.*?</think><answer>.*?</answer>$"
    completion_contents = [completion[0]["content"] for completion in completions]
    matches = [re.match(pattern, content) for content in completion_contents]
    return [1.0 if match else 0.0 for match in matches]

다음과 같이 이 함수를 테스트할 수 있습니다:

>>> prompts = [
...     [{"role": "user", "content": "What is the result of (1 + 2) * 4?"}],
...     [{"role": "user", "content": "What is the result of (3 + 1) * 2?"}],
... ]
>>> completions = [
...     [{"role": "assistant", "content": "<think>The sum of 1 and 2 is 3, which we multiply by 4 to get 12.</think><answer>(1 + 2) * 4 = 12</answer>"}],
...     [{"role": "assistant", "content": "The sum of 3 and 1 is 4, which we multiply by 2 to get 8. So (3 + 1) * 2 = 8."}],
... ]
>>> format_reward_func(prompts=prompts, completions=completions)
[1.0, 0.0]

예제 3: 참조를 기반으로 보상 완료

아래는 완성물이 올바른지 확인하는 보상 함수의 예시입니다. 이 예시는 DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 논문에서 사용된 accuracy reward 함수에서 영감을 받았습니다. 이 예시는 standard format를 위해 설계되었으며, 데이터셋에는 ground_truth라는 이름의 열이 포함되어 있습니다.

import re

def reward_func(completions, ground_truth, **kwargs):
    # Regular expression to capture content inside \boxed{}
    matches = [re.search(r"\\boxed\{(.*?)\}", completion) for completion in completions]
    contents = [match.group(1) if match else "" for match in matches]
    # Reward 1 if the content is the same as the ground truth, 0 otherwise
    return [1.0 if c == gt else 0.0 for c, gt in zip(contents, ground_truth)]

다음과 같이 이 함수를 테스트할 수 있습니다:

>>> prompts = ["Problem: Solve the equation $2x + 3 = 7$. Solution:", "Problem: Solve the equation $3x - 5 = 10$."]
>>> completions = [r" The solution is \boxed{2}.", r" The solution is \boxed{6}."]
>>> ground_truth = ["2", "5"]
>>> reward_func(prompts=prompts, completions=completions, ground_truth=ground_truth)
[1.0, 0.0]

예제 4: 다중 작업 보상 함수

아래는 RLOOTrainer에서 여러 보상 함수를 사용하는 예시입니다. 이 예시에서는 두 가지 작업별 보상 함수인 math_reward_func와 coding_reward_func를 정의합니다. math_reward_func는 수학 문제의 정답 여부 기준으로 보상을 부여하고, coding_reward_func는 코딩 문제의 솔루션이 정상적으로 작동하는지 여부 기준으로 보상을 부여합니다.

from datasets import Dataset
from trl import RLOOTrainer

# Define a dataset that contains both math and coding problems
dataset = Dataset.from_list(
    [
        {"prompt": "What is 2+2?", "task": "math"},
        {"prompt": "Write a function that returns the sum of two numbers.", "task": "code"},
        {"prompt": "What is 3*4?", "task": "math"},
        {"prompt": "Write a function that returns the product of two numbers.", "task": "code"},
    ]
)

# Math-specific reward function
def math_reward_func(prompts, completions, task, **kwargs):
    rewards = []
    for prompt, completion, t in zip(prompts, completions, task):
        if t == "math":
            # Calculate math-specific reward
            correct = check_math_solution(prompt, completion)
            reward = 1.0 if correct else -1.0
            rewards.append(reward)
        else:
            # Return None for non-math tasks
            rewards.append(None)
    return rewards

# Coding-specific reward function
def coding_reward_func(prompts, completions, task, **kwargs):
    rewards = []
    for prompt, completion, t in zip(prompts, completions, task):
        if t == "code":
            # Calculate coding-specific reward
            works = test_code_solution(prompt, completion)
            reward = 1.0 if works else -1.0
            rewards.append(reward)
        else:
            # Return None for non-coding tasks
            rewards.append(None)
    return rewards

# Use both task-specific reward functions
trainer = RLOOTrainer(
    model="Qwen/Qwen2-0.5B-Instruct",
    reward_funcs=[math_reward_func, coding_reward_func],
    train_dataset=dataset,
)

trainer.train()

이 예시에서 math_reward_func와 coding_reward_func는 수학 문제와 코딩 문제를 모두 포함하는 혼합 데이터셋과 함께 작동하도록 설계되었습니다. 데이터셋의 task 컬럼은 각 문제에 어떤 보상 함수를 적용할지 결정하는 데 사용됩니다. 데이터셋의 샘플에 해당하는 보상 함수가 없으면 보상 함수는 None을 반환하고, RLOOTrainer는 유효한 함수와 작업을 계속 처리합니다. 이를 통해 RLOOTrainer는 서로 다른 적용 범위를 가진 여러 보상 함수를 처리할 수 있습니다.

RLOOTrainer는 보상 함수가 반환하는 None 보상을 무시하고 관련 함수가 반환한 보상만 고려한다는 점에 유의하세요. 이를 통해 모델은 관련 작업으로 학습되고, 관련 보상 함수가 없는 작업은 무시됩니다.

예제 5: 비동상 보상 함수

커스텀 보상 함수는 async def 코루틴으로 정의할 수도 있습니다. 보상이 느린 I/O(예: 원격 서비스 호출)에 의존하는 경우 유용합니다. 여러 개의 async 보상 함수를 전달하면 RLOOTrainer는 이를 병렬로 실행하여 지연 시간이 겹치게 합니다.

다음은 I/O 바운드 작업을 시뮬레이션하는 비동기 보상 함수의 최소 예시입니다:

import asyncio

async def async_reward_func(prompts, completions, **kwargs):
    # Simulate an I/O-bound call (e.g., HTTP request, database lookup)
    await asyncio.sleep(0.01)
    # Simple toy reward: 1.0 if the completion is non-empty, else 0.0
    return [1.0 if completion else 0.0 for completion in completions]

예제 6: 추가 열 및 지표 로깅

completions 테이블에 추가 열을 기록하고 스칼라 메트릭을 플롯으로 기록하는 보상 함수의 예시는 다음과 같습니다.

import re

def reward_func(completions, ground_truth, log_extra=None, log_metric=None, **kwargs):
    extracted = [re.search(r"\\boxed\{(.*?)\}", c) for c in completions]
    extracted = [m.group(1) if m else None for m in extracted]
    rewards = [1.0 if e == gt else 0.0 for e, gt in zip(extracted, ground_truth)]

    if log_extra:
        log_extra("golden_answer", list(ground_truth))
        log_extra("extracted_answer", [e or "[none]" for e in extracted])

    if log_metric:
        log_metric("accuracy", sum(rewards) / len(rewards))

    return rewards

트레이너에 보상 함수 전달

사용자 정의 보상 함수를 사용하려면 다음과 같이 RLOOTrainer에 전달하세요:

from trl import RLOOTrainer

trainer = RLOOTrainer(
    reward_funcs=reward_func,
    ...,
)

여러 개의 보상 함수를 리스트로 전달할 수 있으며, 이 리스트에는 동기 함수와 비동기 함수가 모두 포함될 수 있습니다:

from trl import RLOOTrainer

trainer = RLOOTrainer(
    reward_funcs=[reward_func, async_reward_func1, async_reward_func2],
    ...,
)

보상은 각 함수의 보상 합으로 계산되며, 설정에 reward_weights가 제공된 경우 가중 합으로 계산됩니다.

RLOOTrainer는 서로 다른 유형의 여러 보상 함수를 지원합니다. 자세한 내용은 매개변수 문서를 참조하세요.

비전 언어 모델 학습

RLOO는 텍스트와 이미지를 모두 포함하는 멀티모달 데이터셋에서 Vision-Language Models(VLM)을 학습하는 것을 지원합니다.

지원되는 모델

테스트 환경:

  • Gemma3 — 예: google/gemma-3-4b-it
  • LLaVA-NeXT — 예: llava-hf/llava-v1.6-mistral-7b-hf
  • Qwen2-VL — 예: Qwen/Qwen2-VL-2B-Instruct
  • Qwen2.5-VL — 예: Qwen/Qwen2.5-VL-3B-Instruct
  • SmolVLM2 — 예: HuggingFaceTB/SmolVLM2-2.2B-Instruct

모든 VLM과의 호환성이 보장되지는 않습니다. 특정 모델이 지원되어야 한다고 생각하시면 GitHub에서 이슈를 열어 주세요. 더 좋다면, 필요한 변경 사항이 포함된 pull request를 제출해 주세요.

빠른 시작

rloo_vlm.py를 사용하여 VLM을 파인튜닝합니다. lmms-lab/multimodal-open-r1-8k-verified로 학습하는 명령어 예시:

torchrun --nproc_per_node 8 examples/rloo_visual_math/rloo_visual_math.py \
  --deepspeed examples/deepspeed_configs/zero3.json \
  --model_name_or_path Qwen/Qwen2.5-VL-3B-Instruct \
  --output_dir rloo-Qwen2.5-VL-3B-Instruct \
  --learning_rate 1e-5 \
  --dtype bfloat16 \
  --max_completion_length 1024 \
  --use_vllm \
  --vllm_mode colocate \
  --use_peft \
  --lora_target_modules "q_proj", "v_proj" \
  --log_completions

구성 팁

  • 시각-언어 투영 레이어에 LoRA 사용
  • 메모리 사용량을 줄이기 위해 4-bit 양자화를 활성화
  • VLM은 메모리 집약적입니다 — 작은 배치 크기부터 시작하세요
  • 대부분의 모델은 vLLM(server 및 colocate 모드)과 호환됩니다

데이터셋 형식

각 학습 샘플에는 다음을 포함해야 합니다:

  • prompt: 프로세서의 채팅 템플릿을 통해 포맷된 텍스트
  • image/images: PIL Image 또는 PIL Image 목록

트레이너는 모델의 이미지 프로세서를 통해 이미지에서 텐서로의 변환을 자동으로 처리합니다.

RLOOTrainer

클래스 trl.RLOOTrainer

< >

( model: str | PreTrainedModel | PeftModelreward_funcs: str | transformers.modeling_utils.PreTrainedModel | collections.abc.Callable[..., list[float | None]] | list[str | transformers.modeling_utils.PreTrainedModel | collections.abc.Callable[..., list[float | None]]]args: trl.trainer.rloo_config.RLOOConfig | None = Nonetrain_dataset: datasets.arrow_dataset.Dataset | datasets.iterable_dataset.IterableDataset | None = Noneeval_dataset: datasets.arrow_dataset.Dataset | datasets.iterable_dataset.IterableDataset | datasets.dataset_dict.DatasetDict | datasets.dataset_dict.IterableDatasetDict | dict[str, datasets.arrow_dataset.Dataset | datasets.iterable_dataset.IterableDataset] | None = Noneprocessing_class: transformers.tokenization_utils_base.PreTrainedTokenizerBase | transformers.processing_utils.ProcessorMixin | None = Nonereward_processing_classes: transformers.tokenization_utils_base.PreTrainedTokenizerBase | list[transformers.tokenization_utils_base.PreTrainedTokenizerBase] | None = Nonecallbacks: list[transformers.trainer_callback.TrainerCallback] | None = Noneoptimizers: tuple[typing.Optional[torch.optim.Optimizer], typing.Optional[torch.optim.lr_scheduler.LambdaLR]] = (None, None)quantization_config: BitsAndBytesConfig | None = Nonepeft_config: PeftConfig | None = None )

매개변수

  • model (str 또는 PreTrainedModel 또는 PeftModel) — 학습할 모델. 다음 중 하나여야 합니다:
    • huggingface.co의 모델 저장소에 호스팅된 사전 학습 모델의 model id인 문자열, 또는 save_pretrained를 사용하여 모델 가중치를 저장한 디렉터리의 경로, 예: './my_model_directory/'입니다. 모델은 args.model_init_kwargs의 키워드 인수를 사용하여 <ModelArchitecture>.from_pretrained(여기서 <ModelArchitecture>는 모델 구성에서 파생됨)로 로드됩니다. args.model_init_kwargs에 dtype이 지정되지 않은 경우 기본값은 float32입니다. 이는 from_pretrained와 다르며, 후자의 경우(Transfomers v5부터) dtype은 모델 구성에서 추론됩니다.
    • PreTrainedModel 객체입니다. 인과적 언어 모델만 지원됩니다.
    • PeftModel 객체입니다. 인과 언어 모델만 지원됩니다.
  • reward_funcs (RewardFunc | list[RewardFunc]) — 보상을 계산하는 데 사용할 보상 함수입니다. 보상을 계산하려면 프롬프트와 completions을 인수로 모든 보상 함수를 호출한 후 보상을 합산합니다. 다음 중 하나일 수 있습니다:
    • 다음과 같은 단일 보상 함수:

      • 문자열: huggingface.co의 모델 저장소에 호스팅된 사전 학습 모델의 모델 ID 또는 save_pretrained를 사용하여 모델 가중치를 저장한 디렉터리의 경로, 예: './my_model_directory/'. 모델은 num_labels=1 및 args.model_init_kwargs의 키워드 인수를 사용하여 from_pretrained로 로드됩니다.

      • PreTrainedModel 객체: 시퀀스 분류 모델만 지원됩니다.

      • 사용자 정의 보상 함수: 이 함수에는 프롬프트와 생성된 완성 결과, 그리고 데이터셋의 추가 열이 제공됩니다. 보상 목록을 반환해야 합니다. 사용자 정의 보상 함수는 동기식 또는 비동기식으로 작성할 수 있으며, 해당 샘플에 보상이 적용되지 않는 경우 None을 반환할 수도 있습니다. 이는 서로 다른 유형의 샘플에 서로 다른 보상 함수가 적용되는 멀티태스크 학습에 유용합니다. 보상 함수가 특정 샘플에 대해 None을 반환하면, 해당 샘플의 보상 계산에서 그 보상 함수가 제외됩니다. 자세한 내용은 사용자 정의 보상 함수 사용을 참조하세요.

        Trainer의 상태는 보상 함수에도 전달됩니다. Trainer의 상태는 TrainerState의 인스턴스이며, 보상 함수 시그니처의 trainer_state 인수를 통해 접근할 수 있습니다.

    • 보상 함수의 목록으로, 각 항목은 독립적으로 위의 유형 중 하나일 수 있습니다. 목록 내에서 서로 다른 유형을 혼합하는 것(예: 문자열 모델 ID와 사용자 정의 보상 함수)이 허용됩니다.

  • args (RLOOConfig, 선택 사항) — 이 trainer에 대한 설정입니다. None인 경우 기본 설정이 사용됩니다.
  • train_dataset (Dataset 또는 IterableDataset) — 학습에 사용할 Dataset입니다. 반드시 "prompt". 컬럼을 포함해야 합니다. Dataset의 추가 컬럼은 무시됩니다. 샘플 형식은 다음과 같습니다:
    • Standard: 각 샘플에는 일반 텍스트가 포함됩니다.
    • 대화형: 각 샘플에는 구조화된 메시지(예: 역할 및 내용)가 포함됩니다.

    train_dataset이 IterableDataset(예: 스트리밍 데이터셋)인 경우, 그 길이를 추론할 수 없으므로 학습 루프를 제한하고 학습률 스케줄러를 구성하는 데 필요한 총 학습 단계 수를 지정하기 위해 학습 인자에 max_steps를 설정해야 합니다.

  • eval_dataset (Dataset, IterableDataset, DatasetDict, IterableDatasetDict 또는 dict[str, Dataset | IterableDataset]) — 평가에 사용할 Dataset입니다. train_dataset과 동일한 요구 사항을 충족해야 합니다.
  • processing_class (PreTrainedTokenizerBase, ProcessorMixin, 선택 사항) — 데이터를 처리하는 데 사용되는 처리 클래스입니다. 패딩 쪽은 “left”로 설정해야 합니다. None인 경우, from_pretrained를 사용하여 모델 이름에서 처리 클래스를 로드합니다. 패딩 토큰인 tokenizer.pad_token이 설정되어 있어야 합니다. 처리 클래스에 패딩 토큰이 설정되지 않은 경우, tokenizer.eos_token이 기본값으로 사용됩니다.
  • reward_processing_classes (PreTrainedTokenizerBase 또는 list[PreTrainedTokenizerBase], 선택 사항) — 에 지정된 보상 함수에 해당하는 처리 클래스 reward_funcs. 다음 중 하나일 수 있습니다:
    • reward_funcs에 보상 함수가 하나만 포함된 경우: 단일 처리 클래스가 사용됩니다.
    • 처리 클래스 목록: reward_funcs의 보상 함수 순서와 길이에 일치해야 합니다. None으로 설정하거나, PreTrainedModel에 해당하는 목록 요소가 None인 경우, from_pretrained를 사용하여 해당 모델의 토크나이저가 자동으로 로드됩니다. reward_funcs의 요소 중 커스텀 보상 함수(PreTrainedModel이 아닌 경우)에 해당하는 reward_processing_classes 항목은 무시됩니다.
  • callbacks (의 목록 TrainerCallback, 선택 사항) — 학습 루프를 사용자 정의할 콜백 목록입니다. 여기.

    기본으로 사용되는 콜백 중 하나를 제거하려면 remove_callback 메서드를 사용하세요.

  • optimizers (tuple[torch.optim.Optimizer | None, torch.optim.lr_scheduler.LambdaLR | None], 선택 사항, 기본값 (None, None)) — 사용할 옵티마이저와 스케줄러를 포함하는 튜플입니다. 기본적으로 모델에 AdamW 인스턴스와 args에 의해 제어되는 get_linear_schedule_with_warmup로 생성된 스케줄러를 사용합니다.
  • quantization_config (BitsAndBytesConfig, 선택 사항) — 모델 식별자로부터 모델을 로드할 때 사용되는 양자화 구성입니다. QLoRA 학습을 위해 peft_config와 함께 사용하세요. 모델이 이미 인스턴스화되어 있으면 무시됩니다.
  • peft_config (PeftConfig, 선택 사항) — 모델을 래핑하는 데 사용되는 PEFT 구성입니다. None인 경우 모델은 래핑되지 않습니다.

Trainer for the Reinforce Leave One Out (RLOO) method. This algorithm was initially proposed in the paper Back to Basics: Revisiting REINFORCE Style Optimization for Learning from Human Feedback in LLMs.

예:

>>> from trl import RLOOTrainer
>>> from trl.rewards import accuracy_reward
>>> from datasets import load_dataset

>>> dataset = load_dataset("trl-lib/DeepMath-103K", split="train")

>>> trainer = RLOOTrainer(
...     model="Qwen/Qwen2.5-0.5B-Instruct",
...     reward_funcs=accuracy_reward,
...     train_dataset=dataset,
... )
>>> trainer.train()

train

< >

( resume_from_checkpoint: str | bool | None = Nonetrial: optuna.Trial | dict[str, Any] | None = Noneignore_keys_for_eval: list[str] | None = None ) → ~trainer_utils.TrainOutput

매개변수

  • resume_from_checkpoint (str 또는 bool, 선택 사항) — str인 경우, 이전 Trainer 인스턴스가 저장한 체크포인트의 로컬 경로입니다. bool이고 True와 같으면, 이전 Trainer 인스턴스가 args.output_dir에 저장한 마지막 체크포인트를 로드합니다. 이 값이 지정되어 있으면, 여기서 로드된 모델/옵티마이저/스케줄러 상태로부터 학습이 재개됩니다.
  • trial (optuna.Trial 또는 dict[str, Any], 선택 사항) — 하이퍼파라미터 탐색을 위한 트라이얼 실행 또는 하이퍼파라미터 사전입니다.
  • ignore_keys_for_eval (list[str], 선택 사항) — 모델의 출력(사전에 해당하는 경우)에서 학습 중 평가 예측을 수집할 때 무시해야 할 키의 목록입니다.

반환값

~trainer_utils.TrainOutput

전체 스텝 수, 학습 손실, 메트릭을 포함하는 객체.

주요 학습 진입점.

save_model

< >

( output_dir: str | None = None_internal_call: bool = False )

모델을 저장하므로 from_pretrained()를 사용하여 다시 로드할 수 있습니다.

main 프로세스에서만 저장합니다.

push_to_hub

< >

( commit_message: str | None = 'End of training'blocking: bool = Truetoken: str | None = Nonerevision: str | None = None**kwargs )

매개변수

  • commit_message (str, 선택 사항, 기본값 "End of training") — 푸시할 때 커밋할 메시지입니다.
  • blocking (bool, 선택 사항, 기본값 True) — git push가 완료된 후에만 함수가 반환되어야 하는지 여부.
  • token (str, 선택 사항, 기본값 None) — Trainer의 원래 args를 덮어쓸 수 있는 쓰기 권한이 있는 토큰.
  • revision (str, 선택 사항) — 커밋할 git revision입니다. 기본값은 “main” 브랜치의 head입니다.
  • kwargs (dict[str, Any], 선택) — ~Trainer.create_model_card에 함께 전달되는 추가 키워드 인자입니다.

self.args.hub_model_id 저장소에 self.model과 self.processing_class를 🤗 모델 허브에 업로드합니다.

RLOOConfig

클래스 trl.RLOOConfig

< >

( output_dir: str | None = Noneper_device_train_batch_size: int = 8num_train_epochs: float = 3.0max_steps: int = -1learning_rate: float = 1e-06lr_scheduler_type: transformers.trainer_utils.SchedulerType | str = 'linear'lr_scheduler_kwargs: dict | str | None = Nonewarmup_steps: float = 0optim: transformers.training_args.OptimizerNames | str = 'adamw_torch_fused'optim_args: str | None = Noneweight_decay: float = 0.0adam_beta1: float = 0.9adam_beta2: float = 0.999adam_epsilon: float = 1e-08optim_target_modules: None | str | list[str] = Nonegradient_accumulation_steps: int = 1average_tokens_across_devices: bool = Truemax_grad_norm: float = 1.0label_smoothing_factor: float = 0.0bf16: bool | None = Nonefp16: bool = Falsebf16_full_eval: bool = Falsefp16_full_eval: bool = Falsetf32: bool | None = Nonegradient_checkpointing: bool = Truegradient_checkpointing_kwargs: dict[str, typing.Any] | str | None = Nonetorch_compile: bool = Falsetorch_compile_backend: str | None = Nonetorch_compile_mode: str | None = Noneuse_liger_kernel: bool = Falseliger_kernel_config: dict[str, bool] | None = Noneuse_cache: bool = Falseneftune_noise_alpha: float | None = Nonetorch_empty_cache_steps: int | None = Noneauto_find_batch_size: bool = Falselogging_strategy: transformers.trainer_utils.IntervalStrategy | str = 'steps'logging_steps: float = 10logging_first_step: bool = Falselog_on_each_node: bool = Truelogging_nan_inf_filter: bool = Trueinclude_num_input_tokens_seen: str | bool = 'no'log_level: str = 'passive'log_level_replica: str = 'warning'disable_tqdm: bool | None = Nonereport_to: None | str | list[str] = 'none'run_name: str | None = Noneproject: str = 'huggingface'trackio_space_id: str | None = Nonetrackio_bucket_id: str | None = Nonetrackio_static_space_id: typing.Union[str, NoneType, typing.Literal[False]] = Noneeval_strategy: transformers.trainer_utils.IntervalStrategy | str = 'no'eval_steps: float | None = Noneeval_delay: float = 0per_device_eval_batch_size: int = 8prediction_loss_only: bool = Falseeval_on_start: bool = Falseeval_do_concat_batches: bool = Trueeval_use_gather_object: bool = Falseeval_accumulation_steps: int | None = Noneinclude_for_metrics: list[str] = <factory>batch_eval_metrics: bool = Falsesave_only_model: bool = Falsesave_strategy: transformers.trainer_utils.SaveStrategy | str = 'steps'save_steps: float = 500save_on_each_node: bool = Falsesave_total_limit: int | None = Noneenable_jit_checkpoint: bool = Falsepush_to_hub: bool = Falsehub_token: str | None = Nonehub_private_repo: bool | None = Nonehub_model_id: str | None = Nonehub_strategy: transformers.trainer_utils.HubStrategy | str = 'every_save'hub_always_push: bool = Falsehub_revision: str | None = Noneload_best_model_at_end: bool = Falsemetric_for_best_model: str | None = Nonegreater_is_better: bool | None = Noneignore_data_skip: bool = Falserestore_callback_states_from_checkpoint: bool = Falsefull_determinism: bool = Falseseed: int = 42data_seed: int | None = Noneuse_cpu: bool = Falseaccelerator_config: dict | str | None = Noneparallelism_config: accelerate.parallelism_config.ParallelismConfig | None = Nonedataloader_drop_last: bool = Falsedataloader_num_workers: int = 0dataloader_pin_memory: bool = Truedataloader_persistent_workers: bool = Falsedataloader_prefetch_factor: int | None = Nonedataloader_multiprocessing_context: str | None = Nonedataloader_in_order: bool = Trueremove_unused_columns: bool | None = Falselabel_names: list[str] | None = Nonetrain_sampling_strategy: str = 'random'length_column_name: str = 'length'ddp_find_unused_parameters: bool | None = Noneddp_bucket_cap_mb: int | None = Noneddp_broadcast_buffers: bool | None = Noneddp_static_graph: bool | None = Noneddp_backend: str | None = Noneddp_timeout: int = 1800fsdp: str | None = Nonefsdp_config: dict[str, typing.Any] | str | None = Nonedeepspeed: dict | str | None = Nonedebug: str | list[transformers.debug_utils.DebugOption] = ''skip_memory_metrics: bool = Truedo_train: bool = Falsedo_eval: bool = Falsedo_predict: bool = Falseresume_from_checkpoint: str | None = Nonelocal_rank: int = -1model_init_kwargs: dict[str, typing.Any] | str | None = Nonetrust_remote_code: bool = Falserouter_aux_loss_coef: float | None = Nonedisable_dropout: bool = Falsenum_generations: int | None = 2num_generations_eval: int | None = Nonemax_completion_length: int | None = 512ds3_gather_for_generation: bool = Trueshuffle_dataset: bool | None = Truepad_to_multiple_of: int | str | None = 'auto'generation_batch_size: int | None = Nonesteps_per_generation: int | None = Nonetemperature: float = 1.0top_p: float = 1.0top_k: int = 0min_p: float | None = Nonegeneration_kwargs: dict | str | None = Nonechat_template_kwargs: dict | str | None = Nonerepetition_penalty: float = 1.0cache_implementation: str | None = Noneuse_vllm: bool = Falsevllm_mode: str = 'colocate'vllm_model_impl: str = 'vllm'vllm_enable_sleep_mode: bool = Falsevllm_structured_outputs_regex: str | None = Nonevllm_server_base_url: str | None = Nonevllm_server_host: str = '0.0.0.0'vllm_server_port: int = 8000vllm_server_timeout: float = 240.0vllm_group_port: int = 51216vllm_gpu_memory_utilization: float = 0.3vllm_max_model_length: int | None = Nonevllm_tensor_parallel_size: int = 1beta: float = 0.05num_iterations: int = 1epsilon: float = 0.2epsilon_high: float | None = Nonereward_weights: list[float] | None = Nonenormalize_advantages: bool = Falsereward_clip_range: tuple[float, float] | None = Nonemask_truncated_completions: bool = Falsesync_ref_model: bool = Falseref_model_mixup_alpha: float = 0.6ref_model_sync_steps: int = 512log_completions: bool = Falselog_multimodal: bool = Truenum_completions_to_print: int | None = Nonelog_unique_prompts: bool = Falseuse_transformers_continuous_batching: bool = Falsetransformers_continuous_batching_config: dict | str | None = Noneuse_transformers_paged: bool = False )

모델과 참조 모델을 제어하는 매개변수

  • model_init_kwargs (str 또는 dict[str, Any], 선택 사항) — model 인수가 RLOOTrainer에 문자열로 제공될 때 from_pretrained에 사용되는 키워드 인수입니다. revision 값은 처리 클래스를 로드할 때에도 사용됩니다.
  • trust_remote_code (bool, optional, defaults to False) — Whether to allow loading models and tokenizers that ship custom Python code from the Hub. Forwarded to from_pretrained and from_pretrained. Also applied to reward-model and reward-tokenizer loads.
  • router_aux_loss_coef (float, 선택 사항) — Mixture-of-Experts(MoE) 모델의 로드 밸런싱 보조 손실 계수로, 이 가중치로 학습 손실에 추가됩니다. 설정되지 않으면 모델 구성에서 선언된 값이 사용됩니다. 비활성화하려면 0.0으로 설정하세요. MoE가 아닌 모델과 함께 사용하면 실패합니다.
  • disable_dropout (bool, 선택 사항, 기본값 False) — 모델에서 dropout을 비활성화할지 여부입니다. 이는 참조 모델과 함께 학습할 때 유용하며, 동일한 입력에 대해 모델이 서로 다른 logprobs를 생성하는 것을 방지합니다.

데이터 전처리를 제어하는 매개변수

  • remove_unused_columns (bool, 선택 사항, 기본값 False) — 데이터셋에서 "prompt" 컬럼만 유지할지 여부입니다. "prompts"와 "completions" 이외의 컬럼이 필요한 사용자 정의 보상 함수를 사용하는 경우, 이 값을 False로 유지해야 합니다.
  • num_generations (int, 선택 사항, 기본값은 2) — 프롬프트당 샘플링할 생성 횟수. 유효 배치 크기(num_processes * per_device_batch_size
    • gradient_accumulation_steps)은 이 값으로 나누어 떨어져야 합니다.
  • num_generations_eval (int, 선택 사항) — 평가 중에 샘플링할 생성 횟수입니다. 이를 통해 평가 시 생성 횟수를 줄여 계산 비용을 절약할 수 있습니다. None인 경우 num_generations의 값을 사용합니다.
  • max_completion_length (int 또는 None, 선택 사항, 기본값 512) — 생성된 completion의 최대 길이입니다.
  • ds3_gather_for_generation (bool, 선택 사항, 기본값 True) — 이 설정은 DeepSpeed ZeRO-3에 적용됩니다. 활성화하면 정책 모델 가중치가 생성을 위해 수집되어 생성 속도가 향상됩니다. 그러나 이 옵션을 비활성화하면 단일 GPU의 VRAM 용량을 초과하는 모델을 학습할 수 있지만, 생성 속도가 느려집니다. 이 옵션을 비활성화하면 vLLM 생성과 호환되지 않습니다.
  • shuffle_dataset (bool, 선택 사항, 기본값 True) — 학습 데이터셋을 섞을지 여부입니다.
  • pad_to_multiple_of (int 또는 str, 선택 사항, 기본값 "auto") — 설정된 경우, 프롬프트 ID와 완성문 ID는 이 값의 배수로 패딩됩니다. "auto"는 Neuron(AWS Trainium)에서 입력 형식별로 한 번만 컴파일되도록 128의 배수로 패딩하며, 다른 환경에서는 패딩하지 않습니다.

생성을 제어하는 매개변수

  • generation_batch_size (int, 선택 사항) — 생성에 사용할 배치 크기입니다. None인 경우, 실제 학습 배치 크기인 per_device_train_batch_size * num_processes * steps_per_generation가 기본값으로 사용됩니다. 즉, 최적화 단계마다 하나의 생성 배치만 처리됩니다. steps_per_generation와 상호 배타적입니다.
  • steps_per_generation (int, 선택 사항) — 생성당히 스텝 수입니다. None인 경우 기본값은 gradient_accumulation_steps입니다. generation_batch_size와 상호 배타적입니다.
  • temperature (float, 선택 사항, 기본값 1.0) — 샘플링에 사용할 온도입니다. 온도가 높을수록 완성 결과가 더 무작위적으로 생성됩니다.
  • top_p (float, 선택 사항, 기본값 1.0) — 고려할 상위 토큰의 누적 확률을 제어하는 값입니다. 값은 (0, 1] 범위에 있어야 합니다. 모든 토큰을 고려하려면 1.0으로 설정하세요.
  • top_k (int, 선택 사항, 기본값 0) — top-k-filtering을 위해 유지할 가장 높은 확률의 어휘 토큰 수입니다. 0인 경우 top-k-filtering이 비활성화되고 모든 토큰이 고려됩니다.
  • min_p (float, 선택 사항) — 최대 확률을 가진 토큰의 확률로 스케일링되는 최소 토큰 확률입니다. 0.0과 1.0 사이의 값이어야 합니다. 일반적인 값은 0.01-0.2 범위입니다.
  • generation_kwargs (dict[str, Any], 선택 사항) — completions 샘플링 시 GenerationConfig(transformers 사용 시) 또는 SamplingParams(vLLM 사용 시)에 전달할 추가 키워드 인자입니다. suppress_tokens, num_beams 등을 설정하여 생성 동작을 더 자세히 커스터마이징하는 데 사용할 수 있습니다. 다른 생성 매개변수(예: min_p, top_p 등)와 충돌하는 키가 포함된 경우, 해당 키가 우선 적용됩니다.
  • chat_template_kwargs (dict[str, Any], 선택) — 완성 결과를 생성할 때 apply_chat_template 함수에 전달할 추가 키워드 인자입니다.
  • repetition_penalty (float, 선택 사항, 기본값 1.0) — 프롬프트와 지금까지 생성된 텍스트에 해당 토큰이 등장했는지에 따라 새로운 토큰에 페널티를 부과하는 값입니다. 1.0보다 큰 값은 모델이 새로운 토큰을 사용하도록 장려하고, 1.0보다 작은 값은 모델이 토큰을 반복하도록 장려합니다.
  • cache_implementation (str, 선택 사항) — use_vllm이 False로 설정된 경우 더 빠른 생성을 위한 캐시 메서드 구현입니다.

vLLM 기반 생성 가속을 제어하는 매개변수

  • use_vllm (bool, 선택 사항, 기본값 False) — 완성 결과를 생성하는 데 vLLM을 사용할지 여부입니다. True로 설정하면 트레이너는 기본인 model.generate() 대신 vLLM을 사용하여 생성을 수행합니다. vllm이 설치되어 있어야 합니다.
  • vllm_mode (str, 선택 사항, 기본값은 "colocate") — 일 때 vLLM 통합에 사용할 모드 use_vllm 로 설정되어 True. 다음 중 하나여야 합니다 "server" 또는 "colocate".
    • "server": 트레이너가 별도의 vLLM 서버로 생성 요청을 보냅니다. vLLM 서버가 실행 중인지 확인하세요(vllm serve로 시작).
    • "colocate": vLLM이 동일한 프로세스에서 실행되며 학습 GPU를 공유합니다. 별도의 서버가 필요 없지만 학습과 리소스 경쟁이 발생할 수 있습니다.
  • vllm_model_impl (str, 선택 사항, 기본값 "vllm") — vLLM에 사용할 모델 구현입니다. "transformers" 또는 "vllm" 중 하나여야 합니다. "transformers": 모델 구현에 transformers 백엔드를 사용합니다. "vllm": 모델 구현에 vllm 라이브러리를 사용합니다.
  • vllm_enable_sleep_mode (bool, 선택 사항, 기본값 False) — 옵티마이저 단계에서 가중치/캐시를 오프로드하기 위해 vLLM sleep mode를 활성화합니다. GPU 메모리 사용량을 낮게 유지하지만, 엔진을 깨울 때 호스트-디바이스 전송 지연이 발생합니다.
  • vllm_structured_outputs_regex (str, 선택 사항) — vLLM 구조화 출력을 위한 정규식입니다. None(기본값)인 경우 구조화 출력이 비활성화됩니다.

vLLM 서버를 제어하는 매개변수(`vllm_mode`가 `"server"`인 경우에만 사용)

  • vllm_server_base_url (str, 선택 사항) — vLLM 서버의 기본 URL(예: "http://localhost:8000"). 지정된 경우 vllm_server_host 및 vllm_server_port는 무시됩니다.
  • vllm_server_host (str, 선택 사항, 기본값 "0.0.0.0") — 연결할 vLLM 서버의 호스트입니다. vllm_server_base_url이 제공된 경우 무시됩니다.
  • vllm_server_port (int, 선택 사항, 기본값 8000) — 연결할 vLLM 서버의 포트입니다. vllm_server_base_url이 제공된 경우 무시됩니다.
  • vllm_server_timeout (float, 선택 사항, 기본값 240.0) — vLLM 서버가 실행될 때까지 대기할 총 시간(초). 시간 초과 후에도 서버가 실행되지 않으면 ConnectionError가 발생합니다.
  • vllm_group_port (int, 선택 사항, 기본값 51216) — 가중치 업데이트 그룹에 사용할 포트 번호입니다. vLLM 서버와 통신하는 데 사용됩니다. 포트가 사용 중이 아니라면 변경할 필요가 없습니다.

colocate된 vLLM 실행을 제어하는 매개변수(`vllm_mode`가 `"colocate"`인 경우에만 사용)

  • vllm_gpu_memory_utilization (float, 선택 사항, 기본값 0.3) — vLLM의 GPU 메모리 사용률을 제어합니다. 이 설정은 vllm_mode가 "colocate"로 설정된 경우에만 적용됩니다. vllm_mode="server"를 사용하는 경우, 이 매개변수는 --vllm_gpu_memory_utilization 플래그를 통해 vLLM 서버를 시작할 때 별도로 전달해야 합니다.
  • vllm_max_model_length (int, 선택 사항) — vLLM의 컨텍스트 윈도우입니다. 데이터셋의 최대 프롬프트 길이보다 max_completion_length를 더한 값 이상으로 설정해야 하며, 생략하면 모델 구성에서 추론됩니다.
  • vllm_tensor_parallel_size (int, 선택 사항, 기본값 1) — vLLM의 tensor parallel size를 제어합니다. 이 설정은 vllm_mode가 "colocate"로 설정된 경우에만 적용됩니다. vllm_mode="server"를 사용하는 경우, 이 매개변수는 --vllm_tensor_parallel_size 플래그를 통해 vLLM 서버를 시작할 때 별도로 전달해야 합니다.

학습을 제어하는 매개변수

  • beta (float, 선택 사항, 기본값 0.05) — KL 계수입니다. 0.0인 경우 참조 모델이 로드되지 않아 메모리 사용량이 줄고 학습 속도가 향상됩니다.
  • num_iterations (int, 선택 사항, 기본값 1) — 배치당 반복 횟수(알고리즘에서 μ로 표기됨).
  • epsilon (float, 선택 사항, 기본값 0.2) — 클리핑에 사용되는 Epsilon 값입니다.
  • epsilon_high (float, 선택 사항) — 클리핑을 위한 상한 epsilon 값입니다. 지정하지 않으면 epsilon 인수로 지정된 하한 값과 동일한 값이 기본값으로 사용됩니다. DAPO 논문에서는 0.28을 권장합니다.
  • reward_weights (list[float], 선택 사항) — 각 보상 함수에 대한 가중치입니다. 보상 함수의 수와 일치해야 합니다. None인 경우, 모든 보상은 1.0의 동일한 가중치로 적용됩니다.
  • normalize_advantages (bool, 선택 사항, 기본값 False) — 이점을 정규화할지 여부입니다. 정규화는 각 생성 배치별로 수행되며, 평균이 0.0이고 표준편차가 1.0이 되도록 합니다.
  • reward_clip_range (tuple[float, float], 선택 사항) — (min, max) 형식의 보상 클리핑 범위입니다. None인 경우 클리핑이 적용되지 않습니다.
  • mask_truncated_completions (bool, 선택 사항, 기본값 False) — 활성화하면 잘린(completed) 응답이 손실 계산에서 제외되어, 학습 과정에서 잘못 페널티를 받거나 노이즈가 도입되는 것을 방지합니다. DAPO 논문에 따르면 이는 학습 안정성을 위한 좋은 관행입니다.
  • sync_ref_model (bool, 선택 사항, 기본값 False) — ref_model_mixup_alpha 매개변수를 사용하여 ref_model_sync_steps 스텝마다 참조 모델을 활성 모델과 동기화할지 여부입니다. 이 동기화 방식은 TR-DPO 논문에서 유래했습니다.
  • ref_model_mixup_alpha (float, 선택 사항, 기본값 0.6) — TR-DPO 논문에서 가져온 α 매개변수로, 업데이트 과정에서 현재 정책과 이전 참조 정책 간의 혼합을 제어합니다. 참조 정책은 다음 방정식에 따라 업데이트됩니다: π_ref = α * π_θ + (1 - α) * π_ref_prev. 이 매개변수를 사용하려면 sync_ref_model=True를 설정해야 합니다.
  • ref_model_sync_steps (int, 선택 사항, 기본값 512) — TR-DPO 논문에서 제시한 τ 파라미터로, 현재 정책이 참조 정책과 얼마나 자주 동기화되는지를 결정합니다. 이 파라미터를 사용하려면 sync_ref_model=True를 설정해야 합니다.

로깅을 제어하는 매개변수

  • log_completions (bool, 선택 사항, 기본값 False) — logging_steps 단계마다 (prompt, completion) 쌍의 샘플을 기록할지 여부입니다. rich가 설치되어 있으면 샘플을 출력합니다. wandb 및/또는 trackio 로깅이 활성화되어 있으면 wandb 및/또는 trackio에 기록합니다.
  • log_multimodal (bool, 선택 사항, 기본값 True) — 완성 결과와 함께 멀티모달 콘텐츠(이미지, 비디오 등)를 기록할지 여부입니다. 고해상도 멀티모달 데이터를 사용할 때 로그 크기를 줄이려면 이 옵션을 비활성화하세요.
  • num_completions_to_print (int, 선택 사항) — rich로 출력할 completions의 수입니다. None인 경우 모든 completions이 기록됩니다.
  • log_unique_prompts (bool, 선택 사항, 기본값 False) — 고유한 프롬프트만 기록할지 여부입니다. True인 경우 고유한 프롬프트만 기록되고, False인 경우 모든 프롬프트가 기록됩니다.

transformers의 연속 배치 처리로 구동되는 생성 가속을 제어하는 매개변수

  • use_transformers_continuous_batching (bool, 선택 사항, 기본값 False) — completions 생성에 transformers의 continuous batching 엔진을 사용할지 여부입니다. transformers>=5.8.0이 필요합니다.
  • transformers_continuous_batching_config (dict, 선택 사항) — ContinuousBatchingConfig에 대한 키워드 인자입니다.

비추천되는 매개변수

  • use_transformers_paged —

    use_transformers_paged 매개변수는 비추천(deprecated)되며 v2.0.0 버전에서 제거됩니다. 대신 use_transformers_continuous_batching을 사용하세요.

RLOOTrainer의 구성 클래스입니다.

이 클래스에는 RLOO 학습에 특화된 매개변수만 포함되어 있습니다. 학습 인자의 전체 목록은 TrainingArguments 문서를 참고하세요. 이 클래스의 기본값은 TrainingArguments의 기본값과 다를 수 있습니다.

HfArgumentParser를 사용하면 이 클래스를 커맨드 라인에서 지정할 수 있는 argparse 인수로 변환할 수 있습니다.

이러한 파라미터는 TrainingArguments와 다른 기본값을 가집니다:

  • logging_steps: 기본값이 500 대신 10입니다.
  • gradient_checkpointing: 기본값이 False가 아닌 True입니다.
  • bf16: fp16가 설정되지 않은 경우 기본값이 False가 아닌 True입니다.
  • learning_rate: 기본값이 5e-5 대신 1e-6입니다.

참고

  1. RLOO 논문
  2. 기본으로 돌아가기: LLM에서 인간 피드백을 통한 학습을 위한 REINFORCE 스타일 최적화 재검토
  3. 논문 - REINFORCE++: 대규모 언어 모델 정렬을 위한 단순하고 효율적인 접근법
  4. 블로그 게시물 - RLHF에 RL을 다시 적용하기
  5. 블로그 포스트 - RLHF와 그 변형 파헤치기: 진행 상황과 실무 엔지니어링 인사이트
  6. Youtube - RLOO: LLM에서 인간 피드백을 학습하기 위한 비용 효율적 최적화

구버전 구현(0.21 이하)에서 마이그레이션 가이드

0.22.0 버전 출시와 함께 RLOOTrainer가 리팩토링되어, GRPOTrainer와 같은 라이브러리 내 다른 온라인 트레이너와 더 일관되도록 개선되었습니다. 이 새로운 구현은 트레이너의 구성 매개변수와 전체 구조에 여러 가지 변경 사항을 도입합니다. 아래는 RLOOConfig의 주요 변경 사항 요약입니다:

TRL ≤ 0.21.xTRL ≥ 0.22.0
rloo_knum_generations(으)로 이름이 변경되었습니다
cliprangeepsilon(으)로 이름이 변경되었습니다
kl_coefbeta(으)로 이름이 변경되었습니다
exp_namerun_name(으)로 이름이 변경되었습니다. 이전 동작을 재현하려면 run_name = f"{exp_name}__{seed}__{int(time.time())}"을(를) 사용하세요.
normalize_rewardnormalize_advantages(으)로 이름이 변경되었습니다. 참고: 이 함수는 항상 이점을 정규화했습니다(이전 이름과 관계없이).
num_ppo_epochsnum_iterations(기본값: 1)으로 이름이 변경되었습니다
token_level_klremoved – KL은 이제 시퀀스 수준에서만 계산됩니다
dataset_num_procremoved – 사용되지 않았습니다
num_mini_batchessteps_per_generation(으)로 이름이 변경되었습니다
total_episodesmax_steps=total_episodes / gradient_accumulation_steps를 대신 사용하세요
local_rollout_forward_batch_sizeremoved – 이제 per_device_train_batch_size(평가 중에는 per_device_eval_batch_size)로 자동 설정됩니다
num_sample_generations제거됨 – 생성 로깅 빈도를 제어하려면 logging_steps를 사용하세요
response_lengthmax_completion_length(기본값: 512)으로 이름이 변경되었습니다
stop_token제거됨
stop_token_id제거됨 – 대신 processing_class.eos_token_id를 사용하세요
missing_eos_penalty제거됨 – completion_ids에 eos_token_id가 있는지 확인하는 사용자 정의 보상 함수로 대체

다음은 RLOOTrainer의 주요 변경 사항 요약입니다:

TRL ≤ 0.21.xTRL ≥ 0.22.0
configargs(으)로 이름이 변경되었습니다
reward_modelreward_funcs(으)로 이름이 변경되었으며, 이제 보상 모델과 사용자 정의 보상 함수를 모두 지원합니다
policymodel(으)로 이름이 변경되었습니다
ref_policy제거됨 – 참조 모델이 이제 model에서 자동으로 생성됩니다
data_collator제거됨
Update on GitHub