ManiSkill 从演示中学习(LfD)环境搭建指南:轨迹下载重放、公平评估与常见陷阱

ManiSkill 从演示中学习(LfD)环境搭建指南:轨迹下载重放、公平评估与常见陷阱 ManiSkill 从演示中学习LfD环境搭建指南轨迹下载重放、公平评估与常见陷阱【免费下载链接】ManiSkillManipulation Skill Framework, an open source GPU parallelized robotics simulator and benchmark项目地址: https://gitcode.com/GitHub_Trending/ma/ManiSkill本篇技术指南以 ManiSkill 官方文档中从演示中学习Learning from Demonstrations的 Setup 章节为核心系统讲解如何在 ManiSkill 中搭建用于模仿学习基准测试Imitation Learning Benchmarking的环境包括如何下载官方压缩演示数据、如何用统一脚本重放出标准可训练数据集、如何用标准化代码公平评估各类 LfD 策略以及评估指标success_once/success_at_end/fail_once/fail_at_end/return的确切语义。读完本篇你将能够复现 ManiSkill 官方 LfD 基准的数据准备流程并写出可直接跑通、可与其他论文结果公平对比的评估代码。数据准备为什么官方演示数据不含观测为了加快下载速度并减小文件体积ManiSkill 官方演示数据默认以高度精简/压缩的格式存储。这种 raw 格式不包含任何观测数据observation只保留重放一条轨迹所必需的信息环境状态env states、动作actions、随机种子seeds与 reset 参数。从源码看download_demo.py 中的DemoDatasetSource数据类注释明确说明了这一点dataclass class DemoDatasetSource: raw_dataset_url: str URL pointing to the raw dataset which does not contain any observations, just env states, actions, and reset kwargs pre_processed_dataset_url: Optional[str] None URL pointing to preprocessed versions if any env_type: str rigid_body # or soft_body也就是说raw 数据只包含重放一条轨迹所需的全部信息观测需要你在本地重放时按需生成。这样做的好处是同样的 raw 数据可以被重放成不同观测模式state、rgb、pointcloud 等和不同控制模式controller的数据集而无需为每种模式存储一份巨大的文件。下载演示数据运行下面的命令即可下载指定任务如PickCube-v1的 raw 精简演示数据python -m mani_skill.utils.download_demo PickCube-v1该命令支持几种 uid 取值见 download_demo.py具体环境 ID例如PickCube-v1、PushT-v1all下载全部可用任务的演示数据rigid_body/soft_body按环境类型批量下载不带参数运行打印所有可用的数据集 UID 列表。下载默认保存到~/.maniskill/demos或环境变量MS_ASSET_DIR指定的目录也可通过-o/--output_dir指定自定义输出目录文件会保存在output_dir/env_type/env_id下。raw 数据本身是 zip 压缩包下载后会自动解压源码中通过zipfile.ZipFile(...).extractall(output_dir)完成。从 download_demo.py 可以看到当前支持下载演示数据的刚性体任务包括AnymalC-Reach-v1、DrawTriangle-v1、LiftPegUpright-v1、PegInsertionSide-v1、PickCube-v1、PlugCharger-v1、PokeCube-v1、PullCube-v1、PullCubeTool-v1、PushCube-v1、PushT-v1、RollBall-v1、StackCube-v1、StackPyramid-v1、TwoRobotPickCube-v1、TwoRobotStackCube-v1等。为什么不能直接用 raw 数据训练raw 数据虽然体积小但存在两个问题没有观测数据无法直接用于监督式模仿学习动作不覆盖所有控制模式controller。raw 数据记录的是采集时的控制器动作而不同基线算法对动作空间有不同偏好。因此官方要求统一使用重放脚本把 raw 数据重放成预处理/重放后的标准数据集preprocessed/replayed dataset确保所有研究者拿到的是同一份数据从而保证基准结果可比。标准数据集重放replay_for_il_baselines.sh官方脚本 scripts/data_generation/replay_for_il_baselines.sh 用于把下载好的 raw 演示重放为包含观测数据与指定控制器动作空间的标准数据集。脚本头部注释明确说明了设计意图Script used for replaying downloaded demonstrations to include the relevant observation data and action space (controller) data used for the imitation learning benchmarking in ManiSkill. Note that we specify here the controller mode to use, different from the original stored in the datasets. The strategy here is to use the simplest controller possible such that the task is still solvable.也就是说脚本会显式指定控制器模式与原始数据中存储的不同策略是在任务仍可解的前提下使用尽可能简单的控制器。另外脚本注释也解释了为何官方不直接上传重放后的数据因为包含图像数据后文件体积会极其庞大上传的演示通常只保留体积极小的环境状态数据。脚本使用方式# 默认演示数据目录 DEMO_PATH~/.maniskill/demos # 若设置了不同的 ManiSkill 数据目录可取消下面一行的注释 # DEMO_PATH${MS_ASSET_DIR}/demos python -m mani_skill.trajectory.replay_trajectory \ --traj-path ${DEMO_PATH}/PickCube-v1/motionplanning/trajectory.h5 \ --use-first-env-state -c pd_ee_delta_pos -o state \ --save-traj --num-envs 10 -b physx_cpu脚本覆盖了多个基准任务例如任务数据来源控制器观测模式后端PushCube-v1 / PickCube-v1 / StackCube-v1motionplanningpd_ee_delta_posstate/rgbphysx_cpuStackPyramid-v1 / PegInsertionSide-v1motionplanningpd_ee_delta_posestate/rgbphysx_cpuDrawTriangle-v1motionplanningpanda stickpd_ee_delta_posrgbphysx_cpuPushT-v1rl神经网络策略生成pd_ee_delta_pose/pd_ee_delta_posstate/rgbphysx_cuda注意脚本中的差异控制器选择平移类任务用pd_ee_delta_pos末端执行器 delta 位置控制涉及姿态调整的任务用pd_ee_delta_pose末端执行器 delta 位姿控制。这两者都属于 ManiSkill 的 PD EE 末端执行器控制器族实现于 pd_ee_pose.pyPDEEPosController继承自PDJointPosController。后端选择-b physx_cpu用于大部分任务-b physx_cudaGPU 并行仿真仅用于 PushT-v1因为其演示数据本身就是用 GPU 仿真收集的文件名后缀physx_cuda且该任务需要大量并行环境重放--num-envs 1024/--num-envs 256。初始状态恢复方式motionplanning 数据用--use-first-env-state只取首帧环境状态设定初始条件PushT 数据用--use-env-states逐帧回放环境状态保证每一步都与原始轨迹完全一致适用于高精度任务。⚠️ 文档特别提醒部分命令使用 GPU 仿真标记为-b physx_cuda进行重放可能超出你的 GPU 显存。可以通过调低--num-procs或--num-envs来降低并行环境数量从而减少显存占用。为什么需要固定这些参数重放脚本的参数不是随意定的它们直接决定了训练数据的性质-c指定目标控制器所有基准结果统一使用末端执行器 delta 控制这对模仿学习来说更容易学习-o state/-o rgb指定观测模式分别对应状态基state-based与视觉基vision-based模仿学习基准--save-traj把重放结果保存为新的.h5轨迹文件不会覆盖原始文件见 replay_trajectory.py 中save_traj参数注释--num-envs控制并行环境数CPU 后端通过 Python 多进程并行GPU 后端在单进程内利用 GPU 并行见 replay_trajectory.py。ManiSkill 官方在 Wandb 上发布的全部基准训练结果使用的都是该脚本重放出的数据。因此想要复现官方 LfD 基准必须使用此脚本重放数据而不是直接用 raw 数据训练。重放工具的进阶用法如果你需要更高级的重放场景例如生成点云观测、切换控制器模式可以参考 轨迹重放文档。这里提炼几个与 LfD 数据准备直接相关的关键点重放工具的核心参数完整参数定义见 replay_trajectory.py基于tyro解析常用参数如下参数别名作用--traj-path-待重放的.h5轨迹文件路径必需同目录下还需有对应的trajectory.json--sim-backend-b仿真后端physx_cpu或physx_gpu不指定则沿用收集数据时的后端--obs-mode-o目标观测模式state、rgb、pointcloud等--target-control-mode-c目标控制模式做动作转换注意并非所有控制器都能互相转换Panda 机器人支持最好且 GPU 并行环境下不支持控制器转换--save-traj-将重放结果保存为新轨迹文件不覆盖原文件--save-video-保存重放视频--num-envs-n并行环境数--num-procs是 CPU 后端下的兼容别名--use-env-states-逐帧用环境状态回放保证每一步与原始轨迹完全一致--use-first-env-state-仅用首帧环境状态初始化适合把 CPU 仿真收集的演示搬到 GPU 仿真重放--max-retry-重放失败时最大重试次数直到任务末端成功--allow-failure-是否保留失败的回合默认只保留成功回合--discard-timeout-是否丢弃超时被截断的回合--count-重放前 N 条演示后退出默认全部重放--reward-mode-指定奖励类型sparse、none部分任务支持dense/normalized_dense--record-rewards-是否在重放轨迹中记录奖励--shader-渲染着色器rt光线追踪写实渲染、rt-fast更快的低质量光线追踪--vis-通过 SAPIEN viewer 可视化重放过程实用的重放工作流示例从 CPU 仿真数据重放为 GPU 仿真可用的数据CPU 与 GPU 仿真在相同动作和初始状态下存在细微行为差异teleoperation 采集的演示常在 CPU 仿真进行而训练往往在 GPU 仿真。此时用首帧状态初始化并在 GPU 上重放、仅保留重放成功的演示python -m mani_skill.trajectory.replay_trajectory \ --traj-path path/to/trajectory.h5 \ --use-first-env-state -b physx_cuda \ -c pd_joint_delta_pos -o state \ --save-traj把控制器转换为更易学习的控制模式末端执行器控制通常比关节控制更容易学习python -m mani_skill.trajectory.replay_trajectory \ --traj-path path/to/trajectory.h5 \ -c pd_ee_delta_pose -o state \ --save-traj为轨迹补充奖励与观测演示数据默认不含观测和奖励可用如下方式补回--use-env-states确保重放数据与原始轨迹完全一致python -m mani_skill.trajectory.replay_trajectory \ --traj-path path/to/trajectory.h5 \ --record-rewards --reward-modenormalized_dense -o rgb \ --use-env-states \ --save-traj数据集的加载方式重放完成后官方还提供了即插即用的 PyTorch DatasetManiSkillTrajectoryDataset。它读取.h5轨迹文件与同名的.json元数据trajectory.json支持load_count加载条数-1 为全部、success_only仅保留成功轨迹、device数据存放位置等参数。该类的 docstring 也提醒它只是最基础的加载代码不包含数据变换进阶用法建议直接复制并修改此类。公平评估标准化的评估配置与代码ManiSkill 中有多种环境类型、算法和评估方式为公平比较官方定义了统一的评估设置。其核心思想在 setup.md 中总结为两点关闭部分重置环境不在成功/失败/终止时提前重置ignore_terminationsTrue而是记录多种成功/失败指标每次重置都重新配置环境reconfiguration_freq1让任务的对象几何随机化如果该任务支持随机化充分生效避免评估被固定的初始条件作弊。GPU 向量化环境评估代码如果你的演示数据是在 GPU 仿真physx_cuda上收集的建议在 GPU 后端上评估策略。官方推荐按环境 ID 评估的代码如下import gymnasium as gym import torch from collections import defaultdict from mani_skill.vector.wrappers.gymnasium import ManiSkillVectorEnv env_id PushCube-v1 num_eval_envs 64 env_kwargs dict(obs_modestate) # modify your env_kwargs here eval_envs gym.make(env_id, num_envsnum_eval_envs, reconfiguration_freq1, **env_kwargs) # add any other wrappers here eval_envs ManiSkillVectorEnv(eval_envs, ignore_terminationsTrue, record_metricsTrue) # evaluation loop, which will record metrics for complete episodes only obs, _ eval_envs.reset(seed0) eval_metrics defaultdict(list) for _ in range(400): action eval_envs.action_space.sample() # replace with your policy action obs, rew, terminated, truncated, info eval_envs.step(action) # note as there are no partial resets, truncated is True for all environments at the same time if truncated.any(): for k, v in info[final_info][episode].items(): eval_metrics[k].append(v.float()) for k in eval_metrics.keys(): print(f{k}_mean: {torch.mean(torch.stack(eval_metrics[k])).item()})从 ManiSkillVectorEnv 的源码可以印证评估逻辑ignore_terminationsTrue时step返回的terminations会被强制置为 False源码第 150-151 行即任务不会因成功/失败提前结束而是跑满整个 episode由时间上限 truncated 决定record_metricsTrue时环境内部累积success_once、fail_once、return、episode_len、reward并在ignore_terminations开启时额外记录success_at_end、fail_at_end源码第 132-158 行由于关闭了部分重置所有环境会在同一时刻 truncated此时info[final_info]中携带本回合完整的 episode 指标评估循环只需在truncated.any()时收集即可。CPU 向量化环境评估代码如果演示数据是在 PhysX CPU 仿真上收集的则应使用 CPU 向量化环境评估官方推荐代码如下import gymnasium as gym import numpy as np from collections import defaultdict from mani_skill.utils.wrappers import CPUGymWrapper env_id PickCube-v1 num_eval_envs 8 env_kwargs dict(obs_modestate) # modify your env_kwargs here def cpu_make_env(env_id, env_kwargs dict()): def thunk(): env gym.make(env_id, reconfiguration_freq1, **env_kwargs) env CPUGymWrapper(env, ignore_terminationsTrue, record_metricsTrue) # add any other wrappers here return env return thunk vector_cls gym.vector.SyncVectorEnv if num_eval_envs 1 else lambda x : gym.vector.AsyncVectorEnv(x, contextforkserver) eval_envs vector_cls([cpu_make_env(env_id, env_kwargs) for _ in range(num_eval_envs)]) # evaluation loop, which will record metrics for complete episodes only obs, _ eval_envs.reset(seed0) eval_metrics defaultdict(list) for _ in range(400): action eval_envs.action_space.sample() # replace with your policy action obs, rew, terminated, truncated, info eval_envs.step(action) # note as there are no partial resets, truncated is True for all environments at the same time if truncated.any(): for final_info in info[final_info]: for k, v in final_info[episode].items(): eval_metrics[k].append(v) for k in eval_metrics.keys(): print(f{k}_mean: {np.mean(eval_metrics[k])})这里用到了 CPUGymWrapper它把单环境封装成完全符合标准 gymnasium API 的接口返回 numpy 数组、去掉 batch 维度并可选择记录标准化评估指标。它的 docstring 明确指出该 wrapper 仅适用于 CPU 后端、非并行环境且一般应放在所有其他 wrapper 之后应用因为多数 ManiSkill wrapper 假设数据是批量的 torch 张量。num_eval_envs 1时用SyncVectorEnv多环境时用AsyncVectorEnv(contextforkserver)。指标含义两种评估代码记录的是同一套指标含义如下指标含义success_once回合中任意时刻任务是否成功过LfD 研究中最重要的指标success_at_end回合最后一步任务是否处于成功状态fail_once/fail_at_end与上面两个对应但针对失败注意并非所有任务都有成功/失败判据return整个回合累积的总奖励文档明确说明对于从演示中学习唯一重要的指标通常是success_once这也是 ManiSkill 相关研究工作普遍报告的结果。此外从 CPUGymWrapper 源码可以看到info[episode]中还会附带episode_len回合长度与reward平均奖励 return / episode_len方便你做更细粒度的分析。常见陷阱与注意事项1. 仿真后端必须匹配如果演示数据是在 PhysX CPU 仿真中收集的评估基于该数据训练的策略时必须在同一仿真后端评估。对于高精度任务如 PushT-v1即使1e-3级别的误差也可能导致完全不同的结果。这也是为什么官方轨迹重放工具会在轨迹文件名上标注所用仿真后端例如trajectory.none.pd_ee_delta_pose.physx_cuda.h5表明这是 GPU 仿真收集的。从 replay_trajectory.py 的源码注释还可以看到对于 PushT 这类高精度任务即使在 GPU 仿真中每走一步都强制set_state_dict恢复环境状态仍可能因为单步仿真哪怕步数相同、并行环境数不同产生非确定性导致部分步骤的观测/奖励/成功/失败标签出现1e-4级别的误差。2. 演示数据的来源会影响训练效果演示数据的来源对训练性能影响巨大经典行为克隆BC可以较好地模仿由神经网络/RL 训练策略生成的演示但对于多模态演示例如人类遥操作、运动规划生成的演示经典 BC 会明显吃力这类问题正是 Diffusion PolicyDP等方法被设计来解决的。如果你不确定数据来源ManiSkill 的官方数据集都会在轨迹元数据 JSON 文件trajectory.json中清楚说明数据是如何收集的采集方式与数据类型。从仓库的演示生成脚本也可以印证这一点例如 scripts/data_generation/motionplanning.sh 通过运动规划方式启发式生成演示python -m mani_skill.examples.motionplanning.panda.run而PushT-v1的数据文件名中带有rl子目录标识表明来自 RL 策略。3. 不要跳过重放脚本直接使用 raw 数据训练会导致(a) 没有观测数据可用(b) 动作空间与官方基线不一致结果不可比。务必先运行 replay_for_il_baselines.sh或参照其参数自行重放确保与他人使用相同预处理后的标准数据集。配套资源LfD 基线实现搭建好环境后可以在 从演示中学习LfD基线文档 中查看官方提供的各类基线它们覆盖了从演示中学习的三个主流方向行为克隆 / 监督学习标准行为克隆BC、Diffusion Policy (DP)、Action Chunking Transformer (ACT)离线强化学习相关实现见 examples/baselines 目录在线从演示学习Reverse Forward Curriculum Learning (RFCL)注意其使用环境状态重置这是仿真特有的功能、RLPD 等。这些基线的训练/评估脚本与本文介绍的数据准备、评估代码配合使用即可完整复现 ManiSkill 的 LfD 基准研究流程。总结在 ManiSkill 中进行从演示中学习的研究环境搭建的关键链路可以归纳为四步下载 raw 演示数据download_demo→ 用统一脚本重放为标准数据集replay_for_il_baselines.sh固定控制器与观测模式→ 训练策略 → 在相同仿真后端上用ignore_terminationsTruereconfiguration_freq1record_metricsTrue的标准代码评估。只要严格遵守演示数据与评估后端一致、使用官方重放数据、报告success_once这三条原则你的实验结果就能与 ManiSkill 官方基准及其他研究工作进行公平、可复现的比较。【免费下载链接】ManiSkillManipulation Skill Framework, an open source GPU parallelized robotics simulator and benchmark项目地址: https://gitcode.com/GitHub_Trending/ma/ManiSkill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考