使用 Vitis AI 部署 Ultralytics YOLO 到 AMD Xilinx#
AMD Xilinx 设备的 Ultralytics 原生导出支持即将推出。在此之前,本指南将介绍 AMD Xilinx 的硬件和软件生态,并说明如何从 ONNX 导出文件或 PyTorch 检查点开始,立即使用 AMD Vitis AI 工具部署 Ultralytics YOLO26。
AMD Xilinx 设备广泛应用于全球各地的工业相机、汽车视觉系统、机器人、无人机和医学影像产品。这些设备将 Arm 处理器与可编程逻辑相结合,新款设备还配备专用 AI Engines,因此单个芯片便能采集视频、进行预处理、执行目标检测,并以低且可预测的推理延迟对结果作出响应。
本指南介绍各 AMD Xilinx 设备系列、设备上的 AI 运行方式、每种加速器支持的 Ultralytics YOLO 算子,以及在 Zynq UltraScale+、Kria 和 Versal 硬件上部署 YOLO 模型的分步工作流。
什么是 AMD Xilinx?#
Xilinx 于 20 世纪 80 年代发明了现场可编程门阵列(FPGA),并成为自适应 SoC 和 FPGA领域的领先供应商。AMD 于 2022 年 2 月完成对 Xilinx 的收购,如今这些产品线以 AMD 品牌销售,名称分别为 AMD Zynq、AMD Kria、AMD Versal 和 AMD Vitis。
这两个名称指的是相同的产品。AMD 将它们称为“自适应 SoC 和 FPGA”,但工程师仍普遍使用“Xilinx”这个名称。部件号保留 XC 前缀(例如 xczu7ev),而较早的 Vitis AI 仓库和 Docker 镜像仍以 Xilinx 名称托管在 GitHub 和 Docker Hub 上。本指南使用“AMD Xilinx”,方便你通过任一名称找到相关内容。
关键术语和概念#
AMD Xilinx 部署有一套专用术语。下表解释了本指南中使用的所有术语。
| 术语 | 含义 |
|---|---|
| FPGA | 现场可编程门阵列:一种芯片,其数字逻辑可在制造完成后通过加载称为位流的设计来配置。它可实现视频管线或神经网络加速器等定制硬件。 |
| 可编程逻辑(PL) | AMD Xilinx SoC 内部的 FPGA 逻辑。在 Zynq 和 Kria 设备上,AI 加速器构建于 PL 中。 |
| 处理系统(PS) | SoC 的硬核 Arm CPU、内存控制器和外设。它运行 Linux、你的应用程序,以及加速器无法执行的模型层。 |
| 自适应 SoC / MPSoC | 一种将处理系统与可编程逻辑集成在一起的片上系统,许多 Versal 设备还配有 AI Engines。MPSoC 是多处理器片上系统的简称。 |
| AI Engine(AIE、AIE-ML、AIE-MLv2) | 许多 Versal 设备上的硬化向量处理器阵列,包括本指南介绍的 Versal AI Edge 系列;这些阵列专为机器学习和信号处理而设计。 |
| DPU | 深度学习处理单元:AMD 的 INT8 神经网络加速器,以 IP 形式交付并构建于 PL 中(例如 Zynq UltraScale+ 和 Kria 上的 DPUCZDX8G)。B512 到 B4096 等规格表示每个时钟周期的峰值运算次数。 |
| NPU / NPU IP | 神经处理单元:AMD 当前一代的推理加速器,在近期的 Vitis AI 版本中取代了 DPU。AMD 将其 NPU IP 描述为结合 AI Engines 与可编程逻辑的软加速器,因此还需要匹配的硬件设计。请参阅 NPU 术语表条目。 |
| Vitis AI | AMD 为在 AMD Xilinx 设备上部署神经网络提供的工具链,涵盖量化、编译、运行时、示例和 Docker 环境。 |
| AMD Quark | AMD 当前的模型量化库,Versal AI Edge Gen 2 工作流使用该库将 FP32 ONNX 模型转换为 INT8 模型。 |
| 量化、PTQ 和 QAT | 将 FP32 权重和激活值转换为 INT8。训练后量化(PTQ)使用校准图像。量化感知训练(QAT)通过微调模型来恢复精度。 |
| 校准图像 | 在 PTQ 期间输入模型的一小组代表性图像,用于为每个张量选择 INT8 缩放比例。 |
| BF16 和混合精度 | BFloat16 是一种 16 位浮点格式,数值范围与 FP32 相同。混合精度让网络的大部分以 INT8 运行,敏感层则以 BF16 运行。 |
| XIR | Xilinx 中间表示:DPU 编译器生成、运行时读取的图格式。 |
.xmodel | 序列化的 XIR 图。量化器会写出量化后的 .xmodel,DPU 编译器则将其转换为编译后的 .xmodel,其中包含 DPU 指令、量化权重和任何 CPU 子图。编译后的模型需要匹配的 DPU 配置。 |
arch.json / DPU 指纹 | 用于描述特定 DPU 配置的文件。DPU 编译器需要该文件,而且针对某个指纹编译的 .xmodel 无法在其他指纹上运行。 |
| 快照 | Versal AI Edge(VEK280)NPU 工作流生成的编译模型目录。它与某个 NPU IP 变体绑定。 |
.rai | Versal AI Edge Gen 2 NPU 工作流生成的编译模型文件。 |
| VART / VART-ML | Vitis AI Runtime 库,用于加载编译后的模型并在开发板上运行模型,提供 C++ 和 Python API。 |
| ONNX Runtime Vitis AI EP | 用于 ONNX Runtime 的 VitisAIExecutionProvider,可在 AMD NPU 上编译和运行 ONNX 模型。 |
| CPU 回退 / 图划分 | 当加速器无法运行某个算子时,编译器通常会将模型拆分为加速器子图和 CPU 子图;每次拆分都会增加一次数据传输,而这可能成为延迟的主要来源。某些算子则会导致整个模型改由 CPU 执行,或使编译失败。 |
适用于边缘 AI 的 AMD Xilinx 设备系列#
适用于边缘 AI 的 AMD Xilinx 设备分为三个系列。Zynq 和 Kria 在可编程逻辑中使用 DPU,而本指南介绍的 Versal AI Edge 设备则在其 AI Engines 上使用 NPU。
| 系列 | 简介 | 应用处理器 | AI 加速器 | 开发板示例 |
|---|---|---|---|---|
| Zynq UltraScale+ MPSoC | 在同一芯片上集成 Arm CPU 和 FPGA 逻辑,规格从 ZU1 到 ZU19 | 双核或四核 Arm Cortex-A53 | 构建于可编程逻辑中的 DPU | ZCU104、ZCU102、定制开发板 |
| Kria K26 系统级模块 | 基于 Zynq UltraScale+ MPSoC 构建的量产级模块 | 四核 Arm Cortex-A53 | 构建于可编程逻辑中的 DPU | KV260 Vision AI 入门套件、KR260 Robotics 入门套件 |
| Versal AI Edge 系列 | 自适应 SoC;VE2302 和 VE2802 等 AIE-ML 芯片运行 NPU | 双核 Arm Cortex-A72 | 位于 AIE-ML AI Engines 和 PL 上的 NPU | VEK280 |
| Versal AI Edge 系列 Gen 2 | 搭载 AIE-MLv2 AI Engines 的新一代自适应 SoC | 最多八个 Arm Cortex-A78AE | 位于 AIE-MLv2 AI Engines 和 PL 上的 NPU | VEK385 |
Zynq UltraScale+ MPSoC#
每款 Zynq UltraScale+ 芯片都将 Arm 处理系统与 FPGA 逻辑相结合。处理系统配有双核(CG)或四核(EG 和 EV)Cortex-A53 核心以及实时 Cortex-R5F 核心。EV 设备还增加了硬化 H.264/H.265 视频编解码器。要运行神经网络,设计人员会在摄像头和视频管线旁的逻辑中构建 DPU。在小型设备上,DPU 会与设计的其他部分争夺空间。
Kria 系统级模块#
Kria K26 模块将 Zynq UltraScale+ MPSoC、内存和电源集成在量产级模块中,因此你无需自行设计处理器、内存和电源子系统。该模块可插入载板,可以是入门套件开发板,也可以是你自己的设计。它为智能摄像头提供 KV260 Vision AI 入门套件,为机器人提供 KR260 Robotics 入门套件。由于 K26 基于 Zynq UltraScale+ 构建,因此使用相同的 DPU 工作流。Kria 产品组合还包括其他模块,因此选择工作流前,请确认你的模块使用哪种处理器。
Versal 自适应 SoC#
Versal 是 AMD 的自适应 SoC 系列。其 AI Edge 和 AI Core 系列在 Arm 核心与可编程逻辑旁增加了硬化 AI Engines,而其他一些 Versal 系列则没有 AI Engines。AMD 的 NPU IP 会同时运行于 AI Engines 和可编程逻辑之上;Vitis AI 面向 AI Edge 系列中的 AIE-ML 芯片,例如 VE2302 和 VE2802。Versal AI Edge 系列(VEK280 评估套件)和 Versal AI Edge 系列 Gen 2(VEK385 评估套件)是 AMD 当前面向边缘 AI 的目标平台,也是当前 Vitis AI 版本的重点。
AMD Xilinx 设备上的 AI 运行方式:DPU 与 NPU#
大多数 AMD Xilinx AI 部署都遵循相同的模式。加速器运行其支持的层;Arm CPU 负责预处理、后处理,以及加速器无法执行的层;开发板上的运行时负责协调二者。
graph LR
A[Camera / video input]:::start --> B[Arm CPU<br>Linux, preprocessing,<br>post-processing]:::proc
B <--> C[AI accelerator<br>DPU in programmable logic<br>or NPU on AI Engines + PL]:::out
B --> D[Application<br>alerts, control, display]:::start
classDef start fill:#4CAF50,color:#fff
classDef proc fill:#2196F3,color:#fff
classDef out fill:#9C27B0,color:#fffAMD 已推出两代加速器,每一代都有各自的工具链和编译模型文件。本指南使用 Vitis AI 3.5 介绍 DPU,使用 Vitis AI 6.3 介绍 NPU;如需了解后续版本,请查阅 AMD 的最新文档。
| 工作流 | 硬件 | 工具链 | 量化器 | 编译产物 | 开发板运行时 | 状态 |
|---|---|---|---|---|---|---|
| DPU | Zynq UltraScale+、Kria | Vitis AI 3.5(Docker) | vai_q_pytorch | .xmodel | VART | 固定版本的编译器、模型库和 DPU IP |
| NPU(Versal AI Edge) | VEK280 和其他 Versal AI Edge 器件 | Vitis AI 6.3(Docker) | 内置于快照流程中 | 快照 | VART-ML | 活跃 |
| NPU(Versal AI Edge Gen 2) | VEK385 和其他 Gen 2 器件 | Vitis AI 6.3(Docker) | AMD Quark | .rai | ONNX Runtime Vitis AI EP 或 VART-ML | 活跃 |
Vitis AI 3.5 是最后一个包含 DPU 编译器和模型库更新的版本。后续版本在 Xilinx/Vitis-AI 仓库中保持编译器、模型库和 Zynq UltraScale+ DPU IP 不变,同时更新运行时和对较新 AMD 工具版本的兼容性(参见 Vitis AI 5.0 发行说明);AMD 当前的 Vitis AI 文档则将 NPU 描述为已弃用 DPU 架构的替代方案。现有 Zynq UltraScale+ 和 Kria 产品可以继续使用 DPU 出货,但其算子支持不会扩展,因此较新的模型架构需要采用 YOLO 模型兼容性中介绍的适配方法。
PC 中的 AMD Ryzen AI 处理器也包含 NPU,但它们使用独立的 Ryzen AI Software 技术栈,而不是本指南介绍的嵌入式 Vitis AI 流程。AMD Instinct 和 Radeon GPU 请参阅 AMD GPU 集成。
我需要哪种 Vitis AI 流程?#
根据开发板上的器件选择流程:
graph TD
A[Start: which AMD device<br>is on your board?]:::start --> B{Device family?}:::decide
B -->|Zynq UltraScale+ MPSoC<br>or Kria K26| C[DPU flow<br>Vitis AI 3.5]:::proc
B -->|Versal AI Edge<br>VEK280| D[NPU snapshot flow<br>Vitis AI 6.3]:::proc
B -->|Versal AI Edge Gen 2<br>VEK385| E[NPU Quark flow<br>Vitis AI 6.3]:::proc
C --> F[Train YOLO with Hard-Swish<br>then compile to .xmodel]:::out
D --> G[Run your model on calibration<br>images to capture a snapshot]:::out
E --> H[Quantize ONNX with Quark<br>then compile to .rai]:::out
classDef start fill:#4CAF50,color:#fff
classDef proc fill:#2196F3,color:#fff
classDef decide fill:#FF9800,color:#fff
classDef out fill:#9C27B0,color:#fffYOLO 模型兼容性与支持的算子#
加速器只能加速由硬件实现的算子。如果模型包含不受支持的算子,编译器通常会将网络的这部分交给 Arm CPU 运行,而加速器与 CPU 之间的每次往返都会增加延迟。有些算子无法进行分区:在 Versal AI Edge Gen 2 NPU 上,AMD 列出的 NonZero 和 NonMaxSuppression 等算子可能会导致整个模型都在 CPU 上运行。算子支持是影响 YOLO 模型在 AMD Xilinx 硬件上运行效果的最重要因素。
graph LR
subgraph S1 [Stock YOLO26 on the DPU]
A1[Conv]:::out --> A2[SiLU<br>CPU]:::error --> A3[Conv]:::out --> A4[SiLU<br>CPU]:::error --> A5[...]:::proc
end
subgraph S2 [Hard-Swish YOLO26 on the DPU]
B1[Backbone<br>Conv + Hard-Swish<br>DPU]:::out --> B2[C2PSA attention<br>CPU]:::error --> B3[Neck<br>DPU]:::out --> B4[C3k2 attention<br>CPU]:::error --> B5[Detect head<br>DPU]:::out --> B6[Sigmoid and<br>post-processing<br>CPU]:::error
end
classDef proc fill:#2196F3,color:#fff
classDef out fill:#9C27B0,color:#fff
classDef error fill:#F44336,color:#fff此表展示了 YOLO26 模型中的各个算子在哪里运行。未经修改的 YOLO26n ONNX 导出模型包含 87 个 SiLU 激活,每个都导出为一个 Sigmoid 和一个 Mul;此外还有 4 个 MatMul 算子和 2 个 Softmax 算子,它们来自两个注意力模块:C2PSA 模块位于主干网络末端(第 10 层),启用注意力的 C3k2 模块则负责生成 P5 输出(第 22 层)。
| 算子 | 在 YOLO 中的位置 | DPU(Zynq UltraScale+、Kria) | NPU(Versal AI Edge Gen 2) |
|---|---|---|---|
| 卷积 + 批归一化 | 每个 Conv 模块 | ✅ | ✅ |
| SiLU 激活 | 每个 Conv 模块(默认激活函数) | ❌ 在 CPU 上运行;替换为 Hard-Swish | ✅ |
| Hard-Swish、ReLU、ReLU6、LeakyReLU | 在模型 YAML 中设置的可选激活函数 | ✅ 融合到卷积中 | ✅ |
| Sigmoid | 检测头中的类别分数 | ❌ 在 CPU 上运行(通常属于后处理的一部分) | ✅ |
| 两个激活之间的 MatMul | 注意力模块(C2PSA;YOLO26 C3k2) | ❌ 在 CPU 上运行 | ✅ |
| Softmax | 注意力模块;YOLOv8 和 YOLO11 中的 DFL | ❌ 在 CPU 上运行 | ✅ |
| Reshape、Transpose | 注意力模块 | ⚠️ 尽可能融合,否则在 CPU 上运行 | ✅ |
| Split、Slice | C3k2 和 C2f 模块 | ⚠️ 转换为切片;请检查编译器报告 | ✅ |
| Resize(最近邻上采样) | 颈部网络上采样 | ✅ | ✅ |
| MaxPool、Concat、Add | SPPF 模块和特征融合 | ✅ | ✅ |
| TopK、GatherElements | YOLO26 无 NMS 检测头(nms=False) | ❌ 在 CPU 上运行 | ⚠️ 在 Arm 主机上进行 CPU 分区 |
| NonMaxSuppression | 仅在使用 nms=True 导出时 | ❌ 在 CPU 上运行 | ❌ 可能导致模型在 CPU 上运行 |
来源:AMD 的 UG1414 支持的算子、PyTorch 算子支持,以及 Versal AI Edge Gen 2 的支持、CPU 分区和不支持的算子列表。支持情况还取决于 DPU 配置和计算图模式,因此务必检查编译器的分区报告。
YOLO26 移除了分布焦点损失 (DFL),因此不同于 YOLO11 和 YOLOv8,它的边界框输出无需通过 softmax 解码。与 YOLO11 相比,它还增加了第二个注意力模块,因此在选择模型之前,请比较针对目标设备的编译器报告和设备端基准测试结果。未设置 nms 时导出的模型会保留一对多检测头,并且和其他 YOLO 模型一样,需要在 CPU 上执行 NMS。设置 nms=False 导出,即可改用 YOLO26 的 无 NMS 一对一检测头,它以轻量级 top-k 选择取代 NMS,并在 CPU 上运行。
通过 Hard-Swish 让 YOLO26 适配 DPU#
DPU 只会将 ReLU、ReLU6、LeakyReLU、Hard-Swish 和 Hard-Sigmoid 融合到卷积中。Hard-Swish 是 SiLU 的硬件友好近似,因此是自然的替代方案。Ultralytics 模型 YAML 文件支持 activation 键,用于更改 Conv 模块的默认激活函数(模型 YAML 配置指南)。
将 yolo26.yaml 复制到 yolo26-hswish.yaml,然后在参数下添加一行:
# Parameters
nc: 80 # number of classes
activation: nn.Hardswish() # default Conv activation, DPU-native
end2end: True # whether to use end-to-end mode然后构建模型,迁移预训练的 YOLO26 权重,并在你的数据集上微调:
from ultralytics import YOLO
# 使用 Hard-Swish 激活构建 YOLO26n;名称中的 'n' 表示 nano 尺度
model = YOLO("yolo26n-hswish.yaml").load("yolo26n.pt") # 迁移预训练权重
# 进行微调,使网络适配 Hard-Swish
model.train(data="coco8.yaml", epochs=100, imgsz=640)激活函数没有权重,因此所有预训练权重都会迁移。导出的 ONNX 计算图随后会包含 87 个 HardSwish 算子,且不包含 SiLU。将 coco8.yaml 替换为你自己的数据集,并在部署前使用验证模式将准确率与 SiLU 模型进行比较。
- 在量化时替换:在 Vitis AI 3.5 PyTorch 量化器的 JSON 配置中设置
"convert_silu_to_hswish": true,即可在量化期间替换 SiLU。这样可以省去一次训练,但通常会损失更多准确率;AMD 的快速微调或 QAT 可以弥补其中一部分。请参阅 vai_q_pytorch 配置指南。 - LeakyReLU:DPU 使用固定的负斜率 26/256(约为 0.1)实现 LeakyReLU。如果使用 LeakyReLU,请使用
activation: nn.LeakyReLU(0.1015625)进行训练,以确保训练和部署时的斜率一致。
在 DPU 上处理注意力模块#
YOLO26 在最低分辨率处(输入尺寸为 640 时是 20×20 网格)应用注意力,共两处:C2PSA 模块位于第 10 层,启用注意力的 C3k2 模块位于第 22 层。YOLO11 有一个 C2PSA 模块。在 DPU 上,它们的 MatMul 和 Softmax 算子会在 CPU 上运行,从而将模型拆分为交替运行的 DPU 和 CPU 子图。你有三种选择:
-
接受 CPU 模块。 编译后的
.xmodel会包含 CPU 子图,因此请使用 AMD 的 Graph Runner 运行;当每个算子都有 CPU 实现时,它会一起执行 DPU 和 CPU 子图,否则你必须实现并注册缺少的算子。20×20 时注意力计算量很小,但 DPU 与 CPU 之间的每次额外传输都会增加延迟,因此请在开发板上进行测量。 -
使用不含注意力的 YAML。 在 Hard-Swish YAML 中,将 C2PSA 层替换为
nn.Identity,以确保Concat和Detect使用的层索引仍然有效,并禁用第 22 层中的注意力:backbone: # ... layers 0-9 unchanged - [-1, 1, nn.Identity, []] # 10 C2PSA removed; keeps later layer indices valid head: # ... layers 11-21 unchanged - [-1, 1, C3k2, [1024, True, 0.5, False]] # 22 (P5/32-large), attention disabled - [[16, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)导出的 ONNX 计算图随后将不包含 MatMul 或 Softmax 算子。注意力权重将不再适用(YOLO26n 的 666 个权重中有 624 个可以迁移),因此请延长微调时间,并使用验证模式比较准确率。
-
使用不含注意力的模型,例如 YOLOv8;AMD 在自己的 DPU 示例中使用过该模型。
在 Versal AI Edge Gen 2 上,注意力算子被列为 NPU 支持的算子,因此通常不需要进行这些更改。请在编译器报告中确认算子的位置,因为 AMD 指出,即使算子受支持,也可能因配置或内存限制而回退到 CPU。
模型兼容性一览#
| 模型 | DPU(Zynq UltraScale+、Kria) | NPU(Versal AI Edge Gen 2) |
|---|---|---|
| YOLO26 | 使用 Hard-Swish 训练;两个注意力模块会成为 CPU 子图;不使用 DFL | 预计无需更改即可运行;请在你的开发板上验证 |
| YOLO11 | 使用 Hard-Swish 训练;C2PSA 和 DFL softmax 在 CPU 上运行 | 预计无需更改即可运行;请在你的开发板上验证 |
| YOLOv8 | 使用 Hard-Swish 训练;DFL softmax 在 CPU 上运行 | AMD 的 YOLOv8m 教程(Vitis AI 6.3、VEK385、INT8 搭配 BF16 尾部):编译器报告显示 NPU 上有 1,181 个算子(99.915%),GOPs 占比为 99.994%,无需更改模型 |
立即在 AMD Xilinx 上部署 YOLO26#
在原生导出功能可用之前,部署分为四个步骤:
graph LR
A[1. Train or fine-tune<br>Ultralytics YOLO]:::start --> B{Target?}:::decide
B -->|Versal NPU| C[2. Export to ONNX<br>model.export]:::proc
B -->|Zynq or Kria DPU| D[2. Keep the trained<br>PyTorch checkpoint]:::proc
C --> E[3. Quantize and compile<br>Vitis AI 6.3 Docker]:::proc
D --> F[3. Quantize and compile<br>Vitis AI 3.5 Docker]:::proc
E --> G[4. Run on the board<br>VART-ML or ONNX Runtime]:::out
F --> H[4. Run on the board<br>VART]:::out
G -.->|accuracy check| A
H -.->|accuracy check| A
classDef start fill:#4CAF50,color:#fff
classDef proc fill:#2196F3,color:#fff
classDef decide fill:#FF9800,color:#fff
classDef out fill:#9C27B0,color:#fff步骤 1:训练或微调模型#
使用训练模式在你自己的数据上训练,或在 Ultralytics Platform 上训练。对于 DPU 目标设备,请从 Hard-Swish YAML 开始。使用验证模式记录基准,以便之后测量量化对准确率的影响。
步骤 2:为 NPU 目标设备导出为 ONNX#
ONNX 是 AMD NPU 流程的通用输入。DPU 流程会在 Vitis AI 3.5 Docker 镜像中直接量化训练好的 PyTorch 检查点,因此 DPU 用户可以跳过此步骤。导出时请使用固定批次大小 1,以及 AMD 支持的 opset;AMD 面向 Versal AI Edge Gen 2 的 YOLOv8m 教程使用 opset 17。
from ultralytics import YOLO
# 加载你在步骤 1 中训练的模型
model = YOLO("runs/detect/train/weights/best.pt")
# 导出为 ONNX,并使用静态形状供 AMD 编译器处理
model.export(format="onnx", opset=17, imgsz=640) # 在 'best.pt' 旁创建 'best.onnx'所有选项请参阅 ONNX 集成和导出参数。未设置 nms 时,请在推理后于 CPU 上运行 NMS;对于 YOLO26,nms=False 用于选择无 NMS 检测头。不要使用 nms=True 嵌入 NMS,因为 AMD 将 NonMaxSuppression 列为可能导致整个模型在 CPU 上运行的算子之一。
AMD 的 Docker 镜像自带包含 Vitis AI Execution Provider 的 ONNX Runtime 构建版本。Ultralytics 会在导出期间检查 ONNX Runtime,并可能用标准软件包覆盖它。你可以在任意计算机上导出,然后将 .onnx 文件复制到容器中;也可以在 AMD Docker 镜像中运行 Ultralytics 时设置 YOLO_AUTOINSTALL=false。
步骤 3:使用 Vitis AI 量化和编译#
以下工作流使用 AMD 的 Docker 镜像,并运行在 x86-64 Linux 主机上。此步骤不需要开发板。请选择与你的器件对应的选项卡:
- 启动面向 Versal AI Edge Gen 2 的 AMD Vitis AI 6.3 Docker 镜像。请参阅系统要求。
- 使用 AMD Quark 和
VINT8配置,将 ONNX 模型量化为 INT8。AMD 的最低配置还要求Int32Bias=False、enable_npu_cnn=True、DedicatedQDQPair=True和QuantizeAllOpTypes=True。Quark 通过你编写的数据读取器读取校准数据,因此请对数据应用与推理相同的预处理:将图像 letterbox 调整为导出尺寸、使用 RGB 通道顺序、缩放到 0–1,并采用 NCHW 布局;校准图像应从你的数据集中选取具有代表性的样本。 - 不要将后处理子图纳入量化。AMD 的 YOLOv8m 教程提醒,量化后处理子图会导致漏检。在该 YOLOv8m 示例中,编译器随后会在 NPU 上以 BF16 运行尾部;不受支持的尾部算子(例如 YOLO26 的 top-k 选择)仍会在 CPU 上运行。
- 编译前先选择板卡运行时。标准编译适用于 ONNX Runtime;ONNX Runtime 会在 CPU 上运行 NPU 不支持的算子(例如 YOLO26 的 top-k 选择)。标准编译也适用于 VART-ML,但前提是所有算子都在 NPU 上运行。若要通过 VART-ML 运行包含 CPU 算子的模型,请将 AMD 的 CPU 分区 pass添加到
vitisai_config.json。这些产物无法通过 ONNX Runtime 运行。 - 编译时,创建 ONNX Runtime 会话,并传入
VitisAIExecutionProvider和指定目标设备的vitisai_config.json。编译会在缓存目录中写入一个.rai文件。请参阅编译模型。
若要跳过量化,可直接编译 FP32 ONNX 模型,编译器会将其转换为 BF16。编译需要 AMD AI Engine 编译器许可证;请参阅 AMD 的许可页面。
第 4 步:在板卡上运行并验证#
先准备好板卡。板卡必须运行包含你所编译加速器配置的硬件设计和 Linux 镜像,还必须运行匹配的 Vitis AI 运行时。请参阅 AMD 的设置指南:Zynq UltraScale+ 和 Kria DPU 目标、Versal AI Edge (VEK280)和Versal AI Edge Gen 2 (VEK385)。
然后复制运行时所需的产物:
| 工作流 | 要复制到板卡的产物 | 开发板运行时 |
|---|---|---|
| DPU(Zynq UltraScale+、Kria) | 编译后的 .xmodel | VART;用于 CPU 子图的 Graph Runner |
| NPU(Versal AI Edge,VEK280) | 快照目录 | VART-ML |
| NPU(Versal AI Edge Gen 2),ORT | 用于编译的 FP32 或量化 ONNX 模型、vitisai_config.json 和编译后的缓存目录 | 搭配 Vitis AI EP 的 ONNX Runtime |
| NPU(Versal AI Edge Gen 2),VART-ML | .rai 文件(若有算子在 CPU 上运行,则包含 CPU 分区 pass),以及 VART-ML runner 配置 | VART-ML |
对于 NPU 工作流,导出的 ONNX 图已经解码边界框并应用类别分数 sigmoid,因此主机只需解析输出:
- 未设置
nms:检测模型会输出一个包含xywh个边界框和各类别分数的(1, 4 + nc, anchors)张量。为每个锚点选择得分最高的类别,将边界框转换为角点格式,按置信度筛选并运行 NMS;Ultralytics 的non_max_suppression函数会完成所有这些步骤。 nms=False(YOLO26):模型会输出一个包含[x1, y1, x2, y2, score, class]行的(1, max_det, 6)张量,只需应用置信度阈值。
在这两种情况下,都要将边界框从添加了填充的输入图像缩放回原始图像。只有在解码步骤之前被截断的计算图才需要在主机上解码边界框。在 DPU 上,VART 缓冲区存储定点 INT8 值:查询每个张量的形状和 fix_point scale,在应用上述步骤前对输入量化并对输出反量化。Graph Runner 会返回完整计算图的输出,而仅运行 DPU 的 runner 会返回 DPU 子图的中间输出,剩余计算必须由你的代码完成。上述布局是 ONNX(CPU 视图)的布局:VART-ML 默认使用硬件张量视图,其形状、数据类型和内存布局可能不同,因此请将 runner 的输入和输出张量类型配置为 CPU 视图,或自行转换硬件格式(请参阅 AMD 的 VART-ML 架构概览)。
使用你自己的验证集和相同的性能指标(例如 mAP),将设备上的精度与第 1 步的 FP32 基线进行比较。AMD 发布的 VEK385 上 YOLOv8m 结果展示了 INT8 部署对精度的影响:
| YOLOv8m 配置 | 硬件 | mAP50-95(COCO) |
|---|---|---|
| FP32 ONNX | 主机 CPU | 49.95 |
| BF16 | VEK385 NPU | 50.29 |
| VINT8 量化,FP32 尾部 | 主机 CPU | 48.75 |
| VINT8,BF16 尾部 | VEK385 NPU | 48.38 |
来源:AMD 的 Versal AI Edge Gen 2 YOLOv8m 教程;该教程还报告了 dp_size=1 下 VART 运行 100 次的平均推理时间为 10.69 ms。
在 AMD Xilinx 商业产品中交付 Ultralytics YOLO,必须遵守 AGPL-3.0 许可证,或获取 Ultralytics 企业许可证。
实际应用#
在需要以低功耗、实时地在传感器附近运行视觉 AI 的场景中,AMD Xilinx 设备十分常见:
- 工业和建筑安全:检测重型设备周围的人员和机器,并使用目标检测和目标计数监控作业区域。
- 汽车和非公路车辆视觉:在符合汽车级标准的部件上运行基于摄像头的感知,支持自动驾驶汽车和驾驶辅助。
- 智能摄像头和视频分析:在一颗芯片上结合视频采集、编码和 YOLO 推理,用于安防系统和视频分析。
- 机器视觉和质量检测:将基于 FPGA 的高速图像采集与 YOLO 的实例分割或分类结合,用于生产线上的缺陷检测。
- 机器人和无人机:使用 Kria KR260 或 Versal 模块进行姿态估计、有向目标检测和导航,实现确定性延迟。
总结#
AMD Xilinx 设备通过两代加速器运行 YOLO 模型。Zynq UltraScale+ 和 Kria 上的 DPU 使用冻结的 Vitis AI 3.5 工作流,并生成 .xmodel 文件。DPU 需要 Hard-Swish 等 DPU 原生激活函数,并会在 CPU 上运行 attention。Versal AI Edge 和 Versal AI Edge Gen 2 上的 NPU 使用当前版本的 Vitis AI。Gen 2 NPU 支持 SiLU 和 attention 算子;AMD 的 YOLOv8m 示例在 VEK385 上几乎完全由 NPU 运行,而较早的 VEK280 NPU 的算子支持情况取决于 Vitis AI 版本和精度。
AMD Xilinx 设备的原生 Ultralytics 导出功能即将推出。在此之前,请使用 Ultralytics 训练;对于 Versal NPU 目标,导出为 ONNX,对于 DPU 目标则保留 PyTorch 检查点,然后按照上述说明使用 Vitis AI 编译。有关其他部署目标,请参阅模型部署选项指南、部署最佳实践,以及 Hailo、Rockchip RKNN和 Axelera等加速器集成方案。
常见问题#
是。AMD 于 2022 年 2 月完成对 Xilinx 的收购,Xilinx 产品如今以 AMD 自适应 SoC 和 FPGA 的形式销售:AMD Zynq、AMD Kria、AMD Versal 和 AMD Vitis。工程师仍广泛使用 Xilinx 这个名称,器件编号也保留
XC前缀。还不能。AMD Xilinx 设备的原生 Ultralytics 导出功能即将推出。目前,对于 Versal NPU 目标,可使用
model.export(format="onnx")导出为 ONNX;对于 Zynq UltraScale+ 和 Kria DPU 目标,可使用vai_q_pytorch量化训练好的 PyTorch 检查点,然后按照立即在 AMD Xilinx 上部署 YOLO26中的说明使用 AMD Vitis AI 工具进行编译。DPU(深度学习处理单元)是 AMD 较早推出的 INT8 加速器,构建在 Zynq UltraScale+ 和 Kria 设备的可编程逻辑中,使用 Vitis AI 3.5 编译,并生成
.xmodel文件。NPU 是当前 Vitis AI 版本中的替代方案。在 Versal AI Edge 设备上,NPU 将硬化的 AI Engines 与可编程逻辑相结合,支持 INT8、BF16 和混合精度,并支持更多算子,包括 SiLU;在 Versal AI Edge Gen 2 上还支持 attention。.xmodel是 AMD DPU 工具链使用的序列化 XIR 计算图。量化器会写入量化后的.xmodel,而vai_c_xir编译器会将其转换为编译后的.xmodel,其中包含 DPU 指令流、量化后的 INT8 权重,以及必须在 CPU 上运行的所有子图。编译后的文件针对某一特定 DPU 配置,具体配置由arch.json指纹描述;该文件可通过 Vitis AI Runtime (VART) 在板卡上运行,如果其中包含 CPU 子图,也可通过 Graph Runner运行。不支持。DPU 只会加速 ReLU、ReLU6、LeakyReLU、Hard-Swish 和 Hard-Sigmoid 激活函数;Sigmoid、Softmax 以及两个激活函数之间的 MatMul 则会在 CPU 上运行。在模型 YAML 中使用
activation: nn.Hardswish()训练 YOLO,以便让卷积层在 DPU 上运行;attention 选项请参阅在 DPU 上处理 Attention 模块。Versal AI Edge Gen 2 NPU 原生支持 SiLU、Softmax 和 MatMul。KV260 使用搭载 DPU 的 Zynq UltraScale+ MPSoC,因此请按照 DPU 工作流操作。训练使用 Hard-Swish 的 YOLO26 模型,在 Vitis AI 3.5 Docker 镜像中使用
vai_q_pytorch对其进行量化,再使用vai_c_xir和 KV260 的arch.json编译模型,然后在板卡上通过 VART 运行生成的.xmodel;如果其中包含 CPU 子图,则使用 Graph Runner 运行。不需要。量化和编译可在 x86-64 Linux 主机上的 AMD Vitis AI Docker 镜像中运行。你只需使用板卡运行编译后的模型,并测量设备上的延迟和精度。