lerobot so101 从零开始到部署推理(基础配置参见官方文档)


注意:以下脚本中机械臂串口号和相机idx要根据自己实际情况更改

0. 推理部署脚本(record_eval.sh

record_eval.sh 内容如下(下面文档会逐项解释它的参数):

#!/bin/bash
sudo chmod 666 /dev/ttyACM*

rm -rf /home/g/.cache/huggingface/lerobot/seeed/eval_screwdriver
export HF_ENDPOINT=https://hf-mirror.com

#export TRANSFORMERS_OFFLINE=1
#export HF_DATASETS_OFFLINE=1

lerobot-record \
  --robot.type=so101_follower \
  --robot.port=/dev/ttyACM0 \
  --robot.id=my_awesome_follower_arm \
  --robot.cameras="{ camera1: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, camera2: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30}}" \
  --dataset.single_task="Grab the screwdriver123" \
  --dataset.repo_id=seeed/eval_screwdriver \
  --dataset.episode_time_s=30 \
  --dataset.num_episodes=10 \
  --dataset.push_to_hub=false \
  --policy.path=/home/g/robot/outputs/train/my_smolvla/checkpoints/last/pretrained_model

1. 环境准备

  1. 安装 LeRobot(推荐直接安装当前仓库的开发依赖;如果你用的是 SmolVLA,还需要它的额外依赖)
pip install -e .
# 如果你的策略是 SmolVLA(你的 checkpoint 路径叫 my_smolvla,强烈暗示你在用 SmolVLA)
pip install -e ".[smolvla]"
  1. (可选)设置 Hugging Face 镜像,避免国内网络慢/不可达
export HF_ENDPOINT=https://hf-mirror.com
  1. (可选)离线模式
    脚本里把这两行注释掉了,表示:如果没有网络、但本地缓存齐全,可以取消注释:
# export TRANSFORMERS_OFFLINE=1
# export HF_DATASETS_OFFLINE=1

2. 真实硬件连接与标定(必须尽量按“同一套 id + 同一套硬件姿态/对齐”来)

推理部署只用到了 so101_follower(跟随臂)。但在训练数据收集阶段通常需要 leader/follower 的一致性。

2.1 硬件串口端口与权限
  • 脚本用 sudo chmod 666 /dev/ttyACM* 来解决串口权限问题。
  • 如果你换了设备/端口号,务必同步改 --robot.port=/dev/ttyACM0
2.2 标定(建议至少在第一次部署前做)

id 用于保存标定文件;同一个机器人 setup(尤其是电机/安装方式/姿态映射)里,id 一致性会直接影响推理效果。

SO101 follower 标定命令(官方文档示例)类似:

lerobot-calibrate \
  --robot.type=so101_follower \
  --robot.port=/dev/ttyACM0 \
  --robot.id=my_awesome_follower_arm

3. 获取策略 checkpoint(两条路:已有就跳过)

脚本直接使用本地 checkpoint:
--policy.path=/home/g/robot/outputs/train/my_smolvla/checkpoints/last/pretrained_model

因此你需要保证该目录存在且结构正确(通常包含策略配置与权重等文件)。

3.1 如果你已经训练好了

直接跳到第 4 节“部署推理”。

3.2 如果你还没训练:用 lerobot-train 微调 SmolVLA(示例)

SmolVLA 官方文档给了类似训练命令(你把 --dataset.repo_id--output_dir--job_name 替换成你的即可):

cd lerobot && lerobot-train \
  --policy.path=lerobot/smolvla_base \
  --dataset.repo_id=${HF_USER}/mydataset \
  --batch_size=64 \
  --steps=20000 \
  --output_dir=outputs/train/my_smolvla \
  --job_name=my_smolvla_training \
  --policy.device=cuda \
  --wandb.enable=true

训练完成后,checkpoint 一般在:
outputs/train/my_smolvla/checkpoints/last/pretrained_model


4. 部署推理(关键:运行 record_eval.sh

  1. 给脚本可执行权限(只需一次):
chmod +x record_eval.sh
  1. 直接运行(推理 + 录制评估 episodes):
bash record_eval.sh
4.1 命令行逐项含义
  • lerobot-record
    在真实机器人上循环:读取观测 obs -> 用 --policy.path 做推理 -> 下发动作到机器人 -> 把 episode 数据写入数据集(视频/帧等)。

  • --robot.type=so101_follower
    表示控制对象是 SO101 的 follower 臂。

  • --robot.port=/dev/ttyACM0
    follower 串口端口;硬件换线/换设备后必须改。

  • --robot.id=my_awesome_follower_arm
    用于定位/读取该机器人对应的标定文件;建议与训练/记录阶段一致。

  • --robot.cameras=...
    真实相机配置。这里是两个 OpenCV 摄像头:

    • camera1: index_or_path=0
    • camera2: index_or_path=2
      同时指定了 640x480fps=30
  • --dataset.single_task="Grab the screwdriver123"
    非常关键:推理时策略会用这个自然语言任务描述作为条件。通常应与训练/数据集收集时用的 single_task 完全一致或至少语义一致。

  • --dataset.repo_id=seeed/eval_screwdriver
    评估数据集的标识(会写到本地缓存);设置了 --dataset.push_to_hub=false,所以不会上传。

  • --dataset.episode_time_s=30--dataset.num_episodes=10
    每个 episode 运行 30 秒,总共 10 个 episode。

  • --policy.path=.../pretrained_model
    部署的策略权重/配置路径(可以是本地目录,也可以是 HF repo id,取决于 PreTrainedConfig.from_pretrained 的支持方式)。


5. 部署效果检查与常见参数调整

5.1 推理速度跟不上怎么办

常见原因:

  • 相机帧率/分辨率过高
  • 策略推理耗时太长
  • 编码(视频/帧保存)太慢

优先尝试:

  • 降低相机分辨率或 fps
  • 尝试开启流式编码(官方示例里会用到 --dataset.streaming_encoding=true
5.2 任务成功率低怎么办

优先检查:

  • --robot.id 是否和你标定时一致
  • --dataset.single_task 是否和训练时一致/足够相近
  • 使用的策略是否和该 robot 数据特征匹配(不同 robot/不同特征维度的策略可能无法正确推理)

附录 sh脚本(路径以及配置请自行更改)提供给大家借鉴

标定 双臂 

   # rm -rf ~/.cache/huggingface/lerobot/calibration/teleoperators
   # rm -rf ~/.cache/huggingface/lerobot/calibration/robots
   
   sudo chmod 666 /dev/ttyACM*

lerobot-calibrate \
    --robot.type=bi_so_follower \
    --robot.port=/dev/ttyACM0 \
    --robot.id=left_follower

# lerobot-calibrate \
#     --teleop.type=bi_so_leader \
#     --teleop.port=/dev/ttyACM1 \
#     --teleop.id=left_leader
远程推理 单臂 pi05
#!/bin/bash
 sudo chmod 666 /dev/ttyACM*
python -m lerobot.async_inference.robot_client \
    --server_address=10.200.25.1:8080 \
    --robot.type=so101_follower \
    --robot.port=/dev/ttyACM0 \
    --robot.id=my_awesome_follower_arm \
    --robot.cameras="{ \
        handeye: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, \
        front: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30} \
    }" \
    --task="Grab the screwdriver123" \
    --policy_type=pi05 \
    --pretrained_name_or_path=/home/train_pi05/outputs/pi05_training/checkpoints/last/pretrained_model \
    --policy_device=cuda \
    --actions_per_chunk=50 \
    --chunk_size_threshold=0.5 \
    --aggregate_fn_name=weighted_average \
    --debug_visualize_queue_size=True 
远程推理 双臂 pi05
#!/bin/bash
 sudo chmod 666 /dev/ttyACM*
# 启动双臂推理客户端
python -m lerobot.async_inference.robot_client \
    --server_address=10.200.25.1:8080 \
    --robot.type=bi_so_follower \
    --robot.left_arm_config.port=/dev/ttyACM0 \
    --robot.right_arm_config.port=/dev/ttyACM1 \
    --robot.left_arm_config.cameras='{
        "left_wrist": {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30},
        "top": {"type": "opencv", "index_or_path": 2, "width": 640, "height": 480, "fps": 30}
    }' \
    --robot.right_arm_config.cameras='{
        "right_wrist": {"type": "opencv", "index_or_path": 4, "width": 640, "height": 480, "fps": 30}
    }' \
    --robot.id=bimanual_follower \
    --task="Wipe the plates" \
    --policy_type=pi05 \
    --pretrained_name_or_path=/home/train_pi05/shuangbi/outputs/pi05_training_bimanual/checkpoints/last/pretrained_model \
    --policy_device=cuda \
    --actions_per_chunk=100 \
    --chunk_size_threshold=0.5 \
    --aggregate_fn_name=weighted_average \
    --debug_visualize_queue_size=True 
 

远程推理 单臂 smolvla
#!/bin/bash
 sudo chmod 666 /dev/ttyACM*
python -m lerobot.async_inference.robot_client \
    --server_address=10.200.25.1:8080 \
    --robot.type=so101_follower \
    --robot.port=/dev/ttyACM0 \
    --robot.id=my_awesome_follower_arm \
    --robot.cameras="{ \
        camera1: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, \
        camera2: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30} \
    }" \
    --task="Grab the screwdriver123" \
    --policy_type=smolvla \
    --pretrained_name_or_path=/home/smolvla/train_smolvla/outputs/train/my_smolvla/checkpoints/last/pretrained_model \
    --policy_device=cuda \
    --actions_per_chunk=50 \
    --chunk_size_threshold=0.5 \
    --aggregate_fn_name=weighted_average \
    --debug_visualize_queue_size=True

数据录制 双臂 
 sudo chmod 666 /dev/ttyACM*
rm -rf /home/g/.cache/huggingface/lerobot/bi_so_follower
#export CUDA_VISIBLE_DEVICES=""
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY
lerobot-record \
  --robot.type=bi_so_follower \
  --robot.left_arm_config.port=/dev/ttyACM0 \
  --robot.right_arm_config.port=/dev/ttyACM2 \
  --robot.left_arm_config.cameras='{
    "left_wrist": {"type": "opencv", "index_or_path": 4, "width": 640, "height": 480, "fps": 30},
    "top": {"type": "opencv", "index_or_path": 2, "width": 640, "height": 480, "fps": 30}
  }' \
  --robot.right_arm_config.cameras='{
    "right_wrist": {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30}
  }' \
  --robot.id=bimanual_follower \
  --teleop.type=bi_so_leader \
  --teleop.left_arm_config.port=/dev/ttyACM1 \
  --teleop.right_arm_config.port=/dev/ttyACM3 \
  --teleop.id=bimanual_leader \
  --display_data=false \
  --dataset.repo_id=bi_so_follower/bimanual \
  --dataset.num_episodes=20 \
  --dataset.single_task="Wipe the plates" \
  --dataset.streaming_encoding=true \
  --dataset.encoder_threads=2 \
  --dataset.episode_time_s=30 \
  --dataset.reset_time_s=12 \
    --dataset.push_to_hub=false 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐