0x00 概要

SERL 的核心使命是:在真实世界中,让机器人在 20-40 分钟内学会高精度的机械操作。它通过集成 SAC、RLPD、DrQ 和 VICE,将原本需要数百万次尝试的 RL,压缩到了人类演示水平的量级。

RLPD(Reinforcement Learning with Prior Data)是一种基于 off-policy 的 actor-critic强化学习算法,借鉴了 soft-actor-critic 等时序差分算法的成功经验,但为满足上述需求做出了一些关键修改,它其实就是 SAC + 之前的数据(Prior Data)+ 极高的更新频率(High UTD)。

注:

  • 本系列的最终目标是“通过一系列相关项目/算法的解读,来深入学习/分析/反推 LWD(Learning while Deploying)这篇论文的机理和可能实现”。之所以从SERL入手,是因为 SERL,HIL-SERL,SOP(没有开源)都是罗剑岚博士的一系列论文,可以从中管窥作者的思路脉络。
  • 本文依然是从工程/论文进行反推,还请读者不吝指出问题,多谢。

0x01 基础 & 背景

1.1 总体流程图

SERL 的总体流程图如下,其中:

  • SAC(Soft Actor-Critic)是算法底座 ,是整个系统的"引擎"。
  • RLPD (RL with Prior Data) 是性能加速器,是 SERL 实现"20 分钟学会"的关键,它通过"暴力更新"和"不忘初心"来榨取每一条数据的价值。
  • High UTD:迫使模型对有限的样本进行 "深度研读",从而在极短的物理时间内捕捉到成功的信号。

SERL-总体-流程

1.2 面临的问题

在许多场景中,强化学习的优异表现依赖于与环境进行大量的在线交互,这通常通过使用模拟器来实现。然而,在实际问题中,常常面临样本获取成本高昂的情况。此外,奖励信号稀疏,且高维的状态和动作空间往往使这一问题更加严重。

一些先前的研究致力于通过预训练利用这些数据,而其他方法则在在线训练时引入约束,以应对分布转移问题。然而,每种方法都有其缺点,例如需要额外的训练时间和超参数,或者在行为策略之外的提升有限。

0x02 RLPD 基础

RLPD关注的是,是否可以在 在线学习时,直接应用现有的离策略方法以充分利用离线数据。在每一步训练中,RLPD 在先验(离线)数据和on-policy数据之间等概率采样,以形成一个训练批次,即“对称采样”,即每个批次有50%的数据来自(在线)回放缓冲区,另外50%来自离线数据缓冲区(先验数据)。

我们对比如下:

  • 原生:纯靠自己试

  • SERL:在 SAC 的 Batch 里塞进人类演示数据,相当于给 SAC 考试时递了一张带有参考答案的纸,让它不用从头瞎猜

那"RLPD"这四个字母贵在哪里?秘密不在"怎么算"(Loss Function),而在"喂什么"(Batch Composition)。RLPD 50/50 抽样 强行保证每个 Batch 都有 128 条 Demo。这相当于给机器人装了一个"强制记忆模块",让它每一秒钟都在看正确答案。

2.1 RLPD 的三大支柱

  1. High UTD(Update-to-Data):
  • SERL 每跑一步环境,就进行 20 次网络更新。这种"暴力刷题"让每一条物理数据都被反复压榨,是 20 分钟收敛的硬件级保证。
  1. Layer Normalization(LN):
  • 问题:在普通的 SAC 中, 网络通常就是纯 MLP。但在 RLPD 中, 由于我们要做 High UTD (高频更新), Q 值的估算非常容易发散。
  • 解决方案:因此,RLPD 会在 Critic 网络 (甚至 Actor 网络) 的每一个隐藏层之后, 都加上 LayerNorm。
  • 直观理解:高 UTD 会产生巨大的梯度冲击。LN 就给高速赛车装上强力悬挂,确保每一层神经元的输出在 20 倍更新频率下依然稳定,不至于"飞出去"。
  1. 50/50 混合采样:
  • 做法:在 update 过程中, 我们不再只从 replay_buffer 抽数据, 而是将演示数据(Demo)与在线数据(Online)强行等比例混合,确保智能体在探索新坑时,始终能看到正确路标。
    • 抽 128 个在线数据 (自己跑出来的)。
    • 抽 128 个先验数据 (人类演示的 Demo)。
    • 把它们拼成一个 256 的 Batch 进行训练。
  • 为什么有效?:演示数据告诉智能体"正确的路长啥样", 在线数据告诉智能体"这里的坑别踩"。两者结合, 收敛速度能提升数倍。

2.2 Prior Data 策略

Prior Data 策略决定了演示数据与在线数据的黄金采样配比。

真机强化学习最怕"冷启动"— 机器人像没头苍蝇一样乱撞。SERL 引入了 RLPD(Reinforcement Learning with Prior Data)机制:

数据混洗:在训练的每一个 Batch 中,系统会强制性地混合:

  1. 50% 的演示数据:这是由人类老师录制好的"标准答案"
  2. 50% 的在线数据:这是机器人自己折腾出来的"实战记录"

算法价值:这种混合采样确保了模型在进化的每一秒,都在不断对比"正确答案"与"自己的尝试"。它解决了强化学习初期的探索困境,让机器人即使在完全没拿高分的情况下,也能通过模仿专家数据来迅速建立起任务的初步认知。

我们可以这样理解:

  • prior data 像"老师给的标准答案"
  • online replay 像"学生自己的练习记录"
  • 每次训练都同时看标准答案和自己的错题,策略就不会偏离任务太远

这也是 SERL 样本效率高的关键之一。它不是让机器人从零开始乱试,而是在 demonstrations 的引导下进行强化学习微调。论文中明确写到,每次更新使用 sample-based approximation,其中 half of the samples drawn from prior data,half drawn from replay buffer。

2.3 算法流程图

下面是根据 rlpd.py 的代码逻辑整理的 RLPD 训练流程逻辑图。这个图展示了从数据采样到网络更新的完整路径, 特别标注了 RLPD 相对于普通 SAC 的核心改进点 (如 BC Loss 和 Pessimistic Backup)。

SERL-RLPD-流程

2.4 代码细节

RLPD 关键组件说明

  • Ensemble Q (10 Qs): 使用 10 个 Q 网络而非 2 个, 增加评估的多样性。
  • rho (Pessimism): 通过 "均值 - rho * 标准差" 来实现对不确定区域的惩罚。
  • BC Loss: 在 Actor 更新中加入行为克隆, 强迫智能体初始阶段不要偏离演示数据。
  • High UTD (Scan): JAX 的 lax.scan 允许在一个硬件循环内执行 20 次上述流程。
  • LayerNorm (代码内部) 在所有隐藏层后强制执行归一化, 支撑高频更新。

结合 rlpd.py 代码的深度解读:

  1. 关于 rho 的计算:

    next_qs = self.network.select('target_critic')(batch['next_observations'][..., -1, :], next_actions)
    next_q = next_qs.mean(axis=0) - next_qs.std(axis=0) * self.config["rho"]
    

    这是 RLPD 的精髓。普通的 SAC 是 min(Q1, Q2), 而这里是用标准差来量化"不确定性"。如果 10 个 Q 网络对某个状态动作意见不统一 (std 大), next_q 就会被压得很低。

  2. 关于 BC Loss:

    bc_loss = -(dist.log_prob(jnp.clip(batch_actions, -1 + 1e-5, 1 - 1e-5)) * batch["valid"][..., -1]).mean() * self.config["bc_alpha"]
    

    这行代码在告诉 Actor: "不管 Q 值怎么说, 你输出的动作最好和 Buffer 里的真实动作 (演示数据) 接近一些"。这对机器人任务极其关键, 因为它防止了机器人在训练初期因为乱甩而撞坏硬件。

  3. 关于 High UTD:

    @jax.jit
    def batch_update(self, batch):
        agent, infos = jax.lax.scan(self._update, self, batch)
    

    这里使用了 JAX 的 scan 原语。这比 Python 的 for 循环快得多, 它能把 20 次更新编译成一个高效的 GPU 算子。

  4. 演示数据(Prior Data):
    SERL 所基于的 RLPD 算法中,作者发现最简单、最有效的办法就是一视同仁,比如:

    • 从 Replay Buffer(自己跑的数据)取 128 个。
    • 从 Demo Buffer(演示数据)取 128 个。
    • 凑成一个 256 的 Batch,直接丢进 Loss 函数。
    • 意义:不需要复杂的权重计算,这种简单的"对半开"采样就能极大地提升效率。
  5. "看未来"与"看现在"的逻辑

    • rlpd.py 中计算 next_q 用的是 target_critic, 而计算 actor_loss 时用的是 critic (当前网络)。

    • Target Critic (看未来): 用于计算 r + γ Q_{target}。由于 Q_{target} 更新得很慢 (Soft Update), 它提供了一个稳定的地基, 防止 Q 值计算产生正反馈螺旋 (即自己把自己估高)。

    • Critic (看现在): 用于 Actor 的更新。Actor 问: "我现在的动作好吗? "。由于 Critic 正在被最快地训练, 它能给 Actor 提供最及时的反馈。

    • 矛盾解决: 这就是"评估要稳 (Target), 改进要快 (Current)"的权衡。

0x03 BC

在 SERL 的复现中, 通常的步骤是:

  1. 收集 20 个 Demo。
  2. 跑 bc.py 进行预训练, 让机器人学会"手往哪放"。
  3. 跑 rlpd.py 进行正式训练, 利用 BC 训练好的模型作为起点, 通过 50/50 采样快速进化。

在 SERL 的完整流程中,bc.py 的代码非常关键, 它揭示了 SERL 系统中 Behavioral Cloning (BC) 环节是如何运作的。

3.1 BCAgent

BCAgent 负责预训练冷启动,是纯监督学习的行为克隆实现,架构最为简洁。SERL先用 BC 模仿 Demo,让机器人学会"手往哪放",再开启 RL 寻找"怎么抓取"。

3.1.1 BCAgent 在SERL中的作用
  1. 冷启动:为RL算法提供初始策略
  2. 演示数据利用:从专家演示中学习
  3. 安全基线:在RL训练初期提供安全策略

核心优势:BCAgent 的简洁性使其成为从演示到强化学习的理想桥梁,通过监督学习快速获得可用的策略,然后可以在此基础上进行RL微调。

BCAgent 的特性如下:

特性BCAgent说明
网络数量仅1个Policy网络无Critic,无Temperature
tanh_squashFalse不使用tanh压缩
输出分布MultivariateNormalDiag标准高斯分布
训练目标最小化MSE + 负对数似然监督学习
3.1.2 BCAgent 核心组件

唯一的 Policy 网络

network_kwargs["activate_final"] = True
networks = {
    "actor": Policy(
        encoder_def,              # 视觉编码器
        MLP(**network_kwargs),    # 默认 [256, 256]
        action_dim=actions.shape[-1],
        tanh_squash_distribution=False,  # 关键差异
    )
}
组件输入网络结构输出特点
Policy图像观测编码器+MLP[256,256]动作分布(μ,σ)纯监督学习
3.1.3 BCAgent 编码器架构

"small" 编码器

encoders = {
    image_key: SmallEncoder(
        features=(32, 64, 128, 256),
        kernel_sizes=(3, 3, 3, 3),
        strides=(2, 2, 2, 2),
        padding="VALID",
        pool_method="avg",
        bottleneck_dim=256,
        spatial_block_size=8,
    )
}
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐