RLforge
完整主线 路线25 / 27 · L4 淬火退出路线
原理预计 35 分钟

调参优先级:先动哪三个旋钮

十几个超参不必都调。按影响排序,前三个决定成败,剩下的基本不用碰。

学完这节你能做到

  • 按影响力给 GRPO 的超参排序,并说出每个的合理起始值
  • 判断一个现象该调哪个参数,而不是全部微调一遍
  • 在有限的卡时里设计出信息量最大的实验序列

十几个旋钮,只有三个值得动

GRPO 的配置项加起来有二十多个。新手的典型做法是逐个微调,跑完发现哪个都没用,卡时烧光了。

真实的影响力分布极不均匀:

影响力
  ▲
  │ ████████████████████  reward 设计
  │ ████████              学习率 / KL 系数
  │ ████                  G / batch / temperature
  │ ▌                     clip 阈值 / betas / warmup
  └──────────────────────────────────────────────→

这一节给出这个排序的依据,以及每一档的合理起始值。L2「三轮迭代」那次实验的结论正是这个排序的实证:调超参最好只拿到 +0.8(噪声内),改采样策略拿到 +5.3。

第一优先:reward 设计

它不算超参,但影响最大——而且是唯一一个「调错了别的都救不了」的东西。

理由在 L1「reward 从哪来」讲过:模型优化的是你写的 reward,不是你心里想的目标。如果 reward 有捷径,无论学习率、KL、batch 怎么调,模型都会去走那条捷径。

检查顺序(每次实验前都过一遍):

□ reward 拆成分项记录了吗?(否则 hacking 发生时看不出来)
□ 每一项的「成功率 × 分值」排序对吗?便宜的分给得少吗?
□ 空答案 / 截断样本拿多少分?
□ 有没有「重复某模式就能重复拿分」的项?
□ 分数是纯 0/1 吗?(容易整组归零)
×一个反直觉的现象

调 reward 常常不表现为分数上涨,而表现为「训练终于开始动了」。

比如 L2 里格式分从 0.2 降到 0.05,分数只 +0.5(噪声内)——但 reward 的绝对值从 0.847 降到 0.661,更贴近真实正确率,曲线一下变得好读了。

reward 的价值不只在最终分数,还在让你的监控可信。

第二优先:学习率与 KL 系数

学习率

RL 后训练的学习率比 SFT 低一到两个数量级:

阶段典型学习率
预训练1e-4 ~ 3e-4
SFT1e-5 ~ 5e-5
RL 后训练1e-6 ~ 5e-6

为什么这么低:RL 的每一步都在改变数据分布本身(改了模型就改了下一批采样)。走太快会让分布剧烈震荡,采出来的数据和优势估计都失去意义。

起始值 1e-6(slime、Miles、TRL 的推荐档都在这里)。

✓用 clip_frac 当学习率的仪表盘

不要凭感觉调,看这个数:

clip_frac判断动作
< 1%更新过于保守可以试 2e-6 ~ 3e-6
2% ~ 10%健康别动
10% ~ 20%偏猛观察 reward 有没有还在涨
> 20%太猛降一个档

配合 gnorm(梯度范数)一起看:健康时在 1 附近,跑到 5 以上说明单步想跳太远。

L2 read-the-curve 的 D 组辨认过:clip=0.419 / gnorm=6 就是学习率过大(那次是 5e-5,高了 50 倍)。

KL 系数 β

β效果什么时候用
0完全不约束✅ 默认起点(可验证奖励 + 中短训练)
0.001轻度训练变长、开始看到 KL 上行
0.01中度⚠️ L2 实测掉 11.8 个点,慎用
> 0.05强约束只在救火时用

L2 那轮实验的结论值得记住:β=0.01 有害的机制是 KL 不区分「有益的漂移」和「有害的漂移」。 它把模型拴在初始分布附近,连「多写几步推理」这个有益变化都做不出来(len 只涨到 108,对照组 152)。

!β=0 但一定要留参考模型

现代配方常把 β 设 0(slime 入门例子就是 --kl-loss-coef 0.00),但它同时开着 --use-kl-loss——KL 不进损失,作为监控指标记录。

单卡上为省 1.1 GiB 而完全不要参考模型,代价是失去 KL 预警。L4「五种炸法」里那份 KL 从 0.002 飙到 12.88 的日志,就是这么来的。

留着它。1.1 GiB 换一条预警线,很划算。

第三优先:G、batch、temperature

G(组大小)

L2 的实测结论:收益递减点在 8 附近。

G退化组占比等卡时下的表现
418.4%−4.3 个百分点,明显更差
89.1%✅ 基准
166.2%+0.8(噪声内),不划算

下界是 4(再小基线估计不可用),上界看你的耐心。不确定就用 8。

batch

两个维度要分开看:

维度加大的收益优先级
每步 prompt 数数据多样性上升✅ 优先加这个
G组内基线更准收益 8 之后递减

单卡上受显存限制,8 prompt × G=8 = 64 条序列是个舒服的组合。显存有余量时优先加 prompt 数。

imicro batch 不是超参

micro_batch 只影响显存和速度,不影响数学结果(配合梯度累积等价)。

所以它不参与调参——OOM 了就降到 1,够用就加大。别把它和「有效 batch」混在一起讨论。

temperature

它是探索与稳定之间最直接的旋钮:

temperature效果
0❌ 组内无差异,训练完全不动
0.7 ~ 0.8偏保守,容易出现整组全对或全错
1.0✅ 默认起点
1.1 ~ 1.2救熵崩塌用
> 1.3输出质量下滑,容易变胡话

诊断对应关系:

adv_std 一直很低(且 entropy 正常)  →  提 temperature,增加组内差异
entropy 在往 0 走                   →  提 temperature(配合熵奖励)
输出开始不通顺、格式散乱             →  降回 1.0

基本不用动的

参数推荐值为什么不用动
clip 下界 eps0.2PPO 以来的稳定默认值
clip 上界 eps_high0.28DAPO 的非对称 clip,鼓励探索;slime 入门配方就是这组
adam_beta10.9标准值
adam_beta20.98⚠️ 注意不是默认的 0.999。RL 里梯度统计变化快,0.98 更跟得上
weight_decay0 ~ 0.1影响很小
warmup0 步RL 从一个已训练好的模型出发,不需要 warmup
max_grad_norm1.0标准的梯度裁剪
✓beta2=0.98 是唯一一个「反默认」的推荐

PyTorch 的 AdamW 默认 betas=(0.9, 0.999)。RL 后训练普遍用 0.98。

原因:0.999 意味着二阶动量的有效窗口约 1000 步。而 RL 里数据分布每步都在变,1000 步前的梯度统计已经过时了。0.98 把窗口缩到约 50 步,跟得上分布变化。

slime 的入门配方就是 --adam-beta1 0.9 --adam-beta2 0.98。直接抄。

三组起始配置

拿去直接用,不用自己试。

Qwen3-0.6B 全参(本路径主线)

G                    8
每步 prompt 数         8
micro batch          2      (OOM 就降到 1 + 梯度累积)
学习率                1e-6
betas                0.9 / 0.98
β (KL)               0      (但留参考模型做监控)
clip                 0.2 / 0.28
temperature          1.0
top_p                1.0
max_completion_len   512
归一化                序列平权
梯度检查点             开
参考模型               留
vLLM util            0.30 起,跑通后往上调到 0.5
sleep mode           开
────────────────────────────────
预期显存              约 21 GiB / 32 GiB
预期单步              约 45 秒

Qwen3-1.7B LoRA

LoRA rank            16      (target: attn + mlp)
G                    8
每步 prompt 数         8
micro batch          1  + 梯度累积 4
学习率                2e-5    ← LoRA 要比全参高一个数量级
betas                0.9 / 0.98
β (KL)               0       (参考模型 = 禁用适配器,免费)
temperature          1.0
max_completion_len   512
vLLM util            0.35
────────────────────────────────
预期显存              约 24 GiB / 32 GiB
▣LoRA 的两个「不一样」
  1. 学习率要高一到两个数量级(2e-5 而不是 1e-6)。因为可训练参数只有 0.4%,同样的学习率下参数的实际变化量小得多。

  2. 参考模型是免费的:

with model.disable_adapter():
    logp_ref, _ = sequence_logprobs(model, input_ids, attn_mask, comp_mask)

禁用适配器就是基座模型。所以 LoRA 用户没有理由不开 KL 监控。

Qwen3-8B QLoRA(32GB 的上限)

量化                  4bit (nf4)
LoRA rank            16
G                    4       ← 显存所迫,已到下界
每步 prompt 数         4
micro batch          1  + 梯度累积 8
学习率                2e-5
max_completion_len   512     ← 不能再长
vLLM util            0.30
sleep mode           开(必须)
────────────────────────────────
预期显存              约 29 GiB / 32 GiB   ⚠️ 很紧
预期单步              约 3 分钟
!8B 在 32GB 上是「能跑」不是「好跑」

G 已经压到下界 4,回答长度不能超过 512,单步三分钟——200 步要跑十小时。

除非你有明确理由必须用 8B,否则留在 0.6B 或 1.7B。 小模型快速迭代学到的东西,远多于在 8B 上跑一次十小时的实验。

调参的实验序列

有限卡时下,按这个顺序花:

第 1 步  基准配置跑通,拿到对照组          (必须)
第 2 步  检查 reward:分项记录、找作弊路径   (最高性价比,不花卡时)
第 3 步  看 clip_frac 决定学习率要不要动    (看仪表盘,多半不用动)
第 4 步  上动态采样过滤退化组              (L2 实测 +5.3,最大单项收益)
第 5 步  数据难度:adv_std 低了就换难题     (比调参有效)
第 6 步  才轮到 G / temperature 微调       (通常在噪声内)
✓第 2 和第 4 步是性价比最高的两步

第 2 步不花卡时,纯思考;第 4 步是 L2 三轮实验里唯一确定有效的改动(+5.3,远超 4 个百分点的分辨率下限)。

而第 6 步——大多数人最先做的那一步——在 L2 实测里全部落在噪声内。

顺序错了,卡时就浪费在最没用的地方。

Checkpoint单选

为什么 RL 后训练的学习率比 SFT 低一到两个数量级?

Checkpoint单选

`adam_beta2` 为什么推荐 0.98 而不是 PyTorch 默认的 0.999?

Checkpoint单选

有限卡时下,下面哪个动作的性价比最高?

Checkpoint单选

LoRA 训练相比全参,有哪两处配置明显不同?

这节课的落点

  • 影响力排序:reward 设计 ≫ 学习率/KL > G/batch/temperature ≫ clip/betas/warmup
  • reward 是唯一「调错了别的都救不了」的东西,且改它常表现为「监控变可信」而非分数上涨
  • 学习率起始 1e-6(比 SFT 低一到两个数量级),用 clip_frac 当仪表盘
  • β 默认 0,但一定要留参考模型做 KL 监控;β=0.01 实测掉 11.8 个点
  • G 的收益递减点在 8;加大 batch 优先加 prompt 数而非 G
  • micro_batch 不是超参(配梯度累积数学等价),只管显存和速度
  • temperature 1.0 起步,是探索与稳定的直接旋钮
  • adam_beta2 用 0.98(唯一的反默认推荐),warmup 不需要
  • 三组起始配置:0.6B 全参 / 1.7B LoRA(lr 2e-5 + 免费参考模型)/ 8B QLoRA(能跑不好跑)
  • 实验序列:跑通 → 查 reward → 看 clip_frac → 上动态采样 → 换难题 → 才微调 G

延伸资料