TRL documentation

GRPO 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

GRPO Trainer

model badge

Ikhtisar

TRL mendukung GRPO Trainer untuk melatih model bahasa, seperti yang dijelaskan dalam makalah DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models oleh Zhihong Shao, Peiyi Wang, Qihao Zhu, Runxin Xu, Junxiao Song, Mingchuan Zhang, Y. K. Li, Y. Wu, Daya Guo.

Abstrak dari makalah tersebut adalah sebagai berikut:

Penalaran matematika merupakan tantangan signifikan bagi model bahasa karena sifatnya yang kompleks dan terstruktur. Dalam makalah ini, kami memperkenalkan DeepSeekMath 7B, yang melanjutkan pra-pelatihan DeepSeek-Coder-Base-v1.5 7B dengan 120B token terkait matematika yang bersumber dari Common Crawl, bersama dengan data bahasa alami dan kode. DeepSeekMath 7B telah mencapai skor mengesankan sebesar 51,7% pada benchmark MATH tingkat kompetisi tanpa mengandalkan toolkit eksternal dan teknik voting, mendekati tingkat kinerja Gemini-Ultra dan GPT-4. Self-consistency atas 64 sampel dari DeepSeekMath 7B mencapai 60,9% pada MATH. Kemampuan penalaran matematika dari DeepSeekMath dikaitkan dengan dua faktor kunci: Pertama, kami memanfaatkan potensi signifikan dari data web yang tersedia secara publik melalui pipeline seleksi data yang dirancang dengan cermat. Kedua, kami memperkenalkan Group Relative Policy Optimization (GRPO), sebuah varian dari Proximal Policy Optimization (PPO), yang meningkatkan kemampuan penalaran matematika sambil secara bersamaan mengoptimalkan penggunaan memori dari PPO.

Metode pasca-pelatihan ini disumbangkan oleh Quentin Gallouédec.

Mulai cepat

Contoh ini menunjukkan cara melatih model menggunakan metode GRPO. Kami melatih Qwen2.5 0.5B Instruct model dengan prompt dari DeepMath-103K dataset. Anda dapat melihat data dalam dataset di sini:

Berikut adalah skrip untuk melatih model. accuracy_reward memerlukan math-verify, yang dapat Anda instal dengan pip install trl[math_verify].

# train_grpo.py
from datasets import load_dataset
from trl import GRPOTrainer
from trl.rewards import accuracy_reward

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

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

Jalankan skrip menggunakan perintah berikut:

accelerate launch train_grpo.py

Distribusi di 8 GPU, pelatihan memakan waktu sekitar 1 hari.

GRPO curves

Catatan: Kurva reward di atas dihasilkan dengan Qwen/Qwen2-0.5B-Instruct. Hasil dengan Qwen/Qwen2.5-0.5B-Instruct akan serupa secara kualitatif.

Menggali lebih dalam ke metode GRPO

GRPO adalah algoritma pembelajaran online, yang berarti ia meningkatkan secara iteratif dengan menggunakan data yang dihasilkan oleh model terlatih itu sendiri selama pelatihan. Intuisi di balik tujuan GRPO adalah memaksimalkan keuntungan dari penyelesaian yang dihasilkan, sambil memastikan bahwa model tetap dekat dengan kebijakan referensi. Untuk memahami cara kerja GRPO, hal ini dapat dipecah menjadi empat langkah utama: menghasilkan penyelesaian, menghitung keuntungan, mengestimasi divergensi KL, dan menghitung loss.

GRPO visual

Membuat kelengkapan

Pada setiap langkah pelatihan, kami mengambil sampel batch prompt dan menghasilkan satu set G G komplemen untuk setiap prompt (dilambangkan sebagai oi o_i ).

Menghitung keuntungan

Untuk masing-masing dari G G urutan, kami menghitung reward menggunakan model reward atau fungsi reward. Untuk selaras dengan sifat komparatif model reward—yang biasanya dilatih pada dataset perbandingan antara output untuk pertanyaan yang sama—advantage dihitung untuk mencerminkan perbandingan relatif ini. Dinormalisasi sebagai berikut: A^i,t=ri−mean(r)std(r)\hat{A}_{i,t} = \frac{r_i - \text{mean}(\mathbf{r})}{\text{std}(\mathbf{r})}

Pendekatan ini memberikan nama pada metode tersebut: Group Relative Policy Optimization (GRPO).

Ditunjukkan dalam makalah Understanding R1-Zero-Like Training: A Critical Perspective bahwa penskalaan dengan std(r) \text{std}(\mathbf{r}) dapat menyebabkan bias tingkat kesulitan per pertanyaan. Anda dapat menonaktifkan penskalaan ini dengan mengatur scale_rewards=False di GRPOConfig. Perlu dicatat bahwa menonaktifkan penskalaan berbasis std juga menghilangkan normalisasi varians, sehingga magnitudo pembaruan bergantung langsung pada skala reward mentah dan komposisi batch.

Seperti ditunjukkan dalam Bagian I: Trik atau Jebakan? Pendalaman tentang RL untuk Penalaran LLM (Lite PPO), menghitung rata-rata pada level lokal (grup) dan deviasi standar pada level global (batch) memungkinkan pembentukan reward yang lebih robust. Anda dapat menggunakan strategi penskalaan ini dengan mengatur scale_rewards="batch" di GRPOConfig.

Mengestimasi divergensi KL

Divergensi KL diperkirakan menggunakan aproksimator yang diperkenalkan oleh Schulman et al. (2020). Aproksimator tersebut didefinisikan sebagai berikut: DKL[πθ∥πref]=πref(oi,t∣q,oi,<t)πθ(oi,t∣q,oi,<t)−log⁡πref(oi,t∣q,oi,<t)πθ(oi,t∣q,oi,<t)−1,\mathbb{D}_{\text{KL}}\left[\pi_\theta \|\pi_{\text{ref}}\right] = \frac{\pi_{\text{ref}}(o_{i,t} \mid q, o_{i,<t})}{\pi_\theta(o_{i,t} \mid q, o_{i,<t})} - \log \frac{\pi_{\text{ref}}(o_{i,t} \mid q, o_{i,<t})}{\pi_\theta(o_{i,t} \mid q, o_{i,<t})} - 1,

Menghitung loss

Tujuannya adalah memaksimalkan keuntungan sambil memastikan model tetap dekat dengan kebijakan referensi. Oleh karena itu, loss didefinisikan sebagai berikut: LGRPO(θ)=−1∑i=1G∣oi∣∑i=1G∑t=1∣oi∣[πθ(oi,t∣q,oi,<t)[πθ(oi,t∣q,oi,<t)]no gradA^i,t−βDKL[πθ∥πref]], \mathcal{L}_{\text{GRPO}}(\theta) = -\frac{1}{\sum_{i=1}^G |o_i|} \sum_{i=1}^G \sum_{t=1}^{|o_i|} \left[ \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\left[\pi_\theta(o_{i,t} \mid q, o_{i,< t})\right]_{\text{no grad}}} \hat{A}_{i,t} - \beta \mathbb{D}_{\text{KL}}\left[\pi_\theta \| \pi_{\text{ref}}\right] \right],

di mana suku pertama mewakili keuntungan yang diskalakan dan suku kedua menghukum penyimpangan dari kebijakan referensi melalui divergensi KL.

Perhatikan bahwa dibandingkan dengan formulasi asli dalam DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models, kami tidak melakukan penskalaan dengan 1∣oi∣ \frac{1}{|o_i|} karena ditunjukkan dalam makalah Understanding R1-Zero-Like Training: A Critical Perspective bahwa hal ini memperkenalkan bias panjang pada tingkat respons. Detail lebih lanjut ada di tipe loss.

Perhatikan bahwa dibandingkan dengan formulasi asli dalam DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models, kami menggunakan β=0.0 \beta = 0.0 secara default, yang berarti bahwa istilah divergensi KL tidak digunakan. Pilihan ini didorong oleh beberapa studi terbaru (misalnya, Open-Reasoner-Zero: An Open Source Approach to Scaling Up Reinforcement Learning on the Base Model) yang telah menunjukkan bahwa istilah divergensi KL tidak esensial untuk pelatihan dengan GRPO. Akibatnya, telah menjadi praktik umum untuk mengecualikannya (misalnya Understanding R1-Zero-Like Training: A Critical Perspective, DAPO: An Open-Source LLM Reinforcement Learning System at Scale). Jika Anda ingin menyertakan istilah divergensi KL, Anda dapat mengatur beta di GRPOConfig ke nilai yang tidak nol.

Dalam paper aslinya, formulasi ini digeneralisasi untuk memperhitungkan beberapa pembaruan setelah setiap generasi (dilambangkan dengan μ \mu , dapat diatur dengan num_iterations di GRPOConfig) dengan memanfaatkan objektif surogat yang dipangkas: LGRPO(θ)=−1∑i=1G∣oi∣∑i=1G∑t=1∣oi∣[min⁡(πθ(oi,t∣q,oi,<t)πθold(oi,t∣q,oi,<t)A^i,t, clip(πθ(oi,t∣q,oi,<t)πθold(oi,t∣q,oi,<t),1−ϵ,1+ϵ)A^i,t)−βDKL[πθ∥πref]], \mathcal{L}_{\text{GRPO}}(\theta) = - \frac{1}{\sum_{i=1}^G |o_i|} \sum_{i=1}^G \sum_{t=1}^{|o_i|} \left[ \min \left( \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,< t})} \hat{A}_{i,t}, \, \text{clip}\left( \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,< t})}, 1 - \epsilon, 1 + \epsilon \right) \hat{A}_{i,t} \right) - \beta \mathbb{D}_{\text{KL}}\left[\pi_\theta \| \pi_{\text{ref}}\right] \right],

di mana clip(⋅,1−ϵ,1+ϵ)\text{clip}(\cdot, 1 - \epsilon, 1 + \epsilon) memastikan bahwa pembaruan tidak menyimpang secara berlebihan dari kebijakan referensi dengan membatasi rasio kebijakan antara 1−ϵ 1 - \epsilon dan 1+ϵ 1 + \epsilon . Ketika μ=1 \mu = 1 (default di TRL), tujuan pengganti yang dipangkas disederhanakan menjadi tujuan asli.

Jenis-jenis Loss

Beberapa formulasi dari fungsi tujuan telah diusulkan dalam literatur. Awalnya, fungsi tujuan GRPO didefinisikan sebagai berikut: LGRPO(θ)=−1G∑i=1G1∣oi∣∑t=1∣oi∣li,t, \mathcal{L}_{\text{GRPO}}(\theta) = - \frac{1}{G} \sum_{i=1}^G \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} l_{i,t},

di mana li,t=πθ(oi,t∣q,oi,<t)[πθ(oi,t∣q,oi,<t)]no gradA^i,t−βDKL[πθ∥πref]. l_{i,t} = \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\left[\pi_\theta(o_{i,t} \mid q, o_{i,< t})\right]_{\text{no grad}}} \hat{A}_{i,t} - \beta \mathbb{D}_{\text{KL}}\left[\pi_\theta \| \pi_{\text{ref}}\right].

Kertas DAPO menyoroti keterbatasan loss tingkat sampel dari algoritma GRPO dalam skenario long-CoT, di mana respons yang lebih panjang kurang dihukum, sehingga menghasilkan output dengan kualitas yang lebih buruk. Solusi yang diusulkan adalah normalisasi tingkat token, yang menangani urutan yang lebih panjang dengan lebih baik dengan memberikan imbalan yang lebih seimbang untuk setiap token, terlepas dari panjang respons: LDAPO(θ)=−1∑i=1G∣oi∣∑i=1G∑t=1∣oi∣li,t, \mathcal{L}_{\text{DAPO}}(\theta) = - \frac{1}{\sum_{i=1}^G |o_i|} \sum_{i=1}^G \sum_{t=1}^{|o_i|} l_{i,t},

Untuk menggunakan formulasi ini, atur loss_type="dapo" di GRPOConfig.

Selain itu, dalam makalah Understanding R1-Zero-Like Training: A Critical Perspective dibuktikan bahwa formulasi awal GRPO memperkenalkan bias panjang respons. Mereka menunjukkan bahwa meskipun formulasi DAPO mengurangi bias ini, bias tersebut tidak sepenuhnya dihilangkan. Untuk sepenuhnya menghilangkan bias ini, mereka mengusulkan pembagian dengan konstanta alih-alih panjang sekuens, yang menghasilkan formulasi berikut: LDr. GRPO(θ)=−1LG∑i=1G∑t=1∣oi∣li,t, \mathcal{L}_{\text{Dr. GRPO}}(\theta) = - \frac{1}{LG} \sum_{i=1}^G \sum_{t=1}^{|o_i|} l_{i,t},

Konstanta ini disarankan untuk menjadi panjang penyelesaian maksimum. Untuk menggunakan formulasi ini, atur loss_type="dr_grpo" di GRPOConfig.

Sebagai alternatif, dalam makalah SAPO, tim Qwen mengusulkan penggantian mekanisme pemotongan “keras” pada GRPO dengan mekanisme gerbang lunak yang halus dan dikendalikan suhu. Sementara GRPO menolkan gradien ketika kebijakan menyimpang terlalu jauh dari referensi, SAPO menggunakan wilayah kepercayaan lunak yang secara halus meredam bobot gradien. Hal ini memungkinkan model untuk mempertahankan sinyal pembelajaran yang berguna dari token “dekat-on-policy” sambil menekan noise dari penyimpangan ekstrem.

Fungsi loss didefinisikan sebagai: LSAPO(θ)=−1G∑i=1G1∣oi∣∑t=1∣oi∣fi,t(πθ(oi,t∣q,oi,<t)πθold(oi,t∣q,oi,<t))A^i,t \mathcal{L}_{\text{SAPO}}(\theta) = - \frac{1}{G} \sum_{i=1}^G \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} f_{i,t} \left( \frac{\pi_\theta(o_{i,t} | q, o_{i,<t})}{\pi_{\theta_{old}}(o_{i,t} | q, o_{i,<t})} \right) \hat{A}_{i,t}

Fungsi soft-gating fi,t f_{i,t} didefinisikan menggunakan fungsi sigmoid σ \sigma sebagai berikut: fi,t(x)=σ(τi,t(x−1))⋅4τi,t f_{i,t}(x) = \sigma \left( \tau_{i,t} (x - 1) \right) \cdot \frac{4}{\tau_{i,t}}

Suhu τi,t \tau_{i,t} dipilih berdasarkan tanda dari keuntungan A^i,t \hat{A}_{i,t} : τi,t={τpos,if A^i,t>0τneg,otherwise \tau_{i,t} = \begin{cases} \tau_{\text{pos}}, & \text{if } \hat{A}_{i,t} > 0 \\ \tau_{\text{neg}}, & \text{otherwise} \end{cases}

Mereka merekomendasikan penggunaan suhu asimetris, τneg>τpos \tau_{\text{neg}} > \tau_{\text{pos}} (nilai default adalah τpos=1.0,τneg=1.05 \tau_{\text{pos}}=1.0, \tau_{\text{neg}}=1.05 ). Hal ini memastikan bahwa model dihukum lebih ketat untuk aksi “buruk” guna mencegah ketidakstabilan, sementara lebih longgar untuk aksi “baik”.

Untuk menggunakan formulasi ini, atur loss_type="sapo" di GRPOConfig.

Metrik yang dicatat

Selama pelatihan dan evaluasi, kami mencatat metrik berikut:

  • num_tokens: Total jumlah token yang diproses sejauh ini, termasuk prompt dan completion. Saat menggunakan tools, hanya token non-tool yang dihitung.
  • step_time: Rata-rata waktu (dalam detik) yang dibutuhkan per langkah pelatihan (termasuk generasi).
  • completions/mean_length: Rata-rata panjang dari completion yang dihasilkan. Saat menggunakan tools, hanya token non-tool yang dihitung.
  • completions/min_length: Panjang minimum dari komposisi yang dihasilkan. Saat menggunakan tools, hanya token non-tool yang dihitung.
  • completions/max_length: Panjang maksimum dari komplitasi yang dihasilkan. Saat menggunakan tools, hanya token non-tool yang dihitung.
  • completions/mean_terminated_length: Rata-rata panjang dari kelengkapan yang dihasilkan yang diakhiri dengan EOS. Saat menggunakan alat, hanya token non-alat yang dihitung.
  • completions/min_terminated_length: Panjang minimum dari completion yang dihasilkan yang diakhiri dengan EOS. Saat menggunakan tools, hanya token non-tool yang dihitung.
  • completions/max_terminated_length: Panjang maksimum dari completion yang dihasilkan yang diakhiri dengan EOS. Saat menggunakan tools, hanya token non-tool yang dihitung.
  • completions/clipped_ratio: Rasio penyelesaian yang dipotong (clipped).
  • tools/call_frequency: Rata-rata jumlah pemanggilan alat per penyelesaian dalam batch generasi. Dicatat hanya ketika tools disediakan.
  • tools/failure_frequency: Proporsi pemanggilan alat yang gagal (alat tidak ditemukan, memicu pengecualian, atau tipe pemanggilan tidak didukung). Nilainya 0.0 jika tidak ada alat yang dipanggil. Dicatat hanya ketika tools disediakan.
  • rewards/{reward_func_name}/mean: Rata-rata reward dari fungsi reward tertentu. Ketika lingkungan memiliki reward melalui get_reward, {reward_func_name} adalah nama kelas lingkungan tersebut.
  • rewards/{reward_func_name}/std: Deviasi standar dari reward yang dihasilkan oleh fungsi reward tertentu.
  • reward: Rata-rata keseluruhan reward setelah menjumlahkan reward di seluruh fungsi (diberi bobot oleh reward_weights).
  • reward_std: Standar deviasi dari total reward di seluruh fungsi (diberat oleh reward_weights), dihitung pada batch penuh.
  • frac_reward_zero_std: Proporsi sampel dalam batch generasi yang memiliki standar deviasi reward nol, yang mengindikasikan bahwa terdapat sedikit keberagaman untuk prompt tersebut (semua jawaban benar atau salah).
  • sampling/sampling_logp_difference/mean: Rata-rata selisih absolut antara log probabilitas yang dikembalikan oleh sampler (vLLM) dan yang dihitung ulang oleh model pelatihan, di atas token penyelesaian. Nilai yang meningkat menunjukkan ketidakcocokan pelatihan-inferensi yang melebar. Dicatat hanya ketika use_vllm=True dan vllm_importance_sampling_correction=True.
  • sampling/sampling_logp_difference/max: Selisih absolut terbesar seperti itu. Dicatat hanya ketika use_vllm=True dan vllm_importance_sampling_correction=True.
  • sampling/importance_sampling_ratio/min: Rasio importance sampling terkecil yang digunakan untuk mengoreksi ketidakcocokan antara pelatihan dan inferensi, setelah kendala yang dipilih oleh vllm_importance_sampling_mode diterapkan (dipangkas ke [C_min, C_max] untuk mode *_truncate, diatur ke nol untuk mode *_mask). Dihitung pada token penyelesaian, atau pada urutan untuk mode sequence_*. Dicatat hanya ketika use_vllm=True dan vllm_importance_sampling_correction=True.
  • sampling/importance_sampling_ratio/mean: Rasio importance sampling terikat rata-rata. Dicatat hanya ketika use_vllm=True dan vllm_importance_sampling_correction=True.
  • sampling/importance_sampling_ratio/max: Rasio importance sampling terkonstrain terbesar. Dicatat hanya ketika use_vllm=True dan vllm_importance_sampling_correction=True.
  • policy_loss: Nilai kerugian gradien kebijakan (sebelum bonus entropi apa pun). Dicatat ketika entropy_coef tidak nol atau use_adaptive_entropy=True.
  • entropy: Entropi rata-rata dari prediksi token di seluruh kelengkapan yang dihasilkan. (Jika mask_truncated_completions=True, token dari urutan yang dimasker dikecualikan.)
  • entropy_coef: Koefisien regularisasi entropi saat ini. Dicatat ketika entropy_coef tidak nol atau use_adaptive_entropy=True. Diperbarui sekali per langkah optimizer ketika use_adaptive_entropy=True.
  • aux_loss: kerugian bantu penyeimbangan beban dari model Mixture-of-Experts, sebelum dikalikan dengan router_aux_loss_coef dan ditambahkan ke kerugian. Dicatat hanya ketika model adalah model MoE dan router_aux_loss_coef tidak nol.
  • kl: Rata-rata divergensi KL antara model dan model referensi, dihitung di atas kelengkapan yang dihasilkan. Dicatat hanya jika beta tidak nol.
  • clip_ratio/region_mean: Rasio token (atau urutan, jika importance_sampling_level="sequence") probabilitas di mana tujuan GRPO dipangkas agar tetap berada dalam wilayah kepercayaan: clip(ri,t(θ),1−ϵlow,1+ϵhigh) ,ri,t(θ)=πθ(oi,t∣q,oi,<t)πθold(oi,t∣q,oi,<t) \text{clip}\left( r_{i,t}(\theta), 1 - \epsilon_\mathrm{low}, 1 + \epsilon_\mathrm{high} \right)\,, \quad r_{i,t}(\theta) = \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,< t})} . Nilai yang lebih tinggi berarti lebih banyak token yang dipangkas, yang membatasi seberapa besar kebijakan πθ\pi_\theta dapat berubah.
  • clip_ratio/low_mean: Rata-rata rasio probabilitas token (atau urutan, jika importance_sampling_level="sequence") yang dipangkas pada batas bawah trust region: ri,t(θ)<1−ϵlowr_{i,t}(\theta) < 1 - \epsilon_\mathrm{low}.
  • clip_ratio/low_min: Fraksi token per-penyelesaian terkecil (atau urutan itu sendiri, jika importance_sampling_level="sequence") dipangkas pada batas bawah trust region: ri,t(θ)<1−ϵlowr_{i,t}(\theta) < 1 - \epsilon_\mathrm{low}.
  • clip_ratio/high_mean: Rata-rata rasio probabilitas token (atau urutan, jika importance_sampling_level="sequence") yang dipangkas pada batas atas trust region: ri,t(θ)>1+ϵhighr_{i,t}(\theta) > 1 + \epsilon_\mathrm{high}.
  • clip_ratio/high_max: Fraksi token terbesar per penyelesaian (atau urutan itu sendiri, jika importance_sampling_level="sequence") dipangkas pada batas atas trust region: ri,t(θ)>1+ϵhighr_{i,t}(\theta) > 1 + \epsilon_\mathrm{high}.
  • cispo_clip_ratio: Rasio token (atau urutan, jika importance_sampling_level="sequence") bobot importance sampling yang dipangkas pada epsilon_high sambil memiliki keuntungan positif: ri,t(θ)>ϵhighr_{i,t}(\theta) > \epsilon_\mathrm{high}. Dicatat hanya ketika loss_type="cispo".
  • vespo/phi_seq_mean: Nilai rata-rata dari pembobotan Gamma VESPO φ(w)\varphi(w) yang diterapkan pada bobot kepentingan tingkat sekuens. Nilai di bawah 1.0 berarti sekuens diberi bobot lebih rendah. Dicatat hanya ketika loss_type="vespo".

Kustomisasi

Percepat pelatihan dengan generasi yang didukung vLLM

Generasi sering menjadi bottleneck utama saat melatih dengan metode online. Untuk mempercepat generasi, Anda dapat menggunakan vLLM, mesin inferensi ber-throughput tinggi dan ber-latensi rendah untuk LLM. Untuk mengaktifkannya, pertama instal paketnya dengan

pip install trl[vllm]

Kami mendukung dua cara penggunaan vLLM selama pelatihan: mode server dan mode colocate.

Secara default, sequence-level Masked Importance Sampling (vllm_importance_sampling_mode="sequence_mask") diaktifkan untuk generasi vLLM guna mengatasi ketidakcocokan antara generasi dan pelatihan yang terjadi saat menggunakan framework yang berbeda. Fitur ini dapat dimatikan dengan mengatur vllm_importance_sampling_correction=False. Untuk informasi lebih lanjut, lihat Masked Importance Sampling dan Sequence-level Importance Sampling

Opsi 1: Mode Colocate

Pada mode ini, vLLM berjalan di dalam proses trainer dan berbagi memori GPU dengan model pelatihan. Hal ini menghindari peluncuran server terpisah dan dapat meningkatkan pemanfaatan GPU, tetapi dapat menyebabkan perebutan memori pada GPU pelatihan. Ini adalah mode default.

from trl import GRPOConfig

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

Opsi 2: Mode server

Pada mode ini, vLLM berjalan dalam proses terpisah (dan menggunakan GPU terpisah) serta berkomunikasi dengan trainer melalui HTTP. Ini ideal jika Anda memiliki GPU khusus untuk inferensi.

  1. Mulai server vLLM:

    VLLM_SERVER_DEV_MODE=1 vllm serve <model_name> \
        --weight-transfer-config '{"backend": "nccl"}' \
        --logprobs-mode processed_logprobs \
        --max-logprobs -1
  2. Aktifkan mode server di skrip pelatihan Anda:

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

Pastikan server menggunakan GPU yang berbeda dari trainer, jika tidak Anda mungkin akan menemui error NCCL. Anda dapat menentukan GPU yang akan digunakan dengan variabel lingkungan CUDA_VISIBLE_DEVICES.

Tergantung pada ukuran model dan kebutuhan memori GPU keseluruhan untuk pelatihan, Anda mungkin perlu menyesuaikan parameter vllm_gpu_memory_utilization di GRPOConfig untuk menghindari underutilization atau error out-of-memory.

Kami menyediakan HF Space untuk membantu memperkirakan pemanfaatan memori GPU yang direkomendasikan berdasarkan konfigurasi model dan pengaturan eksperimen Anda. Cukup gunakan sebagai berikut untuk mendapatkan rekomendasi vllm_gpu_memory_utilization:

Jika nilai yang direkomendasikan tidak berfungsi di lingkungan Anda, kami menyarankan untuk menambahkan buffer kecil (misalnya, +0.05 atau +0.1) ke nilai yang direkomendasikan untuk memastikan stabilitas.

Jika Anda masih mengalami error out-of-memory, atur vllm_enable_sleep_mode ke True sehingga parameter vllm dan cache akan di-offload selama langkah optimasi. Untuk informasi lebih lanjut, lihat Mengurangi Penggunaan Memori dengan vLLM Sleep Mode.

Secara default, GRPO menggunakan MASTER_ADDR=localhost dan MASTER_PORT=12345 untuk vLLM, tetapi Anda dapat menimpa nilai-nilai ini dengan mengatur variabel lingkungan secara sesuai.

Untuk informasi lebih lanjut, lihat Mempercepat pelatihan dengan vLLM.

Mengatasi Ketidakcocokan antara Pelatihan dan Inferensi

Meskipun vLLM sangat mempercepat inferensi, ia juga memisahkan mesin inferensi dari mesin pelatihan. Secara teori, mesin-mesin ini identik secara matematis, namun dalam praktiknya mereka dapat menghasilkan output yang berbeda akibat efek presisi dan optimasi yang spesifik pada perangkat keras. Divergensi ini mencerminkan tujuan optimasi yang berbeda dari kedua sistem tersebut. Mesin inferensi bertujuan untuk memaksimalkan throughput sampling, yang biasanya diukur dalam token per detik, sambil mempertahankan fidelitas sampling yang dapat diterima. Sebaliknya, framework pelatihan berfokus pada stabilitas numerik dan presisi untuk komputasi gradien, sering kali menggunakan format presisi yang lebih tinggi seperti FP32 untuk bobot master dan status optimizer. Prioritas dan kendala yang berbeda ini memperkenalkan ketidakcocokan yang tidak terhindarkan, meskipun halus, antara pelatihan dan inferensi.

Ketidakcocokan ini menyebabkan pembaruan gradien yang bias, yang telah diamati dapat mendestabilkan pelatihan ([1][2][3][4][5]). Untuk kesederhanaan, pertimbangkan gradien kebijakan REINFORCE: ∇θJ(x,θ)=Ey∼πtrain(⋅∣x,θ)[∇θlog⁡πtrain(y∣x,θ)⋅R(x,y)] \nabla_\theta \mathcal{J}(x,\theta) = \mathbb{E}_{y \sim \pi^\text{train}(\cdot \mid x,\theta)} \left[ \nabla_\theta \log \pi^\text{train}(y \mid x,\theta) \cdot R(x,y) \right]

Di sini x x menyatakan prompt yang diambil dari beberapa distribusi data, dan πtrain \pi^\text{train} adalah kebijakan yang diimplementasikan oleh mesin pelatihan. Dengan vLLM dalam alur kerja, kita memperoleh kebijakan inferensi terpisah πinference \pi^\text{inference} , sehingga gradien kebijakan efektif menjadi ∇θJbiased(x,θ)=Ey∼πinference(⋅∣x,θ)[∇θlog⁡πtrain(y∣x,θ)⋅R(x,y)]. \nabla_\theta \mathcal{J}_{\text{biased}}(x,\theta) = \mathbb{E}_{y \sim \pi^\text{inference}(\cdot \mid x,\theta)} \left[ \nabla_\theta \log \pi^\text{train}(y \mid x,\theta) \cdot R(x,y) \right].

Hal ini mengubah masalah RL on policy menjadi masalah off policy.

Cara standar untuk mengoreksi pergeseran distribusi ini adalah importance sampling (IS). Kami menyediakan dua varian IS: Truncated Importance Sampling (TIS) dan Masked Importance Sampling (MIS). Kedua varian ini dapat diterapkan baik pada level token maupun level sekuens. Misalkan ρ \rho menyatakan bobot importance, misalnya ρt \rho_t per token atau ρseq \rho_{\text{seq}} per sekuens. Di bawah TIS, rasio di luar rentang [vllm_importance_sampling_clip_min, vllm_importance_sampling_clip_max] dipangkas, ρ←clip(ρ,Cmin⁡,Cmax⁡). \rho \leftarrow \text{clip}(\rho, C_{\min}, C_{\max}).

Asli makalah TIS mengusulkan mekanisme pemotongan batas atas tunggal, yaitu, min⁡(ρ,Cmax⁡) \min(\rho, C_{\max}) . Implementasi di TRL menggeneralisasi hal ini dengan juga memperkenalkan batas bawah, menghasilkan formulasi dua sisi yang ditunjukkan di atas, terinspirasi oleh IcePop metode.
Perhatikan bahwa di IcePop, batas-batas tersebut diberi label sebagai α \alpha dan β \beta sedangkan di TRL kami menggunakan Cmin⁡ C_{\min} dan Cmax⁡ C_{\max} .

Di bawah MIS, rasio di luar rentang ini diatur menjadi nol, sehingga sampel-sampel tersebut tidak berkontribusi terhadap gradien. Dengan kata lain, sampel outlier diberi bobot lebih rendah di bawah TIS dan dibuang di bawah MIS. Flag konfigurasi vllm_importance_sampling_mode memilih kedua varian IS (masking atau truncation) dan granularitas (level token atau level sequence).

Importance sampling adalah respons algoritmik yang berprinsip terhadap ketidakcocokan antara pelatihan dan inferensi. Namun, terdapat juga pendekatan yang lebih langsung yang berupaya mengurangi ketidakcocokan antara kedua mesin tersebut. Sebagian besar dari pendekatan ini merupakan solusi rekayasa. Misalnya, MiniMax M1 menggunakan kepala model bahasa FP32 di mesin inferensi. Thinking Machines telah mengeksplorasi kernel inferensi deterministik, meskipun hal ini datang dengan biaya efisiensi yang signifikan. vLLM telah menunjukkan kebijakan yang konsisten secara bitwise dengan membangun di atas kernel deterministik yang invarian terhadap batch dari Thinking Machines, tetapi per November 2025 masih terdapat penalti throughput yang substansial dibandingkan dengan inferensi vLLM standar.

Percepat pelatihan dengan continuous batching transformers

Sebagai alternatif vLLM, Anda dapat menggunakan mesin continuous batching bawaan transformers untuk generasi yang lebih cepat. Continuous batching menghapus urutan yang sudah selesai dari batch secara langsung, bukan menunggu yang paling lambat untuk selesai. Untuk tugas dengan panjang penyelesaian yang bervariasi (misalnya, penalaran matematika), hal ini menghasilkan generasi yang lebih cepat dan penggunaan VRAM yang lebih rendah dibandingkan generate() default pada ukuran batch besar (N≥32).

Continuous batching adalah peningkatan langsung tanpa perlu pengaturan server atau sinkronisasi bobot. Proses ini berjalan dalam proses dan sangat cocok untuk pelatihan single-GPU atau lingkungan dengan keterbatasan memori. Untuk throughput generasi maksimum dalam skala besar, gunakan vLLM sebagai gantinya.

from trl import GRPOConfig

training_args = GRPOConfig(
    ...,
    use_transformers_continuous_batching=True,
    transformers_continuous_batching_config={
        "use_cuda_graph": False,
        "max_memory_percent": 0.4,  # lower values leave more VRAM for the training backward pass
    },
)

TRL menetapkan max_memory_percent secara default ke 0.5 (bukan 0.9 seperti pada transformers) untuk menyisakan VRAM yang cukup bagi backward pass pelatihan. Turunkan nilainya ke 0.3–0.4 untuk batch generasi besar (N≥32) atau jika Anda melihat error out-of-memory.

Untuk contoh pelatihan lengkap, lihat examples/grpo_continuous_batching/grpo_continuous_batching.py.

GRPO berskala besar: latih model 70B+ di beberapa node

Saat melatih model besar seperti Qwen2.5-72B, Anda memerlukan beberapa optimasi kunci untuk membuat pelatihan efisien dan dapat diskalakan di beberapa GPU dan node. Optimasi ini meliputi:

  • DeepSpeed ZeRO Stage 3: ZeRO memanfaatkan data parallelism untuk mendistribusikan state model (weights, gradients, optimizer states) ke beberapa GPU dan CPU, sehingga mengurangi kebutuhan memori dan komputasi pada setiap perangkat. Karena model besar tidak muat di satu GPU, penggunaan ZeRO Stage 3 diperlukan untuk melatih model semacam itu. Untuk detail lebih lanjut, lihat DeepSpeed Integration.
  • Accelerate: Accelerate adalah pustaka yang menyederhanakan pelatihan terdistribusi di beberapa GPU dan node. Pustaka ini menyediakan API sederhana untuk meluncurkan pelatihan terdistribusi dan menangani kompleksitas pelatihan terdistribusi, seperti paralelisme data, akumulasi gradien, dan pemuatan data terdistribusi. Untuk detail lebih lanjut, lihat Distributing Training.
  • vLLM: Lihat bagian sebelumnya tentang cara menggunakan vLLM untuk mempercepat generasi.

Di bawah ini adalah contoh skrip SLURM untuk melatih model 70B dengan GRPO pada beberapa node. Skrip ini melatih model pada 4 node dan menggunakan node ke-5 untuk generasi yang didukung 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}" accelerate launch \
     --config_file examples/accelerate_configs/deepspeed_zero3.yaml \
     --num_processes 32 \
     --num_machines 4 \
     --main_process_ip ${NODELIST[0]} \
     --machine_rank $SLURM_PROCID \
     --rdzv_backend c10d \
     train_grpo.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 GRPOTrainer, GRPOConfig
from trl.rewards import accuracy_reward

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

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

    training_args = GRPOConfig(
        per_device_train_batch_size=4,
        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 = GRPOTrainer(
        model="Qwen/Qwen2.5-72B",
        args=training_args,
        reward_funcs=accuracy_reward,
        train_dataset=dataset
    )
    trainer.train()

if __name__=="__main__":
    main()

Menggunakan fungsi reward kustom

GRPOTrainer mendukung penggunaan fungsi reward kustom sebagai pengganti model reward padat. Untuk memastikan kompatibilitas, fungsi reward Anda harus memenuhi persyaratan berikut:

Fungsi reward dapat berupa callable Python sinkron atau coroutine async def asinkron. Ketika Anda menyediakan beberapa fungsi reward asinkron, fungsi-fungsi tersebut ditunggu secara bersamaan (dijalankan paralel melalui asyncio.gather) sehingga latensinya tumpang tindih.

  1. Argumen input:

    • Fungsi harus menerima argumen berikut sebagai argumen kata kunci:

      • prompts (mengandung prompt),
      • completions (mengandung kelengkapan yang dihasilkan),
      • completion_ids (mengandung pelengkapan yang telah ditokenisasi),
      • trainer_state (TrainerState): Status terkini dari trainer. Hal ini dapat digunakan untuk mengimplementasikan fungsi reward dinamis, seperti pembelajaran kurikulum, di mana reward disesuaikan berdasarkan kemajuan pelatihan.
      • log_extra: callable log_extra(column: str, values: list) untuk menambahkan kolom tambahan ke tabel completions. Lihat Contoh 6.
      • log_metric: callable log_metric(name: str, value: float) untuk mencatat metrik skalar sebagai plot di samping kl, entropy, dll. Lihat Contoh 6.
      • environments: daftar instance lingkungan, satu per completion. Hanya ada ketika environment_factory disediakan. Gunakan ini untuk membaca state yang terakumulasi selama episode (misalnya, env.counter). Untuk lingkungan stateful, lebih baik biarkan lingkungan memiliki reward melalui metode get_reward — lihat Rewards.
      • Semua nama kolom (kecuali prompt) yang mungkin dimiliki dataset. Misalnya, jika dataset berisi kolom bernama ground_truth, fungsi tersebut akan dipanggil dengan ground_truth sebagai argumen kata kunci.

      Cara termudah untuk memenuhi persyaratan ini adalah dengan menggunakan **kwargs dalam tanda tangan fungsi.

    • Tergantung pada format dataset, input akan bervariasi:

  2. Nilai yang dikembalikan: Fungsi harus mengembalikan daftar float. Setiap float mewakili reward yang sesuai dengan satu completion.

Contoh 1: Memberi imbalan pada penyelesaian yang lebih panjang

Berikut adalah contoh fungsi reward untuk format standar yang memberikan reward lebih tinggi untuk penyelesaian yang lebih panjang:

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]

Anda dapat mengujinya sebagai berikut:

>>> 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]

Contoh 1.1: Memberi imbalan untuk penyelesaian yang lebih panjang (berdasarkan jumlah karakter)

Sama seperti contoh sebelumnya, tetapi kali ini fungsi reward didasarkan pada jumlah karakter, bukan token.

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]

Anda dapat mengujinya sebagai berikut:

>>> 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]

Contoh 2: Memberikan imbalan untuk penyelesaian dengan format tertentu

Berikut adalah contoh fungsi reward yang memeriksa apakah penyelesaian memiliki format tertentu. Contoh ini terinspirasi dari fungsi format reward yang digunakan dalam makalah DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning. Fungsi ini dirancang untuk format percakapan, di mana prompt dan penyelesaian terdiri dari pesan terstruktur.

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]

Anda dapat menguji fungsi ini sebagai berikut:

>>> 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]

Contoh 3: Memberikan imbalan pada penyelesaian berdasarkan referensi

Berikut adalah contoh fungsi reward yang memeriksa apakah penyelesaian benar. Contoh ini terinspirasi dari fungsi reward akurasi yang digunakan dalam makalah DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning. Contoh ini dirancang untuk format standar, di mana dataset berisi kolom bernama 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)]

Anda dapat menguji fungsi ini sebagai berikut:

>>> 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]

Contoh 4: Fungsi reward multi-tugas

Berikut adalah contoh penggunaan beberapa fungsi reward dalam GRPOTrainer. Dalam contoh ini, kami mendefinisikan dua fungsi reward yang spesifik untuk tugas: math_reward_func dan coding_reward_func. Fungsi math_reward_func memberikan reward untuk soal matematika berdasarkan kebenarannya, sedangkan coding_reward_func memberikan reward untuk soal pemrograman berdasarkan apakah solusinya berfungsi.

from datasets import Dataset
from trl import GRPOTrainer

# 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 = GRPOTrainer(
    model="Qwen/Qwen2.5-0.5B-Instruct",
    reward_funcs=[math_reward_func, coding_reward_func],
    train_dataset=dataset,
)

trainer.train()

Pada contoh ini, math_reward_func dan coding_reward_func dirancang untuk bekerja dengan dataset campuran yang berisi soal matematika dan pemrograman. Kolom task dalam dataset digunakan untuk menentukan fungsi reward mana yang akan diterapkan pada setiap soal. Jika tidak ada fungsi reward yang relevan untuk sampel dalam dataset, fungsi reward akan mengembalikan None, dan GRPOTrainer akan melanjutkan dengan fungsi dan tugas yang valid. Hal ini memungkinkan GRPOTrainer untuk menangani beberapa fungsi reward dengan tingkat penerapan yang berbeda.

Perhatikan bahwa GRPOTrainer akan mengabaikan reward None yang dikembalikan oleh fungsi reward dan hanya mempertimbangkan reward yang dikembalikan oleh fungsi yang relevan. Hal ini memastikan bahwa model dilatih pada tugas yang relevan dan mengabaikan tugas yang tidak memiliki fungsi reward yang relevan.

Contoh 5: Fungsi reward asinkron

Fungsi reward kustom juga dapat didefinisikan sebagai korutin async def. Hal ini berguna jika reward Anda bergantung pada I/O yang lambat (misalnya, memanggil layanan jarak jauh). Ketika Anda meneruskan beberapa fungsi reward asinkron, GRPOTrainer akan mengeksekusinya secara bersamaan sehingga latensinya saling tumpang tindih.

Berikut adalah contoh minimal dari fungsi reward asinkron yang mensimulasikan operasi yang terikat 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]

Contoh 6: Pencatatan kolom dan metrik tambahan

Di bawah ini adalah contoh fungsi reward yang mencatat kolom tambahan ke tabel completions dan metrik skalar sebagai plot.

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

Menyalurkan fungsi reward ke trainer

Untuk menggunakan fungsi reward kustom Anda, berikan ke GRPOTrainer sebagai berikut:

from trl import GRPOTrainer

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

Anda dapat meneruskan beberapa fungsi reward sebagai daftar; daftar ini dapat mencakup fungsi sinkron dan asinkron:

from trl import GRPOTrainer

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

dan hadiah akan dihitung sebagai jumlah dari hadiah dari setiap fungsi, atau jumlah berbobot jika reward_weights disediakan dalam konfigurasi.

Perhatikan bahwa GRPOTrainer mendukung beberapa fungsi reward dengan tipe yang berbeda. Lihat dokumentasi parameter untuk detail lebih lanjut.

Regularisasi entropi

Untuk mendorong eksplorasi dan mencegah kebijakan runtuh ke output yang hampir deterministik, Anda dapat menambahkan bonus entropi ke tujuan pelatihan. Regularisasi entropi memperluas loss GRPO sebagai berikut: L(θ)=LGRPO(θ)−α⋅H(πθ), \mathcal{L}(\theta) = \mathcal{L}_{\text{GRPO}}(\theta) - \alpha \cdot \mathcal{H}(\pi_\theta),

di manaH(πθ)\mathcal{H}(\pi_\theta) adalah entropi rata-rata per token dari kebijakan, danα\alpha adalah koefisien entropi. Bonus selalu berupa entropi rata-rata per token, terlepas dari loss_type; tidak diskalakan ulang untuk menyesuaikan normalisasi kebijakan dari tipe loss (misalnya penyebut batch_size * max_completion_length dari Dr. GRPO), sehingga entropy_coef memiliki makna yang sama untuk setiap tipe loss.

Entropi statis — koefisien tetap selama pelatihan:

from trl import GRPOConfig, GRPOTrainer

training_args = GRPOConfig(entropy_coef=0.05, ...)

Entropi adaptif — koefisien diperbarui pada setiap langkah optimizer berdasarkan entropi target, sebagaimana diperkenalkan dalam Skywork-OR1. Ketika entropi saat ini berada pada atau di bawah entropy_target, koefisien ditambah sebesar entropy_coef_delta; selain itu, koefisien dikurangi. Koefisien hanya diterapkan (yaitu tidak nol) selama entropi berada pada atau di bawah target:

training_args = GRPOConfig(
    entropy_coef=0.01,          # initial coefficient
    use_adaptive_entropy=True,
    entropy_target=5.0,         # target mean per-token entropy (nats); tune for your model
    entropy_coef_delta=0.005,   # step size per optimizer step
    entropy_coef_min=0.0,
    entropy_coef_max=1.0,
    ...
)

Model bahasa yang umum memiliki entropi per token sebesar 2–10 nats, sehingga nilai default entropy_target=0.2 hampir tidak pernah memicu regularisasi — bonus hanya aktif ketika entropi berada pada atau di bawah target, yaitu saat terjadi kolaps hampir total. Atur nilainya menjadi angka yang bermakna untuk model Anda, misalnya mendekati entropi yang Anda amati di awal pelatihan (dicatat sebagai metrik entropy). Saat menggunakan top_entropy_quantile < 1.0, entropy_target diterapkan pada subset token ber-entropi tinggi — entropi subset tersebut akan lebih tinggi daripada entropy penuh-token yang dicatat, sehingga kalibrasikan sesuai dengan itu.

Ketika use_adaptive_entropy=True, koefisien entropi saat ini entropy_coef disimpan bersama setiap checkpoint dan dipulihkan saat resume, sehingga pelatihan sepenuhnya dapat dilanjutkan.

Eksperimen Cepat untuk GRPO

RapidFire AI adalah mesin eksperimen open-source yang berada di atas TRL dan memungkinkan Anda meluncurkan beberapa konfigurasi GRPO sekaligus, bahkan pada satu GPU. Alih-alih mencoba konfigurasi secara berurutan, RapidFire memungkinkan Anda melihat semua kurva pembelajaran mereka lebih awal, menghentikan run yang kinerjanya rendah, dan mengkloning yang menjanjikan dengan pengaturan baru saat berjalan tanpa perlu memulai ulang. Untuk informasi lebih lanjut, lihat RapidFire AI Integration.

Pelatihan Agen

GRPO mendukung pelatihan agen: model memanggil alat selama generasi dan belajar dari hasilnya.

  • tool adalah fungsi Python polos (sinkron atau asinkron) yang diekspos ke model. Gunakan tools untuk panggilan tanpa status (kalkulator, pencarian web).
  • Environment adalah bentuk yang lebih umum: objek berstatus yang dibuat baru untuk setiap rollout, di mana metode publiknya diekspos sebagai tools, ditambah hook siklus hidup reset dan get_reward opsional yang memungkinkannya memiliki reward. Gunakan environment_factory ketika Anda membutuhkan status per-rollout, hook reset, atau reward yang dimiliki oleh environment.

Mereka dapat dikomposisikan — Anda dapat meneruskan tools mandiri bersama dengan environment_factory.

Alat

Argumen tools mengharapkan daftar fungsi Python (sinkron atau asinkron) yang mendefinisikan alat yang tersedia untuk agen:

from trl import GRPOTrainer

trainer = GRPOTrainer(
    tools=[tool1, tool2],
    ...,
)

Setiap tool harus berupa fungsi Python standar dengan argumen dan tipe pengembalian yang diberi type-hint, serta docstring bergaya Google yang menjelaskan tujuannya, argumennya, dan nilai pengembaliannya. Untuk detail lebih lanjut, lihat panduan Passing tools.

Loop panggilan alat GRPO memerlukan template chat yang menjaga prefiks (menambahkan pesan alat tidak boleh mengubah cara pesan sebelumnya dirender). Untuk keluarga model yang dikenal (misalnya Qwen3, DeepSeek-V3), TRL secara otomatis mengganti template pelatihan dengan template yang telah diperbaiki ketika alat diaktifkan. Lihat Chat Templates untuk daftar lengkap.

Gunakan max_tool_calling_iterations di GRPOConfig untuk membatasi jumlah giliran pemanggilan alat. Secara default tidak ada batas, dan generasi berhenti ketika model menghasilkan giliran respons tanpa pemanggilan alat.

Contoh:

from trl import GRPOTrainer

def multiply(a: int, b: int) -> int:
    """
    Multiplies two integers.

    Args:
        a: The first integer.
        b: The second integer.

    Returns:
        The product of the two integers.
    """
    return a * b

async def async_add(a: int, b: int) -> int:
    """
    Asynchronously adds two integers.

    Args:
        a: The first integer.
        b: The second integer.

    Returns:
        The sum of the two integers.
    """
    return a + b

trainer = GRPOTrainer(
    tools=[multiply, async_add],
    ...,
)

Lingkungan

Anda juga dapat menyediakan alat melalui environment_factory. Dalam mode ini, GRPOTrainer membuat satu instance lingkungan per rollout dan mengekspos metode publik lingkungan sebagai alat.

environment_factory membutuhkan transformers>=5.2.0.

Saat Anda menggunakan environment_factory, lingkungan memiliki data: tidak ada train_dataset eksternal. Pada setiap rollout, reset() menghasilkan tugas — pengambilan sampel mandiri dari korpus yang dimiliki lingkungan, atau menghasilkan state secara prosedural — dan mengembalikan prompt. max_steps mengatur panjang pelatihan. Berikut adalah contoh minimal dari lingkungan yang mengambil sampel target secara mandiri dan mengekspos metode increment (diekspos sebagai tool).

import random

from trl import GRPOConfig, GRPOTrainer

class IncrementEnv:
    # Reserved methods
    def reset(self, **kwargs) -> str | None:  # required; called at the start of each rollout
        self.counter = 0
        self.target = random.randint(1, 6)  # self-sample the task
        return f"Increment the counter by {self.target}."  # returned string becomes the prompt

    def get_reward(self) -> float:  # optional: the environment scores itself from its own state
        return float(self.counter == self.target)

    # Public methods (exposed as tools)
    def increment(self, step: int) -> int:
        """
        Increment the internal counter.

        Args:
            step: Value to add to the counter.

        Returns:
            The updated counter value.
        """
        self.counter += step
        return self.counter

trainer = GRPOTrainer(
    model="Qwen/Qwen3-0.6B",
    args=GRPOConfig(max_steps=1000, chat_template_kwargs={"enable_thinking": False}),
    environment_factory=IncrementEnv,
)
trainer.train()

Kelas lingkungan memiliki dua metode cadangan: reset dan get_reward. Berbeda dengan metode publik lainnya, metode-metode ini tidak diungkapkan ke model sebagai alat.

  • reset (wajib) dipanggil saat rollout dimulai. Metode ini dapat mengembalikan None atau sebuah string. Dalam GRPO, jika mengembalikan string, string tersebut adalah prompt pengguna.
  • get_reward (opsional, sinkron atau asinkron) tidak menerima argumen dan mengembalikan float: lingkungan memberikan skor pada episode yang baru saja dijalankan berdasarkan status internalnya sendiri (apakah permainan berakhir dengan kemenangan? apakah kata tersebut berhasil ditebak?). Fungsi ini dipanggil sekali untuk setiap rollout yang selesai dan berfungsi sebagai sumber reward.

Karena lingkungan melakukan pengambilan sampel mandiri pada setiap reset(), anggota G dari sebuah grup GRPO mungkin tidak berbagi keadaan awal yang sama, sehingga membuat baseline grup menjadi sedikit lebih bising. Untuk keadaan yang identik di dalam sebuah grup, pastikan reset() menurunkan keadaan secara deterministik dari kunci bersama.

Menyediakan dataset eksternal (opsional)

Alih-alih membiarkan lingkungan melakukan pengambilan sampel mandiri, Anda dapat menyediakan train_dataset eksternal. Misalnya, ketika tugas Anda sudah ada dalam dataset, atau untuk mengalihkan rute antara beberapa lingkungan. Per rollout, trainer mengambil sampel satu baris, menggunakan kolom "prompt" baris tersebut sebagai prompt, dan meneruskan kolom lain dari baris itu ke reset() sebagai argumen kata kunci (sehingga lingkungan membaca tugas dari dataset).

from datasets import Dataset
from trl import GRPOTrainer

# Each row carries the prompt and the task data (here, the counter target to reach).
dataset = Dataset.from_dict(
    {
        "prompt": [[{"role": "user", "content": f"Increment the counter to {i}."}] for i in range(1, 7)],
        "target": list(range(1, 7)),
    }
)

class IncrementEnv:
    def reset(self, target, **kwargs) -> None:  # the row's `target` column arrives as a keyword argument
        self.counter = 0
        self.target = target

    def get_reward(self) -> float:
        return float(self.counter == self.target)

    def increment(self, step: int) -> int:  # exposed as a tool (see the full docstring above)
        self.counter += step
        return self.counter

trainer = GRPOTrainer(
    model="Qwen/Qwen3-0.6B",
    train_dataset=dataset,  # the dataset owns the task; the "target" column reaches reset(target=...)
    environment_factory=IncrementEnv,
)
trainer.train()

Hadiah

Reward yang dimiliki environment dan reward yang dimiliki trainer tidak bersifat eksklusif. Sampaikan reward_funcs untuk reward yang wajar dihitung dari completion (misalnya pemeriksaan format pada teks) dan biarkan environment mengembalikan reward yang bergantung pada state-nya melalui get_reward. Semua sumber dijumlahkan; reward_weights hanya berlaku untuk reward_funcs (environment memiliki skala miliknya sendiri).

def format_reward(completions, **kwargs):  # trainer-owned: scores the completion text
    ...

trainer = GRPOTrainer(
    model="Qwen/Qwen3-0.6B",
    args=GRPOConfig(max_steps=1000),
    reward_funcs=format_reward,          # trainer-owned: scores the completion
    environment_factory=IncrementEnv,    # env-owned: scores its internal state via `get_reward`
)

reward_func juga dapat membaca status lingkungan secara langsung: ketika environment_factory diset, trainer meneruskan kwarg environments (satu instance per completion). Ini kadang berguna, tetapi untuk reward yang bergantung pada status, lebih disarankan menggunakan get_reward.

Ini bekerja identik untuk AsyncGRPOTrainer.

Lingkungan yang beragam

Untuk melatih pada campuran tugas dalam satu eksekusi (misalnya tugas pemrograman dan permainan), teruskan kamus yang memetakan nama lingkungan ke pabrik, bukan satu callable. Setiap rollout memilih lingkungannya melalui kolom environment dalam dataset, dan hanya alat dari lingkungan tersebut yang diekspos. Hal ini mencegah kebocoran alat yang tidak relevan (alat move dari permainan ke contoh pemrograman, dan sebaliknya). Setiap lingkungan tetap memiliki datanya sendiri dan mengembalikan prompt dari reset(), sehingga dataset hanya membutuhkan kolom environment untuk merutekan di antara mereka.

import random

from datasets import Dataset
from trl import GRPOConfig, GRPOTrainer


class CodingEnv:
    def reset(self, **kwargs) -> str:
        n = random.randint(1, 20)
        return f"Compute the {n}th Fibonacci number."

    def run_code(self, code: str) -> str:  # exposed as a tool only for "coding" examples
        """Run the given Python code and return its stdout.

        Args:
            code: The Python source to execute.

        Returns:
            The captured standard output.
        """
        ...

class GameEnv:
    def reset(self, **kwargs) -> str:
        return "Reach the goal tile."

    def move(self, action: str) -> str:  # exposed as a tool only for "game" examples
        """Apply an action to the game and return the new observation.

        Args:
            action: One of "up", "down", "left", "right".

        Returns:
            The observation after the move.
        """
        ...

# The dataset only routes: each row picks the environment for that rollout
dataset = Dataset.from_dict({"environment": ["coding", "game"] * 500})

trainer = GRPOTrainer(
    model="Qwen/Qwen3-0.6B",
    args=GRPOConfig(chat_template_kwargs={"enable_thinking": False}),
    train_dataset=dataset,
    reward_funcs=reward_func,
    environment_factory={"coding": CodingEnv, "game": GameEnv},
)
trainer.train()

Fungsi reward masih menerima lingkungan dari setiap contoh melalui reward_kwargs["environments"], sehingga dapat bercabang berdasarkan tipe lingkungan (mis. isinstance(env, CodingEnv)). Instance lingkungan digunakan ulang di antara langkah (di-reset di antara episode), sehingga __init__ yang mahal hanya dibayar sekali, bukan di setiap langkah. Field environment dikonsumsi oleh trainer dan tidak diteruskan ke reset.

Respons Alat Multimodal

Tools dapat mengembalikan gambar bersama teks dengan mengembalikan daftar blok konten. Hal ini berguna untuk pelatihan agen VLM di mana tools menyediakan umpan balik visual (misalnya, tangkapan layar, plot, tangkapan kamera).

from PIL import Image

def take_screenshot() -> list:
    """
    Takes a screenshot of the current screen.

    Returns:
        The screenshot image with a description.
    """
    img = Image.open("screenshot.png")
    return [{"type": "image", "image": img}, {"type": "text", "text": "Here is the screenshot."}]

Gambar yang dikembalikan secara otomatis disuntikkan ke dalam percakapan dan diteruskan ke VLM untuk giliran generasi berikutnya.

Model yang Didukung

Diuji dengan:

  • Beam — misalnya, reflection/Beam-1.0-501B-A23B
  • DeepSeek-R1 — misalnya, deepseek-ai/DeepSeek-R1
  • Gemma4 — misalnya, google/gemma-4-E2B-it
  • GLM-4-MoE (4.5, 4.6 atau 4.7) — misalnya, zai-org/GLM-4.7
  • GPT-OSS — misalnya, openai/gpt-oss-20b
  • Llama 3.1 — misalnya, meta-llama/Llama-3.1-8B-Instruct
  • Llama 3.2 — misalnya, meta-llama/Llama-3.2-3B-Instruct
  • Qwen2.5 — misalnya, Qwen/Qwen2.5-0.5B-Instruct
  • Qwen3 — misalnya, Qwen/Qwen3-0.6B
  • Qwen3-VL — misalnya, Qwen/Qwen3-VL-2B-Instruct
  • Qwen3.5 — misalnya, Qwen/Qwen3.5-2B
  • Qwen3.6 — misalnya, Qwen/Qwen3.6-35B-A3B

Kompatibilitas dengan semua LLM tidak dijamin. Jika Anda yakin suatu model harus didukung, silakan buka issue di GitHub — atau lebih baik lagi, kirimkan pull request dengan perubahan yang diperlukan.

Integrasi Lingkungan

Semua lingkungan terhubung ke slot environment_factory yang sama, sehingga dapat dipertukarkan pada level TRL — pilih yang ekosistemnya sesuai dengan tugas Anda:

IntegrasiApa ituGunakan saat
OpenEnvStandar lingkungan terbuka (API bergaya Gymnasium, disajikan melalui WebSocket atau eksekusi terkontainerisasi), didukung oleh Hugging Face dan komunitas.Anda menggunakan lingkungan OpenEnv yang sudah jadi dari Hub, atau mendefinisikan lingkungan Anda sendiri berdasarkan standar terbuka (misalnya Wordle, Sudoku, Catch).
OpenRewardIntegrasi dengan lingkungan berbahasa ORS (katalog openreward.ai atau server ORS Anda sendiri); tugas dan reward disajikan melalui HTTP.Anda ingin melatih terhadap lingkungan ORS: katalog (misalnya Eigent/SETA), yang Anda host sendiri di infrastruktur Anda, atau server lokal yang sedang Anda kembangkan.
HarborIntegrasi dengan suite tugas Harbor: setiap tugas adalah instruksi, image sandbox nyata (docker, e2b, …), dan verifier di dalam sandbox.Anda ingin melatih terhadap suite tugas Harbor: sebuah pohon tugas, di mana masing-masing tugas adalah sandbox mandiri plus verifier (misalnya agen analisis data yang mengeksplorasi file di dalam sandbox dan menulis jawaban yang diperiksa oleh grader).

Pelatihan Model Bahasa Visual

GRPO mendukung pelatihan Vision-Language Models (VLM) pada dataset multimodal yang berisi teks dan gambar.

Model yang Didukung

Diuji dengan:

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

Kompatibilitas dengan semua VLM tidak dijamin. Jika Anda yakin suatu model harus didukung, silakan buka issue di GitHub — atau lebih baik lagi, kirimkan pull request dengan perubahan yang diperlukan.

Mulai Cepat

Gunakan grpo_vlm.py untuk fine-tune sebuah VLM. Contoh perintah untuk pelatihan pada lmms-lab/multimodal-open-r1-8k-verified:

accelerate launch \
  --config_file=examples/accelerate_configs/deepspeed_zero3.yaml \
  examples/grpo_visual_math/grpo_visual_math.py \
  --model_name_or_path Qwen/Qwen2.5-VL-3B-Instruct \
  --output_dir grpo-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

Tips Konfigurasi

  • Gunakan LoRA pada lapisan proyeksi bahasa-visi
  • Aktifkan kuantisasi 4-bit untuk mengurangi penggunaan memori
  • VLMs sangat intensif terhadap memori — mulailah dengan ukuran batch yang lebih kecil
  • Sebagian besar model kompatibel dengan vLLM (mode server dan colocate)

Format Dataset

Setiap sampel pelatihan harus mencakup:

  • prompt: Teks yang diformat melalui template chat prosesor
  • image/images: Gambar PIL atau daftar Gambar PIL

Trainer secara otomatis menangani konversi gambar-ke-tensor melalui image processor model.

GRPOTrainer

kelas trl.GRPOTrainer

< >

( 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]]] | None = Noneargs: trl.trainer.grpo_config.GRPOConfig | 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 = Nonetools: list[collections.abc.Callable] | None = Nonerollout_func: collections.abc.Callable[[list[str], 'GRPOTrainer'], dict[str, typing.Any]] | None = Noneenvironment_factory: collections.abc.Callable[[], trl.trainer.grpo_trainer._SupportsReset] | dict[str, collections.abc.Callable[[], trl.trainer.grpo_trainer._SupportsReset]] | None = None )

Parameter

  • model (str atau PreTrainedModel atau PeftModel) — Model yang akan dilatih. Bisa berupa:
    • String, berupa model id dari model pretrained yang dihosting di dalam model repo di huggingface.co, atau path ke directory yang berisi model weights yang disimpan menggunakan save_pretrained, misalnya './my_model_directory/'. Model dimuat menggunakan <ModelArchitecture>.from_pretrained (di mana <ModelArchitecture> diturunkan dari model config) dengan keyword arguments di args.model_init_kwargs. Jika dtype tidak ditentukan di args.model_init_kwargs, default-nya adalah float32. Ini berbeda dari from_pretrained, di mana (sejak Transformers v5) dtype disimpulkan dari model config.
    • Objek PreTrainedModel. Hanya model bahasa kausal yang didukung.
    • Objek PeftModel. Hanya model bahasa kausal yang didukung.
  • reward_funcs (RewardFunc | list[RewardFunc], opsional) — Fungsi reward yang akan digunakan untuk menghitung reward. Untuk menghitung reward, kami memanggil semua fungsi reward dengan prompt dan completion, lalu menjumlahkan reward-nya. Dapat diabaikan ketika reward disediakan oleh lingkungan melalui environment_factory (lihat di bawah). Bisa berupa:
    • Satu fungsi reward, seperti:

      • Sebuah string: ID model dari model pretrained yang dihosting di dalam repo model di huggingface.co, atau path ke direktori yang berisi bobot model yang disimpan menggunakan save_pretrained, misalnya './my_model_directory/'. Model dimuat menggunakan from_pretrained dengan num_labels=1 dan keyword arguments di args.model_init_kwargs.

      • Objek PreTrainedModel: Hanya model klasifikasi urutan yang didukung.

      • Fungsi reward kustom: Fungsi ini diberikan prompt dan kelengkapan yang dihasilkan, ditambah kolom tambahan apa pun dalam dataset. Fungsi ini harus mengembalikan daftar reward. Fungsi reward kustom dapat bersifat sinkron atau asinkron, dan juga dapat mengembalikan None ketika reward tidak berlaku untuk sampel tersebut. Hal ini berguna untuk pelatihan multi-tugas di mana fungsi reward yang berbeda berlaku untuk jenis sampel yang berbeda. Ketika fungsi reward mengembalikan None untuk suatu sampel, fungsi reward tersebut dikecualikan dari perhitungan reward untuk sampel tersebut. Untuk detail lebih lanjut, lihat Menggunakan fungsi reward kustom.

        Status trainer juga diteruskan ke fungsi reward. Status trainer adalah instance dari TrainerState dan dapat diakses dengan mengakses argumen trainer_state pada signature fungsi reward.

    • Daftar fungsi reward, di mana setiap item dapat secara independen berupa salah satu tipe di atas. Pencampuran tipe yang berbeda dalam daftar (misalnya, ID model string dan fungsi reward kustom) diizinkan.

  • args (GRPOConfig, opsional) — Konfigurasi untuk trainer ini. Jika None, konfigurasi default akan digunakan.
  • train_dataset (Dataset atau IterableDataset, opsional) — Dataset yang digunakan untuk pelatihan. Dataset ini harus menyertakan kolom "prompt". Kolom tambahan lainnya dalam dataset akan diabaikan. Format sampel dapat berupa: Standar: Setiap sampel berisi teks polos. Konversasional: Setiap sampel berisi pesan terstruktur (misalnya, role dan content). Parameter ini hanya boleh diabaikan jika environment_factory disediakan dan lingkungan memiliki (atau menghasilkan secara prosedural) data tersebut, dengan mengembalikan prompt dari metode reset(). Dalam kasus tersebut, max_steps harus diatur untuk menentukan panjang pelatihan. Jika train_dataset adalah IterableDataset (misalnya dataset streaming), max_steps harus diatur dalam argumen pelatihan, karena panjangnya tidak dapat disimpulkan dan jumlah total langkah pelatihan diperlukan untuk membatasi loop pelatihan serta mengonfigurasi learning rate scheduler.
    • Standar: Setiap sampel berisi teks polos.
    • Konversasional: Setiap sampel berisi pesan terstruktur (misalnya, peran dan konten).

    Dapat diabaikan hanya ketika environment_factory disediakan dan lingkungan memiliki (atau menghasilkan secara prosedural) data, dengan mengembalikan prompt dari metode reset()-nya. Dalam kasus tersebut, max_steps harus diatur untuk menentukan panjang pelatihan.

    Ketika train_dataset adalah IterableDataset (misalnya dataset streaming), max_steps harus diatur dalam argumen pelatihan, karena panjangnya tidak dapat disimpulkan dan jumlah total langkah pelatihan diperlukan untuk membatasi loop pelatihan serta mengonfigurasi penjadwal laju pembelajaran.

  • eval_dataset (Dataset, IterableDataset, DatasetDict, IterableDatasetDict atau dict[str, Dataset | IterableDataset]) — Dataset yang digunakan untuk evaluasi. Dataset ini harus memenuhi persyaratan yang sama dengan train_dataset.
  • processing_class (PreTrainedTokenizerBase, ProcessorMixin, opsional) — Kelas pemrosesan yang digunakan untuk memproses data. Sisi padding harus diatur ke “left”. Jika None, kelas pemrosesan dimuat dari nama model dengan from_pretrained. Token padding, tokenizer.pad_token, harus diatur. Jika kelas pemrosesan belum mengatur token padding, tokenizer.eos_token akan digunakan sebagai default.
  • reward_processing_classes (PreTrainedTokenizerBase atau list[PreTrainedTokenizerBase], opsional) — Kelas pemrosesan yang sesuai dengan fungsi reward yang ditentukan dalam reward_funcs. Dapat berupa:
    • Satu kelas pemrosesan: Digunakan ketika reward_funcs hanya berisi satu fungsi reward.
    • Daftar kelas pemrosesan: Harus sesuai dengan urutan dan panjang fungsi reward di reward_funcs. Jika diatur ke None, atau jika elemen daftar yang sesuai dengan PreTrainedModel adalah None, tokenizer untuk model tersebut dimuat secara otomatis menggunakan from_pretrained. Untuk elemen di reward_funcs yang merupakan fungsi reward kustom (bukan PreTrainedModel), entri yang sesuai di reward_processing_classes diabaikan.
  • callbacks (daftar TrainerCallback, opsional) — Daftar callback untuk menyesuaikan loop pelatihan. Callback ini akan ditambahkan ke daftar callback default yang dijelaskan di sini.

    Jika Anda ingin menghapus salah satu callback default yang digunakan, gunakan metode remove_callback.

  • optimizers (tuple[torch.optim.Optimizer | None, torch.optim.lr_scheduler.LambdaLR | None], opsional, defaultnya (None, None)) — Tuple yang berisi optimizer dan scheduler yang akan digunakan. Secara default akan menggunakan instance AdamW pada model Anda dan scheduler yang diberikan oleh get_linear_schedule_with_warmup yang dikendalikan oleh args.
  • quantization_config (BitsAndBytesConfig, opsional) — Konfigurasi kuantisasi yang digunakan saat memuat model dari pengidentifikasi model. Gabungkan dengan peft_config untuk pelatihan QLoRA. Diabaikan jika model sudah diinstansiasi.
  • peft_config (PeftConfig, opsional) — Konfigurasi PEFT yang digunakan untuk membungkus model. Jika None, model tidak dibungkus.
  • tools (list of Callable, opsional) — Daftar fungsi tool yang dapat dipanggil (sinkron atau asinkron) yang dapat diaktifkan oleh model selama proses generasi. Setiap tool harus berupa fungsi Python standar dengan argumen dan nilai return yang diberi type hint dengan benar, serta docstring bergaya Google yang menjelaskan tujuannya, argumennya, dan nilai return-nya. Untuk detail lebih lanjut, lihat: https://huggingface.co/docs/transformers/en/chat_extras#passing-tools. Model menggunakan nama fungsi, type hints, dan docstring untuk menentukan cara memanggilnya. Pastikan bahwa chat template model mendukung penggunaan tool dan bahwa model tersebut telah di-fine-tune untuk tool calling.
  • rollout_func (RolloutFunc, opsional) — Fungsi yang digunakan untuk menghasilkan kelengkapan. Fungsi ini menerima daftar prompt yang dialokasikan ke proses saat ini dan instance trainer. Fungsi ini harus mengembalikan dict dengan field "prompt_ids", "completion_ids", dan "logprobs", dan secara opsional dapat mengembalikan "logprob_token_ids" (bentuk yang sama dengan "logprobs"). Field lainnya diteruskan ke fungsi reward. Fungsi ini menerima potongan prompt per proses mentah tanpa duplikasi; fungsi ini bertanggung jawab untuk mengembalikan jumlah kelengkapan yang benar per prompt (lihat num_generations / num_generations_eval pada trainer). Fitur ini bersifat eksperimental dan dapat berubah atau dihapus kapan saja tanpa pemberitahuan sebelumnya.
  • environment_factory (EnvironmentFactory atau dict[str, EnvironmentFactory], opsional) — Callable yang membuat dan mengembalikan instance environment, atau kamus yang memetakan nama environment ke callable semacam itu. Kelas environment harus mendefinisikan metode yang dapat dipanggil sebagai tools selama generation. Setiap metode harus mematuhi persyaratan yang sama dengan tools yang dijelaskan di atas. Environment juga harus mengimplementasikan metode callable reset yang dapat digunakan untuk mereset state antar generation. Metode reset seharusnya mengembalikan None atau string: ketika mengembalikan string, string tersebut ditambahkan ke pesan user terakhir sebelum generation. Environment juga dapat mendefinisikan metode get_reward yang tidak mengambil argumen dan mengembalikan float: ketika ada, environment memiliki reward, dan get_reward dipanggil sekali per rollout yang selesai untuk memberikan skor berdasarkan state internal environment. Ini berfungsi sebagai sumber reward tambahan (dengan bobot 1, dicatat di bawah nama kelas environment) di samping reward_funcs, yang kemudian menjadi opsional.

    Dengan satu callable, setiap contoh menggunakan lingkungan yang sama, dengan satu instance per rollout sehingga interaksi mereka tetap terisolasi. Dengan dictionary, setiap contoh harus memiliki field environment yang memilih lingkungannya berdasarkan nama, dan hanya tool dari lingkungan tersebut yang diekspos di prompt-nya — memungkinkan satu run mencampur tugas (misalnya lingkungan coding dan game). Fitur ini bersifat eksperimental dan dapat berubah atau dihapus kapan saja tanpa pemberitahuan sebelumnya.

Trainer untuk metode Group Relative Policy Optimization (GRPO). Algoritma ini pertama kali diusulkan dalam makalah DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models.

Contoh:

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

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

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

latih

< >

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

Parameter

  • resume_from_checkpoint (str atau bool, opsional) — Jika berupa str, jalur lokal ke checkpoint yang disimpan oleh instance Trainer sebelumnya. Jika berupa bool dan bernilai True, muat checkpoint terakhir di args.output_dir yang disimpan oleh instance Trainer sebelumnya. Jika ada, pelatihan akan dilanjutkan dari status model/optimizer/scheduler yang dimuat di sini.
  • trial (optuna.Trial atau dict[str, Any], opsional) — Jalankan trial atau kamus hiperparameter untuk pencarian hiperparameter.
  • ignore_keys_for_eval (list[str], opsional) — Daftar kunci dalam output model Anda (jika berupa dictionary) yang harus diabaikan saat mengumpulkan prediksi untuk evaluasi selama pelatihan.

Mengembalikan

~trainer_utils.TrainOutput

Objek yang berisi jumlah langkah global, kerugian pelatihan, dan metrik.

Titik masuk utama pelatihan.

save_model

< >

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

Akan menyimpan model, sehingga Anda dapat memuatnya kembali menggunakan from_pretrained().

Hanya akan menyimpan dari proses utama.

push_to_hub

< >

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

Parameter

  • commit_message (str, opsional, default "End of training") — Pesan untuk commit saat melakukan push.
  • blocking (bool, opsional, default True) — Apakah fungsi harus hanya mengembalikan nilai setelah git push selesai.
  • token (str, opsional, defaultnya None) — Token dengan izin tulis untuk menimpa argumen asli Trainer.
  • revision (str, opsional) — Revisi git untuk di-commit. Secara default menggunakan head dari branch “main”.
  • kwargs (dict[str, Any], opsional) — Argumen kata kunci tambahan yang diteruskan ke ~Trainer.create_model_card.

Unggah self.model dan self.processing_class ke 🤗 model hub di repo self.args.hub_model_id.

GRPOConfig

kelas trl.GRPOConfig

< >

( 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 = Falsecast_lm_head_to_fp32: bool = Falsenum_generations: int | None = 8num_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.0num_iterations: int = 1epsilon: float = 0.2delta: float | None = Noneepsilon_high: float | None = Nonesapo_temperature_neg: float = 1.05sapo_temperature_pos: float = 1.0vespo_k_pos: float = 2.0vespo_lambda_pos: float = 3.0vespo_k_neg: float = 3.0vespo_lambda_neg: float = 2.0importance_sampling_level: str = 'token'reward_weights: list[float] | None = Nonemulti_objective_aggregation: str = 'sum_then_normalize'scale_rewards: str = 'group'loss_type: str = 'dapo'mask_truncated_completions: bool = Falsesync_ref_model: bool = Falseref_model_mixup_alpha: float = 0.6ref_model_sync_steps: int = 512top_entropy_quantile: float = 1.0entropy_coef: float = 0.0use_adaptive_entropy: bool = Falseentropy_coef_min: float = 0.0entropy_coef_max: float = 1.0entropy_coef_delta: float = 0.005entropy_target: float = 0.2max_tool_calling_iterations: int | None = Nonevllm_importance_sampling_correction: bool = Truevllm_importance_sampling_mode: str = 'sequence_mask'vllm_importance_sampling_clip_max: float | None = 3.0vllm_importance_sampling_clip_min: float | None = Noneoff_policy_mask_threshold: float | None = Noneuse_bias_correction_kl: bool = Truelog_completions: bool = Falselog_multimodal: bool = Truenum_completions_to_print: int | None = Nonelog_unique_prompts: bool = Falselog_completions_hub_repo: str | None = Noneuse_transformers_continuous_batching: bool = Falsetransformers_continuous_batching_config: dict | str | None = Noneuse_transformers_paged: bool = Falsevllm_importance_sampling_cap: float | None = None )

Parameter yang mengontrol model dan model referensi

  • model_init_kwargs (str atau dict[str, Any], opsional) — Argumen kata kunci untuk from_pretrained, digunakan ketika argumen model dari GRPOTrainer diberikan sebagai string. Nilai revision juga digunakan saat memuat kelas pemrosesan.
  • trust_remote_code (bool, opsional, default False) — Apakah mengizinkan pemuatan model dan tokenizer yang menyertakan kode Python kustom dari Hub. Diteruskan ke from_pretrained dan from_pretrained. Juga diterapkan pada pemuatan reward-model dan reward-tokenizer.
  • router_aux_loss_coef (float, opsional) — Koefisien dari loss tambahan penyeimbangan beban untuk model Mixture-of-Experts (MoE), yang ditambahkan ke loss pelatihan dengan bobot ini. Jika tidak diatur, nilai yang dideklarasikan oleh konfigurasi model akan digunakan. Atur ke 0.0 untuk menonaktifkannya. Gagal jika digunakan dengan model non-MoE.
  • disable_dropout (bool, opsional, default False) — Apakah akan menonaktifkan dropout pada model. Ini berguna untuk pelatihan dengan model referensi, karena mencegah model menghasilkan logprobs yang berbeda untuk input yang sama.
  • cast_lm_head_to_fp32 (bool, opsional, default False) — Apakah akan meng-cast language modeling head dari model policy dan reference ke float32. Sesuai rekomendasi dari resep ScaleRL. Flag ini hanya didukung ketika model memiliki lapisan word embedding dan language modeling head yang tidak terikat, yaitu tie_word_embeddings dalam konfigurasi model bernilai False.

Parameter yang mengontrol pra-pemrosesan data

  • remove_unused_columns (bool, opsional, default False) — Apakah hanya kolom "prompt" yang akan dipertahankan dalam dataset. Jika Anda menggunakan fungsi reward kustom yang memerlukan kolom selain "prompts" dan "completions", Anda sebaiknya mempertahankan nilai ini sebagai False.
  • num_generations (int, opsional, defaultnya 8) — Jumlah generasi per prompt yang akan disampelkan. Ukuran batch efektif (num_processes * per_device_batch_size * gradient_accumulation_steps) harus dapat dibagi habis oleh nilai ini.
    • gradient_accumulation_steps) harus dapat dibagi habis oleh nilai ini.
  • num_generations_eval (int, opsional) — Jumlah generasi yang akan disampelkan selama evaluasi. Hal ini memungkinkan penggunaan lebih sedikit generasi selama evaluasi untuk menghemat komputasi. Jika None, menggunakan nilai dari num_generations.
  • max_completion_length (int atau None, opsional, defaultnya 512) — Panjang maksimum dari penyelesaian yang dihasilkan.
  • ds3_gather_for_generation (bool, opsional, default True) — Pengaturan ini berlaku untuk DeepSpeed ZeRO-3. Jika diaktifkan, bobot model kebijakan akan dikumpulkan untuk generasi, sehingga meningkatkan kecepatan generasi. Namun, menonaktifkan opsi ini memungkinkan pelatihan model yang melebihi kapasitas VRAM satu GPU, meskipun dengan biaya kecepatan generasi yang lebih lambat. Menonaktifkan opsi ini tidak kompatibel dengan generasi vLLM.
  • shuffle_dataset (bool, opsional, default True) — Apakah dataset pelatihan akan diacak.
  • pad_to_multiple_of (int atau str, opsional, default "auto") — Jika diset, prompt ids dan completion ids akan di-pad hingga menjadi kelipatan dari nilai ini. "auto" melakukan padding hingga kelipatan 128 pada Neuron (AWS Trainium), yang dikompilasi sekali per bentuk input, dan tidak melakukan padding di tempat lain.

Parameter yang mengontrol generasi

  • generation_batch_size (int, opsional) — Ukuran batch yang digunakan untuk generasi. Jika None, nilainya secara default adalah ukuran batch pelatihan efektif: per_device_train_batch_size * num_processes * steps_per_generation. Dengan kata lain, ada satu batch generasi yang diproses per langkah optimasi. Saling eksklusif dengan steps_per_generation.
  • steps_per_generation (int, opsional) — Jumlah langkah per generasi. Jika None, nilainya secara default adalah gradient_accumulation_steps. Saling eksklusif dengan generation_batch_size.
  • temperature (float, opsional, default 1.0) — Suhu untuk sampling. Semakin tinggi suhu, semakin acak hasil pelengkapannya.
  • top_p (float, opsional, default 1.0) — Float yang mengontrol probabilitas kumulatif dari token teratas yang dipertimbangkan. Harus berada dalam (0, 1]. Atur ke 1.0 untuk mempertimbangkan semua token.
  • top_k (int, opsional, default 0) — Jumlah token kosakata dengan probabilitas tertinggi yang dipertahankan untuk top-k-filtering. Jika 0, top-k-filtering dinonaktifkan dan semua token dipertimbangkan.
  • min_p (float, opsional) — Probabilitas token minimum, yang akan diskalakan oleh probabilitas token yang paling mungkin. Nilainya harus berada di antara 0.0 dan 1.0. Nilai tipikal berada dalam rentang 0.01-0.2.
  • generation_kwargs (dict[str, Any], opsional) — Argumen kata kunci tambahan untuk diteruskan ke GenerationConfig (jika menggunakan transformers) atau SamplingParams (jika menggunakan vLLM) saat mengambil sampel penyelesaian. Ini dapat digunakan untuk lebih menyesuaikan perilaku generasi, seperti mengatur suppress_tokens, num_beams, dll. Jika berisi kunci yang bertentangan dengan parameter generasi lainnya (seperti min_p, top_p, dll.), mereka akan menimpanya.
  • chat_template_kwargs (dict[str, Any], opsional) — Argumen kata kunci tambahan untuk diteruskan ke fungsi apply_chat_template saat menghasilkan kelengkapan.
  • repetition_penalty (float, opsional, default 1.0) — Float yang menghukum token baru berdasarkan apakah token tersebut muncul dalam prompt dan teks yang telah dihasilkan sejauh ini. Nilai > 1.0 mendorong model untuk menggunakan token baru, sedangkan nilai < 1.0 mendorong model untuk mengulang token.
  • cache_implementation (str, opsional) — Implementasi metode cache untuk generasi yang lebih cepat ketika use_vllm diatur ke False.

Parameter yang mengontrol akselerasi generasi yang didukung oleh vLLM

  • use_vllm (bool, opsional, default False) — Apakah akan menggunakan vLLM untuk menghasilkan kelengkapan. Jika diatur ke True, trainer akan menggunakan vLLM untuk generasi alih-alih model.generate() default. Memerlukan vllm terpasang.
  • vllm_mode (str, opsional, defaultnya "colocate") — Mode yang digunakan untuk integrasi vLLM ketika use_vllm diatur ke True. Harus salah satu dari "server" atau "colocate".
    • "server": Trainer akan mengirim permintaan generasi ke server vLLM terpisah. Pastikan server vLLM sedang berjalan (mulai dengan vllm serve).
    • "colocate": vLLM akan berjalan dalam proses yang sama dan berbagi GPU pelatihan. Hal ini menghindari kebutuhan akan server terpisah, tetapi dapat menyebabkan perebutan sumber daya dengan pelatihan.
  • vllm_model_impl (str, opsional, default "vllm") — Implementasi model yang digunakan untuk vLLM. Harus salah satu dari "transformers" atau "vllm". "transformers": Gunakan backend transformers untuk implementasi model. "vllm": Gunakan pustaka vllm untuk implementasi model.
  • vllm_enable_sleep_mode (bool, opsional, default False) — Aktifkan mode tidur vLLM untuk memindahkan bobot/cache selama langkah optimizer. Menjaga penggunaan memori GPU tetap rendah, tetapi membangunkan mesin menambah latensi transfer host–perangkat.
  • vllm_structured_outputs_regex (str, opsional) — Regex untuk structured outputs vLLM. Jika None (default), structured outputs dinonaktifkan.

Parameter yang mengontrol server vLLM (hanya digunakan ketika `vllm_mode` adalah `"server"`)

  • vllm_server_base_url (str, opsional) — URL dasar untuk server vLLM (misalnya, "http://localhost:8000"). Jika disediakan, vllm_server_host dan vllm_server_port diabaikan.
  • vllm_server_host (str, opsional, default "0.0.0.0") — Host dari server vLLM yang akan dihubungi. Diabaikan jika vllm_server_base_url disediakan.
  • vllm_server_port (int, opsional, default 8000) — Port server vLLM yang akan dihubungi. Diabaikan jika vllm_server_base_url disediakan.
  • vllm_server_timeout (float, opsional, default 240.0) — Durasi total timeout dalam detik untuk menunggu server vLLM siap. Jika server belum siap setelah timeout, ConnectionError akan dilempar.
  • vllm_group_port (int, opsional, default 51216) — Nomor port untuk grup pembaruan bobot. Ini digunakan untuk berkomunikasi dengan server vLLM. Kecuali port tersebut sedang digunakan, tidak perlu diubah.

Parameter yang mengontrol eksekusi vLLM yang terkolokasi (hanya digunakan ketika `vllm_mode` adalah `"colocate"`)

  • vllm_gpu_memory_utilization (float, opsional, default 0.3) — Mengontrol utilisasi memori GPU untuk vLLM. Pengaturan ini hanya berlaku ketika vllm_mode diatur ke "colocate". Jika Anda menggunakan vllm_mode="server", parameter ini harus diteruskan secara terpisah saat meluncurkan server vLLM melalui flag --vllm_gpu_memory_utilization.
  • vllm_max_model_length (int, opsional) — Jendela konteks untuk vLLM. Atur nilainya setidaknya sama dengan panjang prompt maksimum dalam dataset ditambah max_completion_length; jika diabaikan, nilainya akan disimpulkan dari konfigurasi model.
  • vllm_tensor_parallel_size (int, opsional, default 1) — Mengontrol ukuran paralel tensor untuk vLLM. Pengaturan ini hanya berlaku ketika vllm_mode diatur ke "colocate". Jika Anda menggunakan vllm_mode="server", parameter ini harus diteruskan secara terpisah saat meluncurkan server vLLM melalui flag --vllm_tensor_parallel_size.

Parameter yang mengontrol pelatihan

  • beta (float, opsional, default 0.0) — Koefisien KL. Jika 0.0 (default), model referensi tidak dimuat, sehingga mengurangi penggunaan memori dan meningkatkan kecepatan pelatihan. DeepSeek-R1 mendorong penalaran pada LLM melalui pembelajaran penguatan menggunakan nilai 0.001.
  • num_iterations (int, opsional, default 1) — Jumlah iterasi per batch (dilambangkan sebagai μ dalam algoritma).
  • epsilon (float, optional, defaults to 0.2) — Epsilon value for clipping.
  • delta (float, opsional) — Mengaktifkan batas pemotongan atas pada kerugian GRPO dua sisi ketika diatur ke float. Jika None (default), pemotongan GRPO standar digunakan. Disarankan agar nilainya lebih besar dari 1 + ε saat diaktifkan. Metode ini diperkenalkan dalam laporan teknologi INTELLECT-2.
  • epsilon_high (float, opsional) — Nilai epsilon batas atas untuk clipping. Jika tidak ditentukan, nilainya secara default sama dengan nilai batas bawah yang ditentukan dalam argumen epsilon. Paper DAPO merekomendasikan 0.28. Saat digunakan dengan loss_type='cispo', ini sesuai dengan parameter ε_max yang ditentukan dalam paper ScaleRL dan secara default menggunakan nilai yang direkomendasikan, yaitu 5.0.
  • sapo_temperature_neg (float, opsional, default 1.05) — Suhu untuk token dengan skor keuntungan non-positif yang digunakan dalam fungsi kerugian sapo. Parameter ini diperkenalkan dalam makalah Soft Adaptive Policy Optimization.
  • sapo_temperature_pos (float, opsional, default 1.0) — Suhu untuk token dengan skor keuntungan positif yang digunakan dalam fungsi kerugian sapo. Parameter ini diperkenalkan dalam makalah Soft Adaptive Policy Optimization.
  • vespo_k_pos (float, opsional, default 2.0) — parameter k untuk keuntungan positif, yaitu pangkat eksponen dalam loss VESPO. Mengontrol seberapa agresif kita menurunkan bobot sampel dengan bobot kepentingan rendah (ketika rasio importance sampling < 1).
  • vespo_lambda_pos (float, opsional, default 3.0) — parameter lambda untuk keuntungan positif, yaitu faktor peluruhan dalam loss VESPO. Mengontrol seberapa agresif kita menurunkan bobot sampel dengan bobot kepentingan tinggi (ketika rasio importance sampling > 1).
  • vespo_k_neg (float, opsional, default 3.0) — parameter k untuk keuntungan negatif, yaitu pangkat eksponen dalam loss VESPO. Mengontrol seberapa agresif kita menurunkan bobot sampel dengan bobot kepentingan rendah (ketika rasio importance sampling < 1).
  • vespo_lambda_neg (float, opsional, default 2.0) — parameter lambda untuk keuntungan negatif, yaitu faktor peluruhan eksponensial dalam loss VESPO. Mengontrol seberapa agresif kita menurunkan bobot sampel dengan bobot kepentingan tinggi (ketika rasio importance sampling > 1).
  • importance_sampling_level (str, opsional, default "token") — Mengontrol apakah rasio importance sampling dihitung pada level "token" atau "sequence". "token" menjaga rasio log-probabilitas per token mentah (satu bobot per token). "sequence" merata-ratakan rasio log-probabilitas di seluruh token valid untuk menghasilkan satu rasio per sequence. makalah GSPO menunjukkan bahwa sampling level sequence sering kali menghasilkan pelatihan yang lebih stabil dan keselarasan yang lebih baik dengan reward level sequence.
  • reward_weights (list[float], opsional) — Bobot untuk setiap fungsi reward. Harus sesuai dengan jumlah fungsi reward. Jika None, semua reward diberi bobot yang sama dengan nilai 1.0.
  • multi_objective_aggregation (str, opsional, default ke "sum_then_normalize") — Metode untuk mengagregasi beberapa fungsi reward. Nilai yang didukung adalah:
    • "sum_then_normalize" (default): Pertama menjumlahkan reward berbobot dari setiap fungsi reward, kemudian menerapkan penskalaan/normalisasi reward sesuai dengan yang ditentukan oleh scale_rewards (lihat scale_rewards untuk detailnya).
    • "normalize_then_sum": Pertama-tama menormalisasi/menskala setiap fungsi reward di seluruh generasi (di dalam setiap grup), kemudian menjumlahkan reward yang telah dinormalisasi menggunakan bobot yang ditentukan. Reward agregat kemudian dinormalisasi pada level batch saat membentuk keuntungan. Ini adalah pendekatan yang disarankan dari makalah GDPO: Group reward-Decoupled Normalization Policy Optimization for Multi-reward RL Optimization.
  • scale_rewards (str atau bool, opsional, defaultnya "group") — Menentukan strategi penskalaan untuk reward. Nilai yang didukung adalah:
    • True atau "group" (default): reward diskalakan berdasarkan standar deviasi di dalam setiap grup, memastikan varians unit di dalam sebuah grup.
    • "batch": reward diskalakan berdasarkan standar deviasi di seluruh batch, seperti yang direkomendasikan dalam makalah PPO Lite.
    • False atau "none": tidak ada penskalaan yang diterapkan. makalah Dr. GRPO merekomendasikan untuk tidak melakukan penskalaan pada reward, karena penskalaan berdasarkan standar deviasi memperkenalkan bias tingkat kesulitan per pertanyaan.
  • loss_type (str, opsional, defaultnya "dapo") — Menentukan formulasi loss yang akan digunakan. Nilai yang didukung adalah:
    • "grpo": Mengagregasi kerugian tingkat token dengan menormalisasi berdasarkan panjang urutan. Tidak disarankan karena bias panjang—pendekatan ini cenderung lebih memilih penyelesaian yang lebih pendek dengan keuntungan positif dan yang lebih panjang dengan keuntungan negatif.
    • "dr_grpo": Mengagregasi kerugian pada tingkat token dengan menormalisasi menggunakan konstanta global. Metode ini diperkenalkan dalam makalah Dr. GRPO untuk menghilangkan bias panjang. Nilai konstanta tersebut sesuai dengan max_completion_length.
    • "dapo" (default): Mengagregasi kerugian pada tingkat token dengan menormalisasi menggunakan jumlah token aktif dalam batch akumulasi global. Metode ini diperkenalkan dalam makalah DAPO untuk menghilangkan bias panjang.
    • "bnpo": Mengagregasi kerugian pada tingkat token dengan menormalkan berdasarkan jumlah token aktif dalam batch lokal. Perhatikan bahwa normalisasi hanya dilakukan pada batch lokal, sehingga hasil mungkin sedikit bervariasi tergantung pada ukuran batch lokal, meskipun ukuran batch efektif tetap konstan. Saat menggunakan per_device_train_batch_size==1, kerugian ini ekuivalen dengan kerugian GRPO.
    • "cispo": Memotong bobot importance sampling, bukan bobot importance sampling yang diskalakan dengan advantage. Bobot yang dipotong tersebut kemudian dikalikan dengan advantage dan log probs dari model kebijakan. Kerugian per token diagregasi dengan menormalisasi berdasarkan jumlah token aktif dalam batch global yang terakumulasi. Metode ini diperkenalkan dalam paper MiniMax-M1.
    • "sapo": kerugian Soft Adaptive Policy Optimization, sebagaimana diperkenalkan dalam makalah Soft Adaptive Policy Optimization. Mengganti pemotongan keras dengan gerbang halus yang dikendalikan suhu, yang secara adaptif meredam pembaruan off-policy sambil mempertahankan sinyal pembelajaran yang berguna.
    • "luspo": Loss Length-Unbiased Sequence Policy Optimization. Loss tingkat-sekuens yang menskalakan loss setiap sekuens berdasarkan panjangnya. Ini adalah modifikasi dari GSPO dan membutuhkan importance_sampling_level="sequence". Diperkenalkan dalam paper LUSPO.
    • "vespo": Variational Sequence-Level Soft Policy Optimization. Mengganti hard clipping dengan fungsi penimbangan Gamma yang halus dan asimetris, yang diterapkan langsung pada bobot kepentingan tingkat sekuens. Diperkenalkan dalam makalah VESPO.
  • mask_truncated_completions (bool, opsional, default False) — Jika diaktifkan, completion yang terpotong akan dikecualikan dari perhitungan loss, sehingga mencegah mereka dihukum secara tidak tepat dan memperkenalkan noise selama pelatihan. Menurut paper DAPO, ini adalah praktik yang baik untuk stabilitas pelatihan.
  • sync_ref_model (bool, opsional, default False) — Apakah model referensi akan disinkronkan dengan model aktif setiap ref_model_sync_steps langkah, menggunakan parameter ref_model_mixup_alpha. Sinkronisasi ini berasal dari paper TR-DPO.
  • ref_model_mixup_alpha (float, opsional, default 0.6) — parameter α dari paper TR-DPO, yang mengontrol campuran antara kebijakan saat ini dan kebijakan referensi sebelumnya selama pembaruan. Kebijakan referensi diperbarui sesuai persamaan: π_ref = α * π_θ + (1 - α) * π_ref_prev. Untuk menggunakan parameter ini, Anda harus mengatur sync_ref_model=True.
  • ref_model_sync_steps (int, opsional, default 512) — parameter τ dari paper TR-DPO, yang menentukan seberapa sering kebijakan saat ini disinkronkan dengan kebijakan referensi. Untuk menggunakan parameter ini, Anda harus mengatur sync_ref_model=True.
  • top_entropy_quantile (float, opsional, default 1.0) — parameter ρ dari Beyond the 80/20 Rule. Menjaga hanya kuantil atas-ρ token berdasarkan entropi distribusi probabilitas pada setiap posisi urutan dalam suku loss kebijakan, sehingga meningkatkan hasil. Rentang: [0.0-1.0]. Nilai 0.0 memmasking semua token kecuali token dengan entropi tertinggi; 1.0 mempertahankan semua token. Kertas tersebut merekomendasikan nilai 0.2. Jika digunakan dengan mask_truncated_completions=True, hanya token dari penyelesaian yang tidak terpotong yang dipertimbangkan.
  • entropy_coef (float, opsional, default 0.0) — Koefisien dari suku regularisasi entropi dalam loss. Nilai positif menambahkan bonus entropi yang mendorong eksplorasi dengan mencegah kebijakan (policy) runtuh ke output yang hampir deterministik. Bonus ini selalu berupa entropi rata-rata per token terlepas dari loss_type; bonus ini tidak diskalakan ulang untuk menyesuaikan normalisasi kebijakan dari tipe loss tertentu, sehingga entropy_coef memiliki makna yang sama untuk setiap tipe loss. Ketika use_adaptive_entropy=True, nilai ini berfungsi sebagai koefisien awal dan diperbarui pada setiap langkah optimizer. Tidak memiliki efek ketika diatur ke 0.0 (default).
  • use_adaptive_entropy (bool, opsional, default False) — Apakah akan menggunakan kontrol entropi adaptif, yang diperkenalkan dalam Skywork-OR1. Saat diaktifkan, koefisien entropi entropy_coef diperbarui pada setiap langkah optimizer: ditambah entropy_coef_delta jika entropi saat ini di bawah entropy_target, dan dikurangi jika tidak. Koefisien ini hanya diterapkan ketika entropi berada pada atau di bawah entropy_target.
  • entropy_coef_min (float, opsional, default 0.0) — Batas bawah untuk koefisien entropi saat menggunakan kontrol entropi adaptif.
  • entropy_coef_max (float, opsional, defaultnya 1.0) — Batas atas untuk koefisien entropi saat menggunakan kontrol entropi adaptif.
  • entropy_coef_delta (float, opsional, default 0.005) — Ukuran langkah untuk menyesuaikan koefisien entropi pada setiap langkah optimizer selama kontrol entropi adaptif.
  • entropy_target (float, opsional, default 0.2) — Target entropi rata-rata per token (dalam nats) yang digunakan oleh kontrol entropi adaptif. Koefisien hanya diterapkan ketika entropi saat ini berada pada atau di bawah nilai ini. Diukur pada set token yang sama dengan policy loss: semua token completion secara default, atau hanya subset entropi tinggi ketika top_entropy_quantile < 1.0. Model bahasa yang tipikal memiliki entropi per token dalam rentang 2–10 nats, sehingga default 0.2 hampir tidak pernah memicu regularisasi (hanya pada kolaps entropi yang hampir sempurna); atur nilainya mendekati entropi yang Anda amati di awal pelatihan (dicatat sebagai metrik entropy) agar bonus aktif sebelum policy kolaps (dan pertimbangkan subset token ketika menggunakan top_entropy_quantile).
  • max_tool_calling_iterations (int, opsional) — Jumlah maksimum giliran pemanggilan alat saat melatih agen. Jika None, tidak ada batas dan generasi berhenti ketika model menghasilkan giliran respons tanpa pemanggilan alat atau ketika panjang total respons mencapai max_model_length.
  • vllm_importance_sampling_correction (bool, opsional, default True) — Apakah Importance Sampling (IS) akan diterapkan untuk mengoreksi ketidakcocokan antara logprobs penyelesaian vLLM dan logprobs pelatihan yang dihitung ulang. Jika diatur ke False, IS tidak diterapkan terlepas dari vllm_importance_sampling_mode. Ketika True, mode yang dipilih menentukan bagaimana rasio IS dihitung dan dibatasi. Dengan top_p < 1, top_k > 0 atau min_p > 0, logprobs yang dihitung ulang dinormalisasi di atas set kandidat tempat setiap token diambil, yang memerlukan vllm_mode="colocate" dan vLLM 0.28 atau lebih baru; jika tidak, rasio IS akan bias. vLLM membatasi set kandidat tersebut dengan top_k, sehingga top_p < 1 dan min_p > 0 memerlukan top_k > 0 (mis. top_k=512). vLLM juga menerapkan repetition_penalty pada logprobs yang dikembalikannya, sehingga repetition_penalty != 1.0 memerlukan vllm_importance_sampling_correction=False.
  • vllm_importance_sampling_mode (str, opsional, defaultnya "sequence_mask") — Menentukan bagaimana Importance Sampling dilakukan ketika vllm_importance_sampling_correction=True. Nilai yang mungkin adalah:
    • "token_truncate": IS terpotong pada level token. Rasio per-token dipangkas ke [C_min, C_max].
    • "token_mask": IS ber-mask pada tingkat token. Rasio per-token di luar [C_min, C_max] diatur menjadi nol.
    • "sequence_truncate": IS terpotong pada level sekuens. Rasio sekuens tunggal dipangkas ke [C_min, C_max] dan diterapkan ke semua token dalam sekuens.
    • "sequence_mask": IS ter-mask pada level sekuens. Sekuens dengan rasio di luar [C_min, C_max] akan di-mask.
  • vllm_importance_sampling_clip_max (float, opsional, default 3.0) — Batas atas importance sampling C_max yang digunakan oleh vllm_importance_sampling_mode. Untuk mode *_truncate, rasio importance dipangkas dari atas pada C_max. Untuk mode *_mask, rasio yang lebih besar dari C_max diatur menjadi nol.
  • vllm_importance_sampling_clip_min (float, opsional) — Batas bawah importance sampling C_min yang digunakan oleh vllm_importance_sampling_mode. Untuk mode *_truncate, rasio dipangkas dari bawah pada C_min. Untuk mode *_mask, rasio di bawah C_min diatur menjadi nol. Untuk secara ketat mem-mask rasio di bawah C_min tanpa batas atas, atur vllm_importance_sampling_clip_max=None.
  • off_policy_mask_threshold (float, opsional) — Ambang batas untuk masking urutan off-policy. Jika None, masking urutan off-policy dinonaktifkan. Ketika diatur, urutan dengan keuntungan negatif dan divergensi KL tinggi akan dimasking untuk menstabilkan pelatihan. Parameter ini berkorespondensi dengan ambang batas delta pada Persamaan 9 dari makalah DeepSeek-V3.2. Parameter ini mengharapkan nilai positif (misalnya, 0.5).
  • use_bias_correction_kl (bool, opsional, default True) — Apakah akan mengalikan suku KL dengan rasio importance sampling, sehingga gradien KL menjadi gradien reverse-KL yang tidak bias, seperti yang dijelaskan dalam makalah DeepSeek-V3.2. Hal ini mengubah gradien KL setiap kali beta != 0, termasuk pada on-policy: rasio tersebut dapat diturunkan (differentiable), sehingga memengaruhi gradien bahkan di tempat nilainya tepat 1. Sifat reverse-KL yang tidak bias berlaku untuk importance_sampling_level="token"; dengan "sequence", bobot level-sekuens disiarkan (broadcast) ke KL per-token.

Parameter yang mengontrol logging

  • log_completions (bool, opsional, default False) — Apakah akan mencatat sampel pasangan (prompt, completion) setiap logging_steps langkah. Jika rich terinstal, sampel tersebut akan dicetak. Jika logging wandb dan/atau trackio diaktifkan, sampel akan dicatat ke wandb dan/atau trackio.
  • log_multimodal (bool, opsional, default True) — Apakah akan mencatat konten multimodal (gambar, video, dll.) bersama dengan kompliti. Nonaktifkan ini untuk mengurangi ukuran log saat menggunakan data multimodal beresolusi tinggi.
  • num_completions_to_print (int, opsional) — Jumlah completion yang dicetak dengan rich. Jika None, semua completion dicatat.
  • log_unique_prompts (bool, opsional, default False) — Apakah akan mencatat prompt unik. Jika True, hanya prompt unik yang dicatat. Jika False, semua prompt dicatat.
  • log_completions_hub_repo (str, opsional) — Repositori Hugging Face Hub untuk menyimpan hasil komplit. Harus berupa nama repositori lengkap seperti 'username/reponame' atau 'orgname/reponame', atau hanya 'reponame' yang mana repositori akan dibuat dalam namespace pengguna Hugging Face yang sedang masuk. Perhatikan bahwa repositori ini akan bersifat publik kecuali Anda mengatur hub_private_repo=True atau pengaturan default organisasi Anda adalah membuat repositori privat.

Parameter yang mengontrol akselerasi generasi yang didukung oleh continuous batching dari transformers

  • use_transformers_continuous_batching (bool, opsional, default False) — Apakah akan menggunakan mesin continuous batching dari transformers untuk menghasilkan kelengkapan. Memerlukan transformers>=5.8.0.
  • transformers_continuous_batching_config (dict, opsional) — Argumen kata kunci untuk ContinuousBatchingConfig.

Parameter yang tidak didukung lagi

  • use_transformers_paged —

    Parameter use_transformers_paged sudah tidak didukung dan akan dihapus pada versi v2.0.0. Gunakan use_transformers_continuous_batching sebagai gantinya.

  • vllm_importance_sampling_cap —

    Parameter vllm_importance_sampling_cap sudah tidak didukung dan akan dihapus pada versi v2.0.0. Gunakan vllm_importance_sampling_clip_max sebagai gantinya.

Kelas konfigurasi untuk GRPOTrainer.

Kelas ini hanya mencakup parameter yang spesifik untuk pelatihan GRPO. Untuk daftar lengkap argumen pelatihan, silakan merujuk ke dokumentasi TrainingArguments. Perhatikan bahwa nilai default dalam kelas ini mungkin berbeda dari yang ada di TrainingArguments.

Dengan HfArgumentParser, kita dapat mengubah kelas ini menjadi argumen argparse yang dapat ditentukan di baris perintah.

Parameter-parameter ini memiliki nilai default yang berbeda dari TrainingArguments:

  • logging_steps: Bawaan adalah 10 alih-alih 500.
  • gradient_checkpointing: Beralih ke True sebagai nilai bawaan, bukan False.
  • bf16: Beralih ke True jika fp16 tidak diatur, alih-alih False.
  • learning_rate: Bawaan adalah 1e-6 alih-alih 5e-5.
Update on GitHub