共计 1735 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
传统语言模型微调(Fine-tuning)与基于人类反馈的强化学习(RLHF, Reinforcement Learning from Human Feedback)存在本质差异。传统微调依赖大量标注数据直接调整模型参数,而 RLHF 通过人类对模型输出的偏好反馈来间接优化模型,这种差异带来了几个关键挑战:

- 人类反馈数据比传统标注数据更稀疏且成本更高
- 奖励信号需要从主观的人类偏好中提取量化指标
- 策略优化过程涉及多个组件的复杂交互
RLHF 流程中最难直观理解的环节包括:
- 如何将人类的主观偏好转化为可计算的奖励信号
- 策略优化时如何平衡即时奖励和长期语言质量
- 多阶段训练中不同组件(策略模型、奖励模型)的协同机制
技术图解
以下是 RLHF 三阶段训练的 ASCII 流程图:
[监督微调 SFT 阶段]
原始预训练模型 → 标注数据 → 微调模型
↓
[奖励建模 RM 阶段] 人类偏好数据
↓
[强化学习 PPO 阶段] 当前策略 → 生成响应 → 奖励模型评分 → PPO 更新
↑____________∣
关键数据流向说明:
- SFT 阶段:使用高质量的标注对话数据对基础模型进行微调
- RM 阶段:收集人类对不同模型输出的偏好排名,训练奖励模型
- PPO 阶段:当前策略生成响应,奖励模型给出评分,通过 PPO 算法更新策略
人类反馈数据在两个关键点注入:
- RM 阶段:直接作为训练数据
- PPO 阶段:通过奖励模型间接影响策略更新
代码实现
环境要求:Python 3.8+, PyTorch 1.12+
import torch
import torch.nn as nn
# 策略网络定义
class PolicyNetwork(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super().__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
x = torch.relu(self.fc1(x))
return torch.softmax(self.fc2(x), dim=-1)
# 值函数网络定义
class ValueNetwork(nn.Module):
def __init__(self, input_dim, hidden_dim):
super().__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, 1)
def forward(self, x):
x = torch.relu(self.fc1(x))
return self.fc2(x)
# 人类偏好数据转换示例
def convert_preference_to_reward(preference_pairs):
"""将人类偏好对转换为奖励信号"""
rewards = {}
for winner, loser in preference_pairs:
rewards[winner] = rewards.get(winner, 0) + 1
rewards[loser] = rewards.get(loser, 0) - 1
return rewards
# PPO 关键参数
LEARNING_RATE = 3e-4 # 学习率
GAMMA = 0.99 # 折扣因子
CLIP_EPSILON = 0.2 # PPO 截断参数
避坑指南
常见误区及解决方案
- 奖励黑客(Reward Hacking)
- 现象:模型找到漏洞获得高奖励但输出质量差
- 监控:人工定期检查高分样本
-
方案:添加 KL 散度约束限制策略偏离基准模型
-
KL 散度失控
- 现象:策略与基准模型差异过大导致语义混乱
- 监控:实时计算 $D_{KL}(π_θ||π_{base})$
-
方案:动态调整 KL 惩罚系数 β
-
奖励模型过拟合
- 现象:在训练数据上表现好但泛化差
- 监控:保留验证集评估奖励模型
- 方案:增加数据多样性,使用 dropout 等正则化
延伸思考
-
奖励模型偏见评估:如何检测奖励模型对不同性别 / 种族话题的隐含偏好?可以设计对抗测试集量化评估
-
小规模模型适用性:RLHF 通常需要大规模模型才能有效工作,对于参数量 <1B 的模型,是否有更高效的替代方案?可能探索蒸馏 +RL 的混合方法
正文完
