MolmoAct2-SO100_101 是 AllenAI 开源的视觉-语言-动作(VLA)机器人策略模型,基于 Molmo2-ER 文本/视觉主干,挂载 flow-matching 连续动作专家(Action Expert),针对 SO-100/SO-101 机械臂(绝对关节位姿控制)微调。输入为 RGB 相机图像 + 语言指令 + 机器人 6-DoF 状态向量,输出为长度为 30 的绝对关节动作 chunk(肩关节等 6 维:shoulder_pan / shoulder_lift / elbow_flex / wrist_flex / wrist_roll / gripper)。
本项目将 allenai/MolmoAct2-SO100_101 适配到华为 Ascend NPU(910 系列,CANN 8.5.1),完成:
inference.py:--device npu|cpu 双端推理(同输入、同 seed),输出动作 shape / 耗时 / 显存峰值,并保存 {device}_output.txt、{device}_run.log、{device}_actions.npy、{device}_times.json。compare.py:NPU vs CPU 六项指标对比,输出 assets/compare_result.txt。torch.where 条件统一 .bool();flow-matching 初始噪声在 CPU 生成再 .to(device)(保证两端输入一致、可复现);全程不使用 torch.cuda;enable_cuda_graph=False(NPU 不支持 CUDA Graph)。环境:Python 3.11 / torch 2.9.0+cpu / torch_npu 2.9.0.post1 / transformers 4.57.6 / CANN 8.5.1 / Ascend 910 ×2。
pip install -r requirements.txt # torch, transformers==4.57.6, torch_npu==2.9.0.post1, numpy
# 权重已下载至本地目录(5 个 safetensors 分片 + trust_remote_code 相关 py/json),
# 加载时使用 trust_remote_code=True, dtype=bfloat16模型目录需包含:model-*.safetensors(5 分片)、config.json、modeling_molmoact2.py、configuration_molmoact2.py、processing_molmoact2.py、image_processing_molmoact2.py、norm_stats.json、tokenizer*.json 等。
# NPU 推理(Ascend 910, device 0)
python3 inference.py --device npu
# CPU 推理(同输入同 seed,用于精度对比基线)
python3 inference.py --device cpu
# 六项指标对比
python3 compare.py关键调用(与官方 inference 保持一致,仅针对 NPU 调整):
import torch, torch_npu
torch_npu.npu.set_device(0)
from transformers import AutoModelForImageTextToText, AutoProcessor
processor = AutoProcessor.from_pretrained(MODEL_DIR, trust_remote_code=True)
model = AutoModelForImageTextToText.from_pretrained(
MODEL_DIR, trust_remote_code=True, dtype=torch.bfloat16
).to("npu").eval()
out = model.predict_action(
processor=processor,
images=[top_rgb, side_rgb], # 224x224 RGB(合成图像,固定 seed)
task="pick up the object and place it into the bowl",
state=robot_state, # 6-DoF 原始状态向量(度)
norm_tag="so100_so101_molmoact2",
inference_action_mode="continuous",
enable_depth_reasoning=False,
num_steps=10,
normalize_language=True,
enable_cuda_graph=False, # NPU 不支持 CUDA Graph,必须关闭
)
actions = out.actions # shape (1, 30, 6),机器人尺度(度)| 指标 | 数值 | 说明 |
|---|---|---|
| cos_sim(动作 flatten) | 1.000000 | 余弦相似度,越接近 1 越好 |
| max_abs | 0.250000 (deg) | 逐元素最大绝对误差 |
| mean_abs | 0.017480 (deg) | 逐元素平均绝对误差 |
| 动作符号一致率 | 1.000000 | sign 一致比例(|cpu|>1e-3,180/180 元素) |
| 动作 L2 误差 | 0.000438 | 相对 L2:||npu-cpu||_2 / ||cpu||_2 |
| NPU/CPU 耗时比 | 0.006694 | NPU 平均 0.8505s vs CPU 平均 127.0549s(各 3 次平均) |
补充实测数据:动作 shape (1, 30, 6);NPU 峰值显存 11.062 GB(max_memory_allocated);CPU 峰值 RSS 18.109 GB;CPU 动作范围 [-3.5156, 186.0000] deg,NPU 动作范围 [-3.5156, 186.0000] deg。
结论:NPU(bf16)与 CPU(bf16)输出高度一致(cos_sim≈1.0,平均绝对误差 0.017°,相对 L2 误差 4.4e-4),NPU 推理速度约为 CPU 的 149 倍。
详见 assets/compare_result.txt。