💡强化学习(RL)指南

全面了解强化学习(RL),以及如何使用 Unsloth 和 GRPO 训练你自己的 DeepSeek-R1 推理模型。从入门到高级的完整指南。

强化学习是指“智能体”通过与环境交互并接收 反馈奖励惩罚.

  • 动作: 模型生成的内容(例如一句话)。

  • 奖励: 表示模型动作好坏的信号(例如,回答是否遵循指令?是否有帮助?)。

  • 环境: 模型正在处理的场景或任务(例如回答用户的问题)。

🦥你将学到什么

  1. 什么是 RL?RLVR?PPO?GRPO?RLHF?RFT? “运气就是你所需要的一切?” 用于 RL?

  2. 什么是环境?智能体?动作?奖励函数?奖励?

本文涵盖你需要了解的关于 GRPO、强化学习(RL)和奖励函数的一切内容(从入门到进阶),以及技巧和使用 GRPO 的基础知识, 使用 Unsloth 进行arrow-up-right。如果你在寻找使用 GRPO 的逐步教程,请查看我们的指南 这里.

circle-check

什么是强化学习(RL)?

RL 的目标是:

  1. 提高看到 “好” 结果的概率。

  2. 降低看到 “坏” 结果的概率。

就这样! “好”和“坏”具体指什么,或者我们该如何“提高”或“降低”它,甚至“结果”是什么意思,其中都有很多细节。

例如,在 吃豆人游戏:

  1. 使用 Unsloth 包和模型的 环境中 就是游戏世界。

  2. 使用 Unsloth 包和模型的 你可以采取的 动作

  3. 使用 Unsloth 包和模型的 奖励 包括向上、向左、向右和向下。

  4. 如果你吃到饼干就是好动作,如果撞到那些弯弯曲曲的敌人就是坏动作。

在 RL 中,你不能预先知道你能采取的“最佳动作”,但你可以观察中间步骤,或最终的游戏状态(赢或输) 另一个例子是,假设你被问到: “2 + 2 等于多少?”(4)一个未对齐的语言模型会输出 3、4、C、D、-10,几乎什么都可能。

  1. 数字总比 C 或 D 好,对吧?

  2. 得到 3 总比比如 8 好,对吧?

  3. 得到 4 当然是正确的。

我们刚刚设计了一个 奖励函数!

🏃从 RLHF、PPO 到 GRPO 和 RLVR

OpenAI 普及了 RLHFarrow-up-right (基于人类反馈的强化学习)这个概念,在其中我们训练一个 “智能体” 为某个问题生成输出(即 状态),这些输出会被人类评为更有用。

例如,ChatGPT 中的点赞和点踩可以用于 RLHF 流程。

PPO 公式

clip(..., 1-e, 1+e) 这一项用于强制 PPO 不进行过大的变化。此外还有一个 KL 项,将 beta 设为 > 0,以强制模型不要偏离太多。

为了进行 RLHF, PPOarrow-up-right (近端策略优化)被开发出来。此时的 智能体 就是语言模型。事实上,它由 3 个系统组成:

  1. 使用 Unsloth 包和模型的 生成策略(当前训练中的模型)

  2. 使用 Unsloth 包和模型的 参考策略(原始模型)

  3. 使用 Unsloth 包和模型的 价值模型(平均奖励估计器)

我们使用 奖励模型 来计算当前环境的奖励,我们的目标是 最大化这个奖励!

PPO 的公式看起来相当复杂,因为它是为了稳定性而设计的。想了解更深入的 PPO 数学推导,请访问我们在 2025 年关于 RL 的 AI Engineer 演讲arrow-up-right

DeepSeek 开发了 GRPOarrow-up-right (组相对策略优化)来训练他们的 R1 推理模型。与 PPO 的主要区别是:

  1. 使用 Unsloth 包和模型的 移除了价值模型, 改为使用多次调用奖励模型得到的统计信息。

  2. 使用 Unsloth 包和模型的 移除了奖励模型 并将其替换为仅使用自定义奖励函数, RLVR 可以使用。

这意味着 GRPO 极其高效。此前 PPO 需要训练多个模型——现在去掉奖励模型和价值模型后,我们可以节省内存并加快一切。

RLVR(带可验证奖励的强化学习) 使我们能够基于易于验证解答的任务来奖励模型。例如:

  1. 数学方程可以轻松验证。例如 2+2 = 4。

  2. 代码输出可以验证是否正确执行。

  3. 设计可验证的奖励函数可能很难,所以大多数示例都是数学或代码。

  4. GRPO 的用途不只是代码或数学——它的推理过程还能增强电子邮件自动化、数据库检索、法律和医学等任务,并根据你的数据集和奖励函数大幅提高准确率——诀窍在于定义一个 评分标准——也就是一组更小、可验证的奖励,而不是一个最终包揽一切的单一奖励。 OpenAI 在他们的 强化学习微调(RFT)arrow-up-right 服务中普及了这一点。

为什么是“Group Relative(组相对)”?

GRPO 完全移除了价值模型,但我们仍需要估计 “平均奖励” ,基于当前状态。

使用 Unsloth 包和模型的 诀窍是对 LLM 进行采样!然后我们通过多个不同问题上的采样过程统计来计算平均奖励。

例如,对于“2+2 等于多少?”我们采样 4 次。可能得到 4、3、D、C。然后我们分别计算这些答案的奖励,再计算 平均奖励标准差,然后进行 Z 分数标准化

这会得到 优势 A,我们将用它来替代价值模型。这能节省大量内存!

GRPO 优势计算

🤞运气(嗯,耐心)就是你所需要的一切

RL 的诀窍只需要 2 件事:

  1. 一个问题或指令,例如“2+2 等于多少?”、“用 Python 创建一个 Flappy Bird 游戏”

  2. 一个奖励函数和验证器,用来验证输出是好还是坏。

只要有这 2 个,我们本质上就可以 无限次调用语言模型 ,直到得到一个好答案。比如对于“2+2 等于多少?”,一个未训练的糟糕语言模型会输出:

0、cat、-10、1928、3、A、B、122、17、182、172、A、C、BAHS、%$、#、9、-192、12.31**** 然后突然变成 4.

奖励信号是 0、0、0、0、0、0、0、0、0、0、0、0、0、0、0**** 然后突然变成 1。

所以凭运气和偶然,RL 成功在多个 rollout(采样展开)中找到了正确答案。我们的目标是希望看到正确答案 4 的次数更多,而其余的(错误答案)少得多。

所以 RL 的目标是保持耐心——在极限情况下,如果正确答案的概率至少是一个很小的数(不为零),那这本质上就是一场等待游戏——最终你 100% 一定会遇到正确答案。

所以我喜欢把它称为 RL 的“运气就是你所需要的一切”。

不过更好的说法是 RL 的“耐心就是你所需要的一切”。

RL 本质上给了我们一个技巧——我们并不只是等待到无限长,而是会得到“坏信号”,也就是坏答案,然后我们本质上可以“引导”模型,提前尝试不要生成坏解。这意味着,虽然你花了很长时间等一个“好”答案出现,但模型其实已经被改变了,会尽最大努力不输出坏答案。

在“2+2 等于多少?”这个例子里—— 0、cat、-10、1928、3、A、B、122、17、182、172、A、C、BAHS、%$、#、9、-192、12.31**** 然后突然变成 4.

由于我们得到了坏答案,RL 会影响模型尽量不要输出坏答案。这意味着随着时间推移,我们会小心地“剪枝”或将模型的输出分布从坏答案中移开。这意味着 RL 是 高效的,因为我们并不是只是在无限等待,而是在主动试图把模型尽可能推向“正确答案空间”。

triangle-exclamation

🦥Unsloth 为 RL 提供什么

  • 只需 15GB 显存,Unsloth 就能让你把任何最多 17B 参数的模型,如 Llama 3.1(8B)、Phi-4(14B)、Mistral(7B)或 Qwen2.5(7B)转换为推理模型

  • Unsloth 现在支持 用于视觉/多模态的 RL 模型!

  • 最低要求: 只需 5GB 显存即可在本地训练你自己的推理模型(适用于任何 1.5B 参数或更小的模型)

circle-info

对于 高级 GRPO 关于批处理、生成和训练参数的文档, 请阅读我们的指南!

GRPO 笔记本:

circle-check
  • 如果你没有得到任何推理结果,请确保你有足够的训练步数,并确认你的 奖励函数/验证器 正在正常工作。我们提供了奖励函数示例 这里.

  • 之前的演示表明,你可以用 Qwen2.5(3B)实现你自己的“顿悟”时刻——但那需要 2 张 A100 GPU(160GB 显存)。现在借助 Unsloth,你只需一张 5GB 显存的 GPU 就能实现同样的“顿悟”时刻。

  • 以前,GRPO 只支持全量微调,但我们已经让它可以与 QLoRA 和 LoRA 一起工作

  • 20K 上下文长度 下,例如每个 prompt 生成 8 个输出时,Unsloth 对 Llama 3.1(8B)只使用 54.3GB 显存,而标准实现(+ Flash Attention 2)需要 510.8GB(Unsloth 少 90%).

  • 请注意,这并不是对 DeepSeek 的 R1 蒸馏模型进行微调,也不是使用 R1 的蒸馏数据进行调优——这些 Unsloth 已经支持。这里指的是使用 GRPO 将标准模型转换为完整的推理模型。

在一个测试示例中,尽管我们只用 GRPO 训练了 Phi-4 100 步,结果已经很明显。未使用 GRPO 训练的模型没有思考 token,而使用 GRPO 训练的模型则有,并且也给出了正确答案。

💻使用 GRPO 训练

如果你想了解如何使用 Unsloth 和 GRPO 将任何开源 LLM 转换为推理模型的教程, 请看这里.

circle-check

GRPO 如何训练模型

  1. 对于每个问答对,模型会生成多个可能的回复(例如 8 种变体)。

  2. 每个回复都会使用奖励函数进行评估。

  3. 训练步骤:

    • 如果你有 300 行数据,那就是 300 个训练步骤(如果训练 3 个 epoch,则是 900 步)。

    • 你可以增加每个问题生成的回复数量(例如从 8 个增加到 16 个)。

  4. 模型会通过每一步更新其权重来学习。

circle-exclamation

基础/提示

  • 至少等待 300 步 让奖励真正开始上升。为了获得不错的结果,你可能需要至少投入 12 小时(这就是 GRPO 的工作方式),但请记住这不是强制的,因为你随时可以停止。

  • 为了获得最佳结果,至少要有 500 行数据。你也可以只用 10 行数据试试,但更多会更好。

  • 每次训练运行都会因你的模型、数据、奖励函数/验证器等而不同,因此虽然我们写的最低值是 300 步,但有时可能需要 1000 步或更多。所以,这取决于多种因素。

  • 如果你在本地使用 Unsloth 的 GRPO,请在报错时同时执行“pip install diffusers”。另外也请使用最新版本的 vLLM。

  • 建议将 GRPO 应用于至少 1.5B 参数 的模型,以便正确生成思考 token,因为更小的模型可能无法做到。

  • 对于 GRPO 的 GPU 显存需求 在 QLoRA 4-bit下,一般规则是模型参数量 = 你需要的显存大小(你可以使用更少显存,但这只是为了稳妥)。你设置的上下文长度越长,所需显存越多。LoRA 16-bit 至少会使用 4 倍以上的显存。

  • 持续微调是 可行的,你只需让 GRPO 在后台运行即可。

  • 在示例笔记本中,我们使用 GSM8K 数据集,这是目前 R1 风格训练最流行的选择。

  • 如果你使用的是基础模型,请确保你有聊天模板。

  • 你用 GRPO 训练得越多越好。GRPO 最棒的地方在于你甚至不需要太多数据。你只需要一个优秀的奖励函数/验证器,训练时间越长,你的模型就会越好。你可以预期奖励与步数的关系会随着时间推移像这样上升:

  • GRPO 的训练损失跟踪现在已直接集成到 Unsloth 中,不再需要 wandb 等外部工具。它现在包含所有奖励函数的完整日志细节,包括总的聚合奖励函数本身。

在不受支持模型上的 RL:

你也可以在 Unsloth 上对 vLLM 不支持的模型运行 RL,例如 Qwen3.5。只需在加载模型时设置 fast_inference=False

📋奖励函数 / 验证器

在强化学习中, 奖励函数验证器 在评估模型输出时承担不同角色。一般来说,你可以把它们理解为同一回事,但严格来说它们并不相同,不过这并不重要,因为它们通常会一起使用。

验证器:

  • 决定生成的回复是正确还是错误。

  • 它不赋予数值分数——它只是验证正确性。

  • 示例:如果模型对“2+2”生成“5”,验证器会检查并标记为“错误”(因为正确答案是 4)。

  • 验证器还可以执行代码(例如 Python)来验证逻辑、语法和正确性,而无需人工评估。

奖励函数:

  • 将验证结果(或其他标准)转换为数值分数。

  • 示例:如果答案错误,它可能给出惩罚(-1、-2 等);而正确答案则可能获得正分(+1、+2)。

  • 它也可以根据正确性之外的标准进行惩罚,例如过长或可读性差。

关键区别:

  • 一个 验证器 检查正确性但不评分。

  • 一个 奖励函数 给出分数,但不一定自己验证正确性。

  • 奖励函数 可以 使用验证器,但严格来说它们并不相同。

理解奖励函数

GRPO 的主要目标是最大化奖励并学习答案是如何得出的,而不只是记住并复现训练数据中的回复。

  • 在每个训练步骤中,GRPO 调整模型权重 以最大化奖励。这个过程会逐步对模型进行微调。

  • 常规微调 (没有 GRPO)只会 最大化下一个词的预测概率 ,但不会针对奖励进行优化。GRPO 优化的是奖励函数 ,而不只是预测下一个词。

  • 你可以 重复使用数据 跨多个 epoch。

  • 默认奖励函数 可以预先定义,用于各种场景;或者你也可以让 ChatGPT/本地模型为你生成它们。

  • 设计奖励函数或验证器没有唯一正确的方法——可能性是无穷的。不过,它们必须设计得当且有意义,因为糟糕的奖励设计可能会无意中降低模型性能。

🪙奖励函数示例

你可以参考下面的示例。你可以将生成结果输入到 ChatGPT 4o 或 Llama 3.1(8B)这样的 LLM 中,并设计一个奖励函数和验证器来评估它。例如,把你的生成结果输入你选择的 LLM,并设定一条规则:“如果答案听起来太机械,就扣 3 分。”这有助于根据质量标准优化输出

示例 #1:简单算术任务

  • 问题: "2 + 2"

  • 答案: "4"

  • 奖励函数 1:

    • 如果检测到数字 → +1

    • 如果未检测到数字 → -1

  • 奖励函数 2:

    • 如果数字与正确答案匹配 → +3

    • 如果错误 → -3

  • 总奖励: 所有奖励函数之和

示例 #2:电子邮件自动化任务

  • 问题: 传入邮件

  • 答案: 发出邮件

  • 奖励函数:

    • 如果答案包含必需关键词 → +1

    • 如果答案与理想回复完全匹配 → +1

    • 如果回复过长 → -1

    • 如果包含收件人姓名 → +1

    • 如果包含签名块(电话、邮箱、地址) → +1

Unsloth 基于接近度的奖励函数

如果你查看过我们的 高级 GRPO Colab 笔记本,你会注意到我们创建了一个 自定义的基于接近度的奖励函数 ,完全从零构建,旨在奖励更接近正确答案的回复。这个灵活的函数可应用于广泛的任务。

  • 在我们的示例中,我们在 Qwen3(Base)中启用推理,并引导它完成特定任务

  • 应用预微调策略,避免 GRPO 默认只学习格式化的倾向

  • 使用基于正则表达式的匹配提高评估准确率

  • 创建超越通用提示词的自定义 GRPO 模板,例如 think,例如, <start_working_out></end_working_out>

  • 应用基于接近度的评分——模型对更接近的答案获得更多奖励(例如,预测 9 而不是 10 比预测 3 更好),而离群答案会受到惩罚

GSM8K 奖励函数

在我们其他示例中,我们使用由 @willccbbarrow-up-right 提供的现成 GSM8K 奖励函数,它很受欢迎,并且被证明非常有效:

  • correctness_reward_func – 奖励与标签完全匹配。

  • int_reward_func – 鼓励仅包含整数的答案。

  • soft_format_reward_func – 检查结构,但允许轻微的换行不匹配。

  • strict_format_reward_func – 确保回复结构与提示匹配,包括换行。

  • xmlcount_reward_func – 确保回复中每个 XML 标签都恰好出现一次。

🧮使用 vLLM

你现在可以在你的微调栈中直接使用 vLLMarrow-up-right ,这能带来更高吞吐量,并让你能够同时对模型进行微调和推理!在 1 张 A100 40GB 上,使用 Unsloth 对 Llama 3.2 3B Instruct 的动态 4bit 量化时,预计速度约为 4000 tokens/s。在 16GB 的 Tesla T4(免费的 Colab GPU)上,你可以达到 300 tokens/s。 我们还神奇地移除了同时加载 vLLM 和 Unsloth 时的双倍内存占用,为 Llama 3.1 8B 节省约 5GB,为 Llama 3.2 3B 节省 3GB。Unsloth 最初可以在 1 张 48GB GPU 上微调 Llama 3.3 70B Instruct,而 Llama 3.3 70B 权重本身就占用 40GB 显存。如果我们不消除双倍内存占用,那么将 Unsloth 和 vLLM 一起加载时就需要 >= 80GB 显存。 但借助 Unsloth,你仍然可以在不到 48GB 显存的单个方案中完成微调,并获得快速推理的好处!要使用快速推理,首先安装 vllm,然后以 fast_inference 实例化 Unsloth:

GRPO 要求指南

当你使用 Unsloth 进行 GRPO 时,我们通过多种技巧,相比使用 Flash Attention 2 的标准实现,智能地将显存使用降低 90% 以上!例如在 20K 上下文长度、每个 prompt 生成 8 个结果的情况下,Unsloth 对 Llama 3.1 8B 只使用 54.3GB 显存,而标准实现需要 510.8GB(Unsloth 少 90%).

  1. 对于 GRPO 的 QLoRA 4-bit 的 GPU 显存需求下,一般规则是模型参数量 = 你需要的显存大小(你可以使用更少显存,但这只是为了稳妥)。你设置的上下文长度越长,所需显存越多。LoRA 16-bit 至少会使用 4 倍以上的显存。

  2. 我们用于 GRPO 的新型内存高效线性内核可将内存使用减少 8 倍或更多。这节省了 68.5GB 内存,而且借助 torch.compile 实际上还更快!

  3. 我们利用了智能的 Unsloth 梯度检查点arrow-up-right 算法,这是我们之前发布的一项技术。它会在几乎只慢 1% 的情况下,智能地异步将中间激活值卸载到系统内存中。这节省了 52GB 内存。

  4. 与其他包中的实现不同,Unsloth 还使用与底层推理引擎(vLLM)相同的 GPU/CUDA 内存空间。这节省了 16GB 内存。

指标
使用 Unsloth 进行
标准 + FA2

训练内存成本(GB)

42GB

414GB

GRPO 内存成本(GB)

9.8GB

78.3GB

推理成本(GB)

0GB

16GB

20K 上下文长度的推理 KV 缓存(GB)

2.5GB

2.5GB

总内存使用

54.33GB(少 90%)

510.8GB

在典型的标准 GRPO 实现中,你需要创建大小为 (8. 20K) 的 2 个 logits 来计算 GRPO 损失。这需要 2 * 2 字节 * 8(生成数量)* 20K(上下文长度)* 128256(词表大小)= 78.3GB 显存。

Unsloth 将长上下文 GRPO 的内存使用减少了 8 倍,因此在 20K 上下文长度下,我们只需额外 9.8GB 显存!

我们还需要以 16bit 存储 KV Cache。Llama 3.1 8B 有 32 层,K 和 V 的大小都为 1024。因此 20K 上下文长度下的内存使用 = 2 * 2 字节 * 32 层 * 20K 上下文长度 * 1024 = 每个 batch 2.5GB。为了节省显存,我们会将 vLLM 的 batch size 设为 8,但在计算中我们先保持为 1。否则你会需要 20GB 的 KV cache。

🎥 Unsloth RL 3 小时工作坊视频

🎓延伸阅读

  1. Yannic Kilcher 的 GRPO YouTube 视频也是必看! https://www.youtube.com/watch?v=bAWV_yrqx4warrow-up-right

  2. 我们在 2025 年 AI Engineer World's Fair 上做了一个 3 小时工作坊。幻灯片和其他材料在 https://docs.unsloth.ai/ai-engineers-2025arrow-up-right

视频教程

这里有一些由很棒的 YouTuber 制作的视频教程,我们认为它们非常出色!

非常适合学习如何准备你的数据集,以及理解强化学习 + GRPO 基础背后的解释
在你自己的设备上进行本地 GRPO

最后更新于

这有帮助吗?