ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

BONES-SEED时间分段标签实战:用NVIDIA Kimodo时间戳精准切分复杂动作(附代码)

BONES-SEED时间分段标签实战:用NVIDIA Kimodo时间戳精准切分复杂动作(附代码)
  • 数据集
  • 机器人
  • 具身智能

【免费下载链接】seed

项目地址:https://ai.gitcode.com/hf_mirrors/bones-studio/seed
点击查看免费下载

BONES-SEED(Skeletal Everyday Embodiment Dataset)是一个包含142,220 条标注人体动作的开源动捕数据集,面向人形机器人全身控制、文本生成动作等任务。每条动作都附带了 NVIDIA 为 Kimodo 项目制作的时间分段标签(temporal segmentation labels),通过start_time/end_time时间戳把长动作精确切分成多个语义阶段。本文将带你快速上手:如何读取这些标签、如何按时间戳把 BVH / G1 动作轨迹切成可用的动作片段。

什么是BONES-SEED时间分段标签?Kimodo时间戳3分钟看懂

一条动捕动作往往是"多阶段"的:比如开门动作,先拧门把手、再推门、最后松手站立。如果整条当成一个样本训练,模型很难学会每个阶段的细节。

BONES-SEED 的时间分段标签就是为了解决这个问题——由 NVIDIA 在 Kimodo 项目框架下人工制作,把每条完整动作切分为若干有意义的语义阶段,每个阶段都有精确的秒级时间戳和自然语言描述。

标签文件位于 metadata/ 目录:

文件说明
seed_metadata_v002_temporal_labels.jsonl时间分段标签,每行一个 JSON 对象
seed_metadata_v004.parquet主元数据(51 列 × 142,220 行),filename列与标签文件对应
seed_metadata_v004.csv同一份元数据的 CSV 版本

JSONL 的 Schema 非常直观(详见 README.md):

字段类型含义
filenamestring动作文件名,与主元数据filename列一致
num_eventsint分段数量
eventsarray按时间顺序排列的分段列表
events[].start_timefloat分段起始时间(秒)
events[].end_timefloat分段结束时间(秒)
events[].descriptionstring该阶段的自然语言描述

官方示例(inside_door_knob_left_side_open_R_002__A512,一个"开门"动作被切成 3 段):

{ "filename": "inside_door_knob_left_side_open_R_002__A512", "num_events": 3, "events": [ {"start_time": 0.0, "end_time": 1.88, "description": "A person rotates the door knob with their right hand."}, {"start_time": 1.88, "end_time": 3.53, "description": "A person opens the door outward from the inside, holding the knob and then lowers their hand."}, {"start_time": 3.53, "end_time": 4.83, "description": "A person is standing idle and slightly moving their right hand."} ] }

可以看到:4.83 秒的动作被切成了"拧把手 → 推门松手 → 站立"三个阶段,每段都有独立的文字标签——这就是"语言条件策略"训练所需的"动作+描述"配对数据。

获取数据:完整克隆BONES-SEED仓库的步骤

使用 Git LFS 克隆即可(数据文件较大,请预留磁盘空间):

git lfs install git clone https://link.gitcode.com/i/07781fd2fb37a9d06a1ccf96a705f995

克隆完成后,动作数据以压缩包形式分发,解压到数据集根目录即可(完整目录结构见 README.md):

tar -xzf soma_uniform.tar.gz tar -xzf soma_proportional.tar.gz tar -xzf g1.tar.gz

关键目录速览:

路径内容
soma_uniform/bvh/{date}/{motion_name}.bvhSOMA Uniform 标准骨架 BVH 动作
soma_proportional/bvh/{date}/{motion_name}.bvh保留演员体型比例的 BVH 动作
g1/csv/{date}/{motion_name}.csvUnitree G1 机器人 MuJoCo 兼容关节角度轨迹
soma_shapes/骨架与体型参数(含 soma_base_rig/soma_base_skel_minimal.bvh 骨架定义)

💡 所有动作统一以120 fps采集,这个采样率是后面时间戳换算的关键。

快速上手:一步加载temporal标签文件

标签是标准 JSONL,用几行 Python 就能建好"文件名 → 分段"的字典(示例代码源自 README.md):

import json temporal_labels = {} with open("metadata/seed_metadata_v002_temporal_labels.jsonl") as f: for line in f: entry = json.loads(line) temporal_labels[entry["filename"]] = entry["events"] # 查看某条动作的分段 events = temporal_labels["inside_door_knob_left_side_open_R_002__A512"] for event in events: print(f"[{event['start_time']:.2f}s - {event['end_time']:.2f}s] {event['description']}")

输出:

[0.00s - 1.88s] A person rotates the door knob with their right hand. [1.88s - 3.53s] A person opens the door outward from the inside, holding the knob and then lowers their hand. [3.53s - 4.83s] A person is standing idle and slightly moving their right hand.

核心代码:用start_time和end_time切分动作帧

拿到秒级时间戳后,切分动作只需两步:时间换算成帧,再截取轨迹。

换算关系(120 fps):

FPS = 120 def to_frame_range(event): """把秒级时间区间换算成帧索引 [start, end)""" start = int(round(event["start_time"] * FPS)) end = int(round(event["end_time"] * FPS)) return start, end

以 G1 机器人关节轨迹(CSV 格式,每行一帧)为例,切出单个语义片段非常简单:

import pandas as pd def cut_g1_clip(csv_path, event, out_path): df = pd.read_csv(csv_path) s, e = to_frame_range(event) clip = df.iloc[s:e] # 截取该阶段的关节角度 clip.to_csv(out_path, index=False) print(f"已切出: {event['description'][:40]}... 共 {len(clip)} 帧") cut_g1_clip("g1/csv/250101/inside_door_knob_left_side_open_R_002__A512.csv", events[0], "clip_rotate_knob.csv")

对 BVH 文件(soma_uniform/bvh/...)同理:BVH 分HIERARCHY(骨架定义,见 soma_base_skel_minimal.bvh)和MOTION(帧数据)两大部分,切分时只需保留MOTION段中对应帧区间的数据即可:

def cut_bvh_motion(bvh_path, start_frame, end_frame, out_path): text = open(bvh_path).read() head, motion = text.split("MOTION") frames = motion.strip().splitlines() sliced = "\n".join(frames[start_frame:end_frame]) out = head + "MOTION\nFrames: " + str(end_frame - start_frame) + "\n" + sliced open(out_path, "w").write(out)

⚠️ 一个实用技巧:切出的片段若要单独播放,通常需把首帧作为新的原点做相对化(减去首帧平移/旋转),否则角色会"跳"到原世界坐标位置。新手阶段可先忽略,直接用于训练数据没问题。

复杂动作切分的3个实战应用场景

1️⃣ 语言条件策略训练(Kimodo 的原始目标)

把每个片段作为训练样本:片段BVH帧序列 + 该阶段 description 文本构成配对数据。相比整条动作,"拧把手"片段配上 "rotates the door knob",语义对齐更精准,正是人形机器人 language-to-action 学习最需要的粒度。

2️⃣ 动作检索与理解

用content_complex_action、content_repeated_action等元数据列(seed_metadata_v004.parquet)先筛出多阶段动作,再结合分段标签做动作识别、风格分类等下游任务。

3️⃣ G1 机器人 Sim-to-Real

把切出的片段直接喂给 MuJoCo:g1/csv/下每个片段都是可直接播放的关节角度轨迹,可在仿真中逐阶段验证机器人是否能复现"拧把手"这个单步操作,比整条验证更容易定位失败点。

常见错误清单:避坑指南

坑点说明
单位混淆start_time/end_time单位是秒,帧数需乘 120;不要直接拿它当帧索引
文件名对不上标签的filename对应主元数据的filename列(不含扩展名),而不是move_name
左右镜像动作数据集含约 7.1 万条镜像动作(is_mirror为 true),镜像后"左手/右手"类描述需留意方向反转
切完忘记重采样end_time是闭区间的边界点,取帧时用[start, end)半开区间,避免相邻片段重复一帧
压缩包含解压克隆后soma_uniform等目录是 tar 包,忘了tar -xzf会找不到 BVH 文件

总结

BONES-SEED 的时间分段标签是"动作 + 精确时间戳 + 自然语言描述"三合一的宝贵资产:

  • 标签文件 seed_metadata_v002_temporal_labels.jsonl 采用简洁的 JSONL 格式,events数组里的start_time/end_time就是切分依据;
  • 换算公式只有一条:帧 = 秒 × 120,之后对 BVH 的 MOTION 段或 G1 的 CSV 轨迹按帧截取即可;
  • 切出的片段可直接用于语言条件策略训练、动作识别和 G1 机器人仿真验证。

掌握这套"标签读取 → 时间换算 → 轨迹截取"的流程,你就能把 14 万条复杂动作库变成细粒度、语义清晰的高质量训练样本。

  • 数据集
  • 机器人
  • 具身智能

【免费下载链接】seed

项目地址:https://ai.gitcode.com/hf_mirrors/bones-studio/seed
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进