# 高级强化学习文档

有关使用 Unsloth 进行 GRPO 的详细指南：批处理、生成与训练参数：

## 训练参数

* **`beta`** *（float，默认 0.0）*：KL 系数。
  * `0.0` ⇒ 未加载参考模型（更省内存，更快）。
  * 更高的 `beta` 会约束策略，使其更接近参考策略。
* **`num_iterations`** *（int，默认 1）*：每个批次的 PPO 轮数（算法中的 μ）。\
  在每个梯度累积步骤内重复利用数据；例如， `2` = 每个累积步骤进行两次前向传播。
* **`epsilon`** *（float，默认 0.2）*：用于 token 级 log-prob 比率的裁剪值（使用默认 ε 时，典型比率范围约为 \[-1.2, 1.2]）。
* **`delta`** *（float，可选）*：启用 **上界** 裁剪边界，用于 **双边 GRPO** ，当设置时。如果 `None`，则使用标准 GRPO 裁剪。建议在启用时 `> 1 + ε` （根据 INTELLECT-2 报告）。
* **`epsilon_high`** *（float，可选）*：上界 epsilon；若未设置，默认为 `epsilon` 。DAPO 建议 **0.28**.
* **`importance_sampling_level`** *（“token” | “sequence”，默认“token”）*:
  * `"token"`：原始的逐 token 比率（每个 token 一个权重）。
  * `"sequence"`：将逐 token 比率平均为单个序列级比率。\
    GSPO 表明，序列级采样通常能为序列级奖励带来更稳定的训练。
* **`reward_weights`** *（list\[float]，可选）*：每个奖励对应一个权重。如果 `None`，则所有权重 = 1.0。
* **`scale_rewards`** *（str|bool，默认 "group"）*:
  * `True` 或 `"group"`：按 **每个组内的标准差** 进行缩放（组内单位方差）。
  * `"batch"`：按 **整个批次的标准差** （参见 PPO-Lite）。
  * `False` 或 `"none"`: **不缩放**。Dr. GRPO 建议不要缩放，以避免标准差缩放带来的难度偏差。
* **`loss_type`** *（str，默认 "dapo"）*:
  * `"grpo"`：按序列长度归一化（存在长度偏差；不推荐）。
  * `"dr_grpo"`：按 **全局常数** 归一化（由 Dr. GRPO 引入；消除长度偏差）。常数约为 `max_completion_length`.
  * `"dapo"` **（默认）**：按 **全局累积批次中的有效 token 数** 进行归一化（由 DAPO 引入；消除长度偏差）。
  * `"bnpo"`：按 **仅本地批次中的有效 token 数** （结果可能随本地批次大小而变化；当 `per_device_train_batch_size == 1`).
* **`mask_truncated_completions`** *（bool，默认 False）*：\
  当 `True`时，截断的完成内容会从损失中排除（DAPO 建议这样做以提升稳定性）。\
  **注意**：这个标志存在一些 KL 问题，因此我们建议将其关闭。

  ```python
  # 如果启用了 mask_truncated_completions，则将 completion_mask 中的截断完成内容置零
  if self.mask_truncated_completions:
      truncated_completions = ~is_eos.any(dim=1)
      completion_mask = completion_mask * (~truncated_completions).unsqueeze(1).int()
  ```

  当许多完成内容被截断时，这可能会将所有 `completion_mask` 条目置零，从而使 `n_mask_per_reward = 0` 并导致 KL 变为 NaN。 [参见](https://github.com/unslothai/unsloth-zoo/blob/e705f7cb50aa3470a0b6e36052c61b7486a39133/unsloth_zoo/rl_replacements.py#L184)
* **`vllm_importance_sampling_correction`** *（bool，默认 True）*：\
  应用 **截断重要性采样（TIS）** ，以在生成（例如 vLLM / fast\_inference）与训练后端不同时时修正离策略效应。\
  在 Unsloth 中，如果你使用 vLLM/fast\_inference，这将 **自动设为 True** ；否则 **False**.
* **`vllm_importance_sampling_cap`** *（float，默认 2.0）*：\
  TIS 的截断参数 **C** ；为重要性采样比率设置上界，以提高稳定性。
* **`dtype`** 当选择 float16 或 bfloat16 时，参见 [用于 RL 的 FP16 vs BF16](/docs/zh/kai-shi-shi-yong/reinforcement-learning-rl-guide/advanced-rl-documentation/fp16-vs-bf16-for-rl.md)

### 不受支持模型上的 RL：

你也可以在 Unsloth 上对 vLLM 不支持的模型运行 RL，例如 [Qwen3.5](/docs/zh/mo-xing/qwen3.5/fine-tune.md)。只需在加载模型时设置 `fast_inference=False` 。

```python
from unsloth import FastLanguageModel

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="unsloth/Qwen3.5-4B",
    fast_inference=False,
)
```

## 生成参数

* `temperature（float，默认 1.0）：`\
  采样温度。温度越高，完成内容越随机。请确保使用相对较高的（1.0）温度，以便生成多样性，这有助于学习。
* `top_p（float，可选，默认 1.0）：`\
  控制要考虑的最高概率 token 的累计概率的浮点数。必须在 (0, 1] 范围内。设为 1.0 以考虑所有 token。
* `top_k（int，可选）：`\
  保留用于 top-k 过滤的最高概率词表 token 数量。如果为 None，则禁用 top-k 过滤，并考虑所有 token。
* `min_p（float，可选）：`\
  最小 token 概率，它会按最可能 token 的概率进行缩放。其值必须在 0.0 到 1.0 之间。典型值在 0.01-0.2 范围内。
* `repetition_penalty（float，可选，默认 1.0）：`\
  根据新 token 是否出现在提示词和已生成文本中，对其进行惩罚的浮点数。值 > 1.0 会鼓励模型使用新 token，而值 < 1.0 会鼓励模型重复 token。
* `steps_per_generation:（int，可选）：`\
  每次生成的步数。如果为 None，则默认为 `gradient_accumulation_steps`。与 `generation_batch_size`.

{% hint style="info" %}
互斥。 `对于批大小，建议修改` per\_device\_train\_batch\_size
{% endhint %}

## 和梯度累积

### 批次与吞吐量参数

* **`train_batch_size`**：每个样本数 **每个进程** 每步。\
  如果这个整数 **小于 `num_generations`**，则默认设为 `num_generations`.
* **`steps_per_generation`**： **微批次** 的数量，这些微批次会参与 **一次生成的** 损失计算（仅前向传播）。\
  每隔 `steps_per_generation` 步会生成一个新批次的数据；反向传播时机取决于 `gradient_accumulation_steps`.
* **`num_processes`**：分布式训练进程数量（例如 GPU / worker）。
* **`gradient_accumulation_steps`** （又名 `gradient_accumulation`）：在 **之前** 累积的微批次数，然后再进行反向传播和优化器更新。
* **有效批大小**:

  ```
  effective_batch_size = steps_per_generation * num_processes * train_batch_size
  ```

  在一次更新之前，对梯度有贡献的总样本数（跨所有进程和步骤）。
* **每次生成的优化器步数**:

  ```
  optimizer_steps_per_generation = steps_per_generation / gradient_accumulation_steps
  ```

  示例： `4 / 2 = 2`.
* **`num_generations`**：每个提示词生成的数量 **每个提示词** （在计算 **之后** 进行 `effective_batch_size`）。\
  一个生成周期中的 **唯一提示词** 数量为：

  ```
  unique_prompts = effective_batch_size / num_generations
  ```

  **必须大于 2** GRPO 才能工作。

### GRPO 批次示例

下表展示了批次如何在步骤中流动、优化器何时更新，以及新批次如何生成。

#### 示例 1

```
num_gpus = 1
per_device_train_batch_size = 3
gradient_accumulation_steps = 2
steps_per_generation = 4

effective_batch_size = 4 * 3 * 1 = 12
num_generations = 3
```

**生成周期 A**

| 步骤 | 批次       | 备注                  |
| -: | -------- | ------------------- |
|  0 | \[0,0,0] |                     |
|  1 | \[1,1,1] | → 优化器更新（累计 = 2 已达到） |
|  2 | \[2,2,2] |                     |
|  3 | \[3,3,3] | 优化器更新               |

**生成周期 B**

| 步骤 | 批次       | 备注                  |
| -: | -------- | ------------------- |
|  0 | \[4,4,4] |                     |
|  1 | \[5,5,5] | → 优化器更新（累计 = 2 已达到） |
|  2 | \[6,6,6] |                     |
|  3 | \[7,7,7] | 优化器更新               |

#### 示例 2

```
num_gpus = 1
per_device_train_batch_size = 3
steps_per_generation = gradient_accumulation_steps = 4

effective_batch_size = 4 * 3 * 1 = 12
num_generations = 3
```

**生成周期 A**

| 步骤 | 批次       | 备注                |
| -: | -------- | ----------------- |
|  0 | \[0,0,0] |                   |
|  1 | \[1,1,1] |                   |
|  2 | \[2,2,2] |                   |
|  3 | \[3,3,3] | 优化器更新（累计 = 4 已达到） |

**生成周期 B**

| 步骤 | 批次       | 备注                |
| -: | -------- | ----------------- |
|  0 | \[4,4,4] |                   |
|  1 | \[5,5,5] |                   |
|  2 | \[6,6,6] |                   |
|  3 | \[7,7,7] | 优化器更新（累计 = 4 已达到） |

#### 示例 3

```
num_gpus = 1
per_device_train_batch_size = 3
steps_per_generation = gradient_accumulation_steps = 4

effective_batch_size = 4 * 3 * 1 = 12
num_generations = 4
unique_prompts = effective_batch_size / num_generations = 3
```

**生成周期 A**

| 步骤 | 批次       | 备注                |
| -: | -------- | ----------------- |
|  0 | \[0,0,0] |                   |
|  1 | \[0,1,1] |                   |
|  2 | \[1,1,3] |                   |
|  3 | \[3,3,3] | 优化器更新（累计 = 4 已达到） |

**生成周期 B**

| 步骤 | 批次       | 备注                |
| -: | -------- | ----------------- |
|  0 | \[4,4,4] |                   |
|  1 | \[4,5,5] |                   |
|  2 | \[5,5,6] |                   |
|  3 | \[6,6,6] | 优化器更新（累计 = 4 已达到） |

#### 示例 4

```
num_gpus = 1
per_device_train_batch_size = 6
steps_per_generation = gradient_accumulation_steps = 2

effective_batch_size = 2 * 6 * 1 = 12
num_generations = 3
unique_prompts = 4
```

**生成周期 A**

| 步骤 | 批次              | 备注                |
| -: | --------------- | ----------------- |
|  0 | \[0,0,0, 1,1,1] |                   |
|  1 | \[2,2,2, 3,3,3] | 优化器更新（累计 = 2 已达到） |

**生成周期 B**

| 步骤 | 批次              | 备注                |
| -: | --------------- | ----------------- |
|  0 | \[4,4,4, 5,5,5] |                   |
|  1 | \[6,6,6, 7,7,7] | 优化器更新（累计 = 2 已达到） |

### 快速公式参考

```
effective_batch_size = steps_per_generation * num_processes * train_batch_size
optimizer_steps_per_generation = steps_per_generation / gradient_accumulation_steps
unique_prompts = effective_batch_size / num_generations   # 必须大于 2
```


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unsloth.ai/docs/zh/kai-shi-shi-yong/reinforcement-learning-rl-guide/advanced-rl-documentation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
