---
tags: [强化学习, GRPO, Wordle]
doc_type: knowledge-note
abstract: "从SFT起点构建多轮rollout、规则奖励、GRPO更新与稳定性分析。"
creation: 2026-10-15
返回目录: "[[计算机系/昇腾与CANN/大模型与算子专题学习导航|大模型与算子专题学习导航]]"
上一篇: "[[计算机系/昇腾与CANN/SFT监督微调与FSDP训练|SFT监督微调与FSDP训练]]"
前置知识: "[[计算机系/昇腾与CANN/SFT监督微调与FSDP训练|SFT监督微调与FSDP训练]]"
---

# Wordle 强化学习与 GRPO

前置：[SFT 监督微调与 FSDP](SFT监督微调与FSDP训练.md)。Wordle 协议、训练公共概念和 FSDP 机制在前篇集中说明。

## 1. 从示范学习到反馈学习

SFT 使用参考回复告诉模型怎样回答。RL 让模型生成不同尝试，用结果反馈调整策略分布。在 Wordle 中，逐步标注最优猜词很难，但猜中、格式是否有效、轮数等可以通过环境计算。

```text
Prompt → Policy 采样 → 多轮 Rollout → Reward → Advantage → 策略更新
```

Rollout 是一次完整交互轨迹，不只是一个 token 或一次前向。当前猜词改变环境反馈，反馈改变下一步上下文，因此奖励反映的是多步行为。

秘密词只能供环境与奖励函数判断结果，不能作为可见答案泄漏进模型 Prompt。

## 2. 三种策略角色

| 策略 | 作用 |
| --- | --- |
| 当前策略 $\pi_\theta$ | 正在更新的 Actor |
| 旧策略 $\pi_{old}$ | 产生本批 rollout 的行为策略，提供概率比的基准 |
| 参考策略 $\pi_{ref}$ | 通常固定为 SFT 初始模型，用于 KL 约束 |

旧策略与参考策略不能混为一谈。前者对应本次采样分布，后者用于限制长程漂移。参考策略也不必在所有实现中以独立、始终驻留的完整模型存在，存储方式由框架决定。

## 3. 奖励设计

| 分量 | 优化方向 | 风险 |
| --- | --- | --- |
| `correct_answer` | 在规定轮数内猜中 | 成功稀疏时学习信号不足 |
| `partial_answer` | 奖励部分字母或位置匹配 | 可能鼓励重复赚取局部得分 |
| `length_bonus` | 用更少轮数猜中 | 需明确成功条件，避免鼓励无效早停 |
| `format_reward` | 输出可解析的猜词标签 | 仅格式正确不能代表策略有效 |

示例中 correct 权重为 1，部分绿/黄反馈使用 0.2/0.1，format 权重为 0.2。奖励计算是否累计、猜中后是否保留 partial，需要读取具体奖励实现。

在一个“第 2 轮猜中、partial 计为 0”的约定下：

$$
r=1+0+\frac12+1\times0.2=1.7
$$

总奖励上涨但成功率不升，可能意味着模型正在改善格式或利用局部奖励。要同时看各分量和独立测试成功率。

## 4. GRPO 的组内相对优势

同一 Prompt 采样 $G$ 条轨迹，奖励为 $r_1,\ldots,r_G$，组内均值与标准差为 $\mu,\sigma$：

$$
A_i=\frac{r_i-\mu}{\sigma+\epsilon}
$$

正优势表示优于同组平均，负优势表示低于同组平均。这是相对比较，不是绝对正确性标签。

![GRPO优势](.assets/大模型与算子专题/GRPO优势.png)

图中的简式省略了数值稳定项。实际需要处理组内奖励全相同、标准差为零的情形；这种组通常没有可区分的相对奖励信号。

GRPO 通过组内奖励建立基线，可以省去单独训练的 Critic，但仍需 Actor、rollout、参考概率、激活与优化器等资源，不代表显存成本很低。

## 5. Clip、KL 与熵

对生成 token $a_t$ 和历史 $h_t$，概率比为：

$$
\rho_t=\frac{\pi_\theta(a_t\mid h_t)}{\pi_{old}(a_t\mid h_t)}
$$

典型剪裁目标使用：

$$
\min\left(\rho_t A_i,\operatorname{clip}(\rho_t,1-\delta,1+\delta)A_i\right)
$$

示例 $\delta\approx0.2$。Clip 限制更新激励，不能理解为所有策略变化都被严格限制在固定距离内。

| 项 | 作用 | 过强或过弱的影响 |
| --- | --- | --- |
| Policy gradient | 提高相对高奖励输出概率 | 过激时分布可能快速收缩 |
| KL penalty | 约束偏离参考策略 | 太弱易漂移，太强难以学习 |
| Entropy bonus | 保持一定探索 | 太弱可能塌缩，太强可能输出发散 |

若以最小化 loss 表示，可概括为 $L_{PG}+\beta L_{KL}-\alpha H$，但实际框架的符号、估计器、归一化与开关需看实现。这里的 $ε$（除零保护）与 $δ$（Clip 阈值）用途不同。

## 6. 训练框架与资源切换

![RL框架协作](.assets/大模型与算子专题/RL框架协作.png)

| 组件 | 职责 |
| --- | --- |
| verl / TaskRunner | 组织采样、奖励、优势和更新 |
| WordleAgentLoop | 解析猜词、调用环境、追加反馈与终止交互 |
| vLLM | 高吞吐生成 |
| vLLM-Ascend | 接入 NPU 执行 |
| Ray / FSDP | 分布式工作进程与训练更新 |

![训练与推理资源切换](.assets/大模型与算子专题/训练推理资源切换.png)

Hybrid Engine 让一组卡在推理和训练阶段切换角色，通过 sleep/wake、参数 offload 等方式降低同时驻留的资源压力。切换也有开销，并且必须保持 rollout 使用的策略版本与更新概率一致。

示例环境：CANN `9.0.0`、PyTorch/torch_npu `2.9.0`、vLLM/vLLM-Ascend `0.18.0`、verl `0.8.0`。这与 SFT 示例是不同的软件组合。

## 7. 环境与数据准备

以下流程采用 CANNLab 示例目录，仓库需提前准备在匹配的版本。每段命令的目录前提要独立确认。

vLLM 与适配器：

```bash
cd /home/developer/vllm
VLLM_TARGET_DEVICE=empty pip install -v -e .
cd /home/developer/vllm-ascend
git submodule update --init --recursive
pip install -v -e .
```

从 `cann-recipes-train` 根目录进入 Wordle 工程：

```bash
cd llm_rl/qwen3_wordle
pip install -r requirements.txt
python3 -c "import nltk; nltk.download('words'); nltk.download('averaged_perceptron_tagger_eng')"
cd verl
pip install -v -e .
git apply ../patches/0001-wordle-agent-loop.patch
```

补丁只适用于对应源码版本，已应用后不要重复执行。安装后在 Wordle 项目目录验证导入：

```python
from verl.experimental.agent_loop.wordle_agent_loop import WordleAgentLoop
from importlib.metadata import version

print("verl:", version("verl"))
print("vllm:", version("vllm"))
```

示例数据由 Wordle 词表经五字母词过滤生成，使用 2000 条训练、20 条测试：

```bash
python3 prepare_data.py --num_train 2000 --num_test 20 --output_dir data
```

20 个测试任务适合短流程检查，但成功率每个样本就变化 5 个百分点，不足以稳定证明小幅提升。应检查训练测试隔离，扩大评估或重复采样。

## 8. 一次 GRPO Step

![GRPO训练步骤](.assets/大模型与算子专题/GRPO训练步骤.png)

1. 读取一批 Prompt，保留秘密词供环境评分。
2. 每个 Prompt 采样多条完整游戏轨迹。
3. AgentLoop 解析 `<guess>`，产生 G/Y/X 反馈并追加到上下文。
4. 猜中或达到 6 次猜测上限后终止。
5. 计算分项奖励，再在同 Prompt 组内计算优势。
6. 计算策略目标与约束，反向传播并更新 Actor。

`response_mask=1` 对应模型生成的 token，`mask=0` 的环境反馈只提供上下文，不直接作为模型动作参与 policy gradient。否则会把环境写入的文字误当成模型行为训练。

| 参数 | 示例值 | 含义 |
| --- | --- | --- |
| `TRAIN_BATCH_SIZE` | 64 | Prompt 数 |
| `ROLLOUT_N` | 8 | 每个 Prompt 的尝试数 |
| `MAX_TURNS` | 6 | 最大猜测次数 |
| `ACTOR_LR` | `1e-6` | 策略学习率 |
| `ROLLOUT_TP` | 2 | 推理侧张量并行度 |
| `MAX_PROMPT_LENGTH` | 1024 | 输入长度上限 |
| `MAX_RESPONSE_LENGTH` | 4096 | 多轮响应长度上限，具体统计含义依框架 |

64 个 Prompt、每个 8 条轨迹，对应每批 512 条尝试，不等于需要同时在设备上展开全部轨迹，框架会进行调度。

配置 `MODEL_PATH` 指向 SFT checkpoint 后，在 Wordle 工程目录启动：

```bash
ASCEND_RT_VISIBLE_DEVICES=0,1 \
bash run_qwen3_1.7b_wordle_npu.sh
```

示例记录约 350 s/step、1500 token/s、47 GB/卡，属于特定运行参考，不能直接套用到其他卡型与长度配置。

## 9. 多指标诊断训练

| 指标 | 关注问题 |
| --- | --- |
| `actor/entropy` | 是否失去探索，或随机性失控 |
| `actor/kl_loss` | 偏离参考策略是否过快 |
| `actor/grad_norm` | 梯度异常与更新不稳定 |
| `critic/score/mean` | 奖励趋势；日志命名不代表一定存在 Critic |
| `response_length/mean` | 是否重复、截断或全部打满上限 |
| `num_turns/mean` | 交互长度，需明确计数口径 |
| correct / success rate | 是否实际完成目标 |

![稳定与崩溃对照](.assets/大模型与算子专题/RL稳定与崩溃对照.png)

稳定示例中，成功率从 15% 提升到 70%，输出长度约从 2078 降到 1255，熵仍有约 0.22。崩溃示例中，熵接近 0.0003、成功率归零、长度达到 3232。

3232 是该日志的截断现象，不是所有环境的固定上限。熵低本身也不是失败的充分条件，应结合成功率、输出内容、KL 和长度判断。

### 超参数对照

![熵系数实验](.assets/大模型与算子专题/熵系数实验.png)

在这一组实验中，熵系数 0 或 0.001 出现不同程度的塌缩，0.002 较稳定，0.005/0.01 有探索过强现象。这些值是 Wordle 实验起点，不能变成通用最优值。

可比较两组配置：

| 项 | A | B |
| --- | --- | --- |
| entropy coefficient | 0.002 | 0.002 |
| KL coefficient | 0.001 | 0.01 |
| Actor learning rate | `1e-6` | `1e-6` |
| 调度 | cosine | cosine |
| checkpoint 间隔 | 25 steps | 25 steps |

示例还使用 `min_lr_ratio=0.1`、`warmup_ratio=0.03`。调参应短跑观察，一次改变一个主要变量。过低学习率可能进展慢，过高可能不稳定，但不能仅凭某个数值断言必然梯度爆炸。

## 10. 异常后的处理顺序

1. 检查真实 rollout，排除格式解析、奖励函数、截断或答案泄漏问题。
2. 联合观察 entropy、KL、correct、长度和 grad_norm。
3. 保留日志并回到稳定 checkpoint，避免在已经塌缩的策略上盲目追加训练。
4. 根据原因调整：提高适量探索、增强 KL 或减小学习率，并做单变量对照。
5. 用独立验证任务确认改善，不能只看训练 reward。

实验中的修复路径包括 entropy `0→0.002`、KL `0.001→0.01`、学习率 `1e-6→5e-7`。这些是可比较的干预，不应一次同时修改后声称找到了唯一根因。

完成短跑后，应能解释：一条 rollout 包含什么、组内优势如何计算、旧策略与参考策略的区别、为什么环境反馈不参与动作损失，以及奖励提升是否对应成功率提升。

参考：[RL 训练流程](https://gitcode.com/cann/cann-learning-hub/tree/test/tutorials/rl_training_pipeline)。
