ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

机器人数据飞轮实战:从数据采集到模型训练全流程

机器人数据飞轮实战:从数据采集到模型训练全流程 从 Figure 的“人类数据采集计划”说起机器人领域最近最热的已经不是单纯的硬件堆料而是“数据从哪里来”。Figure 通过全球征集人类远程操作数据的方式把大量真实操作过程变成可训练样本本质上是为具身智能搭建数据飞轮。这个方向对机器人开发者、AI 工程师和数据工程团队都有很强的参考价值。这篇文章会从数据飞轮的概念讲起拆解机器人数据采集、格式化、增强和训练落地的完整链路并给出一套可运行的最小工程示例帮助你把“给机器人囤数据”这件事从思路变成代码。1. 背景与核心概念为什么机器人需要“囤数据”1.1 Figure 的悬赏逻辑与数据飞轮先来看新闻本身。Figure 这家做人形机器人的公司公开招募人类通过远程操作设备“干活”并为此付费。参与者需要穿戴或操作专门的遥操作设备控制机器人完成抓取、放置、移动、开门等日常任务。Figure 收集这些操作过程中的动作序列、关节角度、图像与力反馈信息然后用于训练机器人的视觉-语言-动作模型。这套逻辑在行业内被称为“数据飞轮”人类远程操作产生高质量示范数据。数据被清洗、增强并送入大模型训练。模型能力提升后机器人能够在更多场景中自主完成任务。自主任务过程中又会产生新的数据继续进入训练流程。Figure 的“悬赏”只是这个飞轮的启动阶段。它解决的是最核心的问题高质量操作数据从哪里来。1.2 为什么数据是具身智能的瓶颈过去几年自然语言大模型的突破很大程度上依赖于互联网海量文本。但机器人领域没有现成的“互联网操作数据”。一个机器人要学会“拿起杯子”需要知道杯子在图像中的位置。机械臂以什么轨迹靠近。手指施加多大的力。拿起之后移动到什么位置。过程中遇到阻碍如何调整。这些数据涉及高维连续动作空间只靠真实世界中的传感器采集效率很低互联网上也根本不存在现成数据集。因此当前具身智能的核心矛盾就是“模型能力增长”和“高质量操作数据供给不足”之间的矛盾。从工程角度说围绕数据采集、清洗、增强、存储、训练建立一条完整流水线就是每位机器人算法工程师需要面对的核心课题。1.3 机器人数据采集和普通数据标注的区别很多人会把机器人数据采集理解成传统的数据标注工作比如给图片打框、给文本分类。实际上两者差别非常大维度传统数据标注机器人操作数据采集数据形式图片、文本、语音图像序列 关节角度 力觉 状态标注方式人工打标签遥操作采集真机动作动作维度离散标签高维连续运动轨迹质量要求类别正确动作平滑、安全、任务完整数据成本相对较低非常高依赖硬件和人力最关键的区别是机器人操作数据是“时序连续动作”的组合不只是“是什么”还包括“怎么动”。这决定了数据采集和后处理需要专门的设计。2. 机器人数据流水线整体架构2.1 四层架构总览把“囤数据”这件事工程化我通常会拆成四层数据采集层负责通过遥操作、自动脚本或仿真环境生成原始数据。数据处理层负责格式标准化、清洗、对齐、去重。数据增强层负责扩充样本、提升泛化能力。模型训练层负责把数据送入行为克隆、强化学习或 VLA视觉-语言-动作模型。把四层串起来就是一条典型的机器人数据流水线数据采集遥操作/仿真 ↓ 数据标准化统一格式、单位、坐标 ↓ 数据清洗去异常帧、对齐时间戳 ↓ 数据增强平移/旋转/亮度扰动 ↓ 模型训练行为克隆 / 强化学习 ↓ 模型部署真机/仿真验证每一层都有独立的技术选型和优化空间下文逐一展开。2.2 数据从采集到训练的关键路径我们再细致一点看一段数据从机械臂上“出生”到进入模型需要经过哪些环节传感器读数是多路并发的关节角度来自控制器图像来自摄像头力觉来自力矩传感器。这些传感器频率不一致需要先做时间戳对齐。不同坐标系的转换比如相机坐标到基坐标的变换矩阵。数据保存成标准格式目前社区常用的包括 HDF5、JSONL、Zarr。训练前需要定义动作空间例如末端位姿增量还是关节绝对角度。数据进入数据集管理平台划分训练集/验证集/测试集。每一步处理不到位都会直接影响最终模型的表现。这也是为什么很多团队“模型代码写得不错但训练出来效果很差”——问题往往出在数据链路里。2.3 主流采集方式对比按照成本和数据质量的权衡机器人数据采集大致有四种路径采集方式数据质量成本适用场景人工遥操作真机高真实物理反馈高精细操作、真实场景仿真环境自动采集中存在 sim-to-real 差距低大规模预训练、探索自动化脚本采集真机中高中重复性流程人类行为捕捉动捕/穿戴设备高自然度高高人形机器人动作学习Figure 的悬赏模式属于第一种和第四种的结合人类穿戴遥操作设备用自己的自然动作控制机器人生产的数据同时具备自然性和真实物理反馈。对大多数开发者来说没有 Figure 那样的硬件条件也可以用仿真环境加上开源机械臂搭建一个简化版。3. 环境准备与软件栈选型3.1 硬件场景本文的实战示例以“简化版数据流水线”为目标不需要真实机械臂也能跑通逻辑。但如果你手头有真实机械臂推荐具备以下条件带有关节角度读取功能的机械臂如常见的 6 轴协作机械臂。RGB-D 深度相机或普通 RGB 相机。支持遥操作的示教器或 SpaceMouse、VR 手柄等输入设备。一台 GPU 服务器用于训练。如果暂时没有机械臂也没有关系示例中会用一个“虚拟数据模拟器”来生成动作数据方便你完整跑通整套代码逻辑。3.2 软件依赖版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路。核心依赖如下Python 3.9NumPyOpenCVJSON 标准库或 PyYAMLh5py用于保存数据集PyTorch用于训练示例pandas用于数据管理示例安装命令pip install numpy opencv-python h5py torch pandas如果你使用 ROS2 环境还需要安装 ROS2 相关的 Python 包但本文的核心逻辑不依赖 ROS2方便没有机器人环境的同学理解。3.3 目录规划建议按下面的目录结构组织项目robot_data_pipeline/ ├── collect.py # 数据采集入口 ├── convert.py # 数据标准化转换 ├── augment.py # 数据增强 ├── train.py # 简化训练脚本 ├── dataset/ # 原始数据存放目录 ├── processed/ # 处理后的数据目录 └── models/ # 模型保存目录代码结构清晰之后后续扩展新传感器、新数据集都会更方便。4. 核心模块拆解从采集到训练4.1 遥操作数据采集模块数据采集模块的职责是把“一次操作过程”完整记录下来。一次操作过程包含几个关键字段timestamp每条数据的时间戳。joint_positions机械臂关节角度是连续动作的核心。ee_pose末端执行器位姿。force_torque力觉信息部分场景需要。rgb_image视觉信息图像帧。action_label这个操作属于什么任务例如“拿起杯子”“开门”。从工程角度看采集端最重要的是保证同步性。机械臂控制频率常见为 50Hz 到 100Hz图像帧率常见为 30fps。如果不对齐就会出现“图像看到的和关节动作不匹配”的问题这对训练是致命的。下面是一个简化版的数据采集脚本框架# 文件路径robot_data_pipeline/collect.py 模拟数据采集脚本。 真实环境中你需要替换 read_joint_positions() 和 read_camera_frame() 为 机械臂 SDK 和相机 SDK 的读取函数。 import json import time import numpy as np from pathlib import Path # 模拟读取机械臂关节角度 def read_joint_positions(): return np.random.rand(6) * 2 - 1 # 6轴机械臂范围归一化 # 模拟读取相机图像这里生成一个带噪点的灰度图 def read_camera_frame(): return np.random.randint(0, 255, (240, 320, 3), dtypenp.uint8) def collect_episode(episode_id, num_frames200, save_dirdataset): save_dir Path(save_dir) / fepisode_{episode_id} save_dir.mkdir(parentsTrue, exist_okTrue) images [] states [] start_time time.time() for i in range(num_frames): joint_pos read_joint_positions() image read_camera_frame() states.append({ timestamp: time.time() - start_time, joint_positions: joint_pos.tolist(), action: joint_pos.tolist(), # 在行为克隆中动作与状态维度对齐 task: pick_place }) images.append(image) # 控制采样频率约 20Hz time.sleep(0.05) # 保存状态数据 with open(save_dir / states.json, w) as f: json.dump(states, f, indent2) # 保存图像数据 np.savez_compressed(save_dir / images.npz, imagesnp.array(images)) print(fEpisode {episode_id} 已保存帧数: {num_frames}) return len(images) if __name__ __main__: collect_episode(episode_id1, num_frames200)这段代码演示了采集过程中的核心思路按固定频率记录状态和图像保存为独立文件夹。真实项目中read_joint_positions()需要改成机械臂 SDK 的实时读取接口比如通过 ROS2 topic 订阅joint_states相机帧则从相机话题订阅。4.2 数据格式标准化采集到的原始数据是“一组文件夹 多个文件”的形态不同传感器还可能来自不同设备因此需要拆解成标准格式。标准化的意义有两点统一数据结构方便后续训练代码读取。对时间戳进行对齐过滤掉缺失帧。当前具身智能社区比较常见的做法是将一组 episode 保存为一个 HDF5 文件内部结构类似episode_1.h5 ├── /observations │ ├── /joint_positions (T, 6) float │ └── /rgb (T, H, W, 3) uint8 ├── /actions │ └── /joint_positions (T, 6) float └── /meta └── task string转换脚本如下# 文件路径robot_data_pipeline/convert.py 将采集目录中的 states.json 和 images.npz 转换为 HDF5 格式。 import json import numpy as np import h5py from pathlib import Path def convert_episode(episode_dir, output_dir): episode_dir Path(episode_dir) output_dir Path(output_dir) output_dir.mkdir(parentsTrue, exist_okTrue) # 读取状态 with open(episode_dir / states.json, r) as f: states json.load(f) # 读取图像 images np.load(episode_dir / images.npz)[images] joint_positions np.array([s[joint_positions] for s in states]) actions np.array([s[action] for s in states]) task states[0][task] episode_id episode_dir.name.split(_)[-1] h5_path output_dir / fepisode_{episode_id}.h5 with h5py.File(h5_path, w) as h5: obs_group h5.create_group(observations) obs_group.create_dataset(joint_positions, datajoint_positions) obs_group.create_dataset(rgb, dataimages, compressiongzip) action_group h5.create_group(actions) action_group.create_dataset(joint_positions, dataactions) meta_group h5.create_group(meta) meta_group.create_dataset(task, datatask.encode(utf-8)) print(f转换完成: {h5_path}数据形状 joint: {joint_positions.shape}, rgb: {images.shape}) return h5_path if __name__ __main__: convert_episode(dataset/episode_1, processed)转换后训练代码可以通过 h5py 直接读取不需要再关心原始采集文件的组织方式。这里使用的 HDF5 格式适合小型数据集当数据规模更大时可以参考社区广泛使用的“数据集管理系统 流式读取”方案不再把所有数据一次性加载进内存。4.3 数据清洗与增强数据清洗是容易被忽略但极其重要的环节。原始采集数据中常见的问题包括时间戳错乱导致帧顺序颠倒。出现操作中断、机械臂急停等异常帧。图像全黑或过曝。动作重复、静止帧过多。清洗手段包括按时间戳重排、剔除连续重复帧、人工回放检查。对于图像可以做亮度异常检测。数据增强则是缓解数据量不足的最直接手段。机器人操作数据可以采用如下增强策略图像颜色扰动调整亮度、对比度。图像噪声添加高斯噪声模拟传感器噪声。动作空间平移对关节角度增加小幅随机噪声。时间轴缩放对整段轨迹做时间拉伸。增强脚本示例如下# 文件路径robot_data_pipeline/augment.py 对单条 episode 做数据增强。 import numpy as np import h5py from pathlib import Path def add_random_noise_to_joints(joint_data, noise_std0.01): noise np.random.normal(0, noise_std, joint_data.shape) return joint_data noise def adjust_brightness(image, factorNone): if factor is None: factor np.random.uniform(0.8, 1.2) return np.clip(image * factor, 0, 255).astype(np.uint8) def augment_h5(input_h5_path, output_h5_path): with h5py.File(input_h5_path, r) as src: joints src[observations/joint_positions][:] rgb src[observations/rgb][:] actions src[actions/joint_positions][:] task src[meta/task][()].decode(utf-8) # 增强关节噪声 图像亮度扰动 joints_aug add_random_noise_to_joints(joints) actions_aug add_random_noise_to_joints(actions) rgb_aug np.stack([adjust_brightness(img) for img in rgb]) with h5py.File(output_h5_path, w) as dst: obs_group dst.create_group(observations) obs_group.create_dataset(joint_positions, datajoints_aug) obs_group.create_dataset(rgb, datargb_aug, compressiongzip) action_group dst.create_group(actions) action_group.create_dataset(joint_positions, dataactions_aug) meta_group dst.create_group(meta) meta_group.create_dataset(task, datatask.encode(utf-8)) print(f增强完成: {output_h5_path}) if __name__ __main__: augment_h5(processed/episode_1.h5, processed/episode_1_aug.h5)注意增强操作要按需谨慎使用。动作噪声过大反而会让模型学到抖动策略图像增强幅度过大也会引入失真。实际项目中建议先做小规模 A/B 实验确认增强确实提升了模型在验证集上的表现后再扩大增强规模。4.4 行为克隆训练模型示例有了数据就可以开始训练。这里给出一个最简化的行为克隆模型它做的事是输入当前状态关节角度 图像特征。输出下一个动作关节角度增量。真实 VLA 模型结构非常复杂本文示例只说明数据读取与训练的接口关系。# 文件路径robot_data_pipeline/train.py 简化版行为克隆训练脚本。 仅演示数据读取和训练流程真实场景请替换为更强大的网络结构。 import torch import torch.nn as nn import numpy as np import h5py from pathlib import Path class BCAgent(nn.Module): def __init__(self, input_dim6, hidden_dim64, output_dim6): super().__init__() self.net nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, output_dim) ) def forward(self, x): return self.net(x) def load_h5_data(h5_path): with h5py.File(h5_path, r) as h5: states h5[observations/joint_positions][:] actions h5[actions/joint_positions][:] return states, actions def train_loop(model, dataloader, epochs50, lr1e-3): optimizer torch.optim.Adam(model.parameters(), lrlr) loss_fn nn.MSELoss() model.train() for epoch in range(epochs): total_loss 0.0 for state, action in dataloader: optimizer.zero_grad() pred model(state) loss loss_fn(pred, action) loss.backward() optimizer.step() total_loss loss.item() if (epoch 1) % 10 0: print(fEpoch {epoch 1}/{epochs}, Loss: {total_loss:.4f}) def main(): states, actions load_h5_data(processed/episode_1_aug.h5) # 简单封装为 PyTorch 数据集 states_t torch.tensor(states, dtypetorch.float32) actions_t torch.tensor(actions, dtypetorch.float32) dataset torch.utils.data.TensorDataset(states_t, actions_t) dataloader torch.utils.data.DataLoader(dataset, batch_size32, shuffleTrue) model BCAgent(input_dim6, output_dim6) train_loop(model, dataloader, epochs100) Path(models).mkdir(exist_okTrue) torch.save(model.state_dict(), models/bc_agent.pt) print(模型已保存到 models/bc_agent.pt) if __name__ __main__: main()在真实项目中输入通常要包含图像特征、机器人状态、语言指令等多个模态输出也可能是高维动作 token。但无论模型多复杂“读数据-算损失-反向传播-保存权重”这条链路是不变的。4.5 数据规模对模型效果的影响最后补充一个工程经验机器人操作数据的“质量”比“数量”重要得多。100 条高质量、多样化、覆盖不同初始位置和光照条件的操作轨迹训练效果往往好于 1000 条单一场景的重复轨迹。这也是 Figure 选择“全球悬赏”而不是“内部机器自动采集”的一个原因人类操作能自然覆盖更多边缘场景比如物体被遮挡、光线变化、桌面杂乱等。数据增强可以部分弥补数量不足但不能完全替代真实世界数据的多样性。5. 完整实战搭建一个最小可运行的数据流水线5.1 创建项目结构现在把上面的模块串起来完整执行一遍。首先创建项目目录mkdir robot_data_pipeline cd robot_data_pipeline mkdir dataset processed models将上文的collect.py、convert.py、augment.py、train.py分别放入项目根目录。5.2 执行数据采集运行采集脚本生成模拟数据python collect.py预期输出类似Episode 1 已保存帧数: 200同时项目下会产生dataset/episode_1/ ├── states.json └── images.npz5.3 执行数据转换运行转换脚本python convert.py预期输出类似转换完成: processed/episode_1.h5数据形状 joint: (200, 6), rgb: (200, 240, 320, 3)这代表 200 帧的关节数据形状为(200, 6)图像数据形状为(200, 240, 320, 3)。5.4 执行数据增强运行增强脚本python augment.py预期输出增强完成: processed/episode_1_aug.h5为了让训练更稳定可以考虑把多个 episode 的数据合并成一个数据集文件。合并逻辑和单文件转换类似只是在创建 HDF5 时需要按 episode 分组或者直接拼接为一个大数组。5.5 执行训练运行训练脚本python train.py预期输出类似Epoch 10/100, Loss: 0.2040 Epoch 20/100, Loss: 0.1102 ... Epoch 100/100, Loss: 0.0187 模型已保存到 models/bc_agent.pt这个示例中的 Loss 只反映了模拟数据的拟合情况。真实机械臂数据由于包含复杂物理交互Loss 不会下降得这么平滑需要更大模型、更多数据和更细致的特征工程。5.6 数据可视化与检查建议在训练前对数据做可视化检查。可以用下面这段代码快速回放一条 episodeimport h5py import cv2 import numpy as np with h5py.File(processed/episode_1.h5, r) as h5: rgb h5[observations/rgb][:] joints h5[observations/joint_positions][:] for i in range(len(rgb)): frame rgb[i] cv2.putText(frame, fjoint: {joints[i][:3].round(2)}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imshow(Episode Replay, frame) if cv2.waitKey(50) 0xFF ord(q): break cv2.destroyAllWindows()回放时重点检查以下几点关节角度是否连续平滑。图像是否出现全黑或花屏。动作和画面是否匹配。是否存在长时间静止帧。只有通过人工抽查的数据才值得送入训练流程。这也是 Figure 这类数据计划中“人对数据质量负责”的重要原因。6. 常见问题与排查思路在机器人数据采集与训练流水线中我整理了几个高频问题方便你按表排查问题现象常见原因解决思路采集数据时间戳错乱多个传感器线程未同步使用统一时钟源加硬件同步或软件时间戳校准模型训练 Loss 不下降动作空间未归一化或数据质量差检查数据范围做标准化人工回放数据样本图像全黑/花屏相机参数错误或曝光异常检查相机 SDK 返回数据打印图像均值与方差关节角度有明显跳变机械臂通讯丢包检查控制器网络增加滤波与插值真机验证效果差仿真与真实数据分布差距大优先增加真实数据比例使用域随机化数据增强后动作抖动动作噪声设置过大降低噪声标准差对比增强前后验证集效果训练数据量太大内存溢出一次性加载全部数据使用流式读取、torch Dataset 按需加载排查时建议遵循“先数据、后模型”的顺序。很多训练问题表面看是模型结构或超参数问题实际根因是数据里存在脏数据。先把数据集可视化检查一遍往往能省下大量调参时间。7. 最佳实践与工程建议7.1 数据版本管理机器人数据流水线中的数据集和模型一样需要版本管理。建议为每个数据集记录采集日期、采集设备、采集人。任务类型、场景描述。传感器标定参数。数据清洗与增强操作记录。数据集划分方式。这些信息可以写在数据集目录下的metadata.yaml中。数据版本化管理能够帮助团队复现实验也方便后续回溯“某个模型效果提升是因为数据还是模型”。dataset_name: pick_place_v1 collect_date: 2025-06-01 device: arm: example_6dof camera: rgb_camera teleop: spacemouse task: pick_place augmentation: joint_noise_std: 0.01 brightness_factor: [0.8, 1.2] train_val_test_split: [0.8, 0.1, 0.1]7.2 关注安全与合规涉及真人采集数据时需要考虑隐私和安全合规问题尤其是采集环境是否涉及他人隐私。操作员是否知情同意。数据是否包含敏感场所信息。机器人动作是否可能对人造成伤害。远程操作过程中必须有急停机制和安全围栏。对于企业级数据采集项目还应当在数据存储和传输中加密并严格控制访问权限。7.3 真机与仿真数据结合真实数据质量高但成本贵仿真数据成本低但存在 sim-to-real 差距。工程上推荐采用“仿真预训练 真机微调”的策略先用仿真环境大规模生成数据让模型学到基础的物体交互逻辑。再用真机遥操作数据微调修正仿真与现实的差异。真机部署后持续采集新数据进入下一轮迭代。这种模式能显著降低数据采集成本同时保证模型在真实环境的表现。7.4 建立自动化质量监控数据流水线一旦跑起来人工检查所有数据是不现实的。建议建立自动化质量监控统计每个 episode 的帧数、动作幅度、关节速度。检测异常帧全黑、爆音、关节跳变。设置数据质量分数低于阈值的自动标记为低质量。自动化监控并不能完全替代人工抽查但可以把人工精力集中在最可能出现问题的数据上。7.5 任务设计是数据质量的起点最后想强调一点数据采集开始之前先设计好任务规范。一个任务应该如何开始、成功标准是什么、失败如何处理、边界条件有哪些这些规则越清晰采集到的数据一致性越高后续训练效果也越稳定。8. 总结与下一步学习方向这篇文章从 Figure 全球悬赏人类采集数据的新闻出发拆解了机器人数据飞轮的完整工程链路采集、标准化、增强、训练。我们完整实现了一个最小可运行的机器人数据流水线包括模拟数据采集、HDF5 转换、数据增强和简化行为克隆训练并给出了常见问题排查表。如果你想继续深入这个方向建议按以下路径学习学习 ROS2 基础掌握joint_states、image_transport等机器人数据处理接口。了解主流机器人仿真平台在仿真中批量生成训练数据。研究 VLA 模型的输入输出设计理解图像、语言与动作如何融合。关注社区数据集规范参考成熟的数据集组织方式。实践真实机械臂遥操作积累真实数据采集经验。数据是具身智能时代最重要的“燃料”。Figure 用真金白银悬赏人类干活说明高质量操作数据在短期内仍然稀缺。对于开发者而言谁能先把数据流水线搭建得足够高效稳定谁就更能抓住这波机会。希望本文的代码和思路能帮你跨出第一步。如果这篇文章对你有帮助可以收藏备用。你有做机器人数据采集的项目经验吗踩过哪些数据坑欢迎在评论区交流讨论。
返回列表