Skip to content

필사 모드: 从 DPO 到 KTO:人类反馈对齐技术最新论文综述与实战实现

中文
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
从 DPO 到 KTO:人类反馈对齐技术最新论文综述与实战实现

为什么需要 RLHF 之后的对齐技术

让 LLM 与人类偏好对齐的工作,也就是对齐(alignment),自 ChatGPT 以来已成为所有生产环境 LLM 的必备流水线。OpenAI 在 InstructGPT(Ouyang 等,2022,arxiv:2203.02155)中确立的 RLHF(Reinforcement Learning from Human Feedback,基于人类反馈的强化学习)流水线由三个阶段组成:通过 SFT(Supervised Fine-Tuning,监督微调)植入基础能力,单独训练奖励模型(Reward Model),再用 PPO(Proximal Policy Optimization,近端策略优化)优化策略。

这套三阶段流水线虽然强大,但运营成本很高。训练奖励模型需要额外的 GPU 资源,而在 PPO 训练时,需要把策略模型(policy model)、参考模型(reference model)、奖励模型(reward model)、价值模型(value model)这四个模型同时载入内存。以 70B 模型为准,至少需要 8 张以上的 A100 80GB。训练稳定性也是个问题。PPO 的裁剪比例、KL 惩罚系数、GAE lambda 等敏感超参数众多,很少能一次性收敛。

从 2023 年下半年开始,大幅降低这种复杂性的研究相继涌现。DPO 证明了无需奖励模型即可直接从偏好数据优化策略,IPO 指出了 Bradley-Terry 假设的风险,KTO 证明了无需成对(pairwise)偏好数据、仅凭二元信号即可完成对齐。2024-2025 年间,SimPO、ORPO、GRPO 等相继登场,对齐技术的选择迅速扩展。

本文将综述从 RLHF 到 DPO、IPO、KTO 以及最新技术的相关论文,并介绍基于 Hugging Face TRL 库的实战实现代码、超参数调优策略、失败案例与恢复流程。

RLHF 流水线的结构与局限

三阶段流水线详解

用公式梳理 RLHF 的整体流程如下。

第 1 阶段——SFT:用高质量的 instruction-response 数据对 base model 进行微调。

第 2 阶段——训练 Reward Model:针对同一 prompt 生成两个响应,由人类评估者标注出更受偏好的响应(chosen)和不受偏好的响应(rejected)。基于 Bradley-Terry 模型训练奖励函数 r(x, y)。

L_RM = -E[log sigma(r(x, y_w) - r(x, y_l))]

这里 y_w 是 chosen 响应,y_l 是 rejected 响应。

第 3 阶段——PPO 优化:在最大化奖励模型分数的同时,用与参考策略之间的 KL 散度加以约束。

max E[r(x, y)] - beta * KL(pi_theta || pi_ref)

RLHF 的实务局限

局限说明
内存成本需同时加载 Policy、Reference、Reward、Value 共 4 个模型
训练不稳定PPO 裁剪、KL 系数、learning rate 等敏感超参数众多
Reward hacking策略可能学会利用奖励模型的弱点
数据成本收集成对比较数据需要人类评估者成本
可复现性即使设置相同,结果也会因 seed 而大幅变化

这些局限,正是 DPO 等 RL-free 对齐技术出现的背景。

DPO:无需奖励模型的直接偏好优化

核心论文综述

Direct Preference Optimization: Your Language Model is Secretly a Reward Model(Rafailov 等,2023,NeurIPS 2023,arxiv:2305.18290)

DPO 的核心洞察很简洁。RLHF 的奖励函数优化问题存在 closed-form 解,利用这一点,无需显式训练奖励模型,也能直接从偏好数据优化策略。

RLHF 的最优策略具有以下形式:

pi*(y|x) = (1/Z(x)) * pi_ref(y|x) * exp(r(x, y) / beta)

反过来求解,就可以把奖励函数表示为策略的比值:

r(x, y) = beta * log(pi_theta(y|x) / pi_ref(y|x)) + beta * log Z(x)

把这一关系代入 Bradley-Terry 模型,Z(x) 项会被抵消,从而推导出最终的 DPO 损失函数:

L_DPO = -E[log sigma(beta * (log(pi_theta(y_w|x)/pi_ref(y_w|x)) - log(pi_theta(y_l|x)/pi_ref(y_l|x))))]

重要的一点是,DPO 并不是"去除"了奖励模型,而是"隐式地包含"了它。由于策略本身兼任了奖励模型的角色,单独的奖励模型训练与 PPO 阶段就变得不再必要。

DPO 的优点与局限

优点:实现简单。由于形式与 cross-entropy loss 类似,几乎可以用和 SFT 相同的训练代码来实现。内存占用也只需要 policy + reference 两个模型,约为 RLHF 的一半。使用 Hugging Face TRL 的 DPOTrainer,几十行代码就能搭建起整条流水线。

局限:DPO 依赖 Bradley-Terry 模型的假设。人类的偏好未必总是遵循这一模型。此外,若不经过 SFT 直接对 base model 应用 DPO,据报告会出现响应变得冗长(rambling)或幻觉(hallucination)增多的现象。chosen/rejected 成对数据的质量若偏低,训练可能无法收敛,性能甚至可能反而下降。

基于 TRL 的 DPO 实现

from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import DPOConfig, DPOTrainer

# 1. 加载模型与分词器
model_name = "Qwen/Qwen2.5-1.5B-Instruct"
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="bfloat16")
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 2. 加载偏好数据(prompt, chosen, rejected 结构)
dataset = load_dataset("trl-lib/ultrafeedback_binarized", split="train[:5000]")

# 3. DPO 训练配置
training_args = DPOConfig(
    output_dir="./dpo-qwen2.5-1.5b",
    per_device_train_batch_size=2,
    gradient_accumulation_steps=8,
    learning_rate=5e-7,       # DPO 必须使用非常低的 learning rate
    beta=0.1,                 # KL 约束强度
    max_length=1024,
    max_prompt_length=512,
    num_train_epochs=1,
    bf16=True,
    logging_steps=10,
    save_strategy="steps",
    save_steps=500,
    warmup_ratio=0.1,
    gradient_checkpointing=True,
)

# 4. 创建 DPO Trainer 并训练
trainer = DPOTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset,
    processing_class=tokenizer,
)
trainer.train()
trainer.save_model("./dpo-qwen2.5-1.5b-final")

上面代码中最重要的超参数是 betalearning_rate。beta 过高,模型会过度靠近 reference model,对齐效果就会不明显;beta 过低,策略又会变得不稳定。learning rate 通常要设置为比 SFT 低 10 倍以上。

IPO:Bradley-Terry 假设的风险

核心论文综述

A General Theoretical Paradigm to Understand Learning from Human Preferences(Azar 等,2024,AISTATS 2024,arxiv:2310.12036)

IPO(Identity Preference Optimization)对 DPO 的核心假设——Bradley-Terry 模型——提出了质疑。Bradley-Terry 模型把成对偏好转换为 pointwise 的奖励值,IPO 的核心主张是:这一转换过程会造成信息损失,并提高过拟合(overfitting)的风险。

IPO 提出了一个更通用的框架 PsiPO(Psi-Preference Optimization),并将使用 identity function 的特殊情形推导为 IPO。IPO 的损失函数如下:

L_IPO = E[(log(pi_theta(y_w|x)/pi_ref(y_w|x)) - log(pi_theta(y_l|x)/pi_ref(y_l|x)) - 1/(2*beta))^2]

与 DPO 使用 log-sigmoid 不同,IPO 使用的是 squared loss。这一差异提升了模型对过拟合的鲁棒性。在 DPO 中,优化可能朝着把 chosen 概率无限提高、rejected 概率无限降低的方向进行,而在 IPO 中,优化被约束在收敛到一个 target margin(1/2beta)上。

IPO 推荐的 beta 值约为 0.01,比 DPO 的推荐值(0.1〜0.5)低得多。这是因为 IPO 的 loss 结构与 DPO 有本质区别,两者不应使用相同的 beta 值。

KTO:无需成对数据、仅凭二元信号完成对齐

核心论文综述

KTO: Model Alignment as Prospect Theoretic Optimization(Ethayarajh & Jurafsky,2024,ICML 2024,arxiv:2402.01306)

KTO 最大的创新在于数据需求的变化。DPO 和 IPO 都需要针对同一 prompt 的 chosen/rejected 成对数据,而 KTO 只需要针对单个响应的二元标签("好"或"差")即可。这在实务中造成了巨大差异,因为收集成对比较数据的成本,是二元标注的 5〜10 倍。

KTO 的理论基础是 Kahneman 与 Tversky 的展望理论(Prospect Theory)。它把人类对损失比对收益更敏感这一损失厌恶(loss aversion)现象,直接反映进了对齐的目标函数中。

KTO 提出了 HALO(Human-Aware Loss Objective)框架,并说明现有对齐技术其实隐式地包含了展望理论中的偏差。其分析认为,DPO 的成功部分也是因为反映了这类人类认知偏差。

KTO 的损失函数对 desirable 响应和 undesirable 响应做了非对称定义:

L_KTO = E_desirable[1 - sigma(beta * (log(pi/pi_ref) - z_ref))]
      + lambda * E_undesirable[1 - sigma(beta * (z_ref - log(pi/pi_ref)))]

这里 z_ref 是 KL 散度的估计值,lambda 是损失厌恶系数(默认约为 1.33,源自展望理论的实验结果)。

KTO 的实验结果

从 1B 到 30B 规模,KTO 都表现出与 DPO 相当或更优的性能。尤其是在不经过 SFT、直接应用于 base model 的情况下,DPO 中出现的 rambling 现象在 KTO 中并未出现。这被解读为,KTO 的非对称 loss 结构对不良响应施加了更强的惩罚。

基于 TRL 的 KTO 实现

from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl.experimental.kto import KTOConfig, KTOTrainer

# 1. 加载模型
model_name = "Qwen/Qwen2.5-1.5B-Instruct"
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="bfloat16")
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 2. 加载 KTO 数据(prompt, completion, label 结构)
# label: True(desirable) / False(undesirable)
dataset = load_dataset("trl-lib/kto-mix-14k", split="train")

# 3. KTO 训练配置
training_args = KTOConfig(
    output_dir="./kto-qwen2.5-1.5b",
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    learning_rate=5e-7,
    beta=0.1,                       # KL 约束强度
    desirable_weight=1.0,           # desirable 响应的权重
    undesirable_weight=1.0,         # undesirable 响应的权重
    max_length=1024,
    max_prompt_length=512,
    num_train_epochs=1,
    bf16=True,
    logging_steps=10,
    gradient_checkpointing=True,
)

# 4. 创建 KTO Trainer 并训练
trainer = KTOTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset,
    processing_class=tokenizer,
)
trainer.train()
trainer.save_model("./kto-qwen2.5-1.5b-final")

KTO 数据格式的核心在于,它使用的是单个响应的标签,而不是成对数据。如果你已经在收集 thumbs-up/thumbs-down 反馈,无需任何数据转换即可直接用于 KTO 训练。

最新对齐技术:SimPO、ORPO、GRPO

SimPO(Simple Preference Optimization)

SimPO: Simple Preference Optimization with a Reference-Free Reward(Meng 等,2024,arxiv:2405.14734)

SimPO 完全去除了 reference model。在 DPO 中,reference model 起着防止策略偏离过远的约束作用,而 SimPO 通过使用按响应长度归一化的平均 log probability 作为奖励信号,解决了这一问题。它在 AlpacaEval 2 和 Arena-Hard 上的表现显著超过 DPO。

由于不需要 reference model,内存占用比 DPO 减少一半。这使得在单张 GPU 上也能完成 7B 模型的对齐训练。

ORPO(Odds-Ratio Preference Optimization)

ORPO 把 SFT 和对齐整合进单一目标函数。通过在 SFT loss 上加入基于 odds-ratio 的偏好 loss,无需单独的 SFT 阶段,一次训练即可同时达成 instruction following 和偏好对齐。由于同时去除了 KL 惩罚,也就不再需要调优 beta。

GRPO(Group Relative Policy Optimization)

DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models(Shao 等,2024,arxiv:2402.03300)

DeepSeek 提出的 GRPO 去除了 PPO 的 value network(critic model),将 RLHF 的内存需求降低约 50%。它针对同一个 prompt 以组的形式采样多个响应,用组内的相对奖励来估计 advantage。由于不再需要单独的 critic model,实现与训练都变得更简单。

在 DeepSeek-R1 的训练中,GRPO 也发挥了关键作用,尤其在数学、编程等可验证(verifiable)任务上表现出强劲的性能。

算法对比表

项目RLHF (PPO)DPOIPOKTOSimPOORPOGRPO
奖励模型需要显式训练隐式(内在于策略)隐式隐式不需要不需要显式/基于规则
Reference Model需要需要需要需要不需要不需要需要
数据格式pairwisepairwisepairwisebinarypairwisepairwise基于规则的奖励
内存占用非常高(4 个模型)高(2 个模型)高(2 个模型)高(2 个模型)中等(1 个模型)中等(1 个模型)高(2 个模型)
核心超参数KL coeff, clip ratio, GAE lambdabeta, lrbetabeta, lambdagamma, betalambdaclip ratio, KL coeff
训练稳定性中等中〜高中等
实现难度非常低非常低中等
推荐 beta-0.1〜0.50.010.1〜0.32.0〜2.5--
是否需要 SFT 预训练强烈推荐推荐可选推荐不需要(已整合)

超参数调优指南

Beta 参数调优

beta 是所有 DPO 系技术中最重要的超参数。它决定了约束策略与参考策略之间距离的 KL 约束强度。

# 按 beta 取值分析训练行为的脚本
import torch
import matplotlib.pyplot as plt

def dpo_loss_landscape(beta_values, log_ratio_range):
    """按 beta 值可视化 DPO loss 曲面"""
    fig, axes = plt.subplots(1, len(beta_values), figsize=(5*len(beta_values), 4))

    for idx, beta in enumerate(beta_values):
        log_ratios = torch.linspace(-log_ratio_range, log_ratio_range, 200)
        # DPO loss: -log(sigma(beta * (log_ratio_w - log_ratio_l)))
        # 这里把 log_ratio_w - log_ratio_l 当作单一变量处理
        loss = -torch.log(torch.sigmoid(beta * log_ratios))
        gradient = -beta * (1 - torch.sigmoid(beta * log_ratios))

        ax = axes[idx]
        ax.plot(log_ratios.numpy(), loss.numpy(), label="Loss", color="blue")
        ax.plot(log_ratios.numpy(), gradient.numpy(), label="Gradient", color="red")
        ax.set_title(f"beta = {beta}")
        ax.set_xlabel("log(pi/pi_ref)_w - log(pi/pi_ref)_l")
        ax.legend()
        ax.grid(True)

    plt.tight_layout()
    plt.savefig("dpo_beta_analysis.png", dpi=150)
    plt.show()

# beta 越大,loss 曲面越陡峭,训练也越激进
dpo_loss_landscape([0.05, 0.1, 0.3, 0.5], log_ratio_range=5.0)

实战调优策略:

  • 模型规模越小(1B〜3B),beta 应设置得越低(0.05〜0.1)。因为小模型更容易偏离参考策略。
  • 模型规模越大(7B〜70B),即便把 beta 设置得更高(0.1〜0.5)也依然稳定。
  • 偏好数据的质量越高,就可以把 beta 调低,从而更激进地训练。
  • 如果数据质量不确定,可以从 beta=0.1 开始,再根据 validation loss 进行调整。

Learning Rate 调优

在 DPO 中,标准做法是把 learning rate 设置为比 SFT 低 5〜20 倍。

模型规模SFT LRDPO LR 推荐范围备注
1B〜3B2e-51e-6〜5e-7过拟合风险较高
7B〜13B1e-55e-7〜1e-7最稳定的区间
30B〜70B5e-61e-7〜5e-8必须使用 gradient accumulation

learning rate 过高,会导致模型急剧偏离参考策略,out-of-distribution 响应增多。过低则 chosen/rejected 的区分能力学习不充分,win rate 的提升会很有限。

偏好数据构建实战指南

DPO 数据格式转换

def convert_to_dpo_format(raw_data):
    """将各种原始数据转换为 DPO 训练格式

    DPO 需要 prompt、chosen、rejected 三个字段。
    建议每个字段都使用 conversation 形式(list of dict)。
    """
    dpo_dataset = []

    for item in raw_data:
        prompt = item["instruction"]

        # 方法 1: 人类评估者的直接比较
        if "chosen_response" in item and "rejected_response" in item:
            entry = {
                "prompt": [{"role": "user", "content": prompt}],
                "chosen": [{"role": "assistant", "content": item["chosen_response"]}],
                "rejected": [{"role": "assistant", "content": item["rejected_response"]}],
            }
            dpo_dataset.append(entry)

        # 方法 2: 基于评分的自动转换(rating >= 4: chosen, rating <= 2: rejected)
        elif "responses" in item:
            responses = sorted(item["responses"], key=lambda x: x["rating"], reverse=True)
            if len(responses) >= 2 and responses[0]["rating"] >= 4 and responses[-1]["rating"] <= 2:
                entry = {
                    "prompt": [{"role": "user", "content": prompt}],
                    "chosen": [{"role": "assistant", "content": responses[0]["text"]}],
                    "rejected": [{"role": "assistant", "content": responses[-1]["text"]}],
                }
                dpo_dataset.append(entry)

    return dpo_dataset

KTO 数据格式转换

def convert_to_kto_format(raw_data):
    """将现有反馈数据转换为 KTO 格式

    KTO 需要 prompt、completion、label 三个字段。
    label 为 True(desirable) 或 False(undesirable)。
    由于不需要成对数据,thumbs-up/down 数据可以直接使用。
    """
    kto_dataset = []

    for item in raw_data:
        prompt = item["instruction"]

        # 方法 1: 直接使用 thumbs-up/down 反馈
        if "response" in item and "thumbs_up" in item:
            entry = {
                "prompt": [{"role": "user", "content": prompt}],
                "completion": [{"role": "assistant", "content": item["response"]}],
                "label": item["thumbs_up"],  # True or False
            }
            kto_dataset.append(entry)

        # 方法 2: 基于 rating 的二元转换
        elif "response" in item and "rating" in item:
            entry = {
                "prompt": [{"role": "user", "content": prompt}],
                "completion": [{"role": "assistant", "content": item["response"]}],
                "label": item["rating"] >= 4,  # 4 分以上: desirable
            }
            kto_dataset.append(entry)

        # 方法 3: 从 DPO 成对数据生成 KTO 数据
        if "chosen_response" in item and "rejected_response" in item:
            kto_dataset.append({
                "prompt": [{"role": "user", "content": prompt}],
                "completion": [{"role": "assistant", "content": item["chosen_response"]}],
                "label": True,
            })
            kto_dataset.append({
                "prompt": [{"role": "user", "content": prompt}],
                "completion": [{"role": "assistant", "content": item["rejected_response"]}],
                "label": False,
            })

    return kto_dataset

把 DPO 数据转换为 KTO 格式很简单,但反过来却不可能。这正是 KTO 的实用优势。对于已经拥有非成对方式收集到的二元反馈数据的组织而言,KTO 可能是唯一的选择。

实战故障排查:常见失败案例与恢复

失败案例 1:DPO 训练后响应质量下降

症状:DPO 训练后,模型生成的响应变短且不诚实,或者相反地变得极度冗长。

原因分析:这通常发生在数据中大量存在 chosen 与 rejected 质量差异不明确的样本时。尤其当 rejected 响应实际上是合理的回答、只是比 chosen"略逊一筹"时,模型就无法学到正确的方向。

恢复流程

  1. 数据过滤:剔除 chosen 与 rejected 的奖励模型分数差低于阈值(例如 0.5)的样本对。
  2. 提高 beta(0.3〜0.5),使策略更贴近参考策略。
  3. 进一步降低 learning rate(当前值的 1/2)。
  4. 确认 SFT checkpoint 是否已经充分训练。

失败案例 2:KTO 中 desirable/undesirable 比例失衡

症状:训练无法收敛,或者只有 desirable 响应的概率在上升,undesirable 响应的概率却没有变化。

原因分析:当 desirable 数据比 undesirable 数据多出 5 倍以上时,undesirable 的梯度信号会被稀释。KTO 论文建议将 desirable:undesirable 的比例控制在 1:1 到 4:1 之间。

恢复流程

  1. 提高 undesirable_weight(例如从 1.0 提高到 2.0)。
  2. 对 undesirable 数据进行过采样(oversampling)。
  3. 如果比例极端(超过 10:1),考虑改用 DPO。

失败案例 3:训练初期 loss 爆炸

症状:训练开始后仅几十步以内,loss 就急剧上升并出现 NaN。

原因分析:这通常发生在 reference model 与训练模型的初始差异过大,或者 learning rate 过高的情况下。若用 base model 而非 SFT checkpoint 来充当 reference,这个问题会尤其明显。

恢复流程

  1. 把 learning rate 降到原来的 1/5。
  2. 将 warmup_ratio 设置为 0.1 以上。
  3. 让 reference model 与训练模型从同一个 SFT checkpoint 出发。
  4. 把 bf16 切换为 fp32,确认数值稳定性。
  5. 将 gradient clipping 设置为 1.0。

失败案例 4:过拟合——train loss 在下降,validation loss 却在上升

症状:train loss 持续下降,但 validation loss 从训练中段开始上升。生成质量表现出直接照抄训练数据中 chosen 响应的倾向。

恢复流程

  1. 在 validation loss 最低的 checkpoint 处停止训练(early stopping)。
  2. 确认相对于数据量而言,训练轮数(epoch)是否合适。通常 1〜3 个 epoch 就足够。
  3. 考虑改用 IPO。由于 squared loss 结构,IPO 对过拟合更鲁棒。

UNA:统一 RLHF/DPO/KTO 的框架

近期研究中值得关注的是 UNA(Unifying Alignments)框架(arxiv:2408.15339)。UNA 用一个泛化的隐式奖励函数,将 RLHF(PPO)、DPO、KTO 统一了起来。其核心洞察是:这三种技术都可以被重新解释为"最小化隐式奖励与显式奖励之间差异的 supervised learning"。

从这个角度看,pairwise 反馈(DPO)、binary 反馈(KTO)、scalar 反馈(RLHF)对应的是同一个目标函数的不同特殊情形。实务中,可以根据手头数据的形态选择合适的技术;而当多种形态的反馈数据混杂在一起时,UNA 框架能够将它们统一利用起来。

对齐技术选择清单

选择对齐技术时,按以下清单依次确认。

数据形态确认

  • 是否有成对比较数据(A 比 B 更好)?-> 可使用 DPO、IPO、SimPO
  • 是否只有二元反馈数据(好/差)?-> 使用 KTO
  • 是否有数值评分(1〜5 分)?-> 基于阈值转换为 DPO 或 KTO 格式
  • 是否是存在可验证正确答案的任务?-> 考虑 GRPO

基础设施确认

  • GPU 内存是否在 48GB 以上?-> DPO、IPO、KTO 均可行
  • GPU 内存是否在 24GB 以下?-> 推荐 SimPO 或 ORPO(不需要 reference model)
  • 是否有余力单独进行 SFT 训练?-> DPO + SFT 流水线
  • 是否希望一次性完成 SFT 与对齐?-> ORPO

质量要求确认

  • 是否担心过拟合?-> IPO(通过 squared loss 防止过拟合)
  • 是否必须不经 SFT、直接应用于 base model?-> KTO(rambling 现象更少)
  • 数据质量是否不确定?-> 把 beta 设置得更高,并使用 IPO
  • 目标是追求最高性能?-> DPO + 高质量成对数据的组合

运营注意事项

  • 训练前是否已单独保存 reference model 的 checkpoint?
  • 是否已划分出 validation set?(至少为全部数据的 5%)
  • 是否已启用 gradient checkpointing?(节省内存)
  • 是否已配置 wandb 等训练日志?
  • 是否已人工检查过 chosen/rejected(或 desirable/undesirable)数据的质量?

评估流水线:验证对齐结果

对齐训练后,对模型质量进行定量评估是必不可少的。仅仅因为 loss 下降,并不代表对齐就已经成功。

# 用于评估对齐模型的 win rate 计算脚本
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

def calculate_win_rate(model_path, ref_model_path, eval_prompts, tokenizer_name):
    """用 reward model 评估对齐模型 vs reference 模型的 win rate"""
    model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.bfloat16)
    ref_model = AutoModelForCausalLM.from_pretrained(ref_model_path, torch_dtype=torch.bfloat16)
    tokenizer = AutoTokenizer.from_pretrained(tokenizer_name)

    wins, total = 0, 0

    for prompt in eval_prompts:
        inputs = tokenizer(prompt, return_tensors="pt")

        # 生成对齐模型的响应
        with torch.no_grad():
            aligned_output = model.generate(
                **inputs, max_new_tokens=512,
                temperature=0.7, do_sample=True
            )
            ref_output = ref_model.generate(
                **inputs, max_new_tokens=512,
                temperature=0.7, do_sample=True
            )

        aligned_text = tokenizer.decode(aligned_output[0], skip_special_tokens=True)
        ref_text = tokenizer.decode(ref_output[0], skip_special_tokens=True)

        # 在此添加使用 judge model 或 reward model 进行比较评估的逻辑
        # 例如:使用 GPT-4 作为 judge,或使用已训练好的 reward model
        # win = judge(prompt, aligned_text, ref_text)
        # wins += win
        total += 1

    return wins / total if total > 0 else 0.0

评估时需要注意的一点是,要避免 self-evaluation(对齐模型评估自己)。并行使用单独的 judge model 或人工评估,才是获得可靠结果的方法。也推荐使用 AlpacaEval、MT-Bench、Arena-Hard 等标准基准。

2025-2026 年对齐研究的方向

当前的对齐研究正朝着几个方向快速演进。

Verifier-driven RL:继 GRPO 的成功之后,在数学、编程等可验证正确答案的任务上使用基于规则的奖励这一方向正在被强化。无需人类反馈也能完成对齐的领域正在扩大。

Online DPO / Iterative DPO:训练中的模型直接生成响应、并据此更新偏好数据的在线(online)方式,相比 offline DPO 表现出了性能提升。不过也存在训练成本增加的权衡。

Multi-objective alignment:不再只是单纯追求"好的响应",而是同时优化 helpfulness、harmlessness、honesty 等多个维度的研究十分活跃。像 Mo-KTO(Multi-Objective KTO)这样的扩展也已被提出。

Synthetic preference data:用强大的 LLM(GPT-4、Claude 等)代替人类评估者来生成偏好数据的技术正日益普及。成本大幅降低,但 judge model 的偏差会原样转移过来,这一点需要留意。

结语

从 RLHF 到 DPO、再从 DPO 到 KTO 的演进,并不只是算法层面的改进,而是在不断追问"对齐所需的最小条件究竟是什么"这一根本问题的过程。RLHF 需要显式的奖励模型和 RL 循环,DPO 去掉了奖励模型,而 KTO 甚至让成对比较数据也变得不再必要。

实务中的选择,与其说取决于理论上的优越性,不如说取决于手头数据的形态、基础设施的限制,以及团队的经验水平。如果有成对比较数据和充足的 GPU,DPO 是经过验证的选择;如果只有二元反馈数据,KTO 就是唯一的选择。如果内存有限,可以考虑 SimPO 或 ORPO;如果是可验证任务,GRPO 是强有力的替代方案。

无论选择哪种技术,数据质量都决定了一切。1 万条高质量偏好数据,胜过 10 万条低质量数据。训练前的数据检查、训练中的 validation 监控、训练后的系统化评估——不省略这些步骤,才是成功对齐的关键。

参考资料

  1. DPO - Rafailov et al., "Direct Preference Optimization: Your Language Model is Secretly a Reward Model", NeurIPS 2023. arxiv:2305.18290
  2. KTO - Ethayarajh & Jurafsky, "KTO: Model Alignment as Prospect Theoretic Optimization", ICML 2024. arxiv:2402.01306
  3. IPO - Azar et al., "A General Theoretical Paradigm to Understand Learning from Human Preferences", AISTATS 2024. arxiv:2310.12036
  4. GRPO - Shao et al., "DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models", 2024. arxiv:2402.03300
  5. SimPO - Meng et al., "SimPO: Simple Preference Optimization with a Reference-Free Reward", 2024. arxiv:2405.14734
  6. UNA - "UNA: Unifying Alignments of RLHF/PPO, DPO and KTO by a Generalized Implicit Reward Function", 2024. arxiv:2408.15339
  7. DPO Comprehensive Survey - "A Comprehensive Survey of Direct Preference Optimization: Datasets, Theories, Variants, and Applications", 2024. arxiv:2410.15595
  8. Hugging Face TRL - DPO Trainer Documentation. https://huggingface.co/docs/trl/main/en/dpo_trainer
  9. Hugging Face TRL - KTO Trainer Documentation. https://huggingface.co/docs/trl/main/en/kto_trainer
  10. InstructGPT - Ouyang et al., "Training language models to follow instructions with human feedback", NeurIPS 2022. arxiv:2203.02155

小测验

Q1:《从 DPO 到 KTO:人类反馈对齐技术最新论文综述与实战实现》一文主要涵盖哪些内容?

综述克服 RLHF 局限的 DPO、IPO、KTO 等最新人类反馈对齐技术论文,并提供基于 TRL 的实战实现指南。涵盖算法对比、超参数调优,直至失败案例。

Q2:为什么需要 RLHF 之后的对齐技术? 让 LLM 与人类偏好对齐的工作,也就是对齐(alignment),自 ChatGPT 以来已成为所有生产环境 LLM 的必备流水线。

Q3:说明"RLHF 流水线的结构与局限"这一部分的核心内容。 三阶段流水线详解:用公式梳理 RLHF 的整体流程如下。第 1 阶段——SFT:用高质量的 instruction-response 数据对 base model 进行微调。

Q4:"IPO:Bradley-Terry 假设的风险"这一部分的要点是什么? 核心论文综述:A General Theoretical Paradigm to Understand Learning from Human Preferences (Azar et al., 2024, AISTATS 2024, arxiv:2310.12036)。IPO(Identity Preference Optimization)对 DPO 的核心假设——Bradley-Terry 模型——提出了质疑。

Q5:"KTO:无需成对数据、仅凭二元信号完成对齐"是如何实现的? 核心论文综述:KTO: Model Alignment as Prospect Theoretic Optimization (Ethayarajh & Jurafsky, 2024, ICML 2024, arxiv:2402.01306)。KTO 最大的创新在于数据需求的变化。

현재 단락 (1/316)

让 LLM 与人类偏好对齐的工作,也就是对齐(alignment),自 ChatGPT 以来已成为所有生产环境 LLM 的必备流水线。OpenAI 在 InstructGPT(Ouyang 等,202...

작성 글자: 0원문 글자: 17,527작성 단락: 0/316