☰
NLA 的 GRPO 强化学习奖励 mse_nrm 与在线 Critic:如何用 Ray Remote 实现活权重实时打分
2026/10/23 1:53:01 网站建设 项目流程

【免费下载链接】natural_language_autoencoders

项目地址:https://gitcode.com/gh_mirrors/na/natural_language_autoencoders
点击查看免费下载

本文基于开源项目 natural_language_autoencoders(NLA),完整讲解 NLA 训练中GRPO 强化学习的奖励函数 mse_nrm、在线 Critic(在线值网络)的设计,以及它如何通过Ray Remote 调用正在训练的 Critic 活权重完成实时打分,帮助新手理解这套"边训练、边打分"的 RL 架构。

📌 名词提示:在 NLA 里,AV(activation verbalizer,激活口头化器)负责把向量"说"成文字,对应 RL 中的actor(策略);AR(activation reconstructor,激活重构器)负责从文字"还原"向量,对应 RL 中的critic(价值网络),同时它还是奖励模型本身。

一、mse_nrm 奖励函数是什么:0 分最好,-2 分最差

NLA 的 RL 目标很简单:让 AV 写出的解释,能被 AR 还原回原始激活向量的方向。因此奖励不用人工标注,而是直接算重构误差:

概念说明
计算公式reward = -MSE(pred, gold),两侧向量先做 L2 归一化
取值范围完美重构时 MSE=0 → 奖励0.0(最好);两向量正交时 MSE=2 → 奖励-2.0(最差)
归一化含义归一化后MSE = 2(1 − cosθ),只衡量方向一致性,不纠结向量模长
提取失败兜底生成被截断、取不到<explanation>内容时,直接给FAILED_EXTRACTION_REWARD = -2.0,保证"没写出来的样本"永远不会比写出来的占便宜

奖励函数的实现就在 nla/reward.py,核心只有两步:把 AV 生成的解释套进 Critic 的 prompt 模板 → 前向求出预测向量 → 用normalize_activation归一化后算 MSE(见_mse_to_reward,第 110 行起)。

💡 小贴士:设置环境变量NLA_LOG_MSE_REWARD=1可切换为-log(MSE)变体。由于 GRPO 会做组内归一化,两种形式在实践中几乎等价,官方默认用更直观的mse_nrm。

二、为什么 Critic 必须"在线":冻结的 AR 会被 AV 学会钻空子

普通 GRPO 训练里,奖励模型往往是冻结的。但 NLA 的奖励模型就是 AR 本身——它和 AV 是互相定义的:AV 说"这段话是什么意思",AR 说"这句话能还原成哪个方向"。如果冻结 AR,会出现两个问题:

  1. 奖励过时(staleness):AV 在进步,冻结的 AR 对"新解释风格"的打分能力却在原地踏步;
  2. 可被钻空子(reward hacking):AV 会找到冻结 AR 的盲区,用"AR 觉得对但其实错"的解释刷高分。

NLA 的解法是双轨同时训练:actor 组(AV,GRPO)和 critic 组(AR,监督 MSE)各占一块独立 GPU 池,共用同一份 rollout 数据——AV 生成 1024 条解释后,actor 组拿它算策略梯度,critic 组拿它继续拟合真实激活向量。两者每步都更新,奖励标准永远跟着 AV 的分布走。

这套调度由 configs/rl.sh 一键拉起(--advantage-estimator grpo+--force-use-critic),详细的双 RayTrainGroup 流程见 docs/design.md 的 §4.3。

三、Ray Remote 实时打分:用活权重,不复制模型、不重载 checkpoint

既然 Critic 是"活的",那 rollout 阶段(SGLang 在生成 150 token 解释)打分的权重从哪来?答案是:直接用正在训练的那份 Critic。

整个链路分三步:

  1. 偷闲:rollout 生成发生在 SGLang 的 GPU 上,此时 Critic 的 GPU 完全空闲;
  2. 递手柄:训练入口把 Critic 训练组的 Ray actor 句柄存进args._nla_critic_handles(这一步是上游补丁加的,见 nla/miles_patches/0002_train_py_nla_hooks.patch 中set_critic_handles部分);
  3. 远程前向:每条生成完成时,nla_rm调用handle.critic_fwd.remote(ids, mask),在空闲的 Critic 卡上做一次推理前向,拿回[B, d]的预测向量再算奖励(调用点见 nla/reward.py 第 140 行)。

critic_fwd是推理专用的前向函数(nla/train_actor.py 第 681 行),几个关键设计:

  • ✅无快照、无 checkpoint 重载——每次打分用的都是当前最新权重,天然零延迟;
  • ⚠️FSDP 集体通信约束——Critic 按 FSDP 分片存放,前向需要所有 rank 参与 all-gather,所以 Ray 调用会广播到每个 rank、取 rank 0 的相同结果;
  • 🔎右边界定位——prompt 模板以固定后缀</text> <summary>结尾,打分取"最后一个真实 token"的输出(用 attention_mask 的cumsum.argmax定位,兼容左右 padding),与训练时的提取位置完全一致。

官方明确表态:在线 Critic 是唯一支持的 RL 模式——"frozen-critic was never implemented"(见 docs/design.md §7 第 8 条)。

四、异步批处理:--nla-reward-batch-size 把奖励计算提速 6 倍

如果每 8 条样本(一个 GRPO 组)就单独打一次分,会撞上性能墙:FSDP 前向是串行集体通信,实测 27B 模型上64 组 × 每次约 2s ≈ 128s,反而比 SGLang 生成本身更慢,成了真正的瓶颈。

nla/reward.py 里的异步累积器解决了这个问题:

机制说明
攒批样本先入队,攒满--nla-reward-batch-size才发起一次批量critic_fwd
尾部超时迟迟攒不满时,等NLA_REWARD_FLUSH_SECS(默认 5s,组间错峰到达约 60s)后强制刷出
不堵事件循环阻塞的ray.get被包进asyncio.to_thread,等待期间后续组仍能继续回调
效果512 条样本从 64 次串行前向压缩为 1~4 次批量前向,总奖励耗时从 ~128s 降到 ~10-20s

配合--group-rm(按组路由奖励),生成流水线与奖励计算完全重叠——"生成还在跑,前面的组已经在打分了"。

五、一键配置与超参速查

生产级配置全部内置在 configs/rl.sh(以发布的 Qwen2.5-7B 为基准),常用关键项:

  • --custom-rm-path nla.reward.nla_rm:挂接自定义奖励函数
  • --force-use-critic:在 GRPO 下解锁 critic 训练组(GRPO 默认会强制关闭)
  • --rollout-batch-size 128 --n-samples-per-prompt 8:128 prompts × 8 采样 =1024 样本全局批
  • --use-kl-loss --kl-loss-coef 0.01:防止 AV 偏离 SFT 起点太远
  • --rollout-max-response-len 150:响应上限,截断样本按 -2.0 惩罚

超参细节与踩坑记录(如 actor/critic 学习率按 √(batch) 缩放、保持 on-policy 训练)都写在 configs/TRAINING_NOTES.md,其中"Production run"一节记录了发布 checkpoint 的完整参数表。

六、新手常见疑问 FAQ

Q1:为什么 GRPO 要配--force-use-critic?Miles 上游中use_critic只在 PPO 下为真,GRPO 默认关闭 critic。而 NLA 的 critic 不输出 GAE 价值、只做 MSE 训练,需要这个补丁开关(上游改动见 nla/miles_patches/0001_miles_nla_integration.patch)。

Q2:奖励用的归一化尺度听谁的?听Critic 自己的mse_scale(来自它的 sidecar 配置),而不是数据集的——奖励计算和 Critic 训练损失必须用同一个归一化函数,否则奖励信号会漂移。

Q3:可以换成异步 rollout 边生成边训练吗?不建议。仓库明确保持 on-policy:train.py每步"生成 → 训练 → 同步权重到 SGLang",一次 rollout 恰好消费一个优化步。异步模式下 rollout N+1 用的是略旧的权重,实测可能伤害训练。

Q4:怎么验证奖励链路是对的?启动时会自动做一次"活体校验":同一批数据分别走奖励路径(paddedcritic_fwd)和训练路径(thd-packed 前向),两者 MSE 必须一致才放行(见 nla/train_actor.py 第 89 行起的_assert_reward_train_paths_agree)。


小结:NLA 的 RL 精髓在于"奖励模型即被训模型"——mse_nrm把不可解释的向量重构误差变成了 GRPO 可用的标量奖励,Ray Remote 让这份奖励永远来自 Critic 的活权重,异步累积器再把 FSDP 集体通信的开销抹平。三者合起来,才支撑起了 7B 到 70B 规模的 AV+AR 同步强化学习。想深入数据流设计,建议继续阅读 docs/design.md 与 nla/reward.py 的源码注释。

【免费下载链接】natural_language_autoencoders

项目地址:https://gitcode.com/gh_mirrors/na/natural_language_autoencoders
点击查看免费下载

相关推荐

上一篇:nanomsg内存池实现:提升消息分配效率的核心机制
下一篇:MXNet Gluon 的 Layers 与 Blocks:从 Sequential 到自定义 Block 的模型构建实战指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询