Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >强化学习系列(十)--基于大语言模型的RLHF

强化学习系列(十)--基于大语言模型的RLHF

原创
作者头像
languageX
修改于 2024-11-27 01:14:37
修改于 2024-11-27 01:14:37
52100
代码可运行
举报
文章被收录于专栏:强化学习系列强化学习系列
运行总次数:0
代码可运行

推荐文章:《Linux本地部署开源项目OpenHands基于AI的软件开发代理平台及公网访问

本篇文章介绍如何在 Linux 本地部署开源项目 OpenHands 基于人工智能软件开发代理平台,并结合 cpolar 实现公网访问,部署强大的开发助手提升你的工作效率。


这篇文章我们回顾了强化学习的理论知识和各种强化学习算法。

这篇文章我们介绍过大语言模型LLM

本文就介绍将两个知识点结合,让LLM和人类对齐的技术--基于人类反馈的强化学习。

大语言模型训练

大模型训练业界普遍遵循的三部曲:预训练(Pre-training)、微调(Fine-tuning)和对齐(Alignment)。过去两年,行业主要聚焦在Pretraining和SFT上,而基于人类反馈的强化学习(Reinforcement Learning from Human Feedback, RLHF)的框架虽然被广泛讨论也有很多开源框架,但在实际落地应用场景并不算多。今年9月领军模型ChatGPT又推出了o1模型,在逻辑推理和慢思考问题上取得了显著的进展,这也使得强化学习逐渐成为业界的热门话题。最近几个月大家可以看到多个o1复现框架开源。

再次奉上经典pipline图:

descript
descript

先回顾通过pretrain和SFT后我们得到了什么。

pretraiing是给模型读万卷书,这个底座基础模型具有的功能就是续写,通过上文迭代输出下一个token。

SFT是使用问答对对pretraining进行微调,这个模型具有的功能就是可以进行对话。

但是单纯的SFT模型可能会生成语法或者技术上正确但与人类价值观、偏好不符的回答。所以需要第三部RLHF来帮助模型学习更符合人类意图和偏好的回复,更好地与人类的价值观保持一致,即生成更安全合规的回答。

RLHF(基于人类反馈的强化学习)

先套强化学习公式,看看在LLM中的几大元素什么含义:

智能体(Agent):与环境交互、并执行策略的主体。LLM领域那就是LLM本身。

环境(Environment):可以认为是用户提供的prompt和上下文信息。

状态(state):输入给模型的tokens

动作(Action):模型的输出token

奖励(Reward):人类对模型的输出的质量评估

那要进行RLHF是什么流程呢?

再次献上经典deepspeed的RLHF流程图:

descript
descript

众所知周,RLHF-PPO需要四个模型,那到底是哪四个模型,分别是干什么的,四个模型什么关系,如何将PPO应用到RLHF里面?不慌,一步一步看~

本文主要基于开源代码LLM-turning进行学习。

2.1 step1:SFT

这一步不做过多介绍,基于问答对训练一个对话模型。可以使用开源模型,比如Qwen-7B-Chat进行微调。

2.2 step2:RW

这一步就是使用pari goog/bad answers进行训练得到一个奖励模型,简单来说是训练一个分类模型来判断模型回复的好坏。

训练过程中我们需要准备的数据示例:

descript
descript

其中chosen代表较好的回复,rejected表示较差的回复。

核心实现代码:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 处理数据:tokenized_j好的回复,tokenized_k差的回复
for question, response_j, response_k in zip(examples[question_key], examples[good_key], examples[bad_key]):
        tokenized_j = tokenizer("问:" + question + "\n\n答:" + response_j, truncation=True)
        tokenized_k = tokenizer("问:" + question + "\n\n答:" + response_k, truncation=True)
...
# Define how to compute the reward loss. We use the InstructGPT pairwise logloss: https://arxiv.org/abs/2203.02155
    # 由于训练数据都是好坏成对出现,所以这里两个输入两个输出
    def compute_loss(self, model, inputs, return_outputs=False):
        rewards_j = model(input_ids=inputs["input_ids_j"], attention_mask=inputs["attention_mask_j"])[0]
        rewards_k = model(input_ids=inputs["input_ids_k"], attention_mask=inputs["attention_mask_k"])[0]
        loss = -nn.functional.logsigmoid(rewards_j - rewards_k).mean()
        if return_outputs:
            return loss, {"rewards_j": rewards_j, "rewards_k": rewards_k}
        return loss

2.3 step3: PPO

这一步比较复杂,通过上图结合前篇文章我们介绍的PPO算法思路,我们基于代码来分析整个流程和思路。

先看PPO训练过程中需要的四个模型分别是什么:

descript
descript

Reference model(参考模型): 其实就是step1中的SFT模型冻结了参数作为refModel,主要用于指导Actor model,让策略模型和ref模型在分布上差距不要太大,防止Actor model训歪。

Reward Model(奖励模型):其实就是step2中的RM模型冻结了参数作,用于计算策略生成token的即时奖励。

Actor Model(演员模型):就是我们要训练的目标策略模型,一般使用step1的SFT作为初始化。

Critic Model(评论家模型):用于预测策略生成token的累计回报。因为critic和actor的输入一致,所以可以和Actor Model共享参数,然后增加一层value head作为预测累计回报值。

2.3.1 加载模型

在LLM-Tuning项目中,Actor Model和 Critic Model是共享参数,然后新增value head层来预测回报V。

AutoModelForCausalLMWithValueHead核心代码:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
...
lm_logits = base_model_output.logits
loss = base_model_output.loss
...
# 增加一层v_head
value = self.v_head(last_hidden_state).squeeze(-1)
...
return (lm_logits, loss, value)

所以在项目中加载实际是需要3个模型,冻结的Reference Model, Reward Model,需要训练的PPO Model。只是这个Model有两个分支任务:Actor 和 Critic。

加载Reference_model:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
ref_model = AutoModelForCausalLMWithValueHead.from_pretrained(
    script_args.merged_sft_model_path,
    trust_remote_code=True
)

加载Rewar_model:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
base_model_for_RM = BaichuanForSequenceClassification.from_pretrained(
    script_args.base_model_name, num_labels=1, 
    trust_remote_code=True, 
    torch_dtype=torch.bfloat16, 
    device_map="auto",
    # device_map={"": current_device},
)
reward_model = PeftModel.from_pretrained(base_model_for_RM, script_args.reward_model_lora_path)

加载ppo_model代码也比较简单,1加载基础模型,2加载sft后 lora模型,3适配了ValueHead的ppo_model:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# load the base model
base_model_for_PPO = AutoModelForCausalLM.from_pretrained(
    script_args.base_model_name,
    trust_remote_code=True,
    torch_dtype=torch.bfloat16, 
    device_map='auto'
    )
# install the lora modules
base_model_for_PPO_with_sft_lora = PeftModel.from_pretrained(
    base_model_for_PPO, 
    script_args.sft_model_lora_path
    )
# wrap with the AutoModelForCausalLMWithValueHead wrapper
ppo_model = AutoModelForCausalLMWithValueHead.from_pretrained(
    base_model_for_PPO_with_sft_lora
)

2.3.2 训练流程

我们可以,直接使用trl库,训练脚本其实比较简单:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
...
response_tensors = ppo_trainer.generate(
            question_tensors,
            return_prompt=False,
            **generation_kwargs,
        )
        batch["response"] = tokenizer.batch_decode(response_tensors, skip_special_tokens=True)

        # Compute sentiment score
        texts = [q + r for q, r in zip(batch["query"], batch["response"])]
        scores = get_reward_value(texts)
        rewards = [torch.tensor(score - script_args.reward_baseline) for score in scores]
        for q, r, s in zip(batch["query"], batch["response"], scores):
            print(epoch,'query:',q)
            print('response:',r)
            print('score:',s)
        # Run PPO step
        stats = ppo_trainer.step(question_tensors, response_tensors, rewards)

如果不分析其中实现逻辑,准备好数据,直接使用trl库就可以开始训练。

训练代码实现就需要去trl里面查看源码, 下面我们结合核心代码理解流程。

首先使用策略网络生成一批数据,这里的unwrapped_model.policy就是Actor_model:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
 # actor网络预测responses和动作logits
 query_responses, logitss = batch_generation(
                        unwrapped_model.policy,
                        queries,
                        args.local_rollout_forward_batch_size,
                        processing_class.pad_token_id,
                        generation_config,
                    )
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
all_logprob = F.log_softmax(logits, dim=-1)
# logporb:actor网络预测response的概率分布
logprob = torch.gather(all_logprob, 2, response.unsqueeze(-1)).squeeze(-1)
...
ref_output = forward(ref_policy, query_response, processing_class.pad_token_id)
...
ref_all_logprob = F.log_softmax(ref_logits, dim=-1)
# ref_logprob:ref网络预测response的概率分布
ref_logprob = torch.gather(ref_all_logprob, 2, response.unsqueeze(-1)).squeeze(-1)
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# critic网络预测的状态值value(累计rewards)
full_value, _, _ = get_reward(unwrapped_value_model, query_response, processing_class.pad_token_id, context_length)
value = full_value[:, context_length - 1 : -1].squeeze(-1)

# reward网络计算的score(T时刻即刻回报reward)
_, score, _ = get_reward(reward_model, postprocessed_query_response, processing_class.pad_token_id, context_length )

通过以上步骤(其中很多mask,filter等细节被省略),我们得到一批数据:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 决策模型的回复
responses = torch.cat(responses, 0)
# 处理response,哪些参与loss计算
postprocessed_responses = torch.cat(postprocessed_responses, 0)
# actor模型预测的动作概率分布
logprobs = torch.cat(logprobs, 0)
# ref模型预测的动作概率分布
ref_logprobs = torch.cat(ref_logprobs, 0)
# 序列长度
sequence_lengths = torch.cat(sequence_lengths, 0)
# reward模型计算的即刻reward
scores = torch.cat(scores, 0)
# critic模型预测的累计V
values = torch.cat(values, 0)

结合之前学习的知识点,构建优势函数:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 4. compute rewards
# actor和 ref输出分布的KL散度 * 非负权重
kl = logprobs - ref_logprobs
non_score_reward = -args.kl_coef * kl
# 每个时刻的reward使用kl散度表示。
# 这里解释下,由于rewardmodel训练是基于input+response一起的分类模型,所以分类结果最为最后一个时刻的奖励R,其他时刻是没有R。这里是使用KL散度,让决策和ref分布靠近来作为即可奖励。
rewards = non_score_reward.clone()
actual_start = torch.arange(rewards.size(0), device=rewards.device)
actual_end = torch.where(sequence_lengths_p1 < rewards.size(1), sequence_lengths_p1, sequence_lengths)
# 最后时刻的R就是reward model的score
rewards[[actual_start, actual_end]] += scores

....

# 6. compute advantages and returns
lastgaelam = 0
advantages_reversed = []
gen_length = responses.shape[1]
# 这里是使用了泛优势函数GAE,从最后时刻逆序计算
for t in reversed(range(gen_length)):
        nextvalues = values[:, t + 1] if t < gen_length - 1 else 0.0
        # TD:t时刻即可回报+gamma*下时刻的累计回报- t时刻累计回报
        delta = rewards[:, t] + args.gamma * nextvalues - values[:, t]
        # GAE的更新公式
        lastgaelam = delta + args.gamma * args.lam * lastgaelam
        advantages_reversed.append(lastgaelam)
advantages = torch.stack(advantages_reversed[::-1], axis=1)
# 优势+状态值估计
returns = advantages + values
advantages = masked_whiten(advantages, ~padding_mask)
advantages = torch.masked_fill(advantages, padding_mask, 0)

通过以上步骤,我们生成了一个batch的经验值数据,基于在线学习方法,就可以对数据重复利用,基于这一批数据训练进行多次ppo训练,训练过程中的loss核心代码如下:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
logprobs_diff = new_logprobs - mb_logprobs
ratio = torch.exp(logprobs_diff)
pg_losses = -mb_advantage * ratio
pg_losses2 = -mb_advantage * torch.clamp(ratio, 1.0 - args.cliprange, 1.0 + args.cliprange)
pg_loss_max = torch.max(pg_losses, pg_losses2)
pg_loss = masked_mean(pg_loss_max, ~padding_mask[micro_batch_inds])
loss = pg_loss + args.vf_coef * vf_loss

这里使用的重要知识点包括重要性采样,KL散度,优势函数,clip操作等之前的系列文章已经讲解非常清楚,本文就不再过多介绍。

以上就是基于人类反馈的强化学习PPO算法的核心思路,相信通过代码的理解,希望本文能让大家对PPO在LLM中的使用有更深刻的理解~

也欢迎大家留言讨论~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【强化学习】Reward Model(奖励模型)详细介绍
Reward Model(奖励模型)是近年来在深度学习和强化学习领域广泛应用的一种技术,特别是在生成式模型(如大型语言模型)和强化学习(RL)结合的场景中,起到了至关重要的作用。它在多个领域的应用中,尤其是在自然语言处理(NLP)和数学推理领域,展现了显著的潜力。
不去幼儿园
2025/03/22
3190
【强化学习】Reward Model(奖励模型)详细介绍
推理大模型的后训练增强技术-强化学习篇
人生中充满选择,每次选择就是一次决策,我们正是从一次次决策中,把自己带领到人生的下一段旅程中。在回忆往事时,我们会对生命中某些时刻的决策印象深刻:“唉,当初我要是去那家公司实习就好了,在那里做的技术研究现在带来了巨大的社会价值。”通过这些反思,我们或许能领悟一些道理,变得更加睿智和成熟,以更积极的精神来迎接未来的选择和成长。
致Great
2025/03/10
1520
推理大模型的后训练增强技术-强化学习篇
HuggingFace 又出新教程啦!手把手教你构建DeepSeek-R1推理模型
LLM 在许多生成任务上表现出色。然而,直到最近,它们还在解决需要推理的复杂问题上举步维艰。例如,它们很难处理需要多步推理的谜题或数学问题。
致Great
2025/03/05
2860
HuggingFace 又出新教程啦!手把手教你构建DeepSeek-R1推理模型
强化学习系列(八)--PPO
回顾上文中的DDPG,DDPG是源于DQN,它使用神经网络替换maxQ(s',a')的功能来解决连续空间问题。也就是说DDPG的Actor网络输出的是一个动作,他的目标是输出一个动作,这个动作输入到Critic后,能过获得最大的Q值。和DQN一样,更新的时候如果更新目标在不断变化会使学习过程困难,所以需要固定目标网络,求target的网络更新后再赋值参数,所以需要四个网络。
languageX
2022/04/01
4.5K0
RLHF-Safe RLHF:带着脚镣跳舞的PPO!
该模型同样经过多轮safe RLHF,模型名为Beaver-V1/V2/V3, 项目是开源的:
zenRRan
2023/12/20
4650
RLHF-Safe RLHF:带着脚镣跳舞的PPO!
【RLHF】想训练ChatGPT?先来看看强化学习(RL)+语言模型(LM)吧(附源码)
随着最近 ChatGPT 的大火,越来越多人开始关注其中用到的 RLHF(Reinforcement Learning from Human Feedback)这一核心思想。
汀丶人工智能
2023/10/11
8330
【RLHF】想训练ChatGPT?先来看看强化学习(RL)+语言模型(LM)吧(附源码)
【强化学习】近端策略优化算法(PPO)万字详解(附代码)
近端策略优化、PPO(Proximal Policy Optimization)是一种强化学习算法,设计的目的是在复杂任务中既保证性能提升,又让算法更稳定和高效。以下用通俗易懂的方式介绍其核心概念和流程。
不去幼儿园
2025/01/02
7.2K0
【强化学习】近端策略优化算法(PPO)万字详解(附代码)
机器学习——强化学习与深度强化学习
近年来,强化学习(Reinforcement Learning, RL)在多个领域取得了巨大的进展。从早期简单的迷宫导航问题到今天 AlphaGo 击败围棋世界冠军,强化学习的潜力得到了充分展现。而随着深度学习的引入,深度强化学习(Deep Reinforcement Learning, DRL)更是将这一技术推向了前所未有的高度。本篇文章将深入探讨强化学习与深度强化学习的基本原理、常见算法以及应用场景,旨在为读者提供一个详尽的学习路线图。
hope kc
2024/10/09
2K0
【RL Base】强化学习:信赖域策略优化(TRPO)算法
在强化学习(RL)领域,如何稳定地优化策略是一个核心挑战。2015 年,由 John Schulman 等人提出的信赖域策略优化(Trust Region Policy Optimization, TRPO)算法为这一问题提供了优雅的解决方案。TRPO 通过限制策略更新的幅度,避免了策略更新过大导致的不稳定问题,是强化学习中经典的策略优化方法之一。
不去幼儿园
2024/12/03
2500
【RL Base】强化学习:信赖域策略优化(TRPO)算法
大语言模型 RLHF 技术的深度解析:从理论到实践的范式革命
在人工智能领域,人类反馈强化学习(Reinforcement Learning from Human Feedback,RLHF)已成为大语言模型(Large Language Models)进化过程中最具突破性的技术之一。这项技术不仅重新定义了人机协作的边界,更在模型伦理对齐、输出可控性、应用场景扩展等维度展现出独特价值。本文将通过技术解构、案例分析和代码实现三个维度,深入揭示 RLHF 的核心机理与实践应用。
编程小妖女
2025/02/03
1770
大语言模型 RLHF 技术的深度解析:从理论到实践的范式革命
使用Huggingface创建大语言模型RLHF训练流程的完整教程
ChatGPT已经成为家喻户晓的名字,而大语言模型在ChatGPT刺激下也得到了快速发展,这使得我们可以基于这些技术来改进我们的业务。
deephub
2023/12/05
1.9K0
使用Huggingface创建大语言模型RLHF训练流程的完整教程
万字长文教你如何做出 ChatGPT
作者:monychen,腾讯 IEG 应用研究员 简单来说,ChatGPT 是自然语言处理(NLP)和强化学习(RL)的一次成功结合,考虑到读者可能只熟悉其中一个方向或者两个方向都不太熟悉,本文会将 ChatGPT 涉及到的所有知识点尽可能通俗易懂的方式展现出来,有基础的同学可以选择性跳过一些内容。 GPT 的进化史 本节的主要目的是介绍自然语言处理中语言模型的一些基础知识,理解语言模型到底在做什么。 GPT 所谓的 GPT(Generative Pre-trained Transformer),其实是 G
腾讯技术工程官方号
2023/02/17
2.9K0
万字长文教你如何做出 ChatGPT
基于 LoRA 的 RLHF: 记一次不太成功但有趣的百川大模型调教经历
为了节省训练资源,快速了解整个 RLHF 的过程,我这里每一步的训练,都采用 LoRA 微调的方式:使用 LoRA 进行 SFT,使用 LoRA 训练 Reward Model,以及使用 LoRA 来进行强化学习 PPO 过程。
beyondGuo
2023/09/01
2.2K0
基于 LoRA 的 RLHF: 记一次不太成功但有趣的百川大模型调教经历
北大硕士RLHF实践,基于DeepSpeed-Chat成功训练上自己的模型
最近两月倒腾了一波RLHF,从ColossalAI到TRLX以及DeepSpeed-Chat,最后基于DeepSpeed-Chat成功训练上了自己的模型,最后效果也是肉眼可见的提升。对这一部分进行下总结,包括原理,代码以及踩坑与解决方案。
新智元
2023/09/09
1K0
北大硕士RLHF实践,基于DeepSpeed-Chat成功训练上自己的模型
大语言模型中的 RLHF:强化学习如何优化 AI 交互体验
近年来,大语言模型(Large Language Model, LLM)取得了突破性的进展,GPT-3、GPT-4 以及其他基于 Transformer 架构的模型在自然语言处理(NLP)任务中展现出卓越的性能。然而,尽管这些模型具备强大的生成能力,它们的输出仍然可能存在不符合人类期望的情况,比如生成误导性信息、带有偏见的内容,或者在对话中缺乏连贯性。
编程小妖女
2025/02/03
1180
大语言模型中的 RLHF:强化学习如何优化 AI 交互体验
详解TensorFlow 2.0新特性在深度强化学习中的应用
TensorFlow 2.0的特性公布已经有一段时间了,但很多人对此应当还是一头雾水。
深度强化学习实验室
2019/11/20
9050
详解深度强化学习展现TensorFlow 2.0新特性
自TensorFlow官方发布其2.0版本新性能以来,不少人可能对此会有些许困惑。因此博主Roman Ring写了一篇概述性的文章,通过实现深度强化学习算法来具体的展示了TensorFlow 2.0的特性。
刀刀老高
2019/05/15
6730
详解深度强化学习展现TensorFlow 2.0新特性
强化学习系列(六)--Actor-Critic实例二
在上文中我们介绍了Acort-Critic的一种实现方式,本文主要介绍AC网络的一些优化算法。
languageX
2022/03/01
1.7K0
强化学习-PPO2
仍旧是玩平衡杆游戏,不过这次用了更为强大的PPO2,看完之后不经感叹里面的思想真的是太奇妙了!相较于朴素的策略网络,多了好多新的trick,不敢想象发明这个算法的人是有多聪明。
luxuantao
2021/02/24
1.3K0
【强化学习】Soft Actor-Critic (SAC) 算法
Soft Actor-Critic(SAC) 是一种最先进的强化学习算法,属于 Actor-Critic 方法的变体。它特别适合处理 连续动作空间,并通过引入最大熵(Maximum Entropy)强化学习的思想,解决了许多传统算法中的稳定性和探索问题。
不去幼儿园
2025/01/08
6450
【强化学习】Soft Actor-Critic (SAC) 算法
推荐阅读
相关推荐
【强化学习】Reward Model(奖励模型)详细介绍
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验