> For the complete documentation index, see [llms.txt](https://unsloth.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unsloth.ai/docs/zh/mo-xing/gpt-oss-how-to-run-and-fine-tune/gpt-oss-reinforcement-learning.md).

# gpt-oss 强化学习

你现在可以训练 OpenAI [gpt-oss](/docs/zh/mo-xing/gpt-oss-how-to-run-and-fine-tune.md) 使用 RL 和 GRPO 通过 [Unsloth](https://github.com/unslothai/unsloth)。Unsloth 现在提供 **最快的推理** （快 3 倍）， **最低的 VRAM 占用** （少 50%）以及 **最长上下文** （长 8 倍），用于 gpt-oss RL，相比任何实现都更优——且没有准确率下降。\
\
由于 gpt-oss 上的强化学习（RL）目前还不兼容 vLLM，我们不得不把推理代码从 Transformers 代码重写出来，以便为 gpt-oss 提供快 3 倍的推理速度，约 21 tokens/s。对于 BF16，Unsloth 也实现了最快的推理（约 30 tokens/s），尤其是在 VRAM 占用方面，相较于任何其他 RL 实现可少用 50% 的 VRAM。我们计划支持我们的 [50% 权重共享功能](/docs/zh/kuai-su-kai-shi/reinforcement-learning-rl-guide/memory-efficient-rl.md) 一旦 vLLM 变得支持 RL。

* **免费笔记本：** [**gpt-oss-20b GRPO Colab 笔记本**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt-oss-\(20B\)-GRPO.ipynb)\
  此笔记本会自动创建 **更快的矩阵乘法内核** 并使用 4 个新的 Unsloth 奖励函数。我们还展示了如何 [对抗奖励投机](#can-we-counter-reward-hacking) 这是 RL 最大的挑战之一。\\

  <figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-0217fec82f064279c090618091109c6b36c724de%2FAuto%20generated.png?alt=media" alt=""><figcaption></figcaption></figure>

使用 Unsloth，你可以在 15GB VRAM 和 **免费** 在 Colab 上训练 gpt-oss-20b 的 GRPO。我们引入了 embedding 卸载，这也通过 `offload_embeddings`。Unsloth 的新推理在 **any** 包括 A100、H100 和旧款 T4 的 GPU 上运行得更快。gpt-oss-120b 可轻松适配 120GB VRAM 的 GPU。

Unsloth 是唯一支持 gpt-oss 的 4-bit RL 框架。所有性能提升都归功于 Unsloth 独特的 [权重共享](/docs/zh/kuai-su-kai-shi/reinforcement-learning-rl-guide.md#what-unsloth-offers-for-rl), [Flex Attention](/docs/zh/kuai-su-kai-shi/reinforcement-learning-rl-guide/memory-efficient-rl.md), [Standby](/docs/zh/kuai-su-kai-shi/reinforcement-learning-rl-guide/memory-efficient-rl.md#unsloth-standby) 和自定义内核。

{% hint style="warning" %}
提醒： **Flash Attention 3（FA3）** [**不适用于 gpt-oss**](/docs/zh/mo-xing/gpt-oss-how-to-run-and-fine-tune/long-context-gpt-oss-training.md#introducing-unsloth-flex-attention-support) **训练** ，因为它目前不支持 attention sinks 的反向传播，导致 **训练损失不正确**。如果你 **不会** 使用 Unsloth，FA3 可能会被 默认，所以请务必仔细检查它没有被启用！\
\
禁用 FA3 还会带来 **O(N^2)** 更高的内存占用，因此 Unsloth 是唯一提供 **O(N)** 通过我们的 Flex attention 实现为 gpt-oss 提供内存占用的框架。
{% endhint %}

## ⚡让推理快得多

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-6e9b6a2f7381de84ed6eeb0feedc566cd443acf3%2F5b957843-eb58-4778-8b90-f25767c51495.png?alt=media" alt=""><figcaption></figcaption></figure>

推理在 RL 训练中至关重要，因为我们需要先生成候选解，然后再最大化某个奖励函数（[请看这里](/docs/zh/kuai-su-kai-shi/reinforcement-learning-rl-guide.md) 有关更详细的解释）。为了在不使用 vLLM 的情况下实现 gpt-oss 的最快推理速度，我们重写了 Transformers 的推理代码，并集成了许多创新，包括像 Unsloth 这样的自定义算法 [Flex Attention](/docs/zh/mo-xing/gpt-oss-how-to-run-and-fine-tune/long-context-gpt-oss-training.md#introducing-unsloth-flex-attention-support)，并在 `torch.compile` 中使用特殊标志（例如 combo kernels）。我们为 gpt-oss 编写的新推理代码是针对一个已经优化过的基线进行评估的（比原生 Transformers 快 2 倍）。

vLLM 不支持 gpt-oss 的 RL，因为它缺少 gpt-oss 的 BF16 训练和 LoRA 支持。没有 Unsloth，只有通过全精度 BF16 训练才可行，这使得 内存使用 **高出 800%+**。大多数框架默认启用 FA3（Flash Attention 3）（这会减少 VRAM 占用并提升速度） **但这会导致训练损失不正确**。参见 [问题 1797](https://github.com/Dao-AILab/flash-attention/issues/1797) 在 FA3 仓库中。你必须禁用 FA3，因为它会阻止长上下文训练，因为 FA3 使用 O(N) 内存占用，而朴素注意力会膨胀为 O(N^2) 占用。为了让 attention sinks 可微分，我们实现了 [Unsloth Flex Attention](/docs/zh/mo-xing/gpt-oss-how-to-run-and-fine-tune/long-context-gpt-oss-training.md).

我们通过对 BitsandBytes 4-bit 进行基准测试来评估 gpt-oss RL 推理，并且还针对 BF16 做了单独测试。Unsloth 的 4-bit 推理快约 4 倍，而 BF16 也更高效，尤其是在 VRAM 占用方面。

Unsloth 的 gpt-oss RL 最棒的一点是它可以在任何 GPU 上工作，甚至包括那些不支持 BF16 的 GPU。我们免费的 gpt-oss-20b Colab 笔记本使用的是较旧的 15GB T4 GPU，所以推理示例运行得很好！

## 🛠️ gpt-oss Flex Attention 问题与怪癖

我们不得不更改 attention sinks 的实现，因为 [这里所述](/docs/zh/mo-xing/gpt-oss-how-to-run-and-fine-tune/long-context-gpt-oss-training.md) 为了让生成在左侧填充下正常工作。我们不得不获取 logsumexp 并应用 sigmoid 激活来像下面这样改变注意力权重：

$$
A(X) = \sigma \bigg( \frac{1}{\sqrt{d}}QK^T \bigg)V \\

A(X) = \frac{\exp{\frac{1}{\sqrt{d}}QK^T}}{\sum{\exp{\frac{1}{\sqrt{d}}QK^T}}}V \\

\text{LSE} = \log{\sum{\exp{\frac{1}{\sqrt{d}}QK^T}}} \\

A\_{sinks}(X) = A(X) \odot \sigma (\text{LSE} - \text{sinks})
$$

推理期间的左侧填充掩码也是 gpt-oss 中一个棘手的问题。我们发现，我们不仅需要在生成 token 时考虑 KV Cache 预填充，还需要考虑批量生成中每个 prompt 各自独特的填充 token 数量，这会改变我们存储 block mask 的方式。下面可以看到这样一个示例：

**普通因果掩码：**

```
   k0 k1 k2 k3 k4   <-- 键
q0  X
q1  X  X
q2  X  X  X
q3  X  X  X  X
q4  X  X  X  X  X   <-- 最后一行查询（对解码最重要）
```

**对于一般情况下的推理（解码）**

```
    k0 k1 k2 k3 k4
q0
q1
q2
q3
q4   X  X  X  X  X
```

**如果我们天真地使用同样的掩码策略，这将失败：**

```
    k0 k1 k2 k3 k4
q0
q1
q2
q3
q4   X   （注意 q4 的 q_idx=0，因为这是当前设置中的第一个查询）
```

对于生成（解码阶段），我们通常只关心注意力矩阵的最后一行，因为只有一个查询 token 在关注所有之前的键 token。如果我们天真地应用因果掩码（`q_idx ≥ k_idx`），这会失败，因为我们的单个查询的索引为 0，而键 token 有 n\_k 个。为了解决这个问题，我们在掩码创建中需要一个偏移量来决定哪些 token 该被关注。但天真的方法很慢，因为偏移量每一步都在变化，迫使掩码和内核重新生成。我们通过缓存和编译优化解决了这个问题。

更难的部分是批量生成。序列长度不同，因此填充会使掩码创建变得复杂。Flex Attention 有很多 [挑战](https://github.com/meta-pytorch/attention-gym/issues/15#issuecomment-2284148665) ，而且动态掩码很棘手。更糟的是，如果不编译，它会回退到 eager attention，这很慢而且占用大量内存（按序列长度为二次方 vs. 线性）。

> *引自* [*https://github.com/meta-pytorch/attention-gym/issues/15#issuecomment-2284148665*](https://github.com/meta-pytorch/attention-gym/issues/15#issuecomment-2284148665)
>
> 你需要使用 \_compile=True 来调用它。我们本质上是把你的 block mask 映射到一个完整的 Q\_LEN x KV\_LEN 矩阵上，以生成 block mask。若不编译，我们就需要把这个完整矩阵物化出来，这在长序列上可能导致 OOM。
>
> 此外，你还需要运行 `flex_attention = torch.compile(flex_attention)`。如果不编译，flex 会回退到非融合的 eager 实现，它非常适合调试，但会慢得多，并且会物化完整的分数矩阵。

最终，掩码必须动态处理 KV Cache 下的 prefill 与 decode，每个序列的 batch 和 padding tokens，并保持 `torch.compile` 友好，并支持滑动窗口。

### 🔍 Flash Attention 调查

我们探索的另一个有趣方向是尝试集成 Flash Attention。它的优势广为人知，但一个限制是它不支持 gpt-oss 在反向传播期间的 attention sinks。为了解决这个问题，我们重新构建了注意力机制，使其只依赖于 FlashAttention 可直接提供的 attention output 和 logsumexp 值。考虑到这些好处，这看起来像是一个显而易见值得尝试的选择。

然而，我们很快开始注意到问题。虽然前几层表现如预期，但后面的层，尤其是第 18 到第 24 层，输出与 transformers 中 eager 模式的实现差异显著。重要的是，这种差异不能归因于误差累积，因为每一层输入在两种方法中都是相同的。为了进一步验证，我们还将结果与 Unsloth **FlexAttention**.

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-1c7a04d20aa814cd04065001d59e338c27426f19%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

这需要进一步调查，为什么只有最后几层与 flash attention 实现相比会表现出如此巨大的差异，而与其他实现不同。

{% hint style="danger" %}
**Flash Attention 3 不支持 attention sinks 的反向传播**

对于大多数训练包（不包括 Unsloth），FA3 通常默认启用，但这对 gpt-oss 来说是错误的。使用 FA3 会让训练损失完全错误，因为 FA3 不支持 gpt-oss 对 attention sinks 的反向传播。很多人仍然不知道这一点，所以请务必小心！
{% endhint %}

## ⚠️ 我们能对抗奖励投机吗？

强化学习（RL）的终极目标是最大化某种奖励（比如速度、收入或某个指标）。但 RL 可能会 **作弊。** 当 RL 算法学会了某种技巧或利用某些漏洞来提高奖励，但实际上并没有完成最终任务时，这被称为“**奖励黑客**".

这就是模型学会修改单元测试以通过编程挑战的原因，而这也是实际部署中的关键阻碍。还有一些很好的例子来自 [维基百科](https://en.wikipedia.org/wiki/Reward_hacking).

<div align="center"><figure><img src="https://i.pinimg.com/originals/55/e0/1b/55e01b94a9c5546b61b59ae300811c83.gif" alt="" width="188"><figcaption></figcaption></figure></div>

在我们的 [免费的 gpt-oss 强化学习笔记本](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt-oss-\(20B\)-GRPO.ipynb) 中，我们探讨了如何在代码生成场景中对抗奖励黑客，并展示了针对常见错误模式的切实解决方案。我们看到模型会修改计时函数、把工作外包给其他库、缓存结果，甚至直接作弊。在进行对抗后，结果是我们的模型生成的是真正优化过的矩阵乘法内核，而不是花招式的作弊。

## :trophy:奖励黑客

RL 期间奖励黑客的一些常见例子包括：

#### 偷懒

RL 学会使用 Numpy、Torch 及其他库，而这些库会调用经过优化的 CUDA 内核。我们可以通过检查生成的代码是否导入了其他非标准 Python 库，来阻止 RL 算法调用优化代码。

#### 缓存与作弊

RL 学会缓存输出结果，并学会通过检查 Python 全局变量来找到实际输出。

我们可以用一个巨大的假矩阵清空缓存，从而阻止 RL 算法使用缓存数据。我们还必须通过多次循环和多轮测试来谨慎地进行基准测试。

#### 作弊

RL 学会修改计时函数，使其输出 0 时间作为经过时间。我们可以通过限制它的 `局部变量` 和 `全局变量`。我们还将使用 `exec` 来创建该函数，因此我们必须将输出保存到一个空字典中。我们还通过以下方式禁止访问全局变量： `types.FunctionType(f.__code__, {})`\\\\

## 教程：如何使用 RL 训练 gpt-oss

LLM 往往难以应对涉及复杂环境的任务。然而，通过应用 [强化学习](/docs/zh/kuai-su-kai-shi/reinforcement-learning-rl-guide.md) （RL）并设计一个自定义 [奖励函数](/docs/zh/kuai-su-kai-shi/reinforcement-learning-rl-guide.md#reward-functions-verifiers)，这些挑战就可以被克服。

RL 可以适用于自动内核或策略创建等任务。本教程展示了如何训练 **gpt-oss** 替换为 [**GRPO**](/docs/zh/kuai-su-kai-shi/reinforcement-learning-rl-guide.md#from-rlhf-ppo-to-grpo-and-rlvr) 并使用 Unsloth 自主打败 2048。

我们的笔记本已经包含了关于如何完成整个流程的逐步指南。

| [2048 笔记本](https://colab.research.google.com/github/openai/gpt-oss/blob/main/examples/reinforcement-fine-tuning.ipynb) （OpenAI 官方示例） | [Kernel 生成笔记本](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/gpt-oss-\(20B\)-GRPO.ipynb) |
| ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |

**你将构建：**

* 训练 gpt-oss-20b，使模型能够自动赢得 2048
* 创建一个模型可以交互的最小 2048 环境
* 定义 **奖励函数** ，它们：
  1. 检查生成的策略是否可编译且可运行，
  2. 防止奖励投机（禁止外部导入），并且
  3. 奖励实际的游戏成功
* 运行推理并导出模型（MXFP4 4 位或合并的 FP16）

{% hint style="info" %}
**硬件：** 2048 示例可在免费的 Colab T4 上运行，但训练会很慢。A100/H100 快得多。4 位加载 + LoRA 让你可以把一个 20B 模型装进适度的 VRAM 中
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://unsloth.ai/docs/zh/mo-xing/gpt-oss-how-to-run-and-fine-tune/gpt-oss-reinforcement-learning.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
