Bug_Factory_w/vla_so101_pick_n_place_full_expert
模型介绍
文件和版本
Pull Requests
讨论
分析

vla_so101_pick_n_place_full_expert (SmolVLA) 昇腾 NPU 迁移与服务化推理指南

模型: anikitakis/vla_so101_pick_n_place_full_expert — SmolVLA 视觉-语言-动作 (VLA) 策略,基于 SmolVLM2-500M-Video-Instruct 骨干 + 流匹配动作专家(约 0.45B 参数),用于 SO-101 机械臂 "put the annotated object in the box" 任务。 本项目: 将 LeRobot 框架的 SmolVLA 策略通过 torch_npu 迁移到昇腾 NPU,提供 FastAPI 服务化推理 (inference.py) 与完整测试用例 (test_client.py)。


目录

  1. 模型说明
  2. 环境要求
  3. 目录结构
  4. 环境准备
  5. 适配过程总结
  6. 服务化推理 (inference.py)
  7. 测试用例 (test_client.py)
  8. 测试结果
  9. 常见问题 (FAQ)

1. 模型说明

项目说明
框架LeRobot (PyTorch + HuggingFace Transformers)
骨干SmolVLM2-500M-Video-Instruct (Qwen2.5 架构 VLM, 16 层)
动作专家流匹配 (Flow Matching) 去噪器, 0.75× 隐藏宽度, 交叉注意力
输入3 路相机图像 (480×640) + 6 维本体状态 + 语言指令
输出6 维动作 chunk (50 步, 反归一化)
训练精度FP32 (config.use_amp=false)

相机命名: 模型训练时使用 annotated / front / target_patch 三个相机(预处理管线中自动映射)。

2. 环境要求

项目要求本机验证值
硬件Ascend910 系列 (≥1 卡)Ascend910 × 16
OSopenEuler / Ubuntu (aarch64)openEuler 22.03 SP4 (aarch64)
CANN≥ 8.025.5.0
Python3.8 – 3.113.11.14
PyTorch与 CANN 配套2.9.0+cpu
torch_npu与 PyTorch 版本一致2.9.0.post1
leRobot≥ 0.4.4 (smolvla 支持)0.4.4
transformers≥ 4.494.57.6

3. 目录结构

vla_so101_pick_n_place_full_expert-npu/
├── inference.py          # 服务化推理脚本 (NPU 适配, FastAPI)
├── test_client.py        # 测试用例 (T1 NPU设备 / T2 离线推理 / T3 服务端到端)
├── requirements.txt      # 运行环境依赖
├── README.md             # 本指南
├── assets/               # 截图 (npu_device_call.png / model_result.png / agent_workflow.png)
├── logs/                 # 服务与测试日志
└── vla_so101_pick_n_place_full_expert/   # 模型文件 (权重为符号链接)
    ├── config.json             # 已适配: device="npu:0", 剔除 0.5.2 不兼容字段
    ├── model.safetensors       # 策略权重 (含完整 VLM + 动作专家)
    ├── policy_preprocessor.json / policy_postprocessor.json  # 归一化管线
    ├── policy_*_normalizer_processor.safetensors              # 归一化统计
    └── train_config.json

权重 (906MB) 以符号链接方式引用原目录;config.json 已解引用并适配(见第 5 节)。

4. 环境准备

# 1) 初始化 CANN 环境
source /usr/local/Ascend/ascend-toolkit/set_env.sh

# 2) 指定可见 NPU
export ASCEND_RT_VISIBLE_DEVICES=0

# 3) 安装依赖 (推荐华为镜像源)
export PIP_INDEX_URL=https://repo.huaweicloud.com/repository/pypi/simple/
pip install -r requirements.txt

# 4) 离线加载: SmolVLM2-500M-Video-Instruct 配置已本地缓存
export HF_HUB_OFFLINE=1

# 5) 验证 torch_npu 基础可用
python3 -c "import torch, torch_npu; a = torch.randn(3,4).npu(); print(a + a)"
# 期望输出: tensor(..., device='npu:0')

5. 适配过程总结

原模型为 LeRobot (lerobot 0.5.2) 训练的 CUDA 策略,迁移到昇腾 NPU 的关键点(模型权重零修改):

#适配项原始 (CUDA)适配后 (NPU)位置
1NPU 后端注入—import torch_npu + transfer_to_npu入口脚本首部
2设备控制config.device="cuda"config.device="npu:0" (leRobot 用其控制设备与 safetensors 加载)config.json
3设备校验leRobot 仅认 cuda/mps/xpu/cpumonkeypatch is_torch_device_available 扩展 npuinference.py
4VLM 加载AutoModelForImageTextToText.from_pretrained (需权重文件)from_config (VLM 权重已含在 policy safetensors 中, 本地无权重文件)inference.py
5输入管线数据集输出 CHW float [0,1] Tensorobservation_to_tensors: numpy HWC → CHW float [0,1] (管线仅处理 Tensor)inference.py
6推理接口select_action (单步队列)predict_action_chunk (整 chunk, 50×6) + 逐动作反归一化inference.py
7配置兼容lerobot 0.5.2 训练剔除 0.4.4 不识别字段 (push_checkpoints_to_hub/revision)config.json
8HTTP 客户端—test_client 禁用代理 (requests 走系统代理会卡死)test_client.py

关键调试记录

  1. draccus ParsingError: 0.4.4 的 SmolVLAConfig 不识别 push_checkpoints_to_hub/revision → 剔除字段;
  2. Unknown device npu:0: leRobot 硬校验设备类型 → monkeypatch 扩展;
  3. checkpoint_files[0].endswith 崩溃: 本地无 SmolVLM2 权重文件(已合并入 policy safetensors)→ from_pretrained 改 from_config;
  4. (b,c,h,w) expected / 480 channels: 预处理管线仅处理 torch.Tensor,numpy 被跳过;HWC 需转 CHW → observation_to_tensors;
  5. requests 卡死: 环境代理导致本机 HTTP 请求走代理 → 禁用代理。

6. 服务化推理 (inference.py)

# 启动服务 (默认 npu:0, 端口 8001; 8000 被其他服务占用时调整)
python inference.py --policy_path ./vla_so101_pick_n_place_full_expert --port 8001

# 可选参数
#   --no-warmup   跳过预热 (默认开启, 触发算子编译避免首请求超时)

服务启动后自动预热(一次 dummy 推理),提供:

接口方法说明
/healthzGET服务健康状态 + 设备信息
/actPOST3 路图像 + 状态 + 指令 → 50×6 动作 chunk
/docsGETOpenAPI 交互式文档

/act 请求示例

curl -X POST http://127.0.0.1:8001/act -H "Content-Type: application/json" -d '{
  "image1": "<json_numpy 编码的 annotated 相机图 480x640>",
  "image2": "<json_numpy 编码的 front 相机图>",
  "image3": "<json_numpy 编码的 target_patch 相机图>",
  "state": "<json_numpy 编码的 6 维本体状态>",
  "task": "put the annotated object in the box"
}'

响应: {"action": [[...]×50], "latency_s": 0.33}(50 步 6 维动作 chunk,已反归一化)。

7. 测试用例 (test_client.py)

# 仅离线测试 (NPU 设备 + 直接推理, 无需服务)
python test_client.py --offline-only --policy_path ./vla_so101_pick_n_place_full_expert

# 完整测试 (需先启动 inference.py 服务)
python test_client.py --server http://127.0.0.1:8001
用例验证内容通过标准
T1 NPU 设备调用torch_npu.npu.is_available()、设备名称、显存、张量落盘张量 device 以 npu: 开头
T2 离线推理策略加载到 NPU + 标准管线 (preprocessor → predict_action_chunk → postprocessor)输出 shape=(50, 6),数值有限且幅度合理
T3 服务端到端HTTP POST /act(json_numpy 协议)服务端 device 为 NPU,返回 action shape=(50, 6)

测试结束后打印汇总 测试结果: N 通过 / M 失败,有失败时退出码为 1。

8. 测试结果

本机实际运行结果 (2026-08-19, npu:0, FP32, 0.45B 参数)。3/3 全部通过 ✅(完整日志见 logs/full_test_result.log)

用例结果关键数据
T1 NPU 设备调用✅ PASSAscend910_9382 × 16, 单卡 61.3GB HBM, 张量 device='npu:0'
T2 离线推理✅ PASSaction shape=(50, 6), chunk 推理耗时 0.72s
T3 服务端到端✅ PASSHTTP 200, action shape=(50, 6), 响应延迟 0.33s

实际输出示例:

[T1] NPU 设备调用验证
  NPU 可用: True | NPU 名称: Ascend910_9382 | NPU 数量: 16
  张量设备: npu:0 | 求和示例: 6.5292
  [PASS] T1 NPU 设备调用 device=npu:0

[T2] 离线推理验证 (策略加载到 NPU)
  策略设备: npu:0 | dtype: torch.float32
  预处理后 batch: state=(1, 6) images=(1, 3, 480, 640)
  动作输出 shape: (50, 6) | 耗时: 0.72s
  [PASS] T2 离线 NPU 推理 shape=(50, 6) expected=(50, 6) finite=True

[T3] 服务化推理验证 (HTTP -> http://127.0.0.1:8001)
  /healthz: {'status': 'ok', 'device': 'npu:0', 'dtype': 'torch.float32'}
  HTTP 状态码: 200 | 响应耗时: 0.33s | 返回动作 shape: (50, 6)
  [PASS] T3 服务化端到端 action_shape=(50, 6) expected=(50, 6)

测试结果: 3 通过 / 0 失败

截图见 assets/ 目录:NPU 设备调用 (npu_device_call.png)、测试结果 (model_result.png)、适配过程 (agent_workflow.png)。

9. 常见问题 (FAQ)

问题原因解决
Unknown device npu:0. Supported: cuda, mps, xpu or cpuleRobot 0.4.4 设备硬校验本项目 monkeypatch 已扩展 (inference.py apply_npu_patches)
draccus ParsingError: push_checkpoints_to_hub/revision0.4.4 不识别 0.5.2 训练字段本项目 config.json 已剔除
checkpoint_files[0].endswith 崩溃SmolVLM2 本地无权重文件本项目 patch VLM 加载为 from_config
(b,c,h,w) expected / 480 channels输入格式错误图像需 CHW float [0,1] Tensor (observation_to_tensors)
HTTP 请求卡死无响应requests 走系统代理proxies={"http": None, "https": None}
首个请求耗时数分钟算子首次编译服务预热默认开启 (--warmup)
Port 8000 already in use其他服务占用换端口 (--port 8001)

📦 本仓库由 ascend-model-agent-plugin (ai4s-basic) 自动迁移适配生成