TRL documentation
SDPO
SDPO
自蒸馏策略优化(SDPO)由 Jonas Hübotter、Frederike Lübeck、Lejs Behric、Anton Baumann、Marco Bagatella、Daniel Marta、Ido Hakimi、Idan Shenfeld、Thomas Kleine Buening、Carlos Guestrin 和 Andreas Krause 在 Reinforcement Learning via Self-Distillation 中提出。
大型语言模型越来越多地在代码和数学等可验证领域通过强化学习进行后训练。然而,当前基于可验证奖励的强化学习(RLVR)方法仅从每次尝试的标量结果奖励中学习,造成了严重的信用分配瓶颈。许多可验证环境实际上提供了丰富的文本反馈,例如运行时错误或评判评估,用以解释某次尝试失败的原因。我们将此场景形式化为基于丰富反馈的强化学习,并提出了自蒸馏策略优化(SDPO),该方法将标记化的反馈转化为密集的学习信号,无需任何外部教师或显式奖励模型。SDPO 将当前模型在反馈条件下的状态视为自教师,并将其基于反馈的下一词元预测蒸馏回策略中。通过这种方式,SDPO 利用了模型在上下文中回顾性识别自身错误的能力。在 LiveCodeBench v6 上的科学推理、工具使用和竞赛编程任务中,SDPO 相较于强大的 RLVR 基线提升了样本效率和最终准确率。值得注意的是,在仅返回标量反馈的标准 RLVR 环境中,SDPO 通过将成功的轨迹作为失败尝试的隐式反馈,同样优于基线方法。最后,在测试时对单个问题应用 SDPO 可以加速在困难二元奖励任务上的发现过程,以 3 倍更少的尝试次数达到了与 best-of-k 采样或多轮对话相同的发现概率。
工作原理
SDPO 针对的是基于可验证奖励的强化学习(RLVR),其中每次尝试仅产生一个稀疏的标量奖励。它将该奖励转化为密集的、token 级别的信号:对于每个提示,策略会采样 num_generations 个由 reward_funcs 评分的补全;一次成功的 rollout(加上可选的 privileged_context 反馈)会成为一个教师重提示,而教师基于反馈对补全的分布会被蒸馏回策略中。由于教师和学生是同一个网络,因此除了验证器之外,无需额外的外部教师或奖励模型。
损失模式与教师
distillation_weight 控制两个信号如何以凸组合的方式融合:损失为 (1 - distillation_weight) * policy_loss + distillation_weight * distillation_loss。1.0(默认值)表示纯粹基于自蒸馏损失进行训练,0.0 则回退到标准的 GRPO 风格策略梯度,中间值则混合两者。蒸馏目标本身由 distillation_mode 设定——"sampled_token"(默认值)使用 token 级别的反向 KL,并要求 distillation_alpha=1.0,而 "full_logits" 和 "topk_logits" 则在整个词表或前 distillation_topk 个词表项上进行蒸馏。
teacher_model_kind 用于选择教师权重:"ema"(默认值)通过指数移动平均跟踪学生模型,每 teacher_sync_steps 步以速率 teacher_update_rate 进行同步;"live" 直接复用当前的学生模型;"base" 则冻结初始权重。重新提示(Reprompting)由 use_successful_as_teacher、success_reward_threshold、dont_reprompt_on_self_success 以及 reprompt_template / solution_template / feedback_template 字符串控制。生成过程默认通过 Transformers 运行,当 use_vllm=True 时则使用 vLLM(colocate 或 server 模式)。
预期的数据集列
每个示例必须提供:
prompt:面向学生的提示privileged_context:可选的特权文本,例如环境反馈,在include_environment_feedback=True时使用
用法
from datasets import Dataset
from trl.experimental.sdpo import SDPOConfig, SDPOTrainer
dataset = Dataset.from_dict(
{
"prompt": [[{"role": "user", "content": "Solve 2+2."}]],
"privileged_context": ["Your earlier answer used the wrong format."],
}
)
training_args = SDPOConfig(
output_dir="sdpo-model",
distillation_mode="topk_logits", # Explicitly select top-K logit distillation
distillation_topk=100, # Required when using top-K logit distillation
include_environment_feedback=True, # Use dataset privileged_context for teacher reprompts
)
trainer = SDPOTrainer(
model="Qwen/Qwen2.5-1.5B-Instruct",
reward_funcs=reward_func,
args=training_args,
train_dataset=dataset,
)
trainer.train()SDPO 始终需要一个 prompt 列。若要使用环境反馈,还需包含一个 privileged_context 列,并设置 include_environment_feedback=True。SDPO 将使用成功的 rollout,并在启用时利用该文本,为自蒸馏构建教师 reprompt。
从 vLLM 服务器提供教师模型
当 teacher_model_kind="live" 时,教师模型即为当前的学生模型,其权重已由 vLLM 服务器 持有(每步生成时都会同步)。设置 use_teacher_server=True 可在同一服务器上计算教师对数概率,而无需运行单独的本地教师前向传播,从而将教师模型完全从训练步骤中移除:
training_args = SDPOConfig(
output_dir="sdpo-model",
use_vllm=True,
vllm_mode="server",
teacher_model_kind="live",
use_teacher_server=True,
distillation_weight=1.0,
distillation_mode="sampled_token",
)使用教师服务器时:
use_vllm=True和vllm_mode="server"是必需的teacher_model_kind必须为"live"(服务器持有当前的学生模型权重)distillation_weight必须为1.0(纯蒸馏;与策略损失的凸组合需要完整的词表 logits)distillation_mode必须为"sampled_token"(对已实现的 token 计算反向 KL)或"topk_logits"。服务器返回教师模型自身的 top-k 对数概率,因此topk_logits是在教师模型的 top-k 支撑集上进行蒸馏(与本地目标函数不同,它无法使用学生模型的支撑集);当使用"live"教师模型时,这两个支撑集几乎重合。full_logits不可用。
回调
Trainer 会触发一组用于调试、可观测性和测试的回调钩子。这些钩子旨在作为实验性自蒸馏工作流的实用集成点。
共享自蒸馏钩子:
on_self_distillation_batch_prepared:当自蒸馏批次准备就绪时触发。当重要性采样裁剪输入可用时,负载包括prompt_ids、completion_ids和old_per_token_logps。on_generation_batch_built:当创建新的缓冲生成批次时触发。负载包括generate_every和steps_per_generation。
SDPO 专用钩子:
on_teacher_context_built:在 SDPO 构建教师条件输入后触发。负载包括teacher_input_ids、teacher_attention_mask、completion_mask和self_distillation_mask。
示例脚本
使用 examples/sdpo_math/sdpo_math.py 从命令行启动 SDPO 训练。该脚本支持可验证的数学奖励、通过 --feedback_column 提供的环境反馈,以及通过标准 ModelConfig 标志实现的 PEFT/LoRA。
python examples/sdpo_math/sdpo_math.py \
--model_name_or_path Qwen/Qwen2.5-Math-1.5B-Instruct \
--dataset_name openai/gsm8k \
--dataset_config main \
--output_dir outputs/sdpo-qwen35-2b-gsm8k \
--learning_rate 5e-5 \
--dtype bfloat16 \
--bf16 true \
--max_completion_length 128 \
--use_peft \
--lora_target_modules q_proj k_proj v_proj o_proj gate_proj up_proj down_proj \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 2 \
--num_generations 8 \
--generation_batch_size 32 \
--distillation_alpha 1.0 \
--distillation_mode sampled_token \
--distillation_weight 0.5 \
--report_to none \
--eval_strategy steps \
--eval_steps 1000 \
--save_strategy noSDPOConfig
类 trl.experimental.sdpo.SDPOConfig
< source >( output_dir: str | None = Noneper_device_train_batch_size: int = 8num_train_epochs: float = 3.0max_steps: int = -1learning_rate: float = 5e-05lr_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 = 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] | None = Nonetrust_remote_code: bool = Falsedisable_dropout: bool = Truemax_prompt_length: int | None = 512num_generations: int = 8num_generations_eval: int | None = Nonemax_completion_length: int | None = 256ds3_gather_for_generation: bool = Trueshuffle_dataset: bool = Truegeneration_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, typing.Any] | None = Nonechat_template_kwargs: dict[str, typing.Any] | None = Nonerepetition_penalty: float = 1.0cache_implementation: str | None = Noneuse_vllm: bool = Falseuse_teacher_server: bool = Falsevllm_mode: str = 'colocate'vllm_model_impl: str = 'vllm'vllm_enable_sleep_mode: bool = Falsevllm_server_base_url: str | None = Nonevllm_server_host: str = '0.0.0.0'vllm_server_port: int = 8000vllm_group_port: int = 51216vllm_server_timeout: float = 240.0vllm_tensor_parallel_size: int = 1vllm_gpu_memory_utilization: float = 0.3vllm_max_model_length: int | None = Nonenum_iterations: int = 1loss_type: str = 'dapo'mask_truncated_completions: bool = Falsedont_reprompt_on_self_success: bool = Truebeta: float = 0.0epsilon: float = 0.2epsilon_high: float | None = Noneimportance_sampling_level: str = 'token'reward_weights: list[float] | None = Nonescale_rewards: str = 'group'distillation_alpha: float = 1.0distillation_mode: typing.Literal['sampled_token', 'full_logits', 'topk_logits'] = 'sampled_token'distillation_topk: int | None = Nonedistillation_is_clip: float | None = 2.0distillation_add_tail: bool = Falsedistillation_weight: float = 1.0teacher_model_kind: str = 'ema'teacher_update_rate: float = 0.05teacher_sync_steps: int = 1max_reprompt_len: int = 10240use_successful_as_teacher: bool = Truesuccess_reward_threshold: float = 1.0reprompt_template: str = '{prompt}{solution}{feedback}\n\nCorrectly solve the original question.\n'solution_template: str = '\nCorrect solution:\n\n{successful_previous_attempt}\n\n'feedback_template: str = '\nThe following is feedback from your unsuccessful earlier attempt:\n\n{feedback_raw}\n\n'include_environment_feedback: bool = Falseenvironment_feedback_only_without_solution: bool = Falseremove_thinking_from_demonstration: bool = Falsediagnostics_warning_interval: int = 10diagnostics_flat_tolerance: float = 1e-08 )
控制在线策略目标的参数
- beta (
float,可选,默认为0.0) — KL 系数。如果为0.0(默认值),则不会加载参考模型,从而减少内存占用并提高训练速度。DeepSeek-R1 incentivizes reasoning in LLMs through reinforcement learning 使用0.001的值。 - epsilon (
float, 可选, 默认为0.2) — 用于裁剪的 Epsilon 值。 - epsilon_high (
float, 可选) — 用于裁剪的上限 epsilon 值。如果未指定,则默认与参数epsilon中指定的下限值相同。DAPO 论文推荐0.28。 - importance_sampling_level (
str, 可选, 默认为"token") — 控制重要性采样比率是在'token'还是'sequence'级别上计算。'token'保留原始的逐 token 对数概率比率(每个 token 一个权重)。'sequence'则对有效 token 的对数概率比率取平均,从而为每个序列生成一个比率。GSPO 论文表明,序列级采样通常能带来更稳定的训练,并与序列级奖励更好地对齐。 - reward_weights (
list[float], 可选) — 每个奖励函数的权重。必须与奖励函数的数量相匹配。如果为None,则所有奖励的权重均相等,权重为1.0。 - scale_rewards (
str或bool,可选,默认为"group") — 指定奖励的缩放策略。支持的值为:True或'group'(默认):奖励按每个组内的标准差进行缩放,确保组内具有单位方差。'batch': 奖励按整个批次的标准差进行缩放,如 PPO Lite 论文所建议。False或'none':不应用任何缩放。Dr. GRPO 论文建议不对奖励进行缩放,因为按标准差缩放会引入问题级别的难度偏差。
控制 SDPO 损失的参数
- distillation_weight (
float,可选,默认为1.0) — 策略目标与自蒸馏目标之间的凸组合权重。损失函数为(1 - distillation_weight) * policy_loss + distillation_weight * distillation_loss。取值必须在[0, 1]范围内。1.0(默认值)表示纯粹基于自蒸馏进行训练,0.0则回退到标准的 GRPO 风格策略梯度, 中间值则对两者进行混合。 - distillation_alpha (
float,可选,默认为1.0) — 散度插值系数。采样 token 的 SDPO 需要官方反向 KL 设置distillation_alpha=1.0。 - distillation_mode (
Literal["sampled_token", "full_logits", "topk_logits"],可选,默认为"sampled_token") — 蒸馏目标模式。sampled_token是默认的 SDPO 模式,并且要求distillation_alpha=1.0。 - distillation_topk (
int, 可选) — logit 级别 SDPO 的 Top-k 近似。当distillation_mode=topk_logits时必须设置,否则保持未设置。 - distillation_is_clip (
float,可选,默认为2.0) — 自蒸馏中重要性采样的截断系数。None表示禁用截断。 - distillation_add_tail (
bool,可选,默认为False) — 是否为非 top-k 概率质量添加尾部桶。
控制 teacher 的参数
- teacher_model_kind (
str, 可选, 默认为"ema") — 语义教师选择。base使用初始学生模型,live使用当前学生模型,ema使用指数移动平均教师模型。 - teacher_update_rate (
float,可选,默认为0.05) — 用于 EMA 教师同步的教师更新率。 - teacher_sync_steps (
int, 可选, 默认为1) — 同步 EMA 教师模型的频率。
控制重新提示的参数
- use_successful_as_teacher (
bool,可选,默认为True) — 将成功的 rollout 用作自蒸馏的隐式反馈。 - success_reward_threshold (
float,可选,默认为1.0) — 一次 rollout 被视为成功演示所需的最低奖励。 - dont_reprompt_on_self_success (
bool,可选,默认为True) — 当模型生成正确响应时,跳过重新提示。 - max_reprompt_len (
int,可选,默认为10240) — 自蒸馏中重新提示的最大长度。 - reprompt_template (
str,可选,默认为"{prompt}{solution}{feedback}\n\nCorrectly solve the original question.\n") — 用于向教师模型重新提示成功演示的模板。 - solution_template (
str,可选,默认为"\nCorrect solution -- \n\n{successful_previous_attempt}\n\n"):用于格式化成功演示文本的模板。 - feedback_template (
str,可选,默认为"\nThe following is feedback from your unsuccessful earlier attempt -- \n\n{feedback_raw}\n\n"):用于格式化环境反馈以进行重新提示的模板。 - include_environment_feedback (
bool,可选,默认为False) — 当可用时,是否在教师重新提示中包含环境反馈。 - environment_feedback_only_without_solution (
bool,可选,默认为False) — 是否仅在无成功解决方案时使用反馈。 - remove_thinking_from_demonstration (
bool,可选,默认为False) — 是否从演示文本中移除 <think>…</think> 块。
控制诊断的参数
- diagnostics_warning_interval (
int,可选,默认为10) — 每连续 N 个退化步骤后输出一次重复的训练器诊断信息。设置为 0 可禁用此功能。 - diagnostics_flat_tolerance (
float,可选,默认为1e-8) — 用于判断奖励方差或 reprompt 活动是否实际上为零的容差值。
控制模型的参数
- model_init_kwargs (
dict[str, Any], 可选) —transformers.AutoModelForCausalLM.from_pretrained的关键字参数,当SDPOTrainer的model参数以字符串形式提供时使用。revision值在加载处理类时也会用到。 - trust_remote_code (
bool,可选,默认为False) — 是否允许加载包含自定义 Python 代码的模型和分词器。此参数会传递给 from_pretrained 和 from_pretrained。 同样适用于奖励模型和奖励分词器的加载。 - disable_dropout (
bool,可选,默认为True) — 是否禁用模型中的 dropout。这在配合参考模型进行训练时非常有用,因为它可以防止模型对相同的输入生成不同的 logprobs。
控制数据预处理的参数
- remove_unused_columns (
bool,可选,默认为False) — 是否仅保留数据集中的 ‘prompt’ 列。如果您使用的自定义奖励函数需要 ‘prompts’ 和 ‘completions’ 以外的任何列,则应保持此参数为False。 - max_prompt_length (
int,可选,默认为512) — 最大提示长度。较长的提示将从左侧截断。 - shuffle_dataset (
bool,可选,默认为True) — 是否打乱训练数据集。
控制生成的参数
- num_generations (
int,可选,默认为8) — 要采样的生成数量。有效批大小(num_processes per_device_batch_size gradient_accumulation_steps)必须能被该值整除。 - num_generations_eval (
int, 可选) — 评估期间采样的生成数量。这允许在评估期间使用更少的生成数量以节省计算资源。如果为None,则使用num_generations的值。 - max_completion_length (
int,可选,默认为256) — 生成补全的最大长度。 - temperature (
float,可选,默认为1.0) — 用于采样的温度。温度越高,生成的补全内容越随机。 - top_p (
float,可选,默认为1.0) — 用于控制所考虑的前几个 token 的累积概率的浮点数。取值必须在 (0, 1] 范围内。设置为 1.0 表示考虑所有 token。 - top_k (
int,可选,默认为0) — 用于 top-k 过滤时保留的最高概率词汇表 token 数量。如果为0,则禁用 top-k 过滤,并考虑所有 token。 - min_p (
float, 可选) — 最小 token 概率,该值会按最可能 token 的概率进行缩放。它必须是 0.0 到 1.0 之间的值。典型值在 0.01 到 0.2 范围内。 - repetition_penalty (
float,可选,默认为1.0) — 一个浮点数,根据新 token 是否出现在提示词和迄今为止生成的文本中来对其进行惩罚。 值 > 1.0 会鼓励模型使用新的 token,而值 < 1.0 会鼓励模型重复使用 token。 - cache_implementation (
str, 可选) — 当 use_vllm 设置为 False 时,用于加速生成的缓存方法实现。 - generation_kwargs (
dict[str, Any], 可选) — 在采样补全时传递给GenerationConfig(如果使用 transformers)或SamplingParams(如果使用 vLLM)的额外关键字参数。可用于进一步自定义生成行为,例如设置suppress_tokens、num_beams等。如果其中包含与其他生成参数(如min_p、top_p等)冲突的键,则会覆盖它们。 - chat_template_kwargs (
dict[str, Any], 可选) — 在生成补全时传递给apply_chat_template函数的其他关键字参数。 - ds3_gather_for_generation (
bool,可选,默认为True) — 此设置适用于 DeepSpeed ZeRO-3。如果启用,策略模型权重将在生成时进行聚合,从而提升生成速度。但是,禁用此选项允许训练超出单个 GPU 显存容量的模型,代价是生成速度变慢。禁用此选项与 vLLM 生成不兼容。
控制由 vLLM 驱动的生成加速的参数
- use_vllm (
bool,可选,默认为False) — 是否使用 vLLM 来生成补全。如果设置为True,训练器将使用 vLLM 进行生成,而不是默认的 model.generate()。需要安装vllm。 - use_teacher_server (
bool,可选,默认为False) — 从正在运行的 vLLM 生成服务器计算教师 logprobs,而不是通过本地教师前向传播。仅支持teacher_model_kind='live'且use_vllm=True、vllm_mode='server'、distillation_weight=1.0(纯蒸馏),以及distillation_mode为 {‘sampled_token’, ‘topk_logits’} 的情况(服务器返回的是教师的 top-k logprobs,而非完整词表;topk_logits在教师自身的 top-k 支撑集上进行蒸馏)。 - vllm_mode (
str, 可选,默认为"colocate") — 当use_vllm设置为True时,用于 vLLM 集成的模式。必须是'server'或'colocate'之一。'server':训练器将生成请求发送到独立的 vLLM 服务器。请确保 vLLM 服务器正在运行(使用vllm serve启动)。'colocate':vLLM 将在同一进程中运行并共享 训练 GPU。这避免了单独服务器的需求,但可能会与训练产生资源争用。 - vllm_model_impl (
str,可选,默认为"vllm") — 用于 vLLM 的模型实现。必须是transformers或vllm之一。transformers:使用transformers后端作为模型实现。vllm:使用vllm库作为模型实现。 - vllm_enable_sleep_mode (
bool,可选,默认为False) — 启用 vLLM 睡眠模式,以便在优化器步骤期间卸载权重/缓存。这可以保持较低的 GPU 内存占用,但唤醒引擎会增加主机与设备之间的传输延迟。 - vllm_server_base_url (
str, 可选) — vLLM 服务器的基础 URL(例如 ‘http://localhost:8000’)。如果提供此参数,vllm_server_host和vllm_server_port将被忽略。 - vllm_server_host (
str,可选,默认为"0.0.0.0") — 要连接的 vLLM 服务器的主机地址。如果提供了 vllm_server_base_url,则忽略此参数。 - vllm_server_port (
int, 可选, 默认为8000) — 要连接的 vLLM 服务器端口。如果提供了 vllm_server_base_url,则忽略此参数。 - vllm_group_port (
int, 可选,默认为51216) — 权重更新组的端口号。用于与 vLLM 服务器通信。除非端口被占用,否则无需更改。 - vllm_server_timeout (
float, 可选, 默认值为240.0) — 等待 vLLM 服务器启动的总超时时间(秒)。如果超时后服务器仍未启动,则会引发ConnectionError。 - vllm_tensor_parallel_size (
int,可选,默认为1) — 控制 vLLM 的张量并行大小。此设置仅在vllm_mode设置为'colocate'时生效。如果您使用的是vllm_mode='server',则必须在通过--vllm_tensor_parallel_size标志启动 vLLM 服务器时单独传递此参数。 - vllm_gpu_memory_utilization (
float,可选,默认值为0.3) — 控制 vLLM 的 GPU 内存利用率。此设置仅在vllm_mode设置为'colocate'时生效。如果您使用的是vllm_mode='server',则必须在通过--vllm_gpu_memory_utilization标志启动 vLLM 服务器时单独传递此参数。 - vllm_max_model_length (
int, 可选) — vLLM 的上下文窗口。请将其设置为至少等于数据集中的最大提示长度加上max_completion_length;如果省略,则从模型配置中推断。
控制训练的参数
- loss_type (
str, 可选, 默认为"dapo") — 指定要使用的损失函数形式。支持的值为 ‘grpo’、‘bnpo’、‘dr_grpo’ 和 ‘dapo’。‘grpo’: 通过对序列长度进行归一化来聚合 token 级别的损失。由于存在长度偏差,不推荐此方法——该方法倾向于偏好具有正优势值的较短补全和具有负优势值的较长补全。‘dapo’(默认):通过全局累积批次中活跃 token 的数量对 token 级别的损失进行归一化以进行聚合。该方法在 DAPO 论文中提出,旨在消除长度偏差。 ‘dr_grpo’:通过一个全局常数对 token 级别的损失进行归一化以进行聚合。该方法在 Dr. GRPO 论文中提出,旨在消除长度偏差。该常数的值对应于max_completion_length。‘bnpo’:通过本地批次中活跃 token 的数量对 token 级别的损失进行归一化以进行聚合。请注意,归一化仅在本地批次上进行,因此尽管有效批次大小恒定,结果仍可能因本地批次大小不同而略有差异。当使用per_device_train_batch_size==1时,损失等同于 GRPO 损失。 - num_iterations (
int,可选,默认为1) — 每个批次的迭代次数(在算法中记为 μ)。 - generation_batch_size (
int, 可选) — 用于生成的批大小。如果为None,则默认为有效训练批大小:per_device_train_batch_size * num_processes * steps_per_generation。 - steps_per_generation (
int,可选) — 每次生成的步数。如果为None,则默认为gradient_accumulation_steps。 - mask_truncated_completions (
bool,可选,默认为False) — 启用后,被截断的补全内容将被排除在损失计算之外,从而避免其受到错误惩罚并在训练过程中引入噪声。根据 DAPO 论文,这是保证训练稳定性的良好实践。
SDPOTrainer
类 trl.experimental.sdpo.SDPOTrainer
< source >( model: typing.Union[str, transformers.modeling_utils.PreTrainedModel, torch.nn.Module]reward_funcs: typing.Any | list[typing.Any] | None = Noneargs: trl.experimental.sdpo.sdpo_config.SDPOConfig | None = Nonetrain_dataset: datasets.arrow_dataset.Dataset | datasets.iterable_dataset.IterableDataset | None = Noneeval_dataset: datasets.arrow_dataset.Dataset | datasets.iterable_dataset.IterableDataset | 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)peft_config = None )
用于自蒸馏策略优化(SDPO)的 Trainer。
SDPO 通过从模型自身的高奖励轨迹中进行自蒸馏,来增强在线策略优化。它将标记化的反馈转化为密集的学习信号,无需任何外部教师模型或显式的奖励模型。SDPO 将基于反馈的当前模型视为自教师,并将其受反馈影响的下一词元预测蒸馏回策略中。
训练
< 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
参数
- resume_from_checkpoint (
str或bool,可选) — 如果为str,则为之前Trainer实例保存的检查点的本地路径。如果为bool且等于True,则加载之前Trainer实例保存在 args.output_dir 中的最后一个检查点。如果存在,训练将从此处加载的模型/优化器/调度器状态中恢复。 - trial (
optuna.Trial或dict[str, Any],可选) — 用于超参数搜索的试验运行或超参数字典。 - ignore_keys_for_eval (
list[str],可选) — 在训练期间收集预测结果以进行评估时,应忽略的模型输出(如果输出是字典)中的键列表。
返回值
~trainer_utils.TrainOutput
包含全局步数、训练损失和指标的 Object。
主要训练入口。
将保存模型,以便您可以使用 from_pretrained() 重新加载它。
仅从主进程保存。
push_to_hub
< source >( commit_message: str | None = 'End of training'blocking: bool = Truetoken: str | None = Nonerevision: str | None = None**kwargs )
将 self.model 和 self.processing_class 上传到 🤗 模型库中的仓库 self.args.hub_model_id。