0. 引言
这一章讲的是大模型如何从底座模型变得可用。
原文说,本章重点是 SFT(监督微调),预训练和强化学习主要是总览,强化学习细节会放到下一章,不过Datawhale的组队学习没有下一章。
PT让模型会续写,SFT 模型会按指令回答,RLHF让模型更符合人类偏好。
不过说实话,我真的觉得这章原文也写得挺乱的,凑合看吧。
1. 主线
海量文本
PT预训练
底座模型
SFT 监督微调
指令模型
RLHF/PPO
DPO/SimPO
对齐后的助手模型
PT用的是从原始文本中自动构造出来的伪标签,所以本质上属于自监督学习。
SFT有明确的"问题---标准答案"对,是监督学习。
RLHF没有逐token的标准答案,而是依赖偏好和奖励来做序列决策优化。
DPO把这种偏好优化重新改回了像监督学习的形式。
2. 预训练
预训练学到的首先是续写能力,不是作为一个助手的能力。
GPT-1的范式意义也正在这里:先做大规模预训练,再做下游的微调,这条路线后来被大模型彻底放大。
预训练的核心目标很简单:
P ( x t ∣ x 1 , x 2 , ... , x t − 1 ) P(x_t\mid x_1,x_2,\dots,x_{t-1}) P(xt∣x1,x2,...,xt−1)
意思就是给定前文,预测下一个token。
所以预训练模型本质上是一个条件续写模型,它学到了大量语言规律和世界知识,但不会按助手模式回答你。
GPT-3的意义在于,它第一次让人强烈感受到规模大了,提示一下模型就能做很多事,但它仍然只是续写模型,不能稳定遵循复杂指令,幻觉和偏见也很严重。
3. SFT
SFT是这章的重点。
SFT是把续写模型变成问答模型,原文明确把它定义为构建指令遵循模型的第一步。
更直接一点说,SFT是让模型怎么把已有知识组织成回答。
这也是为什么SFT数据量远小于预训练数据,却能显著改变模型行为。
预训练学到的是底层能力,SFT学到的是回答的格式、风格、安全边界等。
3.1 SFT数据格式
SFT数据本质上就是问题 + 回答。
原文给了两种最常见格式:Alpaca和ChatML/ShareGPT。
Alpaca适合单轮任务:
{
"instruction": "翻译成英文",
"input": "你好",
"output": "Hello"
}
ChatML/ShareGPT适合多轮对话:
{
"messages": [
{"role": "system", "content": "你是客服助手"},
{"role": "user", "content": "怎么修改收货地址?"},
{"role": "assistant", "content": "请在订单详情页点击..."}
]
}
值得注意的是:
训练时只对答案部分算loss。
也就是Loss Masking。
Alpaca 只计算output部分的交叉熵损失,ChatML只对assistant token计算损失。
这里非常重要,因为它直接说明了SFT的训练目标就是"学会怎么回答"。
另一个训练细节是Teacher Forcing。
训练时,不管模型上一步预测得多差,下一步输入的仍然是真实答案前缀。这么做是为了让训练稳定,但也意味着训练和推理不完全一致,推理时要承受前一步犯错的后果。
3.2 高质量数据
SFT 阶段更重要的往往不是更多数据,而是更好的数据。
少量高质量样本,可以优于大规模普通样本。
原因很简单,预训练是学世界知识,所以规模很重要,但SFT是学行为模式,所以示范和质量最重要。
如果数据里有错误事实、伪引用、风格混乱、不懂装懂,模型就会把这些东西直接学成行为。
3.3 幻觉、遗忘、安全
SFT会提升可用性,但也会带来风险。
最典型的就是幻觉和灾难性遗忘。
幻觉的一个重要来源,而是训练样本里示范一种坏模式,面对不会的问题,也要把答案编得像真的一样。
灾难性遗忘说明,如果SFT做得过强、数据过窄,模型可能在学会特定回答风格的同时,损伤预训练阶段的通用知识能力。原文提到,在预训练末期混入高质量SFT数据比如用WSD(Warmup-Stable-Decay,预热-稳定-衰减),有时比完全分离的两阶段训练更好。这个现象也很有启发,说明预训练和后训练的边界,其实并没有那么明显。
安全就是"不输出有害内容"的能力,在SFT阶段就可以被显式示范出来。
4. RLHF
RLHF是一个训练框架。
基本流程:
SFT → 奖励模型RM → 强化学习微调
RLHF的核心动机在于,很多时候,人类很难写出唯一标准答案,但很容易判断两个回答谁更好,于是训练信号从标准答案变成了偏好的排序。
奖励模型RM的作用,就是把这种偏好变成可训练的连续信号。
常见写法是Bradley--Terry形式:
P ( y w ≻ y l ) = σ ( r ( x , y w ) − r ( x , y l ) ) P(y_w \succ y_l)=\sigma(r(x,y_w)-r(x,y_l)) P(yw≻yl)=σ(r(x,yw)−r(x,yl))
y w y_w yw和 y l y_l yl分别是人(或高级模型)觉得更好和更差的输出, x x x是输入。
如果好答案的奖励分数高于差答案,那么就应该奖励一下模型,让它更倾向于预测人类会选前者。
这个公式的意义在于,把离散的人类偏好,转成了可以求梯度的训练目标。
5. PPO
PPO是RLHF里常用的强化学习算法。
优势函数:
A ( s , a ) = Q ( s , a ) − V ( s ) A(s,a)=Q(s,a)-V(s) A(s,a)=Q(s,a)−V(s)
它的作用是减去基线,降低方差。
说白了就是防止把环境本来就容易得高分误算成这个动作很好。
优势函数通常采用GAE(广义优势估计)等方法去近似,用于PPO、A2C、TRPO等主流强化学习算法的策略更新。
GAE(广义优势估计):
TD误差: δ t V = r t + γ V ( s t + 1 ) − V ( s t ) δ_t^V=r_t+γV(s_t+1)−V(s_t) δtV=rt+γV(st+1)−V(st)GAE定义:
A t G A E = ∑ b = 0 ∞ ( γ λ ) b δ t + b V A_t^{GAE}=∑{b=0}^∞(γλ)^bδ{t+b}^V AtGAE=b=0∑∞(γλ)bδt+bV
GAE在偏差--方差之间提供可调平衡。
再看重要性采样比率:
r t ( θ ) = π θ ( a t ∣ s t ) π old ( a t ∣ s t ) r_t(\theta)=\frac{\pi_\theta(a_t|s_t)}{\pi_{\text{old}}(a_t|s_t)} rt(θ)=πold(at∣st)πθ(at∣st)
它的作用是衡量当前策略相对旧策略,把这个动作的概率改大了还是改小了,没有它就不能复用旧策略采样出来的数据。
clip目标:
L t clip ( θ ) = min ( r t ( θ ) A t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A t ) L_t^{\text{clip}}(\theta) = \min\Bigl( r_t(\theta)A_t,\; \text{clip}(r_t(\theta),1-\epsilon,1+\epsilon)A_t \Bigr) Ltclip(θ)=min(rt(θ)At,clip(rt(θ),1−ϵ,1+ϵ)At)
它最核心的作用就是不允许策略一步改太多,因为强化学习的训练很不稳定。
PPO loss通常写成:
L PPO = − E [ L t clip ] + c 1 L value − c 2 H ( π θ ) L^{\text{PPO}} = -\mathbb{E}[L_t^{\text{clip}}] + c_1L^{\text{value}} - c_2H(\pi_\theta) LPPO=−E[Ltclip]+c1Lvalue−c2H(πθ)
其中:
- 第二项训练value/critic。
- 第三项是熵正则,前面是负号,很明显我们要最大化该项,让每一种可能的动作的概率都更高,鼓励模型更多探索。
还有一个必须分清的点是KL惩罚,加在奖励函数上。
它是为了防止偏离参考模型太远:
r ′ ( x , y ) = r ϕ ( x , y ) − β K L ( π θ ( ⋅ ∣ x ) ∥ π ref ( ⋅ ∣ x ) ) r'(x,y)=r_{\phi}(x,y)-\beta\,\mathrm{KL}\bigl(\pi_\theta(\cdot|x)\,\|\,\pi_{\text{ref}}(\cdot|x)\bigr) r′(x,y)=rϕ(x,y)−βKL(πθ(⋅∣x)∥πref(⋅∣x))
r ϕ ( x , y ) r_{\phi}(x,y) rϕ(x,y)是奖励模型打的分。
主要防reward hacking,防止模型越来越会讨好RM。
6. DPO
PPO需要一个价值模型去评估每一步的 V V V,然后又需要一个奖励模型去给每一步打分,我个人觉得这其实有点蠢,因为我觉得最优策略的概率的比值本来就已经隐式地包含了奖励和价值的信息了,DPO解决了这个很蠢的问题。
然后DPO最美的地方,是它把偏好优化重新变成了监督学习问题的。
DPO去掉了奖励模型、优势函数和PPO这套复杂RL流程。
它的核心想法是:
最优策略相对参考策略的概率比,可以直接看成奖励。
所以DPO标志性的损失就写成:
L DPO = − log σ ( β log π θ ( y w ∣ x ) π ref ( y w ∣ x ) − β log π θ ( y l ∣ x ) π ref ( y l ∣ x ) ) \mathcal{L}{\text{DPO}} = -\log \sigma\left( \beta\log\frac{\pi\theta(y_w|x)}{\pi_{\text{ref}}(y_w|x)} - \beta\log\frac{\pi_\theta(y_l|x)}{\pi_{\text{ref}}(y_l|x)} \right) LDPO=−logσ(βlogπref(yw∣x)πθ(yw∣x)−βlogπref(yl∣x)πθ(yl∣x))
说人话就是:
让当前模型相对参考模型,更偏向好答案,而非差答案。
它是把PPO里很多显式的东西,在公式里隐式消掉了。
SimPO则进一步去掉了参考模型,不再和旧模型比,而是让好答案的概率直接大于差答案的概率,并加入长度归一化和margin。
代表性形式是:
L SimPO = − log σ ( β ∣ y w ∣ log π θ ( y w ∣ x ) − β ∣ y l ∣ log π θ ( y l ∣ x ) − γ ) \mathcal{L}{\text{SimPO}} = -\log \sigma\left( \frac{\beta}{|y_w|}\log \pi\theta(y_w|x) - \frac{\beta}{|y_l|}\log \pi_\theta(y_l|x) -\gamma \right) LSimPO=−logσ(∣yw∣βlogπθ(yw∣x)−∣yl∣βlogπθ(yl∣x)−γ)
β β β是温度系数,用于控制概率比的敏感度, γ γ γ是一个超参数,用于在SimPO中引入一个固定的margin,确保好的回答的概率比差的回答的概率高至少 γ γ γ
它主要处理两个问题:
- 继续省资源。
- 防止模型靠写更长来占便宜,因为很明显长的看上去确实好像更好。
7. 理解与反思
核心其实是在探讨一个问题:大模型的行为到底是如何被塑造出来的?
-
PT(预训练):基于海量文本的统计规律进行优化,建立了模型的基础续写能力和知识库,但此时的模型没有价值观,也不知道什么是好回答。
-
SFT(监督微调):通过引入人工示范数据,将人类期望的回答格式、组织逻辑和拒答规则转化为训练目标,帮模型建立起了基本的助手交互模式。
-
偏好优化(RLHF / DPO):将优化目标从模仿标准答案进一步转变为对齐人类偏好,通过强化学习奖励机制,约束模型在有用性、真实性和安全性上的表现。
这揭示了一个在工程实践中非常重要的逻辑:决定大模型最终形态的,是数据分布和优化目标。
模型本身没有是非观念,它只会严格按照目标函数去收敛。
理解这一章不在于单纯对比哪种算法更先进,而在于认识到大模型训练的每一步,本质上都是在通过不同的数学手段和数据,重新定义你期望得到一个什么样的系统,重要的是数据是目标。