华为 Atlas 300V 兼容性测试报告

华为 Atlas 300V 兼容性测试报告

测试结论:PASS ------ 华为 Atlas 300V 视频解析卡在本文所述的 PVE 虚拟化环境中功能完整、运行稳定,全部 8 项测试用例通过,宿主侧 PCIe 错误计数归零。

项 值
报告日期 2026-10-20
报告版本 v1.0
测试对象 华为 Atlas 300V 视频解析卡(PCIe 19e5:d500,芯片 Ascend 310P3,板载 24GB LPDDR4X)
测试形态 整机 PCIe 直通(PVE 宿主 → KVM 虚拟机,非 SR-IOV、非 vNPU 切分)
宿主平台 PVE 9.2.3 / Debian 13.5 / 内核 7.0.6-2-pve / Intel C621 / Xeon Scalable Gen1/2 / 62GB RAM
客户端 OS Ubuntu 20.04 (focal) / 内核 5.15.0-139-generic / 32GB / 48 vCPU
软件栈 Ascend 驱动 25.5.2 + 固件 7.8.0.7.220 + CANN 8.5.2(toolkit / ops / nnal)
被测程序 AscendDemo(C++ / ACL,含 Python 扩展)
关联文档 透传实施记录、固件修复实施记录

0. 摘要

本次测试的目标是回答一个问题:Atlas 300V 这张卡,在"物理机装 Hypervisor、卡整体直通给一台 Linux 虚拟机"这种形态下,能不能正常用?

结论是能。但过程中踩到了 5 个真实的坑,其中 2 个是华为官方文档没有明说、或者文档说了但容易被误读的地方:

  1. 固件包必须单独安装 ------驱动包 .run --full 不含固件,漏装不会报错,而是让设备永远等不到 ready,最终由卡自己中止 PCIe 事务把虚拟机打崩。
  2. "固件不支持在虚拟机安装"这个限制在直通场景下不触发 ------它的实现是安装器里的一个退出码判断,直通时驱动把卡认作物理机,因此可以直接在虚拟机里刷固件。

本报告第 5 章完整记录了这 5 个坑的现象、根因与解法,照着第 3 章的步骤 + 第 5 章的坑位,可以在任意一台同规格机器上复现全部结果。

测试结果总览

编号 测试项 判定 关键实测结果
T1 设备识别 ✅ PASS npu-smi info 识别 310P3 ,Health OK,显存 1858/21525 MB
T2 固件版本一致性 ✅ PASS 卡上 hboot1a/b、hlink = 7.8.0.7.220,与驱动 25.5.2 配套
T3 单元测试 ✅ PASS ctest 4/4 通过(letterbox / output / fp16 / cpu_preprocess)
T4 单帧图像推理 ✅ PASS 3 个检测框:person 91.11%、helmet 81.10%、no_helmet 76.12%
T5 视频流水线推理 ✅ PASS 75 帧全流程跑通,平均推理 0.14 ms/帧,输出可视化视频
T6 Python 扩展模块 ✅ PASS AscendInfer.cpython-38-x86_64-linux-gnu.so 导入正常
T7 PCIe 链路稳定性 ✅ PASS 宿主 AER 错误累计 1 次(修复前) ,测试全程零新增
T8 AICore 算力加载 ✅ PASS 重负载下 Aicore Usage Rate 0% → 3% 实时抬升

1. 测试目的与范围

1.1 目的

验证 Atlas 300V 在虚拟化直通形态下的可用性,覆盖以下五个方面:

  • 设备能否被虚拟机内的驱动正常识别与初始化
  • 驱动 / 固件 / CANN 三层软件栈能否正确配套并协同工作
  • 真实推理程序能否编译、加载模型、下发任务并拿到正确结果
  • 高负载下 PCIe 链路是否稳定(不出现 AER / 链路重置)
  • 算术任务是否真的由 NPU 加速单元执行,而非退化为 Host 侧执行

1.2 范围

覆盖 内容
✅ 覆盖 设备枚举、驱动加载、固件刷写、CANN 运行时、模型转换(atc)、C++ 推理、Python 扩展、PCIe 稳定性、AICore 负载验证
⚠️ 部分覆盖 性能基线------因缺少可用的真模型(YOLO 权重导出链路未打通,见 §7),性能数据仅以合成模型给出趋势性结论,不作为绝对算力基线
❌ 不覆盖 DVPP 硬编解码性能对照(demo 走的是 CPU 预处理回退路径,见 §7)、多卡/多 VM 共享、vNPU 切分、裸金属对比

2. 测试环境

2.1 硬件环境

角色 型号 / 参数
被测卡 华为 Atlas 300V 视频解析卡
宿主主板 G2DEW-B(板号 1.21.222.0353,板卡 Mfg Date 2023-09-25)
芯片组 Intel C621
BIOS AMI 5.14 (2021-01-26)
CPU Intel Xeon Scalable Gen1/2(Skylake-SP / Cascade Lake)
内存 62 GB(测试期已用 38 GB / 可用 24 GB)
宿主存储 local-lvm,VM 101 虚拟磁盘 256 GB
网络 VM 101 → virtio 网卡 → vmbr0,静态 IP 192.168.0.93

2.2 Atlas 300V 卡片信息

项 值
PCI 地址(宿主) 0000:18:00.0
Vendor / Device 19e5:d500(Huawei)
Subsystem 0200:0100
Class 0x120000 Processing accelerators
芯片 Ascend 310P3 ,Chip Version V1,Board ID 0x6e
板载内存 24 GB LPDDR4X(npu-smi 报 DDR 21525 MB 可用)
BAR0 aa000000,64-bit non-prefetchable,8 MB(控制寄存器)
BAR2 387ff8000000,64-bit prefetchable,128 MB(PCIe 侧数据窗口)
MSI-X 512 vectors
PCIe 链路 协商 8 GT/s x16 (capable 16 GT/s Gen4)------受宿主上游 root port 0000:17:00.0(Intel Sky Lake-E 8086:2030)限制,硬件上限
上游 root port 0000:17:00.0
IOMMU group 6,单例 (仅含 0000:18:00.0)------透传理想条件,无需 ACS 绕过 / pcie_acs_override
SPI Flash Macronix 16 MB(Manufacturer ID 0xC2,Flash Count 1)

2.3 虚拟化拓扑

复制代码
PVE 宿主 (192.168.0.144)                          Ubuntu 20.04 VM 101 (192.168.0.93)
├─ 内核 7.0.6-2-pve                                ├─ 内核 5.15.0-139-generic
├─ intel_iommu=on iommu=pt                         ├─ 48 vCPU / 32 GB / local-lvm 256GB
├─ IOMMU group 6 (单例)                             ├─ Ascend 驱动 25.5.2 + 固件 7.8.0.7.220
│  └─ 0000:18:00.0  Atlas 300V                     ├─ CANN 8.5.2 (toolkit/ops/nnal)
│        │  vfio-pci 绑定                            └─ AscendDemo (ACL C++ + Python)
│        └─── PCI 透传 ──►  0000:01:00.0 (devid 0, NPU ID 256)
└─ 宿主侧 AER 计数:1(修复前 1 次,测试期零新增)

宿主侧 IOMMU 状态(实测):

复制代码
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-7.0.6-2-pve ... quiet intel_iommu=on iommu=pt crashkernel=512M

$ dmesg | grep -i "Default domain type"
[    1.154696] iommu: Default domain type: Passthrough (set via kernel command line)

$ ls /sys/kernel/iommu_groups/6/devices/
0000:18:00.0

$ lspci -k -s 18:00.0
18:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d500 (rev 23)
	Subsystem: Dell (wrong ID) Device 0100
	Kernel driver in use: vfio-pci

2.4 软件版本矩阵

三层必须严格配套,本次选用如下组合(依据 CANN 8.5.2 与驱动的官方兼容区间):

层 组件 版本 配套性依据
运行时 Ascend-cann-toolkit 8.5.2 被 AscendDemo/CMakeLists.txt:78 硬编码锁定为 /usr/local/Ascend/cann-8.5.2/x86_64-linux/devlib
运行时 Ascend-cann-310p-ops 8.5.2 与 toolkit 同版本
运行时 Ascend-cann-nnal 8.5.2 必须排在 toolkit 之后安装
驱动 Ascend-hdk-310p-npu-driver 25.5.2 固件包声明 compatible_version_drv=[..., 25.0, 25.5.]
固件 Ascend-hdk-310p-npu-firmware 7.8.0.7.220 驱动声明 compatible_version_fw=[6.4.0,6.4.99],[7.0.0,8.9.9]

安装包完整性:5 个 .run 全部通过 --version 自证,并逐个校验 SHA256 通过。

客户端系统包版本(实测):

包 版本 用途
build-essential 12.8ubuntu1.1(gcc 9.4.0) 驱动 DKMS 编译 / C++ 编译
cmake 3.16.3 构建 AscendDemo
libopencv-dev 4.2.0+dfsg-5 视频解码 / 预处理 / 可视化
nlohmann-json3-dev 3.7.3 配置解析
libgtest-dev 1.10.0-2 单元测试框架
ffmpeg + libavcodec-dev 4.2.7 测试视频生成
python3-dev / python3-pip 3.8.2 / 20.0.2 Python 扩展模块编译

Python 环境(按"开发用 uv venv / 工具链用系统 Python"的分离原则):

环境 Python 关键包
项目 venv(.venv) 3.8.10 numpy 1.24.4、onnx 1.17.0、onnxruntime 1.19.2、opencv-python-headless 4.10.0.84、torch 2.4.1+cpu
系统 python3(atc 用) 3.8.10 numpy 1.24.4、protobuf 3.6.1、attrs、psutil、PyYAML、cffi、Pillow、sympy、scipy、requests、absl-py、decorator 5.3.1

decorator 是 CANN atc 的硬依赖,缺失时 atc 会报 Environment_Error_Import_Python_Module_Failed(EC0010): No module named 'decorator'。


3. 安装部署步骤(可复现)

以下命令均以普通用户在 VM 内执行,需要 root 权限处加 sudo。

SSH 提示 host key 问题时可用 ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=NUL <user>@<ip>。

3.0 前置准备

下载并上传 5 个安装包到 VM 的 /home/hybors/atlas300v/:

复制代码
Ascend-hdk-310p-npu-driver_25.5.2_linux-x86-64.run
Ascend-hdk-310p-npu-firmware_7.8.0.7.220.run
Ascend-cann-toolkit_8.5.2_linux-x86-64.run
Ascend-cann-310p-ops_8.5.2_linux-x86-64.run
Ascend-cann-nnal_8.5.2_linux-x86-64.run

逐个自证版本(避免拿到错包):

bash 复制代码
cd /home/hybors/atlas300v
for f in *.run; do echo "--- $f"; ./$f --version 2>&1 | grep -E "Verifying|SHA256|Version" | head -3; done

3.1 宿主侧:把卡交给 vfio-pci

bash 复制代码
# PVE 宿主 (root)
cat > /etc/modprobe.d/vfio.conf <<'EOF'
options vfio-pci ids=10de:2204,10de:1aef,19e5:d500 disable_vga=1
EOF
update-initramfs -u -k all
reboot

验证绑定:

bash 复制代码
lspci -k -s 18:00.0 | grep "Kernel driver"     # → Kernel driver in use: vfio-pci
ls /sys/kernel/iommu_groups/6/devices/          # → 0000:18:00.0(单例)

3.2 客户端 OS 基础环境

换 apt 源 。默认源缺少 focal-updates / focal-security,会导致 OpenCV 依赖链断掉(libgphoto2-6 只有 dev 2.5.24 而需求 2.5.25):

bash 复制代码
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak-ascend
sudo tee /etc/apt/sources.list > /dev/null <<'EOF'
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal universe
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
EOF
sudo apt update

装系统包:

bash 复制代码
sudo apt install -y build-essential cmake git pkg-config \
    libopencv-dev nlohmann-json3-dev libgtest-dev \
    python3-dev python3-pip ffmpeg libavcodec-dev

创建驱动安装硬性要求的运行用户(安装器会以 0x0091 拒绝没有该用户的环境):

bash 复制代码
sudo groupadd -f HwHiAiUser
sudo useradd -g HwHiAiUser -d /home/HwHiAiUser -m -s /bin/bash HwHiAiUser

预留大页(可选,驱动在分配大块连续内存时会用到):

bash 复制代码
echo 'vm.nr_hugepages = 2048' | sudo tee /etc/sysctl.d/99-ascend-hugepages.conf
sudo sysctl --system

3.3 安装 Ascend 驱动(25.5.2)

⚠️ 本步骤含一个内核兼容性 workaround,详见 §5.1。 在 5.15 内核上直接安装会 DKMS 编译失败。

(可选但推荐)预置内核头补丁:

bash 复制代码
for V in 139 46; do
  F=/usr/src/linux-headers-5.15.0-${V}-generic/include/linux/bits.h
  sudo cp -n "$F" "$F.orig-ascend"
  sudo sed -i 's/(l) > (h)/(long)(l) > (long)(h)/g' "$F"
done

该模式在 bits.h 中只出现在第 25 行 (一处行内两处),替换范围唯一,不影响其他宏。

实际改动是把 GENMASK_INPUT_CHECK 里的 (l) > (h) 改成 (long)(l) > (long)(h),消除有符号/无符号比较告警,断言语义保持不变。补丁后:

c 复制代码
/* 补丁前 */
#define GENMASK_INPUT_CHECK(h, l) \
	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
		__is_constexpr((l) > (h)), (l) > (h), 0)))

/* 补丁后 */
#define GENMASK_INPUT_CHECK(h, l) \
	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
		__is_constexpr((long)(l) > (long)(h)), (long)(l) > (long)(h), 0)))

安装驱动:

bash 复制代码
cd /home/hybors/atlas300v
sudo ./Ascend-hdk-310p-npu-driver_25.5.2_linux-x86-64.run --full

重启使驱动生效:

bash 复制代码
sudo reboot

3.4 安装配套固件(7.8.0.7.220)★ 关键步骤

这是最容易漏掉的一步。驱动装完不算装完,没有配套固件,设备永远等不到 ready,第一次推理就会把虚拟机打崩(现象见 §5.2)。

bash 复制代码
cd /home/hybors/atlas300v
sudo ./Ascend-hdk-310p-npu-firmware_7.8.0.7.220.run --full --quiet

预期输出:

复制代码
[Firmware] [INFO]upgradePercentage: 0% → 90% → 100%
[Firmware] [INFO]The firmware of [1] chips are successfully upgraded.
[Firmware] [INFO]Firmware package installed successfully! Reboot now or after driver installation ...

必须重启虚拟机,固件才生效:

bash 复制代码
# PVE 宿主
qm shutdown 101 --timeout 90
qm start 101

验证固件真的落到卡上(版本号应从出厂旧版变成 7.8.0.7.220):

bash 复制代码
sudo /usr/local/Ascend/driver/tools/upgrade-tool --device_index -1 --component -1 --version

3.5 安装 CANN 8.5.2

顺序固定:toolkit → ops → nnal 。安装器默认要交互接受 EULA,用 --quiet 免交互。

bash 复制代码
cd /home/hybors/atlas300v
yes | sudo ./Ascend-cann-toolkit_8.5.2_linux-x86-64.run --install
yes | sudo ./Ascend-cann-310p-ops_8.5.2_linux-x86-64.run --install

# nnal 依赖 toolkit 的环境变量,必须带全套 env 重装
source /usr/local/Ascend/ascend-toolkit/set_env.sh
yes | sudo env "ASCEND_TOOLKIT_HOME=$ASCEND_TOOLKIT_HOME" \
              "ASCEND_NNAE_HOME=$ASCEND_NNAE_HOME" \
              "ASCEND_HOME_PATH=$ASCEND_HOME_PATH" \
              "ASCEND_OPP_PATH=$ASCEND_OPP_PATH" \
              "ASCEND_AICPU_PATH=$ASCEND_AICPU_PATH" \
              "TOOLCHAIN_HOME=$TOOLCHAIN_HOME" \
              ./Ascend-cann-nnal_8.5.2_linux-x86-64.run --install

验证关键路径:

bash 复制代码
ls /usr/local/Ascend/cann-8.5.2/set_env.sh
ls /usr/local/Ascend/ascend-toolkit/set_env.sh
ls /usr/local/Ascend/cann-8.5.2/x86_64-linux/devlib/libascend_hal.so

3.6 Python 环境

项目 venv(开发用):

bash 复制代码
# uv 0.13.3(GitHub 不可达时从清华 PyPI 装)
uv venv --python /usr/bin/python3 /home/hybors/atlas300v/AscendDemo/.venv
uv pip install --python /home/hybors/atlas300v/AscendDemo/.venv/bin/python \
    numpy==1.24.4 onnx==1.17.0 onnxruntime==1.19.2 \
    opencv-python-headless==4.10.0.84 torch==2.4.1

opencv-python-headless 固定在 4.10.0.84,不要用 5.x:需与 C++ 侧的 libopencv 4.2.0 行为对齐。

系统 python3(atc 工具链用):

bash 复制代码
sudo pip3 install "numpy<1.25" "protobuf<3.21" attrs psutil pyyaml cffi \
     pillow sympy scipy requests absl-py decorator

⚠️ atc 必须在系统 python 下跑 。若当前 shell 激活了 uv venv,atc 会用 venv 的 python,报 No module named 'decorator'。转换前先 deactivate 或开新会话。

3.7 编译 AscendDemo

bash 复制代码
cd /home/hybors/atlas300v/AscendDemo
source /usr/local/Ascend/ascend-toolkit/set_env.sh

cmake -S . -B build \
  -DASCEND_ENABLED=ON \
  -DASCEND_DIR=/usr/local/Ascend/ascend-toolkit/latest \
  -DPython3_EXECUTABLE=/home/hybors/atlas300v/AscendDemo/.venv/bin/python

cmake --build build -j$(nproc)

cd build && ctest --output-on-failure

ctest --test-dir 需要 CMake ≥ 3.20,本机 3.16 必须先 cd build 再 ctest。

3.8 准备测试模型

bash 复制代码
cd /home/hybors/atlas300v/test_assets
atc --model=test_model.onnx --framework=5 --output=test_model \
    --soc_version=Ascend310P3 --input_shape="image:1,3,544,960" \
    --input_format=NCHW --log=info

⚠️ --framework 必须是 5 (ONNX)。CANN 8.5.2 只接受 0/1/3/5,--framework=10 会直接报错。

测试素材(合成模型 + 640x480/25fps/75 帧测试视频 + 单帧图片)放在 /home/hybors/atlas300v/test_assets/。


4. 测试用例与结果

T1|设备识别 ✅ PASS

步骤

bash 复制代码
sg HwHiAiUser -c "npu-smi info"
sg HwHiAiUser -c "npu-smi info -t board -i 256 -c 0"

实测输出

复制代码
+--------------------------------------------------------------------------------------------------------+
| npu-smi 25.5.2                                   Version: 25.5.2                                       |
+-------------------------------+-----------------+------------------------------------------------------+
| NPU     Name                  | Health          | Power(W)     Temp(C)           Hugepages-Usage(page) |
| Chip    Device                | Bus-Id          | AICore(%)    Memory-Usage(MB)                        |
+===============================+=================+======================================================+
| 256     310P3                 | OK              | NA           32                0     / 0             |
| 0       0                     | 0000:01:00.0    | 0            1858 / 21525                            |
+-------------------------------+-----------------+------------------------------------------------------+

板级信息:

复制代码
	NPU ID                         : 256
	Chip ID                        : 0
	Chip Type                      : Ascend
	Chip Name                      : 310P3
	Chip Version                   : V1
	Board ID                       : 0x6e
	PCIe Bus Info                  : 0000:01:00.0

判定:卡被正常枚举为 310P3,Health = OK,显存 1858/21525 MB,温度可读(32~41 ℃ 随负载变化)。✔

T2|固件版本一致性 ✅ PASS

步骤

bash 复制代码
sudo /usr/local/Ascend/driver/tools/upgrade-tool --device_index -1 --component -1 --version

实测输出

复制代码
{
Get component version(7.8.0.7.220) succeed for deviceId(0), componentType(11).
	{"device_id":0, "component":hboot1a, "version":7.8.0.7.220}
Get component version(7.8.0.7.220) succeed for deviceId(0), componentType(12).
	{"device_id":0, "component":hboot1b, "version":7.8.0.7.220}
Get component version(7.8.0.7.220) succeed for deviceId(0), componentType(18).
	{"device_id":0, "component":hlink, "version":7.8.0.7.220}
}

判定 :卡上固件为 7.8.0.7.220,与驱动 25.5.2、CANN 8.5.2 三方配套一致。✔

已知读数异常(不影响功能) :npu-smi info -t board 的 Firmware Version 字段在本环境中恒为 NA,而 upgrade-tool 能正确读出 7.8.0.7.220。说明该字段在 vfio 直通下的读取路径受限,不能作为"固件是否安装成功"的判据 ------请以 upgrade-tool --component -1 --version 为准。

T3|单元测试 ✅ PASS

步骤 :cd build && ctest --output-on-failure

实测输出

复制代码
    Start 1: letterbox
1/4 Test #1: letterbox .........................   Passed
    Start 2: output
2/4 Test #2: output ............................   Passed
    Start 3: fp16
3/4 Test #3: fp16 .............................   Passed
    Start 4: cpu_preprocess
4/4 Test #4: cpu_preprocess ...................   Passed

100% tests passed, 0 tests failed out of 4

判定:4/4 通过(letterbox 预处理 / 输出编码 / fp16 精度 / CPU 预处理路径)。✔

T4|单帧图像推理 ✅ PASS

步骤

bash 复制代码
cd /home/hybors/atlas300v/AscendDemo
source /usr/local/Ascend/ascend-toolkit/set_env.sh
./build/ascend_demo --model ../test_assets/test_model.om \
    --image ../test_assets/test.jpg --output ../test_assets/result_img.jpg --bench 1

实测输出

复制代码
[ascend] creating context for device 0...
[ascend] context created successfully
[ascend] stream created successfully
[ascend] model loaded successfully
[test] Single image mode: ../test_assets/test.jpg
[infer] DVPP path declined; CPU fallback
[ascend] Execute: copying input to device...
[ascend] Execute: running model...
[ascend] Execute: synchronizing stream...
[ascend] Execute: inference completed in 0.25 ms
[test] Detection completed in 132.94 ms
[test]   Preprocess: 98.52 ms
[test]   Inference:  0.25 ms
[test]   Detections: 3
[test]   - person: 91.11% at (0,88)-(73,265)
[test]   - helmet: 81.10% at (161,132)-(250,309)
[test]   - no_helmet: 76.12% at (338,176)-(426,353)
[test] Visualization saved to ../test_assets/result_img.jpg

判定:模型加载成功、推理下发成功、输出与合成模型的设计值(0.90 / 0.80 / 0.75,fp16 舍入后为 0.9111 / 0.8110 / 0.7612)逐项吻合,检测框坐标与模型内固定框一致,可视化图正常输出。✔

T5|视频流水线推理 ✅ PASS

步骤

bash 复制代码
./build/ascend_demo --model ../test_assets/test_model.om \
    --video ../test_assets/test_video.mp4 --output ../test_assets/result_video.mp4 \
    --bench 75 --no-track

实测输出

复制代码
opened video: 640x480, 25.00 FPS, 75 frames
preprocess: CPU  |  tracking: OFF  |  frames: 75  |  avg preprocess 47.32 ms  |  avg inference 0.14 ms  |  7173.42 FPS (inference only)

判定:75 帧全流程(解码 → 预处理 → 推理 → 后处理 → 编码输出)跑通,无丢帧、无报错,可视化视频正常生成。✔

T6|Python 扩展模块 ✅ PASS

步骤

bash 复制代码
cd /home/hybors/atlas300v/AscendDemo
source /usr/local/Ascend/ascend-toolkit/set_env.sh
.venv/bin/python -c "import sys; sys.path.insert(0,'build'); import AscendInfer; print(AscendInfer.__file__)"

实测输出

复制代码
/home/hybors/atlas300v/AscendDemo/build/AscendInfer.cpython-38-x86_64-linux-gnu.so

判定:pybind11 生成的 Python 扩展与 CANN 运行时正确链接并可导入。✔

注意:扩展需要 LD_LIBRARY_PATH 包含 CANN 的 lib64(否则报 ImportError: libmsprofiler.so: cannot open shared object file),且 .so 位于 build/ 下,需自行加入 sys.path。

T7|PCIe 链路稳定性 ✅ PASS

步骤(宿主)

bash 复制代码
dmesg | grep -i -E "CmpltAbrt|AER:"

实测结果

复制代码
[  554.553021] vfio-pci 0000:18:00.0:    [15] CmpltAbrt              (First)
[  554.553071] pcieport 0000:17:00.0: AER: device recovery successful

判定 :整轮测试(含 T4/T5/T8 的多次推理与重负载)结束后,宿主 AER 累计仍为 1 次 ,且该次发生在固件补装之前 (宿主开机后第 554 秒的旧崩溃)。固件修复后零新增,链路稳定。✔

T8|AICore 算力加载验证 ✅ PASS

这一项回答"算术到底是不是 NPU 干的"。方法与结论见 §5.5,摘要如下。

探针模型 :构造一个依赖输入、无法被常量折叠 的重模型------把 image[1,3,544,960] 展平后 reshape 成 [1248,1248](批量维 1248),接 16 级 MatMul,合计 33.9 GMAC = 67.8 GFLOP/次 ;.om 中 17 个权重矩阵全部保留(om_info_list 权重字节 54,358,016),证明链式矩阵乘没有被化简掉。

证据一:墙钟斜率 (bench N 两点求每帧耗时)

模型 bench 3 bench 13 每帧
合成小模型(算力可忽略) 3.98 s 4.92 s 94 ms
重模型(67.8 GFLOP/帧) 5.12 s 5.92 s 80 ms

重模型每帧没有付出额外墙钟代价 。若这 67.8 GFLOP 跑在 Host CPU(实测约 13 GFLOPS),每帧需要约 5 秒。

证据二:AICore 利用率计数器 (npu-smi info -t usages -i 256 -c 0 高频采样)

复制代码
Aicore Usage Rate(%) : 3     ← 密集模型执行期间(连续 6 次采样均为 3)
Aicore Usage Rate(%) : 0     ← 运行结束、空闲后

证据三:未加载模拟器库 ------正常运行环境下 LD_PRELOAD 与 SIMULATOR_HOME 均为空,即未加载 libruntime_camodel.so / libcamodel.so,走的是 CANN 真实运行时。

判定 :算术由 NPU 的 AICore 执行,未退化为 Host CPU 执行。✔

数值保留 :按 67.8 GFLOP 折算的等效算力高于 310P 标称 FP16 峰值,怀疑 atc tiling 对链式 MatMul 做了部分化简(om_info_list 只能证明权重未被整体折成一个常量)。因此本报告不给出等效 TFLOPS 数字,绝对算力基线需用真模型另测(见 §7)。


5. 关键问题与解决方案

本节是本报告最重要的部分------不照做就会踩坑。

5.1 驱动 DKMS 编译失败:-Werror=type-limits

现象

复制代码
driver rebuild failed.
driver map or rebuild failed.

根因是 Linux 5.15 的 GENMASK_INPUT_CHECK 宏原版长这样:

c 复制代码
#define GENMASK_INPUT_CHECK(h, l) \
	(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
		__is_constexpr((l) > (h)), (l) > (h), 0)))

__builtin_choose_expr 的两个分支中同时出现有符号/无符号比较,驱动工程以 -Werror 编译时直接告警转错误(-Werror=type-limits)。

换内核无效 :5.15.0-46 与 5.15.0-139 的 bits.h / find.h 逐字节相同;驱动包内只预编译了 openEuler 4.18 / 5.10 的内核。

解法(改内核头文件,不改驱动源码)

bash 复制代码
F=/usr/src/linux-headers-5.15.0-139-generic/include/linux/bits.h
sudo cp "$F" "$F.orig-ascend"
# 把 (l) > (h) 改为 (long)(l) > (long)(h)

为什么不改驱动源码:安装器每次运行都会重新解压驱动包,源码补丁会被覆盖;改内核头则一次生效、两个内核都受益,且断言语义保持不变。

结果 :编译零错误,32 个 .ko 落到 /lib/modules/5.15.0-139-generic/updates/,npu-smi 25.5.2 装于 /usr/local/sbin/。

5.2 ★ 固件漏装 → 第一次推理必崩虚拟机

现象

  • Guest:CANN plog 停在 [npu_driver.cc:6929] GetDeviceStatus: GetDeviceStatus status=1.,runtime 无限轮询等设备 ready
  • 宿主:vfio-pci 0000:18:00.0: [15] CmpltAbrt (First)、aer_agent=Completer ID(卡自己 中止事务)、TLP Header 60000010 000000ff 0000387f fe000000 → AER: device recovery successful → QEMU 退出 → PVE status: internal-error
  • 宿主冷重启后仍以完全相同的 TLP 头复现(确定性失败,不是卡被 wedged)

根因 :驱动包 .run --full 不包含固件。安装日志里的铁证:

复制代码
[Firmware] [INFO]UserCommand: Ascend-hdk-310p-npu-firmware_7.8.0.7.220.run --version
[Driver]  [WARNING]old firmware not installed, stop version relationship check

固件安装器只被调用过一次,且是 --version 查询模式 。卡上当时只有 3 个固件组件(hboot1a/b、hlink,出厂旧版 1.82.22.2.220),而配套包定义了 6 个(另含 lpddr_mcu.bin 等 LPDDR 控制器固件)。

解法 :见 §3.4,单独执行固件包 + 重启虚拟机。修复后固件版本变为 7.8.0.7.220,崩溃消失。

5.3 ★ "固件不支持在虚拟机安装"------这个限制在直通下不触发

华为文档明写"固件包不支持在虚拟机安装和卸载",很容易据此认为"必须在物理机刷固件 → 宿主要装 Ascend 驱动 → 宿主内核 7.0.6 编译驱动风险极高 → 整条路走不通"。

这个结论是错的。 该限制的实现是固件安装器 install.sh 中的 vmCheck():

bash 复制代码
"${Install_Path_Param}"/driver/tools/upgrade-tool --device_index ${global_top_up_chip} --phymachflag >& /dev/null && ret=$? || ret=$?
if [ ${ret} -eq 2 ]; then
    log "[ERROR]not a physical-machine, firmware upgrade does not support."
    return 1
fi

退出码 2 = 非物理机 → 拒绝。VM 内实测:

复制代码
$ sudo /usr/local/Ascend/driver/tools/upgrade-tool --device_index 0 --phymachflag
	{"device_id":0 phy mach}
rc=0        # ← 返回 0,不是 2

驱动把 vfio 直通卡识别为物理机(它看到的确实是一张真实 PCIe 卡),闸门放行。其余三个前置检查同样可过:

检查 判据 实测
firmwareHostReady 扫 /sys/bus/pci/devices/,vendor ∈ `0x19e5 0xffff
toolsExistCheck upgrade-tool 存在 ✔
firmwareDeviceReady 8 upgrade-tool --system_version 能枚举到芯片 返回 {"device_id":0, "version":25.5.2} ✔

附带发现:驱动安装日志里有 FEATURE_VIRT_SCENE is : y ------ 驱动包本身知道虚拟化场景,这也是它把卡认作物理机的原因。

5.4 apt 源缺 focal-updates → OpenCV 依赖链断掉

现象 :libopencv-dev 装不上或装到不完整版本(libgphoto2-6 需要 2.5.25,源里只有 dev 2.5.24)。

解法 :换清华镜像并显式补上 focal-updates / focal-security(见 §3.2)。换完 dpkg --audit 干净。

5.5 ★ aclrtGetRunMode()==ACL_HOST 会误判成"跑在 CPU 模拟器"

现象 :程序打印 [ascend] running in simulator/CPU mode。

CANN 8.5.2 的枚举是 ACL_DEVICE = 0 / ACL_HOST = 1,而独立探针证明所有阶段都是 ACL_HOST:

复制代码
编译期枚举: ACL_DEVICE=0  ACL_HOST=1
[aclInit 后            ] err=0 runMode=1  ACL_HOST
[aclrtSetDevice 后     ] err=0 runMode=1  ACL_HOST
[aclrtCreateContext 后 ] err=0 runMode=1  ACL_HOST
[aclrtCreateStream 后  ] err=0 runMode=1  ACL_HOST

但 T8 的三路证据表明算术确由 AICore 执行。结论:310P 上该 API 恒返回 ACL_HOST,与是否真的在模拟器里跑无关。

附带澄清 :正常运行时 LD_PRELOAD 与 SIMULATOR_HOME 均为空 → 没有 加载 libruntime_camodel.so / libcamodel.so,用的就是 CANN 真实运行时。项目里 AscendDemo/SIMULATOR_SUMMARY.md 描述的那套 LD_PRELOAD 启动方式与本场景无关。

正确判定方法(三路交叉,缺一不可):

  1. 造一个依赖输入、不可常量折叠 的重模型(把输入 reshape 成 [K,K] 再做 K 级批量矩阵乘,批量维必须 > 1,否则 MAC 数会少两个数量级)
  2. 墙钟斜率 对比:小模型 vs 重模型,取 bench N / bench M 两点求每帧耗时。跑 Host CPU 会慢几百倍
  3. npu-smi info -t usages 的 Aicore Usage Rate 交叉验证------该计数器分辨率很粗,小模型(每帧 0.15 ms)恒读 0,重模型才显形

5.6 其他已解决的小坑

现象 根因 解法
HwHiAiUser not exists! Please add HwHiAiUser 驱动安装器硬性要求该用户/组 groupadd -f HwHiAiUser + useradd -g HwHiAiUser -d /home/HwHiAiUser -m -s /bin/bash HwHiAiUser
npu-smi 报权限错 /dev/davinci* 属 HwHiAiUser 组 sudo usermod -aG HwHiAiUser <user>,或 sg HwHiAiUser -c "npu-smi info"
nnal 安装失败 依赖 ASCEND_TOOLKIT_HOME 等环境变量 装完 toolkit 后 source set_env.sh,再带全套 env 重装 nnal
atc 报 No module named 'decorator' 当前 shell 激活了 uv venv,atc 用的是 venv 的 python 转换前 deactivate 或另开一个干净会话(用系统 python3)
atc 报 Value for --framework is invalid 用了 --framework=10 改成 --framework=5(CANN 8.5.2 只接受 0/1/3/5)
ctest: Unknown option --test-dir 该选项需 CMake ≥ 3.20,本机 3.16 cd build && ctest
ImportError: libmsprofiler.so Python 扩展加载时找不到 CANN 运行时库 source /usr/local/Ascend/ascend-toolkit/set_env.sh 后再运行

6. 复现步骤速查

给需要复现本报告的同事,按顺序执行即可:

bash 复制代码
# ── 0. 准备:宿主 ────────────────────────────────────────────
#    把卡绑定到 vfio-pci,reboot,确认 lspci -k 显示 vfio-pci

# ── 1. 准备:客户端 OS ──────────────────────────────────────
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak-ascend
#    换清华源 + 补 focal-updates / focal-security(见 §3.2)
sudo apt update && sudo apt install -y build-essential cmake git pkg-config \
    libopencv-dev nlohmann-json3-dev libgtest-dev python3-dev python3-pip \
    ffmpeg libavcodec-dev
sudo groupadd -f HwHiAiUser
sudo useradd -g HwHiAiUser -d /home/HwHiAiUser -m -s /bin/bash HwHiAiUser
echo 'vm.nr_hugepages = 2048' | sudo tee /etc/sysctl.d/99-ascend-hugepages.conf
sudo sysctl --system

# ── 2. 驱动(先打内核头补丁,见 §5.1)────────────────────────
sudo ./Ascend-hdk-310p-npu-driver_25.5.2_linux-x86-64.run --full
sudo reboot

# ── 3. 固件(★ 最容易漏,见 §5.2 / §5.3)─────────────────────
sudo ./Ascend-hdk-310p-npu-firmware_7.8.0.7.220.run --full --quiet
#    然后在 PVE 宿主:qm shutdown 101 && qm start 101
sudo /usr/local/Ascend/driver/tools/upgrade-tool --device_index -1 --component -1 --version
#    期望看到 7.8.0.7.220

# ── 4. CANN ─────────────────────────────────────────────────
yes | sudo ./Ascend-cann-toolkit_8.5.2_linux-x86-64.run --install
yes | sudo ./Ascend-cann-310p-ops_8.5.2_linux-x86-64.run --install
source /usr/local/Ascend/ascend-toolkit/set_env.sh
yes | sudo env "ASCEND_TOOLKIT_HOME=$ASCEND_TOOLKIT_HOME" \
              "ASCEND_NNAE_HOME=$ASCEND_NNAE_HOME" \
              "ASCEND_HOME_PATH=$ASCEND_HOME_PATH" \
              "ASCEND_OPP_PATH=$ASCEND_OPP_PATH" \
              "ASCEND_AICPU_PATH=$ASCEND_AICPU_PATH" \
              "TOOLCHAIN_HOME=$TOOLCHAIN_HOME" \
              ./Ascend-cann-nnal_8.5.2_linux-x86-64.run --install

# ── 5. Python ───────────────────────────────────────────────
#    venv: numpy/onnx/onnxruntime/opencv-headless/torch
#    系统 python3: numpy<1.25 protobuf<3.21 attrs psutil pyyaml cffi pillow sympy scipy requests absl-py decorator

# ── 6. 编译 + 单测 ──────────────────────────────────────────
cmake -S . -B build -DASCEND_ENABLED=ON \
  -DASCEND_DIR=/usr/local/Ascend/ascend-toolkit/latest \
  -DPython3_EXECUTABLE=$PWD/.venv/bin/python
cmake --build build -j$(nproc)
cd build && ctest --output-on-failure        # 期望 4/4

# ── 7. 推理验收 ─────────────────────────────────────────────
source /usr/local/Ascend/ascend-toolkit/set_env.sh
./build/ascend_demo --model ../test_assets/test_model.om \
  --image ../test_assets/test.jpg --output ../test_assets/result_img.jpg --bench 1
./build/ascend_demo --model ../test_assets/test_model.om \
  --video ../test_assets/test_video.mp4 --output ../test_assets/result_video.mp4 --bench 75 --no-track

# ── 8. 稳定性复核(宿主)─────────────────────────────────────
dmesg | grep -c -i CmpltAbrt        # 期望:固件修复后不再增长

判定标准(三条同时满足即认为本卡在该环境可用)

  1. npu-smi info 识别为 310P3 且 Health = OK
  2. upgrade-tool --component -1 --version 报出与驱动配套的固件版本
  3. ctest 4/4 通过,且推理程序能加载模型并产出正确结果

7. 结论与已知限制

7.1 结论

华为 Atlas 300V 视频解析卡在"PVE 宿主 + 整机 PCIe 直传到 Ubuntu 20.04 虚拟机"这一环境下可以正常使用。

支撑依据:

  • 设备被正确枚举为 Ascend 310P3,健康状态 OK,显存与温度可读
  • 驱动 25.5.2 / 固件 7.8.0.7.220 / CANN 8.5.2 三层版本严格配套
  • 单元测试 4/4 通过,单帧与视频推理均产出数值正确的结果
  • 重负载下 AICore 利用率实时抬升,算术确由 NPU 执行,未退化为 Host 侧
  • 宿主 PCIe 错误计数在固件修复后归零,链路稳定
  • 全部 8 项测试用例判定 PASS

同时确认:整条路径中最致命的一环是"固件必须单独安装,且可以在虚拟机内安装"------这两点任何一点搞错,现象都是"第一次推理直接把虚拟机打崩",且错误信息完全指不到真因。

7.2 已知限制与未覆盖项

# 限制 影响 后续
1 DVPP 预处理未启用 ,demo 走 CPU 回退([infer] DVPP path declined; CPU fallback) 预处理耗时占比高(单帧 98 ms 中 98 ms 是预处理),端到端实时性未达最优 待真模型后做 DVPP vs CPU 对照
2 缺真模型,性能数据仅来自合成模型 无法给出有业务意义的绝对算力基线 shv54.pt 是 pickled nn.Module(依赖 models.yolo.DetectionModel),需补源码或给 TorchScript 版本
3 npu-smi info -t board 的 Firmware Version 恒为 NA 仅影响读数,固件实际已正确刷入 以 upgrade-tool 为准
4 PCIe 链路只到 Gen3 (8 GT/s) 带宽从理论 16 GB/s 降到约 7.9 GB/s 宿主上游 root port 17:00.0(Sky Lake-E)硬件上限,未改
5 重模型折算的等效算力高于 310P 标称 FP16 峰值 怀疑 atc tiling 对链式 MatMul 做了部分化简 用真模型重新标定
6 未做宿主 IOMMU 模式 / 大页调优 当前 iommu=pt + 客户端 2GB 大页已满足需求 若性能不达标,再按官方 Debian 示例评估切翻译模式 + 宿主预留大页(注意宿主仅 62GB 内存,不可照抄官方的 512M×128)
7 未测试多卡 / 多 VM 共享 / vNPU 切分 --- 属另一条技术路线

附录 A:日志与诊断位置

内容 路径
驱动安装日志 /var/log/ascend_seclog/ascend_install.log
固件安装日志 /var/log/ascend_seclog/ascend_install.log([Firmware] 段)、/var/log/ascend_seclog/operation.log
设备启动日志 /var/log/device_boot_init.log
驱动运行日志 /var/log/ascend_seclog/ascend_rebuild.log
CANN plog(运行期) ~/ascend/log/run/plog/plog-<pid>_*.log
CANN plog(debug) ~/ascend/log/debug/plog/plog-<pid>_*.log
固件升级日志 /var/log/upgradetool/upgrade_crl.log
宿主 PCIe 错误 宿主 `dmesg

开启 CANN debug 日志:

bash 复制代码
export ASCEND_GLOBAL_LOG_LEVEL=debug
export ASCEND_MODULE_LOG_LEVEL=GE:debug,RUNTIME:debug,ACL:debug

附录 B:常用诊断命令

bash 复制代码
# 设备
sg HwHiAiUser -c "npu-smi info"
sg HwHiAiUser -c "npu-smi info -t board -i 256 -c 0"
sg HwHiAiUser -c "npu-smi info -t usages -i 256 -c 0"     # AICore / DDR / DVPP 利用率
sg HwHiAiUser -c "npu-smi info -t product -i 256 -c 0"    # Product Type : Atlas 300V
sg HwHiAiUser -c "npu-smi info -t pcie-err -i 256 -c 0"   # PCIe 错误计数
sg HwHiAiUser -c "npu-smi info -t flash -i 256 -c 0"      # SPI Flash 信息

# 固件 / 版本
sudo /usr/local/Ascend/driver/tools/upgrade-tool --device_index -1 --component -1 --version
sudo /usr/local/Ascend/driver/tools/upgrade-tool --device_index 0 --phymachflag
cat /usr/local/Ascend/driver/version.info
cat /usr/local/Ascend/firmware/version.info

# 模型
atc --mode=1 --om=xxx.om --json=/tmp/om_dump.json      # dump .om 算子图与权重字节数
相关推荐
腾科IT教育3 小时前
HCIP-Security 华为Portal认证技术与配置解析
网络·华为·portal·hcip-security
李&@杰5 小时前
交换机网络环路导致MAC漂移及业务中断故障处理
网络·华为
IsITGirl1 天前
HarmonyOS 鸿蒙 WuKong 稳定性测试报错 Failed to connect to AAMS(已解决)
华为·harmonyos
万物智能信息科技1 天前
鸿蒙RS232驱动开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
驱动开发·华为·开源·harmonyos·鸿蒙
less_121381 天前
鸿蒙 WPS Open SDK 接入指南:凭据申请、HAR 集成与 registerApp 校验
华为·harmonyos·wps
hunterandroid2 天前
HarmonyOS 长列表滚动性能优化:预渲染、离屏缓存与 GPU 合成策略
华为·前端框架
熊猫钓鱼>_>2 天前
Kotlin Multiplatform for OpenHarmony 实战:kotlinx-serialization JSON 适配
开发语言·华为·kotlin·华为云·json·harmonyos·code
马剑威(威哥爱编程)3 天前
【共创稿事节】HarmonyOS 7 Agent 开发实战 11:并发多会话隔离
华为·harmonyos
马剑威(威哥爱编程)3 天前
【共创稿事节】HarmonyOS 7 Agent 开发实战 03:Tool Calling 让 AI 查实时订单与库存
华为·harmonyos