☰
从预训练到后训练:SFT与RLHF实战指南
2026/10/7 5:37:04 网站建设 项目流程

1. 从预训练到后训练:一条被低估的分水岭

如果你这两年一直在跟大模型打交道,大概率会有一种感觉:预训练(Pre-Training)决定模型的下限,后训练(Post-Training)决定模型的上限。这句话我第一次听到的时候觉得有点绝对,但真正自己动手做过几轮SFT和RLHF之后,我越来越认同。预训练像是给模型打地基、灌通识,后训练才是把它从一个"什么都懂一点但什么都不精"的博学少年,调教成一个能干活、听得懂人话、不胡说八道的靠谱员工。

这篇文章我想系统聊聊Post-Training这件事——它的前世是怎么来的,今生大家都在用什么方法,未来可能往哪走。核心会围绕几个关键词展开:Post-Training、Pre-Training、Fine-Tuning、SFT、RL-Based Post-Training。不管你是刚入行想搞清楚这几个概念区别的新人,还是已经在做微调但想理清整体脉络的工程师,我都尽量把话说透,把踩过的坑和实操细节摊开讲。

先说清楚定位:这篇文章不是论文综述,也不是官方文档翻译,而是一个一线从业者对整条技术脉络的梳理和实战总结。我会解释每个阶段"为什么这么做",会给出可参考的参数和流程,也会分享一些文档里不会写的经验。读完之后,你应该能自己判断:手上这个任务,到底该用SFT还是上RL,数据该怎么准备,坑在哪里。

2. Post-Training的前世:它到底是怎么被逼出来的

2.1 预训练时代的"能力过剩"困境

要讲后训练的前世,得先回到预训练本身。早期的语言模型,比如GPT-1、BERT那个阶段,大家的核心思路是:用海量无标注文本做自监督学习,让模型学会语言的统计规律。BERT用的是掩码语言建模(Masked Language Modeling),GPT系列用的是自回归预测下一个token。这个阶段的目标很纯粹——让模型"读懂"语言。

但问题很快就暴露了。一个只在预训练目标上训练出来的模型,本质上是一个"文本续写机器"。你给它一句话,它会顺着概率往下写,但它并不理解"指令"这个概念。比如你输入"帮我写一封请假邮件",预训练模型可能会续写出"帮我写一封请假邮件,帮我写一封辞职邮件,帮我写一封……"这种复读机式的输出。这不是模型笨,而是它的训练目标里根本没有"遵循指令"这一项。

我在早期做实验的时候深有体会:一个几十亿参数的预训练模型,知识储备其实相当可观,但你没法直接用它,因为它不听话。你想让它做A,它偏要做B,输出格式也完全不可控。这就是所谓的能力过剩但可控性为零——模型有能力,但你调不动它。

2.2 从Fine-Tuning到SFT:第一次"驯化"

解决这个问题的第一代方案就是Fine-Tuning(微调)。最朴素的做法是:拿一批"输入-输出"配对的数据,在预训练模型基础上继续训练,让模型学会针对特定输入给出特定输出。这在BERT时代非常流行,比如文本分类、命名实体识别,都是拿标注数据微调。

但真正让"指令遵循"这件事跑通的,是SFT(Supervised Fine-Tuning,监督微调)。SFT和传统Fine-Tuning的核心区别在于:SFT的数据是"指令-回答"格式的,目标是让模型学会"看到指令就给回答"这个行为模式。OpenAI在InstructGPT那篇工作里把这个思路讲得很清楚——他们雇了一批标注员,写了几万条高质量的指令-回答对,然后拿这些数据去微调GPT-3,结果模型在遵循指令上的表现大幅提升。

我自己的经验是,SFT的效果对数据质量极其敏感。同样是1万条数据,精心写的和随便爬的,效果能差出一个档次。这里有个反直觉的点:SFT不是让模型学新知识,而是让它学会"以什么格式、什么风格、什么态度"来输出它已经知道的东西。所以数据量不是关键,数据的示范性和一致性才是关键。

2.3 为什么SFT还不够:对齐问题的浮现

SFT解决了"听不听话"的问题,但没解决"听得好不好"的问题。具体来说,SFT有几个绕不过去的坎:

第一,SFT只能模仿,不能超越。模型学的是标注员写的答案,标注员的水平就是模型的上限。如果标注员写得不完美,模型就学得不完美。

第二,SFT难以处理"多答案"场景。同一个问题可能有多个合理回答,SFT会让模型在这些答案之间"平均",结果可能哪个都不像。

第三,SFT无法表达偏好。人类对回答的偏好是相对的——"这个回答比那个好",而不是绝对的"这个回答是对的"。SFT的监督信号是绝对的对错,表达不了这种相对偏好。

正是这些局限,催生了RL-Based Post-Training(基于强化学习的后训练)。这就是后训练"今生"的主线故事。

3. Post-Training的今生:SFT与RL的双轮驱动

3.1 SFT依然是地基,但定位变了

现在业界主流的后训练流程,基本是**"预训练 → SFT → RL"三段式**。SFT的角色从"最终方案"变成了"打底方案"。它的任务是把模型拉到一个"基本能用"的状态,为后面的RL提供一个合理的起点。

为什么RL需要SFT打底?因为强化学习本质上是在一个策略空间里搜索,如果起点太差,搜索效率极低,甚至训崩。SFT相当于把模型先放到一个"及格线"附近,RL再从这个位置往上推。我试过跳过SFT直接上RL,结果模型输出乱七八糟,奖励信号根本没法有效传导,纯属浪费时间。

SFT阶段有几个实操要点值得说:

  • 数据配比:不要只堆某一类任务。指令多样性比数量重要。我一般会保证任务类型覆盖至少10个大类,每类几百到几千条不等。
  • 数据质量:宁缺毋滥。一条低质量数据带来的负面影响,可能需要十条高质量数据才能抵消。
  • 训练轮数:通常1-3个epoch就够,多了容易过拟合,模型会变得"死板",丧失泛化能力。
  • 学习率:比预训练小一到两个数量级,常见在1e-5到2e-5之间。

提示:SFT阶段最容易被忽视的是"负样本"的处理。如果你的数据里混入了错误示范,模型会照单全收。清洗数据这一步,花多少时间都值得。

3.2 RL-Based Post-Training:从RLHF到更细的分支

RL-Based Post-Training的核心思想是:不再告诉模型"标准答案是什么",而是告诉它"哪个答案更好",让模型自己去优化。这条线最早的代表是RLHF(Reinforcement Learning from Human Feedback),后来演化出一堆变体。

RLHF的经典流程分三步:

  1. SFT:先做监督微调,得到基础策略模型。
  2. 训练奖励模型(Reward Model, RM):让人类对同一问题的多个回答进行排序,用这些排序数据训练一个能打分的模型。
  3. RL优化:用RM作为奖励信号,通过PPO等算法优化策略模型,让它生成RM打分更高的回答。

这套流程的问题也很明显:流程复杂、训练不稳定、对RM质量极度依赖。PPO本身调参就够头疼了,再加上RM的偏差,整个系统像个精密但脆弱的仪器。我见过太多团队卡在PPO不收敛上,最后不了了之。

后来出现了DPO(Direct Preference Optimization),思路是把"训练RM + RL优化"两步合并成一步,直接用偏好数据优化策略模型。DPO的好处是简单、稳定,不需要单独训RM,也不需要PPO那套复杂的采样和优势估计。实测下来,DPO在很多场景下能达到接近RLHF的效果,但工程复杂度低了一个量级。

再往后,又出现了GRPO、KTO、ORPO等一系列变体,各有侧重。GRPO去掉了价值网络,用组内相对奖励来估计优势;KTO只需要"好/坏"二元标签,不需要成对偏好;ORPO把SFT和偏好优化合并。这些方法的共同趋势是:降低对标注数据的依赖,简化训练流程,提升稳定性。

3.3 方法选型:到底该用哪个

面对这么多方法,实际项目里怎么选?我整理了一个简单的判断表:

方法数据需求训练复杂度稳定性适用场景
SFT指令-回答对低高基础能力对齐、格式控制
RLHF (PPO)偏好排序 + RM高低追求极致效果、有充足资源
DPO成对偏好数据中中高大多数偏好对齐场景
GRPO成对偏好数据中中高推理类任务、需要组内对比
KTO二元好坏标签中中高标注成本敏感场景

我的建议是:除非你有明确证据表明DPO类方法不够用,否则优先从DPO或GRPO入手。RLHF那套PPO流程,除非团队里有专门做RL的人,否则投入产出比不高。

4. 核心细节拆解:数据、奖励与训练稳定性

4.1 数据:后训练的真正瓶颈

做后训练做久了会发现,算法是次要的,数据才是核心。同样的DPO算法,数据质量差一个档次,效果差出十万八千里。后训练的数据大致分三类:

  • SFT数据:指令-回答对,要求示范性强、格式统一、覆盖多样。
  • 偏好数据:同一输入下的多个回答及排序,要求标注一致、区分度明显。
  • 奖励数据:用于训练RM的打分数据,要求评分标准清晰、标注员培训到位。

偏好数据的标注有个大坑:标注员之间的不一致性。同一个回答,A标注员觉得好,B标注员觉得差,这种噪声会直接污染训练信号。解决办法是制定详细的标注指南,做标注员一致性校验(比如计算Kappa系数),并且定期抽检。

另一个坑是偏好数据的区分度。如果两个回答质量差不多,标注员硬要分个高下,这种数据对训练是有害的。我一般会要求标注员在"两个都好"或"两个都差"时明确标注,这类数据要么丢弃,要么单独处理。

4.2 奖励模型:RLHF的命门

如果你走RLHF路线,RM的质量直接决定最终效果。RM训练有几个关键点:

  • RM的容量要匹配:RM太小,学不到细粒度偏好;RM太大,容易过拟合标注噪声。一般和策略模型同量级或略小。
  • RM的偏差会被放大:RL优化会疯狂寻找RM的漏洞,生成"高分但实际很差"的回答,这就是所谓的reward hacking。缓解办法包括:加KL惩罚约束策略不要偏离SFT模型太远、定期用人类评估校准RM、使用多个RM集成。
  • RM的评估:不能只看RM在验证集上的准确率,还要看它和人类判断的一致性。我一般会保留一批人工评估数据,专门用来检验RM。

注意:reward hacking是RLHF最隐蔽的坑。模型可能学会输出又长又啰嗦但看起来很"全面"的回答,因为RM可能被长度带偏。训练时一定要监控输出长度分布,发现异常及时调整。

4.3 训练稳定性:那些文档不会告诉你的事

后训练的训练稳定性问题,比预训练更棘手。几个我踩过的坑:

KL散度爆炸:RLHF里KL惩罚系数设小了,策略会跑飞;设大了,模型学不动。这个系数需要根据实际训练曲线动态调整,没有万能值。

奖励崩塌:训练到某个点,奖励突然掉下去,模型输出变得重复或无意义。这通常是学习率过大或KL约束失效导致的。解决办法是降低学习率、增大KL系数、或者回滚到之前的checkpoint。

DPO的隐式奖励偏移:DPO虽然稳定,但如果偏好数据里"好回答"和"坏回答"的差异太小,模型学到的信号很弱。这时候需要提高数据质量,或者调整beta参数(控制偏离参考模型的程度)。

GRPO的组大小选择:GRPO需要为每个prompt采样一组回答,组大小太小,优势估计噪声大;太大,计算成本高。一般4-8比较合适,具体看任务。

5. 实操过程:一次完整的后训练流程复现

5.1 环境与工具准备

假设你要做一次标准的SFT + DPO后训练,需要准备的东西:

  • 基座模型:选一个开源基座,比如7B或13B量级,根据你的算力决定。
  • 训练框架:HuggingFace TRL是目前最方便的选择,SFT、DPO、PPO、GRPO都有现成实现。DeepSpeed或FSDP做分布式训练。
  • 数据:SFT数据至少几千条高质量指令对,DPO数据至少几千条偏好对。
  • 算力:7B模型全量SFT大概需要几张A100;如果资源紧张,用LoRA做参数高效微调。

环境配置大致如下:

pip install transformers trl peft accelerate deepspeed datasets

5.2 SFT阶段实操

SFT的数据格式一般是JSONL,每行一个样本:

{"instruction": "解释什么是过拟合", "input": "", "output": "过拟合是指模型在训练数据上表现很好,但在未见过的数据上表现差……"}

用TRL的SFTTrainer,核心参数:

from trl import SFTTrainer, SFTConfig config = SFTConfig( output_dir="./sft_output", num_train_epochs=2, per_device_train_batch_size=4, gradient_accumulation_steps=8, learning_rate=2e-5, lr_scheduler_type="cosine", warmup_ratio=0.03, logging_steps=10, save_strategy="epoch", bf16=True, max_seq_length=2048, )

几个参数选择的理由:学习率2e-5是SFT的常见起点,太大容易破坏预训练知识,太小收敛慢;warmup 3%是为了避免训练初期梯度震荡;bf16比fp16更稳定,不容易出现loss NaN。

训练过程中重点看两个指标:训练loss和验证loss。如果训练loss持续下降但验证loss开始上升,说明过拟合了,该停。如果loss震荡剧烈,检查学习率和batch size。

5.3 DPO阶段实操

DPO的数据格式是三元组:prompt、chosen、rejected。

{"prompt": "写一首关于秋天的诗", "chosen": "秋风起,落叶黄……", "rejected": "秋天到了,天气凉了……"}

DPO训练的核心参数:

from trl import DPOTrainer, DPOConfig config = DPOConfig( output_dir="./dpo_output", num_train_epochs=1, per_device_train_batch_size=2, gradient_accumulation_steps=8, learning_rate=5e-6, beta=0.1, bf16=True, max_length=2048, max_prompt_length=1024, )

beta参数是DPO的关键,它控制模型偏离参考模型的程度。beta越大,约束越强,模型越保守;beta越小,模型越激进。0.1是个常用起点,实际要根据效果调。我一般会试0.05、0.1、0.3三档,看哪个在验证集上表现最好。

DPO训练时重点监控隐式奖励的差值(chosen和rejected的log概率差)。如果这个差值一直不涨,说明模型没学到东西,可能是数据区分度不够或beta设置不当。

5.4 评估:别只看loss

后训练的评估是最容易被糊弄的环节。loss降了不代表模型变好了。我一般会做三层评估:

  • 自动评估:用GPT-4类模型做裁判,对回答质量打分。方便但有小偏差。
  • 人工评估:抽样一批输出,人工打分。成本高但最可靠。
  • 专项测试:针对你的目标能力设计测试集,比如格式遵循率、事实准确率、拒绝率等。

提示:一定要保留一个"训练时没见过"的测试集。我见过太多团队在训练集上评估,结果上线后效果崩盘。

6. 常见问题与排查技巧实录

6.1 后训练高频问题速查

问题现象可能原因排查方向解决办法
SFT后模型变"傻"学习率过大、数据质量差检查loss曲线、抽样数据降学习率、清洗数据
DPO不收敛beta不当、数据区分度低看隐式奖励差值调beta、筛数据
RLHF奖励崩塌KL约束失效、reward hacking监控KL和输出长度增大KL系数、加长度惩罚
输出重复训练过度、解码参数问题检查epoch数和temperature减epoch、调解码参数
格式不遵循SFT数据格式不统一检查数据模板统一格式、增加格式样本
拒绝能力差缺少安全/边界数据检查数据覆盖补充拒绝类样本

6.2 几个独家避坑经验

第一,SFT数据里的"完美答案"未必是好事。如果所有回答都写得像教科书,模型会变得过于正式、缺乏灵活性。适当加入一些口语化、简洁的回答,能让模型输出更自然。

第二,DPO的chosen和rejected不要差异太大。如果chosen是满分回答,rejected是垃圾,模型学到的信号太粗,泛化差。理想情况是两者质量有差距但差距适中,让模型学到细粒度的偏好。

第三,RL训练一定要设checkpoint回滚机制。RL训练崩是常态,没有回滚机制,一次崩盘可能浪费几天算力。我一般每几百步存一次,发现异常立即回滚。

第四,评估集要"防污染"。如果你的评估数据不小心混进了训练集,评估结果会虚高。我一般会用哈希去重,确保训练集和评估集零重叠。

第五,别迷信大而全。后训练不是数据越多越好。一个精心设计的几千条数据集,效果可能超过几万条粗糙数据。质量永远优先于数量。

7. Post-Training的未来:几个值得关注的方向

7.1 从"对齐"到"能力增强"

早期的后训练主要解决"对齐"问题——让模型听话、安全、有用。但现在的趋势是,后训练开始承担"能力增强"的角色。比如推理能力,很多工作表明,通过RL后训练可以显著提升模型的数学和代码推理能力。这不再是简单的对齐,而是在预训练基础上"逼"出新的能力。

这个转变的意义很大:它意味着后训练不再只是"锦上添花",而是可能成为模型能力的"第二增长曲线"。预训练的边际收益在放缓,后训练的想象空间反而更大了。

7.2 数据效率与自动化

后训练最大的成本是数据标注。未来的方向一定是用更少的人工标注,撬动更大的效果。几个思路:

  • AI反馈替代人工反馈:用强模型给弱模型的输出打分,即RLAIF。成本低,但要注意偏差传递。
  • 自我博弈与自我改进:让模型自己生成数据、自己评估、自己迭代。这条路有潜力,但容易陷入自我强化的偏差。
  • 合成数据:用强模型生成训练数据。关键是保证多样性和真实性,避免模式坍塌。

7.3 多模态与Agent场景的后训练

现在的后训练方法大多针对纯文本。但随着多模态模型和Agent的兴起,后训练要处理的东西更复杂了:图像、动作、工具调用、多轮交互。这些场景下的偏好定义、奖励设计、数据标注,都是全新的问题。

比如Agent场景,一个动作的好坏不能只看单步,要看整个任务是否完成。这种"延迟奖励"的处理,比文本生成难得多。我预计未来几年,Agent后训练会是一个热门方向。

7.4 训练与推理的融合

还有一个有意思的趋势:后训练和推理的边界在模糊。比如一些工作把推理时的搜索、验证能力,通过后训练"内化"到模型参数里。反过来,也有一些方法在推理时做动态的偏好优化。这种融合可能会催生新的训练范式。

8. 我个人的一些体会

做了这么多轮后训练,最大的感受是:这活儿七分靠数据,两分靠算法,一分靠运气。算法层面的创新层出不穷,但真正决定效果的,往往是你有没有把数据这件事做扎实。我见过太多团队在算法上反复折腾,却不愿意花时间清洗数据、设计标注指南,最后效果上不去,还以为是算法不行。

另一个体会是:后训练没有银弹。SFT、DPO、RLHF各有适用场景,没有哪个方法能通吃。实际项目里,往往是组合使用——先SFT打底,再DPO对齐,必要时上RL精调。关键是理解每个方法解决什么问题、有什么局限,然后根据手头的资源和目标做取舍。

最后分享一个小技巧:后训练的效果,很多时候在数据准备阶段就决定了。与其在训练时反复调参,不如在数据上多花一倍时间。我现在的习惯是,数据准备和清洗的时间,至少占总时间的60%。这个比例听起来夸张,但实测下来,它带来的收益远超在算法上的折腾。

后训练这个领域变化很快,今天好用的方法明天可能就被新的替代。但底层逻辑是不变的:让模型更好地理解人类意图,更可靠地完成人类任务。抓住这个核心,具体方法怎么变,都不会迷路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询