
🎯 在学习完prompting工程【大模型学习 | Prompt工程基础学习】-腾讯云开发者社区-腾讯云,RAG技术【大模型学习 | RAG & DeepSeek 实战】-腾讯云开发者社区-腾讯云后,虽然模型已经可以输出用户想要的信息,但是依然可能存在着幻觉、有害内容、不遵循指令等情况。它能启发任务能力,但无法系统控制模型行为。这是由于目前答案的生成是通过预测网页文本数据的下一个token,作者认为这是语言建模目标的不一致,为此,作者提出采用reinforcement learning from human feedback (RLHF)来微调GPT3.
InstructGPT主要分为了三个步骤:
Step1. 标注数据,通过SFT(有监督微调)来训练模型
Step2. 收集相同prompt不同模型的输出数据,并标注不同输出的得分排名,构建奖励模型RM,训练出一个可以选择出更符合人类偏好的模型
Step3. 将奖励模型作为奖励函数,通过PPO最大化奖励机制微调SFT后的模型

这一阶段的数据标注是 prompt + labeler 写的回答
在这一阶段,作者对GPT-3模型进行微调,通过标注数据集,训练16轮。作者发现:在一轮后的验证损失已经存在了过拟合,但是更多轮次的迭代训练更有助于RM得分以及人类偏好评级。
这一阶段的数据标注是 prompt + 多个回答 + labeler 排序. 原本的语言模型只是根据 token 预测下一个词,并不理解‘什么是好回答’,而我们希望它学会更符合人类偏好的回答,就需要一个机制告诉它“这样回答更好”
基于上一阶段训练后的模型,作者将模型输出token的词嵌入层丢弃,并加入一个评分头,用于输出一个标量reward得分。作者只采用了6B大小作为RM模型,因为175B的模型不稳定,不适合用于奖励函数。(在之前的做法中,是通过同一个prompt输出两个结果,让模型选择更优的结果来训练奖励函数。)在本文中,作者在每个prompt中输出4-9个回答,如果采用以前的方式,会产生$C(9,2)$个问答对,容易导致过拟合,这是由于:
🧠 将每一个问答对作为一个独立样本的话,会导致模型在同一个 prompt 上见到太多相关数据,进而过拟合到局部排序模式而不是学到真正的泛化偏好信号。例如同一个 prompt 会在多个 batch 中反复出现,比如:
less复制编辑Prompt A: - A > B - A > C - B > D ...
模型每次都在更新:A 比 B 好,A 比 C 好…,会特别强化 A 的 reward,即使这些比较结果之间有冗余。容易在这个 prompt 上学得太好,导致泛化能力差
为此,作者将这些问答对放在同一个batch中进行训练,所有回答仅需进行一次前向传播,获得所 reward分数,对这些reward分数进行组合、计算 pairwise loss
这一阶段的数据标注是 prompt + 模型生成回答(无需标注)
在 SFT 阶段,模型只是模仿人类写的回应; 在 PPO (RL)阶段,模型要自己尝试回应,然后通过 Reward Model 打分,优化“怎么写人更喜欢”。
强化学习(RL):智能体(GPT-3)与一个环境(人类偏好环境)交互。环境会根据模型生成的行为(如回答一个问题)给出一个反馈信号(奖励)。如果模型的输出符合预期,就给予正向奖励;如果表现不佳,则给予较低甚至负向奖励。模型通过反复尝试、获得奖励并不断调整策略,逐步学会产生更优的输出。
PPO:是强化学习中常用的策略优化方法。它通过限制模型每次策略更新的幅度,保证训练稳定、避免模型输出发生剧烈漂移。在语言模型训练中,PPO 会让模型在获得更高奖励的同时,尽量保持语言流畅性和原始风格(通常通过引入 KL 散度惩罚项来控制变化幅度)
模型能力 | InstructGPT 表现 |
|---|---|
💬 人类偏好 | 明显优于 GPT-3,即便是小模型1.3B 的 InstructGPT 比 175B 的 GPT-3 更受人类偏好(标签员选择) |
📖 事实准确 | 在 TruthfulQA 基准上,InstructGPT生成真值回答频率是 GPT-3 的 2 倍,RLHF 明显提升 factual 可靠性,但并非完全消除幻觉。 |
🚫 毒性 | 在 |
⚖️ 偏见 | 无显著提升 |
🔄 基准能力 | RLHF 导致部分任务性能下降(SQuAD、DROP、HellaSwag、WMT15),存在了“对齐代价” |
🌐 泛化 | 能处理 unseen 任务 |
1️⃣ SFT(有监督微调):参考【大模型学习 | BLIP2 跌倒检测项目实战(一)】-腾讯云开发者社区-腾讯云
2️⃣ RM函数:难点在于把原有的输出token头换为评分头,但huggingface已经提供了可直接加载的函数:
from transformers import AutoModelForSequenceClassification
rm_model = AutoModelForSequenceClassification.from_pretrained("your_model", num_labels=1)🟢 但也可以手动构造:
from transformers import AutoModel, AutoConfig
import torch.nn as nn
class RewardModel(nn.Module):
def __init__(self, base_model_name):
super().__init__()
self.backbone = AutoModel.from_pretrained(base_model_name)
self.reward_head = nn.Sequential(
nn.Linear(self.backbone.config.hidden_size, 1)
)
def forward(self, input_ids, attention_mask):
outputs = self.backbone(input_ids=input_ids, attention_mask=attention_mask)
last_hidden = outputs.last_hidden_state # shape: (batch, seq_len, hidden)
cls_repr = last_hidden[:, 0, :] # 取第一个token的表征
reward = self.reward_head(cls_repr)
return reward.squeeze(-1) # 输出 shape: (batch,)3️⃣ PPO
from trl import PPOTrainer, PPOConfig
def run_ppo():
tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL, use_fast=False)
model = AutoModelForCausalLM.from_pretrained("sft_output")
rm_model = AutoModelForSequenceClassification.from_pretrained("rm_output").to(DEVICE)
config = PPOConfig(
model_name="sft_output",
learning_rate=1e-5,
batch_size=4,
mini_batch_size=2,
gradient_accumulation_steps=1,
log_with=None
)
ppo_trainer = PPOTrainer(
config=config,
model=model,
tokenizer=tokenizer,
reward_model=rm_model
)
prompts = ["Explain the concept of overfitting."]
for epoch in range(5):
batch = random.sample(prompts, k=3)
query_tensors = tokenizer(batch, return_tensors="pt", padding=True, truncation=True).input_ids.to(DEVICE)
response_tensors = ppo_trainer.model.generate(query_tensors, max_new_tokens=100)
texts = [tokenizer.decode(r, skip_special_tokens=True) for r in response_tensors]
rewards = []
for q, r in zip(batch, texts):
input_text = f"{q}\n{r}"
inputs = tokenizer(input_text, return_tensors="pt", truncation=True, padding=True).to(DEVICE)
reward = rm_model(**inputs)["logits"].squeeze().item()
rewards.append(reward)
print(f"[PPO] E{epoch}: Rewards = {rewards}")
ppo_trainer.step(query_tensors, response_tensors, torch.tensor(rewards))原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。