2toINF/X-VLA-Libero(X-VLA 0.9B Foundation Edition)在华为昇腾 Ascend 910 NPU 上的推理适配与 CPU 精度/性能对比。
X-VLA 是一个 0.9B 参数的跨本体视觉-语言-动作(Vision-Language-Action)通用机器人策略模型,架构为:
| 组件 | 作用 |
|---|---|
| Florence-2-large 编码器 | 视觉-语言表征骨干(encoder-only,文本 + 多视角图像) |
| SoftPromptedTransformer | 基于流匹配(flow-matching)的动作去噪 Transformer,每个本体一组可学习 soft prompt |
| Action Hub | 动作空间定义(ee6d: xyz + 6D 旋转 + 夹爪,20 维)、前后处理与损失 |
| 项目 | 版本 |
|---|---|
| 硬件 | Ascend 910 ×2(单卡即可推理) |
| CANN | 8.5.1 |
| Python | 3.11.14 |
| PyTorch | 2.9.0 |
| torch_npu | 2.9.0.post1 |
| transformers | 4.57.6 |
# 1. 安装依赖(华为镜像源)
pip install -r requirements.txt -i https://repo.huaweicloud.com/repository/pypi/simple/
# 2. 下载权重到 models/(本仓库 .gitignore 已排除 models/)
HF_ENDPOINT=https://hf-mirror.com HF_HUB_DOWNLOAD_TIMEOUT=120 python -c \
"from huggingface_hub import snapshot_download; snapshot_download('2toINF/X-VLA-Libero', local_dir='/data/X-VLA-Libero/models')"
# 3. source CANN 环境
source /usr/local/Ascend/ascend-toolkit/set_env.sh
# 4. NPU 推理
python inference.py --device npu
# 5. CPU 推理(对比基准)
python inference.py --device cpu_supports_sdpa 属性安全回退(models/modeling_florence2.py):transformers ≥ 4.57 在 __init__ 早期(子模块尚未创建)即访问 _supports_sdpa / _supports_flash_attn_2,原实现直接读 self.language_model 抛 AttributeError。改为 getattr(self, "language_model", None) 判空回退。models/modeling_xvla.py):Florence2 为 encoder-only,删除 decoder/lm_head 后须禁用自动权重绑定,避免加载时访问已删除模块。inference.py):XVLA 禁用了 tie_weights 以避免访问已删除的 decoder,而新版 transformers 的 assign 加载会解开 __init__ 中 shared → encoder.embed_tokens 的参数共享,导致 embed_tokens 随机初始化(checkpoint 中存为 model.shared.weight)。加载后手动 copy_ 恢复,保证权重完整且 CPU/NPU 结果可比。F.scaled_dot_product_attention,昇腾上由 torch_npu 原生支持,无需修改。x1 用 CPU 固定种子 torch.Generator 生成后再搬运到目标设备,保证两端输入逐位一致。import torch, torch_npu # NPU 环境
from transformers import AutoModel, AutoProcessor
model = AutoModel.from_pretrained("models/", trust_remote_code=True).to("npu:0").eval()
# 注意: 需按上文适配点 3 重新 tying encoder.embed_tokens
processor = AutoProcessor.from_pretrained("models/", trust_remote_code=True)
action = model.generate_actions(
input_ids=..., image_input=..., image_mask=..., # processor(images, text) 输出
domain_id=torch.zeros(1, dtype=torch.long, device="npu:0"),
proprio=torch.zeros(1, 20, device="npu:0"),
steps=10,
) # -> [1, 30, 20] ee6d 动作序列输入:固定种子合成观测(3 视角 256×256 图像 + 指令 "pick up the red block and place it into the bin" + 20 维本体感觉),初始噪声 seed=42,10 步流匹配去噪;计时为 3 次迭代均值(预热 1 次后)。实测数据见 results_*.json。
| 指标 | 数值 |
|---|---|
| cos_sim | 0.99999998 |
| max_abs_err | 1.424e-04 |
| mean_abs_err | 3.350e-05 |
| NPU 平均延迟(Ascend 910) | 142.7 ms |
| CPU 平均延迟 | 40 281.1 ms |
| 加速比 | ≈ 282× |
差异来源说明:NPU 与 CPU 的 fp32 算子实现(LayerNorm / Softmax / SDPA)归约顺序不同,误差在 1e-4 量级属正常范围,cos_sim ≈ 1.0 表明数值对齐良好。
| 文件 | 说明 |
|---|---|
inference.py | 推理入口,--device npu|cpu,输出 cos_sim / max_abs_err / mean_abs_err / 耗时 |
results_npu.json / results_cpu.json | 两端完整结果(延迟、动作序列、环境信息、精度指标) |
assets/agent_workflow.png | 适配工作流(分步流程与耗时) |
assets/npu_device_call.png | NPU 设备调用证据(npu-smi、设备名/显存、推理关键输出) |
assets/model_result.png | 2×2 结果信息图(模型信息卡 / 耗时对比 / 精度表 / 动作轨迹可视化) |
requirements.txt | Python 依赖清单 |
Apache 2.0(遵循上游 2toINF/X-VLA)。