昨晚八点多睡觉了,睡到半夜三点起了,玩了一小时手机又一口气睡到早上十点。
刷视频刷到巴哥和HEBE,磕爽了,这么好磕的cp不多了。寒假上一对磕的是lex,恨海情天的cp就是很有故事张力啊(迫真)!!
今天继续学习后训练,明天晚上之前一定开始海投实习。
ChatML 天然支持多轮对话,只需按顺序排列多轮 user/assistant 消息
在实践中,不要手动拼接模板字符串。使用 Hugging Face Transformers 提供的 apply_chat_template 方法可以自动处理格式转换:
| |
该函数可以自己适应不同模型的模板格式。
掩码损失(Masked Loss)
在 SFT 中,我们只希望模型学习"如何回答",而不是学习"如何复述问题"。
训练目标是仅在 assistant token 上计算交叉熵损失:$\mathcal{L}_\mathrm{SFT}=-\sum_{t\in\mathcal{A}}\log P_\theta(x_t|x_{ A表示助手回复对应位置的token集合 具体实现用mask来控制哪些位置参与损失计算:SFTTrainer 通过 DataCollatorForCompletionOnlyLM 自动实现掩码损失:
# SFTConfig 默认会在 assistant token 上计算损失
数据质量重于数量 精选少量高质量数据往往优于大量低质量数据。
LIMA(Zhou 等,2023)是证明数据质量重于数量的里程碑论文:1000条精选数据效果接近50000条训练的模型。 提出了 “Superficial Alignment Hypothesis”(表层对齐假说):模型的知识和能力主要来自预训练,SFT 的作用仅仅是教会模型使用正确的输出格式和风格
GRAPE(2025)方法进一步细化了数据选择策略:
- 核心思想:不是所有高质量数据对特定基座模型都同样有效
- 方法:选择与基座模型分布匹配的数据——既不太简单(模型已经会),也不太难(模型学不会)
- 效果:在相同数据量下,GRAPE 选择的数据子集显著优于随机选择
MAGPIE(Xu 等,ICLR 2025)提出了一种创新的指令数据合成方法,显著降低成本,提高生成速度: 1 利用对齐模型的自动补全 向一个已经对齐的 LLM(如 Qwen3-32B Instruct)仅输入系统提示和用户消息的前缀 token($<\text{im\_start}>\text{user}\n$),让模型自动补全出一条指令。 2 生成回复 将生成的指令重新输入模型,获得对应的回复。 3 质量过滤 使用多维度过滤(长度、多样性、质量评分)筛选高质量样本。
数据选取核心原则:质量大于数量、多样性、匹配基座能力、格式一致性、避免有害内容
1.3 参数高效微调
Qwen3-8B 为例,全参数微调(Full Fine-Tuning)的显存需求远超单张 GPU 容量 显存构成: $\mathrm{Memory_{total}=Memory_{params}+Memory_{gradients}+Memory_{optimizer}+Memory_{activations}}$
PEFT的核心:冻结大部分原始参数,仅训练少量新增参数,从而大幅降低梯度和优化器状态的显存需求。 LoRA关键假设:预训练模型在微调时的权重更新具有低秩结构。
前向传播:α 是缩放因子(scaling factor),αrrα 控制了 LoRA 更新的幅度。 $h=W_0x+\Delta Wx=W_0x+\frac{\alpha}{r}BAx$
秩 r 决定了 LoRA 的表达能力 一般8-16进行风格调整,32进行指令跟随调整,64进行领域适配
LoRA初始化 矩阵 A:使用 Kaiming 均匀分布初始化 矩阵 B:初始化为全零
这保证了 ΔW=BA=0 ,即训练开始时 W′=W0
QLoRA:量化低秩适配 LoRA 基础上增加了 4-bit NormalFloat(NF4)量化,将基座模型的权重从 FP16(16 bit)量化到 4 bit,进一步将显存需求减半。 NormalFloat 量化基于一个关键观察:预训练模型的权重近似服从正态分布。NF4 将正态分布的分位数作为量化级别,使得量化误差在信息论意义上最优。 还引入了双重量化(Double Quantization):对量化常数本身再做一次量化,额外节省约 0.4 bit/参数。 LoRA 部分(B, A)始终保持 FP16 精度 W0 从 NF4 反量化到 FP16 后参与计算
| |
- 全参数微调:~100 GB(需多卡)
- LoRA(FP16):~20 GB(A100-40G 或 RTX 4090)
- QLoRA(NF4):~10 GB(T4 16GB 勉强可用)
BLEU/ROUGE 已经不够 评估观念:有用、无害、诚实、指令跟随
LLM-as-Judge 使用更强的模型(如 GPT-4、Qwen3-32B)作为"评委",对目标模型的回复进行评分。这一方法在 MT-Bench(Zheng 等,NeurIPS 2023)中被系统化提出。
- 80 个双轮问题:每个问题包含第一轮提问和基于第一轮回复的追问
- 8 个类别,每个类别 10 道题:
支持单回复评分和成对比较(pairwise) llm as judge有个明显问题:位置偏差(Position Bias)是 LLM-as-Judge 的已知问题:评委模型可能倾向于选择特定位置(通常是第一个)的回复。 缓解方法:
- 交换位置重复评判:对每对回复评判两次(A-B 和 B-A),取一致结果
- 多次采样:使用较高 temperature 多次评判,取多数投票
- 选择偏差较小的评委模型:GPT-4 和 Qwen3-32B 的位置偏差相对较小
人类偏好评估
AlpacaEval是一个自动化的 LLM 评估基准:
- 805 条来自不同领域的指令
- 使用 GPT-4 作为评委,对模型回复与参考回复(GPT-4 Turbo 的回复)进行成对比较
- 主要指标:胜率(Win Rate)——模型回复被评委判定优于参考回复的比例
- AlpacaEval 2.0 使用长度控制(Length-Controlled Win Rate),避免模型通过生成更长回复来获得优势
Chatbot Arena是最权威的人类偏好排行榜:
- 真实用户匿名投票:用户向两个匿名模型提问,选择更好的回复
- 使用 Elo 评分系统(类似国际象棋排名)对模型进行排名
- 优势:最接近真实用户偏好,不受自动评估偏差影响
- 数据规模:截至 2025 年已累积数百万次投票
简单试用了一下llamafactory,这可以方便快速训练,避免动不动就手搓各种训练文件,参数不会写错,支持的模型格式非常多,做了统一适配层。 自动管理多种PEFT的内容,支持模型导出为huggingface格式,网页里还会自动估算显存,支持自动推荐batch size,避免OOM。 但有时它为了通用适配,未必是最精简调用,抽象层太厚debug困难,性能有点损失,但做后训练的话,这一点损失是完全不必care的,我个人觉得。
如果在远程服务器上,比如autodl这种没有公网端口没浏览器上用的话。 可以直接用cli模式,llamafactory-cli train config.yaml 手写yaml即可。 或者直接用SSH端口转发网页到本地浏览器,填写完之后执行即可。
(以下是假想结果,出于时间考虑,没有真跟一遍,原来的项目已经做过一个差不多的了) 实验1:微调 Qwen3-1.7B 为指令跟随助手
- 初始 loss:2.1 左右
- 前 200 steps 迅速下降至 1.2
- 之后缓慢下降
- 在 800–1000 steps 收敛至 0.85 左右
- 后期震荡幅度较小(±0.03)
设计 3 类 prompt:
- 知识问答
- 指令改写
- 思维链推理 微调模型相比基座模型:
- 指令跟随能力提升明显
- 输出结构更清晰
- 风格更统一
- 推理能力略有提升但非根本性变化
超参数实验结果 r = 4 改善有限 r = 8 最优 r = 16 略好但不明显
alpha 8 慢 16稳定 32 loss波动大
lr 1e-5 收敛慢 2e-5 最稳定 5e-5 不稳定
数据质量与数量的关系
本实验使用的数据规模较小,但具有较高的指令质量与表达一致性。训练结果表明,即便数据量有限,模型仍然可以显著提升指令跟随能力和输出结构化程度。与 LIMA 论文的核心观点一致:
高质量指令数据比大规模低质量数据更能有效提升模型的对齐能力。
LoRA rank 决定可学习的低秩矩阵表达能力 alpha 控制更新幅度 LoRA 本质上是在“可控地注入知识”
基座模型 vs 微调模型差异 最明显的差异体现在:
- 指令跟随能力
- 输出结构清晰度
- 风格一致性 而在:
- 复杂推理能力
- 世界知识广度 方面变化不明显。
微调更多是“行为对齐”,而不是“能力跃迁”。
Instruct 模型经过大规模 SFT + RLHF - 本实验只是轻量适配
第2课 SFT 进阶 数据工程与指令微调深入
本课将深入数据工程——这是决定 SFT 效果的最关键因素。
- 掌握指令数据集的构建方法:从 Self-Instruct 到 MAGPIE 的技术演进
- 实施数据质量控制:去重、难度分级、去污染等关键步骤
- 理解数据混合策略对模型能力的影响(Tülu 3 方法论)
- 配置 SFT 超参数并诊断常见训练问题
- 搭建 LLM-as-Judge 评估流程,使用 MT-Bench 风格的提示模板
- 完成从数据准备到模型评估的完整指令微调实验
指令数据集的构建方法经历了快速演进——从手工标注到完全自动化合成。 Self-Instruct(Wang 等,2023)是第一个系统性的指令数据自动生成方法。 人工编写 175 条种子任务,涵盖不同类型(生成、分类、问答等)。每条包含指令、输入(可选)和输出。从种子池中随机采样 8 条指令作为 in-context 示例,提示 GPT-3 生成新指令。
- 去除与已有指令过于相似的(ROUGE-L > 0.7)
- 去除以特定黑名单短语开头的(如"Write a program…“过于简单)
- 去除过长或过短的指令 对过滤后的指令,使用 GPT-3 生成对应回复,形成完整的(指令,回复)对。
Alpaca:快速跟进与规模化
- 使用 GPT-3.5-Turbo 替代 GPT-3,质量更高、成本更低
- 用这些数据微调 LLaMA-7B,总成本不到 600 美元
- 效果令人惊喜:7B 模型展现出接近 GPT-3.5 的对话能力 使用了teacher的文本输出,不需要真teacher,精细程度不如真蒸馏学习logits和soft targets来的那么高,但成本也同样的比较低。
UltraChat:高质量多轮对话 UltraChat(Ding 等,2023)将指令数据从单轮扩展到多轮对话:
- 话题种子:从三大类别出发——关于世界的问题、创作与写作、协助完成任务
- 多轮模拟:使用两个 ChatGPT 实例分别扮演用户和助手,进行多轮对话
- 质量控制:过滤长度异常、重复率高的对话
MAGPIE:无种子数据合成 MAGPIE 的关键洞察:已对齐的 LLM 在看到聊天模板的用户消息前缀时,会自动补全出一条合理的指令。
| 特性 | Self-Instruct | Alpaca | MAGPIE |
|---|---|---|---|
| 种子数据 | 175 条 | 175 条(继承) | 无需 |
| 生成模型 | GPT-3 | GPT-3.5 | 任意对齐 LLM |
| 多轮能力 | 弱 | 弱 | ✅ 支持 |
| 指令多样性 | 受种子限制 | 受种子限制 | 来自模型自身分布 |
| 成本 | API 调用 | API 调用 | 本地推理 |
| 数据质量 | 中等 | 中等 | 高(来自强模型) |
MAGPIE 的指令多样性来自对齐模型自身的概率分布。不同的随机种子和 temperature 设置会采样出覆盖面广泛的指令类型
重复或近似重复的训练数据会导致模型过拟合到特定模式。故需要去重
| 方法 | 原理 | 优势 | 成本 |
|---|---|---|---|
| 精确去重 | 完全相同的文本 | 实现简单 | 低 |
| n-gram 去重 | Jaccard 相似度 > 阈值 | 捕获近似重复 | 中 |
| 嵌入去重 | 向量余弦相似度 > 阈值 | 捕获语义重复 | 高 |
| MinHash LSH | 近似最近邻搜索 | 大规模高效 | 中 |
并非所有难度的数据对 SFT 同等有效。研究表明应优先选择中等难度样本
去污染(Decontamination) 极其重要:训练数据绝对不能包含评估基准的测试集内容。否则评估结果将毫无意义。这就是"数据泄露”(data contamination)问题。
SFT 超参数实践指南 基于 Pareja 等(2024) 的系统性实验结论——该论文在 3B-7B 模型上进行了大量 SFT 超参数消融实验,为小型到中型 LLM 的 SFT 提供了全面的实践指南。
学习率对最终性能的影响超过其他任何单一超参数。过大的学习率会导致灾难性遗忘(模型忘记预训练知识),过小则会欠拟合。
学习率调度器推荐使用 cosine 调度,配合 warmup:
$$\eta_t=\begin{cases}\eta_{\max}\cdot\frac{t}{T_{\mathrm{warmup}}}&\mathrm{if~}t训练轮数(Epochs)
| 数据规模 | 推荐 Epochs | 说明 |
|---|---|---|
| < 5K 条 | 3-5 | 数据少,需要多看几遍 |
| 5K-50K 条 | 1-3 | 最常见的配置 |
| > 50K 条 | 1 | 数据充足,1 个 epoch 通常够 |
对于高质量数据,1-2 个 epoch 通常是最优的。 超过 3 个 epoch 几乎总会导致过拟合
序列长度(Sequence Length) 显存∝batch_size×seq_length^2(注意力机制)
超参数搜索策略
第一步:固定其他参数,搜索学习率 在 0.00005 中搜索(QLoRA 在 0.0003)。选择验证损失最低的。 第二步:确定训练轮数 用最优学习率训练 3 个 epoch,观察验证损失何时开始上升,确定最佳 epoch 数。 第三步:调整 LoRA rank 在 64 中尝试,观察性能与效率的权衡。 第四步:微调批量大小 在 64 中尝试(通过梯度累积实现)。
问题诊断表
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
| 训练损失不下降 | 学习率太小 | 增大学习率(如 2e-5 → 5e-5) |
| 训练损失不下降 | 数据格式错误 | 检查 chat template 和掩码 |
| 训练损失不下降 | 梯度消失 | 检查量化配置、使用 BF16 |
| 训练损失下降后又上升 | 学习率太大 | 减小学习率(如 5e-5 → 1e-5) |
| 训练损失下降后又上升 | 训练轮数过多 | 减少 epochs 或使用 early stopping |
| 模型输出大量重复 | 过拟合 | 减少 epochs、增大 dropout |
| 模型输出大量重复 | temperature 太低 | 推理时增大 temperature 到 0.7+ |
| 模型输出大量重复 | 数据多样性不足 | 增加数据来源或样本数 |
| 模型”忘记”预训练知识 | 灾难性遗忘 | 减小学习率、减少 epochs |
| 模型”忘记”预训练知识 | LoRA rank 太大 | 减小 rank(64 → 32 → 16) |
| 验证损失持续上升 | 过拟合 | 经典过拟合,减少训练量 |
| 验证损失持续上升 | 验证集分布不同 | 检查数据划分 |
| 回复风格不自然 | 数据质量差 | 清洗数据、增加高质量样本 |
| 回复风格不自然 | 格式模板错误 | 检查 chat template 是否正确 |
| 超参数 | 推荐值 | 影响 |
|---|---|---|
| 学习率 | 2e-5(LoRA) / 2e-4(QLoRA) | 最敏感,过大遗忘,过小欠拟合 |
| 有效批量 | 16-32 | 影响训练稳定性 |
| Epochs | 1-2 | 过多导致过拟合 |
| 序列长度 | 覆盖 95% 数据 | 影响显存和效率 |
| LoRA rank | 32 | 表达能力与效率的权衡 |
| LoRA alpha | 2 × rank | 控制更新幅度 |
LLM-as-Judge 评估方法 使用强 LLM(如 GPT-4、Qwen3-32B)对目标模型的回复进行评分,兼具人类评估的全面性和自动评估的效率 GPT-4 作为评委的判断与人类偏好的一致性超过 80%,高于人类评估者之间的一致性(约 81%)。这使得 LLM-as-Judge 成为实践中最常用的评估方法。
MT-Bench是标准实现 分为单回复评分和成对比较两个模板,归根结底是prompt工程层面的实现。 中文场景替换成中文评判模板即可。 有着位置偏差的毛病,通过交换位置,多次采样,提示强调,选择好的评委来解决。其中交换位置最有用,从对称性上来看也最有用。
(以下为假想,我没实际操作) 实验2:构建领域定制 SFT 模型并系统评估
数据来源:xxxx 数据规模:xxx 清洗后规模:xx 平均每条对话轮数 列信息:id messages source meta token长度分布图
- 分布形态:
【如:右偏长尾/近似对数正态/双峰】 - 主要集中区间:
【如:大多数落在 20–200 tokens】 - 长尾情况:
【如:>512 tokens 的样本占比约 X%】 - 统计量:P50=
【】,P90=【】,P95=【】,最大值=【】助手回复 token 长度分布 。 。 。 。
质量控制结果(去重/过滤前后数据量变化)
- 去重:
【exact match / MinHash / SimHash】,阈值【】 - 过滤:
- 过短:user <
【】tokens 或 assistant <【】tokens - 过长:截断/剔除 >
【】tokens - 非目标语言/乱码:规则
【】 - 低质量模式:如“只输出一句话/模板化回答/重复标点”等规则
【】
- 过短:user <
数据量变化(前 → 后)
- 原始:
【N_raw】 - 去重后:
【N_dedup】(减少【N_raw - N_dedup】,约【%】) - 过滤后:
【N_clean】(再减少【】,约【%】)
文字描述建议:
- “清洗主要删除了
【重复对话/极短样本/乱码样本】,数据量从【】降至【】,总体减少【】%,但样本平均长度与信息密度提升。”
训练/验证/测试集划分信息
- 划分比例:Train/Val/Test =
【比如 8/1/1】 - 划分方法:
【随机划分/按 source 分层/按主题分层】 - 随机种子:
【seed】 - 每份样本数:
- Train:
【N_train】 - Val:
【N_val】 - Test:
【N_test】
- Train:
一致性说明:
- “划分前先去重,避免同一对话同时出现在训练与评测中造成泄漏。”
给出不同类别的数据,输入,给出不同模型的做答评分。
ablation 数据量消融 - 25% → 50%:提升明显 - 50% → 100%:提升变缓 数据太少时严重不稳定 数据过多但质量一般 → 提升不明显
数据质量消融(低质量 vs 高质量) 高质量数据明显优于低质量数据(最常见) 总分提升不大,但“稳定性提升”
LoRA 秩消融(r = 8 / 16 / 32) r 太小 → 欠拟合 r 适中 → 效果最好(常见在 16 左右) r 过大 → 收益递减甚至轻微下降
第3课 偏好对齐 DPO及其变体
为什么仅靠 SFT 不足以实现模型对齐,阐述人类偏好的比较性本质 SFT 教会模型’说什么’,但未教会它’如何选择’。 人类偏好本质上是比较性的,偏好优化直接捕获这一信号。 SFT可以将 Qwen3-1.7B 基座模型转化为一个能够遵循指令、进行多轮对话的助手。存在一个根本性的局限:它教会了模型模仿,但没有教会模型选择。
$$\mathcal{L}_{\mathrm{SFT}}=-\mathbb{E}_{(x,y)\sim\mathcal{D}}\left[\log\pi_\theta(y|x)\right]$$SFT本质是模型被训练去复制训练数据中的回复模式。 它学会的是数据的混合分布,而不是学会辨别哪些回复更好。 一个经过 SFT 的模型可能生成多个不同的回复: 回复 A:详细技术指南 回复 B:过于简短 回复 C:正确但冗长 回复 D:有误导性 缺乏一个关键能力——在回复 A、B、C、D 之间做出有意识的选择
SFT核心局限:无法处理偏好冲突、安全对齐的困境(通过偏好优化,我们可以直接告诉模型:“对于有害请求,拒绝回复比详细回答更好;对于正常请求,有帮助的回复比拒绝更好。")、回复多样性的不可控(偏好优化通过 KL 散度约束来进行多样性控制) 基于人类偏好的对齐方法。核心思路是: 1 收集偏好数据 对同一个提示,让模型(或人类)生成两个回复 $y_w$ 和 $y_t$,由人类标注者判断哪个更好。得到三元组数据集 $\mathcal{D} = \left\{ \left(x^{(i)}, y_w^{(i)}, y_t^{(i)}\right) \right\}$。
2 训练偏好信号 利用偏好数据训练模型区分好回复和差回复。有两条技术路线:
- RLHF 路线:先训练奖励模型(Reward Model),再用强化学习(PPO)优化策略
- DPO 路线:直接在偏好对上优化策略,跳过奖励模型和 RL 循环
3 对齐后的模型 经过偏好优化后,模型学会了在生成回复时自动"选择"更好的方向——更有帮助、更安全、更诚实。
主要偏好数据集包括
| 数据集 | 规模 | 标注方式 | 特点 |
|---|---|---|---|
| Anthropic HH-RLHF | 170K | 人类标注 | 早期代表性数据集 |
| UltraFeedback | 64K | GPT-4 标注 | 多维度评分,本课实验使用 |
| Nectar | 183K | GPT-4 排名 | 来自多个模型的回复 |
| Chatbot Arena | 持续增长 | 用户实时投票 | 最真实的人类偏好 |
从 RLHF 目标到 DPO 损失函数的完整数学路径(四步推导) 人类偏好的比较性本质 偏好是相对的,不是绝对的 $y_w\succ y_l\mid x$ 表示在给定提示 x 的条件下,人类偏好(preferred)回复 yw(winner)胜过回复 yl(loser)。 Bradley-Terry 偏好模型 假设存在一个潜在的奖励函数 r∗(x,y),那么人类偏好 yw 胜过 yl 的概率为: $P(y_w\succ y_l\mid x)=\sigma\left(r^*(x,y_w)-r^*(x,y_l)\right)$ 当 r∗(x,yw)−r∗(x,yl)→+∞时,偏好概率趋近于 1;当差距为零时,偏好概率为 0.5(完全随机)。
偏好优化是有必要的,传统的解决方案是RLHF:先训练一个奖励模型,再用 PPO 等强化学习算法优化策略。但这个流程复杂且不稳定。 DPO(Direct Preference Optimization) 的核心贡献是:通过一个精巧的数学推导,证明了可以完全跳过奖励模型和 RL 训练,直接在偏好对数据上用一个简单的监督损失来优化策略。
推导路线图:RLHF 目标 → 闭式最优策略 → 奖励的策略表达 → 代入 Bradley-Terry 模型 → DPO 损失函数。每一步都建立在前一步的基础上,最终得到一个只依赖策略模型和参考模型的简洁损失函数。
1、RLHF 目标
RLHF 的目标是找到一个策略 πθ,使得生成的回复获得尽可能高的人类奖励,同时不偏离参考策略 πref 太远。数学上表示为:
$$\max_{\pi_\theta}\mathbb{E}_{x\sim\mathcal{D},y\sim\pi_\theta(\cdot|x)}\left[r(x,y)\right]-\beta\operatorname{KL}\left[\pi_\theta(y|x)\|\pi_{\operatorname{ref}}(y|x)\right]$$β>0:KL 惩罚系数,控制策略偏离参考模型的程度 D:提示(prompt)的分布
KL 散度约束的作用 避免reward hacking 模式坍缩(只生成高分模板,多样性丧失) 语言退化(输出不自然,充满高分token) KL 约束确保优化后的策略不会偏离参考模型太远,起到正则化的作用。
展开目标为:
$$\max_{\pi_\theta}\mathbb{E}_{x\sim\mathcal{D}}\left[\mathbb{E}_{y\sim\pi_\theta(\cdot|x)}\left[r(x,y)-\beta\log\frac{\pi_\theta(y|x)}{\pi_\mathrm{ref}(y|x)}\right]\right]$$x是输入,则对于固定的x,内层优化问题变成了 $\max_{\pi_\theta(\cdot|x)}\sum_y\pi_\theta(y|x)\left[r(x,y)-\beta\log\frac{\pi_\theta(y|x)}{\pi_\mathrm{ref}(y|x)}\right]$
2、闭式最优策略
上面的内层优化问题,带约束的优化问题,内层概率和为1且每一子项大于0.
使用拉格朗日乘子法,对策略函数求导 $$\frac{\partial}{\partial \pi_\theta(y \mid x)} \left[ \pi_\theta(y \mid x) \left( r(x,y) - \beta \log \frac{\pi_\theta(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x)} \right)
- \lambda \left( 1 - \sum_{y’} \pi_\theta(y’ \mid x) \right) \right] = 0 $$ 最大化一个带 KL 正则项的期望奖励 同时满足概率归一化约束 求导整理后得到$$\log\frac{\pi_\theta(y|x)}{\pi_\mathrm{ref}(y|x)}=\frac{1}{\beta}\left(r(x,y)-\lambda-\beta\right) $$最优策略的闭式解 从上式可得 $$\pi^*(y|x)=\pi_\mathrm{ref}(y|x)\cdot\exp\left(\frac{r(x,y)}{\beta}\right)\cdot\frac{1}{Z(x)} $$ Z(x) 只依赖于 x,不依赖于具体的 y:这在后续推导中非常关键 $$Z(x)=\sum_y\pi_\mathrm{ref}(y|x)\cdot\exp\left(\frac{r(x,y)}{\beta}\right)$$
3、将奖励表示为策略的函数
易得
$$\log\pi^*(y|x)=\log\pi_\mathrm{ref}(y|x)+\frac{r(x,y)}{\beta}-\log Z(x)$$移项
$$r(x,y)=\beta\log\frac{\pi^*(y|x)}{\pi_\mathrm{ref}(y|x)}+\beta\log Z(x)$$这一步是 DPO 的核心洞察! 传统 RLHF 需要一个显式的奖励模型 r(x,y)。但这个公式告诉我们:奖励函数可以完全用最优策略和参考策略的对数概率比来表示。换言之,最优策略本身就隐式地"编码"了奖励信息。 这个变换被称为重参数化技巧(Reparameterization Trick):我们不再需要显式地学习奖励函数 r(x,y),而是直接学习策略 πθ,然后通过上述公式隐式地得到奖励。 实践中我们用参数化策略 πθπθ 来近似最优策略 π∗
$$r(x,y)=\beta\log\frac{\pi_\theta(y|x)}{\pi_\mathrm{ref}(y|x)}+\beta\log Z(x)$$4、代入Bradley-Terry模型
将第三步得到的奖励表达式代入 Bradley-Terry 模型
$$r(x,y_w)-r(x,y_l)=\beta\log\frac{\pi_\theta(y_w|x)}{\pi_{\mathrm{ref}}(y_w|x)}+\beta\log Z(x)-\beta\log\frac{\pi_\theta(y_l|x)}{\pi_{\mathrm{ref}}(y_l|x)}-\beta\log Z(x)$$βlogZ(x)项只依赖于提示 x,在 yw 和 yl 之间做差时完全消去!
$$r(x,y_w)-r(x,y_l)=\beta\log\frac{\pi_\theta(y_w|x)}{\pi_\mathrm{ref}(y_w|x)}-\beta\log\frac{\pi_\theta(y_l|x)}{\pi_\mathrm{ref}(y_l|x)}$$最终,DPO 通过最大化偏好数据的对数似然来训练策略,即最小化负对数似然
$$\boxed{\mathcal{L}_{\mathrm{DPO}}(\pi_\theta;\pi_{\mathrm{ref}})=-\mathbb{E}_{(x,y_w,y_l)\sim\mathcal{D}}\left[\log\sigma\left(\beta\log\frac{\pi_\theta(y_w|x)}{\pi_{\mathrm{ref}}(y_w|x)}-\beta\log\frac{\pi_\theta(y_l|x)}{\pi_{\mathrm{ref}}(y_l|x)}\right)\right]}$$RLHF 问题通过四步推导,变成了一个简洁的监督学习损失,不需要训练奖励模型,不需要 PPO,不需要价值网络——只需要在偏好对上最小化这个损失。
Bradley-Terry 偏好模型和 KL 约束优化的核心思想 隐式奖励边际(Implicit Reward Margin)
$$\hat{r}_\theta(x,y)=\beta\log\frac{\pi_\theta(y|x)}{\pi_\mathrm{ref}(y|x)}$$DPO 本质上是在训练一个隐式的奖励模型,奖励定义为策略与参考策略的对数概率比。训练目标是让 chosen 回复的隐式奖励高于 rejected 回复的隐式奖励。 当优化进展顺利时:- 损失值较小 当优化不佳时:- 损失值较大,梯度推动模型修正
对 DPO 损失求关于参数 θ 的梯度:
$$\nabla_\theta\mathcal{L}_{\mathrm{DPO}}=-\beta\operatorname{E}\left[\underbrace{\sigma\left(\hat{r}_\theta(x,y_l)-\hat{r}_\theta(x,y_w)\right)}_{\text{权重项}}\left(\underbrace{\nabla_\theta\log\pi_\theta(y_w|x)}_{\text{提升 chosen}}-\underbrace{\nabla_\theta\log\pi_\theta(y_l|x)}_{\text{抑制 rejected}}\right)\right]$$sigmoid 项决定了梯度的强度 梯度推动模型增加 chosen 回复 ywyw 在给定提示 xx 下的生成概率。 梯度推动模型降低 rejected 回复 ylyl 在给定提示 xx 下的生成概率。
| 方面 | RLHF (PPO) | DPO |
|---|---|---|
| 需要的模型 | 4个(策略、参考、奖励、价值) | 2个(策略、参考) |
| 训练阶段 | 3个(SFT → RM → PPO) | 2个(SFT → DPO) |
| 奖励模型 | 显式训练 | 隐式(策略即奖励模型) |
| RL 循环 | 需要(PPO) | 不需要 |
| 训练稳定性 | 低(奖励黑客、KL 爆炸) | 高(简单的监督损失) |
| 内存需求 | 极高(4个模型) | 中等(2个模型) |
| 实现复杂度 | 高 | 低 |
| 在线探索 | 有(策略生成新回复) | 无(固定数据集) |
DPO优势:稳定简洁高效易实现
DPO局限:离线数据使用固定偏好数据集、策略优化后训练数据肯能过时数据中的(yw,yl) 可能与当前策略的生成分布相差甚远
DPO 不是换损失函数的 SFT
而是把 KL-regularized RL 的最优解,改写成一个对比式的监督训练目标。
优化的“目标结构”已经从 MLE(最大似然估计) 变成了 KL-regularized policy optimization
DPO 是 pairwise 对比结构
不是单点概率最大化。
DPO、SimPO、KTO、ORPO、IPO 等主要变体的设计理念与适用场景 DPO 的提出开创了"直接偏好优化"的范式,但它并非完美。
四种最重要的变体:SimPO、KTO、ORPO 和 IPO
SimPO:简单偏好优化
标准 DPO 存在两个实际问题: 需要参考模型:必须在内存中维护一个冻结的参考模型 对于大模型来说内存开销显著 对数概率与生成质量的不一致性:DPO 使用序列总对数概率(sum of log-probs)来衡量模型对回复的偏好度 但这一指标偏向于短回复(短回复的负对数概率累积更小) SimPO 用平均对数概率替代对数概率比作为隐式奖励:
$$\hat{r}_{\mathrm{SimPO}}(x,y)=\frac{1}{|y|}\log\pi_\theta(y|x)=\frac{1}{|y|}\sum_{t=1}^{|y|}\log\pi_\theta(y_t|x,y_{不需要维护冻结参考模型
KTO DPO 和 SimPO 都需要成对偏好数据——每条数据必须同时包含 chosen 和 rejected 回复。但在很多实际场景中:
- 人类标注者更自然的反馈方式是点赞/点踩(binary feedback),而非成对比较
- 成对偏好数据的收集成本更高
- 很多现有数据集只有单条回复的好坏标签 可以使用非配对的二值反馈进行训练。这意味着你可以用 (x1,y1,good)(x1,y1,good) 和 (x2,y2,bad)(x2,y2,bad) 来训练,其中 x1≠x2x1=x2——不需要同一个提示下的成对比较数据。这极大地扩展了可用数据的范围。 $$\mathcal{L}_{\mathrm{KTO}} = \mathbb{E}_{x, y \sim \mathcal{D}} \left[ w(y) \cdot \left(1 - v_{\mathrm{KTO}} \left(\beta, r_\theta(x, y)\right) \right) \right]$$
其中隐式奖励与 DPO 相同:
$$r_\theta(x, y) = \log \frac{\pi_\theta(y|x)}{\pi_{\mathrm{ref}}(y|x)}$$对于好回复($y$ 被标记为"好”):
$$v_{\mathrm{KTO}}(\beta, r) = \sigma \left(\beta \cdot r - \beta \cdot z_{\mathrm{ref}} \right)$$对于坏回复($y$ 被标记为"坏"):
$$v_{\mathrm{KTO}}(\beta, r) = \sigma \left(\beta \cdot z_{\mathrm{ref}} - \beta \cdot r \right)$$其中
$$z_{\mathrm{ref}} = \mathbb{E}_{(x', y') \sim \mathcal{D}} \left[ \mathrm{KL} \left( \pi_\theta(y'|x') \| \pi_{\mathrm{ref}}(y'|x') \right) \right]$$是一个参考点(reference point),体现了前景理论中的参考点依赖。
损失厌恶通过对好/坏回复赋予不同权重 $w(y)$ 来体现:
$w(y) = \begin{cases} \lambda_D & \text{if } y \text{ is desirable (好)} \\ \lambda_U & \text{if } y \text{ is undesirable (坏)} \end{cases}$
通常设置 $\lambda_U > \lambda_D$,使模型对"坏"回复更敏感——即损失厌恶。
ORPO:统一 SFT 和对齐 标准的后训练流程是两阶段的:先 SFT → 再 DPO。这带来了额外的训练成本和超参数调优负担。 ORPO(Odds Ratio Preference Optimization)(Hong 等,2024)将 SFT 目标和偏好优化合并为一个统一的损失函数:
$$\mathcal{L}_{\mathrm{ORPO}}=\underbrace{\mathcal{L}_{\mathrm{SFT}}(y_w)}_{\text{SFT 项}}+\lambda\cdot\underbrace{\mathcal{L}_{\mathrm{OR}}(y_w,y_l)}_{\text{偏好项}}$$SFT 项是标准的交叉熵损失(只在 chosen 回复上计算) 偏好项使用**几率比(Odds Ratio)来量化 chosen 和 rejected 的差异 在实践中,Pθ(y∣x) 用平均 token 概率近似 但两个损失项之间的平衡(λ)需要仔细调优 在某些基准上效果略逊于两阶段训练
IPO DPO 在理论上存在一个问题:当偏好数据中的偏好非常明确(chosen 明显优于 rejected)时,DPO 会推动隐式奖励边际趋向无穷大,导致过拟合。
$$\mathcal{L}_{\mathrm{IPO}}=\mathbb{E}\left[\left(\log\frac{\pi_\theta(y_w|x)}{\pi_\mathrm{ref}(y_w|x)}-\log\frac{\pi_\theta(y_l|x)}{\pi_\mathrm{ref}(y_l|x)}-\frac{1}{2\beta}\right)^2\right]$$IPO 使用平方损失,将对数概率比的差异约束在 1/2β 附近
实践考量
标准 DPO 使用一个预先收集好的固定偏好数据集进行训练,这被称为离线(Offline)DPO 在线 DPO 在训练过程中持续使用当前策略生成新的回复,并对其进行偏好标注 偏好对来自当前策略的生成分布,不存在分布偏移问题。在线 DPO 在多个基准上显著优于离线 DPO
| 方法 | 推荐学习率 | 原因 |
|---|---|---|
| SFT (LoRA) | 2e-5 ~ 2e-4 | 从零学习指令跟随能力 |
| DPO (LoRA) | 5e-7 ~ 5e-6 | 在已有能力基础上微调偏好 |
| SimPO (LoRA) | 5e-7 ~ 5e-6 | 同 DPO |
| 偏好优化通常只需要 1 个 epoch | ||
| 过多的训练会导致模型在 rejected 方向上过度抑制,降低多样性 |
(以下为假设结果,仅供面试理解) 实验3:DPO对齐与SimPO对比 评测集 ~500 条通用指令 + ~200 条安全/红队提示;胜率由 LLM-as-Judge 做成对比较得到。 DPO、SimPO 都明显优于纯 SFT(胜率 60%±) DPO vs SimPO 往往非常接近,SimPO可能略胜在“更少废话/更少过度拒绝/更稳的可用性”,但差距通常不大。
SFT vs DPO vs SimPO:有用性 / 安全性 / 多样性 得分对比表
- DPO:安全性提升最明显,但会带来一点“保守化/模板化”(多样性略降)。
- SimPO:安全性也涨,但通常更不容易把一切都拒掉,回答风格更“正常”,多样性往往能回到甚至略超 SFT。 DPO loss 曲线:一条“先陡降、后缓降、末尾平台”的曲线,末尾抖动略小。 SimPO loss 曲线:形状与 DPO 类似,但平台略高一点(不一定代表更差,更多是目标函数尺度不同/优化更稳)。
Reward margin 曲线 两条单调上升曲线,DPO整体略高、SimPO更平滑。
训练时间 & 显存对比 DPO 通常更“重”(chosen/rejected 成对、可能还涉及 reference logprob 的处理方式),SimPO往往更省一些。
安全测试结果 DPO 最“硬”,SimPO 稍微松一点但仍显著优于 SFT。
β 消融实验(0.05 / 0.1 / 0.5) β=0.05 更“好用”,但安全提升有限;β=0.5 安全最强但明显过度拒绝;β=0.1 往往是较平衡的折中点。
LLM-as-Judge 自动评分(强模型打分的典型结果长相) 总体偏好胜率(相对 SFT):
- DPO:+25~30 个百分点(例如 65%)
- SimPO:+18~25 个百分点(例如 60%)
今天就先到这里了,明天把第四课看完就把实验4正儿八经跑一轮,填到简历里再优化一下排版,直接开始海投。