pi05-edge · Physical Intelligence π0.5(openpi pi05_libero)→ Jetson AGX Orin · LIBERO 闭环评测 + 性能解剖
任务 · LIBERO spatial:Franka 机械臂把桌上的黑碗拿起、放到盘子上(十个任务只是碗的初始位置不同——盘与ramekin之间、桌面中央、饼干盒上、ramekin 上等)。每段视频是一个完整回合:策略看一帧观测 → 输出 10 步动作 → 执行前 5 步 → 重规划,直到成功或超步数。
形态 · 跨机桥接:π0.5 策略跑在 Jetson AGX Orin(websocket server),LIBERO 仿真跑在另一台机器(client),二者用 openpi 官方的 client/server 协议对接——这正是上游 examples/libero 的架构,只是拆到两台物理机。
⚠ 画面是模型看到的 agentview(已按训练预处理旋转 180°),非人眼原始渲染;以 20 Hz 控制节奏播放(1 帧 = 1 个控制步 = 50 ms 机器人时间)。LIBERO 官方评测循环没有实时 pacing,故成功率与推理延迟是两条独立的轴——视频展示「策略能否完成任务」,延迟/实时性见「评测结果」。
四段均为 num_steps=10(官方默认)下的成功回合,取自本次 demo 录像跑(seed 7、固定初始状态,与「评测结果」表 2 同一 server 配置)。完整逐 task 成功率见评测结果;更多任务的 rollout 见仓库 results/。
测试数据集与协议:LIBERO spatial 套件(10 个任务,每配置 10 task × 10 trial = 100 episode,一 trial 一固定初始状态,seed 7),照 openpi 官方 examples/libero 协议——replan_steps=5、20 Hz 控制、成功判据 = 环境返回的 done。延迟在 Orin 上测两口径:L1 = 本地纯推理墙钟(in-process,不含网络),L2 = obs→Orin→action 端到端往返(跨机 websocket,client 侧计时)。官方报告值 spatial = 98.8(500 ep);本页 100 ep 为缩减样本,是校准(证明 harness 正确)而非超越。
| num_steps | 成功率(100 ep) | misses | boosted L1 | throttled L1(闭环) | L2(端到端) |
|---|---|---|---|---|---|
| 10(默认) | 99/100 = 99% | task9 ×1 | 515 ms | 585 ms | 593 ms |
| 5 | 100/100 = 100% | 无 | 441 ms | 517 ms | 524 ms |
| 1(地板) | 98/100 = 98% | task4 ×1, task7 ×1 | 383 ms | 458 ms | 465 ms |
结论:在 libero_spatial 上把去噪步数从 10 减到 1 基本免费——三档成功率全落在 98–100%(100 ep 二项噪声内),misses 是分散的单 ep 噪声(不集中在某难 task),与 π0.5 用(近)rectified flow(流路径近似直线、单步 Euler 积分即够)一致。延迟随 num_steps 线性下降(每步 ~14.7 ms),boosted 与 throttled 两口径同步,交叉验证了下面的延迟分解。
| 组件 | 是什么 | 耗时 | 占 L(10) |
|---|---|---|---|
| prefix(跑 1 次) | SigLIP 图像编码 + Gemma 2B prefill,填 KV cache | 368 ms | 71% |
| ├ SigLIP 图像编码 | 2×224² RGB → image tokens | ~100 ms | ~19% |
| └ Gemma 2B prefill | 读图+文 token、填 KV cache——整次推理的最大单块 | ~210 ms | ~41% |
| per denoising step | Gemma 300M action expert,flow-matching 去噪(× num_steps) | 14.7 ms/步 | 29%(@10 步) |
线性度检查:implied per_step = (L(N)−prefix)/N 在 N=1/2/3/5/10 全落在 14.6–14.8 ms(完美线性)⇒ 分解可信。延迟被 backbone prefix 主导(71%),减 num_steps 只能砍那 29%——num_steps=1 也只到 383 ms(prefix 368 ms 是地板)。prefix 细分口径:各阶段单独 JIT 计时(g4_prefix_profile.py,SigLIP 100.3 + Gemma 2B 209.6 ≈ 310 ms 模型前向),对扫描反解的 368 ms 有 ~54 ms 残差 = preprocess(~4 ms)+ 噪声生成 + while_loop 控制 + 「单独 JIT vs 融合 JIT」测量口径差(非模型前向,如实标注)⇒ G5 压延迟第一靶子 = Gemma 2B prefill。
| 配置 | 预算 | 用哪个 L1 | 占空比 | 20 Hz 实时? |
|---|---|---|---|---|
| 官方 replan=5(同步) | 250 ms | throttled 585 | 235% | ✗ 远超 |
| replan=10(同步) | 500 ms | throttled 585 | 117% | ✗ 超支 |
| replan=10 + async prefetch | 500 ms | boosted 504 | ~101% | ⚠ 贴边 |
| replan=10 + num_steps=5 + prefetch | 500 ms | boosted 441 | 88% | ✓ 延迟轴可行 |
🔴 但 prefetch 撞上第二堵墙:推理 ≈ 一个 chunk 执行时间 ⇒ prefetch 必须提前 1 整 chunk 用旧 obs 推理 ⇒ obs 陈旧毁掉成功率(实测同 task/seed:sync replan=10 = 6/6 vs prefetch replan=10 = 0/6)。⇒ Orin 上 π0.5「20 Hz 实时」与「准确」不可兼得:要么 sync(新鲜 obs、准确,但机器人等待 + DVFS 降频、有效 ~9–10 Hz),要么 prefetch(实时可行但 obs 陈旧、成功率崩)。出路只有更快推理压 prefix(把 383 ms 地板再压到 <250 ms,需 TRT/量化)或更低控制频率。
实时性的核心不等式:T_infer ≤ H / f_control(一次推理时间 ≤ H 步动作的物理执行时间)——提高控制频率只会让预算 H/f_control 更小、实时更不可行(控制步是机器人物理时间、非计算,动作幅度按 20 Hz 标定);业界解法(temporal ensembling / 压模型 / 分层解耦控制)详见 REPORT.md 讨论节。
计时口径:L1 不是常数——由 GPU DVFS 主导,分 boosted(背靠背/async prefetch,GPU 持续忙、~1300 MHz,487–515 ms)与 throttled(同步闭环,GPU 两次推理间空转掉到 306 MHz 地板、每次从低频爬坡,570–587 ms)两口径;报任何 L1 必须标明。L3 = LIBERO 期望控制频率 = 20 Hz(源码核实)。诚实边界:单 seed、100 ep(官方 500)、仅 libero_spatial(最易套件,十 task 同质「pick black bowl」);更难套件(libero_10 官方 92.4、更灵巧)可能对减步更敏感,「减步免费」结论 scope 限本套件。纯仿真、无真机;模型层零贡献(用官方 fine-tuned 权重)。
图 1 · π0.5 两段式推理与控制环:观测 → prefix(SigLIP ~100 + Gemma 2B prefill ~210 ms,跑 1 次,共 368 ms)→ action expert(Gemma 300M,去噪 × num_steps,14.7 ms/步)→ action chunk (10,7) → 机器人执行前 5 步 → replan 回到观测
输入 / 输出:系统每次查询吃一帧观测——observation/image (224,224,3) uint8(agentview)+ observation/wrist_image (224,224,3) uint8(腕部)+ observation/state (8,) float(末端位姿 3 + 轴角 3 + 夹爪 2)+ prompt 字符串;吐一个 actions (10, 7) float 动作块(10 步 × 7 维 = 6 DoF 位姿增量 + 夹爪)。原始渲染 256²,client 端 resize_with_pad 到 224 并旋转 180° 以匹配训练预处理。
两段式推理(延迟解剖的对象):sample_actions 先跑 prefix 一次(SigLIP 图像编码 + Gemma 2B prefill,填 KV cache,368 ms),再跑 去噪循环 num_steps 次(Gemma 300M action expert 沿 flow-matching ODE 从噪声积分到动作,每步 14.7 ms)。故 L(N) = prefix + N × per_step——prefix 是地板(71%),减 num_steps 只动那 29%。prefix 再拆一层:SigLIP ~100 ms + Gemma 2B prefill ~210 ms——Gemma 2B prefill 是整次推理的最大单块(41%),是 G5 压缩的第一靶子。num_steps 是 sample_actions 的关键字参数,经 policy._sample_kwargs 注入,无需改 openpi 源码即可扫描。
部署:openpi 源码 @ 215abfb + jetson-containers 29 包链 → 自包含镜像(33.9 GB,jax 0.5.3 + XLA_FLAGS 已烘焙,绕开 Tegra sm_87 的 GemmFusionAutotuner 崩溃)。client 端不装 torch——LIBERO 的 .pruned_init 是 torch.save 的 ZIP 壳但 payload 是纯 numpy pickle,用 zip+pickle 直读即可,守住仿真机 pin 死的 numpy 1.22.4 栈。完整方法学(来源/版本/口径/复现命令)见 METHODOLOGY.md,结果与讨论见 REPORT.md,踩坑见 PROBLEMS.md。