一条推理请求的一生:从观测到动作

openpi_Codebase/openpi_Codebase/openpi_Inference_Path.md

观测进来 → 先「整理+缩放」成模型认识的张量 → 模型「采样」出动作 → 再「还原」成机器人能执行的格式。

渲染流程图…

下面分两部分:先看策略对象怎么一次性组装好,再看每次请求怎么走

先弄清两个词

  • 变换(transform):一个"把数据字典改一改"的小函数(重命名键、缩放数值、把文字切成 token……)。多个变换按顺序串起来就是一条管线
  • 归一化统计量(norm stats):训练数据里每个量(姿态、动作的每一维)的均值和取值范围。用它把数值缩放到统一区间(如 [-1,1]),模型才好学;推理时还要用同一套统计量还原回真实数值。

第一部分:策略对象怎么组装(一次性)

create_trained_policy(config, ckpt_dir)policy_config.py:16)做三件事:

  1. 载模型——靠检查点里有没有 model.safetensors 判定是 PyTorch 还是 JAX 模型(policy_config.py:49-50)。
  2. 载归一化统计量——默认从检查点自带的 assets 目录载,而不是从配置目录,确保用的和训练时一模一样(policy_config.py:59-64)。
  3. 拼好输入、输出两条变换管线policy_config.py:75-94):
    • 输入管线(顺序):整理键名 → 补默认指令 → 机器人专属映射 → 归一化 → 切 token / 缩放图像。
    • 输出管线是它的逆序:反归一化 → 机器人专属还原。

第二部分:一次请求怎么走(Policy.inferpolicy.py:68

  1. 先把输入拷贝一份(变换会原地改,policy.py:70)。
  2. 输入管线policy.py:71)→ 得到模型张量;再加一个 batch 维、转成 JAX/PyTorch 张量(policy.py:72-79)。
  3. 打包成 Observation → 调 model.sample_actions(采样动作;π0 是从噪声一步步去噪,原理见 模型架构)(policy.py:90-95)。
  4. 去掉 batch 维 → 过输出管线policy.py:102):把动作从归一化空间还原,并切回机器人真实动作维。
  5. 返回 actions未来步数 × 机器人动作维)+ 推理耗时。

关键约定:每个机器人一对 Inputs/Outputs

输入管线里"机器人专属映射"这步,是适配不同机器人唯一要改的地方。每个平台写一对 dataclass:

  • LiberoInputslibero_policy.py:29):把机器人的 observation/imageobservation/state 搬到模型要的键(image.base_0_rgbstate),没有的相机用零填充。
  • LiberoOutputslibero_policy.py:87):模型输出的动作维被 pad 到 32,这里切回机器人真实的前 7 维

换个机器人,照着改这一对就行,模型和其余管线都不用动。

归一化为什么是"硬依赖"

训练时所有姿态/动作都被缩放过;推理时模型也只认缩放后的数。必须用训练时那套统计量来缩放输入、还原输出(Normalize / Unnormalizetransforms.py:114 / 148)。统计量缺失或对不上,模型看到的数值尺度就错了,直接产出垃圾动作——所以它默认从检查点自带 assets 载。详见 设计决策

远程推理变体(同一个 Policy)

机器人端算力弱时,可以把模型跑在远端 GPU:serve_policy.py 用同样的 create_trained_policy 造出 Policy,包进一个 WebSocket 服务(默认端口 8000)。客户端(packages/openpi-client)把观测用 msgpack 打包发过来,服务端收到就 policy.infer(obs)、把动作打包发回(websocket_policy_server.py:55-72)。机器人端只管"发观测、收动作"。

这条路径告诉你的事

  • 归一化统计量是推理正确性的硬依赖(从检查点 assets 载,和训练对齐)。
  • 同一套变换训练和推理共用:输出管线是输入管线的逆序,机器人专属逻辑全收在一对 Inputs/Outputs 里。
  • 模型对上层透明Policy 不区分 π0 还是 π0-FAST,差异藏在 sample_actions 和 token 相关变换里。

出链

  • [[openpi_Model_Architecture]]
  • [[openpi_Decisions_and_Danger]]