TRL documentation
GMPO
GMPO
Trong bài báo Geometric-Mean Policy Optimization, các tác giả đề xuất một biến thể của GRPO, tối đa hóa trung bình nhân của các tỷ lệ quan trọng ở cấp độ token thay vì trung bình cộng. Vì trung bình nhân ít nhạy cảm hơn nhiều với các tỷ lệ ngoại lai, việc cập nhật chính sách sẽ ổn định hơn và cho phép một khoảng cắt (clipping) rộng hơn đáng kể. Việc cắt được áp dụng cho từng token, trong không gian log, và một chiều theo dấu của lợi thế (trust region chuẩn của PPO) — quan trọng là, trước khi lấy trung bình nhân.
Để sử dụng GMPO, bạn có thể dùng lớp experimental.gmpo.GMPOTrainer trong trl.experimental.gmpo.
Cách sử dụng
from trl.experimental.gmpo import GMPOConfig, GMPOTrainer
training_args = GMPOConfig(
epsilon=0.4, # log-space clip range -> ratios clipped to (exp(-0.4), exp(0.4)); paper, Sec. 4
beta=0.0,
)
trainer = GMPOTrainer(
model="Qwen/Qwen3-0.6B",
reward_funcs=...,
train_dataset=...,
args=training_args,
)
trainer.train()Trong GMPO, việc cắt (clipping) được áp dụng cho các tỷ lệ quan trọng theo từng token log (tức là trong không gian log) trước khi lấy trung bình hình học, do đó epsilon và epsilon_high được biểu diễn trong không gian log: phạm vi cắt tỷ lệ hiệu dụng là (exp(-epsilon), exp(epsilon_high)). Bài báo đề xuất một phạm vi rộng hơn đáng kể so với GRPO/DAPO, (exp(-0.4), exp(0.4)), nhằm khuyến khích khám phá.
GMPOTrainer
Trainer cho tối ưu hóa chính trị trung bình hình học (GMPO).
GMPO (https://huggingface.co/papers/2507.20673) là một biến thể của GRPO, tối đa hóa trung bình hình học của các tỷ lệ quan trọng ở cấp độ token thay vì trung bình số học. Do trung bình hình học ít nhạy cảm hơn nhiều với các tỷ lệ ngoại lai, việc cập nhật chính sách sẽ ổn định hơn và có thể sử dụng phạm vi cắt (clipping) rộng hơn rất nhiều.
Điểm khác biệt duy nhất so với GRPOTrainer là _compute_loss. Mọi thứ khác (sinh nội dung, tính phần thưởng, đồng bộ trọng số, ghi log chỉ số) đều được kế thừa không thay đổi
train
< source >( resume_from_checkpoint: str | bool | None = Nonetrial: optuna.Trial | dict[str, Any] | None = Noneignore_keys_for_eval: list[str] | None = None ) → ~trainer_utils.TrainOutput
Tham số
- resume_from_checkpoint (
strhoặcbool, tùy chọn) — Nếu làstr, đường dẫn cục bộ đến một checkpoint đã lưu bởi một phiênTrainertrước đó. Nếu làboolvà bằngTrue, tải checkpoint cuối cùng trong args.output_dir do một phiênTrainertrước đó lưu lại. Nếu có, quá trình huấn luyện sẽ tiếp tục từ trạng thái model/optimizer/scheduler được tải ở đây. - trial (
optuna.Trialhoặcdict[str, Any], tùy chọn) — Lần chạy thử nghiệm hoặc từ điển siêu tham số cho việc tìm kiếm siêu tham số. - ignore_keys_for_eval (
list[str], tùy chọn) — Một danh sách các khóa trong đầu ra của mô hình của bạn (nếu đó là một từ điển) cần được bỏ qua khi thu thập các dự đoán để đánh giá trong quá trình huấn luyện.
Trả về
~trainer_utils.TrainOutput
Đối tượng chứa số bước toàn cục, tổn thất huấn luyện và các chỉ số.
Điểm vào chính cho quá trình huấn luyện.
Sẽ lưu mô hình, để bạn có thể tải lại bằng from_pretrained().
Chỉ lưu từ tiến trình chính.
push_to_hub
< source >( commit_message: str | None = 'End of training'blocking: bool = Truetoken: str | None = Nonerevision: str | None = None**kwargs )
Tham số
- commit_message (
str, tùy chọn, mặc định là"End of training") — Thông điệp để commit khi đẩy lên. - blocking (
bool, tùy chọn, mặc định làTrue) — Xác định xem hàm có chỉ trả về khigit pushđã hoàn tất hay không. - token (
str, tùy chọn, mặc định làNone) — Token có quyền ghi để ghi đè lên các args gốc của Trainer. - revision (
str, tùy chọn) — Phiên bản git để commit từ. Mặc định là đầu của nhánh “main”. - kwargs (
dict[str, Any], tùy chọn) — Các đối số từ khóa bổ sung được truyền đến~Trainer.create_model_card.
Tải self.model và self.processing_class lên 🤗 model hub tại repo self.args.hub_model_id.
GMPOConfig
lớp trl.experimental.gmpo.GMPOConfig
< source >( 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.4delta: 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 )
Tham số
- epsilon (
float, tùy chọn, mặc định là0.4) — Giá trị cắt dưới, biểu diễn trong không gian log. Giới hạn dưới của tỷ lệ quan trọng trên mỗi token làexp(-epsilon). - epsilon_high (
float, tùy chọn) — Giá trị cắt trên, biểu diễn trong không gian log. NếuNone, mặc định bằng giá trị củaepsilon. Giới hạn trên của tỷ lệ quan trọng theo từng token làexp(epsilon_high).
Lớp cấu hình cho experimental.gmpo.GMPOTrainer.
experimental.gmpo.GMPOConfig kế thừa mọi tham số từ GRPOConfig; nó chỉ thay đổi ý nghĩa và giá trị mặc định của khoảng cắt (clipping range). Trong GMPO, việc cắt được áp dụng cho các tỷ lệ quan trọng log trên mỗi token (tức là trong không gian log) trước khi lấy trung bình hình học, do đó epsilon và epsilon_high được biểu diễn trong không gian log: khoảng cắt hiệu dụng của tỷ lệ là (exp(-epsilon), exp(epsilon_high)). Bài báo GMPO khuyến nghị một khoảng rộng hơn đáng kể so với GRPO/DAPO, (exp(-0.4), exp(0.4)), để khuyến khích khám phá.