Skip to content

0 总体概览

总体目标:使用310P算力,实现机械臂抓取。本文档提供了一种较典型的VLA模型方案部署:π0

整体结构:参考开发套件介绍及组网


以千寻机器人为例,硬件系统框架如下图所示。



香橙派AI 套件基于USB3.0实现3个外部相机联接,算力拓展坞承载端侧推理用的模型,推理后通过ROS2与千寻机器人本体交互。





1 环境搭建

支持操作系统:Ubuntu22.04;OpenEuler

NPU:昇腾310P 香橙派AI Studio

  表1 组件安装顺序表

组件安装顺序

版本

安装指导

1. Ubuntu

22.04

OS安装

2. Firmware和Driver

24.RC1

驱动安装

3. CANN

8.2.RC1

CANN安装

4. Python

3.10.xx

Ubuntu22.04 自带

5. Pytorch & torch_npu

2.5.1

Pytorch&torch_npu安装指导

6. aie_bench

0.0.2

ais_bench安装指导

7. ACL Lite

/

ACLLite安装指导

2 π0

2.1 概述

为打造具备人类般物理环境适应性的 AI 系统,Physical Intelligence 公司研发通用机器人端到端VLA模型 π₀

  1. 数据训练基础:π₀的训练数据规模大且多元,涵盖 Open X Embodiment 开源机器人操作数据集、互联网规模的视觉 - 语言预训练数据,以及自主收集的 8 种不同机器人(如 UR5e、Franka、双机械臂 Trossen 等)完成灵巧任务的数据集,包含叠衣服、煮咖啡、整理餐桌等多种真实场景任务,旨在让模型形成对物理交互的通用认知;

  2. 独特架构设计:以 30 亿参数的预训练视觉 - 语言模型(VLM)为基础,继承互联网级语义理解与视觉识别能力。针对机器人需高频(每秒达 50 次)输出连续电机指令的需求,采用流匹配(扩散模型变体)技术,为预训练 VLM 增加连续动作输出功能,构建出视觉 - 语言 - 动作模型,可实时实现灵巧机器人控制;

  3. 功能与应用方式:能控制多种不同机器人,支持直接提示(依据指令即时执行任务)和微调(针对复杂场景优化,类似 LLMs 的后训练)两种应用方式,可完成叠衣服、清理餐桌、组装纸箱等多种高难度物理任务,部分任务(如从洗衣篮叠衣服)此前无机器人系统能成功实现。

官方jax源码实现:π0

2.2 实验目的

了解如何在昇腾310P上实现E2E VLA模型π0模型推理,有效输出双臂动作关节角,支持双臂操作;


2.3 模型输入输出

输入数据:

输入数据名(name)

数据类型(dtype)

数据大小(shape)

数据排布格式

observation.images.head

float32

[N,3,240,320]

N,C,H,W

N - batch size

C - channel

H - height

W - width

observation.images.left_hand

float32

[N,3,240,320]

N,C,H,W

observation.images.right_hand

float32

[N,3,240,320]

N - batch size

N,C,H,W

observation.state

float32

[N, 16]

N, state_dim

tasks

string

[N]

N


输出数据:

输入数据名(name)

数据类型(dtype)

数据大小(shape)

数据排布格式

action

float32

[N, 16]

N, action_dim

以上是模型推理的输入和输出,输出包括左臂关节、左夹爪、右臂关节、右夹爪。

输入源来自3个相机、任务语言指令及机器人状态,经过编码器、LLM及动作模型得到输出。


2.3 模型加载

2.3.1 步骤1:获取模型框架

Lerobot/π0模型(建议使用0.3.3版本的lerobot框架,lerobot 官网链接:github.com

为加速推理,建议优化精度FP32→FP16,开源模型lerobot π0 文件调整如下:

在/src/lerobot/policy下的modeling_pi0.py和paligemma_with_expert.py中按ctrl+h,搜索torch.float32并替换为torch.float16



示例使用git拉取

git clone -b v0.3.3 https://github.com/huggingface/lerobot.git

conda create -n lerobot python=3.10 -y

conda activate lerobot

cd lerobot

pip install -e .

pip install pytest transformers==4.52.1 "numpy<2.0"


2.3.2 步骤2:获取lerobot π0模型

因为π0当前仅openpi和lerobot提供源码,推荐使用昇腾已适配的lerobot π0,可以通过huggingface手动下载lerobot π0 模型文件,也可以通过指令下载。

① 手动下载:https://huggingface.co/lerobot/pi0_base/tree/main

② 指令下载:

export HF_ENDPOINT=’https:///hf-mirror.com

hf download lerobot/pi0_base  --local-dir <模型存放路径>

  1. 下载paligemma-3b的tokenzier(只能手动下载)

下载链接:https://www.modelscope.cn/models/google/paligemma-3b-pt-224

从链接中下载added_tokens.json,special_tokens_map.json,tokenizer.json,tokenizer.model和tokenizer_config.json五个文件至同一个文件夹

  1. 在开发板系统上修改lerobot中pi0初始化tokenizer的路径为下载的tokenizer的路径

在src/lerobot/policies/pi0文件夹的modeling_pi0.py文件中,源码固定tokenizer的来源为huggingface,使用时自动下载并加载tokenizer。

实际操作中由于网络问题需手动下载前中并修改路径至本地的tokenizer路径。

在PI0Policy类中的__init__()初始化方法中,将AutoTokenizer.from_pretrained("google/paligemma-3b-pt-224")改为

AutoTokenizer.from_pretrained("下载的tokenizer存放路径")

  1. 310P不支持bfloat16数据格式,需将代码中转换bfloat16格式的代码注释掉

bfloat16转换代码在src/lerobot/policies/pi0文件夹下的 modeling_pi0.py 和 paligemma_with_expert.py 两个文件中,

CTRL+F 搜索 bfloat16,在对应代码行按CTRL+/ 注释该行代码使其失效,如下是5处需注释掉的代码行

3 在线推理验证

基于MiniPC(Host主机)安装 LeRobot进行在线推理(pytorch在npu上的运行方式 → torch_npu)。使用lerobot框架加载pi0模型,迁移至npu上并推理,基于torch_npu进行在线推理,推理速度预计在430ms。

  • 推理数据来源:① Intelrealsense 相机 x 3;② 本体状态,以千寻机器人双臂+夹爪 16自由度的向量;③ 输入指令,如叠衣服“fold shirt”指令

  • 输出数据:动作指令,如千寻机器人双臂+夹爪16自由度向量

python
import torch
import torch_npu
from torch_npu.contrib import transfer_to_npu
from lerobot.policies.pi0.modeling_pi0 import PI0Policy
from lerobot
.configs.types import FeatureType, PolicyFeature
import time
 
def main():
    model_path = "/path/to/model/weights"
    dtype = torch.float16
    # 修改model_path为模型权重路径,from_pretrained方法通过读取权重路径下的config.json文件的配置初始化模型架构,并使用model.safetensors赋予模型预训练权重
    policy = PI0Policy.from_pretrained(model_path).to(device="npu")
    policy.eval()
 
    # 设置输出格式
    policy.config.output_features = {
        "action": PolicyFeature(
            type=FeatureType.ACTION,
            shape=(16,)
        )
    }
    # 设置输入格式
    policy.config.input_features = {
        "observation.images.top": PolicyFeature(
            type=FeatureType.VISUAL,
            shape=(1, 3, 224, 224)
        ),
        "observation.images.left_hand": PolicyFeature(
            type=FeatureType.VISUAL,
            shape=(1, 3, 224, 224)
        ),
        "observation.images.right_hand": PolicyFeature(
            type=FeatureType.VISUAL,
            shape=(1, 3, 224, 224)
        ),
        "observation.state": PolicyFeature(
            type=FeatureType.STATE,
            shape=(1, 16)
        )
    }
    with torch.inference_mode():
    # 验证模型加载与推理效果
        for _ in range(10):
        # pi0模型一次推理输出50个action,selection_action将推理得到的action存储至队列中,
        # 每次调用从队列中取出一个action返回,直至队列为空再进行新一轮推理,
        # 使用reset()方法清空队列使模型每次都进行推理
            policy.reset()
            observation = {
                # 当前输入是随机生成的用于验证的伪数据,
                # 输入三路相机:真机验证时可替换为真实图像,图像像素值需手动归一化至0~1之间再输入至模型中
                "observation.images.head": torch.rand(1, 3, 224, 224, dtype=dtype).npu(),
                "observation.images.left_hand": torch.rand(1, 3, 224, 224, dtype=dtype).npu(),
                "observation.images.right_hand": torch.rand(1, 3, 224, 224, dtype=dtype).npu(),
                # 输入本体状态:以机器人上半身16个自由度本体状态为例,包括双臂(7*2)+夹爪(1*2)
                "observation.state": torch.randn(1, 16, dtype=dtype).npu(),
                "task": ["Do something."]
            }
            start = time.perf_counter()
            # 输出控制指令:基于observation输入,推理生成16个自由度输出(以千寻机器人上半身16自由度为例)
            action = policy.select_action(observation)
            # 输出速度统计
            duration = time.perf_counter() - start
            print(f"Time cost: {duration * 1000} ms.")
            print(action)
if __name__ == '__main__':
    main()


输出效果上,基于香橙派EP模式,基于torch_npu推理π0模型(lerobot),预期单次推理时间 ~ 430ms