TRL documentation

SDPO

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

SDPO

Self-Distillation Policy Optimization(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에서 소개했습니다.

대형 언어 모델은 코드와 수학과 같이 검증이 가능한 도메인에서 강화 학습을 통해 후학습(post-training)되는 경우가 점점 더 많아지고 있습니다. 그러나 검증 가능한 보상(reinforcement learning with verifiable rewards, RLVR)을 사용하는 현재 방법들은 시도당 스칼라 결과 보상만 학습 자료로 활용하여 심각한 크레딧 할당(credit-assignment) 병목을 초래합니다. 많은 검증 가능한 환경은 실제로 시도가 실패한 이유를 설명하는 런타임 오류나 판정 평가와 같은 풍부한 텍스트 피드백을 제공합니다. 우리는 이 설정을 풍부한 피드백을 활용한 강화 학습(reinforcement learning with rich feedback)으로 형식화하고, 외부 교사(teacher)나 명시적인 보상 모델 없이 토큰화된 피드백을 밀집된 학습 신호로 변환하는 Self-Distillation Policy Optimization(SDPO)을 소개합니다. SDPO는 피드백에 조건부화된 현재 모델을 셀프-교사(self-teacher)로 간주하고, 피드백에 기반한 다음 토큰 예측을 정책(policy)으로 증류(distill)합니다. 이를 통해 SDPO는 모델이 컨텍스트 내에서 자신의 실수를 사후적으로 식별하는 능력을 활용합니다. LiveCodeBench v6의 과학적 추론, 도구 사용, 경쟁 프로그래밍에서 SDPO는 강력한 RLVR 베이스라인 대비 샘플 효율성과 최종 정확도를 향상시킵니다. 주목할 점은, SDPO가 실패한 시도에 대해 성공적인 롤아웃(rollout)을 암묵적 피드백으로 활용함으로써 스칼라 피드백만 반환하는 표준 RLVR 환경에서도 베이스라인을 능가한다는 것입니다. 마지막으로, 테스트 시점에 개별 문제에 SDPO를 적용하면 이진 보상(binary-reward)이 주어지는 어려운 작업에서 발견(discovery)을 가속화하여, best-of-k 샘플링이나 다중 턴 대화와 동일한 발견 확률을 3배 적은 시도 수로 달성합니다.

작동 방식

SDPO는 검증 가능한 보상(RLVR)을 통한 강화 학습을 목표로 하며, 이 방식에서는 각 시도가 희소한 스칼라 보상만 생성합니다. 이를 밀집된 토큰 레벨 신호로 변환합니다. 각 프롬프트에 대해 정책이 num_generations개의 완성본을 샘플링하고 reward_funcs로 점수를 매기며, 성공적인 롤아웃(그리고 선택적인 privileged_context 피드백)이 교사 재프롬프트가 됩니다. 이후 교사의 피드백에 기반한 완성본 분포가 정책으로 증류됩니다. 교사와 학생은 동일한 네트워크이므로 검증기 외에 외부 교사나 보상 모델이 필요하지 않습니다.

손실 모드와 교사

distillation_weight는 두 신호가 볼록 조합으로 결합되는 방식을 제어합니다. 손실은 (1 - distillation_weight) * policy_loss + distillation_weight * distillation_loss입니다. 1.0(기본값)은 순수하게 자기 증류 손실로 학습하고, 0.0은 표준 GRPO 스타일의 정책 기울기로 되돌아가며, 중간 값은 두 신호를 혼합합니다. 증류 목적 함수 자체는 distillation_mode로 설정됩니다. "sampled_token"(기본값)은 토큰 수준의 역 KL을 사용하며 distillation_alpha=1.0을 요구합니다. 반면 "full_logits"와 "topk_logits"는 전체 어휘 또는 상위 distillation_topk 어휘에 대해 증류를 수행합니다.

teacher_model_kind은 teacher 가중치를 선택합니다. "ema"(기본값)은 teacher_sync_steps 스텝마다 teacher_update_rate 비율로 동기화되는 지수 이동 평균으로 student를 추적하고, "live"는 현재 student를 그대로 재사용하며, "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는 성공적인 롤아웃을 사용하며, 활성화된 경우 해당 텍스트를 사용하여 자기 증류용 교사 재프롬프트를 구성합니다.

vLLM 서버에서 teacher 서빙

teacher_model_kind="live"를 사용하면 teacher는 현재 student이며, vLLM 서버가 이미 해당 가중치를 보유하고 있습니다(생성을 위해 각 단계에서 동기화됨). use_teacher_server=True를 설정하면 별도의 로컬 teacher forward를 실행하지 않고 동일한 서버에서 teacher log-probabilities를 계산하여, teacher를 학습 단계에서 완전히 제거할 수 있습니다:

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"여야 합니다(서버가 현재 student 가중치를 보유함)
  • distillation_weight은 1.0이어야 합니다(순수 증류; 정책 손실과의 볼록 혼합에는 전체 어휘 로짓이 필요합니다)
  • distillation_mode는 "sampled_token"(실제 토큰에 대한 역 KL) 또는 "topk_logits"여야 합니다. 서버는 teacher의 top-k log-probs를 반환하므로, topk_logits는 teacher의 top-k support에 대해 증류됩니다(로컬 목적 함수와 달리 student의 support를 사용할 수 없음). "live" teacher의 경우 두 support가 거의 일치합니다. full_logits는 사용할 수 없습니다.

콜백

Trainer는 디버깅, 관찰 가능성, 테스트에 유용한 소수의 콜백 훅을 출력합니다. 이러한 훅은 실험적 자기 증류 워크플로우에 대한 실용적인 통합 지점으로 의도되었습니다.

공유된 자기 증류 훅:

  • on_self_distillation_batch_prepared: self-distillation 배치 준비가 완료되면 발생합니다. importance-sampling clipping 입력이 사용 가능한 경우 페이로드에는 prompt_ids, completion_ids, old_per_token_logps가 포함됩니다.
  • on_generation_batch_built: 새로운 버퍼링된 생성 배치(batch)가 생성될 때 발생합니다. 페이로드에는 generate_every와 steps_per_generation가 포함됩니다.

SDPO 전용 훅:

  • on_teacher_context_built: SDPO가 teacher-conditioned 입력을 구성한 후에 발생합니다. 페이로드에는 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 no

SDPOConfig

클래스 trl.experimental.sdpo.SDPOConfig

< >

( 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") — importance sampling 비율이 'token' 수준인지 'sequence' 수준인지 계산할지를 제어합니다. 'token' 은 토큰별 원시 log-probability 비율(토큰당 하나의 가중치)을 유지합니다. 'sequence' 는 유효한 토큰 전체에 걸쳐 log-probability 비율을 평균화하여 시퀀스당 하나의 비율을 생성합니다. GSPO 논문은 시퀀스 수준 샘플링이 종종 더 안정적인 학습과 시퀀스 수준 보상과의 더 나은 정렬을 제공한다고 보여줍니다.
  • reward_weights (list[float], 선택 사항) — 각 보상 함수에 대한 가중치입니다. 보상 함수의 수와 일치해야 합니다. None인 경우, 모든 보상은 1.0의 동일한 가중치로 적용됩니다.
  • scale_rewards (str 또는 bool, 선택 사항, 기본값 "group") — 보상(rewards)의 스케일링 전략을 지정합니다. 지원되는 값은 다음과 같습니다: 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) — Divergence 보간 계수입니다. Sampled-token SDPO는 공식 reverse-KL 설정인 distillation_alpha=1.0을 요구합니다.
  • distillation_mode (Literal["sampled_token", "full_logits", "topk_logits"], 선택 사항, 기본값 "sampled_token") — Distillation 목적 함수 모드입니다. sampled_token은 기본 SDPO 모드이며 distillation_alpha=1.0을 요구합니다.
  • distillation_topk (int, 선택 사항) — logit-level SDPO에 대한 Top-k 근사치입니다. distillation_mode=topk_logits인 경우에만 설정해야 하며, 그 외에는 설정하지 않아야 합니다.
  • distillation_is_clip (float, 선택 사항, 기본값 2.0) — 자기 증류(self-distillation)에서 중요도 샘플링(importance sampling)에 사용되는 클리핑 계수입니다. None을 지정하면 클리핑이 비활성화됩니다.
  • distillation_add_tail (bool, 선택 사항, 기본값 False) — top-k가 아닌 확률 질량에 대한 tail 버킷을 추가할지 여부입니다.

teacher를 제어하는 매개변수

  • teacher_model_kind (str, 선택 사항, 기본값 "ema") — 의미론적 teacher 선택입니다. base는 초기 student를, live는 현재 student를, ema는 지수 평균화된 teacher를 사용합니다.
  • teacher_update_rate (float, 선택 사항, 기본값 0.05) — EMA teacher 동기화에 사용되는 Teacher 업데이트 비율입니다.
  • teacher_sync_steps (int, 선택 사항, 기본값 1) — EMA teacher 모델의 동기화 빈도입니다.

재프롬프팅을 제어하는 매개변수

  • use_successful_as_teacher (bool, 선택 사항, 기본값 True) — 성공적인 롤아웃을 자기 증류(self-distillation)를 위한 암시적 피드백으로 사용합니다.
  • success_reward_threshold (float, 선택 사항, 기본값 1.0) — 롤아웃이 성공적인 데모로 간주되기 위한 최소 보상입니다.
  • dont_reprompt_on_self_success (bool, 선택 사항, 기본값 True) — 모델이 올바른 응답을 생성할 때 재프롬프팅을 건너뜁니다.
  • max_reprompt_len (int, 선택 사항, 기본값 10240) — 자기 증류(self-distillation)에서 재프롬프팅(reprompting)을 위한 최대 길이입니다.
  • reprompt_template (str, 선택 사항, 기본값 "{prompt}{solution}{feedback}\n\nCorrectly solve the original question.\n") — 성공적인 데모를 사용하여 teacher를 다시 프롬프트할 때 사용하는 템플릿.
  • 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) — 사용 가능한 경우, teacher reprompt에 환경 피드백을 포함할지 여부.
  • environment_feedback_only_without_solution (bool, 선택 사항, 기본값 False) — 성공적인 솔루션이 없을 때 피드백만 사용할지 여부입니다.
  • remove_thinking_from_demonstration (bool, 선택 사항, 기본값 False) — 시연 텍스트에서 <think>…</think> 블록을 제거할지 여부.

진단 기능을 제어하는 매개변수

  • diagnostics_warning_interval (int, 선택 사항, 기본값 10) — 연속된 열화 단계 N개마다 반복되는 trainer 진단을 출력합니다. 0으로 설정하면 비활성화됩니다.
  • diagnostics_flat_tolerance (float, 선택 사항, 기본값 1e-8) — 보상 분산 또는 재프롬프트 활동이 실질적으로 0인지 판단하는 데 사용되는 허용 오차입니다.

모델을 제어하는 매개변수

  • model_init_kwargs (dict[str, Any], 선택 사항) — SDPOTrainer의 model 인수가 문자열로 제공될 때 transformers.AutoModelForCausalLM.from_pretrained에 사용되는 키워드 인수입니다. revision 값은 처리 클래스를 로드할 때에도 사용됩니다.
  • trust_remote_code (bool, optional, defaults to False) — Whether to allow loading models and tokenizers that ship custom Python code from the Hub. Forwarded to from_pretrained and from_pretrained. Also applied to reward-model and reward-tokenizer loads.
  • 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) — 생성된 completion의 최대 길이입니다.
  • temperature (float, 선택 사항, 기본값 1.0) — 샘플링에 사용할 온도입니다. 온도가 높을수록 완성 결과가 더 무작위적으로 생성됩니다.
  • top_p (float, 선택 사항, 기본값 1.0) — 고려할 상위 토큰의 누적 확률을 제어하는 값입니다. (0, 1] 범위에 있어야 합니다. 모든 토큰을 고려하려면 1.0으로 설정하세요.
  • top_k (int, 선택 사항, 기본값 0) — top-k-filtering을 위해 유지할 가장 높은 확률의 어휘 토큰 수입니다. 0인 경우 top-k-filtering이 비활성화되고 모든 토큰이 고려됩니다.
  • min_p (float, 선택 사항) — 최소 토큰 확률입니다. 가장 가능성이 높은 토큰의 확률로 스케일링됩니다. 0.0과 1.0 사이의 값이어야 합니다. 일반적인 값은 0.01~0.2 범위입니다.
  • repetition_penalty (float, 선택 사항, 기본값 1.0) — 프롬프트와 지금까지 생성된 텍스트에 해당 토큰이 등장했는지에 따라 새로운 토큰에 페널티를 부과하는 값입니다. 1.0보다 큰 값은 모델이 새로운 토큰을 사용하도록 장려하고, 1.0보다 작은 값은 모델이 토큰을 반복하도록 장려합니다.
  • cache_implementation (str, 선택 사항) — use_vllm이 False로 설정된 경우 더 빠른 생성을 위한 캐시 메서드 구현입니다.
  • generation_kwargs (dict[str, Any], 선택 사항) — completions 샘플링 시 GenerationConfig(transformers 사용 시) 또는 SamplingParams(vLLM 사용 시)에 전달할 추가 키워드 인자입니다. suppress_tokens, num_beams 등을 설정하여 생성 동작을 더 자세히 커스터마이징하는 데 사용할 수 있습니다. 다른 생성 파라미터(min_p, top_p 등)와 충돌하는 키가 포함된 경우, 해당 키가 우선 적용됩니다.
  • chat_template_kwargs (dict[str, Any], 선택) — 완성 결과를 생성할 때 apply_chat_template 함수에 전달할 추가 키워드 인자입니다.
  • ds3_gather_for_generation (bool, 선택 사항, 기본값 True) — 이 설정은 DeepSpeed ZeRO-3에 적용됩니다. 활성화하면 정책 모델 가중치가 생성을 위해 수집되어 생성 속도가 향상됩니다. 그러나 이 옵션을 비활성화하면 단일 GPU의 VRAM 용량을 초과하는 모델을 학습할 수 있지만, 생성 속도가 느려집니다. 이 옵션을 비활성화하면 vLLM 생성과 호환되지 않습니다.

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

  • use_vllm (bool, 선택 사항, 기본값 False) — 완성 결과를 생성하는 데 vLLM을 사용할지 여부입니다. True로 설정하면 트레이너는 기본인 model.generate() 대신 vLLM을 사용하여 생성을 수행합니다. vllm이 설치되어 있어야 합니다.
  • use_teacher_server (bool, 선택 사항, 기본값 False) — 로컬 teacher forward 대신 실행 중인 vLLM generation server에서 teacher logprobs를 계산합니다. teacher_model_kind='live'와 use_vllm=True, vllm_mode='server', distillation_weight=1.0 (순수 distillation), 그리고 distillation_mode가 {‘sampled_token’, ‘topk_logits’}인 경우에만 지원됩니다. (server는 전체 어휘가 아닌 teacher의 top-k logprobs를 반환합니다. topk_logits는 teacher의 자체 top-k support에 대해 distillation을 수행합니다.)
  • 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 sleep mode를 활성화합니다. 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의 tensor parallel size를 제어합니다. 이 설정은 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’: 시퀀스 길이를 기준으로 정규화하여 토큰 수준 손실을 집계합니다. 길이 편향 때문에 권장하지 않습니다. 이 방식은 양의 이점을 가진 짧은 완성 결과와 음의 이점을 가진 긴 완성 결과를 선호하는 경향이 있습니다. ‘dapo’ (기본값): 글로벌 누적 배치 내 활성 토큰 수로 정규화하여 토큰 수준 손실을 집계합니다. 이 방법은 길이 편향을 제거하기 위해 DAPO 논문에서 도입되었습니다. ‘dr_grpo’: 글로벌 상수로 정규화하여 토큰 수준 손실을 집계합니다. 이 방법은 길이 편향을 제거하기 위해 Dr. GRPO 논문에서 도입되었습니다. 상수의 값은 max_completion_length에 해당합니다. ‘bnpo’: 로컬 배치 내 활성 토큰 수로 정규화하여 토큰 수준 손실을 집계합니다. 정규화가 로컬 배치에서만 수행되므로, 유효 배치 크기가 일정하더라도 로컬 배치 크기에 따라 결과가 약간 달라질 수 있습니다. 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) — 활성화하면 잘린(completed) 응답이 손실 계산에서 제외되어, 학습 과정에서 잘못 페널티를 받거나 노이즈가 도입되는 것을 방지합니다. DAPO 논문에 따르면 이는 학습 안정성을 위한 좋은 관행입니다.

experimental.sdpo.SDPOTrainer의 구성 클래스입니다.

SDPOTrainer

클래스 trl.experimental.sdpo.SDPOTrainer

< >

( 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 )

자기 증류 정책 최적화(Self-Distillation Policy Optimization, SDPO)를 위한 Trainer.

SDPO는 모델 자체의 높은 보상 궤적에 대한 자기 증류(self-distillation)를 통해 온-폴리시(on-policy) 최적화를 강화합니다. 이는 외부 교사(teacher)나 명시적인 보상 모델 없이 토큰화된 피드백을 밀집된 학습 신호로 변환합니다. SDPO는 피드백에 조건부화된 현재 모델을 자기 교사로 간주하고, 피드백에 기반한 다음 토큰 예측을 정책(policy)으로 증류합니다.

train

< >

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

매개변수

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

반환값

~trainer_utils.TrainOutput

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

주요 학습 진입점.

save_model

< >

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

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

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

push_to_hub

< >

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

매개변수

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

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

Update on GitHub