技术博客
VLA教程

【三分钟看懂Jetson-PI】把 VLA 从 4090 搬进机器人:Jetson-PI 的端侧异步推理与部署

yiwan-cat2026-08-13 13:09
【三分钟看懂Jetson-PI】把 VLA 从 4090 搬进机器人:Jetson-PI 的端侧异步推理与部署

π0.5 在 Jetson Orin 上从 0.70 Hz 提升到 6.06 Hz,关键不只是“把模型跑快”,而是让感知、预测、执行和底层引擎一起适配端侧延迟。

图 1 Jetson-PI 工程部署概念封面:机器人在机身内完成感知、异步预测与动作执行(封面图)


在 RTX 4090 上运行 VLA,模型慢一点,通常还能靠算力顶住。可一旦把 π0、π0.5 这类模型塞进机器人机身,事情就变了。

论文给出的测试中,π0.5 在 Jetson Orin 上完成一次完整推理需要 1420.8 ms。如果机器人每次都等动作块生成完再执行,控制频率只有 0.70 Hz:摄像头看到环境变化后,机械臂可能一秒多以后才给出新反应。

换成 4090 虽然更快,却要付出功耗、续航和活动范围的代价。论文用 500 Wh 电池估算了三类机器人平台,包含机械功耗后,4090 配置的续航相较 Orin 最多缩短到约六分之一。这个数字不是所有机器人的通用比例,但它把工程矛盾说得很直白:VLA 能在工作站上演示,不等于能在移动机器人上长期工作。

图 2 不同计算设备的续航、功耗与 VLA 控制频率对比


北京大学、AIRS 与 PrimeBot Research Institute 等机构的研究团队因此提出 Jetson-PI。它没有把希望全部押在量化或剪枝上,而是同时处理三件事:

  • 用前瞻对齐异步修正,解决“模型看到的是过去,动作执行在未来”的错位;

  • 用置信度调度,决定什么时候必须重新看环境,什么时候只调用更快的动作专家;

  • 用 Jetson-PI-Edge 重做端侧推理路径,减少建图、内存搬运和重复调度。

最终,论文报告 π0.5 在 Jetson Orin 上的完整推理时间降至 412.9 ms,平均反应时间进一步降至 165.1 ms,对应策略更新频率 6.06 Hz,是原生 PyTorch 的 8.66 倍

这里要先分清三个经常被混用的数字:

指标 论文中的含义 Jetson Orin 最终结果
完整推理时间 ViT、LLM 与动作专家完整跑一轮的时间 412.9 ms
反应时间 环境变化到新动作能够响应的平均间隔 165.1 ms
控制频率 论文按反应时间折算的策略更新频率 6.06 Hz

真实机器人实验中的 15 Hz 则是动作执行频率,不是完整 VLA 每秒运行 15 次。Jetson-PI 依靠动作缓存和异步流水线,让低频策略更新与高频动作执行并行发生。

异步推理消除了停顿,也制造了新的错位

同步推理的问题最容易理解:机器人执行完当前动作块,停下来等模型生成下一块,再继续动作。推理越慢,停顿越明显。

朴素异步推理让机器人一边执行当前动作,一边预测下一块,看起来解决了停顿。但模型开始推理时使用的是时刻 $t$ 的图像;等推理完成,机器人已经执行了若干动作,环境来到 $t+\Delta$。新动作真正落地时,模型依据的画面早已过期。

更棘手的是,过去的方法即使预测了未来机器人关节状态,也没有描述布料、碗、托盘等外部物体会怎样变化。延迟越长,单纯预测机器人自身状态越不够用。


图 3 Jetson-PI 总览:同步停顿、朴素异步错位,以及前瞻修正后的连续更新

Jetson-PI 的核心思路可以压缩成一句话:

不去生成一张昂贵的“未来图像”,而是预测动作执行完以后,VLM 最后一层会形成什么环境表征。

这个轻量模块接收两类输入:当前 VLM 最后一层的压缩隐藏状态,以及已经提交给机器人、在推理期间必然会执行的动作序列。它预测 $t+\Delta$ 时刻的压缩环境表征,再把这份“未来信息”交给动作专家,让下一段动作从未来执行时刻开始生成。

它没有修正每一层 KV Cache,也没有生成完整像素。附录给出的实现先用 Q-Former 将 VLM 最后一层压缩到 4 个 token,再结合动作序列预测修正项。整个未来修正模块约 40M 参数,约占完整 VLA 的 1%


图 4 前瞻对齐异步修正与置信度调度:预测未来表征,并在必要时刷新 VLM


图 5 未来修正模块内部结构:动作编码、Q-Former 压缩、修正头与置信度头


什么时候继续“凭经验走”,什么时候必须重新看一眼

如果始终只靠未来修正模块递推,预测误差会不断累积;如果每一步都重新调用 VLM,反应时间又会回到原点。

Jetson-PI 为修正模块增加了置信度头。置信度高时,系统跳过 VLM,复用现有 KV Buffer,只运行未来修正模块和动作专家;置信度低于阈值时,系统读取最新摄像头画面,重新调用 VLM,并刷新隐藏状态与 KV 缓存。

这不是简单的“固定每 N 步看一次”。抓取、接触、放置等阶段环境变化更难预测,置信度会下降并触发重新观察;平稳移动阶段则可以让动作专家高频工作。

图 6 单次任务中的置信度变化:抓取和放置附近明显下降


一个很有工程味的结论是:团队没有在 Orin 上强行并行 VLM 和动作专家。论文的 Roofline 分析显示,4090 上的 VLM 更偏计算受限,VLM 与动作专家并行可以利用不同资源;但 Orin 的内存带宽更紧,两者都容易变成带宽受限,同时运行反而会争抢带宽。因此 Jetson-PI 选择“按置信度调度调用”,而不是盲目并行。

Jetson-PI-Edge 为什么能把 1.4 秒压到 412.9 毫秒

算法解决“何时算”和“从哪个时刻预测”,底层引擎解决“每次怎么算得更省”。Jetson-PI-Edge 基于 llama.cpp,针对 VLA 的固定输入形态做了三项关键优化。

第一,计算图复用。摄像头数量、图像分辨率和动作维度固定后,VLA 每轮推理的张量形状基本不变。将短指令 padding 到固定长度后,首轮建立的 CUDA Graph 可以重复使用。

第二,GPU 常驻中间缓存。ViT、LLM 和动作专家之间传递视觉 embedding、KV Cache 等中间结果时,不再每轮写回 CPU 再传回 GPU。

第三,Flow Matching 展开。π0.5 的动作专家需要执行 10 步去噪。引擎把多步 Flow Matching 展开到统一计算图中,减少多次建图、调度和 kernel launch。首轮建图会更重,但后续控制循环可以持续复用。

图 7 Jetson Orin 与 Jetson Thor 上各阶段延迟、反应时间和控制频率


在 Orin 上,仅做置信度调度并不会改变一次完整 VLA 的 1420.8 ms 总耗时,但平均反应时间先降到 674.9 ms;加入图复用后,总耗时降到 476.1 ms;再加入 GPU 中间缓存和 Flow Matching 展开,总耗时降到 412.9 ms,动作专家从 536.8 ms 降到 123.1 ms。

这些优化没有修改模型计算本身,因此原则上可以继续叠加量化、剪枝等方法。不过这只是技术上的正交性,不代表任意量化方案都能无损叠加,精度和算子支持仍要单独验证。

快速开始:先在 Jetson 上跑通一次 π0.5 推理

这套项目有两个仓库,第一次使用时很容易下错:

仓库 主要用途 适合谁
Jetson-PI FAAC 训练、LIBERO 评估、置信度调度研究代码 想复现实验或训练未来修正模块
Jetson-PI-Edge GGUF 推理、CUDA 图优化、HTTP/Python/C API 想把模型跑在 Jetson 或其他 CUDA 设备

如果目标是“先在端侧跑起来”,直接从 Jetson-PI-Edge 开始。下面流程依据仓库截至 2026 年 8 月 13 日的接口整理。

1. 编译 CUDA 版本服务端

设备上需要能正常使用 CUDA 编译工具链、CMake 和 Git。官方仓库没有把 Quick Start 锁死到某个 JetPack 小版本,因此先以本机 JetPack/CUDA 的兼容组合为准,不要直接照抄桌面 4090 的 CMAKE_CUDA_ARCHITECTURES=89

git clone https://github.com/PKU-SEC-Lab/Jetson-PI-Edge.git
cd Jetson-PI-Edge

cmake -S . -B build \
  -DGGML_CUDA=ON \
  -DCMAKE_BUILD_TYPE=Release

cmake --build build --target llama-server -j

如果只是验证代码路径,也可以去掉 -DGGML_CUDA=ON 编译 CPU 版本,但这不代表 CPU 能满足实时机器人控制。

2. 下载现成的 π0.5 GGUF

仓库当前已经提供预转换的 PI0、PI0.5 和 GR00T N1.7 GGUF。跑 π0.5 需要同一目录下匹配的主模型与视觉投影模型,不能混用 PI0 的 mmproj

python3 -m pip install -U huggingface_hub

huggingface-cli download diantoudefengshan/Jetson-PI-GGUF \
  pi05/pi_llm.gguf \
  pi05/mmproj-model-f16.gguf \
  --local-dir ./models/Jetson-PI-GGUF

如果使用自己的 π0/π0.5 权重,需要先运行仓库的 pi0_surgery.py 拆出语言/动作与视觉部分,再分别转换为 pi_llm.ggufmmproj-model-f16.gguf。这一流程还要求补齐 config.json 中的 PI 架构字段;自定义模型结构与基础 π 模型不同的,不能照搬默认参数。

3. 启动常驻推理服务

PI_MODEL=pi05 \
./build/bin/llama-server \
  -m ./models/Jetson-PI-GGUF/pi05/pi_llm.gguf \
  --mmproj ./models/Jetson-PI-GGUF/pi05/mmproj-model-f16.gguf \
  -ngl 99 \
  --host 127.0.0.1 \
  --port 8080

官方示例使用 0.0.0.0 方便机器人控制进程从局域网访问。只在本机测试时使用 127.0.0.1 更稳妥;需要跨设备访问时再开放监听地址,并配合局域网隔离和访问控制。

服务端应保持常驻。模型、CUDA 上下文和计算图如果每个控制周期都重新加载,前面的优化就失去意义。

4. 通过 HTTP 跑通一个动作块

先重置任务会话:

curl -X POST http://127.0.0.1:8080/foreground/reset

按模型训练时约定的顺序提交两路图像。路径必须是服务端进程能访问的本地绝对路径:

curl -X POST http://127.0.0.1:8080/foreground/image \
  -H 'Content-Type: application/json' \
  -d '{"path":"/abs/path/to/head.png"}'

curl -X POST http://127.0.0.1:8080/foreground/image \
  -H 'Content-Type: application/json' \
  -d '{"path":"/abs/path/to/wrist.png"}'

再提交归一化后的机器人状态。下面 32 维向量来自官方接口示例,只用于验证数据通路,不能直接当成你自己机械臂的真实状态:

curl -X PUT http://127.0.0.1:8080/foreground/state \
  -H 'Content-Type: application/json' \
  -d '{"state":"1.8731,-1.0370,1.9652,7.0876,0.2546,-9.1432,-0.0147,-0.5037,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"}'

最后提交指令:

curl -X POST http://127.0.0.1:8080/foreground/infer \
  -H 'Content-Type: application/json' \
  -d '{"text":"pick up the object and place it into the tray"}'

返回结果中的 action_final 是最终动作块;encode_msdecode_mstotal_mstiming_breakdown_ms 可用于定位瓶颈。若要做可重复的数值回归测试,可以通过 PI0_ACTION_NOISE_BIN 固定初始动作噪声。

5. Python 中保持长会话

仓库也提供托管式 Python 客户端,适合接入现有机器人控制程序:

import numpy as np
from jetson_pi_foreground import ManagedForegroundSession

session = ManagedForegroundSession(
    server_path="./build/bin/llama-server",
    model_path="./models/Jetson-PI-GGUF/pi05/pi_llm.gguf",
    mmproj_path="./models/Jetson-PI-GGUF/pi05/mmproj-model-f16.gguf",
    gpu=0,
    port=8080,
    timeout=300,
)

state = np.asarray([
    -1.8731, -1.0370, 1.9652, 7.0876,
     0.2546, -9.1432, -0.0147, -0.5037,
] + [0] * 24, dtype=np.float32)

try:
    action, meta = session.predict(
        image_paths=["/abs/path/to/head.png", "/abs/path/to/wrist.png"],
        prompt="pick up the object and place it into the tray",
        state=state,
        reset=True,
    )
    print("action shape:", action.shape)
    print("total_ms:", meta.get("total_ms"))
finally:
    session.close()

真实控制循环中不要每轮创建 ManagedForegroundSession。应长期复用同一个会话,只在新任务、状态污染或显式重新初始化时 reset=True

从“能输出动作”到“能控制机器人”,还差这五步

跑通 action_final 只证明推理链路可用。真正接入机器人,还要完成下面的适配:

  1. 相机顺序与预处理一致。 图像上传顺序必须匹配训练 checkpoint 的视角约定;每轮推理都要提交新图像。
  2. 状态归一化一致。 关节位置、末端位姿和夹爪状态的排列、维度、单位与 norm_stats 必须和训练数据一致。
  3. 动作反归一化与坐标系转换。 检查 action_final 是否已经应用 checkpoint 的分位数反归一化,再映射到实际控制器需要的关节或笛卡尔指令。
  4. 动作缓存与执行频率解耦。 VLA 负责低频更新动作块,控制器以固定高频率消费缓存;新旧动作块切换处还需要限速、限加速度和必要的插值。
  5. 安全层不能省。 上电前先离线记录动作,再做仿真或悬空测试,最后逐步开放真实执行;关节限位、工作空间、碰撞检测、急停和超时回退应独立于 VLA。

第一次推理还会承担建图和缓存初始化成本,不能直接拿首轮延迟当稳定性能。建议先预热多轮,再统计 encode_msdecode_mstotal_ms 的中位数和高分位,并同时记录功耗、温度与降频状态。

真实机器人结果很亮眼,但别把 30 次试验写成工业验证

论文在 X2-W 机器人上测试衣物拾取、折叠和放置,每个条件每项 10 次。Jetson-PI 在 Orin 上分别完成 10/10、8/10、9/10;4090 基线为 10/10、7/10、10/10;朴素异步只有 6/10、0/10、5/10

图 8 X2-W 真实机器人三项子任务结果:拾取、折叠与放置


这组结果说明,未来环境表征比单纯“边执行边推理”更能抵抗长延迟造成的错位。但每项只有 10 次,且论文没有给出长时间热稳定性、不同机器人平台的大规模统计或安全认证,因此更准确的表述是:Jetson-PI 已证明端侧复杂操作具有可行性,而不是已经完成工业级通用验证。

还有一个代码边界需要注意:截至本文整理时,Jetson-PI-Edge 已支持 π0、π0.5 和 GR00T N1.7 的端侧推理;但论文中的 FAAC、置信度调度与主要成功率结论是围绕 π0.5 验证的。不能因为引擎已经能跑 GR00T,就自动把论文的 8.66 倍和成功率结论迁移到 GR00T。

Jetson-PI 真正值得关注的,不是一个加速数字

Jetson-PI 最有价值的地方,是它把端侧 VLA 的问题重新拆对了:

  • 推理无法瞬间完成,就让预测对齐到未来执行时刻;

  • VLM 太慢,就只在环境难以预测时重新观察;

  • 端侧带宽紧,就减少 CPU/GPU 往返和重复图调用;

  • 策略更新不够高频,就让动作缓存承担连续执行。

这套思路比“把工作站上的 PyTorch 脚本原样搬到 Jetson”更接近真正的机器人系统。对于准备做 π0/π0.5 端侧部署的人,最实际的起点也很清楚:先用 Jetson-PI-Edge 和现成 GGUF 跑通一次完整动作块,确认图像、状态、指令与动作接口;再把自己的 checkpoint、归一化统计和控制器接进去;最后才是 FAAC 训练、调度阈值和性能优化。


项目与论文

点赞收藏
// 评论0
0 / 500
还没有评论,快来抢沙发