ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从HER到RLEF:稀疏奖励下的hindsight学习策略解析

从HER到RLEF:稀疏奖励下的hindsight学习策略解析 1. 从事后诸葛亮到训练信号hindsight 为什么值得单独讨论hindsight这个词日常语境里常带点贬义——事后诸葛亮嘛。事情已经发生了你再跳出来说我早就知道会这样除了招人烦没什么用。但放在AI技术圈这两年它却是正儿八经的热词OpenAI那边有 HERHindsight Experience ReplayMeta 这边把 hindsight 嫁接到大模型对齐流程里搞出了新训练范式核心都是同一件事——把事后才知道的结果重写成训练用的有效信号。我第一次接触这个概念时还挺震撼的。当时我在调一个机械臂抓取任务奖励函数稀疏到让人崩溃只有末端执行器完全对准目标物体才给 1其余全部是 0agent随机探索几百万步也拿不到任何有效的梯度信号。传统强化学习拿这种环境一点办法没有直到我看到 HER 的想法既然这次没抓到红色的杯子但实际碰到了旁边的蓝色盘子那为什么不把这条轨迹重新标记成目标是蓝色盘子的成功案例让模型先学会抓到盘子这个子技能这个思路听着甚至有点偷懒但它精准解决了强化学习最痛的痛点之一奖励稀疏。稀疏奖励不是单纯的技术难度问题本质是信号缺失问题。你没法给 agent 每一步都设计出有效反馈但实际发生了什么本身就是天然的反馈来源。hindsight 的核心就是把这份天然信号重新利用起来。这篇文章我会拆成四块聊先仔细拆解 HER 的核心机制和采样策略然后给一个能直接跑通的最小复现流程再聊它怎么从连续控制领域一路延伸到今天的 LLM 训练最后是我踩过的坑和一些参数调优上的实际体会。适合刚接触强化学习、正在被稀疏奖励折磨的同学也适合想理解反馈信号设计这件事的大模型训练玩家。2. HER 的原理拆解为什么把失败改写成成功反而能学到东西2.1 强化学习里的稀疏奖励困局先定义一个基本场景。机器人想抓取红色杯子环境给的奖励只在杯子被抓起来且刚好放进目标框这一瞬间出现。agent 的策略网络是随机初始化的它连手臂关节怎么组合才能碰到桌子都不知道更别提精确抓取了。结果就是整个回合结束reward 几乎永远是 0。这里的问题比表面上看到的更严重。没有非零 rewardadvantage 函数全是零策略梯度就没有方向agent 的所有探索都沦为随机瞎撞。你可能觉得多跑几个回合总有碰运气成功的时候但对高维动作空间来说纯随机碰运气的概率低到可以忽略训练时间会以指数级膨胀。有人会想到用 shaping奖励塑形来解决离目标近一点就多给一点分让奖励变得稠密。但塑形函数非常难设计设计错了还会诱导 agent 钻空子。比如你给接近目标加分agent 可能学会把手伸到目标附近但从来不抓因为保持这个状态得分最高。这种 reward hacking 在实际项目里太常见了我见过不止一个团队在这个坑里反复打转。HER 走的完全是另一条路不修改奖励函数修改目标的定义。2.2 HER 的核心机制轨迹重标假设一个 episode 记录包含状态序列 s_0, s_1, ..., s_T原始目标是 g。在普通 off-policy 算法里比如 DDPG 或者 TD3经验通常以 (s, a, r, s, done) 的形式一条条存进 replay buffer。HER 的流程则完全不同先把整条 trajectory 攒齐存起来从这条轨迹里挑出一个实际达到的状态 s_achieved比如轨迹末尾机械臂碰到的东西、机器人最终到达的位置把原始目标 g 替换成 s_achieved得到新目标 g用环境自带的 reward 函数重新计算轨迹里每条 (s, a, g) 的奖励。因为 g 是实际发生的状态所以轨迹末段一定满足目标达成条件reward 不再全是 0把重写后的轨迹当成正常经验塞进 replay buffer。这样做的直接效果是agent 的经验池里出现了大量有正信号的轨迹。更妙的是这不仅仅是增加信号数量——它还让 agent 学会了一个很有用的泛化能力不管手上最后拿到的是什么都能形成一个对应的目标。用一句大白话总结HER 不改变物理过程只改变事后对过程的解读。物理上 agent 确实没抓到红色杯子但在它的记忆里这是一次成功的抓蓝色盘子的示范。所以当它下一次面对抓蓝色盘子这个真实目标时它早就见过类似的成功案例了。2.3 future 采样策略四种重标方式的取舍HER 原论文提出了四种选取重标目标的策略这个细节直接决定了效果非常关键策略做法优缺点final只用轨迹最后一个状态作为新目标实现最简单但对长轨迹来说每个状态离新目标都太远信号弱episode从同一个 episode 里随机抽一个状态作为目标比 final 多样但可能抽到时间上很近的状态学习价值低random从所有历史经验里随机抽一个状态探索充分但和当前轨迹可能毫无关系训练不稳future从当前轨迹的当前时刻之后随机抽取状态作为新目标时间上自洽因果关联强效果最好实际工程中 future 策略基本是默认选择。原因在于它保证重标目标和轨迹之间存在时间上的因果逻辑——后来确实达到了这个位置这个目标不是凭空捏造的。原论文里用的 K4也就是每条轨迹额外重标约 4 个 future 目标经验池的有效容量直接变成原来的 5 倍。这个参数后面我会单独讲因为它既能提升效果也会显著拉长训练时间。2.4 为什么 off-policy 是硬性前提注意 HER 只适用于 off-policy 算法这一点很多人容易忽略。原因并不复杂重标后的轨迹并不是 agent 实际执行的策略产生的它的 (状态, 动作, 新目标) 联合分布和在线策略分布已经不一致了。Q-learning、DDPG、TD3、SAC 这类算法从 replay buffer 里随机采样理论上能容忍这种分布偏差但是 A2C、PPO 这类 on-policy 算法要求经验必须来自当前策略的 rollout一旦改写了目标重要性权重就没办法正确计算。这个坑我当初真实踩过在一个 PPO 实现里硬套 HER 思路结果训练曲线比不改还难看完全学不进去。后来切到 TD3 才恢复正常。所以如果你手里的算法是 on-policy 一系的先不要想着怎么魔改 HER换算法更现实。3. 动手复现一个最小 HER从环境准备到训练曲线3.1 环境选择与准备工作入门推荐 OpenAI Gym 的 FetchReach-v1或者更新一点的 gymnasium 兼容版本。这是一个经典的稀疏奖励环境机械臂需要把末端移动到指定目标位置只有距离小于某个阈值才给正奖励。虽然比真实抓取任务简单但它完整保留了 HER 发挥作用所需的全部要素连续动作空间、稀疏奖励、可重标目标目标就是一个三维坐标。想更深理解原理的话也可以自己写一个 2D 点导航环境一个点在平面上移动目标是某个坐标只有进入目标半径内才有正奖励。自己写的好处是你能直观地看到 replay buffer 里的重标过程打印出来仔细检查对理解原理帮助非常大。在开始之前你需要先确认自己装了 OpenAI Gym或 gymnasium、numpy 和一个能跑 GPU 的深度学习框架。其实就这个任务而言CPU 也能跑只是慢一些。FetchReach 本身状态维度不高两层 MLP 的网络在 CPU 上也能凑合出结果但至少要准备 30 分钟以上的耐心。3.2 HER 训练循环的骨架代码下面是我复现 HER 时用的一个简化版训练循环核心逻辑保留工程细节适当简化import numpy as np from collections import deque class HERBuffer: def __init__(self, capacity100000, k4): self.buffer deque(maxlencapacity) self.k k # 每条轨迹额外重标几个目标 def store_episode(self, episode, reward_func): episode: list of (obs, achieved_goal, action, done) reward_func: 输入 (obs, achieved_goal, goal) 返回奖励 # 1. 原始轨迹原样入库带原始目标 original_goal episode[0][1] # 用第一个obs里的目标字段 for (obs, ag, act, done) in episode: r reward_func(obs, ag, original_goal) self.buffer.append((obs, ag, act, r, done, original_goal)) # 2. future 策略重标 T len(episode) for _ in range(self.k): t np.random.randint(0, T) future_t np.random.randint(t, T) new_goal episode[future_t][1] # future时刻的achieved_goal for i in range(t, T): obs, ag, act, done episode[i] new_r reward_func(obs, ag, new_goal) self.buffer.append((obs, ag, act, new_r, done, new_goal)) def sample(self, batch_size): # 随机采样一个batch返回格式供Q网络训练 indices np.random.choice(len(self.buffer), batch_size, replaceFalse) batch [self.buffer[i] for i in indices] # 拆成各字段返回... return batch实际训练循环里你只需要在每次 episode 结束后调用store_episode存轨迹然后按 TD3 或 DDPG 的标准更新流程从 buffer 采样训练。核心改动只有两处一是经验格式里多带一个 goal 字段二是改成 episode 级别的存储而不是 step 级别的存储。原因前面提过要重标必须先攒完整条轨迹再动手。3.3 目标编码与归一化容易被忽略的细节一个小但关键的细节目标 g 和观测状态 s 通常在特征空间里是不同的量纲。以 FetchReach 为例机械臂关节角度可能是个位数的弧度目标坐标则是 0 到 1 米之间的数值。如果你直接把两者 concat 送进网络量纲差异会干扰训练梯度更新会被大数值的特征主导。我一般会做两件事第一把目标单独归一化到 [0,1] 区间第二对状态和目标分别做标准化。网络结构上最常见的做法是把 g concat 到 s 后面一起输入也可以单独用一个 goal encoder 提取特征再加权融合。前者简单直接适合入门后者在目标空间比较复杂、维度较高时效果更稳定。入门阶段用前者完全够了。还有一点HER 的 Q 网络输入是 (s, a, g)所以输入维度会发生变化。如果你之前跑过普通的 TD3记得把网络第一层的输入维度同步调大否则报错倒是其次网络容量不够才是真正麻烦的事。3.4 训练效果怎么评估跑通之后你会观察到一个很有意思的现象原始目标不重标的 reward 涨得很慢但在每个 episode 结束时agent 对当前实际达到位置这个目标的 Q 值会涨得非常快——因为重标轨迹里这部分信号最多Q 函数学得最扎实。随着训练继续推进Q 函数对目标空间逐渐产生泛化原始目标的回报才开始跟上。我建议看训练曲线时除了记录原始目标的回报还要单独记录一个成功率指标比如机械臂末端离目标小于 5cm 的比例。HER 最擅长的不是把一个已经能跑通的任务优化到极致而是实现从完全学不动到能完成的质的突破。如果你看到成功率从 0 慢慢爬升到 70% 以上之后提升明显变缓这是非常典型的学习曲线说明 HER 已经把它该给的信号给足了剩下的要靠其他手段比如提高阈值或者换更复杂的算法来继续拔高。4. 从机械臂到大模型Hindsight 在 LLM 训练中的进化4.1 语言模型的稀疏奖励问题HER 这套思想并没有停留在机器人领域。今天大模型训练里几乎存在同样的问题一个 70B 参数规模的模型你让它回答一道数学题整道题只有最终结果正确才给 1错一点就给 0。中间漫长的推理步骤完全没有逐步奖励信号。如果用 RLHF 的做法你需要人类标注员给大量偏好数据或者是专门训练一个 reward model成本高、不稳定而且 reward model 本身也可能出错、会被 hacking。顺着 HER 的思路一想答案就浮出来了模型答错了但错误答案里往往有大量部分正确的推理过程。能不能把错误答案本身作为新的训练信号这就是 hindsight 思想在语言模型领域的自然延伸。4.2 事后反馈重写RLEF 的基本流程近几年比较有代表性的方向可以概括为 RLEF——从错误反馈中强化学习Reinforcement Learning from Error Feedback。它和 HER 的对应关系非常清晰HER 原始思想语言模型中的对应物理世界实际达到的状态模型实际输出的错误答案把状态重标为目标把错误答案重标为反例轨迹变成成功数据反馈器生成错误原因修正方向策略学到子技能策略学会规避同样错误具体流程通常长这样采样让待训练模型对一批 prompt 生成答案判错用规则比如代码能不能跑通、答案字符串是否完全匹配或另一个评判模型检测答案是否错误反馈对错误答案让一个反馈生成器可以是同一个模型也可以是更强的模型写出哪里错了、为什么错、应该注意什么的自然语言描述重标把反馈文本拼接到原始 prompt 后面组成新的训练输入比如请重新回答下面的问题... 注意你之前的错误在于忽略了括号内的运算优先级训练用这些带反馈的样本做监督微调或偏好优化让模型下次遇到同类问题时能避开错误路径。你会发现这个流程里没有人类标注奖励也不需要单独训练 reward model唯一的外部信号就是模型自己产出的批判性文本。一句话总结让模型当自己的事后诸葛亮然后把这份反思写进训练数据。4.3 和 RLHF、DPO 的对比RLHF 的本质是让人类偏好提供梯度方向——A 答案比 B 答案好模型就往 A 靠。DPO 也类似只不过不单独训练 reward model直接用偏好对做分类损失。而 Hindsight 风格的训练信号来源是错误本身修正建议更像一门错题本学习法。这个思路的优势很明显反馈可以自动生成不需要大量人工标注成本结构完全不同。缺点也同样明显反馈质量决定了训练上限如果模型自己给出的反馈是你错了再想想这种空话那训练效果约等于零。所以实际操作中人们通常会用更强的模型充当反馈器或者严格限定反馈格式要求必须指出具体的错误步骤和修正方向。我在实际测试中还有一个体会RLEF 对推理类任务数学、代码、逻辑推演的效果远好于开放式创作任务。原因很好理解——数学和代码有明确的对错标准错误可以被精准定位反馈文本的信息密度高而开放式创作几乎没有错误的定义模型给出来的反馈往往也是正确的废话。如果你的任务不属于前一类RLEF 可能不是最优选择别盲目套用。5. 复现和调参中踩过的坑HER 实战避坑笔记5.1 经验池容量爆炸与采样比例失衡我前面提过 K4 会让 buffer 里的数据总量变成原来的 5 倍。很多人没意识到的是这不只是增加存储压力更重要的是会影响采样分布。如果 buffer 的上限不够大原始经验可能被重标经验挤出去导致真实目标的比例过低agent 就会在一个全是虚拟目标构造的世界里自嗨出现一种诡异的幻觉成功对虚构目标的 Q 值已经很高但真正跑任务时成功率却很低。我的解决方法是把 buffer 容量按(K1) 倍来设计并且在采样时显式控制原始轨迹和重标轨迹的比例比如保持 1:1 到 2:1不要让重标轨迹完全主导。这个比例可以用一个简单参数动态调节根据成功率的波动去微调。5.2 不是所有环境都适合 HERHER 成立的前提是目标可以事后确定且reward 函数可以对新目标计算。像机械臂抓取、机器人导航这类连续目标空间完全没问题但像下棋赢棋这种目标只有胜负二元结果的任务就不行——你没法把一次失败的棋局重标成目标是输掉比赛因为这不是 agent 想要的技能。另一个容易被忽略的点是重标目标必须和原始观测空间保持一致。如果环境给的是像素观测目标也是像素图那 future 采样直接拿某一帧像素当目标会带来大量冗余信息和像素级噪声。处理像素环境时最好先做目标编码比如用 VAE 把像素压缩成低维隐向量再考虑 HER否则训练极不稳定。5.3 训练稳定性的三个具体建议奖励阈值不要太苛刻。FetchReach 里阈值设 0.05 和设 0.01难度完全不同。入门阶段先把阈值放宽一点让正信号先出现让训练跑起来之后再逐步收紧。很多新手一上来就设一个很苛刻的阈值正信号始终不出现模型永远学不到东西于是怀疑是自己实现有 bug其实只是阈值问题。网络结构别贪深。HER 的 Q 网络用两层 256 的 MLP 就足够深网络在稀疏信号下反而不容易收敛。我第一次复现时用了 4 层 512训练曲线震荡得我怀疑人生换成小网络一下子就稳了。稀疏信号环境不需要大模型去拟合复杂特征简单结构反而更抗噪。学习率不要太激进。TD3 默认的 1e-3 可以用但如果配合大 batch比如 512建议降到 5e-4 左右。稀疏环境下过大的学习率会把刚出现的一点正信号瞬间冲掉造成训练来回横跳。5.4 从 HER 到生产项目的一点延伸如果你最终要把 HER 用到真实机器人或更复杂的仿真环境别把它当成一个独立的算法框架更合适的定位是数据增强层。它和 DDPG、TD3、SAC 是完全正交的任何时候你的任务满足有可重标目标这个条件都可以往现有管线里插一层 hindsight。包括最近一些离线强化学习的工作也会用 hindsight 思想来扩充数据集让策略先从事后看到的成功经验里学到一些基础的、稳定的行为模式再逐步提升。我个人的看法是hindsight 真正教给我们的不是某个具体的数学公式或者网络结构而是一种思维方式——不要浪费任何一次失败。在奖励稀缺的现实任务里失败轨迹中往往藏着远超预期的信息量关键看你愿不愿意换个目标重新解读它。做 AI 项目这些年这条思路帮我解决的问题远不止抓取任务。凡是涉及反馈稀缺的场景我都会下意识地问自己一句能不能把这次失败重写成一次成功记录答案经常是肯定的。
返回列表