LeRobot 文件
非同步推理
並獲得增強的文件體驗
開始使用
非同步推理
透過我們的 SmolVLA,我們引入了一種在真實機器人上執行推理的新方法,即 將動作預測與動作執行解耦。在本教程中,我們將展示如何使用 SmolVLA 的微調版本以及 LeRobot 支援的所有策略來進行非同步推理(async inference)。用 LeRobot 支援的所有策略來嘗試非同步推理吧!
你將學到什麼
- 為什麼非同步推理很重要,以及它與更傳統的順序推理有何不同。
- 如何在同一臺機器上,甚至透過網路,啟動一個
PolicyServer
並連線一個RobotClient
。 - 如何為你的機器人和策略調整關鍵引數(
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_chunk
和chunk_size_threshold
是需要為你的設定進行調整的關鍵引數。aggregate_fn_name
是用於聚合重疊部分動作的函式。你可以將新函式新增到函式登錄檔中,也可以在robot_client.py
中新增你自己的函式(參見 此處)debug_visualize_queue_size
是一個用於調整 `CLIENT` 引數的有用工具。
完成!現在你應該能看到你的機器人在四處移動了 😉
非同步推理 vs. 同步推理
同步推理依賴於動作塊預測和動作執行的交替進行。這 inherently 導致了 空閒幀,即機器人空閒地等待策略輸出:一個新的動作塊。反過來,推理過程會受到明顯的即時延遲的困擾,機器人會因為沒有可用的動作而停止行動。隨著機器人模型規模的增大,這個問題只會變得更加嚴重。
同步推理 會在策略計算下一個動作塊時讓機器人處於空閒狀態。
為了克服這個問題,我們設計了非同步推理,這是一種將動作規劃和執行解耦的正規化,從而實現了 (1) 更高的適應性和,最重要的是,(2) 沒有空閒幀。關鍵在於,透過非同步推理,下一個動作塊在當前動作塊耗盡 之前 就已計算完成,從而避免了空閒。更高的適應性是透過在重疊部分聚合不同的動作塊來保證的,從而獲得更新的計劃和更緊密的控制迴路。
非同步推理 不會產生空閒,因為下一個動作塊在當前動作塊耗盡前就已經計算好了。
啟動策略伺服器
策略伺服器是 PreTrainedPolicy
的包裝器,用於將它們與來自機器人客戶端的觀測資料進行介面。策略伺服器被初始化為空容器,在機器人客戶端和策略伺服器之間的初始握手期間,根據請求的策略進行填充。因此,啟動一個策略伺服器就像指定主機地址和埠一樣簡單。如果你在與機器人客戶端相同的機器上執行策略伺服器,你可以使用 localhost
作為主機地址。
python -m lerobot.scripts.server.policy_server \
--host="localhost" \
--port=8080
這將在 localhost:8080
上監聽來自關聯 `RobotClient` 的傳入連線,`RobotClient` 將在首次客戶端-伺服器握手期間傳達要執行的策略。
啟動機器人客戶端
`RobotClient` 是 `Robot` 例項的包裝器,它將 `RobotClient` 連線到(可能是遠端的)`PolicyServer`。`RobotClient` 將觀測資料流式傳輸到 `PolicyServer`,並接收在伺服器上執行推理後獲得的動作塊(我們假設伺服器比機器人控制器具有更好的計算資源)。
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
的值將降低最終沒有動作可執行的可能性,因為在計算新動作塊時會有更多可用的動作。然而,較大的 actions_per_chunk
值也可能導致動作不夠精確,這是由於在較長時間跨度內預測動作所產生的複合誤差。
另一方面,增加 chunk_size_threshold
的值會導致更頻繁地向 `PolicyServer` 傳送觀測資料以進行推理,從而產生更多更新的動作塊,這些動作塊在重要部分上會重疊。這導致了高適應性,在極限情況下,每個觀測資料都會預測一個動作塊,而這個動作塊在產生新動作塊時僅被少量消耗。這種選擇也給推理管道帶來了更大的壓力,因為請求數量很多。相反,接近 0.0 的 chunk_size_threshold
值會退化到同步的邊緣情況,即只有在當前動作塊耗盡時才傳送新的觀測資料。
我們發現,在我們為 SmolVLA 論文 開發的實驗中,`actions_per_chunk` 和 `chunk_size_threshold` 的預設值效果很好,但建議嘗試不同的值以找到最適合你設定的值。
為你的設定調整非同步推理
- 仔細選擇你的計算資源。 PI0 在推理時佔用 14GB 記憶體,而 SmolVLA 僅需約 2GB。你應該根據你的用例確定最佳的計算資源,同時記住較小的策略需要較少的計算資源。策略和所用裝置(CPU 密集型、使用 MPS 或給定 NVIDIA GPU 上的 CUDA 核心數)的組合直接影響你應預期的平均推理延遲。
- 根據推理延遲調整你的 `fps`。 當伺服器生成新的動作塊時,客戶端並非空閒,而是在執行其當前的動作佇列。如果這兩個過程的速度根本不同,客戶端可能會最終導致佇列為空。因此,如果你持續地耗盡佇列中的動作,你應該降低你的 fps。
- 調整
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_chunk
和chunk_size_threshold
。 - 通用相容性:適用於所有 LeRobot 支援的策略,從輕量級的 ACT 模型到像 SmolVLA 這樣的視覺-語言模型。
從預設引數開始實驗,監控你的動作佇列大小,並迭代地最佳化你的設定,以為你的特定用例實現最佳效能。如果你想進一步討論這個問題,請加入我們的 Discord 社群,或在我們的 GitHub 倉庫中提出問題。
< > 在 GitHub 上更新