1. 复现之前,先把“复现目标”说清楚
最近一直在折腾 lerobot 这个开源机器人学习框架的复现,从环境搭建到训练出自己的一个模仿学习策略,整个过程踩了不少坑,也把很多文档里没写明白的细节摸清楚了。如果你正准备复现这个项目,或者你只是想看看现在机器人操作策略训练到底怎么跑通,这篇东西应该能帮你省下至少一周的调研时间。
先说说 lerobot 到底是干嘛的。它本质上是一套面向机器人操作学习的训练和评估工具链,核心是把模仿学习、强化学习里的主流算法(比如扩散策略、ACT、VQ-BeT 等)集成到一个统一框架里,让研究者可以在仿真环境或者真实机器人上采集数据、训练策略、评估效果。复现它,其实就是把官方给出的示例流程在自己的机器上完整跑一遍:从环境配置、数据准备、模型训练,到最终看到策略能控制机器人完成某个具体操作。
在动手之前,我强烈建议你先想清楚一个问题:你要的“复现”是哪一种?我身边不少人是看了论文或视频之后热血上头,直接下载代码开始跑,结果卡在环境依赖或者数据集下载上,最后不了了之。我根据自己的实践,把复现目标分成三类:
- 目标 A:能跑通官方示例。这要求最低,主要目的是理解整个流程怎么流转,结果是否达到论文展示的效果其实不重要。
- 目标 B:换到自己的数据/场景上训练出新策略。这个你需要在数据采集、标注、训练配置上多花精力,对硬件和实验设计也有更高要求。
- 目标 C:二次开发或接入自家机器人平台。这个就不仅仅是复现了,还要理解源码中的传感器接口、策略推理逻辑、坐标变换等内部机制,工作量最大。
目标不同,后面每一步的做法和容错标准都不一样。比如目标 A 的话,你用普通的游戏显卡勉强也能跑,最多慢一些;目标 C 的话,你可能需要先在仿真环境里把逻辑吃透,再考虑真实硬件。
硬件这块,我直接说结论:复现的瓶颈通常在显存和存储,而不是 CPU。lerobot 默认采用的扩散策略,在训练时会同时加载图像观测、关节状态和动作序列,batch size 稍微调大一点,显存占用就往上蹿。官方推荐的 GPU 显存不低于 8GB,但我实测下来,如果不想频繁调整 batch size,12GB 以上会更从容。存储方面,单个仿真数据集动辄几十 GB,真实机器人采集的数据更大,所以你需要留出至少 200GB 的可用磁盘空间,并且最好是 SSD,否则数据加载会成为瓶颈。
对绝大多数人来说,最稳妥的复现路线是先在仿真环境里跑通,再考虑真实机器人。原因有两个:一是仿真环境的数据获取成本低,你可以脚本化地批量生成训练数据;二是仿真出问题时定位更方便,摄像头、机械臂的状态都能可视化查看,不用对着真实硬件束手无策。
1.1 lerobot 的核心组件与工作流程
lerobot 的代码结构不算复杂,但刚开始容易看得眼花缭乱。我用一个不太严谨但很好理解的类比:它像一个“机器人训练车间”。车间里有四个核心工位——数据仓库、模型库、训练流水线、评估与控制接口。
数据仓库负责管理各种格式的演示数据,官方会提供一个命令行工具把原始数据转换成统一的存储格式;模型库里预置了多个策略网络结构,你不需要自己从零写模型;训练流水线封装了数据加载、batch 采样、损失计算和日志记录;评估与控制接口则负责把训练好的策略部署到仿真环境或真实机器人上,让模型输出动作指令去驱动机器人完成目标。
整个工作流程是:先准备数据(下载或自己采集),然后定义实验配置(哪套模型、什么训练参数),启动训练,最后加载训练好的 checkpoint 做评估和部署。复现的核心就是把这个链路完整走通,理解每一步的数据流转和接口约定。
1.2 版本选择比你想的重要
我复现时最头大的不是算法,而是版本兼容问题。lerobot 对 Python、PyTorch、CUDA 的版本组合比较敏感。官方文档会给出建议版本,但如果你照着“最新版”盲目安装,极大概率会碰到冲突。下面这个表格是我整理过的一套相对稳定的组合,供参考:
| 组件 | 推荐版本 | 备注 |
|---|---|---|
| Python | 3.10 | 3.11 及以上有些依赖没跟上 |
| CUDA | 11.8 或 12.1 | 需与 PyTorch 匹配 |
| PyTorch | 2.1.x | 2.2 以上部分算子兼容性有变 |
| 操作系统 | Ubuntu 20.04 / 22.04 | Windows 也可以跑,但仿真可视化体验差一些 |
| 主要依赖 | 以官方 requirements 为准 | 不要轻易升级小版本 |
特别提醒,PyTorch 版本和 CUDA 版本的匹配关系一定要先确认好,不要先装了 PyTorch 再回头纠结 CUDA。稳妥的做法是先装好 CUDA 驱动,然后用pip install torch安装对应的预编译包,让 PyTorch 自己去搞定底层库。
2. 从零搭建运行环境:我的完整步骤记录
我的做法是在一台 Ubuntu 22.04 服务器上进行复现,用的是一张 24GB 显存的显卡。这个环境配置过程前后花了两天,其中真正有效操作的时间其实只有两个小时,剩下的时间全部花在排查依赖冲突和下载数据集上。
下面我把自己的操作步骤完整写出来,每个步骤都附带原因解释,希望你能顺着这个思路走,不要照搬命令就以为是万能答案。
2.1 用 conda 创建干净的 Python 环境
我习惯先用 conda 创建一个独立的虚拟环境,避免把系统 Python 搞乱。这一步没什么技术含量,但非常重要。如果你直接复用 base 环境,装到后面你会发现某个依赖需要 Python 3.9,另一个又要求 3.11,互相打架,直接崩溃。
创建环境命令如下:
conda create -n lerobot python=3.10 conda activate lerobot创建完环境之后,我建议先升级一遍 pip 和 setuptools,因为有些老旧的工具链会解析出奇怪的依赖组合:
pip install --upgrade pip setuptools wheel2.2 安装依赖时最容易踩的坑
lerobot 仓库里的requirements.txt是官方给出的依赖清单,但这里有个坑:直接pip install -r requirements.txt经常会出现版本冲突,尤其是huggingface_hub、torch、numpy这三个库之间,历史版本兼容性很混乱。
我的做法是分两步安装:
第一步,先安装 PyTorch 及其配套组件,指定版本和 CUDA 版本。以 CUDA 12.1 为例:
pip install torch==2.1.2 torchvision==0.16.2 --index-url https://download.pytorch.org/whl/cu121第二步,再安装其余依赖。这里我给个建议:不要一次装完所有依赖再测试,最好装一批,验一批。否则后面报错时你根本不知道是哪一个库引入的问题。
我用到的安装顺序是:
pip install einops gdown h5py omegaconf pip install timm hydra-core pip install wandb其中wandb是训练日志工具,官方示例中默认会尝试连接云端,如果你不想用,可以通过环境变量WANDB_MODE=offline切到离线模式,否则第一次训练时会卡在登录环节,这算是新手最容易遇到的“假卡死”之一。
2.3 验证环境是否跑通的小实验
环境装完后,不要急着下载数据集,先做一个小实验:用随机输入跑一遍模型的前向推理,确认整个链路能通。
我写段简单的 Python 代码来验证:
import torch from lerobot.models import DiffusionPolicy model = DiffusionPolicy.from_pretrained("lerobot/diffusion_policy") dummy_obs = torch.randn(1, 3, 96, 96) dummy_state = torch.randn(1, 2) action = model.predict(dummy_obs, dummy_state) print(action.shape)如果这一步能顺利输出动作张量的形状,说明模型组件、张量计算、依赖加载都正常。如果在这里就报错,那就先别继续往下走了,一定是环境没搭对。
这个验证方法是我强烈推荐的标准操作,它把成千上万个潜在问题压缩到一个极小的范围内,不用等到训练时才触发一堆奇怪的异常。
3. 数据从哪里来:下载官方数据集 vs 自己采集
数据是机器人模仿学习里面最容易被低估的环节。很多人以为复现的核心是跑训练脚本,实际上从数据下载、格式理解到数据装载,都可能成为卡脖子的地方。
lerobot 官方提供了多个仿真数据集和真实机器人数据集,它们都存放在开源模型托管平台上,可以通过项目中的命令行工具直接下载。我复现时用的是官方指定的推箱子任务数据集,它生成自一个仿真环境,包含大量人机交互演示。
3.1 官方数据集的下载流程
下载数据集的命令在官方文档里有,但不同版本的命令参数格式会有变化,我以自己下载时的命令为例:
python lerobot/scripts/download_dataset.py \ --dataset-id lerobot/aloha_mobile_pick_place \ --output-dir ./data这里要提醒一下:下载速度可能会非常不稳定,尤其是数据集文件涉及多个分片。如果你的网络环境一般,建议用带断点续传能力的下载工具,或者多试几次,不要中途放弃。我下载时前两次都失败在第 8 个分片上,第三次才完整拉下来。
下载完成后,数据集目录结构大致如下:
data/ aloha_mobile_pick_place/ metadata.json episodes/ ep_0.h5 ep_1.h5 ... videos/ ep_0.mp4 ep_1.mp4 ...meta 文件描述了传感器标定信息、动作维度、坐标空间等,视频文件主要用于可视化查看演示过程,真正训练时主要用到的是episodes里面的 HDF5 文件。
3.2 数据格式里最容易忽视的细节
每个 HDF5 文件保存一个 episode 的数据,里面通常包含图像序列、机器人关节状态、动作指令、时间戳等。你不需要手动解析它,但至少得清楚“动作”和“状态”之间的区别,因为后续训练时它们是分开处理的。
- 状态(state):观测到的环境信息,比如机械臂关节角度、夹爪开合度。
- 动作(action):在某个状态下,机械臂执行的控制指令,通常是关节角度目标或末端速度。
模仿学习的目标,就是学习一个从观测状态到动作的映射函数。这个映射在训练阶段被反复拟合,在评估阶段则被用来实时决策。
我在查看数据时发现一个很有意思的点:即便是在仿真数据集里,同一个任务的不同 episode 之间,动作节奏、轨迹平滑度也有明显差异。这其实是好事,因为多样性的数据能提升策略的泛化能力。如果你训练出的策略表现不佳,先别急着调模型参数,检查一下训练集是不是太过单一。
3.3 自制数据采集的硬件配置建议
如果你不想只用官方数据,而是想采集自己的操作数据,那你需要一套能够记录机器人状态和图像的硬件方案。官方的采集方案通常要求机械臂具备高精度编码器,外接摄像头或者腕部相机来录制图像。
以常见的六轴机械臂搭配一个夹爪为例,你需要采集这些信号:
| 信号类型 | 获取方式 | 保存格式 |
|---|---|---|
| 关节角度 | 机械臂控制器实时读取 | 一维数值数组 |
| 关节速度 | 差分计算或控制器输出 | 一维数值数组 |
| 夹爪开合 | 夹爪电机反馈 | 标量或向量 |
| 第一视角图像 | 腕部相机 | 图像数组 |
| 外置视角图像 | 固定机位相机 | 图像数组 |
采集频率越高,数据越精细,但数据量也越大。我建议动作指令和状态使用 50Hz 以上采样,图像使用 30~50Hz,这样训练出来的策略在推理时才不会感觉到“一顿一顿”的卡顿。
这里有一个很反直觉的经验:真实采集的数据里偶尔保留一些“不完美”的示范(例如夹取时轻微抖动几毫米然后调整成功),对策略鲁棒性有正面效果。但如果你希望学到的动作更精准,则需要人为筛选掉明显失败的轨迹。到底怎么取舍,取决于你最终想让机械臂达到什么样的表现。
4. 训练一个模仿学习策略:配置解读与启动细节
数据准备好之后,就进入整个复现过程中最核心、也最消耗计算资源的部分:模型训练。lerobot 支持多种模仿学习算法,我复现时主要跑的是扩散策略(Diffusion Policy),原因很简单:它在多种机械臂任务上的鲁棒性都很好,代码实现也相对清晰。
4.1 训练配置文件的逐项拆解
lerobot 使用 YAML 文件管理训练配置,其中关键参数分布在数据、模型、优化器和训练循环几个模块里。我打开默认配置文件时,第一眼看到几十个参数,会有点懵,但真正需要手动调整的其实不多。
我挑几个最容易影响结果的参数解释一下:
batch_size:每次训练迭代送入模型的样本数。显存不足时优先降低它,默认值在面对大模型时容易爆显存。num_epochs:训练轮数。不是越多越好,需要结合验证误差判断。learning_rate:初始学习率。使用默认值一般不会有问题,但如果 loss 震荡剧烈,可以适当降低。num_frames:一个训练样本中包含的连续帧数。扩散策略依赖上下文信息,太小会看不清动作趋势,太大则增加显存占用。delta_timestamps:定义每个输入帧与当前帧的时间偏移量,这决定了策略能看到“过去多久”的信息,对快速运动任务影响很大。
默认配置通常能在通用场景下跑出不错的效果,但如果你想迁移到自己的数据集上,这些参数都需要重新审视,不能指望一把通吃。
4.2 启动训练命令与日志观察
启动训练的官方命令差不多长这样:
python lerobot/scripts/train.py \ --config-dir lerobot/configs \ --config-name diffusion_policy.yaml \ hydra.run.dir=outputs/diffusion_policy_debug \ dataset_repo_id=lerobot/aloha_mobile_pick_place训练开始后,控制台会输出若干条基本信息,包括数据集规模、batch 数量、模型参数量等。看到参数量动辄几千万时不要慌,这是扩散模型的正常规模。
随后每隔固定步数,日志会打印 loss 值和学习率。我习惯把wandb打开,因为图表比命令行输出的文字直观得多。
这里我总结一下训练早期阶段的典型曲线走势:大概前几百步 loss 会快速下降,之后进入缓慢的下坡期,中间会有小幅波动,这很正常。如果 loss 完全没有下降趋势,或者初期就出现 NaN,那基本可以断定是数据异常、学习率过高、或模型初始化出了问题,不是“多训练一会儿”能解决的。
4.3 训练过程中的监控指标与问题判断
监控指标看起来简单,但很多人只盯 loss,容易错判模型的真实状态。建议同时关注这几个指标:
loss:整体训练误差,越低越好,但不能单独依赖它判断模型质量。action_mse_loss:动作预测的均方误差,如果这个值持续偏高,说明策略输出的动作和演示动作差异大,可能导致实际执行时阶段性地“走样”。state_loss:部分算法会额外引入状态上的监督,这个指标过高可能说明观测状态编码不够充分。data_loading_time:数据加载耗时。如果这个值过大,模型吃的都是老旧数据,训练过程就会忽快忽慢,看起来 loss 波动很大。
训练过程中,我特别强调要定期存 checkpoint。lerobot 的默认配置会周期性保存,但你最好在训练脚本里显式设置一个保存间隔更短的 backup 目录。因为有一次我训练到第 300 轮时机器意外断电,默认保存间隔是 50 轮,我损失了整整 50 轮的结果,重新跑花了好几个小时,真的很痛苦。
5. 评估与部署:让策略在仿真/真实环境里动起来
训练结束只是复现的一半,另一半是在评估环境里真正看到策略执行任务。这个环节最容易产生“训练时分数很高,实际动起来却拉胯”的落差,原因是训练和评估之间存在很多容易被忽略的差异。
5.1 评估脚本与可视化
lerobot 提供了评估命令,加载训练好的 checkpoint 并让策略在环境中执行一定数量的 episode,统计成功率或任务得分。常见的运行方式如下:
python lerobot/scripts/eval.py \ --config-name diffusion_policy.yaml \ --pretrained-checkpoint outputs/diffusion_policy_debug/checkpoints/010000.pt \ --dataset-repo-id lerobot/aloha_mobile_pick_place评估时有一个很关键的细节:策略输出的是动作序列,而环境要求每一步执行一个动作。你需要在“执行整个动作序列”和“每步重新预测”之间做取舍。默认配置会在固定时间窗口内执行同一串预测动作,这称为 receding horizon control(滚动时域控制)。如果你发现实际动作用力过猛或者抖动频繁,可以尝试减小动作序列的执行长度,让策略更频繁地重新规划。
可视化的价值不只是“看个热闹”。通过观察机械臂动作,你能够快速判断策略是不是学到了有意义的特征,比如夹爪在接近目标时会不会预先张开,手臂在移动时是不是沿着平滑轨迹。这些信息比数字更能揭示模型的决策行为。
5.2 真实机器人部署前的安全检查
如果你打算在真实机器人上部署,我有几条来自自己教训的安全建议:
- 先空跑测试。不连接真实硬件,只把策略输出发送给仿真环境,验证动作幅值和频率在安全范围内。
- 加动作限幅。在策略输出和真实执行器之间加一个低通滤波或动作限幅模块,防止模型输出瞬时异常大动作。
- 准备急停开关。无论你的模型训练得多好,都要做好随时切断动力的准备,这不是信不信任模型的问题,而是安全底线。
- 从小范围目标开始。让机械臂先完成一个范围很小的接近动作,确认可行后再逐步扩大任务区域。
这四条建议听起来简单,但绝大多数“机器人学习事故”都是因为跳过其中某一条而发生的。我自己就吃过动作限幅没加的亏——模型在仿真里表现完美,真实部署时一个瞬间的异常输出差点把机械臂怼到桌面上。
5.3 策略性能优化的方向
评估之后,如果策略和目标表现还有差距,优化的优先级应当明确。我总结下来,性价比最高的几个方向依次是:
- 检查数据质量问题:是否存在错误标注、时间对齐偏移、图像模糊?数据问题不解决,调什么参数都是白费。
- 调整动作预测窗口长度:窗口太短会让策略缺乏远见,太长则容易让简单任务变得犹豫,需要反复试验。
- 增加上下文帧数:如果任务依赖历史状态(例如需要记得此前是否已经抓取成功),这一点尤其有效。
- 对图像观测做增强:包括亮度扰动、平移裁剪、旋转等,有助于提升泛化能力。
不要一开始就扎进模型结构改动里,那是最耗时且最难见效的方向。先把你手里的数据和评测流程优化到可靠可信的程度,再考虑“魔改网络”。
6. 我复现过程中遇到的三类坑和解决办法
走完整轮复现,最耗时间的一定是踩坑和排错阶段。这些坑在文档里未必写得很清楚,但实际碰到的概率接近百分之百。我把最有代表性的三类坑记录在这里,希望能帮你少走弯路。
6.1 环境依赖冲突:最容易被拖垮的环节
第一次装依赖的时候,我一直卡在一个报错信息上:ModuleNotFoundError: No module named 'torch._six'。这个报错的原因是某些视觉库的新版本不再兼容旧版 torch 的内部工具函数,而 lerobot 里的部分模块还沿用旧写法。
我当时的解决办法是把einops和timm降到与 torch 2.1 兼容的版本,同时将torchvision对齐到 torch 版本。这里给出一个判断逻辑:遇到torch._six或类似内部 API 报错时,优先怀疑某个库版本的隐性 API 变化,不要急着修改源码。
另外还有一个隐藏依赖问题:如果同时安装了系统包里的 OpenCV 和 pip 安装的 OpenCV,很可能出现二进制冲突,表现是加载视频时经常莫名其妙崩溃。建议在 conda 环境内明确指定opencv-python-headless,并且在导入时确认到底加载的是哪一个。
6.2 训练不收敛的排查链路
训练不收敛的具体表现是 loss 在前几千步不下降,或者在某个高位附近来回震荡。我踩过的一次就是数据加载异常导致的“伪不收敛”——数据加载器把图像和动作的时间戳错位了,模型在每个 step 都在学习错误的对应关系,loss 当然下不去。
排查链路应该按这个顺序来:
- 可视化一批训练样本,确认图像内容和对应动作是否合理。
- 检查时间戳对齐:图像帧的时间戳和动作指令的时间戳应该在同一个坐标系里,尤其是自制数据。
- 检查归一化:图像像素范围是否归一化到
[-1, 1]或[0, 1],关节角度是否被标准化,尺度差异过大会让优化器很不稳定。 - 检查学习率和 batch size 的匹配关系:batch size 越小,学习率一般也要相应调小,否则一个 batch 的噪声会干扰更新方向。
这个顺序不是随意的,它是从“数据本身是否正确”逐步过渡到“模型训练机制是否合理”的排查思路,能最快锁定问题区间。
6.3 硬件资源不足时的降级方案
很多人复现 lerobot 用的不是顶配显卡,资源不足是常态。如果你在训练时遭遇显存爆掉,不要立刻想着再买一张卡,有几个可以先试的方案:
- 调小
batch_size:这是最简单有效的办法。batch size 从 8 降到 4,显存占用能减少接近一半。 - 开启梯度累积:通过多个小 batch 累积梯度,等效于大 batch 的训练效果,但显存压力小得多。
- 减小输入图像分辨率:把图像从 256x256 降低到 128x128,模型推理和训练都会快很多,我实测对任务成功率影响不大。
- 使用混合精度训练:PyTorch 自带的自动混合精度机制能显著减小显存占用,同时训练速度更快,代价是轻微的数值精度损失。
这些方案合在一起,可以让你在 8GB 显存的卡上勉强跑通默认规模的训练。当然,如果追求更好的效果,硬件升级还是最终解,但在那之前,这些办法值得先试。
最后再分享一点个人体会
整个 lerobot 复现做下来,我的最大感受是:这个项目真正的门槛并不在算法原理,而在环境兼容和数据链路。只要把这两块稳住,训练和评估都只是时间问题。如果你之前没接触过机器人学习框架,强烈建议先从官方数据集和仿真评估开始,不要一上来就接真实机器人,那样只会把变量搅在一起,出了问题根本不知道从哪里查。
另外,如果你在复现时发现了和官方示例不一致的行为,先检查你的版本号,再检查数据集有没有完整下载,最后再怀疑代码本身。这几类问题在新手期占了我排查时间的九成。
希望这篇记录能帮你在复现 lerobot 的路上少踩一点坑。有什么我没提到但你觉得值得补充的细节,也欢迎留言讨论。