人类演示视频转LeRobot v3.0
更新时间:2026-07-21
概述
将第一人称/第三人称人类手部操作演示视频转换为 LeRobot v3.0 格式的机器人训练数据集。通过 3D 手部重建、动作解算、轨迹平滑和原子动作切分,提取出可用于模仿学习的结构化动作轨迹。
- 输入:清洗后的高质量人类演示视频(manifest.json)
- 输出:LeRobot v3.0 格式数据集(含动作轨迹、视频帧、元信息)
- 业务价值:将低成本的人类手部演示视频自动转换为机器人可学习的动作数据,无需遥操作采集
处理流程
Plain Text
1演示视频 → S1 场景切分 → S2 3D手部重建(GPU) → S3 动作解算 → S4 轨迹平滑 → S5 原子动作切分 → S6 导出LeRobot → v3.0数据集
算子映射
| 步骤 | 算子 | GPU | 说明 |
|---|---|---|---|
| S1 | SplitScene |
否 | 按场景/任务边界切分视频为独立 clip |
| S2 | HandRecon |
是 | 使用 HaMeR/ViTPose 进行 3D 手部网格重建 |
| S3 | HandAction |
否 | 从 3D 手部网格解算末端位姿和夹爪状态 |
| S4 | TrajSmooth |
否 | Savitzky-Golay 滤波平滑动作轨迹 |
| S5 | AtomicSegment |
否 | 按运动模式切分为原子动作片段 |
| S6 | ExportLeRobot |
否 | 导出为 LeRobot v3.0 数据集格式 |
数据流向
Plain Text
1input_file (manifest.json)
2 → S1 → tmp_dir/s1_clips.jsonl
3 → S2 → tmp_dir/s2_recon.jsonl
4 → S3 → tmp_dir/s3_action.jsonl
5 → S4 → tmp_dir/s4_smooth.jsonl
6 → S5 → tmp_dir/s5_segments.jsonl
7 → S6 → output_dir/ (LeRobot v3.0 dataset)
前置条件
| 资源 | 说明 |
|---|---|
| AIHC 队列 | 需要有可用的计算队列(queue_id) |
| PFS 存储 | 用于存放中间数据和最终输出(pfs_id) |
| BOS Bucket | 用于挂载算子脚本、模型和输入数据,默认 aihc-rdw-bj/aihc-daft |
| GPU 资源 | S2 手部重建需要 GPU(默认 1 卡) |
| 镜像 | ccr-registry.baidubce.com/aihc/aihc-daft-gpu:0.5.2.1-cu121-py3.11-ubuntu22.04 |
| 模型 | HaMeR/ViTPose 模型文件(BOS 挂载 /opt/aihc/model 下) |
全局参数说明
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
image |
string | 是 | ccr-registry.baidubce.com/aihc/aihc-daft-gpu:0.5.2.1-cu121-py3.11-ubuntu22.04 |
镜像地址(含 tag),不填则使用默认值 |
queue_id |
string | 是 | — | AIHC 队列 ID |
priority |
string | 否 | high |
任务优先级 |
pfs_id |
string | 是 | — | PFS 存储 ID |
pfs_source_path |
string | 否 | / |
PFS sourcePath |
pfs_mount_path |
string | 否 | /mnt/pfs |
PFS 挂载点 |
bos_source_path |
string | 否 | aihc-rdw-bj/aihc-daft |
BOS sourcePath(统一) |
bos_mount_path |
string | 否 | /opt/aihc |
BOS 挂载点(统一) |
input_file |
string | 是 | /opt/aihc/data/embodied_pipelines/input_data/p2/manifest.json |
输入文件绝对路径 |
output_dir |
string | 是 | — | LeRobot v3.0 数据集输出目录(最终产物) |
tmp_dir |
string | 是 | — | 中间数据目录(6 个 step 共用) |
task |
string | 否 | pick and place the object |
任务描述文本(写入数据集元信息) |
no_split |
string | 否 | false |
是否跳过场景切分(true/false) |
use_videos |
string | 否 | false |
导出时是否包含视频(true/false) |
vcodec |
string | 否 | h264 |
视频编码器(h264/auto/libsvtav1) |
encoder_threads |
string | 否 | 空 | 每个编码器实例的线程数(空=不限制) |
model_dir |
string | 否 | /opt/aihc/model |
模型根目录(BOS 挂载点下的子路径) |
head_cpu |
int | 否 | 4 |
Head 节点 CPU 数 |
head_memory |
int | 否 | 8 |
Head 节点内存(GB) |
shared_memory |
int | 否 | 8 |
sharedMemory 大小(GB) |
worker_replicas |
int | 否 | 1 |
Worker 副本数 |
worker_cpu |
int | 否 | 6 |
Worker 节点 CPU 数 |
worker_memory |
int | 否 | 12 |
Worker 节点内存(GB) |
worker_gpu |
int | 否 | 1 |
Worker 节点 GPU 数(仅 S2 手部重建使用) |
步骤详解
S1 场景切分(Split Scene)
将输入视频按任务边界切分为独立的 clip 片段。每个 clip 对应一次完整的操作演示。支持跳过切分(设置 no_split=true),此时整段视频作为单个 clip。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
(使用全局参数 no_split) |
— | — | — |
- 输入:manifest.json(视频路径清单)
- 输出:
tmp_dir/s1_clips.jsonl(逐 clip 展开的记录)
S2 3D 手部重建(Hand Recon) GPU
使用 HaMeR + ViTPose 模型对视频逐帧进行 3D 手部网格重建,输出手部关键点和 MANO 参数。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
concurrency |
int | 1 |
GPU 推理并发数 |
- 输入:
tmp_dir/s1_clips.jsonl - 输出:
tmp_dir/s2_recon.jsonl(含 3D 手部网格数据) - 资源需求:需要 GPU(默认 1 卡
baidu.com/rtx_rpbzzz6_96g_cgpu)
S3 动作解算(Hand Action)
从 3D 手部网格数据中解算末端执行器的位姿(位置+旋转)和夹爪开合状态,生成结构化动作序列。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
coordinate_frame |
string | camera |
坐标系(camera / world) |
rotation_format |
string | axis_angle |
旋转表示格式(axis_angle / quaternion / euler) |
- 输入:
tmp_dir/s2_recon.jsonl - 输出:
tmp_dir/s3_action.jsonl(含位姿+夹爪动作序列)
S4 轨迹平滑(Trajectory Smooth)
对解算得到的动作轨迹进行 Savitzky-Golay 滤波平滑,去除抖动噪声。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
method |
string | savgol |
平滑算法 |
window |
string | 5 |
滑动窗口大小(奇数) |
polyorder |
string | 2 |
多项式阶数 |
- 输入:
tmp_dir/s3_action.jsonl - 输出:
tmp_dir/s4_smooth.jsonl(平滑后的轨迹)
S5 原子动作切分(Atomic Segment)
根据运动模式变化点将连续轨迹切分为原子动作片段(如"伸手"、"抓取"、"移动"、"放置")。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
min_segment_len |
string | 3 |
最小片段帧数(低于此长度的片段将被合并) |
- 输入:
tmp_dir/s4_smooth.jsonl - 输出:
tmp_dir/s5_segments.jsonl(含原子动作标注)
S6 导出 LeRobot(Export LeRobot)
将处理后的数据导出为 LeRobot v3.0 格式数据集,包含动作轨迹(parquet)、视频帧(可选)和元信息。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
repo_id |
string | human_demo_v3 |
数据集 repo_id |
fps |
string | 30 |
目标帧率 |
- 输入:
tmp_dir/s5_segments.jsonl - 输出:
output_dir/(LeRobot v3.0 数据集目录)
任务拓扑
Plain Text
1+---------------+ +----------------+ +---------------+ +---------------+ +-----------------+ +-----------------+
2| S1 SplitScene | --> | S2 HandRecon | --> | S3 HandAction | --> | S4 TrajSmooth | --> | S5 AtomicSegment| --> | S6 ExportLeRobot|
3| (CPU) | | (GPU) | | (CPU) | | (CPU) | | (CPU) | | (CPU) |
4+---------------+ +----------------+ +---------------+ +---------------+ +-----------------+ +-----------------+
6 个步骤严格串行执行,每步通过 dependencies 声明对前一步的依赖。仅 S2 需要 GPU 资源。
单步独立执行
每个步骤也提供独立的工作流模板,可以单独提交运行。适用于调试单个算子或从中间步骤恢复执行。
例如单独运行 S2 3D 手部重建:
YAML
1version: v1
2kind: PipelineTemplate
3
4inputs:
5- name: image
6 type: string
7 defaultValue: ccr-registry.baidubce.com/aihc/aihc-daft-gpu:0.5.2.1-cu121-py3.11-ubuntu22.04
8
9taskTemplates:
10- name: p2-2-hand-recon
11 type: CustomTask
12 inputs:
13 - name: queue_id
14 type: string
15 - name: pfs_id
16 type: string
17 - name: input_file
18 type: string
19 - name: output_file
20 type: string
21 - name: tmp_dir
22 type: string
23 - name: model_dir
24 type: string
25 defaultValue: /opt/aihc/model
26 - name: concurrency
27 type: int
28 defaultValue: 1
29 spec:
30 queue: '{{inputs.parameters.queue_id}}'
31 priority: high
32 jobType: RayJob
33 command: >-
34 DAFT_RUNNER=ray python3 /opt/aihc/workflow/p2_2_hand_recon.py
35 --input {{inputs.parameters.input_file}}
36 --output {{inputs.parameters.output_file}}
37 --tmp-dir {{inputs.parameters.tmp_dir}}
38 --model-dir {{inputs.parameters.model_dir}}
39 --concurrency {{inputs.parameters.concurrency}}
40 # jobSpec / datasources 配置同完整模板(Worker 需配置 GPU)
41
42tasks:
43- name: p2-hand-recon-task
44 taskTemplateName: p2-2-hand-recon
45 inputs:
46 - name: queue_id
47 value: '<YOUR_QUEUE_ID>'
48 - name: pfs_id
49 value: '<YOUR_PFS_ID>'
50 - name: input_file
51 value: '/mnt/pfs/<YOUR_PATH>/tmp_data/p2/s1_clips.jsonl'
52 - name: output_file
53 value: '/mnt/pfs/<YOUR_PATH>/tmp_data/p2/s2_recon.jsonl'
54 - name: tmp_dir
55 value: '/mnt/pfs/<YOUR_PATH>/tmp_data/p2'
使用建议
- S2 手部重建是计算瓶颈,建议根据数据量调整
worker_replicas和concurrency - 首次使用可设置
no_split=true快速验证全链路 use_videos=true会在导出时生成视频文件(增加存储开销),默认仅导出 parquet 格式动作数据vcodec推荐使用h264兼容性最好;libsvtav1压缩率更高但编码较慢- 如需自定义坐标系或旋转格式,可通过 S3 的
coordinate_frame和rotation_format参数调整
评价此篇文章
