LeRobot:把机器人学习门槛打下来的开源框架,Hugging Face 出品
📖 简介
📝 详细介绍
一个被反光金属件卡住的产线工位
去年底我们接了个内部项目:某连接器产线末端的上下料工位,要把异形金属端子从振动盘里抓起来,插进治具。原来那套方案是 2D 相机 + 轮廓匹配 + 固定轨迹,工程师调了三个月,遇到镀镍反光件就翻车——成功率掉到 42%,一晚上要停机叫人重标定两次。产线负责人给的硬指标很朴素:换型时不能停线超过一天,成功率得进 90%。
我第一反应是上模仿学习。问题是我之前做的是 CV 和 LLM 应用,机器人这边只有大学跑过 ROS 的水平。外包报价 40 万、周期 10 周,还得锁他们家的硬件。于是决定自己搞,落地工具就是 LeRobot。
需求拆解
- 数据:工位没有现成的示教数据,得让产线师傅用遥操作杆采几百条成功轨迹;数据格式必须能直接喂训练,别让我写转换脚本。
- 性能:控制环 30Hz,端到端推理延迟必须压在 50ms 以内,否则动作会抖。训练侧允许一晚跑完。
- 成本:训练预算按云 GPU 小时算,目标单次迭代控制在 百元人民币以内(估算);部署端只能是工控机加一张消费级卡,不能上服务器。
- 部署约束:车间无外网,整个链路要能离线跑;模型换型后师傅自己会按一个脚本重新训,不能每次找我。
方案设计:为什么是 LeRobot
我横向看了四条路。一是继续堆传统视觉,反光件这条路走不通,放弃。二是纯 RL 仿真训练再 sim2real,物理接触和摩擦建模的坑太深,没这个人力。三是 RoboMimic 这类学术代码库,策略实现是全的,但数据管线要自己搭,且维护节奏慢。四是机器人厂商的私有 SDK,绑定硬件、闭源、换型要重新谈。
选 LeRobot 的核心原因有三个,都很实际:
- 数据格式统一。LeRobotDataset 把视频、状态、动作、任务文本打包成一套 Parquet + MP4 结构,还能直接 push 到 Hugging Face Hub。采集、训练、评测三个环节共用同一份数据,我没有写一行转换代码。
- 策略开箱可用。ACT 和 Diffusion Policy 都带完整训练脚本和预置配置,我改的是超参不是网络结构。
- Apache 2.0 + 活跃度。Star 数 27,614,Fork 5,681,最近一次提交就在 2026-09-19,说明不是发完论文就没人管的仓库。商业授权也干净。
取舍也明确:ACT 的泛化能力不如 VLA 类大模型,光照和背景一变就得补数据。但产线环境是固定的,稳定性和推理速度比泛化重要,这个取舍我认。
落地实现
第一步:环境与数据采集
硬件用的是 SO-101 主从臂,主臂遥操作,从臂执行,两路 USB 相机(腕部 + 侧视,640×480@30fps)。
conda create -n lerobot python=3.10 -y
conda activate lerobot
git clone https://github.com/huggingface/lerobot.git
cd lerobot && pip install -e ".[feetech]"
采集命令,让师傅一口气录了 60 条成功轨迹:
lerobot-record
--robot.type=so101_follower --robot.port=/dev/ttyACM0 --robot.id=follower_01
--teleop.type=so101_leader --teleop.port=/dev/ttyACM1 --teleop.id=leader_01
--dataset.repo_id=myorg/pick-terminal-v1
--dataset.single_task="pick the terminal from feeder and insert into fixture"
--dataset.num_episodes=60 --dataset.fps=30 --display_data=true
关键是 --dataset.fps=30 必须和控制频率一致,后面会讲为什么。
第二步:训练 ACT 策略
lerobot-train
--dataset.repo_id=myorg/pick-terminal-v1
--policy.type=act
--output_dir=outputs/train/act_terminal
--job_name=act_terminal
--policy.device=cuda
--batch_size=8
--steps=40000
--save_freq=10000
--wandb.enable=true
一张 4090 跑完 4 万步约 3.5 小时(实测)。ACT 配置约五千万参数,模型体积 200MB 上下。
第三步:离线部署
工控机加载 checkpoint 直接推理,不依赖 Hub:
from lerobot.policies.act.modeling_act import ACTPolicy
import torch
policy = ACTPolicy.from_pretrained(
"outputs/train/act_terminal/checkpoints/last/pretrained_model"
)
policy.eval().to("cuda")
# 主循环:30Hz 读观测 -> 推理 -> 下发
with torch.inference_mode():
while running:
obs = robot.get_observation()
action = policy.select_action(batch_from(obs))
robot.send_action(action)
效果与数据
连续跑了三班各 500 次抓取,数据如下(节拍和成本为现场记录,训练成本为云 GPU 换算估算):
| 指标 | 原方案 | LeRobot ACT | 变化 |
|---|---|---|---|
| 整体成功率 | 71% | 93.5% | +22.5pp |
| 镀镍反光件成功率 | 42% | 89.0% | +47.0pp |
| 单件节拍 | 6.8s | 4.1s | -40% |
| 端到端推理延迟 | — | ~38ms | 满足 50ms 要求 |
| 换型调试周期 | 3–5 天 | 约 0.5 天 | 含重新采集 60 条 |
| 单次训练成本 | — | 约 ¥60(估算) | 云 GPU 3.5h |
踩过的坑
坑一:相机时间戳和机械臂状态错位
现象:训练 loss 正常下降,实机动作却在做出决策后半拍才执行,抓取时明显"追着"目标跑。
排查:把录制的 episode 导出来逐帧对,发现动作比画面晚了 2–3 帧。原因是三路 USB 设备各自独立取流,采集脚本按主循环轮询,USB 带宽不够时相机会丢帧补帧,时间戳慢慢漂移。
解决:腕部相机分辨率从 1280×720 降到 640×480,两路相机分到不同 USB 控制器上,同时把 fps 从 30 拉到 30 但显式对齐采样时刻。重录一遍数据后,动作跟随的问题消失。教训是:数据采集阶段的时间同步,比模型选型重要得多。
坑二:loss 很漂亮,实机抖成筛子
现象:验证集 loss 只有 0.03,实机机械臂在接近目标时高频抖动,插不进去。
排查:查推理耗时,单次前向 62ms,超过 30Hz 控制周期(33ms)。主循环被阻塞,下发的动作序列被截断,等于每个 action chunk 只执行了前几个。ACT 本身是输出动作块的,执行节奏被打乱后行为完全变了。
解决:把输入图像在 CPU 侧预 resize 好再进 GPU,推理降到 38ms;同时加了动作队列,推理和控制在两个线程里跑,队列低于阈值就补一次推理。抖动消失。
坑三:失败样本混进数据集,模型学会了"放弃"
现象:第一版模型成功率只有 65%,且失败方式高度一致——抓起来了,但插到一半松手。
排查:翻录制日志,60 条里有 11 条是师傅操作失误的失败轨迹,当时想的是"多点数据总没坏处"。
解决:写脚本过滤掉长度显著短于均值的 episode,只保留成功轨迹,重训后成功率直接到 93.5%。模仿学习里,一条坏数据的影响远大于十条好数据。
复盘与扩展
做对的三个决策:一是选了格式统一的数据管线,省下的工程量至少两周;二是坚持在实机上做端到端评测而不是只看 loss;三是把推理延迟当成一等公民来优化,这在机器人场景里和精度同等重要。
做得不够的地方:没有在一开始就固定随机种子的采集协议,导致第一批数据光照条件不一致,白扔了 20 条;另外没有做数据增强(随机裁剪、亮度扰动),泛化全靠现场环境不变来兜底,产线换照明灯的时候我们补采了一次数据。
后续扩展方向有三个。一是接 SmolVLA 这类视觉语言动作模型,用自然语言指令切换任务,一套模型管多个工位。二是把每次实机评测的轨迹回传到 Hub,做成持续的数据飞轮,失败样本自动进入下一轮训练集。三是把训练脚本包成车间可用的 GUI,让产线工程师自己按"采集—训练—上线"三步走,彻底脱离我的参与。
总的来说,LeRobot 的价值不在于它发明了什么新算法,而在于它把数据格式、策略实现、训练脚本、模型分发这条链路做通了。对我这种半路出家做机器人的工程师来说,它把最耗时的胶水活干掉了,剩下的就是业务本身。
AI 项目推荐
AI 其他- 标签
- #具身智能 #机器人 #模仿学习 #数据集 #开源
- 浏览
- 👁️ 1
- 发布日期
- 2026-09-19