TRL documentation

비동기 GRPO

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

비동기 GRPO

이 trainer는 vllm, transformers>=5.2.0 및 kernels가 필요합니다(학습 시 이를 통해 Hub에서 FlashAttention을 로드합니다). 분산 학습의 경우 FSDP2만 지원되며(DeepSpeed ZeRO는 지원되지 않습니다).

현재 vllm과 transformers의 종속성 제약 조건이 충돌합니다. 이를 우회하려면 먼저 vLLM을 설치한 후, transformers를 강제 설치하고, kernels를 TRL의 extra를 통해 추가하세요. 이 extra는 transformers가 허용하는 버전을 고정합니다.

pip install vllm
pip install 'transformers>=5.2.0' --no-deps
pip install 'trl[kernels]'

개요

experimental.async_grpo.AsyncGRPOTrainer은 동일한 GRPO 알고리즘을 구현하지만, rollout 생성과 학습을 분리합니다. 백그라운드 워커가 vLLM 서버에서 completions을 지속적으로 스트리밍하는 동안 학습 루프가 이를 소비하므로, 생성과 그래디언트 업데이트가 번갈아 수행되는 대신 겹쳐서 실행됩니다. API는 GRPOTrainer와 동일합니다. GRPO 방법 자체(advantage 계산, KL 추정, 손실 함수 구성, 보상 함수 등)에 대한 자세한 내용은 GRPO Trainer 문서를 참고하세요. GRPOTrainer의 모든 기능이 지원되지는 않으며, 지원되는 파라미터는 experimental.async_grpo.AsyncGRPOConfig를 참조하세요.

이 trainer는 Quentin Gallouédec와 Amine Dirhoussi가 기여했습니다.

GRPOTrainer와의 차이점

표준 GRPOTrainer에서는 생성과 학습이 순차적으로 수행됩니다. 배치 생성, 손실 계산, 가중치 업데이트를 반복하는 방식입니다. 생성이 동일한 GPU에서 실행되는 vLLM colocate mode에서도 한 단계가 완료되어야 다른 단계가 시작됩니다.

experimental.async_grpo.AsyncGRPOTrainer는 이 두 가지 문제를 분리합니다:

  • Rollout worker(백그라운드 프로세스) — vLLM 서버에 프롬프트를 전송하고, 보상 함수로 완성 결과를 점수화하며, 이점을 계산한 후 학습 준비가 된 샘플을 큐에 넣습니다.
  • 학습 루프 (메인 프로세스) — 큐에서 샘플을 가져오고, 클립된 서로게이트 손실을 계산한 후 모델 가중치를 업데이트합니다.

rollout worker는 trainer에서 생성된 별도 프로세스에서 실행되므로, 보상 계산은 GIL을 두고 학습 루프와 경쟁하지 않습니다. 이는 reward_funcs, tools, environment_factory에 전달할 수 있는 값에 두 가지 영향을 미칩니다(후자의 경우, 계약과 사용 가능한 통합을 다루는 OpenEnv 가이드를 참조하세요):

rollout worker를 별도의 프로세스에서 실행하기 때문에, 해당 프로세스에 전달되는 모든 데이터는 pickled됩니다. 따라서 각 reward function, tool, environment_factory(그리고 이들이 close over하는 모든 것)은 picklable이어야 합니다: 모듈 레벨 함수, functools.partial, 또는 callable class instance를 사용하세요. tool은 예외입니다: 모델은 tool을 이름으로 호출하므로, 각 tool은 __name__ 아래에 등록되어야 하며 모듈 레벨 함수여야 합니다. lambda와 closure는 trainer.train()에서 TypeError를 발생시킵니다. 이는 reward function이 프로세스 내에서 호출되고 closure가 작동하는 GRPOTrainer와 다른 점입니다.

롤아웃 과정도 CUDA_VISIBLE_DEVICES=""로 실행되므로 GPU를 사용할 수 없습니다. GPU 기반 보상 모델(예: AutoModelForSequenceClassification 스코어)은 오류 없이 로드되지만 CPU로 조용히 폴백됩니다(GRPOTrainer에서는 이러한 보상 모델이 트레이너의 GPU를 공유한다는 점에 유의하세요). 보상 함수는 CPU 측에서 가볍게 유지하세요(예: accuracy_reward와 같은 검증기, 형식/길이 검사).

GPU 리워드 모델이 실제로 필요할 경우, 권장되는 접근 방식은 독립적인 추론 엔진(vLLM, TGI, …) 뒤에 배치하여 서빙하는 것입니다. 이 경우 별도의 GPU에서 모델을 서빙하고, 가볍고 picklable한 리워드 함수가 HTTP를 통해 해당 모델을 호출하도록 구성합니다. 이렇게 하면 리워드 모델은 자체 디바이스에 유지되는 반면, rollout 프로세스는 CPU 전용으로 유지되며, 트레이너와 독립적으로 확장됩니다.

Tools and environment methods can be synchronous or asynchronous. Synchronous tools run on a thread pool sized to max_concurrent_rollouts, so a slow tool never blocks the other in-flight vLLM requests. Within one assistant turn, tool calls run in the order the model emitted them. Up to max_concurrent_rollouts synchronous tools therefore run at once, so a tool that reads or writes shared state must be thread-safe. Tools와 environment methods는 동기(synchronous) 또는 비동기(asynchronous)일 수 있습니다. 동기 tools는 max_concurrent_rollouts 크기의 thread pool에서 실행되므로, 느린 tool이 다른 in-flight vLLM 요청을 차단하지 않습니다. 하나의 assistant turn 내에서 tool calls는 모델이 출력한 순서대로 실행됩니다. 따라서 최대 max_concurrent_rollouts개의 동기 tools가 동시에 실행될 수 있으므로, 공유 상태를 읽거나 쓰는 tool은 thread-safe여야 합니다.

모든 weight_sync_steps 학습 단계마다 업데이트된 가중치가 NCCL을 통해 vLLM 서버로 전송되어, 이후 생성 결과가 최신 정책을 반영하도록 합니다.

생성과 학습이 동시에 실행되므로 학습 샘플은 약간 오래된 버전의 모델에 의해 생성되었을 수 있습니다. max_staleness 매개변수는 샘플이 폐기되기 전에 허용되는 가중치 업데이트 지연 횟수를 제어합니다.

동시성

vLLM 서버로 전송되는 동시 요청의 수는 max_concurrent_rollouts로 제한됩니다. 기본적으로 max(max_staleness, 1) × per_device_train_batch_size × gradient_accumulation_steps × num_processes로 자동 설정되며, 이는 트레이너가 샘플이 스테일(stale) 상태가 되기 전에 소비할 수 있는 최대 샘플 수입니다. 이보다 많은 샘플을 생성하는 것은 낭비입니다. 초과된 샘플은 폐기되므로요.

max_concurrent_rollouts는 상한선이지 실제로 처리 중인 요청의 수가 아닙니다. 워커는 서버의 /metrics 엔드포인트를 몇 초마다 폴링하여, 그 아래에 실시간 상한(rollout/concurrency_cap)을 유지합니다. 특정 동시성 수준을 넘으면 KV 캐시가 차고, 시퀀스가 선점되어 재계산되며, 캐시된 접두사가 제거되고 다시 프리필링되므로 vLLM이 느려집니다. 상한은 서버 시작 시점에 읽어들인 KV cache tokens / max_model_len로 시작합니다. 이는 전체 길이에 맞춰 들어갈 수 있는 요청 수를 의미하며, 첫 단계에서 스래싱이 일어나지 않도록 합니다. 사용량이 0.6 미만이고 대기 중인 작업이 없으면, 상한 분량의 롤아웃이 완료될 때마다 상한이 25%씩 증가하여 상한선까지 올라갑니다. KV 캐시 사용량이 0.8을 넘으면 상한이 30% 줄어듭니다. 실행 중인 요청은 취소되지 않으며, 풀이 새로운 상한 아래로 비워질 때까지 신규 요청 수락만 중단되고, 그 시점까지 추가 감축은 이루어지지 않습니다. 서버가 /metrics를 노출하지 않으면 상한은 상한선 그대로 유지됩니다.

체크포인트 및 재개: ignore_data_skip의 기본값은 True입니다. 기본 Trainer의 skip-and-replay 루프는 라이브 롤아웃 큐에는 적용되지 않습니다. 대신, 아직 학습되지 않은 첫 번째 프롬프트의 인덱스가 각 체크포인트와 함께 rollout_state.json에 저장되고 재개 시 복원되므로, 워커는 샘플을 재생하지 않고 해당 프롬프트까지 빠르게 이동합니다. 이는 생성기의 위치가 아니라 학습된 위치입니다. 워커는 롤아웃 큐 깊이만큼 학습보다 앞서 실행되며, 이러한 버퍼링된 샘플은 실행이 종료되면 손실되므로, 생성기의 위치에서 재개하면 생성되었지만 학습되지 않은 프롬프트가 건너뛰어집니다. 스트리밍 데이터셋(IterableDataset)은 위치를 재설정할 수 없으며, 재개 시 워커는 프롬프트 0부터 다시 시작합니다. bf16=True(기본값) 또는 fp16=True인 FSDP 환경에서는 마스터 가중치가 fp32임에도 불구하고 model.safetensors가 해당 dtype으로 기록되므로, 푸시된 체크포인트의 크기는 서빙되는 모델의 크기와 같고 두 배가 아닙니다. fp32 마스터 가중치와 옵티마이저 상태는 여전히 재개 파일(pytorch_model_fsdp.bin, optimizer.bin)에 저장되며, 재개 시 읽히는 것이 바로 이 파일들이므로 재개에는 영향이 없습니다. FSDP를 사용하지 않으면 체크포인트가 재개 파일이기도 하므로 마스터 dtype을 유지합니다.

빠른 시작

# train_async_grpo.py
from datasets import load_dataset
from trl.experimental.async_grpo import AsyncGRPOTrainer
from trl.rewards import accuracy_reward

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

trainer = AsyncGRPOTrainer(
    model="Qwen/Qwen3-4B",
    reward_funcs=accuracy_reward,
    train_dataset=dataset,
)
trainer.train()

vLLM 서버와 트레이너는 별도의 GPU에서 실행되어야 합니다. CUDA_VISIBLE_DEVICES를 사용하여 GPU를 분할하세요. 예를 들어, GPU 2개를 사용하는 경우 vLLM 서버를 GPU 0에서, 트레이너를 GPU 1에서 다음과 같이 실행할 수 있습니다:

# Terminal 1: vLLM server on GPU 0 (dev mode + NCCL weight transfer are required)
CUDA_VISIBLE_DEVICES=0 VLLM_SERVER_DEV_MODE=1 vllm serve Qwen/Qwen3-4B \
    --max-model-len 4096 \
    --logprobs-mode processed_logprobs \
    --api-server-count 8 \
    --weight-transfer-config '{"backend":"nccl"}'

--max-model-len을 예상하는 최대 총 시퀀스 길이(프롬프트 + 완성)로 설정하세요. 값이 낮을수록 서버의 GPU 메모리 사용량이 줄어들어 KV 캐시에 더 많은 메모리가 할당되고 처리량이 증가합니다. 좋은 시작점은 설정의 프롬프트 길이에 max_completion_length를 더한 값입니다.

# Terminal 2: training on GPU 1
CUDA_VISIBLE_DEVICES=1 accelerate launch train_async_grpo.py

AMD GPU

Trainer는 추가 설정 없이 AMD GPU(ROCm)에서 실행되며, 위의 명령어는 그대로 작동합니다. 학습은 AMD GPU에서 kernels-community/aiter-flash-attn attention kernel을, NVIDIA Blackwell GPU에서 kernels-community/flash-attn4를, 기타 NVIDIA GPU에서 kernels-community/flash-attn3를 사용하며, 모두 kernels 라이브러리를 통해 Hub에서 다운로드됩니다. attention logits에 상한을 두는 모델(attn_logit_softcapping)은 Gemma 2와 같이 AMD GPU 또는 NVIDIA Blackwell GPU에서 지원되지 않습니다.

비전-언어 모델

비전-언어 모델(Qwen3.5, Qwen3.6, Qwen3-VL, …)은 텍스트 전용 데이터셋으로 학습할 수 있습니다. 모델 ID를 평소와 같이 전달하면 됩니다. 그 외 변경 사항은 없습니다:

CUDA_VISIBLE_DEVICES=0 VLLM_SERVER_DEV_MODE=1 vllm serve Qwen/Qwen3.5-2B \
    --max-model-len 4096 \
    --logprobs-mode processed_logprobs \
    --api-server-count 8 \
    --weight-transfer-config '{"backend":"nccl"}'

비전 타워는 동결됩니다. 텍스트 전용 데이터셋은 이미지 토큰을 생성하지 않으므로, 포워드 패스에서 타워가 사용되지 않습니다. 텍스트 타워를 제외한 모든 구성 요소(비전 타워, 멀티모달 프로젝터)는 requires_grad=False 상태입니다. 따라서 그라디언트나 옵티마이저 상태가 할당되지 않으며, 가중치 동기화에서도 완전히 제외됩니다. 서버는 체크포인트에서 로드한 값을 그대로 유지합니다. 타워는 여전히 로드되므로, 가중치를 위해 GPU 메모리를 차지합니다.

이미지는 아직 지원되지 않습니다. 이미지를 포함하는 프롬프트는 vLLM 서버나 학습 forward pass로 전달되지 않습니다. 멀티모달 학습은 이미지 그리드에서 3D M-RoPE 위치를 구성하기 위해 padding-free packing 경로가 필요하지만, 여기서는 구현되어 있지 않습니다.

Top-k 및 top-p 샘플링

Top-k와 top-p는 전체 어휘가 아닌 제한된 후보 집합에 대해 샘플링 분포를 재정규화합니다. 서버의 로그 확률은 이를 반영하며(--logprobs-mode processed_logprobs), 따라서 트레이너도 동일한 집합에 대해 정규화를 수행해야 합니다. 그렇지 않으면 모든 중요도 비율이 편향됩니다. 전체 어휘 기준의 토큰 확률은 실제로 추출된 후보 집합 기준의 확률보다 낮기 때문입니다(DeepSeek-V3.2, 3.1절). top_p < 1 또는 top_k > 0인 경우, 워커는 서버에 각 샘플링된 토큰의 후보 집합을 요청하고 트레이너는 해당 집합에 대해 로그 확률을 재정규화합니다. 이를 위해 서버 플래그가 두 개 더 필요하며, vLLM이 후보 집합의 크기를 top_k로 제한하기 때문에 top_k를 설정해야 합니다:

CUDA_VISIBLE_DEVICES=0 VLLM_SERVER_DEV_MODE=1 vllm serve Qwen/Qwen3-4B \
    --max-model-len 4096 \
    --logprobs-mode processed_logprobs \
    --api-server-count 8 \
    --weight-transfer-config '{"backend":"nccl"}' \
    --return-sampling-mask \
    --enable-scale-out
config = AsyncGRPOConfig(top_p=0.95, top_k=512)

--return-sampling-mask은 vLLM이 후보 집합을 기록하도록 합니다(vLLM 0.28 이상, V2 모델 러너 사용 시: 서버가 플래그를 거부하면 VLLM_USE_V2_MODEL_RUNNER=1 설정). --enable-scale-out는 해당 집합을 반환하는 token-in-token-out 엔드포인트를 노출합니다. 워커는 시작 시 서버에서 두 설정을 모두 확인합니다. 구버전 vLLM은 해당 집합을 반환할 수 없으므로, 트레이너는 전체 어휘에 대해 정규화를 유지하고 편향된 비율에 대해 경고를 표시합니다.

Score centering

서버의 log-probability는 트레이너의 것과 정확히 일치하지 않습니다: 커널이 다르고, 정밀도가 다르고, 정책이 몇 단계 뒤처져 있기 때문입니다. 중요도 가중치만으로는 이를 보정할 수 없는데, 샘플링된 토큰의 점수 ∇θlog⁡πθ \nabla_\theta \log \pi_\theta 는 샘플러 하에서 평균이 0이 되지 않으므로, 모든 업데이트가 정책을 샘플러 쪽으로 끌어당깁니다(Score centering). 기본적으로 트레이너는 모든 위치에서 해당 기대값을 뺍니다(score_centering=True), 샘플러의 num_sampler_logprobs 가장 가능성 높은 토큰에 대해 추정하고, 샘플러에 대한 중요도 비율이 [vllm_importance_sampling_clip_min, vllm_importance_sampling_clip_max]. 이를 위해 워커는 서버에서 생성된 모든 토큰의 상위 log-probability를 요청하며, 토큰별로 직렬화합니다. 큰 num_sampler_logprobs 은 서버를 느리게 만들고, 그 --max-logprobs 는 서버가 허용하는 범위를 제한합니다. score_centering=False 는 클립된 목적 함수만으로 학습합니다. sampling/masked_mean 는 경계에 의해 제거된 토큰의 비율이고 sampling/sampler_mass 는 상위 토큰이 커버하는 샘플러의 확률 질량입니다.

vLLM의 API 서버에서 상위 log-probabilities를 직렬화하는 작업은 CPU에서 수행되며, 기본값인 단일 API 서버에서 num_sampler_logprobs=8을 사용하면 생성 처리량이 절반으로 줄어듭니다. vLLM 0.32 이상에서는 서버를 --api-server-count 8 옵션으로 시작하세요. H100 1대에서 1.5B~7B 모델을 측정했을 때, 상위 8개 log-probabilities의 비용이 생성 처리량의 3% 미만으로 줄어듭니다. vLLM 0.31에서는 동일한 플래그를 사용해도 20~40%의 손실이 발생하며, 이는 vllm-project/vllm#58181에서 업스트림으로 수정되었습니다.

LoRA

전체 모델 대신 LoRA 어댑터를 학습하려면 peft_config를 전달하세요:

from peft import LoraConfig

trainer = AsyncGRPOTrainer(
    model="Qwen/Qwen3-4B",
    reward_funcs=reward_len,
    train_dataset=dataset,
    peft_config=LoraConfig(r=32, lora_alpha=64, target_modules="all-linear"),
)

모든 가중치 동기화 시 업데이트된 정책을 서버로 전송해야 합니다. 기본적으로 trainer는 어댑터를 베이스 모델에 병합하여 병합된 전체 가중치를 전송하며, 7B 모델의 경우 동기화마다 약 15 GB가 됩니다. vLLM 서버를 --enable-lora 옵션으로 시작하면 어댑터만 전송하며, r=32일 때 약 160 MB입니다:

CUDA_VISIBLE_DEVICES=0 VLLM_SERVER_DEV_MODE=1 VLLM_ALLOW_RUNTIME_LORA_UPDATING=1 vllm serve Qwen/Qwen3-4B \
    --max-model-len 4096 \
    --logprobs-mode processed_logprobs \
    --api-server-count 8 \
    --weight-transfer-config '{"backend":"nccl"}' \
    --enable-lora \
    --max-lora-rank 32 \
    --max-loras 6

VLLM_ALLOW_RUNTIME_LORA_UPDATING=1은 트레이너가 각 새 어댑터를 게시하는 엔드포인트를 노출합니다. --enable-lora를 사용하더라도 --weight-transfer-config를 유지해야 합니다. 트레이너는 시작 시에만 동기화 모드를 선택하는데, 그 시점에는 서버가 이미 실행 중이며 병합 동기화가 폴백으로 사용됩니다.

--max-lora-rank은 1, 8, 16, 32, 64, 128, 256, 320, 512 중 하나여야 합니다. 서버가 제공할 수 있는 최대 랭크를 설정하는 것이므로, 8 환경에서도 r=4 어댑터가 정상적으로 작동합니다. --max-loras는 최소 max_staleness + 2 이상이어야 합니다. 트레이너는 max_staleness + 1개의 어댑터 버전을 등록해 두어, 이전 정책 하에서 시작된 롤아웃이 생성 중간에 정책을 전환하지 않고 해당 정책 하에서 완료될 수 있도록 하며, 각 동기화 시 가장 오래된 버전을 해제하기 전에 다음 버전을 로드합니다. 트레이너는 시작 시 두 값을 확인하고, 서버를 재시작할 때 사용할 값을 알려줍니다.

vLLM은 네트워크가 아닌 디스크에서 어댑터를 로드하므로, 트레이너는 각 버전을 <output_dir>/.vllm_lora/ 아래에 작성하고 서버에 해당 경로를 전달합니다. 서버가 다른 머신에서 실행되는 경우, 해당 디렉토리는 두 머신 모두에서 접근할 수 있는 파일시스템에 위치해야 합니다.

<output_dir>/.vllm_lora/는 서빙 캐시이며, 학습된 어댑터가 저장되는 위치가 아닙니다. 이 디렉터리에는 최신 버전만 보관되며, 각 버전은 스탈니스 윈도우(staleness window)에서 벗어난 직후에 삭제됩니다. 체크포인트가 학습한 어댑터를 보존하므로, 체크포인트 저장을 비활성화하지 마세요. save_strategy="no"를 사용하면 수 시간 동안 실행된 작업이 종료된 후에도 아무것도 남지 않습니다. 또한 output_dir은 서버가 읽을 수 있어야 하고, 작업 종료 후에도 유지되어야 하므로, 느린 공유 파일시스템과의 동기화를 피할 수 있다는 장점에도 불구하고 노드 로컬 스크래치 공간은 사용할 수 없습니다.

Adapter sync가 항상 더 빠르지는 않습니다. vLLM은 LoRA adapter를 서빙할 때 병합된 가중치를 서빙하는 경우보다 토큰당 약 1.33~1.39배 느린 속도로 생성하며, RL에서는 일반적으로 생성 과정이 wall-clock 시간을 지배합니다. 그 대가로 각 sync 시 더 짧은 일시 정지 시간과 약 1%의 sync 대역폭을 얻습니다. 생성 처리량이 병목이라면 병합 sync가 여전히 더 나은 선택인 경우가 많습니다.

롤아웃 루프 사용자 정의

Generation, rewards, advantages and filtering은 experimental.async_grpo.AsyncRolloutLoop의 rollout 프로세스에서 실행됩니다. 이 중 하나를 변경하려면 루프를 서브클래스로 상속하고 해당 단계의 메서드를 오버라이드한 뒤, trainer 서브클래스의 loop_cls로 해당 서브클래스를 설정합니다. trainer의 생성자는 변경되지 않습니다.

메서드호출됨기본값
filter_prompt(row_index, row, epoch)프롬프트당 한 번, 생성 전에모든 프롬프트를 허용합니다
generate_one(prompt, tools, group_id)롤아웃당 1회멀티턴 도구 루프
generate_one_turn(prompt_ids)샘플링 요청당 1회config의 샘플링 설정을 가진 vLLM 요청 하나
compute_advantages(group)group.rewards에 보상이 합산된 후 그룹별로 한 번그룹 내에서 표준화된 보상
setup(), close()루프가 시작되고 종료되는 시점nothing

예를 들어, 정책이 이미 해결한 프롬프트의 샘플링을 중단하는 커리큘럼은 설정 서브클래스의 임계값을 통해 정의할 수 있습니다:

from dataclasses import dataclass

import numpy as np

from trl.experimental.async_grpo import AsyncGRPOConfig, AsyncGRPOTrainer, AsyncRolloutLoop


@dataclass
class CurriculumConfig(AsyncGRPOConfig):
    pass_rate_cap: float = 0.9


class CurriculumRolloutLoop(AsyncRolloutLoop):
    def filter_prompt(self, row_index, row, epoch):
        return self.pass_rates.get(row_index, 0.0) < self.config.pass_rate_cap

    async def setup(self):
        self.pass_rates = {}

    def compute_advantages(self, group):
        scored = group.rewards[~np.isnan(group.rewards)]
        if len(scored):
            self.pass_rates[group.row_index] = float(np.mean(scored > 0))
        return super().compute_advantages(group)


class CurriculumTrainer(AsyncGRPOTrainer):
    loop_cls = CurriculumRolloutLoop

Rewards는 reward_funcs, get_reward을 정의하는 환경, 그리고 커스텀 generate_one가 자신의 experimental.async_grpo.Rollout에 설정하는 reward에 대해 합산됩니다. 판정(judge)으로 점수를 매기려면 비동기 보상 함수를 전달하거나, generate_one 내부에서 점수를 매기세요. compute_advantages는 모든 그룹에 대해 실행되며, 점수화된 보상이 모두 동일하여 나중에 제거되는 그룹도 포함됩니다. 제거 여부는 보상을 기준으로 판단하며, 이점(advantages)을 기준으로 하지 않습니다. 루프는 생성된(spawned) 프로세스에서 구성되므로, 서브클래스는 모듈 수준에서 정의하세요. __init__을 오버라이드하는 대신, 루프의 이벤트 루프에서 실행되는 setup에서 클라이언트를 생성하세요. filter_prompt가 거부하는 프롬프트는 해당 에포크에서 건너뛰며, 제거된 그룹과 마찬가지로 해당 에포크에 카운트됩니다. 한 에포크의 모든 프롬프트를 거부하면 루프가 예외를 발생시킵니다.

디자인 철학

이 trainer은 의도적으로 최소한으로 유지되며 범용 솔루션으로 확장될 목적으로 설계되지 않았습니다. 지원하지 않는 기능이 필요하시다면, 저장소를 클론한 후 trainer을 직접 필요에 맞게 수정하는 것을 권장합니다. 커뮤니티의 수요가 상당할 경우에만 새로운 기능이 검토됩니다.

기록된 지표

롤아웃는 그라디언트가 되기까지 여러 단계를 거칩니다. 프롬프트에서 최종 배치 구성에 이르기까지의 각 단계를 먼저 살펴보겠습니다:

Dataset row = PROMPT (message list + reward kwargs)
 └─ GROUP                  (1 prompt, `num_generations` rollouts, 1 advantage baseline)
     └─ ROLLOUT            (1 conversation, keyed by `rollout_id`)
         ├─ TURN           (1 vLLM /v1/completions call + tool messages fed back)
         │   └─ TurnRecord (prompt_ids, output_ids, output_log_probs)
         └─ reconcile      (`_chain_to_sequences` classifies drift per turn: CLEAN/REALIGN/FORK)
             └─ SEQUENCE   (≥1 per rollout; new one per fork; dropped if no trained token)
                 └─ SAMPLE (Sequence + group advantage + reward + metrics)

════════════ Trainer process boundary: `rollout_buffer` (mp.Queue) ════════════

                 └─ SAMPLE (Pulled 1 at a time; dropped if staleness > `max_staleness`)
                     └─ ROW            (Planner inserts it into one of `dp` prefix tries, attention-cost-balanced)
                         └─ MICRO-BATCH (`dp` rows, one per rank)
                             └─ PACKED ROW (Collator lays each trie out: unique tokens, depth as `position_ids`)
                                 └─ FORWARD (`compute_loss`, bs=1, padding stripped, FA3 per trie segment)
                     └─ OPTIMIZER STEP (from `grad_accum` micro-batches)

위에서 아래로 읽으면:

  • group은 하나의 프롬프트가 num_generations번 생성된 것을 의미합니다. 이 그룹 내부에서 이점(baseline)이 계산되므로, 그룹은 점수가 매겨지는 단위이기도 합니다.
  • rollout는 하나의 대화입니다. 모든 턴에서 전체 메시지 목록을 다시 토큰화하므로, 턴 사이의 드리프트는 마지막에 조정해야 합니다.
  • reconciling은 하나의 rollout을 여러 sequences로 fork할 수 있으므로, 하나의 대화에서 여러 개의 학습 샘플이 생성될 수 있습니다.
  • sample는 시퀀스와 해당 시퀀스의 advantage, reward, metrics로 구성됩니다. 이것이 프로세스 경계를 넘어 전달되는 데이터입니다.
  • 경계를 넘어 trainer는 샘플을 rows(DP rank당 하나)로 계획하고, 각 row를 prefix trie로 접어 공유 토큰이 한 번만 전달되도록 하며, grad_accum개의 micro-batch를 단일 optimizer step으로 누적합니다.

따라서 메트릭은 어떤 단계(또는 entity)에 관한지에 따라 다음과 같이 구분됩니다:

네임스페이스가 카운트하는
rollout/하나의 완전한 대화를 나타냅니다: 대화 턴, 포크, 생성에 걸린 시간
completions/모델(vLLM)이 하나의 프롬프트에 대해 생성한 결과
tools/tool calls metrics
sample/큐에 도착하는 하나의 학습 샘플을 나타냅니다
batch/하나의 마이크로 배치 또는 하나의 옵티마이저 스텝(하나 이상의 샘플로 구성됨)
perf/측정된 초와 FLOPs
sampling/학습된 정책이 토큰을 생성한 샘플러와 얼마나 떨어져 있는지를 나타냅니다

토큰 메트릭의 모호함을 없애기 위해 몇 가지 용어를 정의해 보겠습니다:

  • generated 토큰은 모델이 생성한 결과입니다(completions/*).
  • forwarded 토큰은 forward 패스가 처리하는 모든 토큰을 의미하며, 프롬프트, 도구 결과, 생성된 토큰을 포함합니다.
  • trained 토큰은 completion_mask == 1인 부분집합에 대해 손실이 계산되는 토큰을 의미합니다. 예를 들어, 포크(fork) 또는 리얼라인(realign)은 이미 생성된 토큰을 컨텍스트로 강등시킬 수 있으므로 trained ≠ generated입니다.

배치 번호의 구성 방식

row는 하나의 DP rank가 하나의 micro-batch에서 forward하는 단위로, 여러 샘플이 하나의 prefix forest에 패킹되어 공유하는 토큰은 한 번만 forward됩니다. 자세한 내용은 Tree packing을 참고하세요. 플래너는 어떤 샘플이 어떤 row에 배치될지 결정하여(어떤 rank도 straggler가 되지 않도록 attention 비용을 균형 있게 조절) 데이터 콜레이터가 패킹을 수행합니다.

모든 지표에서 “step”은 항상 하나의 FULL optimizer step을 의미하며, micro-batch를 의미하지 않습니다. gradient_accumulation_steps개의 micro-batch가 하나의 step을 구성하며, _per_step로 이름이 붙은 모든 지표는 optimizer step당 값을 나타내며, 이는 global_step, logging_steps 및 Trainer 어휘의 나머지 부분과 일치합니다. 지표가 micro-batch당 값을 나타내는 경우 명시되어 있으며(batch/microbatches_per_step), 그렇지 않으면 행(row)당 양(batch/row_*, batch/samples_per_row)입니다.

따라서 한 단계에는 고정된 수의 row-slots가 포함됩니다:

row-slots per step = gradient_accumulation_steps x world_size

batch 메트릭이 서로 비교할 수 있는 계단 형태로 구성되도록 합니다:

sample                                     sample/forwarded_tokens_mean
  └─ packed into a ROW                     batch/samples_per_row, batch/row_tokens_mean
      └─ one row per DP rank               = one micro-batch
          └─ gradient_accumulation_steps micro-batches = one STEP
                                           batch/samples_per_step, batch/forwarded_tokens_per_step

즉, batch/samples_per_step ≈ row-slots x batch/samples_per_row이며, 토큰도 마찬가지입니다. 두 값은 스텝 안의 마이크로 배치 간 변동성까지만 일치합니다. 스텝별 지표는 합계이고, 행별 지표는 평균이기 때문에 정확한 일치보다는 몇 퍼센트 이내의 오차를 예상해야 합니다.

샘플이 긴 경우 batch/row_fill_frac을 주목해야 합니다. 10k 토큰 샘플은 32k 예산을 효율적으로 채우지 못합니다(3개는 들어가고 4개는 절대 들어가지 않으므로, 패커는 보통 2개만 채우고 행이 약 77%만 차 있는 상태가 됩니다). 반면 1k 토큰 샘플은 예산을 거의 완벽하게 채웁니다. 이는 버그가 아니라 양자화(quantization)의 특성이며, token_budget이 이를 조절하는 레버입니다. 다만 각 시퀀스당 어텐션이 O(L²)이므로, 긴 시퀀스로 구성된 행이 더 차 있다고 해서 메모리 비용이 선형으로 증가하지는 않습니다.

트리 패킹

행(row)은 prefix trie이며 단순한 연결(concatenation)이 아닙니다: 여러 샘플이 공유하는 토큰은 한 번만 전달(forward)되고, 어텐션은 각 샘플이 정확히 자신의 히스토리만 보이도록 합니다. 하나의 프롬프트에 대한 모든 롤아웃은 해당 프롬프트를 반복하며, 멀티턴 롤아웃의 모든 턴은 대화를 다시 전송하므로, 디코더의 작업량은 packing ratio(원시 토큰 수 ÷ 전달된 토큰 수)만큼 감소합니다. 이는 레이아웃 변경일 뿐입니다: 학습된 모든 토큰은 각자의 타깃, 어드밴티지, 이전 로그-확률(old log-probability)을 유지하며, 해당 샘플을 단독으로 전달했을 때의 로그-확률과 일치합니다.

발생 위치:

planner    TreeRow.add            the trie grows sample by sample; a sample is priced by its novel tokens
   │                              (TreeRow.fits), so `token_budget` bounds unique tokens, not raw ones
collator   TreeRow.pack           DFS layout: unique tokens, depth as position_ids, one loss term per
   │                              original trained token (token_index), and per segment its queries and
   │                              the K/V indices of its root-to-segment path, all built on CPU
attention  tree_attention         gather K/V along the paths, one FA3 varlen call, causal

하나의 프롬프트에 대한 두 번의 롤아웃에서 작동 방식:

1. Rollouts             r0:  p1 p2 p3 a1 a2
                        r1:  p1 p2 p3 b1 b2                      10 raw tokens

2. Trie (one per row)   S0 [p1 p2] ─┬─ S1 [p3 a1 a2]          nodes are keyed on (token, next token),
                                   └─ S2 [p3 b1 b2]          so the fork happens one token early and
                                                              every node predicts exactly one token;
                                                              chains without a fork become segments

3. Packed row           idx           0  1 | 2  3  4 | 5  6  7
   (DFS order)          input_ids    p1 p2 | p3 a1 a2 | p3 b1 b2  8 tokens: MLPs, norms and projections
                        position_ids  0  1 |  2  3  4 |  2  3  4  run once per unique token
                        segment      S0    | S1       | S2

4. Attention            seg   queries      K/V gathered            kv_index
   (one FA3 call)       S0    [p1 p2]      [p1 p2]                 0 1
                        S1    [p3 a1 a2]   [p1 p2 | p3 a1 a2]      0 1 2 3 4
                        S2    [p3 b1 b2]   [p1 p2 | p3 b1 b2]      0 1 5 6 7

                        FA3 aligns the causal mask bottom-right      K:  p1 p2 p3 a1 a2
                        when queries are fewer than keys, so a       Q: p3   ■  ■  ■  ·  ·
                        segment's queries see their ancestors and       a1   ■  ■  ■  ■  ·
                        their own causal past, and nothing else.        a2   ■  ■  ■  ■  ■

5. Loss                 p2 (idx 1) predicts p3 for both rollouts; token_index points every trained
                        token of every rollout at the position that predicts it

몇 가지 결과:

  • 공통 접두사는 공유됩니다: 프롬프트의 롤아웃, 그리고 프롬프트 간 공통 시스템 프롬프트 또는 도구 스키마입니다. 플래너는 샘플을 해당 group_id를 이미 보유하고 있는 행, 즉 해당 프롬프트가 이미 있는 행으로 전송합니다. 해당 행이 가득 차면, 랭크가 아직 비어 있거나 가장 부하가 높은 행의 부하를 높이지 않는 한 샘플은 다른 행으로 이동합니다. 가장 부하가 높은 행은 마이크로 배치의 시간을 결정합니다. 그렇지 않으면 마이크로 배치가 닫힙니다.
  • 공유된 것이 없는 경우는 단순한 패킹입니다. 각 샘플은 자기 자신의 경로가 되는 하나의 세그먼트가 되며, 이는 일반적인 패딩 없는 FA3 varlen 패킹입니다.
  • K/V만 중복됩니다: 공유 접두사는 하위 세그먼트당 한 번만 수집되며, 이는 언패킹된 학습이 보유할 양과 비슷하고 GQA를 사용하면 작습니다.
  • Gated DeltaNet 하이브리드가 지원됩니다(Qwen3.5, Qwen3.6, Qwen3-Next, …): 이 모델의 컨볼루션은 각 토큰의 이전 토큰들을 읽으며, 청크형 델타 규칙은 각 세그먼트를 부모의 최종 상태에서 시작합니다(trl/experimental/async_grpo/tree_gated_delta_rule.py). 이를 위해 transformers>=5.15.0 이상이 필요하며, 해당 버전에서 이러한 레이어는 트리 패킹이 패치하는 모듈 레벨 함수를 호출합니다. 다른 비-어텐션 레이어를 포함하는 모델은 초기화 시 거부됩니다.

구매하는 것: 아무것도 공유하지 않으면 패딩 없는 패킹의 일반 속도와 거의 동일한 속도로 실행되며, 속도 향상은 패킹 비율에 따라 대략적으로 증가합니다(Qwen3-0.6B/1.7B, H100에서 비율 3.4일 때 약 2.8~3배). 비율은 공유 접두사 × 행당 샘플 수이므로 batch/samples_per_row가 주요 지표입니다: 1에 가까우면 아무것도 공유할 수 없으며, 레버는 token_budget입니다.

처리량으로 판단하세요. batch/trained_tokens_per_step / perf/fwd_bwd_s입니다. 패킹된 마이크로 배치에는 더 많은 샘플이 포함되므로 perf/fwd_bwd_s는 증가하고, 포워딩된 토큰으로 나누는 perf/mfu_*는 감소합니다. 둘 다 회귀(regression)가 아닙니다. 행당 샘플 수가 증가하면 스텝당 추출되는 롤아웃도 증가하므로, 생성에 병목이 있는 실행은 그 영향이 더 커집니다.

행을 더 길게 만들거나 줄이는 모든 작업은 공유를 제거합니다. 먼저 fork_threshold_tokens를 확인하세요. 한 턴이 재토큰화 시 해당 토큰 수만큼 드리프트가 발생해야만 독립된 행이 되며, 에이전틱 드리프트는 일반적으로 수십 토큰 수준으로 기본값인 1024에 비해 매우 작아 포크가 발생하지 않고 대화는 랭크당 한 행으로 수렴합니다. rollout/fork_frac는 현재 어떤 상태에 있는지 나타냅니다.

롤아웃 큐

워커는 점수가 매겨진 샘플을 큐에 넣고, 트레이너는 해당 큐에서 데이터를 가져옵니다. 이 하나의 큐를 설명하는 네 가지 지표는 각각 다른 질문에 답합니다:

메트릭질문
sample/rollout_queue_size현재 대기 중인 샘플은 몇 개인가요
sample/time_in_queue_s단일 샘플이 학습되기 전에 얼마나 오래 대기했는지를 나타내며, 이는 오프폴리니스(off-policyness)의 절반을 차지하는 시간입니다
perf/rollout_wait_s큐가 비어 있어 훈련이 얼마나 오래 막혀 있었는지
rollout/backpressure_s큐가 가득 차 있어 생성(워커)이 얼마나 오래 차단되어 있었는지

마지막 두 지표(perf/rollout_wait_s와 rollout/backpressure_s)는 서로 거울 이미지이며, 동시에 큰 값을 가질 수 없습니다. 큐 크기와 함께 읽으면 어느 쪽이 병목인지 알 수 있습니다:

  • 큐가 거의 비어 있고 perf/rollout_wait_s가 높으면 생성 병목 상태입니다. 트레이너가 기아 상태에 빠져 있으므로 rollout/generated_tok_s, rollout/concurrency, rollout/score_queue_size를 확인하세요.
  • 큐가 거의 가득 차고 rollout/backpressure_s가 높으면 → trainer-bound 상태입니다. 생성이 스로틀링되고 그 출력이 큐에서 오래 머물고 있으므로 sample/staleness_mean가 상승하는지 확인하세요.
  • 둘 다 0에 가까움 → 균형 잡힘!

Completions

completion은 vLLM이 하나의 프롬프트에 대해 생성한 결과로, 롤아웃의 모든 턴에 걸쳐 집계됩니다.

메트릭의미
completions/mean_length각 rollout당 생성된 토큰 수, 모든 턴에 걸쳐 평균
completions/min_length, completions/max_length윈도우 내 가장 짧고 가장 긴 롤아웃
completions/clipped_ratio마지막 턴이 EOS로 끝나지 않고 max_completion_length에 의해 잘린 롤아웃의 비율

롤아웃

rollout는 완전한 대화 하나를 의미합니다. 프롬프트가 완료될 때까지 생성되는 과정이며, 그 과정에서 발생한 모든 도구 왕복을 포함합니다. num_generations개의 rollout은 동일한 프롬프트를 공유하며 하나의 그룹을 형성합니다.

메트릭의미
rollout/duration_sdispatch에서 루프가 완료된 rollout을 수집할 때까지의 한 rollout에 걸리는 wall time
rollout/generated_tok_s최근 구간(윈도우)의 생성 처리량, 따라서 스톨이 나타납니다
rollout/concurrencyvLLM에 진행 중인 rollouts.
rollout/turns_mean, rollout/turns_max대화당 평균 및 최대 턴 수
rollout/samples_per_rollout대화당 생성된 samples의 수. 1.0은 포킹이 발생하지 않음을 의미하며 (<1.0은 일부 대화에서 학습 가능한 샘플이 전혀 생성되지 않음을 의미)
rollout/fork_frac, rollout/realign_frac각 턴 경계에서 재토큰화 드리프트가 어떻게 분류되었는지
rollout/drift_tokens_mean, rollout/drift_tokens_max턴의 재토큰화 과정에서 무효화된 보유 토큰의 수를 나타냅니다. fork_threshold_tokens와 비교해 보세요.
rollout/score_queue_size점수를 매길 대기 중인 완료된 그룹
rollout/score_s, rollout/score_wait_s, rollout/score_block_sscoring: 그룹을 점수화하는 데 걸린 시간, 점수화를 대기하는 그룹의 대기 시간, 그리고 점수화 큐가 가득 차서 생성이 차단되어 있던 시간
rollout/vllm_retry_totalvLLM 요청을 재시도했습니다. 성능이 저하된 서버는 그렇지 않으면 원인을 알 수 없는 느린 응답으로 보입니다. 이 항목은 completions/가 아닌 여기에 배치되는 이유는 생성된 텍스트가 아니라 서버에 대한 요청을 집계하기 때문입니다. 재시도된 요청은 완료 결과를 전혀 생성하지 않았기 때문입니다.
rollout/backpressure_srollout 큐가 가득 차서 생성이 차단되어 있던 시간입니다. rollout 큐를 참조하세요.
rollout/concurrency_cap진행 중인 롤아웃의 현재 상한입니다. KV cache tokens / max_model_len(최대 max_concurrent_rollouts)에서 시작하여 vLLM 부하에 따라 변동됩니다. 동시성을 참조하세요.
rollout/kv_cache_usage마지막 폴링 시점의 vLLM KV 캐시 사용량(엔진별 최대값)입니다. 0.8을 초과하면 상한이 낮아지고, 0.6 미만으로 유지되면 상한이 증가합니다.
rollout/vllm_running_requests서버의 엔진들이 디코딩 중인 요청 수(vLLM의 num_requests_running, 엔진 전체 합계)입니다. rollout/concurrency와의 차이는 응답을 구성하는 API 서버 프로세스에 대기 중인 요청 수입니다
rollout/vllm_queued_requests서버가 수락했지만 아직 스케줄링되지 않은 요청의 수(vLLM의 num_requests_waiting, 엔진 전체 합계)입니다. 이 값이 0이 아닌 동안 한도는 증가하지 않습니다
rollout/vllm_preemptions_total로그 윈도우 동안 서버가 선점(preempt)한 요청 수입니다(vLLM의 num_preemptions_total을 엔진별로 합산). 보고만 하는 지표입니다. 가중치 동기화는 서버의 캐시를 초기화하여 실행 중인 모든 요청을 선점하기 때문에, 이는 부하 신호가 아닙니다
frac_reward_zero_std, reward_kept모든 점수화된 보상이 동일했거나 점수화할 수 있는 롤아웃이 두 개 미만인 경우 그룹이 제외된 비율(GRPO는 첫 번째 경우만 계산) 및 학습에 사용된 그룹의 평균 보상입니다. reward는 제외된 그룹을 포함하여 모든 점수화된 그룹에 대한 정책의 보상이므로, 이 값을 추적해야 합니다

모든 rollout이 동일한 보상을 받았거나(또는 점수화 가능한 rollout이 두 개 미만인 경우) 해당 그룹은 큐에 추가되지 않고 제외됩니다. 기본 advantage를 사용할 경우 모든 위치에서 advantage가 0이 되어 forward와 backward를 수행해도 아무것도 이동하지 않으므로, 이 경우 그룹을 제외하는 것이 효율적입니다. 배치에는 영향이 없으며, 유지된 그룹에서 여전히 samples_per_step만큼 채워지므로, 많은 그룹이 제외되면 한 step에 더 많은 생성이 필요합니다. 제외된 그룹도 epoch에 포함되며, epoch은 프롬프트를 한 번만 순회하는 것을 의미합니다.

도구

모델이 도구를 실행할 때만 기록됩니다. tools/<name>/*는 도구 이름별로 반복되며, 이는 rewards/<func>/*가 보상 함수별로 반복되는 방식과 동일합니다. 하나의 실패한 도구가 전체 평균에서는 보이지 않기 때문입니다. 내장된 도구 루프와 OpenEnv harness trainer(HarnessAsyncGRPOTrainer, harness에서 학습 참조)은 동일한 이름을 기록하므로 하나의 대시보드에서 둘 다를 읽을 수 있으며, path 컬럼은 각 메트릭을 생성하는 주체를 나타냅니다.

메트릭path의미
tools/call_frequency, tools/failure_frequency내장, 하네스rollout당 호출 횟수 및 실패 비율입니다. 루프 소유 하네스 경로에서 실패란 텍스트가 오류처럼 보이는 도구 결과를 의미합니다
tools/latency_s, tools/<name>/latency_s내장된 화이트박스 하네스도구 실행에 소요된 시간입니다. 화이트박스 하네스 경로에서는 한 모델 턴의 응답과 다음 턴의 요청 사이의 벽 시간(wall time)이며, 하네스 오버헤드를 포함합니다. 루프 소유 경로에는 지연 시간이 없습니다. OpenEnv의 트레이스는 항목에 타임스탬프를 부여하지 않으므로, 이를 기반으로 지연 시간을 도출할 수 있는 자료가 없기 때문입니다.
tools/<name>/call_total, tools/<name>/failure_total내장, 하네스도구별 호출 및 실패 횟수
tools/unknown_name_total내장모델이 존재하지 않는 도구를 요청했습니다: 실행되어 예외를 발생시킨 도구와 달리, 이는 정책 오류를 추적합니다.
tools/parallel_calls_mean내장tool calls requested in a single assistant message
tools/loop_exhausted_frac내장도구를 계속 요청하는 상태에서 max_tool_calling_iterations에서 중단된 대화

환경

environment_factory가 있는 경우에만 기록됩니다. 두 호출 모두 워커의 도구 스레드 풀에서 실행되므로, 느린 환경은 자신의 롤아웃만 지연시키고 진행 중인 다른 롤아웃에는 영향을 주지 않습니다.

메트릭의미
env/reset_sreset()에서 rollout이 시작되기 전의 시간
env/reward_srollout이 종료된 후 get_reward()에서 소요된 시간

큐에서 도착하는 샘플

각 샘플은 RolloutSample 하나입니다. 그룹 내 모든 generation이 완료되고 점수가 매겨진 후, 워커가 _score_group에서 조율된 시퀀스와 그룹 advantage, 보상 및 샘플별 메트릭을 조립하여 생성합니다. 워커는 이들을 rollout_buffer에 푸시하며, 아래에 설명된 모든 항목은 트레이너 측에서 학습을 위해 이를 가져오는 시점에 측정됩니다.

메트릭의미
sample/forwarded_tokens_mean, sample/forwarded_tokens_maxsample 하나당 토큰 수: 프롬프트 + 도구 컨텍스트 + 생성 결과. 패킹은 행(row) 수준의 문제이며, batch/row_*을 참조하세요.
sample/trained_tokens_mean그 중 손실이 계산되는 샘플의 수
sample/rollout_queue_size큐에서 대기 중인 점수화된 샘플
sample/time_in_queue_s이 샘플이 학습되기 전에 해당 큐에 얼마나 오래 머물렀는지를 나타냅니다. perf/rollout_wait_s와 동일하지 않으며, rollout 큐를 참조하세요.
sample/staleness_mean, sample/staleness_max데이터가 얼마나 많은 정책 버전 뒤처져 있는지 나타냅니다. sampling/importance_sampling_ratio/*와 sampling/sampling_logp_difference/*는 오프폴리니스가 손실에 미치는 영향을 보여주며, 이는 원인을 보여줍니다
sample/dropped_stale_totalmax_staleness 초과로 인해 제거된 샘플

보상 및 오프폴리니스

메트릭의미
reward_group_std각 샘플의 그룹 내에서 보상의 표준편차이며, 학습에 사용된 샘플에 대해 평균을 낸 값입니다. 기본 compute_advantages는 이 값으로 나눕니다. GRPO의 reward_std는 전체 배치에 대한 표준편차로, 다른 양입니다. 쉬운 프롬프트가 모두 1이고 어려운 프롬프트가 모두 0인 배치의 경우, 배치 표준편차는 0.5이지만 그룹 표준편차는 0입니다.
rewards/<func>/mean, rewards/<func>/group_std각 보상 함수의 평균과 각 샘플 그룹 내 표준편차이며, 학습에 사용된 샘플에 대해 평균을 낸 값입니다. GRPO의 rewards/<func>/mean은 배치 내 모든 생성된 완료에 대한 평균이고, rewards/<func>/std은 배치에 대한 표준편차입니다.
sampling/importance_sampling_ratio/mean, /min, /maxπ_θ / π_sampler는 완료 토큰마다 계산되며, 여기서 π_sampler는 해당 토큰을 생성한 vLLM 정책입니다. 이는 학습/추론 불일치뿐만 아니라 스탈니스(staleness)도 포함합니다.
sampling/sampling_logp_difference/mean, /max\|log π_θ − log π_sampler\| 완료 토큰당
num_tokens학습 시작 이후 전달된 토큰 수. 트리 패킹을 사용하면 여러 샘플이 공유하는 접두사는 한 번만 계산됩니다

배치

마이크로 배치 1개는 world_size개의 행으로 구성됩니다(패킹이 1개의 시퀀스로 평탄화한다는 점을 기억하세요). 따라서 DP 랭크당 1개씩 할당되어, 랭크 i는 행 i를 포워드로 전달합니다. 이러한 마이크로 배치 gradient_accumulation_steps개가 하나의 옵티마이저 스텝을 구성합니다. 따라서 스텝 1개는 총 gradient_accumulation_steps × world_size개의 행을 처리합니다. 아래에 나열된 모든 _per_step 메트릭은 전체 스텝과 모든 랭크에 대한 합계이며, batch/row_* 메트릭은 행에 대한 평균입니다.

메트릭의미
batch/forwarded_tokens_per_step, batch/trained_tokens_per_steptokens in one optimizer step, forwarded and trained respectively
batch/samples_per_step, batch/groups_per_step트레이닝 샘플, 그리고 개별 프롬프트, 옵티마이저 스텝당. 이들은 포크 레이트
batch/microbatches_per_step설정에서 읽는 것이 아니라 계산됩니다
batch/masked_token_fraccompletion_mask == 0인 전달된 토큰 — 그래디언트를 얻지 못하는 포워드 비율
batch/samples_per_row, batch/row_tokens_mean, batch/row_tokens_maxplanner가 각 rank의 행을 얼마나 밀도 있게 채웠는지
batch/row_fill_fractoken_budget에 대한 row tokens. 값이 낮으면 예산이 충분히 사용되지 않고 있음을 의미합니다
batch/row_imbalancemax cost / mean cost는 행 전체에 걸쳐 계산되며, 여기서 비용은 해당 행의 어텐션 연산량을 의미합니다. 이는 어떤 랭크가 그래디언트 올리듀스를 지연시키는지 예측합니다. 1.0이 이상적인 값입니다.
batch/packing_ratio전달된 토큰당 raw 토큰: 디코더의 작업이 줄어드는 배율이며, 공유되는 것이 없으면 1.0
batch/pad_frac랭크 간 패딩. 브로드캐스트 바이트 비용만 발생하며, 포워드 전에 제거됩니다
batch/dropped_oversize_totaltoken_budget 초과로 인해 제거된 샘플

성능

Throughput은 트레이너가 초당 처리하는 토큰 수를 측정합니다. Model FLOPs Utilization (MFU)는 모델의 forward pass와 backward pass에 사용된 학습 장치의 이론적 연산 용량의 백분율을 추정합니다. 이 추정에서 사용되는 용량은 하드웨어와 학습 정밀도에 따라 달라집니다.

Throughput과 MFU는 두 가지 시간 기준에 따라 보고됩니다:

  • _fwd_bwd는 순전파와 역전파 과정에서의 성능을 측정합니다.
  • _wall_clock는 옵티마이저 업데이트, 가중치 동기화, 롤아웃 대기 시간을 포함한 전체 옵티마이저 스텝에 걸친 성능을 측정합니다.

이 차이는 계산 성능과 대기 및 조정 비용을 구별하는 데 도움이 됩니다. 두 MFU 지표 모두 학습 장치만 설명합니다. 외부 롤아웃 또는 티처 서버의 계산 또는 하드웨어 용량은 포함되지 않습니다. Wall-clock MFU는 해당 서비스를 위한 트레이너의 대기 시간을 반영하며, 서비스 자체의 사용률을 반영하지 않습니다.

MFU는 선택된 정밀도에서 로컬 학습 장치의 피크 컴퓨트 용량이 알려진 경우에만 보고됩니다. 그렇지 않으면 MFU는 생략되며, 학습은 계속되고 처리량 및 타이밍 지표는 계속 사용할 수 있습니다.

메트릭의미
perf/step_soptimizer 단계 사이의 wall time: compute, optimizer, weight sync 및 queue 대기 시간 포함
perf/fwd_bwd_sforward + backward, 해당 스텝의 마이크로 배치에 대해 합산된 값입니다. 이는 아래 모든 _fwd_bwd 지표의 분모입니다
perf/fwd_s그의 forward 부분입니다. fwd_s / fwd_bwd_s가 1/3 근처인 것이 일반적인 분할이며, 이 값이 더 높다는 것은 backward가 저렴하거나 forward에서 recompute 비용이 발생하고 있음을 의미합니다.
perf/optimizer_soptimizer.step()
perf/rollout_wait_s큐가 비어 있어 트레이너가 얼마나 오래 차단되어 있었는지 확인합니다. 롤아웃 큐를 참조하세요.
perf/weight_sync_s전체 동기화, _pause_s (vLLM 대기), _barrier_s (rank skew), _transfer_s (바이트 수)
perf/forwarded_tok_s_fwd_bwd, perf/forwarded_tok_s_wall_clock각 기준에 따른 초당 전달된 토큰
perf/trained_tok_s_wall_clockloss가 확인한 토큰만 계산하여 동일하게
perf/mfu_fwd_bwd, perf/mfu_wall_clock각 기준에 따른 모델 FLOPs 활용도

AsyncGRPOConfig

class trl.experimental.async_grpo.AsyncGRPOConfig

< >

( 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: str = 'constant'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 = 1logging_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 = Truerestore_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 = Truelabel_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 = Nonedtype: str = 'float32'trust_remote_code: bool = Falserouter_aux_loss_coef: float | None = Nonenum_generations: int = 8max_completion_length: int = 2048temperature: float = 1.0top_p: float = 1.0top_k: int = 0min_p: float | None = Nonerepetition_penalty: float = 1.0chat_template_kwargs: dict | str | None = Nonemax_tool_calling_iterations: int | None = Nonefork_threshold_tokens: int = 1024vllm_server_base_url: str = 'http://localhost:8000'vllm_server_timeout: float = 1800.0epsilon: float = 0.2epsilon_high: float | None = Nonescore_centering: bool = Truevllm_importance_sampling_clip_min: float = 0.5vllm_importance_sampling_clip_max: float = 5.0num_sampler_logprobs: int = 8token_budget: int | None = Nonemax_concurrent_rollouts: int | None = Nonemax_staleness: int = 4queue_maxsize: int = 1024weight_sync_steps: int = 1rollout_worker_timeout: float = 300.0log_completions: bool = Falsenum_completions_to_print: int | None = None )

모델을 제어하는 매개변수

  • model_init_kwargs (dict[str, Any] 또는 str, 선택 사항) — 경로에서 모델을 인스턴스화할 때 from_pretrained에 사용되는 키워드 인수입니다. revision 값은 처리 클래스를 로드할 때에도 사용됩니다.
  • dtype (str, 선택 사항, 기본값은 "float32") — 모델을 로드할 데이터 타입으로, "auto", "bfloat16", "float16" 또는 "float32". 기본값은 "float32" 입니다. 이 트레이너가 측정 기준으로 삼는 학습-추론 불일치(FP16을 통한 학습-추론 불일치 해결, 이 트레이너에 대해 TRL에서 트레이너-생성기 정밀도 불일치 해결) )은 트레이너 자체의 정밀도에 민감합니다. 이러한 격차를 끝에서 끝까지 해소하려면 vLLM 서버도 동일한 dtype(vllm serve --dtype); 불일치는 학습 시작 시 경고로 기록됩니다. dtype 의 model_init_kwargs 이 우선합니다.

    이 설정은 가중치가 로드될 때 사용할 dtype만 지정합니다. FSDP의 혼합 정밀도 환경(bf16=True가 기본값)에서 accelerate는 샤딩 전에 모든 학습 가능한 파라미터를 fp32로 업캐스트합니다. 따라서 dtype 값과 관계없이 마스터 가중치와 옵티마이저 상태는 fp32로 유지되며, 포워드와 백워드는 bf16 또는 fp16으로 실행됩니다. 이후 체크포인트는 fp32가 아닌 해당 혼합 정밀도 dtype로 저장됩니다. FSDP를 사용하지 않으면 업캐스트가 발생하지 않습니다. dtype="bfloat16"와 bf16=True를 함께 사용하면 가중치와 옵티마이저 상태가 모두 bf16으로 유지되며, 이는 순수한 bf16 학습을 의미합니다.

  • 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.
  • router_aux_loss_coef (float, 선택 사항) — Mixture-of-Experts(MoE) 모델의 로드 밸런싱 보조 손실 계수로, 이 가중치로 학습 손실에 추가됩니다. 설정되지 않으면 모델 구성에서 선언된 값이 사용됩니다. 비활성화하려면 0.0으로 설정하세요. MoE가 아닌 모델과 함께 사용하면 실패합니다.

생성을 제어하는 매개변수

  • num_generations (int, 선택 사항, 기본값 8) — 프롬프트당 샘플링할 생성 횟수.
  • max_completion_length (int, 선택 사항, 기본값 2048) — 생성된 completion의 최대 길이입니다.
  • temperature (float, 선택 사항, 기본값 1.0) — 샘플링에 사용할 온도입니다. 온도가 높을수록 완성 결과가 더 무작위적으로 생성됩니다.
  • top_p (float, 선택 사항, 기본값 1.0) — 고려할 상위 토큰의 누적 확률을 제어하는 실수입니다. 값은 (0, 1] 범위에 있어야 합니다. 모든 토큰을 고려하려면 1.0으로 설정합니다. 1.0 미만인 경우 top_k도 함께 설정해야 하며, --return-sampling-mask --enable-scale-out 옵션으로 시작된 vLLM 서버(>= 0.28)가 필요합니다. 트레이너는 서버와 마찬가지로 각 토큰이 샘플링된 후보 집합에 대해 로그 확률을 재정규화합니다. 구버전의 vLLM은 전체 어휘를 유지합니다.
  • top_k (int, 선택 사항, 기본값 0) — top-k-filtering을 위해 유지할 가장 높은 확률의 어휘 토큰 수입니다. 0인 경우 top-k-filtering이 비활성화되고 모든 토큰이 고려됩니다. 그 외의 값은 top_p 아래에 설명된 서버 플래그가 필요합니다.
  • min_p (float, 선택 사항) — 최소 토큰 확률입니다. 가장 가능성이 높은 토큰의 확률로 스케일링됩니다. 0.0과 1.0 사이의 값이어야 합니다. 일반적인 값은 0.01~0.2 범위입니다. 0.0보다 큰 값인 경우, top_p 아래에 설명된 서버 플래그와 함께 top_k도 설정해야 합니다.
  • repetition_penalty (float, 선택 사항, 기본값 1.0) — 프롬프트와 지금까지 생성된 텍스트에 해당 토큰이 등장했는지에 따라 새로운 토큰에 페널티를 부과하는 값입니다. 1.0보다 큰 값은 모델이 새로운 토큰을 사용하도록 장려하고, 1.0보다 작은 값은 모델이 토큰을 반복하도록 장려합니다.
  • chat_template_kwargs (dict[str, Any], 선택) — 완성 결과를 생성할 때 apply_chat_template 함수에 전달할 추가 키워드 인자입니다.
  • max_tool_calling_iterations (int, 선택 사항) — 에이전트를 학습할 때의 최대 도구 호출 턴 수입니다. None인 경우 제한이 없으며, 모델이 도구 호출이 없는 응답 턴을 생성하거나 전체 응답 길이가 max_completion_length에 도달하면 생성이 중단됩니다.
  • fork_threshold_tokens (int, 선택 사항, 기본값 1024) — 멀티턴 대화는 매 턴마다 전체 대화를 다시 토큰화하고 그 결과를 지금까지 유지 중인 토큰과 대조하여 학습 행으로 변환됩니다. 깔끔한 추가는 한 행으로 유지되고, 재작성(추론 제거, 요약된 히스토리)은 새로운 행으로 분기됩니다. 한 턴의 재토큰화 프롬프트가 마지막 생성된 답변 내부에서 벗어나는 경우, 드래프트 크기 — 즉 재정렬 시 컨텍스트로 마스킹되는 이전에 학습된 토큰의 수 — 를 기준으로 판단합니다. 이 토큰 수보다 작은 드래프트는 재토큰화 흔들림으로 간주되어 컨텍스트로 재정렬되고, 더 큰 드래프트(예: 템플릿에 의해 제거된 긴 추론 블록)는 새로운 행으로 분기되어 해당 학습된 토큰이 조용히 마스킹되는 대신 학습 신호를 유지하도록 합니다.

vLLM 서버를 제어하는 매개변수

  • vllm_server_base_url (str, 선택 사항, 기본값 "http --//localhost:8000"): 생성에 사용되는 vLLM 서버의 기본 URL(예: "http://localhost:8000").
  • vllm_server_timeout (float, 선택 사항, 기본값 1800.0) — vLLM 서버 호출에 대한 초 단위 타임아웃입니다. 서버가 시작 시 준비될 때까지 대기하는 시간, 각 생성 요청, 각 가중치 동기화 호출에 적용됩니다. 서버 대기 및 가중치 동기화 호출은 타임아웃이 발생하면 예외를 발생시키고, 타임아웃이 발생한 생성 요청은 재시도됩니다.

학습을 제어하는 매개변수

  • epsilon (float, 선택 사항, 기본값 0.2) — 클리핑에 사용되는 Epsilon 값입니다.
  • epsilon_high (float, 선택 사항) — 클리핑을 위한 상한 epsilon 값입니다. 지정하지 않으면 epsilon 인수로 지정된 하한 값과 동일한 값이 기본값으로 사용됩니다. DAPO 논문에서는 0.28을 권장합니다.
  • score_centering (bool, 선택 사항, 기본값 True) — 클립된 목적 함수 대신 score centering(논문)으로 학습할지 여부입니다. 이는 각 샘플링된 토큰의 중요도 가중 점수에서 vLLM 샘플러에 대한 기대값을 뺀 값으로, 일정한 이점이 정책이 샘플러 쪽으로 끌려가도록 하지 않도록 합니다. 기대값은 각 위치에서 가장 가능성이 높은 num_sampler_logprobs개의 토큰에 대해 계산되며, 샘플러는 해당 토큰의 로그 확률을 보고합니다.
  • vllm_importance_sampling_clip_min (float, 선택 사항, 기본값 0.5) — 정책과 vLLM 샘플러 간의 중요도 비율의 하한 C_min입니다. 비율이 [vllm_importance_sampling_clip_min, vllm_importance_sampling_clip_max] 범위를 벗어나는 토큰은 손실 계산에서 제외됩니다(마스크 중요도 샘플링).
  • vllm_importance_sampling_clip_max (float, 선택 사항, 기본값 5.0) — 중요도 비율의 상한 C_max입니다.
  • num_sampler_logprobs (int, 선택 사항, 기본값 8) — 생성된 각 토큰에 대해 vLLM sampler에서 요청하는 상위 log-probabilities의 개수로, score centering에 사용됩니다. 값이 클수록 sampler의 확률 질량을 더 많이 커버하지만 직렬화 비용이 증가합니다. 서버의 --max-logprobs가 이 값의 상한을 결정합니다.
  • token_budget (int, 선택 사항) — 동적 토큰 예산 기반 마이크로 배치에서 단일 행(하나의 DP 랭크의 포워드)에 전달되는 최대 토큰 수입니다. > 0인 경우, TokenBudgetBatcher는 각 행이 이 예산 내에서 유지되도록 주의력 비용이 균형 잡힌 마이크로 배치로 구성하여, 샘플 수와 독립적으로 피크 메모리를 제한합니다(행당 샘플 수는 동적으로 결정됩니다). 이 예산은 원본 토큰이 아닌 고유 토큰을 제한하므로 여러 샘플에 의해 공유되는 토큰은 한 번만 계산되며, 행의 손실 항도 제한합니다. None(기본값)인 경우, 학습 시작 시 조회되는 vLLM 서버의 max_model_len(프롬프트 + 완성 길이 상한)으로 설정되어, 어떤 롤아웃 샘플도 예산을 초과할 수 없습니다. token_budget보다 긴 샘플은 어떤 행에도 맞지 않아 경고와 함께 제외됩니다. 토큰 예산을 비활성화하고 대신 각 마이크로 배치에 고정된 per_device_train_batch_size × num_processes 샘플을 행에 걸쳐 균형 있게 패킹하려면 <= 0으로 설정하세요.

비동기 롤아웃 파이프라인을 제어하는 매개변수

  • max_concurrent_rollouts (int, 선택 사항) — vLLM 서버에 동시에 실행 중인 롤아웃의 최대 수입니다. None, 인 경우, `max(max_staleness, 1)` * `per_device_train_batch_size` * `gradient_accumulation_steps` * `num_processes` 값으로 설정됩니다. 이 값보다 많은 샘플을 생성하는 것은 trainer가 샘플을 소비하기 전에 stale로 폐기되므로 낭비입니다. 도구 사용 환경을 사용하는 경우, 실행할 수 있는 병렬 환경의 수에 따라 이 값을 수동으로 설정하는 것이 좋습니다.
    • per_device_train_batch_size gradient_accumulation_steps num_processes`: 이 값보다 많은 샘플을 생성하는 것은 trainer가 소비하기 전에 stale로 폐기되므로 낭비입니다. tool-use 환경을 사용하는 경우, 동시에 실행할 수 있는 병렬 환경의 수를 기준으로 이 값을 수동으로 설정하는 것이 좋습니다.
  • max_staleness (int, 선택 사항, 기본값 4) — rollout 샘플이 현재 모델 버전보다 최대 몇 단계까지 뒤처질 수 있는지, 그 한계치입니다. 이 한계를 초과하면 샘플이 제거됩니다.
  • queue_maxsize (int, 선택 사항, 기본값 1024) — rollout 큐에 버퍼링할 rollout 샘플의 최대 개수입니다.
  • weight_sync_steps (int, 선택 사항, 기본값 1) — vLLM 서버로 가중치를 동기화하는 간격(학습 스텝 수).
  • rollout_worker_timeout (float, 선택 사항, 기본값 300.0) — rollout worker의 마지막 heartbeat 이후 trainer가 해당 worker를 hung 상태로 간주하고 작업을 중단하기까지의 초 단위 시간입니다.

로깅을 제어하는 매개변수

  • log_completions (bool, 선택 사항, 기본값 False) — logging_steps 단계마다 (prompt, completion) 쌍의 샘플을 기록할지 여부.
  • num_completions_to_print (int, 선택 사항) — rich로 출력할 completions의 수입니다. None인 경우 모든 completions이 기록됩니다.

experimental.async_grpo.AsyncGRPOTrainer의 구성 클래스입니다.

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

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

  • logging_steps: 기본값이 500 대신 1입니다.
  • gradient_checkpointing: 기본값이 False가 아닌 True입니다.
  • bf16: fp16가 설정되지 않은 경우 기본값이 False가 아닌 True입니다.
  • learning_rate: 기본값이 5e-5 대신 1e-6입니다.
  • lr_scheduler_type: linear 대신 기본값이 constant입니다(아래 참조).
  • ignore_data_skip: 기본값이 False가 아닌 True입니다. 기본 Trainer의 skip-and-replay 루프는 비동기 rollout 큐에 적용되지 않습니다.

메시지 모드 조정(message-mode reconciliation)에서의 학습 시간과 학습률: 멀티턴 대화는 가변 개수의 학습 행으로 분기될 수 있습니다(대화의 재작성(rewrite)은 새로운 행을 시작합니다). 따라서 에포크당 샘플 수, 즉 옵티마이저 스텝 수는 사전에 알 수 없습니다. 그 결과:

  • num_train_epochs은 prompt 데이터셋에 대한 전체 패스 수로 학습을 제한하며, 실제로 학습에 사용된 서로 다른 프롬프트의 개수로 계산됩니다. 이는 포크가 생성하는 행의 수와 무관하므로, N 에포크를 요청하면 항상 데이터에 대해 N번의 패스로 학습됩니다. max_steps가 설정되지 않은 경우, 이것이 중단 조건이 되며 max_steps는 안전 상한선으로만 기능합니다.
  • max_steps가 명시적으로 설정된 경우(> 0), epoch 기반의 중단 조건 대신 optimizer steps 기반의 중단 조건으로 작동하며 epoch 기반 중단을 비활성화합니다.
  • lr_scheduler_type의 기본값은 constant입니다. 감쇠 기간은 옵티마이저 스텝 단위로 측정되는데, 스텝 수가 포크 비율에 따라 달라지면 사전에 알 수 없기 때문입니다. 감쇠하는 학습률을 사용하려면 감쇠 스케줄과 명시적인 max_steps를 함께 설정하세요.

AsyncGRPOTrainer

class trl.experimental.async_grpo.AsyncGRPOTrainer

< >

( model: str | PreTrainedModelreward_funcs: collections.abc.Callable[..., list[float]] | list[collections.abc.Callable[..., list[float]]] | None = Noneargs: trl.experimental.async_grpo.async_grpo_config.AsyncGRPOConfig | None = Nonetrain_dataset: datasets.arrow_dataset.Dataset | datasets.iterable_dataset.IterableDataset | None = Noneprocessing_class: 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)peft_config: PeftConfig | None = Nonetools: list[collections.abc.Callable] | None = Noneenvironment_factory: collections.abc.Callable[[], trl.experimental.async_grpo.async_grpo_trainer._SupportsReset] | dict[str, collections.abc.Callable[[], trl.experimental.async_grpo.async_grpo_trainer._SupportsReset]] | None = None )

매개변수

  • model (str 또는 PreTrainedModel) — 학습할 모델. 다음 중 하나여야 합니다: huggingface.co의 모델 저장소에 호스팅된 사전 학습 모델의 모델 ID인 문자열, 또는 save_pretrained를 사용하여 모델 가중치를 저장한 디렉터리의 경로(예: './my_model_directory/'). 모델은 config에 선언된 아키텍처로 로드됩니다. 비전-언어 체크포인트의 경우 AutoModelForImageTextToText(비전 타워는 로드되지만 동결되며, Vision-language models 참조), 그 외의 경우 AutoModelForCausalLM이 사용됩니다. PreTrainedModel 객체. packed training을 위해 attention 구현이 trainer의 tree attention 백엔드로 전환됩니다. config의 모델 이름은 생성에 사용되는 vLLM 서버에서 모델을 식별하는 데 사용됩니다.
    • huggingface.co의 모델 저장소에 호스팅된 사전 학습 모델의 model id인 문자열, 또는 save_pretrained를 사용하여 모델 가중치를 저장한 directory의 경로, 예: './my_model_directory/'. 모델은 해당 config에 선언된 아키텍처로 로드됩니다: 비전-언어 체크포인트의 경우 AutoModelForImageTextToText(비전 타워는 로드되지만 동결되며, Vision-language models 참조), 그 외의 경우 AutoModelForCausalLM.
    • PreTrainedModel 객체입니다. 패킹 훈련을 위해 어텐션 구현이 트레이너의 트리 어텐션 백엔드로 전환됩니다.

    생성에 사용되는 vLLM 서버에서 모델을 식별하기 위해 config의 모델 이름이 사용됩니다.

  • reward_funcs (RewardFunc | list[RewardFunc], 선택 사항) — 보상을 계산하는 데 사용할 보상 함수입니다. 보상을 계산하려면 프롬프트와 완성 결과를 인수로 모든 보상 함수를 호출한 후 보상을 합산합니다. 보상이 환경에 의해 environment_factory ((아래 참조)를 통해 제공되는 경우 생략할 수 있습니다. 다음 중 하나여야 합니다:
    • 단일 보상 함수: 이 함수에는 프롬프트와 생성된 완성문, 그리고 데이터셋의 추가 열이 제공됩니다. 보상 목록을 반환해야 합니다. 보상 함수는 동기식 또는 비동기식일 수 있으며, 해당 샘플에 보상이 적용되지 않는 경우 None을 반환할 수도 있습니다. 이는 서로 다른 유형의 샘플에 서로 다른 보상 함수가 적용되는 멀티태스크 학습에 유용합니다. 보상 함수가 특정 샘플에 대해 None을 반환하면, 해당 샘플의 보상 계산에서 그 보상 함수가 제외됩니다. 자세한 내용은 사용자 정의 보상 함수 사용을 참조하세요.
    • 위에서 설명한 바와 같이 각 항목이 보상 함수인 보상 함수 목록입니다. 모든 함수의 보상이 합산됩니다.

    GRPOTrainer와 달리 보상(reward)은 생성된 자식 프로세스에서 계산되므로, 각 보상 함수(그리고 tools 및 environment_factory)는 picklable이어야 합니다. 모듈 레벨 함수, functools.partial, 또는 callable 클래스 인스턴스를 사용해야 하며, 람다와 클로저는 시작 시점에 실패합니다. 도구는 __name__ 아래에 등록되므로 모듈 레벨 함수여야 합니다. 자식 프로세스는 CUDA_VISIBLE_DEVICES=""로 실행되므로, GPU 기반 보상 모델은 트레이너의 GPU가 아닌 CPU에서(느리게) 실행됩니다.

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

    environment_factory가 제공되고 환경이 데이터를 소유하거나 절차적으로 생성하여 reset() 메서드에서 프롬프트를 반환하는 경우에만 생략할 수 있습니다. 이 경우 학습 길이를 정의하기 위해 max_steps를 설정해야 합니다.

  • processing_class (PreTrainedTokenizerBase, 선택 사항) — 데이터를 처리하는 데 사용되는 처리 클래스입니다. 패딩 쪽은 “left”로 설정해야 합니다. None인 경우, from_pretrained를 사용하여 모델 이름에서 처리 클래스를 로드합니다. 패딩 토큰인 tokenizer.pad_token이 설정되어 있어야 합니다. 처리 클래스에 패딩 토큰이 설정되지 않은 경우, tokenizer.eos_token이 기본값으로 사용됩니다.
  • 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로 생성된 스케줄러를 사용합니다.
  • peft_config (PeftConfig, 선택 사항) — 모델을 래핑하는 데 사용되는 PEFT 구성입니다. None인 경우 모델은 래핑되지 않습니다. vLLM 서버가 --enable-lora로 시작되었을 때, LoRA 어댑터는 병합된 가중치가 아닌 어댑터로 동기화됩니다. AsyncGRPO 문서의 LoRA 섹션을 참조하세요.
  • tools (Callable의 목록, 선택 사항) — 모델이 생성 과정에서 호출할 수 있는 콜러블 도구 함수(동기 또는 비동기)의 목록입니다. 각 도구는 적절히 타입 힌트가 지정된 인자와 반환 값을 가진 표준 Python 함수여야 하며, 목적, 인자, 반환 값을 설명하는 Google 스타일 docstring을 포함해야 합니다. 자세한 내용은 https://huggingface.co/docs/transformers/en/chat_extras#passing-tools를 참조하세요. 모델은 함수의 이름, 타입 힌트, docstring을 기반으로 호출 방법을 결정합니다. 모델의 chat template이 도구 사용을 지원하고 도구 호출을 위해 fine-tuning이 되었는지 확인하세요.
  • environment_factory (EnvironmentFactory 또는 dict[str, EnvironmentFactory], 선택 사항) — 환경 인스턴스를 생성하여 반환하는 호출 가능한 객체, 또는 환경 이름을 이러한 호출 가능한 객체로 매핑하는 사전입니다. 환경 클래스는 생성 중에 도구로 호출될 수 있는 메서드를 정의해야 합니다. 각 메서드는 위에서 설명한 tools 의 동일한 요구 사항을 충족해야 합니다. 환경은 또한 생성 사이에 상태를 초기화하는 데 사용할 수 있는 호출 가능한 reset 메서드를 구현해야 합니다. reset 메서드는 None 또는 문자열을 반환해야 합니다. 문자열을 반환하는 경우, 해당 문자열은 생성 전에 마지막 사용자 메시지에 추가됩니다. 환경은 인자를 받지 않고 get_reward 를 반환하는 float: 메서드를 정의할 수도 있습니다. 이 메서드가 존재하면 환경이 보상을 소유하게 되고, get_reward 는 완료된 롤아웃마다 한 번씩 호출되어 환경의 내부 상태로부터 점수를 매깁니다. 이는 환경의 클래스 이름으로 기록되는 가중치 1의 추가 보상 소스로 작용하며, 동시에 다음 메서드는 선택 사항이 됩니다. 단일 호출 가능한 객체를 사용하는 경우 모든 예제는 동일한 환경을 사용하며, 롤아웃당 하나의 인스턴스가 생성되어 상호작용이 격리됩니다. 사전을 사용하는 경우 각 예제는 환경 필드를 통해 이름을 지정하여 환경을 선택해야 하며, 해당 환경의 도구만 프롬프트에 노출됩니다. 이를 통해 단일 실행에서 여러 작업을 혼합할 수 있습니다(예: 코딩 환경과 게임). 이 기능은 실험적이며 사전 통보 없이 언제든 변경되거나 제거될 수 있습니다. reward_funcs, 이 선택 사항이 됩니다.

    단일 callable을 사용하는 경우, 모든 예제는 동일한 환경을 사용하며 rollout당 하나의 인스턴스가 생성되어 상호작용이 격리됩니다. 딕셔너리를 사용하는 경우, 각 예제는 environment 필드를 통해 이름을 지정하여 환경을 선택해야 하며, 해당 환경의 도구만 프롬프트에 노출됩니다. 이를 통해 단일 실행에서 여러 작업을 혼합할 수 있습니다(예: 코딩 환경과 게임). 이 기능은 실험적이며 사전 통보 없이 언제든 변경되거나 제거될 수 있습니다.

Group Relative Policy Optimization(GRPO) 방법을 위한 Trainer입니다. 이 알고리즘은 DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models 논문에서 처음 제안되었습니다. 이 Trainer는 GRPO의 비동기 버전으로, 생성을 외부 vLLM 서버로 오프로드하여 학습과 동시에 비동기적으로 실행함으로써 rollout을 그래디언트 업데이트 루프와 분리합니다.

예:

>>> from trl.experimental.async_grpo import AsyncGRPOTrainer
>>> from trl.rewards import accuracy_reward
>>> from datasets import load_dataset

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

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

샘플링할 프롬프트, 롤아웃 생성 방식, 이점(advantage) 계산 방식을 커스터마이즈하려면 experimental.async_grpo.AsyncRolloutLoop를 서브클래스로 상속하고 이를 트레이너의 loop_cls로 설정하세요. TRL은 루프를

rollout 과정:

>>> class CurriculumTrainer(AsyncGRPOTrainer):
...     loop_cls = CurriculumRolloutLoop

AsyncRolloutLoop

class trl.experimental.async_grpo.AsyncRolloutLoop

< >

( config: AsyncGRPOConfigmodel_name: strdataset: Datasetreward_funcs: list[collections.abc.Callable[..., list[float]]]processing_class: PreTrainedTokenizerBaseeos_token_ids: list[int]rollout_buffer: Queuemodel_version_value: Synchronizedheartbeat_value: Synchronizedfailed_event: Eventexception_info_queue: Queuemetrics_queue: Queuetools: list[collections.abc.Callable] | None = Noneenvironment_factory: collections.abc.Callable[[], object] | dict[str, collections.abc.Callable[[], object]] | None = Nonescore_queue_maxsize: int = 16lora_name: str | None = Nonedataset_start_index: int = 0 )

spawn된 rollout 프로세스에서 experimental.async_grpo.AsyncGRPOTrainer의 rollout을 생성하고 점수를 매깁니다.

기본적으로 GRPO를 구현합니다. 실행을 커스터마이징하려면 해당 클래스를 서브클래스로 상속하고, 변경되는 메서드만 오버라이드한 후, 해당 서브클래스를 트레이너의 loop_cls로 설정합니다. 각 프롬프트는 다음 순서대로 처리됩니다:

  • filter_prompt(): 프롬프트에 대해 생성을 수행할지 여부.
  • generate_one(): 각 샘플링 요청에 대해 generate_one_turn()을 호출하는 하나의 전체 롤아웃입니다.
  • num_generations개의 rollout 그룹에 점수가 부여됩니다. 그 보상(reward)은 트레이너의 reward_funcs, get_reward를 정의하는 환경, 그리고 Rollout.reward의 합입니다. 그런 다음 compute_advantages()가 그룹별로 한 번씩 실행됩니다.

setup()와 close()는 HTTP 클라이언트와 같은 리소스를 루프의 이벤트 루프에서 생성하고 해제합니다. 훅은 self.config(experimental.async_grpo.AsyncGRPOConfig의 하위 클래스는 자체 필드를 가질 수 있음)와 self.tokenizer를 읽을 수 있습니다. 루프가 생성된 프로세스에서 빌드되므로, 하위 클래스는 가져올 수 있어야 합니다(모듈 레벨에서 정의됨).

필터 프롬프트

< >

( row_index: introw: dict[str, typing.Any]epoch: int ) → bool

매개변수

  • row_index (int) — 학습 데이터셋에서 행의 인덱스.
  • row (dict[str, Any]) — 데이터셋의 행입니다.
  • epoch (int) — 이 단계에 앞서 데이터셋을 완전히 몇 번 순회했는지를 나타내는 값.

반환값

bool

True이면 프롬프트에 대해 num_generations개의 롤아웃을 생성하고, False이면 건너뜁니다.

프롬프트에 대해 생성할지 여부입니다. 거부된 프롬프트는 해당 epoch에서 건너뛰어지며, 드롭된 그룹과 마찬가지로 소비된 것으로 집계됩니다. 기본적으로 모든 프롬프트를 허용합니다. 전체 epoch의 모든 프롬프트를 거부하면, 이후에는 어떤 배치도 trainer에 도달할 수 없으므로 예외가 발생합니다.

generate_one

< >

( prompt: list[dict[str, str]]tools: list[collections.abc.Callable]group_id: int = 0 ) → Rollout

매개변수

  • prompt (list[dict[str, Any]]) — 프롬프트 메시지입니다.
  • tools (list[Callable]) — 이 rollout에서 사용할 수 있는 도구: trainer의 tools와 environment_factory를 사용할 경우 environment의 public methods입니다.
  • group_id (int, 선택 사항, 기본값 0) — 해당 rollout이 속한 그룹의 식별자입니다.

반환값

롤아웃

완료된 롤아웃.

프롬프트에 대해 롤아웃 하나를 생성합니다.

기본적으로 다중 턴 도구 루프는 다음과 같이 동작합니다. 각 턴에서 채팅 템플릿을 사용하여 전체 대화를 렌더링하고, generate_one_turn()으로 응답을 샘플링한 후, 해당 응답에 포함된 도구 호출을 실행합니다. 이 과정은 모델이 더 이상 도구를 호출하지 않거나 max_tool_calling_iterations에 도달할 때까지 계속됩니다. 에이전트 프레임워크를 사용하여 다르게 생성하는 등, 이 동작을 오버라이드할 수 있습니다. 학습 시퀀스가 이로부터 구성되므로 모든 샘플링 요청을 Rollout.turns에 반환하고, Rollout.reward를 설정하여 여기서 롤아웃을 평가하세요.

generate_one_turn

< >

( prompt_ids: list[int] ) → TurnRecord

매개변수

  • prompt_ids (list[int]) — 전체 프롬프트의 토큰 ID입니다.

반환값

TurnRecord

프롬프트와 샘플링된 토큰 및 해당 로그 확률. top_k 또는 top_p를 사용하면 각 샘플링된 토큰의 후보 집합도 포함되며, num_sampler_logprobs를 사용하면 샘플러의 상위 로그 확률도 포함됩니다.

vLLM 서버에서 설정의 샘플링 설정(temperature, top_p, top_k, min_p, repetition_penalty 및 max_completion_length)을 사용하여 응답 하나를 샘플링합니다.

compute_advantages

< >

( group: RolloutGroup ) → np.ndarray

매개변수

  • group (RolloutGroup) — 하나의 프롬프트에 대한 num_generations개의 롤아웃이며, 총 보상 값은 group.rewards에 저장됩니다.

반환값

np.ndarray

group.rewards 순서대로 롤아웃당 하나의 이점(advantage)

그룹의 각 rollout에 대해 하나의 advantage를 계산합니다. 기본적으로 각 reward는 그룹 내에서 표준화됩니다. NaN reward를 가진 rollout은 advantage가 0로 설정되며, 평균과 표준편차 계산에서 제외됩니다.

각 그룹에 대해 실행됩니다. 점수화된 보상이 모두 동일한 그룹은 이 결과가 어떤 이점을 반환하든 제거됩니다.

설정

< >

( )

다른 훅이 필요한 리소스, 예를 들어 HTTP 클라이언트를 생성합니다. 첫 프롬프트 전에 루프의 이벤트 루프에서 실행됩니다. 기본적으로 아무 동작도 하지 않습니다.

닫기

< >

( )

setup()이 생성한 것을 해제합니다. 루프가 중단될 때 실행되며, 실패한 경우에도 포함됩니다. 기본적으로 아무 동작도 하지 않습니다.

롤아웃

class trl.experimental.async_grpo.Rollout

< >

( completion: list[dict[str, str]]completion_ids: list[int]turns: list[trl.experimental.async_grpo.async_rollout_worker.TurnRecord]tool_call_count: int = 0tool_failure_count: int = 0reward: float | None = None )

매개변수

  • completion (list[dict[str, Any]]) — Messages generated after the prompt, in conversational format. Passed to the reward functions as completions.
  • completion_ids (list[int]) — 생성된 completion의 토큰 ID입니다. completion_ids로 reward 함수에 전달됩니다.
  • turns (list[TurnRecord]) — rollout를 생성한 샘플링 요청을 순서대로 나열한 것입니다. 학습 시퀀스는 이로부터 구성되며, 샘플링된 토큰은 학습 대상이 되고 각 프롬프트의 나머지 부분은 컨텍스트로 사용됩니다.
  • tool_call_count (int, 선택 사항, 기본값 0) — 롤아웃 동안 수행된 도구 호출의 수입니다.
  • tool_failure_count (int, 선택 사항, 기본값 0) — 실패한 도구 호출의 수입니다.
  • reward (float, 선택 사항) — 생성 과정에서 계산된 보상입니다. 예를 들어 외부 평가자에 의해 계산될 수 있습니다. 이 값은 보상 함수와 환경의 보상에 추가됩니다. None인 경우, 이 롤아웃은 해당 출처에서 보상을 받지 않습니다.

generate_one()에서 반환된 완료된 롤아웃 하나입니다.

TurnRecord

class trl.experimental.async_grpo.async_rollout_worker.TurnRecord

< >

( prompt_ids: list[int]output_ids: list[int]output_log_probs: list[float] = <factory>output_mask: list[int] | None = Noneoutput_sampling_mask: list[list[int]] | None = Noneoutput_sampler_logprobs: list[dict[int, float]] | None = None )

매개변수

  • prompt_ids (list[int]) — 이 턴에 전송된 전체 프롬프트의 토큰 ID입니다. 대화의 이전 모든 턴을 포함합니다.
  • output_ids (list[int]) — 샘플러가 생성한 토큰 ID입니다.
  • output_log_probs (list[float], 선택 사항, 기본값 []) — output_ids의 각 토큰에 대한 Sampler log-probability입니다. 이 중 하나가 학습 대상인 경우 필수입니다.
  • output_mask (list[int], 선택 사항) — output_ids의 각 토큰에 대해 하나의 값을 지정합니다. 1은 해당 토큰을 학습 대상으로, 0은 컨텍스트로만 유지함을 의미합니다. None인 경우 모든 출력 토큰이 학습 대상이 됩니다.
  • output_sampling_mask (list[list[int]], 선택 사항) — output_ids의 각 토큰에 대한 목록: top_k / top_p 절단 조건에서 샘플러가 선택할 수 있는 토큰 ID입니다. None인 경우 전체 어휘를 의미합니다.
  • output_sampler_logprobs (list[dict[int, float]], 선택) — output_ids의 각 토큰마다 하나의 dict: 토큰 id를 키로 하여 샘플러의 가장 가능성이 높은 토큰들의 log-probabilities를 담고 있습니다. score centering(num_sampler_logprobs)에 사용됩니다.

샘플링 요청 1개: 샘플러에 전송된 프롬프트와 샘플러가 생성한 토큰

RolloutGroup

class trl.experimental.async_grpo.async_rollout_worker.RolloutGroup

< >

( prompts: list[list[dict[str, str]]]reward_kwargs: dict[str, list[typing.Any]]completions: list[list[dict[str, str]]]completions_ids: list[list[int]]completions_sequences: list[list[trl.experimental.async_grpo.async_rollout_worker.TrainingSequence]]tool_call_counts: list[int]tool_failure_counts: list[int]model_version: intgroup_id: introw_index: intenv_rewards: list[tuple[type, float] | None]rollout_rewards: list[float | None]queued_at: float = 0.0rewards: numpy.ndarray | None = None )

매개변수

  • prompts (list[list[dict[str, Any]]]) — 각 rollout의 프롬프트.
  • reward_kwargs (dict[str, list[Any]]) — 프롬프트 데이터셋 행의 다른 열들을 리워드 함수에 키워드 인수로 전달합니다.
  • completions (list[list[dict[str, Any]]]) — 각 rollout의 Completion 메시지입니다.
  • completions_ids (list[list[int]]) — 각 rollout의 completion 토큰 ID입니다.
  • completions_sequences (list[list[TrainingSequence]]) — 각 rollout에서 생성된 학습 시퀀스입니다. 턴 사이에 재토큰화 된 히스토리가 변경된 rollout은 하나 이상의 시퀀스를 생성합니다.
  • tool_call_counts (list[int]) — 각 롤아웃의 도구 호출 횟수.
  • tool_failure_counts (list[int]) — 각 롤아웃에서 실패한 도구 호출의 수.
  • model_version (int) — 그룹의 첫 번째 rollout이 시작되었을 때의 정책 버전입니다.
  • group_id (int) — rollout 과정에서 0부터 세는 그룹의 식별자입니다.
  • row_index (int) — 학습 데이터셋에서 프롬프트의 행 인덱스.
  • env_rewards (list[tuple[type, float] or None]) — get_reward를 정의하는 환경이 있는 롤아웃의 경우, 해당 환경 클래스와 그 보상입니다. 그렇지 않으면 None입니다.
  • rollout_rewards (list[float or None]) — 각 Rollout의 .reward.
  • queued_at (float, 선택 사항, 기본값 0.0) — 그룹이 스코어링을 위해 대기열에 추가된 시점의 time.monotonic() 값.
  • rewards (np.ndarray, 선택 사항) — 모든 보상 소스에 걸쳐 합산된 각 rollout의 총 보상입니다. 어떤 소스도 점수를 매기지 않은 경우 NaN입니다. compute_advantages()가 호출되기 전에 설정됩니다.

하나의 프롬프트에 대한 num_generations개의 롤아웃을 함께 점수화한 결과입니다. 각 리스트에는 롤아웃당 하나의 항목이 있습니다.

Update on GitHub