LeRobot 文档

异步推理

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

异步推理

通过我们的 SmolVLA,我们引入了一种在真实机器人上运行推理的新方法,即 将动作预测与动作执行解耦。在本教程中,我们将展示如何使用 SmolVLA 的微调版本以及 LeRobot 支持的所有策略来进行异步推理(async inference)。用 LeRobot 支持的所有策略来尝试异步推理吧!

你将学到什么

  1. 为什么异步推理很重要,以及它与更传统的顺序推理有何不同。
  2. 如何在同一台机器上,甚至通过网络,启动一个 PolicyServer 并连接一个 RobotClient
  3. 如何为你的机器人和策略调整关键参数(actions_per_chunk, chunk_size_threshold)。

如果遇到困难,请加入我们的 Discord 社区

简而言之:通过 异步推理,你的机器人可以持续行动,而策略服务器已经在忙于计算下一个动作块——从而消除了“等待推理”的延迟,并实现了更平滑、更具反应性的行为。这与同步推理(sync)根本不同,同步推理中,机器人在策略计算下一个动作块时处于空闲状态。


异步推理入门

你可以在我们的博客文章中阅读更多关于异步推理的信息。本指南旨在帮助你在你的环境中快速设置和运行异步推理。

首先,使用 async 标签安装 lerobot,以安装运行异步推理所需的额外依赖项。

pip install -e ".[async]"

然后,启动一个策略服务器(在一个终端或另一台机器上),指定客户端要连接的主机地址和端口。你可以通过运行以下命令来启动一个策略服务器:

python src/lerobot/scripts/server/policy_server.py \
    --host=127.0.0.1 \
    --port=8080 \

这将启动一个在 127.0.0.1:8080(即 `localhost`,端口 8080)上监听的策略服务器。此时,策略服务器是空的,因为所有关于运行哪个策略以及使用哪些参数的信息都是在与客户端的第一次握手期间指定的。用以下命令启动一个客户端:

python src/lerobot/scripts/server/robot_client.py \
    --server_address=127.0.0.1:8080 \ # SERVER: the host address and port of the policy server
    --robot.type=so100_follower \ # ROBOT: your robot type
    --robot.port=/dev/tty.usbmodem585A0076841 \ # ROBOT: your robot port
    --robot.id=follower_so100 \ # ROBOT: your robot id, to load calibration file
    --robot.cameras="{ laptop: {type: opencv, index_or_path: 0, width: 1920, height: 1080, fps: 30}, phone: {type: opencv, index_or_path: 0, width: 1920, height: 1080, fps: 30}}" \ # POLICY: the cameras used to acquire frames, with keys matching the keys expected by the policy
    --task="dummy" \ # POLICY: The task to run the policy on (`Fold my t-shirt`). Not necessarily defined for all policies, such as `act`
    --policy_type=your_policy_type \ # POLICY: the type of policy to run (smolvla, act, etc)
    --pretrained_name_or_path=user/model \ # POLICY: the model name/path on server to the checkpoint to run (e.g., lerobot/smolvla_base)
    --policy_device=mps \ # POLICY: the device to run the policy on, on the server
    --actions_per_chunk=50 \ # POLICY: the number of actions to output at once
    --chunk_size_threshold=0.5 \ # CLIENT: the threshold for the chunk size before sending a new observation to the server
    --aggregate_fn_name=weighted_average \ # CLIENT: the function to aggregate actions on overlapping portions
    --debug_visualize_queue_size=True # CLIENT: whether to visualize the queue size at runtime

总之,你需要为以下各项指定指令:

  • SERVER:策略服务器的地址和端口
  • ROBOT:要连接的机器人类型、连接的端口以及机器人的本地 `id`
  • POLICY:要运行的策略类型,以及服务器上要运行的检查点的模型名称/路径。你还需要指定服务器应使用哪个设备,以及一次输出多少个动作(上限为策略的最大动作值)。
  • CLIENT:在向服务器发送新观测数据之前,动作块大小的阈值,以及用于聚合重叠部分动作的函数。或者,你还可以在运行时可视化队列大小,以帮助你调整 `CLIENT` 参数。

重要的是,

  • actions_per_chunkchunk_size_threshold 是需要为你的设置进行调整的关键参数。
  • aggregate_fn_name 是用于聚合重叠部分动作的函数。你可以将新函数添加到函数注册表中,也可以在 robot_client.py 中添加你自己的函数(参见 此处
  • debug_visualize_queue_size 是一个用于调整 `CLIENT` 参数的有用工具。

完成!现在你应该能看到你的机器人在四处移动了 😉

异步推理 vs. 同步推理

同步推理依赖于动作块预测和动作执行的交替进行。这 inherently 导致了 空闲帧,即机器人空闲地等待策略输出:一个新的动作块。反过来,推理过程会受到明显的实时延迟的困扰,机器人会因为没有可用的动作而停止行动。随着机器人模型规模的增大,这个问题只会变得更加严重。

同步推理 会在策略计算下一个动作块时让机器人处于空闲状态。

为了克服这个问题,我们设计了异步推理,这是一种将动作规划和执行解耦的范式,从而实现了 (1) 更高的适应性和,最重要的是,(2) 没有空闲帧。关键在于,通过异步推理,下一个动作块在当前动作块耗尽 之前 就已计算完成,从而避免了空闲。更高的适应性是通过在重叠部分聚合不同的动作块来保证的,从而获得更新的计划和更紧密的控制回路。

异步推理 不会产生空闲,因为下一个动作块在当前动作块耗尽前就已经计算好了。


启动策略服务器

策略服务器是 PreTrainedPolicy 的包装器,用于将它们与来自机器人客户端的观测数据进行接口。策略服务器被初始化为空容器,在机器人客户端和策略服务器之间的初始握手期间,根据请求的策略进行填充。因此,启动一个策略服务器就像指定主机地址和端口一样简单。如果你在与机器人客户端相同的机器上运行策略服务器,你可以使用 localhost 作为主机地址。

命令
API 示例
python -m lerobot.scripts.server.policy_server \
    --host="localhost" \
    --port=8080

这将在 localhost:8080 上监听来自关联 `RobotClient` 的传入连接,`RobotClient` 将在首次客户端-服务器握手期间传达要运行的策略。


启动机器人客户端

`RobotClient` 是 `Robot` 实例的包装器,它将 `RobotClient` 连接到(可能是远程的)`PolicyServer`。`RobotClient` 将观测数据流式传输到 `PolicyServer`,并接收在服务器上运行推理后获得的动作块(我们假设服务器比机器人控制器具有更好的计算资源)。

命令
API 示例
python src/lerobot/scripts/server/robot_client.py \
    --server_address=127.0.0.1:8080 \ # SERVER: the host address and port of the policy server
    --robot.type=so100_follower \ # ROBOT: your robot type
    --robot.port=/dev/tty.usbmodem585A0076841 \ # ROBOT: your robot port
    --robot.id=follower_so100 \ # ROBOT: your robot id, to load calibration file
    --robot.cameras="{ laptop: {type: opencv, index_or_path: 0, width: 1920, height: 1080, fps: 30}, phone: {type: opencv, index_or_path: 0, width: 1920, height: 1080, fps: 30}}" \ # POLICY: the cameras used to acquire frames, with keys matching the keys expected by the policy
    --task="dummy" \ # POLICY: The task to run the policy on (`Fold my t-shirt`). Not necessarily defined for all policies, such as `act`
    --policy_type=your_policy_type \ # POLICY: the type of policy to run (smolvla, act, etc)
    --pretrained_name_or_path=user/model \ # POLICY: the model name/path on server to the checkpoint to run (e.g., lerobot/smolvla_base)
    --policy_device=mps \ # POLICY: the device to run the policy on, on the server
    --actions_per_chunk=50 \ # POLICY: the number of actions to output at once
    --chunk_size_threshold=0.5 \ # CLIENT: the threshold for the chunk size before sending a new observation to the server
    --aggregate_fn_name=weighted_average \ # CLIENT: the function to aggregate actions on overlapping portions
    --debug_visualize_queue_size=True # CLIENT: whether to visualize the queue size at runtime

以下两个参数在每个设置中都至关重要

超参数 默认 它的作用
actions_per_chunk 50 策略一次输出多少个动作。典型值:10-50。
chunk_size_threshold 0.7 当队列中的动作 ≤ 50% 时,客户端会发送一个新的观测数据。值在 [0, 1] 之间。
`actions_per_chunk` 和 `chunk_size_threshold` 的不同值确实会导致不同的行为。

一方面,增加 actions_per_chunk 的值将降低最终没有动作可执行的可能性,因为在计算新动作块时会有更多可用的动作。然而,较大的 actions_per_chunk 值也可能导致动作不够精确,这是由于在较长时间跨度内预测动作所产生的复合误差。

另一方面,增加 chunk_size_threshold 的值会导致更频繁地向 `PolicyServer` 发送观测数据以进行推理,从而产生更多更新的动作块,这些动作块在重要部分上会重叠。这导致了高适应性,在极限情况下,每个观测数据都会预测一个动作块,而这个动作块在产生新动作块时仅被少量消耗。这种选择也给推理管道带来了更大的压力,因为请求数量很多。相反,接近 0.0 的 chunk_size_threshold 值会退化到同步的边缘情况,即只有在当前动作块耗尽时才发送新的观测数据。

我们发现,在我们为 SmolVLA 论文 开发的实验中,`actions_per_chunk` 和 `chunk_size_threshold` 的默认值效果很好,但建议尝试不同的值以找到最适合你设置的值。

为你的设置调整异步推理

  1. 仔细选择你的计算资源。 PI0 在推理时占用 14GB 内存,而 SmolVLA 仅需约 2GB。你应该根据你的用例确定最佳的计算资源,同时记住较小的策略需要较少的计算资源。策略和所用设备(CPU 密集型、使用 MPS 或给定 NVIDIA GPU 上的 CUDA 核心数)的组合直接影响你应预期的平均推理延迟。
  2. 根据推理延迟调整你的 `fps`。 当服务器生成新的动作块时,客户端并非空闲,而是在执行其当前的动作队列。如果这两个过程的速度根本不同,客户端可能会最终导致队列为空。因此,如果你持续地耗尽队列中的动作,你应该降低你的 fps。
  3. 调整 chunk_size_threshold.
    • 接近 0.0 的值会导致近乎顺序的行为。接近 1.0 的值 → 每一步都发送观测数据(带宽更大,依赖于良好的世界模型)。
    • 我们发现 0.5-0.6 左右的值效果很好。如果你想调整这个值,可以启动一个 `RobotClient`,并将 `--debug-visualize-queue-size` 设置为 `True`。这将在运行时绘制动作队列大小的变化图,你可以用它来找到最适合你设置的 `chunk_size_threshold` 值。

当传递 `--debug-visualize-queue-size` 标志时,会在运行时绘制动作队列大小,针对不同级别的 `chunk_size_threshold`(在 SmolVLA 论文中为 `g`)。


结论

异步推理代表了实时机器人控制领域的重大进步,解决了长期困扰机器人应用的推理延迟这一根本性挑战。通过本教程,你已经学会了如何实现一个完整的异步推理管道,该管道可以消除空闲帧,并实现更平滑、更具反应性的机器人行为。

关键要点

  • 范式转变:异步推理将动作预测与执行解耦,允许机器人在并行计算新动作块的同时继续行动。
  • 性能优势:消除了同步方法中固有的“等待推理”延迟,随着策略模型越来越大,这一点变得越来越重要。
  • 灵活的架构:客户端-服务器设计支持分布式计算,推理可以在强大的远程硬件上运行,同时保持实时机器人控制。
  • 可调参数:成功与否取决于为你的特定硬件、策略和任务需求正确配置 actions_per_chunkchunk_size_threshold
  • 通用兼容性:适用于所有 LeRobot 支持的策略,从轻量级的 ACT 模型到像 SmolVLA 这样的视觉-语言模型。

从默认参数开始实验,监控你的动作队列大小,并迭代地优化你的设置,以为你的特定用例实现最佳性能。如果你想进一步讨论这个问题,请加入我们的 Discord 社区,或在我们的 GitHub 仓库中提出问题。

< > 在 GitHub 上更新