📌 论文地址:Training language models to follow instructions with human feedback
💻 参考项目:instructGOOSE
📷 模型架构图:
一、引言:为什么需要 InstructGPT?
传统的语言模型往往依赖于“最大似然训练”,学会如何生成符合语法的文本,但却不一定符合人类的指令意图。OpenAI 提出的 InstructGPT 是一种结合 人类反馈监督 + 强化学习(RLHF) 的新训练范式,其目标是使语言模型更能“听人话”。
InstructGPT 的三阶段训练流程如下:
-
SFT(Supervised Fine-tuning):使用人工标注的指令-回复数据进行有监督微调。
-
RM(Reward Modeling):让人工对模型生成的多个候选回复打分,从而训练一个奖励模型。
-
PPO(Proximal Policy Optimization):使用 RL 算法训练语言模型,使其生成的回复最大化奖励模型的得分。
本篇将结合 instructGOOSE
项目,对上述三阶段进行端到端复现,使用的数据集为 IMDb
影评文本,语言模型为 GPT-2
。
二、准备工作:环境与设备
# 安装依赖
# pip3 install instruct_gooseimport os
import torchfrom datasets import load_dataset
from torch.utils.data import DataLoader, random_split
from tqdm.auto import tqdm# 设置 GPU 设备(如使用 Colab 建议 comment 掉代理配置)
os.environ["CUDA_VISIBLE_DEVICES"] = "1"
os.environ['http_proxy'] = 'http://192.41.170.23:3128'
os.environ['https_proxy'] = 'http://192.41.170.23:3128'device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("Using device:", device)
三、加载 IMDb 数据集并构建 DataLoader
dataset = load_dataset("imdb", split="train")# 为演示快速收敛,仅使用前 10 条数据
dataset, _ = random_split(dataset, lengths=[10, len(dataset) - 10])train_dataloader = DataLoader(dataset, batch_size=4, shuffle=True)
四、加载 GPT-2 模型与 InstructGPT 工具链
from transformers import AutoTokenizer, AutoModelForCausalLM
from instruct_goose import Agent, RewardModel, RLHFTrainer, RLHFConfig, create_reference_modelmodel_name_or_path = "gpt2"# 加载主模型与奖励模型
model_base = AutoModelForCausalLM.from_pretrained(model_name_or_path)
reward_model = RewardModel(model_name_or_path)# 加载 tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, padding_side="left")
tokenizer.pad_token = tokenizer.eos_token
eos_token_id = tokenizer.eos_token_id
五、创建 RL 模型代理与参考模型
# 构造 Agent(语言模型 + Value 网络 + 采样接口)
model = Agent(model_base)
ref_model = create_reference_model(model)
六、训练配置与 RLHFTrainer 初始化
max_new_tokens = 20
generation_kwargs = {"min_length": -1,"top_k": 0.0,"top_p": 1.0,"do_sample": True,"pad_token_id": eos_token_id,"max_new_tokens": max_new_tokens
}config = RLHFConfig() # 可使用默认参数trainer = RLHFTrainer(model, ref_model, config)
七、基于 PPO 的 InstructGPT 强化训练
from torch import optimoptimizer = optim.Adam(model.parameters(), lr=1e-3)
num_epochs = 3for epoch in range(num_epochs):for step, batch in enumerate(tqdm(train_dataloader)):# Step 1: 编码输入inputs = tokenizer(batch["text"],padding=True,truncation=True,return_tensors="pt")inputs = {k: v.to(device) for k, v in inputs.items()}# Step 2: 使用主模型生成回复response_ids = model.generate(inputs["input_ids"], attention_mask=inputs["attention_mask"],**generation_kwargs)response_ids = response_ids[:, -max_new_tokens:]response_attention_mask = torch.ones_like(response_ids)# Step 3: 拼接 query + response,使用 Reward Model 评估得分with torch.no_grad():input_pairs = torch.stack([torch.cat([q, r], dim=0)for q, r in zip(inputs["input_ids"], response_ids)]).to(device)rewards = reward_model(input_pairs)# Step 4: 计算 PPO 损失并反向传播loss = trainer.compute_loss(query_ids=inputs["input_ids"],query_attention_mask=inputs["attention_mask"],response_ids=response_ids,response_attention_mask=response_attention_mask,rewards=rewards)optimizer.zero_grad()loss.backward()optimizer.step()print(f"[Epoch {epoch+1}] Loss = {loss.item():.4f}")
八、推理测试与结果展示
# 输入一句文本进行测试
input_text = dataset[0]['text']
input_ids = tokenizer.encode(input_text, return_tensors="pt").to(device)output = model_base.generate(input_ids, max_length=256,num_beams=5, no_repeat_ngram_size=2,top_k=50, top_p=0.95, temperature=0.7
)generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print("🧠 模型生成结果:\n", generated_text)
九、总结
本篇我们复现了 InstructGPT 的核心训练框架,依赖于三大模块:
-
语言模型(GPT2);
-
奖励模型(RewardModel);
-
强化训练器(RLHFTrainer + PPO loss)。
通过引入人类反馈偏好作为优化目标,InstructGPT 展现出更强的任务理解与指令遵循能力,已经成为 ChatGPT 训练体系的核心组成部分之一。
🔮 下一篇预告
📘《基于 Python 的自然语言处理系列(84):SFT原理与实践》
如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!
欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。
谢谢大家的支持!