真实世界机器人上的模仿学习

本教程将讲解如何训练一个神经网络,使其自主控制真实机器人。

你将学到:

  1. 如何记录并可视化你的 dataset。
  2. 如何利用你的数据训练 policy 并准备好进行评估。
  3. 如何评估你的 policy 并可视化结果。

按照这些步骤,你将能够以高成功率复现任务,例如拾取一块乐高积木并将其放入收纳箱,如下方视频所示。

视频:拾取乐高积木任务

本教程不局限于某一特定机器人:我们将带你了解命令和 API 片段,你可以针对任何支持的平台进行调整。

在数据采集过程中,你将使用一台“teleoperation”设备(例如 leader arm 或键盘)来遥操作机器人并记录其运动轨迹。

一旦你收集到足够的轨迹,就可以训练一个神经网络来模仿这些轨迹,并部署训练好的模型,使你的机器人能够自主执行该任务。

如果在任何时候遇到任何问题,欢迎加入我们的 Discord 社区 寻求支持。

想快速获取适合你环境配置的正确命令?快速开始笔记本 Open in Colab 让你只需配置一次机器人,即可生成下面所有可直接粘贴的命令。

设置与 calibration

如果你尚未设置并 calibrate 机器人和 teleoperator,请按照特定于机器人的教程完成设置。

teleoperation

在此示例中,我们将演示如何 teleoperation SO101 机器人。对于每个命令,我们还提供了相应的 API 示例。

请注意,与机器人关联的 id 用于存储 calibration 文件。在使用同一套设备时,teleoperation、录制和评估时必须使用相同的 id

Command
API example
lerobot-teleoperate \
    --robot.type=so101_follower \
    --robot.port=/dev/tty.usbmodem58760431541 \
    --robot.id=my_awesome_follower_arm \
    --teleop.type=so101_leader \
    --teleop.port=/dev/tty.usbmodem58760431551 \
    --teleop.id=my_awesome_leader_arm

teleoperation 命令会自动:

  1. 识别缺失的 calibration 并启动 calibration 流程。
  2. 连接机器人和 teleoperator 并开始 teleoperation。

相机

要为你的设备添加相机,请遵循本指南

带相机 teleoperation

使用 rerun,你可以在 teleoperation 的同时可视化相机画面和关节位置。在此示例中,我们使用 Koch 机械臂。

Command
API example
lerobot-teleoperate \
    --robot.type=so101_follower \
    --robot.port=/dev/tty.usbmodem5AB90687491 \
    --robot.id=my_follower_arm \
    --robot.cameras="{front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}" \
    --teleop.type=so101_leader \
    --teleop.port=/dev/tty.usbmodem5AB90689011 \
    --teleop.id=my_leader_arm \
    --display_data=true

录制 dataset

熟悉 teleoperation 后,你就可以录制第一个 dataset 了。

我们使用 Hugging Face hub 的功能来上传你的 dataset。如果你以前没有使用过 Hub,请确保你能通过命令行使用写权限令牌登录,该令牌可以在 Hugging Face 设置 中生成。

运行以下命令将你的令牌添加到命令行:

hf auth login --token ${HUGGINGFACE_TOKEN} --add-to-git-credential

然后将你的 Hugging Face 仓库名称存储到一个变量中:

HF_USER=$(NO_COLOR=1 hf auth whoami | awk -F': *' 'NR==1 {print $2}')
echo $HF_USER

现在你可以录制 dataset 了。要录制 5 个 episode 并将 dataset 上传到 hub,请根据你的机器人调整下面的代码,然后执行命令或 API 示例。

Command
API example
lerobot-record \
    --robot.type=so101_follower \
    --robot.port=/dev/tty.usbmodem585A0076841 \
    --robot.id=my_awesome_follower_arm \
    --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 1920, height: 1080, fps: 30}}" \
    --teleop.type=so101_leader \
    --teleop.port=/dev/tty.usbmodem58760431551 \
    --teleop.id=my_awesome_leader_arm \
    --display_data=true \
    --dataset.repo_id=${HF_USER}/record-test \
    --dataset.num_episodes=5 \
    --dataset.single_task="Grab the black cube" \
    --dataset.streaming_encoding=true \
    --dataset.encoder_threads=2
# Optional: --dataset.rgb_encoder.vcodec=auto

dataset 上传

在本地,你的 dataset 存储在此文件夹中:~/.cache/huggingface/lerobot/{repo-id}。数据录制结束时,你的 dataset 将上传到你的 Hugging Face 页面(例如 https://huggingface.co/datasets/${HF_USER}/so101_test),你可以通过运行以下命令获取该页面:

echo https://huggingface.co/datasets/${HF_USER}/so101_test

你的 dataset 将自动打上 LeRobot 标签,方便社区查找,你也可以添加自定义标签(例如本例中的 tutorial)。

你可以在 hub 上通过搜索 LeRobot 标签 来查找其他 LeRobot dataset。

你也可以运行以下命令手动将本地 dataset 推送到 Hub:

hf upload ${HF_USER}/record-test ~/.cache/huggingface/lerobot/{repo-id} --repo-type dataset

record 函数

record 函数提供了一整套工具,用于在机器人运行期间捕获和管理数据:

1. 数据存储
  • 数据使用 LeRobotDataset 格式存储,并在录制过程中保存到磁盘。
  • 默认情况下,录制完成后 dataset 会推送到你的 Hugging Face 页面。
    • 要禁用上传,请使用 --dataset.push_to_hub=False
2. checkpoint 与恢复
  • 录制过程中会自动创建 checkpoint。
  • 如果出现问题,或者你想在同一 dataset 中录制更多 episode,可以通过重新运行带有 --resume=true 的相同命令来恢复。恢复录制时,--dataset.num_episodes 必须设置为要额外录制的 episode 数,而不是 dataset 中目标的总 episode 数!请确保同时设置 --dataset.root="local_path",它是保存 dataset 新部分的本地路径,恢复录制时必需。
  • 要从头开始录制,请手动删除dataset 目录。
3. 录制参数

使用命令行参数设置数据录制的流程:

  • --dataset.episode_time_s=60 每次数据录制 episode 的时长(默认值:60 秒)。
  • --dataset.reset_time_s=60 每个 episode 后重置环境的时长(默认值:60 秒)。
  • --dataset.num_episodes=50 要录制的总 episode 数(默认值:50)。
4. 录制期间的键盘控制

使用键盘快捷键控制数据录制流程:

  • 右箭头键(n:提前结束当前 episode 或重置时间并进入下一 episode。
  • 左箭头键(r:取消当前 episode 并重新录制。
  • 退出键(ESCq:立即停止会话,编码视频并上传 dataset。

这些控制流快捷键适用于 X11、Wayland 以及无头/SSH 会话。当全局键盘后端不可用时(Wayland、无头机器或未授予辅助功能权限的 macOS),lerobot-record 会自动从终端读取相同的按键——请从交互式终端启动它并保持其聚焦。你也可以使用字母等效键 n(下一个,等同 )、r(重新录制,等同 )和 q(退出,等同 ESC)。无需设置 $DISPLAY

这仅适用于录制的控制流程。键盘teleoperation(用键盘驱动机器人)仍需要全局按键后端,因此只能在 X11 会话、Windows 桌面或已授予辅助功能/输入监控权限的 macOS 上使用——不适用于 Wayland 或无头会话。

收集数据的提示

当你熟悉数据录制后,就可以创建更大的训练 dataset 了。一个不错的入门任务是抓取不同位置的物体并将其放入收纳箱。我们建议至少录制 50 个 episode,每个位置 10 个 episode。在整个录制过程中保持相机固定,并保持一致的抓取行为。同时确保你操作的物体在相机中可见。一个好的经验法则是:你应当能够仅通过查看相机画面就完成该任务。

在接下来的章节中,你将训练自己的神经网络。在获得可靠的抓取性能后,你可以在数据采集时引入更多变化,例如更多的抓取位置、不同的抓取技巧,以及改变相机位置。

避免过快加入太多变化,否则可能会影响你的结果。

如果你想深入了解这个重要主题,可以查看我们撰写的、关于“什么样的 dataset 才是好 dataset”的博客文章

节奏报告

lerobot-record--dataset.fps 的节奏驱动循环,并报告实际达到的结果:每个保留的 episode 输出一行摘要,录制结束时输出整个会话的汇总块——包括按 Ctrl-C 中断的情况。

Cadence (episode 0): 29.88 Hz vs 30 Hz target · 600 ticks, 20.0 s measured · 8/599 ticks over the 33.3 ms budget (work mean 18.4 ms, worst 45.1 ms)
Cadence (episode 1): 29.88 Hz vs 30 Hz target · 600 ticks, 20.0 s measured · 8/599 ticks over the 33.3 ms budget (work mean 18.4 ms, worst 45.1 ms)
Cadence summary — whole run, 2 episodes · target 30 Hz (33.3 ms budget per tick): 1200 ticks, 1198 judged
  effective cadence: 29.88 Hz over 40.1 s measured
  ticks over the 33.3 ms work budget: 16/1198 (1.3%) — work mean 18.4 ms, worst 45.1 ms
  loop-body steps (share of measured work):
    observe      mean  13.65 ms · worst  40.20 ms ·  74.4% of work · 1200 calls
    process_obs  mean   0.30 ms · worst   0.30 ms ·   1.6% of work · 1200 calls
    teleop       mean   1.80 ms · worst   1.80 ms ·   9.8% of work · 1200 calls
    send         mean   0.90 ms · worst   0.90 ms ·   4.9% of work · 1200 calls
    record       mean   1.70 ms · worst   1.90 ms ·   9.3% of work · 1200 calls
  pacing headroom: 15.1 ms slept per tick on average (max 16.7 ms) — near zero means the loop is saturated

在基于该 dataset 训练之前,这部分值得一读。帧的时间戳由其索引推导得出,因此以 25 Hz 运行的会话仍然会产生一个声称为 30 Hz 的 dataset——录制出来的 action 只是比现实更快。上例中,observe 占了循环工作的 74%,其 worst 在 33.3 ms 的预算内达到了 40 ms:正是相机把多出的 16 个 tick 推到了上限之外。节奏余量接近零意味着没有任何余地来吸收一次慢 tick。

episode 之间的重置阶段也以同样的方式控制节奏,但有意识地不纳入这些数字,因为它们不录制任何数据。lerobot-teleoperatelerobot-replay 以相同方式报告,而 lerobot-rollout 会额外输出 节奏报告 中描述的插值专属行。

故障排查:

  • 在 Linux 上,只要 lerobot-record 在交互式终端中运行,录制控制流按键(方向键、退出键)即可在 X11、Wayland 和无头/SSH 会话中工作——无需设置 $DISPLAY。如果按键没有反应,请确保你处于交互式(TTY)终端而非管道/非 TTY 会话中,并保持聚焦;字母等效键 n / r / q 同样有效。键盘teleoperation(相对于录制控制流程)仍需要全局按键后端——X11 会话、Windows 桌面或已授予辅助功能/输入监控权限的 macOS——并且在 Wayland 或无头机器上不可用。参见 pynput 限制

可视化 dataset

如果你使用 --control.push_to_hub=true 将 dataset 上传到 hub,可以通过复制粘贴命令给出的 repo id 来在线可视化你的 dataset

echo ${HF_USER}/so101_test

回放 episode

一个有用的功能是 replay 函数,它允许你回放自己录制的任何 episode,或任何现有 dataset 中的 episode。该功能可帮助你测试机器人 action 的可重复性,并评估同类模型机器人之间的可迁移性。

你可以使用下面的命令或 API 示例在你的机器人上回放第一个 episode:

Command
API example
lerobot-replay \
    --robot.type=so101_follower \
    --robot.port=/dev/tty.usbmodem58760431541 \
    --robot.id=my_awesome_follower_arm \
    --dataset.repo_id=${HF_USER}/record-test \
    --dataset.episode=0 # choose the episode you want to replay

你的机器人应当复现出与你录制时相似的 action。例如,看看这个视频,我们在来自 Trossen Robotics 的 Aloha 机器人上使用了 replay

训练 policy

要训练一个控制你的机器人的 policy,请使用 lerobot-train 脚本。需要一些参数。以下是一个示例命令:

lerobot-train \
  --dataset.repo_id=${HF_USER}/so101_test \
  --policy.type=act \
  --output_dir=outputs/train/act_so101_test \
  --job_name=act_so101_test \
  --policy.device=cuda \
  --wandb.enable=true \
  --policy.repo_id=${HF_USER}/my_policy

下面解释一下这个命令:

  1. 我们使用 --dataset.repo_id=${HF_USER}/so101_test 将 dataset 作为参数提供。
  2. 我们通过 policy.type=act 指定 policy。这会从 configuration_act.py 加载配置。重要的是,该 policy 会自动适应你 dataset 中保存的机器人电机 state、电机 action 和相机数量(例如 laptopphone)。
  3. 我们提供了 policy.device=cuda,因为我们在 Nvidia GPU 上训练;不过你也可以使用 policy.device=mps 在 Apple 芯片上训练。
  4. 我们提供了 wandb.enable=true 以使用 Weights and Biases 可视化训练曲线。这是可选的,但如果使用它,请确保已通过运行 wandb login 登录。

训练通常需要几个小时。你可以在 outputs/train/act_so101_test/checkpoints 中找到 checkpoint。

要从 checkpoint 恢复训练,下面是恢复 act_so101_test policy 的 last checkpoint 的示例命令:

lerobot-train \
  --config_path=outputs/train/act_so101_test/checkpoints/last/pretrained_model/train_config.json \
  --resume=true

--config_path 也接受 Hub 仓库 id:如果某次运行已将其 checkpoint 推送到 Hub(通过 --save_checkpoint_to_hub=true),你可以直接从该仓库恢复——会下载其最新 checkpoint 并继续训练,同时恢复优化器、调度器、步数计数器和数据顺序:

lerobot-train --config_path=${HF_USER}/my_policy --resume=true

如果训练后不想将模型推送到 hub,请使用 --policy.push_to_hub=false

此外,你还可以添加额外的 tags,或为模型指定 license,或通过添加以下内容将模型仓库设为 private--policy.private=true --policy.tags=\[ppo,rl\] --policy.license=mit

使用 Google Colab 训练

如果你的本地计算机没有强大的 GPU,你可以按照 ACT 训练笔记本 使用 Google Colab 来训练模型。

使用 Hugging Face Jobs 训练

Hugging Face jobs 让你可以轻松选择硬件并在云端运行训练。因此,如果你没有强大的 GPU、需要更多显存,或者只是想更快地训练模型,就用 HF Jobs!它按量付费,只需为每次使用的秒数付费,你可以在此处查看定价和更多信息。

lerobot-train 默认在本地运行。要在 HuggingFace GPU 上运行,请传入带有硬件规格名称的 --job.target

lerobot-train \
  --dataset.repo_id=${HF_USER}/so101_test \
  --policy.type=act \
  --policy.repo_id=${HF_USER}/my_policy \
  --job.target=a10g-small

使用 hf jobs hardware 列出可用的硬件规格和价格。运行时会将其日志流式传输到你的终端;按 Ctrl-C 即可脱离(任务继续在云端运行)。重新连接或取消使用:

hf jobs logs <job-id>
hf jobs cancel <job-id>

如果你的 dataset 仅存在于本地(尚未上传到 Hub),它会自动推送到一个私有 Hub 仓库,以便任务通过 repo_id 下载它(不会公开任何内容)。训练好的模型会在运行结束时推送到模型仓库。要将每个中间 checkpoint 也在保存时推送到 Hub(以便你可以在运行过程中监控进度),请添加 --save_checkpoint_to_hub=true——这需要一个包含该功能的运行时镜像。

每个任务(以及运行期间推送的任何 dataset)都会被标记为 lerobot,以便在 Hub 上轻松找到。你也可以用 --job.tags '["my-tag"]' 添加自己的标签。

默认情况下,任务的挂钟时间上限为 2d(48 小时)。你可以用 HF Jobs 时长字符串覆盖它,例如用 --job.timeout=4h 更快失败,或用 --job.timeout=7d 延长运行时间。

注意: 模型仓库会提前创建(它存放任务运行的暂存训练配置)。如果一次运行在模型推送前失败,该仓库会留在 Hub 上供你查看——它不会被自动删除,因此反复失败可能会留下空仓库。可以使用 hf repo delete <repo-id> 删除。

前置条件: 提交前运行 hf auth login。要集成 Weights & Biases,请在你的机器上运行 wandb login 或设置 WANDB_API_KEY——密钥会自动转发给任务。

在任务上恢复。 在恢复命令中添加 --job.target 即可在云端执行恢复——同一命令在本地或远程都适用。checkpoint 仓库是唯一事实来源,新的 checkpoint 会在同一仓库中延续其传承:

# resume a Hub run on a job (its checkpoints are already on the Hub)
lerobot-train --config_path=${HF_USER}/my_policy --resume=true --job.target=a10g-small

# resume a LOCAL run on a job — the checkpoint is uploaded to a private Hub repo first,
# then the job resumes from it (a local-only dataset is uploaded the same way)
lerobot-train \
  --config_path=outputs/train/act_so101_test/checkpoints/last/pretrained_model/train_config.json \
  --resume=true \
  --job.target=a10g-small

任务设置来自当前命令,因此请根据需要覆盖 --job.target--job.timeout 等;若希望恢复后的运行自身以后也能被恢复,请保留 --save_checkpoint_to_hub=true

上传 policy checkpoint

训练完成后,使用以下命令上传最新 checkpoint:

hf upload ${HF_USER}/act_so101_test \
  outputs/train/act_so101_test/checkpoints/last/pretrained_model

你也可以使用以下命令上传中间 checkpoint:

CKPT=010000
hf upload ${HF_USER}/act_so101_test${CKPT} \
  outputs/train/act_so101_test/checkpoints/${CKPT}/pretrained_model

运行 inference 并评估你的 policy

使用 lerobot-rollout 在机器人上部署训练好的 policy。你可以根据需求选择不同的 policy:

下面的示例从 --policy.path 加载模型。要固定到某个已推送的版本——一旦 --save_checkpoint_to_hub=true 提交了多个 checkpoint 就很有用——请加上 --policy.pretrained_revision 并指定 commit 哈希、分支或标签。每个已推送的 checkpoint 都带有其步数标签(例如 --policy.pretrained_revision=010000),因此你可以按步数恢复 checkpoint,而无需查找其 commit sha。

Base mode (no recording)
Sentry mode (with recording)
lerobot-rollout \
  --strategy.type=base \
  --policy.path=${HF_USER}/my_policy \
  --robot.type=so100_follower \
  --robot.port=/dev/ttyACM1 \
  --robot.cameras="{ up: {type: opencv, index_or_path: /dev/video10, width: 640, height: 480, fps: 30}, side: {type: intelrealsense, serial_number_or_name: 233522074606, width: 640, height: 480, fps: 30}}" \
  --task="Put lego brick into the transparent box" \
  --duration=60

--strategy.type 标志用于选择执行模式:

  • base:自主 rollout,不录制数据(适合快速评估)
  • sentry:持续录制并自动上传(适合大规模评估)
  • highlight:环形缓冲区录制,通过按键保存(适合捕获有趣的事件)
  • dagger:人在回路中的数据采集(参见 HIL 数据采集
  • episodic:面向 episode 的 policy 录制,episode 之间有重置阶段

所有 policy 都支持 --inference.type=rtc,以实现使用慢速 VLA 模型(Pi0、Pi0.5、SmolVLA)时的平滑执行。

在 GitHub 上更新