源文件:chapter7/SimpleVLA-RL/README.md 通过强化学习扩展视觉-语言-动作模型训练 项目地址: https://github.com/PRIME-RL/SimpleVLA-RL/ SimpleVLA-RL 概览。SimpleVLA-RL 是一个高效的 VLA 强化学习框架,能够在数据稀缺条件下改进长时序规划,在模拟和真实任务中的表现超越监督微调(SFT),揭示了"推切"新动作现象,并增强了空间、物体和目标的泛化能力。
源文件:chapter7/SimpleVLA-RL/README.md
项目地址: https://github.com/PRIME-RL/SimpleVLA-RL/
SimpleVLA-RL 概览。SimpleVLA-RL 是一个高效的 VLA 强化学习框架,能够在数据稀缺条件下改进长时序规划,在模拟和真实任务中的表现超越监督微调(SFT),揭示了"推切"新动作现象,并增强了空间、物体和目标的泛化能力。
视觉-语言-动作(Vision-Language-Action, VLA)模型已成为机器人操作领域的有力范式,能够统一视觉感知、语言理解和动作生成。然而,当前 VLA 模型的发展面临两大核心挑战:
传统 VLA 训练严重依赖大规模人工操作的机器人轨迹数据进行监督微调(SFT)。这些数据的收集存在以下问题:
基于有限、特定场景数据训练的 VLA 模型在面对以下情况时性能显著下降:
近期大型推理模型(如 DeepSeek-R1)的突破表明,强化学习(RL)即使仅依赖结果奖励,也能显著提升模型的逐步推理能力。这自然引出一个问题:
RL 能否同样增强 VLA 模型逐步生成精确动作的能力?
SimpleVLA-RL 是一个专为 VLA 模型设计的高效强化学习框架,具有以下创新特点:
基于最新 LLM RL 研究,引入三个关键技术增强:
三者结合可在 300 训练步内相比基线提升约 30%!
训练过程中出现"推切(Pushcut)"现象:
SimpleVLA-RL 构建于以下技术栈:
全成功或全失败的样本组优势方差为零,导致梯度不稳定,训练效率低下。
仅保留混合结果(部分成功/部分失败)的样本组进行训练:
# 数学表达式(论文公式 10) 0 < |{轨迹_i | 是否成功(轨迹_i)}| < G # 实现代码 data.accuracy_lower_bound=0.1 # 排除全失败组(0%) data.accuracy_upper_bound=0.9 # 排除全成功组(100%)
标准 PPO 的对称裁剪 [0.8, 1.2] 限制了低概率动作的概率增长,抑制探索。
采用不对称裁剪范围 [0.8, 1.28]:
actor_rollout_ref.actor.clip_ratio_low=0.2 # 下界 1-0.2 = 0.8 actor_rollout_ref.actor.clip_ratio_high=0.28 # 上界 1+0.28 = 1.28
低温度(1.0)会导致确定性、重复的轨迹生成,缺乏探索。
将推理阶段的采样温度从 1.0 提升至 1.6:
actor_rollout_ref.rollout.temperature=1.6
注意:仅在推理收集数据时使用,训练时不使用。
我们在 LIBERO 基准测试上使用 OpenVLA-OFT 进行评估。SimpleVLA-RL 将性能提升至 97.6 分(满分 100),创下新的最先进水平。
| 设置 | LIBERO-Long 成功率 | 提升幅度 |
|---|---|---|
| 基线 SFT | 60% | - |
| SFT + 300步RL | 90% | +30% |
| 最终性能 | 97.6% | +37.6% |
实验设置:每个任务仅使用 1 条轨迹进行 SFT 初始化
| 方法 | 成功率 | 提升 |
|---|---|---|
| 仅 SFT(1条轨迹) | 17.3% | - |
| SFT + SimpleVLA-RL | 91.7% | +74.4% (430.1%) |
这证明了 RL 在极端数据稀缺场景下的强大能力!
SimpleVLA-RL 在 RoboTwin 2.0 双臂操作基准测试上也取得优异成绩,在部分任务上超越了 π₀ 模型。
RoboTwin 2.0 是一个可扩展的双臂机器人操作基准测试平台,具有以下特点:
根据您要使用的基准测试,选择对应的安装选项:
注意: 建议使用 veRL 0.2 或 0.3 版本。最新版本可能存在库冲突。
参考官方 veRL 安装指南:
# 创建并激活 conda 环境 conda create -n simplevla python==3.10 conda activate simplevla # 安装 PyTorch pip3 install torch==2.4.0 --index-url https://download.pytorch.org/whl/cu124 # 克隆 veRL (建议放在与 simplevla-rl 同级目录,而非 simplevla-rl 文件夹内) git clone -b v0.2.x https://github.com/volcengine/verl.git cd verl pip3 install -e . cd ..
LIBERO 和 RoboTwin 2.0 基准测试都需要此步骤。
安装 EGL 库以在 Docker 容器或无显示器的远程服务器上启用无头渲染:
sudo apt-get update sudo apt-get install -y libegl1 libegl-dev libegl-mesa0 libegl1-mesa-dev libgles2-mesa-dev
注意: 如果没有这些库,在初始化 SAPIEN/机器人环境时可能会遇到
AttributeError: 'NoneType' object has no attribute 'eglQueryString'错误。
参考官方 OpenVLA-OFT 安装指南:
conda activate simplevla pip3 install torch torchvision # 克隆 OpenVLA-OFT (放在与 simplevla-rl 同级目录,而非 simplevla-rl 文件夹内) git clone https://github.com/moojink/openvla-oft.git cd openvla-oft pip install -e . # 安装 Flash Attention 2 用于训练 # 如果遇到问题,可以先尝试 `pip cache remove flash_attn` pip install packaging ninja ninja --version; echo $? # 应返回退出码 "0" pip3 install flash-attn --no-build-isolation cd .. # 安装 LIBERO git clone https://github.com/Lifelong-Robot-Learning/LIBERO.git pip install -e LIBERO cd openvla-oft pip install -r experiments/robot/libero/libero_requirements.txt cd ..
与选项 1 的步骤 1.1 相同。
与选项 1 的步骤 1.2 相同。
参考官方 RoboTwin 2.0 安装指南:
# 安装系统依赖 sudo apt install libvulkan1 mesa-vulkan-drivers vulkan-tools conda activate simplevla # 克隆并安装 RoboTwin git clone https://github.com/RoboTwin-Platform/RoboTwin.git cd RoboTwin bash script/_install.sh # 下载 RoboTwin 资源 bash script/_download_assets.sh cd ..
conda activate simplevla pip3 install torch torchvision # 克隆 OpenVLA-OFT (放在与 simplevla-rl 同级目录,而非 simplevla-rl 文件夹内) git clone https://github.com/moojink/openvla-oft.git cd openvla-oft pip install -e . # 安装 Flash Attention 2 pip install packaging ninja ninja --version; echo $? # 应返回退出码 "0" pip3 install flash-attn --no-build-isolation cd ..
应用必要的 RoboTwin 修改:
git clone https://github.com/PRIME-RL/SimpleVLA-RL.git cd SimpleVLA-RL # 应用 RoboTwin 修改 bash copy_overwrite_robotwin2.sh <your_robotwin_path> <your_simplevlarl_path> # 示例: bash copy_overwrite_robotwin2.sh /mnt/petrelfs/SimpleVLA-RL /mnt/petrelfs/RoboTwin
pip cache remove flash_attn安装完成后,您的目录结构应该如下所示:
your_workspace/ ├── SimpleVLA-RL/ ├── verl/ ├── openvla-oft/ ├── LIBERO/ (用于选项 1) └── RoboTwin/ (用于选项 2)
完成安装后,验证您的设置:
# 激活环境 conda activate simplevla # 验证 PyTorch 安装 python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())" # 验证 OpenVLA-OFT 安装 python -c "import openvla; print('OpenVLA imported successfully')" # 针对 LIBERO (选项 1) python -c "import libero; print('LIBERO imported successfully')" # 针对 RoboTwin (选项 2) python -c "import robotwin; print('RoboTwin imported successfully')"
RoboTwin 2.0 任务可能有不可行的种子(例如,物体超出机械臂可达范围)。为了优化 RL 训练,我们预先收集可行的种子,以避免在训练轮次中重复验证。
收集过程:
pre_collect_robotwin2_seed.sh 中更新 DATASET_NAME 为您的目标任务名称sh pre_collect_robotwin2_seed.sh
robotwin2_train_seeds.jsonSimpleVLA-RL/verl/utils/envs/robotwin2/seeds/robotwin2_train_seeds.json
SimpleVLA-RL/verl/utils/dataset/rob_dataset.py 中添加任务名称SimpleVLA-RL/verl/workers/rollout/rob_rollout.py 中添加任务名称和对应的最大步数在 SimpleVLA-RL/verl/utils/envs/robotwin2/envs/task_name.py 对应的任务文件中添加 get_info() 函数。
实现参考示例:
SimpleVLA-RL/modified_codes/robotwin2/envs/handover_block.py
强化学习训练需要一个 SFT(监督微调) 的 VLA 模型作为起点。
从 SimpleVLA-RL Collection 下载:
LIBERO 基准测试模型:
libero-10 traj1 SFT: 每任务 1 条轨迹训练(冷启动实验)libero-10 trajall SFT: 每任务所有轨迹训练libero-goal traj1 SFT: 目标泛化实验libero-object traj1 SFT: 物体泛化实验libero-spatial traj1 SFT: 空间泛化实验RoboTwin 2.0 基准测试模型:
Robotwin2.0 tasks traj1000 SFT: 每任务 1000 条轨迹训练从 OpenVLA 官方仓库 下载预训练模型。
如需使用其他模型或自定义数据,需要自行进行 SFT 微调。
在运行训练脚本前,需要配置以下关键参数:
在 SimpleVLA-RL/align.json 中替换为您的 WandB API 密钥:
{ "WANDB_API_KEY": "your_wandb_api_key_here" }
编辑 examples/run_openvla_oft_rl_libero.sh 或 examples/run_openvla_oft_rl_twin2.sh:
# 实验配置 export EXPERIMENT_NAME="libero_long_rl_exp1" # 实验名称 export SFT_MODEL_PATH="/path/to/your/sft/model" # SFT模型路径 export CKPT_PATH="/path/to/save/checkpoints" # 检查点保存路径 # 数据集配置 export DATASET_NAME="libero-long" # 选项: libero-10, libero-long, # robotwin2_beat_block_hammer, 等 # 计算资源配置 export NUM_GPUS=8 # 每节点GPU数量 export NUM_NODES=1 # 节点数量 # WandB配置 export ALIGN_PATH="SimpleVLA-RL/align.json"
# 数据采样配置 data.train_batch_size=64 # 每步训练采样64个任务实例 data.n_samples=8 # 每任务采样8个轨迹(GRPO需要) # 动态采样(关键技术1) data.filter_accuracy=True data.accuracy_lower_bound=0.1 # 过滤成功率<10%的任务组 data.accuracy_upper_bound=0.9 # 过滤成功率>90%的任务组 # 推理配置(关键技术3) actor_rollout_ref.rollout.temperature=1.6 # 更高的采样温度 # PPO配置(关键技术2) actor_rollout_ref.actor.clip_ratio_low=0.2 # 裁剪下界 actor_rollout_ref.actor.clip_ratio_high=0.28 # 裁剪上界(更高!) # 优化器配置 actor_rollout_ref.actor.optim.lr=5e-6 # 学习率 actor_rollout_ref.actor.ppo_mini_batch_size=128 actor_rollout_ref.actor.ppo_micro_batch_size=8 # 训练进度配置 trainer.total_epochs=20 # 总轮数(论文用20轮=300步) trainer.save_freq=20 # 每20步保存检查点 trainer.test_freq=4 # 每4步验证一次
bash examples/run_openvla_oft_rl_libero.sh
bash examples/run_openvla_oft_rl_twin2.sh
硬件配置: 8×NVIDIA A800 GPU(80GB)
| 配置 | 训练步数 | 预计时间 | 说明 |
|---|---|---|---|
| 论文设置 | 300步 | ~4.3天 | 20轮,每步约20分钟 |
| 配置文件 | 1500步 | ~21天 | 100轮(可调整) |
时间分解(每训练步):
要评估训练好的模型,在脚本中启用验证模式:
# 在 run_openvla_oft_rl_libero.sh 中添加 trainer.val_only=True
然后运行相同的脚本:
bash examples/run_openvla_oft_rl_libero.sh
每个训练步包含以下阶段:
训练步 i │ ├─ 1. 数据采样 │ └─ 从数据集采样 64 个任务实例 │ ├─ 2. 轨迹推理(Rollout) │ ├─ 每任务生成 8 条轨迹 │ ├─ VLA 模型推理 │ ├─ 环境交互 │ └─ 收集轨迹数据 │ ├─ 3. 动态采样过滤 │ └─ 过滤全成功/全失败的任务组 │ ├─ 4. 奖励计算 │ └─ 应用结果奖励(成功=1.0,失败=0.0) │ ├─ 5. 优势估计(GRPO) │ ├─ 按任务分组 │ ├─ 计算组内平均回报作为基线 │ └─ 优势 = 个体回报 - 组平均 │ ├─ 6. 策略更新(PPO) │ ├─ Mini-batch循环 │ ├─ 计算策略损失(带裁剪) │ ├─ 反向传播 │ └─ 梯度裁剪和优化器更新 │ ├─ 7. 验证(每4步) │ └─ 在256个任务上评估成功率 │ └─ 8. 保存检查点(每20步) └─ 保存模型权重和优化器状态
Group Relative Policy Optimization (GRPO) 是专为结果奖励设计的优势估计方法:
传统的 Generalized Advantage Estimation (GAE) 需要:
GRPO 的优势:
对于同一任务的 N 个轨迹:
# 1. 计算每条轨迹的总回报 R_i = Σ 奖励 # i = 1, 2, ..., N (N=8) # 2. 计算组内平均作为基线 baseline = (1/N) × Σ R_i # 3. 计算优势 A_i = R_i - baseline
任务1的8条轨迹: 回报: [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0] 基线: 0.5 优势: [-0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5] ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ 差 好 差 好 差 好 好 差 含义: 成功的轨迹获得正优势,失败的轨迹获得负优势 策略将学习增加成功轨迹的概率,减少失败轨迹的概率
# 标准 PPO 目标函数 ratio = π(a|s) / π_old(a|s) clipped_ratio = clip(ratio, 0.8, 1.2) # 对称裁剪 loss = -min(ratio × A, clipped_ratio × A) # SimpleVLA-RL: Clip Higher clipped_ratio = clip(ratio, 0.8, 1.28) # 不对称裁剪! loss = -min(ratio × A, clipped_ratio × A)
场景: 某个低概率动作(p=0.1)在一次探索中获得成功
标准 PPO (clip_high=0.2): - ratio = 0.15 / 0.1 = 1.5 - clipped_ratio = 1.2 (被限制!) - 概率最多增长 20% - 新概率 ≤ 0.12 Clip Higher (clip_high=0.28): - ratio = 1.5 - clipped_ratio = 1.5 (未被限制!) - 概率可增长 50% - 新概率 ≤ 0.15 结果: Clip Higher 允许更大的策略更新,鼓励探索
推切是 RL 训练过程中策略自主发现的新颖操作模式,从未在训练演示中出现。
SFT 模型:仅从人类演示学习
标准操作序列: 1. 接近物体 2. 抓取物体 3. 垂直抬起物体(避开桌面) 4. 水平移动到目标位置 5. 放下物体 6. 松开抓手
RL 训练后:发现更优策略
"推切"操作序列: 1. 接近物体 2. 抓取或接触物体 3. 保持低位(贴近桌面) 4. 水平推动/拖拽物体到目标位置 5. 任务完成! ↑ 无需抬起动作,更快速且鲁棒!
这一发现证明:
ReAct 模式(单步):
每步: 观察 → LLM推理 → 生成1个动作 → 执行 → 下一步 总计(200环境步): 200次LLM调用
VLA 动作分块(多步规划):
每轮: 观察 → VLA推理 → 生成25个未来动作 → 全部执行 → 下一轮 总计(200环境步): 8次VLA调用(200÷25=8)
时间轴: 0ms 300ms 1800ms 2100ms 3600ms | | | | | GPU: [VLA 1] 空闲 [VLA 2] 空闲 [VLA 3] ↓ ↓ 动作: 生成25 执行25 生成25 执行25 个动作 个动作 个动作 个动作 环境步: 0 0→24 25 25→49 50 机器人: 静止 运动... 运动... 运动... 运动...
答案:不会! 真实部署使用缓冲执行:
VLA线程: 持续计算下一批25个动作 ↓ 动作缓冲区: [动作0-24] → [动作25-49] → [动作50-74] ↓ ↓ ↓ 控制线程: 执行动作 执行动作 执行动作 (50Hz) (50Hz) (50Hz) 结果: 机器人保持连续、流畅的运动,无暂停!
关键条件:
VLA推理时间 < 动作分块执行时间 300ms < (25动作 × 50ms/动作) = 1250ms ✓ 安全边际: 1250ms / 300ms = 4倍 ✓
三大关键技术的超参数务必保留:
# 1. 动态采样 data.accuracy_lower_bound=0.1 data.accuracy_upper_bound=0.9 # 2. 更高裁剪界 actor_rollout_ref.actor.clip_ratio_high=0.28 # 3. 更高推理温度 actor_rollout_ref.rollout.temperature=1.6
这三个参数共同贡献了约 30% 的性能提升!
SimpleVLA RL rollout 结果(即机器人在虚拟环境中操作的视频)
根据文档,本实验在 RoboTwin 2.0 基准测试上运行了两个关键任务:
PPO KL 散度 (ppo_kl):
策略梯度损失 (pg_loss):
beat_block_hammer 显示更高的损失值和更大的波动move_can_pot 的损失相对稳定且较低策略梯度裁剪比例 (pg_clipfrac):
学习率和梯度范数:
验证器奖励 (train_reward/verifier):
beat_block_hammer(橙色): 从 ~0.3 提升到 ~0.75,增长 150%move_can_pot(蓝色): 从 ~0.15 提升到 ~0.6,增长 300%总体奖励 (train_reward/reward_all):
训练验证分数 (train_verify_score/all):
beat_block_hammer 最终达到 ~0.8 (80% 成功率)move_can_pot 最终达到 ~0.67 (67% 成功率)测试验证分数 (val/test_score):
beat_block_hammer: ~0.85 成功率move_can_pot: ~0.63 成功率beat_block_hammer: ~0.78 成功率move_can_pot: ~0.58 成功率奖励分数统计:
分数分布:
熵损失 (actor_after/entropy_loss_eval):
beat_block_hammer 显示更高的熵值(更多探索)move_can_pot 熵值逐渐降低但保持合理水平本实验在 RoboTwin 2.0 上的结果:
beat_block_hammer: 80% 成功率move_can_pot: 67% 成功率实验展现了 RL 在数据稀缺条件下的强大能力:
本项目基于以下优秀开源项目开发:
感谢以上项目的重要贡献!更多详情和更新,请参阅各项目的官方文档和代码仓库。
如有问题或建议,欢迎联系:
或在 GitHub Issues 提出问题。
如果您觉得 SimpleVLA-RL 对您的研究有帮助,请引用我们的论文:
@article{li2025simplevla, title={SimpleVLA-RL: Scaling VLA Training via Reinforcement Learning}, author={Li, Haozhan and Zuo, Yuxin and Yu, Jiale and Zhang, Yuhao and Yang, Zhaohui and Zhang, Kaiyan and Zhu, Xuekai and Zhang, Yuchen and Chen, Tianxing and Cui, Ganqu and others}, journal={arXiv preprint arXiv:2509.09674}, year={2025} }
同时也请引用 RoboTwin 2.0 基准测试:
@article{robotwin2025, title={RoboTwin 2.0: A Scalable Data Generator and Benchmark with Strong Domain Randomization for Robust Bimanual Robotic Manipulation}, author={...}, journal={arXiv preprint arXiv:2506.18088}, year={2025} }