概述
pi0 接收相机图像、任务文本和机器人 state,输出一段未来 action。PhyAI 的ws1 路径把整条推理链留在一张 GPU 上:vision 与 language stack 先生成可复用的 prefix,action expert 再结合 prefix 和机器人 state,通过 flow matching 把噪声逐步还原成 action chunk。
PI0WS1Scheduler 只实现这条单卡路径,不承担 tensor parallel、continuous batching 或 preemption。
pi0 把 robot state 保留为 expert 侧的数值 token;pi0.5 则先把 state 离散成 bins,再写入语言 prompt。
架构
请求先通过 进入 PhyAI。PI0Entry 负责构造模型和 scheduler,三个 runner 分别接管 vision、prefix 与 expert 计算。代码分布在这些文件中:
phyai/src/phyai/models/pi0
main_pi0.py
scheduler_ws1_pi0.py
model_runner_pi0.py
modeling_pi0.py
configuration_pi0.py
模型布局
代码分散在几个模块中,数据却始终沿着一条路径流动。SigLIP 把相机图像变成 tokens,PaliGemma 将它们与任务文本合并,较小的 Gemma expert 最后生成 action 轨迹。
三部分计算共用一组顶层几何配置:
params_dtype 控制 language 与 expert stacks 的参数精度。Vision tower 使用独立的 vision_params_dtype,默认保留 fp32,以便和参考实现对齐。只有实验本身需要 bf16 vision 时,才传入 PI0Args(vision_params_dtype=torch.bfloat16)。
请求格式
运行时,PI0Request 承接 processor 的输出,并把模型所需的 tensor 交给 scheduler:
B 可以取 1 到 max_batch_size 之间的任意值。较小的 batch 会在 scheduler 内部补到 captured shape,返回前再切回 actual_B。
调度阶段
请求进入engine.step 后,scheduler 按顺序执行这些阶段:
Prefix 在 denoising 期间不会改变,因此每个 request 只需缓存一次。State query 与 action query 随后读取不同范围的 cache:
1 + chunk_size,由一个 state token 和随后的 action tokens 组成。
CUDA graphs
请求形状固定后,runner 才能复用 CUDA graph。启用RuntimeConfig(use_cuda_graph=True) 时,每个 runner 都会在 scheduler.setup() 期间捕获自己的 graph:
每次处理请求时,runners 先刷新 static input buffers,再 replay 已捕获的 graph。Attention metadata 留在 captured region 之外,通过 backend 的 capture-aware buffers 写入。
运行 pi0
1
准备权重
使用包含
config.json 和 model.safetensors 的 HF-style pi0 PyTorch checkpoint 目录。只有检查执行链路时,才省略 --checkpoint 并使用随机权重。2
构造 Engine
选择
"pi0" plugin。构造 Engine 时会加载可选 checkpoint、准备 runners,并在启用时捕获 CUDA graph。max_batch_size 会成为 captured shape 的一部分;修改它需要重建 Engine。3
构造请求
phyai-utils-tools 中的 PI0Processor 负责把原始机器人观测转换成 PI0Request 所需的 tensor。4
运行一步
action_dim,processor.postprocess(actions) 会裁掉 padding 的 action 宽度;存在 dataset stats 时,还会把 action 还原到原始量纲。5
关闭 Engine
端到端示例
examples/pi0/run_pi0.py 既能使用 processor 构造请求,也能直接走 raw smoke 路径。带 checkpoint 时这样运行:
性能测试与分析
使用benchmark/bench_n_batch_ws1_pi0.py,可以在同一套 scheduler 配置下比较不同 batch size:
--vision-dtype bfloat16。
当前限制
CUDA graph 能够复用,前提是请求形状保持固定。PI0WS1Scheduler 构造单卡 Engine 时会固定 max_batch_size,graph capture 还会固定相机数量、图像尺寸和 tokenizer 长度。任何一项发生变化,都需要重建 Engine。Vision tower 则按真实 batch 中的样本逐个 replay,并不会把这些样本合成一次 vision batch。
Scheduler 的边界从预处理之后开始。图像 resize、tokenization、state padding 和 action unnormalize 都由 PI0Processor 完成;直接传给 Engine 的请求必须已经满足这一输入约定。

