SFT、RLHF、DPO技术对比:大模型训练的关键策略
本文介绍了三种优化大语言模型的技术方法:监督微调(SFT)、基于人类反馈的强化学习(RLHF)和直接偏好优化(DPO)。SFT通过标注数据使预训练模型适应特定任务;RLHF利用人类反馈指导模型优化输出质量;DPO简化RLHF流程,直接利用偏好数据优化模型。文中提供了医疗问答、智能客服和内容生成等应用案例,并附各方法的Python实现代码示例(基于Hugging Face、Stable-Baseli
🌈 我是“没事学AI”, 欢迎咨询、交流,共同学习:
👁️ 【关注】我们一起挖 AI 的各种门道,看看它还有多少新奇玩法等着咱们发现
👍 【点赞】为这些有用的 AI 知识鼓鼓掌,让更多人知道学 AI 也能这么轻松
🔖 【收藏】把这些 AI 小技巧存起来,啥时候想练手了,翻出来就能用
💬 【评论】说说你学 AI 时的想法和疑问,让大家的思路碰出更多火花
👉 关注获取更多AI技术干货,点赞/收藏备用,欢迎评论区交流学习心得! 🚀
目录
一、监督微调(SFT)
1.1 技术定位与作用
监督微调(Supervised Fine-Tuning,SFT)是在预训练模型基础上,运用有标注的特定任务数据进一步训练模型,使其适配目标任务的技术。它利用迁移学习思想,借助预训练模型已有的知识,快速适应新任务。在大模型训练体系中,SFT处于将通用模型向特定领域或任务优化的关键环节,能让模型更好地满足实际应用需求。
1.2 案例
以医疗领域问答系统为例,首先有在大规模通用文本上预训练的模型。收集大量医疗领域的问题及对应的专业解答作为标注数据,如“糖尿病的常见症状有哪些?”及对应的症状描述答案。利用这些数据对预训练模型进行SFT。
1.3 案例实现代码(基于Hugging Face的Transformers库)
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, TrainingArguments, Trainer
from datasets import load_dataset
# 加载预训练模型和tokenizer
model_name = "t5-base"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
# 加载医疗问答数据集
dataset = load_dataset('your_dataset_path', split='train')
# 数据预处理
def preprocess_function(examples):
inputs = tokenizer(examples["question"], truncation=True, padding='max_length')
targets = tokenizer(examples["answer"], truncation=True, padding='max_length')
return {
'input_ids': inputs['input_ids'],
'attention_mask': inputs['attention_mask'],
'labels': targets['input_ids']
}
tokenized_datasets = dataset.map(preprocess_function, batched=True)
# 定义训练参数
training_args = TrainingArguments(
output_dir='./results',
num_train_epochs=3,
per_device_train_batch_size=4,
per_device_eval_batch_size=64,
warmup_steps=500,
weight_decay=0.01,
logging_dir='./logs',
logging_steps=10
)
# 初始化Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"]
)
# 开始训练
trainer.train()
二、基于人类反馈的强化学习(RLHF)
2.1 技术定位与作用
基于人类反馈的强化学习(Reinforcement Learning from Human Feedback,RLHF),将人类反馈与强化学习相结合,以人类偏好作为奖励信号指导模型训练,增强模型对人类意图的理解和满足程度,让模型输出更符合人类期望,是提升模型与人类交互自然度和生成内容质量的重要手段。
2.2 案例
在一个智能客服场景中,模型对用户问题生成多个回答,如用户问“如何重置密码?”,模型生成回答A“您可以在APP设置中找到重置密码选项”,回答B“在登录页面点击忘记密码试试”。人工标注员对这些回答按照更符合客服规范和用户需求程度进行排序,如认为A更好。利用这些排序数据训练奖励模型,再通过强化学习算法优化语言模型。
2.3 案例实现代码(使用Stable-Baselines3库实现简化版)
import gym
from stable_baselines3 import PPO
from stable_baselines3.common.env_util import make_vec_env
from custom_rlhf_env import RLHFEnv # 自定义的基于RLHF的环境
# 创建环境
env = make_vec_env(RLHFEnv, n_envs=4)
# 初始化PPO模型
model = PPO('MlpPolicy', env, verbose=1)
# 训练模型
model.learn(total_timesteps=10000)
其中custom_rlhf_env.py
中自定义环境代码大致如下:
import gym
from gym import spaces
import numpy as np
class RLHFEnv(gym.Env):
def __init__(self):
super(RLHFEnv, self).__init__()
# 定义状态空间和动作空间
self.observation_space = spaces.Box(low=-np.inf, high=np.inf, shape=(state_dim,), dtype=np.float32)
self.action_space = spaces.Discrete(action_num)
def step(self, action):
# 根据动作计算奖励等,与人类反馈数据结合
reward = self.calculate_reward(action)
done = False
next_state = self.get_next_state(action)
return next_state, reward, done, {}
def reset(self):
# 重置环境状态
state = self.initial_state()
return state
def calculate_reward(self, action):
# 这里根据人类反馈数据计算奖励,实际中需要与标注数据对接
pass
def get_next_state(self, action):
# 根据动作更新状态
pass
def initial_state(self):
# 返回初始状态
pass
三、直接偏好优化(DPO)
3.1 技术定位与作用
直接偏好优化(Direct Preference Optimization,DPO)是用于优化大语言模型输出符合人类偏好的方法。它简化了RLHF流程,直接利用人类对模型输出的偏好数据(如“输出A比输出B更好”)转化为可优化的损失函数,避免复杂奖励模型训练,在性能相当甚至更优的同时,提升计算效率和稳定性。
3.2 案例
在内容生成场景中,对于输入“写一段关于旅游的宣传文案”,模型生成文案A“踏上旅程,探索未知,感受别样风情”,文案B“旅游,就是出去玩,很开心”。人工标注A优于B,DPO利用这种偏好关系优化模型。
3.3 案例实现代码(简单示例,基于PyTorch)
import torch
import torch.nn as nn
import torch.optim as optim
# 假设已有模型和数据
model = YourLLMModel() # 自定义的大语言模型
preference_pairs = [(input_text, better_output, worse_output) for _ in range(num_pairs)]
criterion = nn.BCEWithLogitsLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
for input_text, better_output, worse_output in preference_pairs:
input_ids = tokenizer(input_text, return_tensors='pt').input_ids
better_logits = model(input_ids).logits
worse_logits = model(input_ids).logits
better_probs = torch.sigmoid(better_logits)
worse_probs = torch.sigmoid(worse_logits)
# 构造DPO损失
dpo_loss = -torch.log(better_probs - worse_probs + 1e-8).mean()
optimizer.zero_grad()
dpo_loss.backward()
optimizer.step()
更多推荐
所有评论(0)