大模型微调技术详解
模型微调
摘要:一文看懂生产阶段大模型微调全路线!先搞懂何时该微调,再拆解 PEFT 的省显存魔法(LoRA/QLoRA),最后对比 RLHF、DPO、GRPO 三大对齐流派,附五类方案对比表,帮你选对技术栈。
什么时候需要微调?
当前 优化Prompt 、加 Few-shot 示例,或者用 RAG 接外部知识,都无法解决你的问题时。
微调的两种分类标准
- 改哪些参数
全量微调(Full Fine-tuning)(模型权重 θ \theta θ全部更新)、参数高效微调(PEFT,Parameter-Efficient Fine-Tuning)。 - 学什么目标
模型要学的是「按指令回答」还是「学会哪种回答更好」
参数高效微调(PEFT)
LoRA(Low-Rank Adaptation)
模型参数的「更新量」(即 A W = W 微调后 − W 原始 ) A_W=W_\text{微调后}-W_\text{原始}) AW=W微调后−W原始)虽然维度很大,但真正有意义的变化只发生在一个低维子空间里。换句话说,真正有意义的变化集中在前几个方向。这些少数方向构成的空间,就可以理解为低维子空间。
4096维空间
│
├── 方向1 ← 重要
├── 方向2 ← 重要
├── 方向3 ← 重要
├── ...
└── 方向4096
基于这个洞见,LoRA 的做法是:
冻结原始权重W不动,在W旁边新增两个小矩阵A和B,训练时只更新这两个小矩阵。推理时把B·A加回到W上,等价于一个全量微调过的模型,但训练时显存和算力开销是全量微调的几十分之一。
矩阵 A(维度
d
×
r
d\times r
d×r,其中r远小于d,通常r=8或16)把输入从 d 维压缩到 r 维;
矩阵 B(维度$r \times d $)把 r 维还原回 d 维。
LoRA 优点
- 推理零开销,合并就消失
LoRA 最被低估的优点之一,是它的推理部分不产生任何额外延迟。 - 模块化插拔,一个基底,多套能力
灵活部署,一个基础模型 + 多套 LoRA 权重,按需加载。
from peft import PeftModel
from transformers import AutoModelForCausalLM
# 基础模型只加载一次,常驻显存(约 14GB)
base_model = AutoModelForCausalLM.from_pretrained("Qwen2.5-7B")
# 场景一:用户发来客服请求,挂载客服 LoRA(只有几十 MB)
lora_customer_service = PeftModel.from_pretrained(
base_model,
"path/to/customer_service_lora"
)
# 场景二:用户发来代码问题,换成代码 LoRA
# 基础模型不用重新加载,只替换旁路矩阵
lora_coding = PeftModel.from_pretrained(
base_model,
"path/to/coding_lora"
)
- 不丢通用能力,白板旁边贴便利贴
FFT有一个著名的问题叫灾难性遗忘(Catastrophic Forgetting)。 - 训练更稳定,超参不敏感
FFT对超参很敏感,尤其是学习率。学习率稍微大一点,模型就会「跑飞,训练不稳定甚至崩溃;学习率太小,收敛又非常慢。这是因为要同步调整几十亿个参数,梯度空间极其复杂。
LoRA只训练A和B两个小矩阵,可训练参数量减少了100倍以上,梯度的搜索空间随之大幅缩小。搜索空间小,意味着优化器更容易找到好的方向,训练过程更平稳,对学习率等超参的敏感性也更低。
实践中,LoRA最关键的超参只有r(低秩维度)。r=8到r=64在很多任务上都能得到不错的结果,不需要反复调参。 - LoRA 权重可以加权混合
多个 LoRA 权重可以加权混合,实现能力融合,而不需要重新训练。
from peft import PeftModel
# 加载第一个 LoRA(指令遵循能力)
model = PeftModel.from_pretrained(base_model, "instruction_lora")
# 再加载第二个 LoRA(代码生成能力)
model.load_adapter("coding_lora", adapter_name="coding")
# 同时激活两个 LoRA,两套权重叠加生效
model.set_adapter(["default", "coding"])
QLoRA
QLoRA 是一种“低显存微调大语言模型”的方法:冻结原模型权重,把它量化到 4-bit,再只训练少量 LoRA 参数。
流程
- 准备微调数据集
- 加载预训练模型并 4-bit 量化
通常用 NF4 量化格式保存基础模型,显著降低显存占用;计算时常搭配 bf16/fp16。 - 冻结基础模型
原始大模型参数不参与梯度更新,避免完整微调的高成本。 - 注入 LoRA 适配器
在注意力层或 MLP 的线性层中加入低秩矩阵。训练的仅是这些新增小矩阵。 - 训练
前向传播使用量化后的基础权重 + LoRA 增量;反向传播只更新 LoRA 参数。
QLoRA 常结合 paged optimizer,降低显存峰值风险。 - 保存结果
通常保存 LoRA adapter,而不是整个模型,因此文件很小。 - 推理或合并
推理时加载“基础模型 + adapter”;也可以将 LoRA 权重合并回模型后部署。
NF4量化
NF4(NormalFloat 4-bit)基于一个事实:模型权重的分布近似于均值为 0 的正态分布。
让密集区域(0 附近)有更多刻度、稀疏区域(远离 0)刻度少。这样量化误差更小。
双重量化
- 量化模型权重
将一组高精度权重按块量化成 NF4 的 4-bit 编码。
每个块还需要保存一个缩放系数 scale,用于把 4-bit 值还原到该块实际的数值范围。 - 量化这些缩放系数
QLoRA 将大量 scale 本身也量化、压缩。
Paged Optimizer
主要解决“训练过程中突然显存不够”的问题。
将优化器状态按“页”管理;GPU 显存不足或出现峰值压力时,把暂时不用的页迁移/统一管理到 CPU 内存;需要时再把相关页调回 GPU。
RLHF
流程
- 收集偏好数据。
标注员对同一个Prompt的多个回答做排序,比如「回答A比回答B好,B比C好」。 - 训练奖励模型。
用偏好数据训一个小模型,输入是(Prompt+回答),输出是一个分数。训练目标是让「人类觉得好的回答」分数高、「差回答」分数低。这个奖励模型代替了人类,可以批量给后续生成的回答自动打分。 - 用PPO算法优化主模型。
让主模型生成回答->用奖励模型打分->PPO调整主模型参数往高分方向走。同时维护一个「参考模型」(SFT模型的冻结副本),用KL散度约束主模型不要离参考模型太远,防止「奖励hacking」(模型学会欺骗奖励模型而不是真的变好)。
PPO
PPO(Proximal Policy Optimization,近端策略优化)是一种让模型“根据奖励改进行为”、同时避免一次改得太猛的强化学习算法。
损失函数:
L
P
P
O
=
−
E
t
[
min
(
r
t
(
θ
)
A
t
,
clip
(
r
t
(
θ
)
,
1
−
ϵ
,
1
+
ϵ
)
A
t
)
]
\mathcal L_{\mathrm{PPO}} = -\mathbb E_t\left[ \min\left( r_t(\theta)A_t,\; \operatorname{clip}(r_t(\theta),1-\epsilon,1+\epsilon)A_t \right) \right]
LPPO=−Et[min(rt(θ)At,clip(rt(θ),1−ϵ,1+ϵ)At)]
核心概率比
核心概率比表示当前正在训练的新模型相比于旧模型选择同一动作的概率提高了多少:
r
t
(
θ
)
=
π
θ
(
a
t
∣
s
t
)
π
θ
o
l
d
(
a
t
∣
s
t
)
r_t(\theta) = \frac{\pi_\theta(a_t\mid s_t)} {\pi_{\theta_{\mathrm{old}}}(a_t\mid s_t)}
rt(θ)=πθold(at∣st)πθ(at∣st)
其中,
- π θ o l d \pi_{\theta_{\mathrm{old}}} πθold:采样回答时的旧模型。
- π θ \pi_\theta πθ:正在更新的新模型。
- r t ( θ ) > 1 r_t(\theta)>1 rt(θ)>1:新模型提高了该 token/动作的概率。
- r t ( θ ) < 1 r_t(\theta)<1 rt(θ)<1:新模型降低了该 token/动作的概率。
优势
A
t
A_t
At 是优势(advantage),表示这个动作比“正常水平”好多少。
直觉上,
A
t
≈
实际得到的回报
−
价值模型原本预期的回报
A_t \approx \text{实际得到的回报} - \text{价值模型原本预期的回报}
At≈实际得到的回报−价值模型原本预期的回报
- A t > 0 A_t>0 At>0:这是好动作,应提高概率。
- A t < 0 A_t<0 At<0:这是坏动作,应降低概率。
- ϵ \epsilon ϵ:裁剪范围,常取 0.1 0.1 0.1 或 0.2 0.2 0.2。
clip
例如,若一个高奖励动作的
A
t
=
1
A_t=1
At=1,
ϵ
=
0.2
\epsilon=0.2
ϵ=0.2,$ r_t=1.5$
没有裁剪时,目标会用
1.5
×
1
=
1.5
1.5\times1=1.5
1.5×1=1.5
但 PPO 裁剪后:
clip
(
1.5
,
0.8
,
1.2
)
=
1.2
,
min
(
1.5
,
1.2
)
=
1.2
\operatorname{clip}(1.5,0.8,1.2)=1.2 , \min(1.5,1.2)=1.2
clip(1.5,0.8,1.2)=1.2,min(1.5,1.2)=1.2
也就是说,即使模型大幅提高这个动作的概率,也不会从这个样本获得太多收益,避免策略突然偏移太远。
同时维护四个模型
- Actor / Policy Model(策略模型)
- 正在被训练的模型
- 输入 prompt,生成回答
- PPO 主要更新它
- Reference Model(参考模型)
Reward hacking 指智能体找到了提高奖励数值、却没有真正完成设计者意图的方法。
- 通常是 SFT 模型的冻结副本
- 用来计算 KL 惩罚,防止 Actor 偏离原模型太远,reward hacking
- Reward Model(奖励模型)
- 判断回答质量,输出 reward
- 例如人类更喜欢哪个回答,就训练 RM 学习这种偏好
- Value Model / Critic(价值模型)
PPO 用它计算 advantage,指导 Actor 更新
Value Model 会在每一步预测:“我刚才这个动作到底做得好不好?”
Advantage 就是“实际结果 − 原本预期, 如果Advantage>0,则→ 增大这个动作的概率
Critic/Value Model 的作用不是给回答打最终分,而是建立一个“基准线”:如果当前状态正常情况下应该拿 7 分,而这次实际拿了 10 分,那么这次行为就值得强化。
Actor
↓
生成 Token
↓
Reward Model
↓
最终 Reward
↓
Value Model
预测“原本应该拿多少分”
↓
实际 Reward - 预测 Reward
↓
Advantage
↓
告诉 Actor:
“这个动作比预期好还是差”
↓
更新 Actor
RLHF优缺点:
优点: 效果上限高,因为RL可以探索出SFT数据里没有的好回答方式
缺点:
- 4个模型同时训练,显存占用高;
- PPO算法本身不稳定、超参敏感;
- reward hacking风险一直存在。
DPO(2023)
论文:Direct Preference Optimization: Your Language Model is Secretly a Reward Model
DPO(Direct Preference Optimization,直接偏好优化)训练数据: (问题,好回答,差回答) 三元组。
让模型直接学会「好回答的概率要比差回答提升得多」。
研究者们发现:RLHF 的优化目标,可以通过推导改写成一个纯监督学习的目标函数,不需要显式训练奖励模型。直觉上,「奖励模型」的功能可以被「主模型相对于参考模型提高了多少概率」替代。
标准损失函数
L
D
P
O
(
θ
)
=
−
E
(
x
,
y
w
,
y
l
)
∼
D
[
log
σ
(
β
[
log
π
θ
(
y
w
∣
x
)
π
r
e
f
(
y
w
∣
x
)
−
log
π
θ
(
y
l
∣
x
)
π
r
e
f
(
y
l
∣
x
)
]
)
]
\mathcal L_{\mathrm{DPO}}(\theta) = -\mathbb E_{(x,y_w,y_l)\sim\mathcal D} \left[ \log\sigma \left( \beta \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)} \right] \right) \right]
LDPO(θ)=−E(x,yw,yl)∼D[logσ(β[logπref(yw∣x)πθ(yw∣x)−logπref(yl∣x)πθ(yl∣x)])]
其中,
- 一个回答的相对提升:
A ( y ) = log π θ ( y ∣ x ) − log π ref ( y ∣ x ) = log π θ ( y ∣ x ) π ref ( y ∣ x ) A(y)=\log \pi_\theta(y|x)-\log \pi_{\text{ref}}(y|x) =\log\frac{\pi_\theta(y|x)}{\pi_{\text{ref}}(y|x)} A(y)=logπθ(y∣x)−logπref(y∣x)=logπref(y∣x)πθ(y∣x)
然后比较 chosen 和 rejected:
偏好间隔 = A ( y w ) − A ( y l ) \text{偏好间隔} = A(y_w)-A(y_l) 偏好间隔=A(yw)−A(yl)
偏好间隔 > 0 偏好间隔>0 偏好间隔>0:当前模型比参考模型更偏向 chosen;
偏好间隔 = 0 偏好间隔=0 偏好间隔=0:偏好关系相对参考模型没有变化;
偏好间隔 < 0 偏好间隔<0 偏好间隔<0:当前模型反而更偏向 rejected。 - β \beta β 控制优化强度
- σ ( z ) = 1 / ( 1 + e − z ) \sigma(z)=1/(1+e^{-z}) σ(z)=1/(1+e−z):Sigmoid 函数。
DPO优缺点
优势:
- 只需2个模型:policy+reference,显存占用是RLHF的一半
- 训练稳定:变成监督学习问题,没有RL的不稳定性
- 实现简单:用现成的深度学习框架就能写
代价: - 探索数据之外的好回答效果上限略低于精心调过的PPO。因为DPO的优化目标是「往偏好数据分布靠拢」,没法像RL那样。
- 依赖偏好数据质量。偏好对收集得不好,DPO学到的偏好就会失真。
DPO 和 PPO 的区别
简单总结:PPO 是「先训练裁判、再训练选手」,DPO 是「直接拿比赛录像告诉选手哪个动作对哪个动作错」,两者目标一致,但 DPO 省去了裁判这个中间层。
GRPO(2024)
论文:DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models
GRPO (Group Relative Policy Optimization)与PPO 的区别仅在于:PPO 原本的 A i A_i Ai 来自 Value Model;GRPO 用同题多次采样的组内相对优势 A i A_i Ai 来替代它。clipping 这部分的目的完全相同。
具体流程
一批问题
↓
当前模型对每题采样 G 个回答
↓
给每个回答打奖励
↓
同一题的 G 个回答在组内比较,得到相对优势 A
↓
用 PPO-style clipping loss 更新模型
↓
重复
- 奖励可来自:
- 奖励模型;
- 可验证规则,例如数学答案对/错、代码测试是否通过、格式是否正确;
- 多个奖励的加权和。
- 组内相对优势通过均值和标准差获得:
A i j = r i j − mean ( r i 1 , … , r i G ) std ( r i 1 , … , r i G ) A_i^j= \frac{ r_i^j-\operatorname{mean}(r_i^1,\ldots,r_i^G) }{ \operatorname{std}(r_i^1,\ldots,r_i^G) } Aij=std(ri1,…,riG)rij−mean(ri1,…,riG)
这里是 GRPO 取代 Value Model 的关键:不预测基线 V ( s ) V(s) V(s),直接用“本组平均表现”作基线。 - 计算新旧策略的概率比
r i , t ( θ ) = π θ ( o i , t ∣ q i , o i , < t ) π old ( o i , t ∣ q i , o i , < t ) r_{i,t}(\theta) = \frac{ \pi_\theta(o_{i,t}\mid q_i,o_{i,<t}) }{ \pi_{\text{old}}(o_{i,t}\mid q_i,o_{i,<t}) } ri,t(θ)=πold(oi,t∣qi,oi,<t)πθ(oi,t∣qi,oi,<t)
假设针对问题1 + 1 等于几?,旧模型生成 token 2 的概率是0.20。新模型生成 token 2 的概率是0.24。
则 r ( θ ) = 0.24 0.20 = 1.2 r(\theta) = \frac{0.24}{0.20}=1.2 r(θ)=0.200.24=1.2,说明新模型把这条行为的概率提高到了旧模型的 1.2 倍,即提高了 20%。 - 用 clipped objective 更新主模型
L GRPO = − E i , j , t [ min ( r i , j , t A i j , clip ( r i , j , t , 1 − ϵ , 1 + ϵ ) A i j ) ] + λ L KL L_{\text{GRPO}} = -\mathbb E_{i,j,t} \left[ \min \left( r_{i,j,t}A_i^j,\; \operatorname{clip}(r_{i,j,t},1-\epsilon,1+\epsilon)A_i^j \right) \right] + \lambda L_{\text{KL}} LGRPO=−Ei,j,t[min(ri,j,tAij,clip(ri,j,t,1−ϵ,1+ϵ)Aij)]+λLKL
clip
假设A=1>0,说明这是一个好的回答。
| r r r | r A rA rA | clip ( r , 0.8 , 1.2 ) A \operatorname{clip}(r,0.8,1.2)A clip(r,0.8,1.2)A | min \min min 结果 | 意义 |
|---|---|---|---|---|
| 0.7 0.7 0.7 | 0.7 0.7 0.7 | 0.8 0.8 0.8 | 0.7 0.7 0.7 | 新模型把好回答的概率降低了,这是不提倡的。因此 PPO 保留未裁剪分支 r A rA rA。 r A rA rA 越小,loss 越大,让梯度下降逐步增大 r r r,即提高模型生成这个好回答的概率。 |
| 1.1 1.1 1.1 | 1.1 1.1 1.1 | 1.1 1.1 1.1 | 1.1 1.1 1.1 | 正常鼓励提高概率。 |
| 1.5 1.5 1.5 | 1.5 1.5 1.5 | 1.2 1.2 1.2 | 1.2 1.2 1.2 | 提高过头,收益封顶。 |
假设 A = − 1 A=-1 A=−1,说明这是一个差的回答。
| r r r | r A rA rA | clip ( r , 0.8 , 1.2 ) A \operatorname{clip}(r,0.8,1.2)A clip(r,0.8,1.2)A | min \min min 结果 | 意义 |
|---|---|---|---|---|
| 0.5 0.5 0.5 | − 0.5 -0.5 −0.5 | − 0.8 -0.8 −0.8 | − 0.8 -0.8 −0.8 | 概率降得过猛,惩罚封顶。 |
| 0.9 0.9 0.9 | − 0.9 -0.9 −0.9 | − 0.9 -0.9 −0.9 | − 0.9 -0.9 −0.9 | 正常降低概率。 |
| 1.4 1.4 1.4 | − 1.4 -1.4 −1.4 | − 1.2 -1.2 −1.2 | − 1.4 -1.4 −1.4 | 新模型把坏回答的概率提高了,这是不提倡的。因此 PPO 保留未裁剪分支 r A rA rA。 r A rA rA 越小,loss 越大,让梯度下降逐步减小 r r r,即降低模型生成这个坏回答的概率。 |
综上,min的作用是限制“有利但过大的更新”,不限制“纠正错误方向的更新”。
GRPO 中的结果监督和过程监督
- 结果监督:对每条完成答案得到 r i j r_i^j rij,然后用组内均值和标准差变成优势 A i j A_i^j Aij。这一个优势通常施加到该回答的所有生成 token 上。
- 过程监督:可以为各推理步骤分别给 reward,再将它们组合成每个 token 或每个步骤对应的优势;这样模型不仅知道“答案是否正确”,还知道“哪一步值得提高或避免”。
GRPO的优势:
- 省掉 Value Model。4个模型变3个,显存接近DPO但还能保留 RL的探索能力。
- 训练更稳。组内归一化天然降低了梯度方差,比PPO更容易训。
- 特别适合可验证任务。数学、代码这种「对就是对、错就是错」的任务。
拒绝采样(Rejection Sampling Fine-tuning)
让模型对每个 Prompt 生成多个回答,用奖励模型筛出高分的,然后再做一轮 SFT。
奖励模型可以用人类标注、或规则判定代替。
优点:简单、稳定、可解释
缺点:上限不如 RL 、多轮迭代成本高
它通常作为对齐的「热身」步骤,先把模型推到一个不错的起点,然后再用 DPO 或 GRPO 做精修。
RLAIF(Reinforcement Learning from AI Feedback)
是用强 AI 模型代替人类标注偏好。
代价:
依赖一个强教师 AI:如果你的目标模型本身就是当前最强的,没法找到比它更强的老师
可能放大教师 AI 的偏见:教师不完美,学生也跟着不完美
五类方案对比
| 方法 | 是否使用 RL | 维护模型数 | 训练稳定性 | 效果上限 |
|---|---|---|---|---|
| RLHF(PPO) | 是 | 4 4 4(policy / ref / RM / value) | 较差 | 高 |
| DPO | 否(监督学习) | 2 2 2(policy / ref) | 好 | 中高 |
| GRPO | 是 | 3 3 3(policy / ref / RM) | 好 | 高 |
| 拒绝采样 | 否(迭代 SFT) | 2 2 2(policy / RM) | 极好 | 中 |
| RLAIF | 是 | 3 – 4 3\text{–}4 3–4(同 RLHF,但 RM 由 AI 标注) | 较差 | 高 |
实际工程组合
Llama 2-Chat 的对齐流程:SFT+拒绝采样+PPO/RLHF
DeepSeek R1 的训练流程:SFT+GRPO+拒绝采样 多轮交替
更多推荐
所有评论(0)