Chapter 06

训练算法:SFT / DPO / KTO / GRPO

📌 commit b58b1bdswift sft / dpo / rlhf 三个入口

ms-swift 把 TRL 的所有算法包装成 CLI 命令。本章过一遍 SFT / DPO / KTO / GRPO / PPO 的命令和数据格式。

6.1算法 CLI 一图表

算法命令对应底层
SFTswift sftHF Trainer + ms-swift Trainer
DPOswift rlhf --rlhf_type dpoTRL DPOTrainer
KTOswift rlhf --rlhf_type ktoTRL KTOTrainer
ORPOswift rlhf --rlhf_type orpoTRL ORPOTrainer
CPOswift rlhf --rlhf_type cpoTRL CPOTrainer
SimPOswift rlhf --rlhf_type simpoTRL DPOTrainer + simpo loss
RMswift rlhf --rlhf_type rmTRL RewardTrainer
PPOswift rlhf --rlhf_type ppoTRL PPOTrainer
GRPOswift rlhf --rlhf_type grpoTRL GRPOTrainer

6.2DPO

swift rlhf \
    --rlhf_type dpo \
    --model Qwen/Qwen2.5-7B-Instruct \
    --dataset AI-ModelScope/orpo-dpo-mix-40k \
    --train_type lora \
    --num_train_epochs 1 \
    --per_device_train_batch_size 1 --gradient_accumulation_steps 16 \
    --learning_rate 5e-6 \
    --beta 0.1 \
    --max_length 2048 \
    --torch_dtype bfloat16 \
    --deepspeed default-zero2

数据集要求:列 chosenrejected(messages 风格)。

6.3KTO

swift rlhf \
    --rlhf_type kto \
    --model Qwen/Qwen2.5-7B-Instruct \
    --dataset trl-lib/kto-mix-15k \
    --train_type lora \
    --desirable_weight 1.0 \
    --undesirable_weight 1.0 \
    --beta 0.1

KTO 数据只需要 label: bool(thumbs up/down),不要 pair。

6.4GRPO(R1 风格)

swift rlhf \
    --rlhf_type grpo \
    --model Qwen/Qwen2.5-7B-Instruct \
    --dataset AI-ModelScope/MATH-lighteval \
    --train_type lora \
    --num_generations 8 \
    --max_completion_length 1024 \
    --reward_funcs accuracy format \      # ★ 内置 reward fn
    --use_vllm true \
    --vllm_gpu_memory_utilization 0.3 \
    --beta 0.04 \
    --learning_rate 1e-6 \
    --deepspeed default-zero2

ms-swift 内置常用 reward function(数学正确性 / 格式 / 长度),不用自己写代码。

6.5RM 训练

swift rlhf \
    --rlhf_type rm \
    --model Qwen/Qwen2.5-7B-Instruct \
    --dataset AI-ModelScope/llama-3-magpie-pro-300k-filtered \
    --train_type full \
    --num_train_epochs 1 \
    --learning_rate 5e-6 \
    --max_length 4096

6.6PPO(4 模型)

swift rlhf \
    --rlhf_type ppo \
    --model ./sft_output \
    --reward_model ./rm_output \
    --dataset AI-ModelScope/some_prompt_only_dataset \
    --train_type lora \
    --num_ppo_epochs 4 \
    --response_length 512 \
    --kl_coef 0.05 \
    --use_vllm true

6.7选择决策表

场景
有 SFT 数据 → 调指令跟随SFT
有偏好对 → 改善质量DPO
只有 thumbs up/down → 学正例KTO
跳过 SFT、直接对齐ORPO / CPO
追极致 + 有 RMPPO
追推理能力(数学 / 代码)GRPO

6.8常见踩坑

现象处理
DPO loss 不降lr 太大;DPO 该用 5e-6
GRPO advantage NaNgroup 内 reward 全一致;提高 sampling temperature
KTO 训练严重偏向 desirable调小 desirable_weight 或调大 undesirable_weight
RM accuracy 一直 ~0.5数据 chosen/rejected 搞反,或 SFT base 太弱

6.9RLHF 9 算法对应的 Trainer 与 TRL 关系

v4 把 RLHF trainer 拆到 swift/rlhf_trainers/,9 种算法各一文件。所有都"继承 TRL + swift mixin",但深度不一样:

rlhf_typeswift 类TRL 父类swift 改了什么
dpo DPOTrainer(dpo_trainer.py) trl.DPOTrainer PEFT 兼容、loss capping、label smoothing
kto KTOTrainer trl.KTOTrainer SwiftMixin + seq parallel
orpo / cpo同上独立 trainer trl.ORPOTrainer / CPOTrainer同上轻量 mixin
rm RewardTrainer trl.RewardTrainer margin loss / center_rewards
ppo PPOTrainer trl.PPOTrainer 仅薄包装
grpo GRPOTrainer trl.GRPOTrainer 重度定制 ~1400 行:vLLM rollout / 多 reward / seq parallel
gkd GKDTrainer 独立(不走 TRL) 支持本地 / 远程 teacher(vLLM 或 swift deploy)

所有 trainer 共享 RLHFTrainerMixinrlhf_mixin.py:19–183):

6.10GRPO 算法变种 6 个

ms-swift v4 的"GRPO"实际是一个统一 trainer + 6 个算法变种(通过 --algorithm--loss_type 切换)。READMEY 标注的支持矩阵:

算法论文 / 论点关键 flag
GRPO(默认) DeepSeek 原版
DAPO 动态采样 + 非对称 clip + token-level loss + 滤除全对/全错 group --dynamic_sample true--clip_higher 0.27
GSPO 序列级 importance sampling × token-level ratio(TRL ch06.8 详) --loss_type gspo
SAPO sigmoid soft-clip(arXiv:2511.20347) --loss_type sapo
CISPO Clipped IS PPO,rollout IS 直接进 ratio --loss_type cispo
CHORD 2025-09 swift 自家训练算法,结合多种策略 --algorithm chord
RLOO / REINFORCE++无 critic 路径(与 verl / OpenRLHF 互通) --rlhf_type rloo / reinforce

6.11多 reward 源 + 权重(swift 独门)

swift 的 GRPO 比 TRL 原版多了"reward 加权聚合"。看 rlhf_args.py:138–142 的字段:

swift rlhf --rlhf_type grpo \
    --reward_funcs accuracy format external_rm \
    --reward_weights 1.0 0.2 0.5 \
    --external_plugins /my/reward_plugin.py

背后 swift/rewards/ 提供:

6.12这章你需要带走的