
具身智能机器人数据格式 · 扫盲总结一份给入门者速查的笔记。覆盖 7 种主流格式rosbag / MCAP / TFRecord / HDF5 / Zarr / Parquet / RLDS / LeRobot主线机器人数据要经历三段旅程——先被录下来再存到硬盘最后加上语义变成训练数据。七种格式就分布在这三段上。〇、最重要的一张图三层模型初学者最大的困惑是这些格式怎么感觉是一类又不是一类。真相是它们不在同一层┌──────────────────────────────────────────────────────────────┐ │ ① 采集层 记录时间上发生了什么 │ │ —— 像行车记录仪按时间录下机器人的一切 │ │ rosbag、MCAP │ └──────────────────────────────────────────────────────────────┘ │ 转换对齐时间、切分回合、定义动作 ▼ ┌──────────────────────────────────────────────────────────────┐ │ ② 存储层 字节在硬盘上怎么摆 │ │ —— 像仓库货架只管高效存取不懂内容是什么 │ │ TFRecord、HDF5、Zarr、Parquet │ └──────────────────────────────────────────────────────────────┘ │ 加语义标注哪是观测、哪是动作、回合边界 ▼ ┌──────────────────────────────────────────────────────────────┐ │ ③ 语义层 这些数据是什么意思怎么喂给模型 │ │ —— 像贴好标签的成品拿来就能训练 │ │ RLDS、LeRobot │ └──────────────────────────────────────────────────────────────┘一句话类比采集层是摄像机拍的原始录像存储层是录像存进什么样的硬盘格式语义层是剪辑好、打上字幕、能直接用的成片。关键认知语义层 存储层 一层约定。RLDS TFRecord存储 RL 风格的字段约定LeRobot Parquet MP4存储 目录规范一、采集层机器人的行车记录仪机器人运行时各个传感器相机、关节编码器、力传感器…不停产生数据。采集层就是把这些数据流按时间原样录下来。特点它只知道某时刻、某个数据通道、来了一条消息不懂什么是一次抓取、什么是动作。是原材料不是成品。rosbagROS 1 的录像格式维度说明是什么ROS 1 生态的标准录制格式扩展名.bag怎么工作把各个话题topic的消息按时间交错存进一个文件攒一批压缩一次优点ROS 原生、工具链成熟、能快进回放致命缺点索引在文件末尾→ 录制中途崩溃/断电索引没写成整个文件基本报废其他缺点解析强依赖 ROS 环境单文件太大后变慢消息定义一改旧文件可能读不了科普比喻像老式录像带——能录能放但你得用配套的机器ROS才能读而且录到一半停电带子可能就废了。MCAPROS 2 的现代录像格式维度说明是什么ROS 2 推荐的录制格式扩展名.mcap是 rosbag 的现代替代核心改进①文件头尾都有标记崩溃了也能抢救出已录数据 ②把消息说明书完整存进文件脱离 ROS 也能读 ③支持消息格式升级通用性不绑定 ROS能存任意数据ROS 消息、protobuf、JSON 都行是通用时序黑匣子rosbag → MCAP 的进化一句话把 rosbag 里隐式依赖 ROS 环境的东西全部显式写进文件本身从ROS 专用录像机升级成自带说明书、摔不坏的通用黑匣子。科普比喻从录像带升级到带元数据、能容错的数字视频文件。二、存储层只管怎么存字节的通用仓库采集完的原始数据经过处理时间对齐、切分回合、定义动作后需要存到硬盘反复用于训练。存储层就是存字节的技术方案。核心这一层的格式都不是机器人专用的——它们是通用工具存图像、存文本、存表格都行压根不知道机器人这回事。它们只关心一件事字节怎么摆才能存得省、读得快。四个成员按数据形状分成两类存多维数组的适合图像、张量图像天生是多维数组高×宽×通道关节序列也是帧×关节。这类数据用下面两个HDF5维度说明是什么经典科学计算格式20 年历史扩展名.h5本质把一个文件系统塞进单个文件——文件内部有文件夹Group和文件Dataset像个微型硬盘优点自带索引随机读快、自描述形状类型都在文件里、单文件好搬运、原生支持多维数组缺点不能多进程同时写、云存储S3上很慢、文件头坏了可能整个文件打不开谁在用RoboMimic、ALOHA/ACT 等大量学术数据集科普比喻一个自带目录索引的超级文件夹但整个装在一个盒子里——本地用很爽搬到云上就笨重。Zarr维度说明是什么HDF5 的云原生版本扩展名是个.zarr/文件夹本质和 HDF5 一样是数组容器但把数据切成小块chunk每块存成一个独立文件优点多进程能并行读写各写各的块、云存储友好每块是独立对象按需下载、坏一块只丢一块缺点小文件爆炸一个大数据集可能几百万个小文件拷贝/备份痛苦、生态比 HDF5 年轻HDF5 vs Zarr 一句话同样是存多维数组。HDF5 装进一个文件本地单机爽Zarr 摊开成一个文件夹、每块一个文件云端、多进程爽。科普比喻HDF5 是一整本书Zarr 是活页夹每页单独抽取——多人同时看、放云端活页夹更方便。存表格的适合状态、动作、数值关节角度、动作指令、时间戳、奖励——这些是一行一行的结构化数值更像 Excel 表。用下面这个Parquet维度说明是什么大数据领域的表格标准格式扩展名.parquet灵魂特性列式存储——同一列的数据存在一起而不是同一行存在一起为什么强①只读你要的列训练只要 action其他列碰都不碰省 I/O②压缩率极高同列同类型好压③能被 pandas/SQL 直接分析关键约定图像不放 Parquet会破坏列式优势图像另存视频用frame_index列关联谁在用LeRobot 的数值部分就是 Parquet列式存储是唯一需要理解的概念科普可以这样讲传统表格按行存一个人的所有信息挨在一起。Parquet 按列存所有人的年龄挨在一起、所有人的身高挨在一起。好处你只想统计平均年龄只需读年龄这一列不用把每个人的全部信息都翻出来。TFRecord存线性记录流比较特殊维度说明是什么Google 为 TensorFlow 造的通用序列化格式扩展名.tfrecord本质一串首尾相接的记录每条 一段带校验的字节简单粗暴特点适合顺序流式读、天然可分片并行但无内建索引随机读慢、只支持 3 种数据类型地位它是RLDS 的地基——RLDS 就是在 TFRecord 上加语义盖起来的科普比喻像一长串首尾相连的数据信封一个接一个拆——适合从头到尾顺着读不适合直接翻到第 500 个。存储层四格式速查表格式数据模型最擅长落盘方式机器人里存什么TFRecord线性记录流顺序读、分片单/多文件整条样本打包HDF5单文件树数组本地、自包含单文件图像状态一锅端Zarr文件夹数组云端、并行多文件夹大规模图像/张量Parquet列式表格选择性读列、分析单文件数值(状态/动作)三、语义层贴好标签、能直接训练的成品存储层只是把字节存下来但它不知道哪个字段是观测、哪个是动作、一个回合从哪到哪、这个任务是什么。语义层就是在存储层之上加一套约定把裸数据变成有意义、能直接喂给模型的训练数据集。两条路线哲学相反RLDSGoogle 路线维度说明是什么Reinforcement Learning DatasetsGoogle 的规范 加载库建在谁上TFRecord数据模型嵌套数据集 → 一串回合(episode) → 每回合一串步(step)回合边界靠每帧的is_first/is_last标记位来逻辑地切分图像存法每帧 JPEG 塞进记录里无跨帧压缩生态TensorFlow / JAX适合超大规模、TPU 训练血统强化学习自带折扣因子等 RL 字段代表OXEOpen X-Embodiment、RT-1、RT-2LeRobotHuggingFace 路线维度说明是什么HuggingFace 主推的机器人数据集规范建在谁上Parquet数值 MP4图像 JSONL元数据数据模型扁平一行一帧一个回合一个 Parquet 文件回合边界靠文件切分换文件换回合直观图像存法编码成 MP4 视频利用帧间相似性更省空间贴心设计内置归一化统计量(stats)、fps 等拿来即训可读性JSON/Parquet 能直接打开看、视频能直接播放调试友好生态PyTorch / HuggingFace社区上手快LeRobot 的目录结构科普时可展示franka_pick_dataset/ ├── meta/ ← 说明书有哪些字段、每回合多长、任务是什么、归一化统计量 ├── data/ ← 数值Parquet状态、动作、奖励、时间戳 └── videos/ ← 图像MP4相机画面三个分区一目了然说明书 数值 画面用frame_index把数值和画面对齐。RLDS vs LeRobot 终极对照RLDSLeRobot存储地基TFRecordParquet MP4 JSONL数据模型嵌套(回合套步)扁平(一行一帧)回合边界is_first/is_last标记文件切分图像JPEG 塞记录(无跨帧压缩)MP4 视频(跨帧压缩更省)可读性❌ 二进制要写代码✅ 直接看可视化方便归一化❌ 自己算✅ 内置生态TensorFlow/JAXPyTorch/HuggingFace血统强化学习模仿学习/监督学习代表OXE、RT 系列HuggingFace 生态、众多开源 VLA一句话总结两条路线RLDS 走Google/TensorFlow/大规模路线OXE 用它LeRobot 走HuggingFace/PyTorch/可读易上手路线社区新宠。如今常把 OXE 数据转成 LeRobot用 PyTorch 训——两者实践中会互转。四、贯穿始终的两个共同智慧科普加分点讲完七个格式有两个设计思想反复出现点出来能让科普更有深度1. “自描述”——把说明书装进数据本身好格式都在做同一件事不依赖外部文档把这数据长什么样写进文件自己。MCAP 内嵌消息 schema、HDF5 内嵌形状类型、Zarr 有zarr.json、Parquet 有 Footer、RLDS 有dataset_info、LeRobot 有info.json科普讲法好的数据格式像自带说明书的家具——不用另找图纸拆开箱子说明书就在里面。2. “chunk”分块——但两层含义不同别混chunk块这个词在两层都出现但意思不一样这是初学者最容易混的点采集层(rosbag/MCAP) 的 chunk 一批消息打包 沿时间切 存储层(HDF5/Zarr) 的 chunk 大数组切成瓷砖 沿数据维度切记忆口诀采集层的块沿时间切消息存储层的块沿维度切数组。五、实用速查我该用哪个按场景选你的场景推荐ROS 机器人实时采集MCAPROS 2/ rosbagROS 1PyTorch 训练、想快速上手、要常看数据LeRobotTensorFlow/JAX、超大规模、混合多数据集RLDS本地单机、数据不太大、要方便拷贝HDF5云端(S3/GCS)、多进程、超大规模Zarr只存数值做分析/统计Parquet后训练实习生的够用就好版认知做后训练你 90% 的时间面对的是LeRobot或RLDS因为你拿到的是别人处理好的训练数据。看到RLDS→ 想到OXE 那套、TensorFlow、for episode: for step读”看到LeRobot→ 想到HuggingFace 那套、PyTorch、meta/ data/ videos/目录、dataset[i]取帧底层的 TFRecord/Parquet/HDF5/Zarr知道是什么、谁是谁的地基即可一般不用手动碰。rosbag/MCAP 是采集端的事除非你要从原始数据做转换否则接触不多。六、七格式一句话总表终极速查层格式一句话① 采集rosbagROS 1 录像带能录能放但摔了(崩溃)容易废① 采集MCAPROS 2 数字黑匣子自带说明书、摔不坏、还通用② 存储TFRecord一串数据信封顺着拆RLDS 的地基② 存储HDF5装进一个盒子的带索引超级文件夹本地爽② 存储Zarr摊成活页夹的 HDF5云端、多进程爽② 存储Parquet按列存的 Excel只读你要的列LeRobot 的地基③ 语义RLDSTensorFlow 路线嵌套结构OXE 用它③ 语义LeRobotPyTorch 路线目录清晰、可读易上手社区新宠附科普讲解建议的叙事线如果做一期科普视频/文章推荐这条线索由浅入深、有故事感抛问题机器人是怎么学会干活的靠喂给它海量看到什么→做什么的数据。那这些数据长什么样、存哪儿讲旅程一条数据要走三步——录下来采集→ 存起来存储→ 贴标签变教材语义。用三层图每层挑代表讲采集讲 rosbag→MCAP 的录像带进化数字黑匣子存储讲数组仓库(HDF5/Zarr) vs 表格仓库(Parquet)语义讲 RLDS vs LeRobot 两条路线之争。升华好格式的两个共同智慧——自带说明书(自描述)“和化整为零(分块)”。落地如果观众也想入门具身智能看到 LeRobot / OXE(RLDS) 这两个词心里就有底了。核心心法别陷进字节细节。科普的价值是建立地图和直觉不是背技术手册。每个格式记住它像什么、解决什么问题、谁在用就足够打动大众了。七、实战篇同一份 Franka 数据七种格式长什么样前面讲的是概念地图。这一节把地图落到具体数据——用同一个例子看每种格式的真实排布和关键参数含义。适合初学者对着摸清每个字段到底是什么。统一实验设定任务Franka Panda 机械臂从桌面抓起一个红色方块。录制相机 30 FPS我们截取3 帧一次抓取的开始/中间/抓住。这 3 帧的原始数据后面所有格式都基于它请记住这张表帧 时间(s) 7个关节角度(rad) 夹爪宽度(m) 8维动作 奖励 ────────────────────────────────────────────────────────────────────────────────────────────────────── 帧0 0.000 [0.10,-0.30, 0.00,-1.20, 0.00,1.50,0.80] 0.08 [ 0.01,-0.02,-0.01,0,0,0, 0.0,0] 0.0 帧1 0.033 [0.15,-0.35,-0.05,-1.10, 0.02,1.45,0.75] 0.08 [ 0.00, 0.00,-0.02,0,0,0,-0.03,0] 0.0 帧2 0.066 [0.20,-0.40,-0.10,-0.90, 0.05,1.40,0.70] 0.02 [ 0.00, 0.05, 0.10,0,0,0, 0.0,0] 1.0 ↑抓住了 ↑成功给奖励每个字段/参数的物理含义这是初学者最该搞懂的部分字段形状含义关键点图像 image(480,640,3)相机 RGB 画面高480×宽640×3通道每个像素 0~255 的 uint8这是模型的眼睛关节角度 joint_positions(7,)Franka 有 7 个可转动关节每个的当前角度弧度Franka 是7 自由度机械臂所以是 7 个数夹爪宽度 gripper_width(1,)两指张开的距离米0.08全张开0.02夹住了方块动作 action(8,)告诉机器人下一步怎么动见下方拆解 ↓奖励 reward(1,)这一步做得好不好RL 用抓住瞬间给 1.0其余 0.0时间戳 timestamp(1,)这一帧的时刻秒用于对齐图像和数值8 维动作 action 拆解初学者常问这 8 个数是啥action [ dx, dy, dz, droll, dpitch, dyaw, gripper, pad ] └───┬────┘ └────────┬─────────┘ └──┬──┘ └┬┘ 末端位置增量 末端姿态增量 夹爪指令 补位 (往哪移动,米) (怎么转动,弧度) (开/合) (凑够8维) 例: 帧2的 [0, 0.05, 0.10, 0,0,0, 0.0, 0] 末端往 y 方向移 0.05m、往 z 方向(上)提 0.10m(把方块提起来)、姿态不变概念补充为什么动作是增量(delta)“而不是绝对位置”大多数具身策略输出的是相对当前位置移动多少如 dz0.10 表示往上抬 10cm而不是移动到坐标 (0.3, 0.2, 0.5)“。因为相对量更好学、更泛化。这类动作空间叫末端笛卡尔增量控制 (delta end-effector control)是 OXE、LeRobot 里最常见的一种。你也会遇到绝对关节角度”绝对末端位姿等其他动作空间——看数据第一件事就是搞清楚 action 的每一维是什么。逐格式看排布① rosbag / MCAP采集层——按时间交错的消息流采集层不认识帧“动作”它只有某时刻、某话题、一条消息。同样这 3 帧在 MCAP 里是这样按时间铺开的pick.mcap (话题: /camera 图像, /joint_states 关节) 时间轴 → t0.000 /camera → 一帧图像(480×640×3) t0.000 /joint_states → position[0.10,-0.30,0.00,-1.20,0.00,1.50,0.80] t0.033 /camera → 一帧图像 t0.033 /joint_states → position[0.15,-0.35,-0.05,-1.10,0.02,1.45,0.75] t0.066 /camera → 一帧图像 t0.066 /joint_states → position[0.20,-0.40,-0.10,-0.90,0.05,1.40,0.70]关键观察 / 参数含义概念含义初学者注意topic话题一个数据通道如/camera、/joint_states不同传感器 不同 topic消息按时间交错图像和关节不是分开存是按时间戳穿插和整齐的表格完全不同这里没有 action采集时只有状态没有动作动作是后期算出来的如下一帧关节 − 当前帧关节或记录遥操作指令时间戳可能不齐相机 30Hz、关节可能 1000Hz频率不同转成训练数据时要做时间对齐给每帧图像配上最近的关节这就是采集层→存储层要做的转换把交错的消息流对齐时间、切好回合、算出动作整理成下面那种整齐的结构。② HDF5存储层——装进一个文件的树3 帧数据在 HDF5 里按树形组织一个 episode 一个 Groupfranka_pick.h5 │ 【根属性 Attribute】 │ robot_type franka_emika_panda │ fps 30 │ └─ episode_0/ ← Group这次抓取 │ task pick up the red block │ success true │ ├─ observations 形状(3, 480, 640, 3) 类型uint8 ← 3帧图像 ├─ joint_positions 形状(3, 7) 类型float32 ← 3帧×7关节 ├─ gripper_width 形状(3,) 类型float32 ← [0.08, 0.08, 0.02] └─ actions 形状(3, 8) 类型float32 ← 3帧×8维动作关键参数含义参数值含义形状 shape如 (3, 7)第一维 3帧数第二维 7关节数。读懂 shape 就读懂了数据维度类型 dtypeuint8 / float32图像用 uint8(0~255省空间)数值用 float32Groupepisode_0相当于文件夹一个回合一个Attributefps30挂在树节点上的小标签存元信息chunk分块常设 (1,480,640,3)一帧一块随机读某帧时只解压那一块读法file[episode_0/actions][2]→ 直接拿到帧2的动作[0,0.05,0.10,...]。③ Zarr存储层——摊成文件夹每块一个文件同样的数据Zarr 把每个数组切块存成独立文件franka_pick.zarr/ ├── zarr.json ← 根说明书(JSON纯文本,可直接打开) │ {attributes: {robot:franka, fps:30}} │ ├── observations/ │ ├── zarr.json ← 这个数组的说明书 ↓ │ │ {shape:[3,480,640,3], data_type:uint8, │ │ chunk_grid:{chunk_shape:[1,480,640,3]}, ← 一帧一块 │ │ codecs:[{name:blosc}]} ← 压缩方式 │ └── c/ │ ├── 0/0/0/0 ← 帧0的图像(独立文件) │ ├── 1/0/0/0 ← 帧1 │ └── 2/0/0/0 ← 帧2 │ ├── joint_positions/ (shape[3,7]) c/0/0, c/1/0, c/2/0 ├── actions/ (shape[3,8]) c/0/0, c/1/0, c/2/0 └── gripper_width/ (shape[3]) c/0关键参数含义参数含义和 HDF5 的区别zarr.json每个数组的说明书JSON 明文HDF5 藏在二进制里Zarr 直接可读shape / data_type同 HDF5形状 类型一样chunk_shape[1,480,640,3]每块的大小一帧决定切成几个文件codecs: blosc压缩算法blosc 很快—文件名c/2/0/0/0chunk 的坐标第2帧、其余维第0块每块是独立文件这是 Zarr 的灵魂④ Parquet存储层——列式表格注意不存图像数值部分状态/动作/奖励用 Parquet是一张表。图像不在这另存视频franka_pick.parquet → 逻辑上就是一张表 timestamp frame_index observation.state action next.reward 0.000 0 [0.10,-0.30,...,0.80] [0.01,-0.02,...,0.0] 0.0 0.033 1 [0.15,-0.35,...,0.75] [0.00, 0.00,...,-0.03] 0.0 0.066 2 [0.20,-0.40,...,0.70] [0.00, 0.05,...,0.0] 1.0 物理上按列存(列式) timestamp列: [0.000, 0.033, 0.066] ← 挨在一起 action列: [[...],[...],[...]] ← 挨在一起 reward列: [0.0, 0.0, 1.0] ← 挨在一起关键参数含义参数含义为什么重要列式存储同列数据物理相邻训练只要 action 列时其他列不用读observation.state就是 7 个关节角度LeRobot 里习惯叫observation.stateframe_index帧号 0,1,2关键用它去视频里找对应帧无图像列图像另存 MP4图像放表里会毁掉列式压缩优势⑤ LeRobot语义层——Parquet MP4 JSONL 拼成完整数据集这是初学者实际最常拿到的格式。完整目录franka_pick_dataset/ │ ├── meta/ ← 说明书区 │ ├── info.json ← schema有哪些字段、形状、fps │ ├── episodes.jsonl ← 回合索引每回合多长、什么任务 │ ├── tasks.jsonl ← 任务表语言描述 │ └── stats.json ← 归一化统计量mean/std │ ├── data/chunk-000/ │ └── episode_000000.parquet ← 数值(上面④那张表) │ └── videos/chunk-000/observation.images.cam_high/ └── episode_000000.mp4 ← 3帧图像编码成的视频四个 meta 文件的实际内容 参数含义info.jsonschema 说明书{robot_type:franka_emika_panda,fps:30,features:{observation.state:{dtype:float32,shape:[7],names:[joint_1,...,joint_7]},←7关节,每维有名字action:{dtype:float32,shape:[8]},←8维动作observation.images.cam_high:{dtype:video,← 注意是video!shape:[480,640,3]}← 表示去MP4取}}episodes.jsonl每行一个回合{episode_index: 0, tasks: [pick up the red block], length: 3}→length:3 这回合 3 帧episode_index:0对应episode_000000.*文件。stats.json归一化统计训练直接用{observation.state:{mean:[0.15,-0.35,-0.05,-1.07,0.02,1.45,0.75],←7关节各自的均值std:[0.04,0.04,0.04,0.12,0.02,0.04,0.04]← 各自的标准差}}→ 训练时归一化后 (原值 − mean) / std让数据分布规整模型好学。一帧是怎么被拼出来的初学者关键想要帧2的完整数据 ① 从 episode_000000.parquet 第2行读: state[0.20,...], action[0,0.05,0.10,...], reward1.0, frame_index2 ② info.json说 cam_high 是video → 去 episode_000000.mp4 解码第2帧 → 得到图像 ③ 拼成: {观测图像 observation.state action} → 喂给模型 └─ 图像来自MP4数值来自Parquet靠 frame_index2 对齐关键参数速查参数含义fps帧率30 表示每秒 30 帧features数据集的 schema声明每个字段的 dtype/shapedtype: “video”该字段图像存在 MP4 里不在 Parquetlength一个回合有多少帧mean / std归一化用的均值和标准差frame_index缝合 Parquet 数值 和 MP4 画面 的帧号⑥ RLDS语义层——嵌套结构OXE 那套同样数据在 RLDS 里是回合套步的嵌套结构一个步(step)长这样# 一个 episode 3 个 step 的序列下面是帧0的 stepstep_0{observation:{image:(480,640,3)uint8,# 相机joint_positions:[0.10,-0.30,0.00,-1.20,0.00,1.50,0.80],gripper_width:0.08,},action:[0.01,-0.02,-0.01,0,0,0,0.0,0],# 8维动作reward:0.0,discount:1.0,# RL折扣因子(RLDS特有)is_first:True,← 这是回合第一帧 ┐ 回合边界is_last:False,← 不是最后一帧 ┘ 靠标记位表示language_instruction:pick up the red block,}关键参数含义重点看和 LeRobot 的差异参数含义和 LeRobot 对比observation嵌套字典观测里再分 image/joint/gripperLeRobot 是扁平的一行is_first / is_last标记回合的第一帧/最后一帧RLDS 靠标记位切回合LeRobot 靠文件切discountRL 折扣因子(未来奖励打折)LeRobot 没有(它偏模仿学习)图像JPEG 直接塞进记录LeRobot 用 MP4(跨帧压缩更省)读法for episode: for step:双层循环LeRobot 是dataset[i]取帧七格式实例总览同一份 Franka 数据格式3帧数据的组织形态action 在哪图像在哪回合边界怎么表示MCAP按时间交错的消息流❌ 采集时没有,后期算/camera 话题无(采集层不分回合)HDF5树: episode_0/{obs,joints,actions}actions 数组(3,8)observations 数组Group 分组Zarr文件夹: 每数组切块成文件actions/c/*observations/c/*Group 目录Parquet一张表(列式)action 列❌ 不存(另存视频)(单文件单回合)LeRobotmetadata(parquet)videos(mp4)Parquet 的 action 列MP4 视频一回合一组文件RLDS嵌套: episode→steps每个 step 的 actionJPEG 塞进 stepis_first/is_last 标记给初学者的三条实操建议拿到任何数据先看三样东西action每一维是什么增量?绝对?、observation有哪些几个相机?有没有本体状态?、回合怎么切分。搞懂这三样数据就通了。shape 是你的路标看到(T, 7)就知道 T 帧、7 个关节(T,480,640,3)就知道是图像序列。读 shape 读结构。归一化统计量(mean/std)别忽略训练前几乎都要归一化LeRobot 直接给了(stats.json)RLDS/裸 HDF5 可能要自己算。数据量纲不统一模型很难训。总结这一节概念地图 具体实例 真正看懂数据。下次你打开一个 LeRobot 或 OXE 数据集对照这里的 Franka 例子每个字段、每个参数就都对得上号了。