3. Vitis AI工具链与模型部署工作流
在 Kria 平台上把训练好的浮点模型真正跑起来,需要经过一条明确的工具链转换链路。Vitis AI 把这条链路拆成若干职责单一的组件:Model Zoo 提供经过验证的参考模型与预训练权重,VAI_Q 负责量化,VAI_C 负责编译,VART 负责运行时执行,Vitis AI Library 则提供面向应用的高层封装。理解每个组件“吃什么、吐什么”,是排查部署问题的前提。
一、各组件职责与输入输出
Vitis AI Model Zoo 是起点。它按任务分类(图像分类、目标检测、语义分割、姿态估计等)提供模型,每个模型通常包含浮点权重、量化权重、编译后的 DPU 文件以及精度评估脚本。以分类网络 ResNet-50 为例,Model Zoo 中会给出 float 目录下的 .pb 或 .h5 浮点模型,以及 quantized 目录下的量化模型。使用 Model Zoo 的价值在于:这些模型已在 DPU 上验证过精度与性能,可作为自定义模型的对照基准。
VAI_Q(vai_q_tensorflow / vai_q_pytorch)是量化器。它把 32 位浮点权重和激活值转换为 8 位定点(INT8),同时生成量化校准信息。量化不是简单截断,而是通过校准集统计激活值分布,确定每层的缩放因子(scale)和零点(zero point)。典型调用形式如下:
vai_q_tensorflow quantize \
--input_frozen_graph float/resnet_v1_50.pb \
--input_fn input_fn.calib_input \
--output_dir quantized/ \
--input_nodes input \
--output_nodes resnet_v1_50/predictions/Softmax \
--input_shapes ?,224,224,3 \
--calib_iter 100
其中 --calib_iter 100 表示用 100 个 batch 做校准。校准集应来自真实应用场景,若只用随机噪声,量化后精度会明显下降。量化完成后,quantized/ 目录下会得到量化模型和量化信息文件,这是 VAI_C 的输入。
VAI_C(vai_c_tensorflow / vai_c_xir)是编译器。它把量化模型映射为 DPU 的指令流,输出 .xmodel 文件。编译时需要指定目标 DPU 架构,例如 Kria KV260 上的 DPUCZDX8G,配置参数包括 --arch 和 --net_name:
vai_c_tensorflow \
--frozen_pb quantized/quantize_eval_model.pb \
--arch /opt/vitis_ai/compiler/arch/DPUCZDX8G/KV260/arch.json \
--output_dir compiled/ \
--net_name resnet_v1_50
编译成功后生成 resnet_v1_50.xmodel。这个文件包含 DPU 可执行的子图指令,以及回落到 CPU 执行的算子描述。若某层不被 DPU 支持,编译器会将其标记为 CPU 算子,此时需要关注是否造成频繁的 DPU/CPU 切换。
VART(Vitis AI Runtime)是运行时库。它加载 .xmodel,管理 DPU 任务队列,提供 C++ 和 Python 接口。VART 的核心对象是 Runner,通过 execute_async 提交推理请求。VART 不关心模型来自哪个框架,只认 .xmodel 格式,因此它是部署链路的“执行底座”。
Vitis AI Library 建立在 VART 之上,封装了常见任务的完整流水线。例如 vitis_ai_library 中的 YOLOv3 类,内部完成预处理、VART 推理、后处理(NMS、解码)全过程,应用层只需传入图像并读取结果。它适合快速搭建演示,但若需要自定义前后处理,仍要回到 VART 层。
二、完整转换链路中的关键判断
从浮点模型到 DPU 可执行文件,链路本身是线性的,但每一步都有需要判断的节点。第一步是模型选择:如果使用 Model Zoo 中的模型,可以直接跳到量化;如果是自定义模型,需要先确认算子是否被 DPU 支持。Vitis AI 提供算子支持列表,不支持的算子会在编译阶段回落到 CPU,若回落过多,推理速度可能不如纯 CPU 实现。
第二步是量化校准。校准集的数量和代表性直接影响精度。以 ResNet-50 为例,若校准集只有 10 张图,量化后 Top-1 精度可能下降 2%~3%;若使用 1000 张覆盖多类别的图像,精度损失通常可控制在 1% 以内。校准完成后,VAI_Q 会输出量化评估模型,可以用 vai_q_tensorflow evaluate 在验证集上对比浮点与量化精度。
第三步是编译配置。arch.json 必须与目标 DPU 架构一致。KV260 的 DPUCZDX8G 配置文件中定义了 DPU 的并行度、RAM 深度等参数。若误用 ZCU104 的 arch.json,编译可能通过,但运行时会出现指令不匹配。编译日志中会列出每个算子的映射结果,重点关注 CPU 标记的算子。
第四步是运行时验证。VART 加载 .xmodel 后,可以用 xir 工具或 Python API 做单张推理,对比量化模型在 CPU 上的输出与 DPU 上的输出。若两者差异在允许范围内(通常 INT8 量化误差在 1e-2 量级),说明编译正确。Vitis AI Library 则进一步封装了多线程和批处理,适合集成到实际应用中。
三、组件协作关系与常见误区
VAI_Q 和 VAI_C 容易混淆:VAI_Q 处理的是数值精度,输出仍是框架可读的模型格式;VAI_C 处理的是硬件映射,输出是 DPU 专用格式。VART 不参与模型转换,它只负责执行。Vitis AI Library 不是必须的,但能显著减少应用层代码量。
另一个常见误区是认为量化一定损失精度。实际上,对于卷积层占主导的视觉模型,INT8 量化在多数情况下精度损失很小,因为卷积核权重分布集中,校准可以较好地拟合。真正容易出问题的是包含大量全连接层或注意力机制的模型,这些层的激活值分布更分散,量化误差更大。
最后,整条链路的产物需要版本对齐:VAI_Q 的版本、VAI_C 的版本、VART 的版本以及 DPU 固件版本必须兼容。Kria 的 Vitis AI 通常以 PetaLinux 镜像形式提供,建议使用官方发布的版本组合,避免自行混搭。
| 组件 | 输入 | 输出 | 核心职责 |
|---|---|---|---|
| Model Zoo | — | 浮点模型、预训练权重 | 提供参考模型与基准 |
| VAI_Q | 浮点模型 + 校准集 | INT8 量化模型 | 数值精度转换 |
| VAI_C | 量化模型 + arch.json | .xmodel | DPU 指令映射 |
| VART | .xmodel | 推理结果 | 运行时执行与队列管理 |
| Vitis AI Library | 图像 / 视频流 | 结构化结果 | 任务级流水线封装 |
掌握这条链路后,部署工作就变成可定位、可验证的工程流程:模型不对查 Model Zoo 或算子支持,精度不对查量化校准,运行报错查 arch.json 和 VART 版本。每个组件只做一件事,出问题时就能快速缩小范围。