📖 0. 前言
在机器人学习(Robot Learning)领域,ManiSkill 是目前最先进的通用仿真平台之一,而 ACT (Action Chunking with Transformers) 是模仿学习领域的算法。
官方文档通常描绘了一条“快乐路径(Happy Path)”:下载数据 -> 运行命令 -> 成功。然而,在真实的科研生产环境中(特别是无显示器的 Linux 服务器),我们面临着三大工程鸿沟:
渲染:Headless 服务器无法直接调用 GPU 进行 Vulkan 渲染(当然我其实可以,但是也写一下方便其他人用)。
数据:ManiSkill 的存储格式(字典/State)与 ACT 的输入格式(数组/Image)不兼容。
维度:仿真环境的向量化特性导致的数据维度错位。
本文将详细记录如何填平这些坑,实现 ACT 视觉模型的成功训练。
🧠 第一部分:核心原理
在动手之前,我们必须理解我们在做什么。
1.1 什么是模仿学习 (Imitation Learning, IL)?
与强化学习(RL)通过“试错-奖励”来学习不同,详细内容自查。
1.2 为什么选择 ACT?(VS 传统 Behavior Cloning)
传统的行为克隆(BC)是单步预测:
。这有个致命弱点:一旦某一步预测有微小误差,机器人就会偏离轨迹,进入从未见过的状态(Distribution Shift),导致误差像滚雪球一样累积。
ACT (Action Chunking with Transformers) 引入了两个关键改进:
Action Chunking(动作分块):一次预测未来 k 步的动作序列
CVAE + Transformer:使用 CVAE 建模动作的多模态分布(同一个任务有多种做法),使用 Transformer 处理时序依赖。
1.3 什么是 Motion Planning?它从哪里来?
我们下载的数据带有 motionplanning 标签。这意味着这些“专家数据”不是人类手操的,而是由算法生成的。
-
原理:基于 IK (逆运动学) 等数学算法。
-
特点:它拥有环境的绝对几何信息,算出的轨迹是物理可行且无碰撞的。
-
价值:它是 ACT 的老师。我们用 ACT 训练出的神经网络,本质上是在蒸馏运动规划算法的知识,将其转化为一个能通过视觉实时反应的策略。
1.4 State vs RGBD:两种观测模式的本质区别
这是本流程中最关键的选择。
| 特性 | State (状态) | RGBD (视觉) |
| 定义 | 上帝视角。直接读取物体的 XYZ 坐标、旋转四元数、关节角度。 | 真实视角。只能看到摄像头拍摄的 RGB 图像和深度图。 |
| 数据形态 | 结构化字典 (Dict) 或低维向量。 | 高维张量 (Tensor),如 (3, 128, 128)。 |
| ACT 兼容性 | 差。官方 ACT 代码预设输入是图片,处理 State 需要魔改代码。 | 完美。ACT 原生就是为视觉设计的。 |
| Sim-to-Real | 极难。现实中很难实时获取物体精确坐标。 | 标准路径。现实中装个摄像头就能用。 |
结论:我们必须在服务器上跑通 RGBD 模式,当然Maniskill提供的是state模式。
⚙️ 第二部分:Environment
在 Headless 服务器上运行 ManiSkill 的 SAPIEN 渲染器,必须解决 Vulkan 驱动问题。
2.1 报错现象
运行代码时出现:UserWarning: Failed to find Vulkan ICD file。这会导致渲染出的图片全黑,或者程序直接崩溃。
2.2 解决方案:环境变量注入
1. 核心修复:指定 Vulkan ICD (Installable Client Driver)
常见路径:/etc/vulkan/icd.d/nvidia_icd.json 或 /usr/share/vulkan/icd.d/export VK_ICD_FILENAMES=/etc/vulkan/icd.d/nvidia_icd.json 2. 权限解锁:允许 Docker/容器 访问所有 GPU 功能
NVIDIA_VISIBLE_DEVICES=all export NVIDIA_DRIVER_CAPABILITIES=all,compute,utility,graphics 3. 资源隔离:指定使用空闲的 GPU (如 ID 6)export CUDA_VISIBLE_DEVICES=6
🌉 第三部分:数据生产与清洗 (Bridge)
我们必须手动编写脚本,连接“原始数据”与“ACT 代码”。
ACT 的 train.py 是一个静态加载器。它打开 .h5 文件后,期望直接读取到名为 images 的数据集。 然而,ManiSkill 为了节省存储空间,下载的原始 .h5 只包含“剧本”(关节角度 + 物体坐标),没有“画面”。
直接运行的后果:
TypeError: new(): data must be a sequence (got dict)
因为代码试图读取 sensor_data (图片),结果读到了 obs (坐标字典)。
3.2 解决方案:Replay & Render (重放与渲染)
我们不能凭空变出图片,但我们可以重放。
我们需要编写一个 Python 脚本 (make_rgbd_data.py),它的逻辑如下:
加载:读取原始 .h5 中的 action 和 env_state。
搭建:使用 gym.make(…, obs_mode="rgbd") 启动仿真器。
拍摄:
env.reset() 回到初始状态。
执行 env.step(action) 重现每一个动作。
SAPIEN 引擎利用 GPU 实时渲染出当前帧的 RGBD 图像。
后期制作:将渲染出的图片数组存入新的 .h5 文件。
3.3 踩坑:三个“维度”的教训
在编写这个脚本时,我遇到了三个由于 ManiSkill v3 特性导致的严重 Bug,这在官方文档中未被提及。
🐛 Bug 1 : 向量化维度的陷阱
-
现象:ValueError: axes don't match array。
-
原因:ManiSkill v3 默认是向量化环境 (Vectorized Env)。即使只跑 1 个环境,返回的数据也是带 Batch 维度的 (1, 128, 128, 3)。
-
修复:在转置之前,必须手动降维。
if raw_rgb.ndim == 4: raw_rgb = raw_rgb[0] # (1, H, W, C) -> (H, W, C)
🐛 Bug 2 : 关节数据的维度
-
现象:训练时 loss 异常或报错。
-
原因:同理,qpos 返回的是 (1, 7),而 PyTorch Dataset 期望 (7,)。
-
修复:
if q.ndim == 2: q = q[0]
🐛 Bug 3 : env_states 的结构变更
-
现象:TypeError: Accessing a group … with int。
-
原因:ManiSkill v3 将 env_states 从 Dataset 改为了 Group(层级化存储)。旧版脚本用 [0] 索引会报错。
-
修复:编写递归函数来提取第一帧状态。
def get_first_state(h5_node):if isinstance(h5_node, h5py.Group): return {k: get_first_state(v) for k, v in h5_node.items()} return h5_node[0]
🚀 第四部分:最终执行 SOP
将上述所有知识汇总,以下是 可以直接执行的标准流程。
Step 1: 准备数据生成脚本
创建 make_rgbd_data.py,填入包含上述所有修复逻辑的代码。 (核心代码逻辑:Reset Env -> Loop Actions -> Step & Render -> Save Images)
Step 2: 执行数据转换
export VK_ICD_FILENAMES=/etc/vulkan/icd.d/nvidia_icd.json python make_rgbd_data.py
结果:生成 trajectory_rgbd.h5,包含 1000 条高质量 RGBD 轨迹。
Step 3: 配置文件同步
cd ~/.maniskill/demos/PushCube-v1/motionplanning/ # 复制并重命名配置,确保 obs_mode 为 rgbdecho '{…"obs_mode": "rgbd"…}' > trajectory_rgbd.json
Step 4: 启动训练
cd ~/cj/ManiSkill python examples/baselines/act/train.py \\ –env-id "PushCube-v1" \\ –demo-path ~/.maniskill/demos/PushCube-v1/motionplanning/trajectory_rgbd.h5 \\ –control-mode "pd_joint_pos" \\ –num-demos 1000 \\ –total-iters 30000 \\ –exp-name "act_rgbd_final" \\ –no-track
网硕互联帮助中心




评论前必须登录!
注册