Part 5 · Training / Fine-tuning 训练与微调

5.4 Alignment & Validation 偏好对齐,与怎么证明它真的能用

难度 ★★★ 阅读 ~15 min 面试出现频率 中高 前置 5.1 – 5.3
故事线 第 4 段 · 验证效果

模型训完了。目标任务上的类别准确率 95%,超过了 94% 的教师基线;单次推理延迟从 2.3 秒降到 0.4 秒,成本按预期大幅下降。

皆大欢喜——但团队里有人问了一个问题:我们怎么知道它没有在别的地方偷偷变笨?以及更根本的:这个 95% 能不能代表它上线后的真实表现?

Core Concept 核心概念

先说对齐:SFT 之后还缺什么

5.3 讲的 SFT 教模型「照着这些示范做」。但有一类需求是示范教不了的:当存在多个都不算错的输出时,哪个更好?摘要是详细些好还是简洁些好?语气该多正式?拒绝一个不合理请求时该怎么措辞?

这类偏好难以写成标准答案,却容易做比较——给人看两个输出,问哪个更好,人几乎总能回答。preference alignment(偏好对齐)就是利用这种「比较比生成容易」的不对称性。

同样的偏好数据,两条路径 RLHF:训一个奖励模型,再用强化学习去最大化它 偏好数据 训练奖励模型 强化学习优化策略 对齐后的模型 两阶段,需采样、需调参,工程复杂度高 DPO:跳过奖励模型,直接在偏好数据上做一次策略训练 偏好数据 单阶段策略训练(本质是一个分类问题) 对齐后的模型 稳定、轻量,无需拟合奖励模型或训练中采样
图 1 · 两条对齐路径。DPO 的洞察是:奖励函数与最优策略之间存在一个映射关系,因此那个受约束的奖励最大化问题,可以用单阶段的策略训练直接求解——本质上变成了在偏好数据上解一个分类问题。奖励模型这个中间产物,从必需变成了可选。

对应用层团队的实用判断:绝大多数微调项目只需要 SFT,不需要偏好对齐。当你的任务有明确的对错标准(分类、抽取、结构化输出),SFT 就够了。只有当「什么算好」本身难以定义、只能靠比较来表达时,才值得引入 DPO 这一层。而在那之前,先确认 SFT 的数据质量已经榨干了——多数被归因为「需要对齐」的问题,其实是 SFT 数据不够好。

验证:训练完成不等于可以上线

本章真正的重点在这里。微调模型的验证有三个层次,缺一层就可能上线一个看起来很好的坏模型:

层次回答什么问题做法漏掉会怎样
① 目标任务训练的这件事做好了吗独立 eval set,按类别分桶看指标被总体指标掩盖的长尾崩塌
② 能力回归别的能力有没有退化与训练任务无关的通用测试集灾难性遗忘悄悄发生,接入更复杂流程时才爆
③ 三方对比相比教师和基座各如何学生 / 教师 / 未微调基座,同一 eval set不知道提升是否来自微调,也不知道离教师还差多远

eval set 设计的三条硬规则

① 必须按时间切分,不能随机切分。这是最重要的一条。随机切分会让训练集和评估集来自同一时间段的同一批数据——近似重复的样本可能同时出现在两边,评估分数因此被系统性高估。正确做法是用训练数据之后时间段的样本做评估,这同时还检验了模型对分布漂移的适应性。

② 必须覆盖长尾。如果 eval set 按真实分布采样,那么长尾类别可能只有几个样本,指标毫无统计意义。应当对长尾类别过采样,保证每个类别都有足够的样本量,然后分类别报告而不是报一个加权总分。

③ 必须包含已知的难例。把历史上教师模型出过错的样本、人工修正过的样本、业务上最关键的边界情况单独收集成一个子集。这个子集的表现比总体准确率更能预测上线后的真实体验——因为用户不会平均地遇到问题,他们遇到的正是这些难例。

数据泄漏是微调项目最常见的自欺。症状是「离线评估 96%,上线后感觉完全不对」。除了时间切分,还要主动检查评估集与训练集之间的近似重复(用 5.3 的去重方法跨集合跑一遍)。一个被污染的评估集,比没有评估集更危险——因为它给了你虚假的信心。

上线:影子模式 → 灰度 → 全量

离线评估再充分,也无法完全预测线上表现。三段式上线是把风险切碎的标准做法:

① 影子模式(shadow mode)。新模型与线上模型并行接收真实流量,但输出不生效,只记录下来做对比。这是最有价值的一步——它用真实的线上分布验证模型,且零风险。运行一到两周,你会发现离线评估集里根本没有的输入形态。

② 灰度发布。从很小的流量比例开始,按业务指标(而非离线指标)逐步放量。关键是监控要能按模型版本分桶,否则新旧模型的表现会被混在一起。

③ 保留回退通道。必须能一键切回教师 API。故事线在 5.1 就把这条写进了退出条件——回退能力不是上线后再补的,是设计时就要保证的(6.5)。

Case Study 真实案例

DPO:把两阶段压成一阶段

Direct Preference Optimization: Your Language Model is Secretly a Reward Model (NeurIPS 2023)

在 DPO 之前,用人类偏好调整模型行为的标准路径是 RLHF:先在偏好数据上拟合一个奖励模型,再用强化学习去最大化这个奖励。这条路径有效,但工程上很重——两个阶段、训练中需要从模型采样、超参数敏感。

Rafailov 等人的贡献是指出:利用奖励函数与最优策略之间的映射关系,这个受约束的奖励最大化问题可以用单阶段的策略训练来求解——本质上变成在偏好数据上解一个分类问题。

单阶段
无需先拟合奖励模型
无需采样
微调过程中不必从语言模型采样
轻量稳定
论文称其稳定、高效,且无需大量超参调优
效果持平或更好
在与人类偏好对齐上不逊于既有方法

这项工作对应用层的意义在于降低了门槛:偏好对齐从「需要一支 RL 团队」变成了「和 SFT 差不多的一次训练」。今天各类微调框架普遍内置 DPO 训练器,一个小团队可以在几天内跑通。

但门槛降低的只是训练那一环——真正的成本转移到了偏好数据的收集上。你仍然需要成对的「A 比 B 好」标注,而这需要明确的偏好标准和一致的标注者。当一项技术的某个环节被大幅简化时,瓶颈通常只是移动到了别处,而不是消失了;此处它移到了数据,这与 5.3 的结论一致。

条件说明:论文的对比在其选定的任务与基线上进行。DPO 与 RLHF 及后续各类变体的优劣仍是活跃的研究领域,不应把「DPO 全面优于 RLHF」当作定论。对应用层团队而言,可迁移的判断是:需要偏好对齐时,DPO 通常是工程上更可行的起点。

来源:Rafailov, Sharma, Mitchell, Manning, Ermon, Finn, "Direct Preference Optimization: Your Language Model is Secretly a Reward Model", NeurIPS 2023. 结论引自论文摘要;示意图为本书重绘。

故事线(完):它真的能用吗

工单结构化任务 · 三层验证与上线

① 目标任务:分类别看,而不是看总分。总体准确率 95% 确实超过了教师的 94%。但按类别分桶后暴露了真相——高频类别上学生已经优于教师,而在两个长尾类别上仍明显落后。若只看总分,这个差距会被完全掩盖。

处理:对这两个长尾类别做专门的数据补充(回到 5.3 补样本),并在上线方案中加了一条兜底规则——当模型对这两类的预测置信度低于阈值时,路由回教师 API(2.3 的级联思路)。不是所有差距都必须靠训练填平,架构上绕过去往往更快更稳。

② 能力回归:发现了一处预期外的退化。用一组与工单无关的通用测试样本跑回归,发现模型在多轮对话的指令遵循上有可察觉的下降——它太习惯于「输入一段文本、输出一个 JSON」,对多轮交互的适应变差了。

对当前用途没有影响(这个任务本来就是单轮的),但团队把这一点明确记录在模型卡里:此模型不适用于多轮场景。这条记录后来阻止了另一个团队把它误用在对话产品上。能力回归测试的价值,往往不在于阻止本次上线,而在于划清这个模型的适用边界。

95% / 94%
学生 / 教师 总体类别准确率
长尾落后
两个低频类别仍不及教师,走置信度回退
76% → 95%
未微调基座 → 微调后,提升确来自训练
多轮能力↓
能力回归发现,已写入模型卡限定用途

③ 三方对比确认了提升的来源。未微调基座 76%、学生 95%、教师 94%——这组数字同时说明了两件事:提升确实来自微调(而非评估集变简单了),且学生在总体上已达到教师水平。缺少基座这一列,你就无法排除「评估集本身偏易」的可能。

④ 上线:影子模式跑了两周。这一步的收获超出预期——真实流量里出现了离线评估集中完全没有的输入形态:超长工单(用户粘贴了整段日志)、多语言混杂、以及几乎空白的工单。这些在历史日志采样中被过滤掉了,却在真实流量里稳定地出现。团队据此补了输入长度截断和空输入的兜底逻辑,然后才开始灰度。

故事线的结论:这个项目最终成立,靠的不是模型训得多好,而是四件事——① 动手前先把便宜的手段榨干并定下退出条件(5.1);② 选了与任务匹配、留有余量的配置(5.2);③ 把绝大部分精力花在数据而非调参上(5.3);④ 用三层验证和影子模式,在真正影响用户之前发现了三处问题(5.4)。其中任何一步偷懒,结局都可能是一个离线 95%、线上翻车的模型。

说明:本故事线为综合多个真实项目的匿名化叙事,不含任何可识别的公司、产品或个人信息。全部数字为便于演算设定的示例假设,非某次具体实验的测量数据。
Tooling Sidebar 工具层
对齐与验证的工具(会过期,正文不依赖本区块) 截至 2026-10

DPO 及其变体:HuggingFace trl 提供 DPOTrainer,Axolotl / LlamaFactory(原名 LLaMA-Factory)均已集成。社区还有 ORPO、KTO、SimPO 等变体,各自在数据要求或训练稳定性上有取舍。先用 DPO 跑通,再考虑是否需要变体——变体带来的差异通常小于数据质量带来的差异。

能力回归测试集:可以从公开评测集里取一个小子集(MMLU、IFEval 等各抽一两百条)作为快速回归。不需要跑完整基准——你要检测的是「有没有明显退化」,不是刷榜,几百条足以发现问题且几分钟就能跑完。

实验追踪:Weights & Biases、MLflow 等记录超参、指标、数据集版本的对应关系。「哪个模型是用哪版数据、哪组超参训的」必须可追溯,否则几轮迭代之后你会完全无法归因。

模型卡(model card):为每个微调模型写一份简短说明——训练数据来源与时间范围、目标任务、已知的能力退化与不适用场景、评估结果(分类别)、回退方案。这份文档的主要价值是防止别人误用你的模型,故事线里正是它阻止了一次误用。写它只要半小时。

影子模式的实现:在服务层把请求复制一份给新模型,异步记录输出但不返回给用户。注意成本——影子期间两个模型都在跑,要计入预算;也要注意幂等性,影子调用绝不能触发任何写操作或副作用。

Quiz 自测

章末自测

概念题为什么 eval set 必须按时间切分,而不能从训练数据里随机切一部分出来?

因为随机切分会造成数据泄漏,让评估分数系统性高估。

真实业务数据里存在大量近似重复——同一模板生成的工单、同一用户的连续提交、批量导入的相似记录。随机切分时,一条样本的「近亲」极可能同时落在训练集和评估集里。模型在训练时见过它的近亲,评估时自然答得很好,但这测的是记忆,不是泛化。

按时间切分解决两个问题:① 天然隔离了近似重复——同一批次产生的相似样本会一起落在同一侧;② 额外检验了分布漂移——真实上线面对的永远是「训练之后」的数据,用户行为、产品形态、话题热点都在变。按时间切分的评估更接近上线后的真实条件。

补充措施:即使按时间切了,仍应跨集合跑一次近似去重检查,确认没有漏网的重复。这一步几分钟就能做完,却能避免「离线 96%、上线翻车」这类最令人困惑的失败。

场景判断微调模型在目标任务上全面超过教师,团队想直接全量替换。你会提出什么?

「全面超过」这个判断本身要先被检验,然后才谈上线方式。四点:

① 「全面」是按什么口径算的?总体准确率超过,不等于每个子集都超过。必须按类别、按输入长度、按难度分桶分别对比。故事线里正是分桶后才发现长尾类别仍落后于教师——而总分是超过的。

② 评估集有没有被污染?确认按时间切分,并跨集合做过近似去重检查。一个被污染的评估集会让「超过教师」这个结论毫无意义。

③ 能力回归做了吗?目标任务超过教师,不代表通用能力没退化。至少要跑一组无关的通用测试,并把发现的退化写进模型卡限定适用范围。

④ 直接全量替换是最大的问题。正确的路径是影子模式 → 灰度 → 全量:先并行接真实流量只记录不生效(能发现离线评估集里没有的输入形态,故事线里发现了三类),再小比例放量按业务指标观察,最后全量。并且必须保留一键切回教师 API 的通道。

可以补一句架构上的建议:即使全量切换,对模型置信度低的请求保留回退到教师的级联路径——这比「非此即彼」的替换稳健得多,成本增加也有限(2.3)。

面试题改编「SFT 和 DPO 分别解决什么问题?什么时候需要 DPO?」

SFT 教「照着这些示范做」。它需要「输入 → 期望输出」的样本对,适用于有明确对错标准的任务:分类、抽取、结构化输出、特定格式或风格的生成。

DPO 教「这两个都不错,但这个更好」。它需要成对的偏好数据,适用于「什么算好」难以写成标准答案、但容易做比较的场景:语气拿捏、详略取舍、拒绝请求时的措辞、开放式生成的整体质量。

核心区别:SFT 从单个正例学习,DPO 从成对的相对比较学习。后者能表达前者表达不了的信息——「A 和 B 都对,但 A 更好」这句话无法用示范样本表示。

什么时候需要 DPO:
• 任务有明确对错 → 只需 SFT,这覆盖了应用层的大多数微调项目;
• SFT 后模型「都对但就是不太好用」,且你能说清哪个更好却写不出标准答案 → 考虑 DPO;
• 但在此之前先确认 SFT 的数据质量已经榨干——很多被归因为「需要对齐」的问题,实际是 SFT 数据里存在不一致的示范。

加分:说清 DPO 相对 RLHF 的工程价值——利用奖励函数与最优策略的映射关系,把「拟合奖励模型 + 强化学习」的两阶段流程压成单阶段的策略训练,无需在微调中采样,稳定且轻量。同时点出门槛降低的只是训练环节,瓶颈转移到了偏好数据的收集与标注一致性上。