Hugging Face 模型部署到机器人硬件应用
Strands Agents 和 LeRobot 框架让 Hugging Face 预训练模型部署到机器人硬件,主要价值在 ML/robotics 领域。
Strands Agents 和 LeRobot 框架让 Hugging Face 预训练模型部署到机器人硬件,主要价值在 ML/robotics 领域。
你有一台机器人、一个存放在 Hugging Face Hub 上的演示数据文件夹,以及一项想让机器人学会的新任务。目前,这需要五种彼此独立的工具:一种用于录制新的演示,一种用于训练,第三种用于在仿真环境中测试,还需要自定义代码将模型部署到硬件上;如果你拥有多台机器人,还得再使用一种工具来协调它们。各个组件单独使用时都能正常工作,但彼此之间无法通信。
Strands Robots 是 AWS 推出的开源 SDK(采用 Apache 2.0 许可证),它将机器人抽象、仿真环境和 LeRobot 技术栈封装为 AgentTools,供你组合到单个 Strands AI 智能体中。这一集成刻意保持轻量:硬件录制和校准由 LeRobot 自己的脚本处理,Strands AgentTools 只负责 AI 智能体真正需要编排的部分。仿真工具录制的 LeRobotDatasets 与 LeRobot 在硬件上写入的数据采用相同格式。GR00T 和 LerobotLocal 通过统一接口提供策略推理服务,MolmoAct2 检查点则通过 LerobotLocal 路径运行。对等网格可将 AI 智能体的任务分发到远程机器人。数据集格式完全保持 LeRobot 写入时的原样;AI 智能体循环只是把这些组件粘合在一起。
本文将带你在单个 AI 智能体中完成五个步骤:基于 LeRobot AgentTools 构建 AI 智能体;在仿真环境中将一次演示录制为 LeRobotDataset;在同一台机器人上运行策略;只修改一个关键字参数,就将同一套 AI 智能体代码部署到实体 SO-101;以及通过 Zenoh 网格向整个机器人集群广播命令。最后,你可以从 GitHub 克隆可运行的示例应用,并在笔记本电脑上通过仿真运行它。默认路径不需要硬件、GPU 或 Hugging Face 凭据。本文对应的可运行示例位于 examples/lerobot/hub_to_hardware.py 和 hub_to_hardware.ipynb。该笔记本仅支持仿真,并且默认使用 Mock 策略。
Strands Robots SDK 将 LeRobot 技术栈公开为 AgentTools,供你组合到一个 Strands AI 智能体中。本文中的示例 AI 智能体会完成四件事:在仿真环境中录制新演示;将结果作为 LeRobotDataset 推送到 Hub;在仿真环境中针对同一格式运行策略;以及只修改一个关键字参数,就将同一套 AI 智能体代码部署到实体机器人。当你拥有多台机器人时,AI 智能体可以通过内置的对等网格协调整个集群。硬件录制和校准由 LeRobot 自己的 CLI(lerobot-record、lerobot-calibrate)完成设备初始化;随后再由 AI 智能体接手。
图 1。Robot("so100") 默认返回基于 MuJoCo 的仿真机器人;mode="real" 返回由 LeRobot 驱动的硬件机器人。两种模式共享相同的 DatasetRecorder 和策略提供程序,因此无论数据集是在仿真环境还是硬件上采集的,都使用相同的磁盘 LeRobotDataset 格式。
两项设计选择使这一切成为可能。首先,Robot("so100") 默认返回仿真环境(无需硬件、没有风险),而 mode="real" 返回由 LeRobot 驱动、以实体硬件为后端的机器人。两种模式下的 AI 智能体代码完全相同。其次,写入 LeRobotDataset 的 DatasetRecorder 由仿真路径和 LeRobot 自己的硬件录制流程共享,因此在 MuJoCo 中采集的数据集与从实体 SO-101 采集的数据集采用相同格式。
整个工作流只需五行 Python:
from strands_robots import Robot
from strands import Agent
arm = Robot("so100") # mode="sim" (default - safe, no hardware)
agent = Agent(tools=[arm])
agent("Pick up the red cube")
接下来,我们将逐步说明这次调用内部实际发生了什么。
需要 Python 3.12+,运行于 Linux 或 macOS(MuJoCo 后端支持 Apple Silicon)。
需要一个与 Strands 兼容的模型提供程序,用于 AI 智能体的推理。可以使用带有 AWS 凭据的 Amazon Bedrock、Anthropic API、OpenAI,或者在本地运行的 Ollama。
安装 Strands Robots 时需要包含以下安装扩展:uv pip install "strands-robots[sim-mujoco,lerobot,mesh]"
就这些。本文中的示例只需这三项条件,即可在笔记本电脑上端到端运行。
如果要将数据集推送到 Hub,或从 Hub 拉取策略检查点,则需要一个具备写入权限的 Hugging Face 账户和令牌。
对于硬件路径:需要一对 SO-101 follower 和 leader,或者 LeRobot 支持的任何其他机器人。两个设备都需要在 ~/.cache/huggingface/lerobot/calibration/ 下保存校准文件。
对于本地 GR00T 推理:需要一块至少拥有 16 GB 显存的 NVIDIA GPU,并且已安装 Docker。本文使用 gr00t_inference 工具的 lifecycle="full" 操作,通过一次调用完成拉取镜像、下载检查点和启动容器。
安装 Strands Robots 并获取示例文件:
uv pip install "strands-robots[sim-mujoco,lerobot,mesh]"
git clone https://github.com/strands-labs/robots.git
cd robots
如果希望 AI 智能体将数据集推送到 Hub,或从 Hub 拉取策略,请导出你的 Hugging Face 令牌。对于本文默认的仿真路径,这一步是可选的;示例可以使用 Mock 策略端到端运行,并将数据集写入本地缓存,无需访问 Hub。
export HF_TOKEN=hf_...
可运行的示例位于 strands-labs/robots 仓库中的 examples/lerobot/hub_to_hardware.py(Python 脚本)和 hub_to_hardware.ipynb(笔记本),与 MuJoCo 和 LIBERO 示例放在一起。建议从笔记本开始:在 JupyterLab 中打开它,在未连接任何硬件的情况下,以仿真模式从上到下依次运行各个单元格。
仿真工具录制的 LeRobotDatasets 与 LeRobot 在硬件上写入的数据采用相同格式,无需任何硬件。Simulation 工具的 start_recording 操作通过同一个 DatasetRecorder 类写入数据:关节状态和动作采用相同的 parquet schema,每个摄像头也采用相同的 MP4 布局。AI 智能体提示词几乎完全相同:
from strands import Agent
from strands_robots import Robot
robot = Robot("so100") # mode="sim" by default
agent = Agent(tools=[robot])
agent(
"Record a demonstration of 'pick the red cube and place it in the box' "
"using the Mock policy provider at FPS 30. Write the dataset to "
"my_user/cube_picking_sim and push to the Hub when done."
)
图 2。MuJoCo 仿真环境中的录制场景:SO-100 机械臂伸向地面上的红色方块,录制结果保存为 LeRobotDataset。该默认路径不需要硬件、GPU 或 Hugging Face 凭据。
这里有意使用 Mock 策略:它会生成占位的关节动作,使整个工作流无需训练好的检查点也能端到端运行。机器人会执行随机动作,而不会真正完成抓取;录制结果在结构上是完整的——包括有效的关节状态、有效的摄像头帧,以及格式正确的 LeRobotDataset episode——但演示本身无法作为有用的训练数据。下面的步骤 3 会换用 GR00T 或 LerobotLocal,以实现真正的抓取行为。如果想在此步骤中看到实际的方块抓取,请运行 --policy lerobot_local --checkpoint allenai/MolmoAct2-SO100_101(这是一个 MolmoAct2 检查点,系统会根据其 config.json 自动检测,并通过 LerobotLocal 路径运行);提示词、数据集格式和 AI 智能体代码均保持不变。
接下来发生的事情就是最好的证明。LeRobot 自己的数据集加载器可以读取仿真环境中录制的数据,无需任何 Strands 专用代码路径:
from lerobot.datasets.lerobot_dataset import LeRobotDataset
dataset = LeRobotDataset("my_user/cube_picking_sim")
print(dataset.features)
# {'observation.state': Sequence(...),
# 'observation.images.front': VideoFrame(...),
# 'action': Sequence(...),
# 'episode_index': Value(...), 'frame_index': Value(...), ...}
这个 features 字典在结构上与 Hub 上任何 LeRobot 数据集完全相同:列名相同、parquet+MP4 布局相同、加载器路径也相同。能够使用硬件录制数据的训练脚本,无需修改即可使用仿真环境中录制的数据。如果你愿意,从仿真环境推送的数据集可以与硬件录制数据并列存放在同一个 Hub 仓库中。
这是录制好的 LeRobotDataset 中的单个 episode,通过录制器为每个摄像头写入的 MP4 文件进行回放;训练脚本读取的正是同一个磁盘视频文件。
如果要在实体 SO-101 上录制演示,而不是在仿真环境中录制,请直接使用 LeRobot 的录制 CLI。Strands 集成没有将该命令封装为 AgentTool,因为 LeRobot 本身已经能够很好地完成这项工作:
lerobot-calibrate --robot.type=so101_follower --robot.id=my_follower
lerobot-calibrate --robot.type=so101_leader --robot.id=my_leader
lerobot-record \
--robot.type=so101_follower --robot.id=my_follower \
--teleop.type=so101_leader --teleop.id=my_leader \
--dataset.repo_id=my_user/cube_picking \
--dataset.single_task='Pick up the red cube and place it in the box' \
--dataset.num_episodes=25 \
--dataset.push_to_hub=true
通过此命令上传到 Hub 的数据集,其格式与仿真录制的数据集相同。要在该数据集上微调策略,请运行 LeRobot 的训练 CLI(lerobot-train);训练本身不在本文讨论范围内,请遵循标准的 LeRobot 工作流。从第 3 步开始,智能体可以无差别地使用原始检查点或经过微调的检查点。有关 SO-101 硬件的完整设置、校准操作指南和故障排查,请参阅示例文件夹中的 README。
数据集上传到 Hub 后,下一步是运行策略。该示例使用默认 sim 模式下的 Robot() 工厂函数,然后挂载 gr00t_inference,使智能体能够管理推理容器:
from strands import Agent
from strands_robots import Robot, gr00t_inference
robot = Robot("so100") # mode="sim" by default
agent = Agent(tools=[robot, gr00t_inference])
agent(
"Start GR00T inference on port 5555 with the cube-picking checkpoint "
"from my_user/cube-picker. Then ask the robot to pick up the red cube."
)
在底层,智能体会运行 gr00t_inference(action="lifecycle", lifecycle="full", ...),以拉取 GR00T 容器镜像、从 Hub 下载检查点并启动推理服务。随后,它会在仿真机器人上运行 run_policy 操作,并设置 policy_provider="groot",同时在 policy_config 字典中传入 GR00T 服务的主机和端口(可通过端口 5555 访问该容器)。仿真使用策略生成的动作块逐步运行,并可通过 Simulation.render 获取结果渲染画面。
图 3. 借助训练好的策略(GR00T 或 MolmoAct2 检查点),智能体在仿真中驱动 SO-100 抓取红色方块;Mock 策略所模拟的正是这一行为。
对于偏好进程内推理(无需容器、无需 ZeroMQ(ZMQ))的开发者,可以将 gr00t_inference 替换为从 Hub 仓库加载的 LerobotLocalPolicy 实例。该提供程序会将 lerobot/ 组织下的任何模型 ID 路由到进程内推理路径:
from strands_robots.policies import create_policy
policy = create_policy("lerobot/act_aloha_sim_transfer_cube_human")
LerobotLocalPolicy 支持 ACT、Diffusion Policy、SmolVLA、π0 和 π0.5,以及 LeRobot 自身的策略注册表能够根据 config.json 解析的任何策略。对于附带 rtc_config 的流匹配策略(π0、SmolVLA),实时分块(Real-Time Chunking)会自动启用。
NVIDIA 最近发布的 Cosmos 3 也可以通过同一接口作为策略提供程序使用,因此无论指向哪个提供程序,智能体代码都保持不变。
注意:LerobotLocalPolicy 使用 trust_remote_code=True 加载 Hugging Face 模型。请设置 STRANDS_TRUST_REMOTE_CODE=1 以明确选择启用,并且只加载来自可信组织的检查点。
这里使用的代码与第 3 步相同,只需修改一个关键字参数。Robot 工厂函数会返回一个由硬件支持、通过 LeRobot 的 make_robot_from_config 驱动的机器人:
robot = Robot(
"so100",
mode="real",
port="/dev/ttyACM0",
data_config="so100_dualcam",
cameras={
"front": {"type": "opencv", "index_or_path": "/dev/video0", "fps": 30},
"wrist": {"type": "opencv", "index_or_path": "/dev/video2", "fps": 30},
},
)
agent = Agent(tools=[robot, gr00t_inference])
agent(
"Start GR00T inference on port 5555 with the cube-picking checkpoint "
"from my_user/cube-picker. Then ask the robot to pick up the red cube."
)
现在,同一个智能体提示词会在物理机械臂上运行。硬件路径使用 LeRobot 的机器人抽象来执行关节命令和读取摄像头,而可通过端口 5555 访问的 GR00T 容器负责生成动作块。
在 SO-101 上运行这段代码之前,必须完成从动端和主控端的校准。请为每台设备运行一次 LeRobot 的校准命令(lerobot-calibrate);生成的文件会保存在 ~/.cache/huggingface/lerobot/calibration/ 下,任何涉及硬件的 Strands 代码路径都会从该位置读取这些文件。如果缺少校准文件,智能体会显示来自 LeRobot 驱动层的错误。
到目前为止,我们一次只驱动一个机器人。Strands Robots 使用网格来处理多个机器人。设想一下:桌面上的主控机械臂遥操作另一个房间里的从动机械臂;五台 SO-101 并行执行同一项仓库任务;或者一个人形机器人与移动底盘协同工作。所有这些都属于网格模式。该网格基于开源点对点协议 Zenoh 构建;你不需要管理 IP 地址、编写发现代码或选择消息代理。新机器人一经启动便会出现在网格中,智能体可以同时与所有机器人通信。
每个 Robot() 和每个 Simulation() 都会自动加入 Zenoh 对等网格。robot_mesh 工具为智能体提供了一套用于执行设备群操作的指令体系,包括发现、结构化命令、广播和紧急停止:
agent = Agent(tools=[robot_mesh])
agent(
"List every robot and simulation on the mesh. "
"Then send 'go to home pose' to each one in parallel."
)
智能体会调用 robot_mesh(action="peers"),枚举本地节点和已发现的对等节点,然后调用 robot_mesh(action="broadcast", ...),在指定的超时时间内向每个对等节点发送结构化命令。添加 [mesh-iot] 扩展后,可以通过 AWS IoT Core 路由这些流量,从而支持跨网络的设备群。项目文档中的 robot_mesh 工具操作参考涵盖了完整的指令体系:订阅、监视、收件箱以及结构化的点对点命令。
默认情况下,每项会触发物理动作的网格操作在运行前都会暂停,等待人工审批中断:其中包括设备群范围的 broadcast 和 emergency_stop,以及面向单个对等节点的 tell、send 和 stop。你可以使用 STRANDS_MESH_HITL_ACTIONS 环境变量调整这个操作集合(将其设置为 all、none 或以逗号分隔的操作子集)。首次运行此示例时,终端中会显示 robot_mesh-broadcast-approval 提示;输入 y(或 yes / approve)即可授权广播。审批信息通过 LLM 工具参数之外的带外通道传递,因此,试图将审批标志暗中塞入命令正文的提示词注入攻击无法绕过该关卡。
这种传输机制可以在不修改智能体代码的情况下扩展。内置的 Zenoh 网格是自动回退方案:在局域网中,Zenoh 多播无需消息代理即可完成对等节点发现;添加 [mesh-iot] 扩展后,流量将通过 AWS IoT Core(使用支持 mTLS 的 MQTT5)进行路由,以支持云端设备群;BridgeTransport 则通过一个 API 扇出局域网和云端流量(使用 STRANDS_MESH_BACKEND=bridge 选择该模式)。
对于生产环境中的设备群,Device Connect 提供了一个与 Arm 合作开发、具备设备感知能力的网络层,负责发现、在线状态、结构化 RPC、事件路由和安全。Device Connect 可用时,同一个 robot_mesh 工具会通过它进行调度;否则会回退到内置的 Zenoh 网格,因此无论采用哪种方式,本文中的智能体代码都无需更改。有关设置方法和当前可用性,请参阅 Device Connect 文档。
完整示例位于 GitHub 上 strands-labs/robots 仓库的 examples/lerobot/ 文件夹中。它将全部五个步骤封装到一个 CLI 脚本(hub_to_hardware.py)和一个 notebook(hub_to_hardware.ipynb)中。使用默认 CLI 配置,即可配合 Mock 策略在仿真环境中端到端运行。无需 GPU、Docker 或 Hugging Face 凭据。
uv pip install "strands-robots[sim-mujoco,lerobot,mesh]"
git clone https://github.com/strands-labs/robots.git
cd robots
export STRANDS_MESH_LOCAL_DEV=1
python examples/lerobot/hub_to_hardware.py
录制的数据集会保存到 ~/.cache/huggingface/lerobot/local/strands-cube-pick/。如果要将数据集推送到 Hugging Face Hub,而不是保存在本地,请先导出具有写入权限的 HF_TOKEN,然后传入 --hf-user <your-user>。若要在第 3 步中实现真实的抓取行为,请传入 --policy groot --checkpoint <hf_repo>(需要 Docker 和 NVIDIA GPU),或传入 --policy lerobot_local --checkpoint <hf_repo>(需要 GPU,并设置 STRANDS_TRUST_REMOTE_CODE=1)。
该 notebook(examples/lerobot/hub_to_hardware.ipynb)以逐单元格方式演示了相同的工作流,并在每个步骤之间提供说明。请在 JupyterLab 中打开它,并在仿真模式下从上到下依次运行。
此设置中展示的代码片段是一个使用 HuggingFace 设置 Strands Robots 的“hello world”示例。对于更严肃、可用于生产环境的用例,用户需要了解一些重要事项:
向智能体提供不可信数据可能导致提示词注入,使不可信的上下文被当作 LLM 指令执行。鉴于这些机器人会在物理空间中产生实际动作,这是一个需要重点关注的风险。为缓解此类风险,开发者应谨慎确保仅向机器人提供来自可信来源的数据。如果无法信任所有输入数据,开发者应限制智能体可使用的工具,防止机器人执行涉及安全关键性的操作。
STRANDS_MESH_LOCAL_DEV=1 设置在本博客代码片段中共享,它在没有认证或访问控制的情况下初始化机器人网格。这意味着同一网络上的任何设备都可以向机器人群提供命令。这对于受信任的开发环境是可接受的,但不适合不受信任的网络或生产环境。对于这些用例,需要 STRANDS_MESH_AUTH_MODE=mtls。
robot_mesh 工具的物理执行操作会影响网络上的对等设备:broadcast 和 emergency_stop 到达每个对等设备,而 tell、send 和 stop 到达单个目标对等设备。为了防止智能体自主发出这些命令(或在提示词注入下发出这些命令),默认情况下所有五个命令都受到人在环中断的保护。当智能体调用受限操作时,Strands 运行时会暂停智能体循环,并要求操作员在带外批准 LLM 的工具参数。你可以使用 STRANDS_MESH_HITL_ACTIONS 环境变量调整受限操作集(all、none 或逗号分隔的子集)。单个操作的速率限制、命令验证和审计日志与中断一起运行。在智能体循环外(裸脚本或单元测试),受限操作会关闭失败。
上面的工作流启动了一个 GR00T 容器,在硬件上打开了串行端口,并写入了本地数据集缓存。要将你的环境恢复到干净状态:
停止 GR00T 推理容器:agent.tool.gr00t_inference(action="stop", port=5555),或使用 lifecycle="teardown" 同时移除容器。
释放串行端口:如果你运行了硬件路径,断开 SO-101 跟随者和领导者的连接。
可选地移除本地数据集缓存:记录的数据集位于 ~/.cache/huggingface/lerobot/<repo_id> 下。你推送到 Hub 的数据集不会受到影响。
该集成的中心设计选择是 Strands Robots 不重新实现 LeRobot 已经提供的东西。硬件抽象、标定和数据集格式保持在上游。Strands 添加了 AgentTool 表面,使它们可以通过自然语言组合。
随之而来两个结果。对于用户,Hub 上的每个数据集都是智能体可以扩展、从中微调和部署的资产,无需转换步骤。对于开发者,模拟数据和硬件数据共享单一文件格式,因此为一个编写的训练脚本不变地使用另一个。sim 和 real 之间的界限变成了一个部署细节,而不是架构分界线。
图 4. Strands Robots 目录涵盖手臂、人型机器人、四足机器人和手臂,都在同一个 MuJoCo 模拟中,以及在同一个 Robot() 工厂后面。本文中的 SO-100 是许多支持的具身形式之一。
完整的 Strands Robots 文档深入覆盖机器人目录、模拟、策略提供者、网格和 Device Connect。对于更大的工作负载,strands-labs/robots-sim 仓库托管了更重型的模拟后端,包括 Isaac Sim 和 Newton,以及 LIBERO 基准示例。两个后端都插入到本文所示的同一个 Robot 抽象中,因此当你扩展时智能体代码保持不变。
Apache 2.0 下欢迎贡献。如果你用这个工作流构建了什么,请打开一个 issue,说明什么有效、什么无效。当开发者反馈直接落在需要改进的表面上时,SDK 改进最快。
Strands Robots(SDK、AgentTools、Robot 工厂): github.com/strands-labs/robots, Apache 2.0
Strands Robots 文档(完整文档): strands-labs.github.io/robots
Strands Robots Sim(示例、模拟后端): github.com/strands-labs/robots-sim
示例: examples/lerobot/hub_to_hardware.py 和 hub_to_hardware.ipynb
How to Build Physical AI Agents: Natural Language for Real-World Robotics(直播和博客)
Diving Deep on Physical AI | S1E4 | Automate with NVIDIA NeMo Agent Toolkit and Bedrock AgentCore(直播)
LeRobot: github.com/huggingface/lerobot - 数据集、策略、硬件驱动
Strands Agents SDK: github.com/strands-agents/harness-sdk
NVIDIA Isaac-GR00T N1.7: GR00T N1.7
NVIDIA Cosmos3 Nano: Cosmos 3 Nano
Cagatay Cali 是 AWS 的研究工程师,专注于智能体 AI 和机器人。他设计连接 AI 智能体到物理机器人的接口,使开发者能够通过自然语言控制机器人系统,并使任何技能水平的构建者都能获得智能体和机器人开发。
Sundar Raghavan 是 AWS 智能体 AI 基础团队的首席解决方案架构师。他领导 Amazon Bedrock AgentCore 的开发者体验,拥有 SDK 和 CLI,并驱动框架和生态系统集成战略。他专注于开发者如何在 AWS 上构建、部署和扩展生产 AI 智能体。他目前正在将这一专注扩展到物理 AI,与 Strands Robots 协作,将相同的智能体开发者体验带到机器人领域。
本文中提及的模型 5
来自此作者的更多内容
From Hugging Face to Amazon SageMaker Studio in one click
Building Blocks for Foundation Model Training and Inference on AWS
很高兴看到!从 MuJoCo sim 到 mode="real" 的单一关键字参数转换(端到端相同的智能体代码、相同的 LeRobotDataset 格式)正是让机器人智能体进入真实实验室的减少摩擦的方式。这样的工作提升了整个行业:我们越容易、越开放地制造智能体到硬件的控制,整个行业发展就越快。Arm 的 Device Connect 团队期待与此协作!
· 注册或登录以发表评论
本文中提及的模型 5