Vitis AI 集成

更多 TVM 中文文档可访问 →Apache TVM 是一个端到端的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。IApache TVM 中文站 **Vitis AI **是用在 Xilinx 平台(包括边缘设备和 Alveo 卡)上进行硬件加速 AI 推理的 Xilinx 开发堆栈。它由优化的 IP、工具、库、模型和示例设计组成。在设计时兼顾高效率和易用性,充分发挥了 Xilinx FPGA 和 ACAP 上 AI 加速的潜力。

TVM 中当前的 Vitis AI 流支持使用** Zynq Ultrascale+ MPSoc, Alveo Versal **平台在边缘和云端加速神经网络模型推理。支持的边缘和云深度学习处理器单元(DPU)的标识符是:

Target Board DPU ID TVM Target ID
ZCU104 DPUCZDX8G DPUCZDX8G-zcu104
ZCU102 DPUCZDX8G DPUCZDX8G-kv260
Kria KV260 DPUCZDX8G DPUCZDX8G-kv260
VCK190 DPUCVDX8G DPUCVDX8G
VCK5000 DPUCVDX8H DPUCVDX8H
U200 DPUCADF8H DPUCADF8H
U250 DPUCADF8H DPUCADF8H
U50 DPUCAHX8H / DPUCAHX8L DPUCAHX8H-u50 / DPUCAHX8L
U280 DPUCAHX8H / DPUCAHX8L DPUCAHX8H-u280 / DPUCAHX8L

有关 DPU 标识符的更多信息,参见下表:

DPU Application HW Platform Quantization Method Quantization Bitwidth Design Target
Deep LearningProcessing Unit C: CNNR: RNN AD: Alveo DDRAH: Alveo HBMVD: Versal DDR with AIE & PLZD: Zynq DDR X: DECENTI: Integer thresholdF: Float thresholdR: RNN 4: 4-bit8: 8-bit16: 16-bitM: Mixed Precision G: General purposeH: High throughputL: Low latencyC: Cost optimized

此教程介绍有关如何在不同平台(Zynq、Alveo、Versal)上使用 Vitis AI 设置 TVM 以及如何开始 编译模型 并在不同平台上执行:推理。

系统要求V

Vitis AI 系统要求页面 列出了运行 Docker 容器以及在 Alveo 卡上执行的系统要求。对于边缘设备(例如 Zynq),部署模型需要使用带有 Vitis AI 流程的 TVM 编译模型的主机,以及用于运行编译模型的边缘设备。主机系统要求与上面链接中指定的相同。

设置说明

本节介绍如何用 Vitis AI 流为云和边缘设置 TVM。支持 Vitis AI 的 TVM 是通过 Docker 容器提供的。提供的脚本和 Dockerfile 将 TVM 和 Vitis AI 编译为单个镜像。

1.克隆 TVM 仓库

bash 复制代码
  git clone --recursive https://github.com/apache/tvm.git
   cd tvm

2.构建并启动 TVM - Vitis AI Docker 容器。

bash 复制代码
   ./docker/build.sh demo_vitis_ai bash
   ./docker/bash.sh tvm.demo_vitis_ai

   # Setup inside container
   conda activate vitis-ai-tensorflow

3.用 Vitis AI(在 TVM 目录内)在容器内构建 TVM

bash 复制代码
   mkdir build
   cp cmake/config.cmake build
   cd build
   echo set(USE_LLVM ON) >> config.cmake
   echo set(USE_VITIS_AI ON) >> config.cmake
   cmake ..
   make -j$(nproc)

4.安装 TVM

bash 复制代码
   cd ../python
   pip3 install -e . --user

在这个 Docker 容器中可以为云和边缘目标编译模型。要在 docker 容器内的云 Alveo 或 Versal VCK5000 卡上运行,按照 Alveo 或者 Versal VCK5000 设置说明进行操作。分别参照 Zynq 和 Versal VCK190,为推理过程设置 Zynq 或 Versal VCK190 评估单板。

Alveo 设置

查看 Alveo 设置 获取设置信息。

设置后,通过以下方式在 Docker 容器内选择正确的 DPU:

bash 复制代码
cd /workspace
git clone --branch v1.4 --single-branch --recursive https://github.com/Xilinx/Vitis-AI.git
cd Vitis-AI/setup/alveo
source setup.sh [DPU-IDENTIFIER]

可在此页面顶部的 DPU Targets 表的第二列中找到此 DPU 标识符。

Versal VCK5000 设置

查看 VCK5000 Setup 获取设置信息。

设置后,可以通过以下方式在 Docker 容器内选择正确的 DPU:

bash 复制代码
cd /workspace
git clone --branch v1.4 --single-branch --recursive https://github.com/Xilinx/Vitis-AI.git
cd Vitis-AI/setup/vck5000
source setup.sh

Zynq 设置

除了构建 TVM - Vitis AI docker 之外,对于 Zynq 目标(DPUCZDX8G),编译阶段在主机上的 docker 内运行,不需要任何特定设置。执行模型时,首先要设置 Zynq 板,更多信息如下。

1.下载 Petalinux 镜像:

  • ZCU104
  • ZCU102
  • Kria KV260 2.使用 Etcher 软件将镜像文件刻录到 SD 卡上。

3.将带有图像的 SD 卡插入目标单板。

4.插入电源并使用串行端口在系统上启动该单板。

5.用串口设置单板的 IP 信息。有关步骤 1 至 5 的更多信息,参阅 设置评估单板。

6.在单板上创建 4GB 的交换空间

bash 复制代码
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile swap swap defaults 0 0" >> /etc/fstab

7.安装 hdf5 依赖(需要 30 分钟到 1 小时)

bash 复制代码
cd /tmp && \
  wget https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.10/hdf5-1.10.7/src/hdf5-1.10.7.tar.gz && \
  tar -zxvf hdf5-1.10.7.tar.gz && \
  cd hdf5-1.10.7 && \
  ./configure --prefix=/usr && \
  make -j$(nproc) && \
  make install && \
  cd /tmp && rm -rf hdf5-1.10.7*

8.安装 Python 依赖

ini 复制代码
pip3 install Cython==0.29.23 h5py==2.10.0 pillow

9.安装 PyXIR

bash 复制代码
git clone --recursive --branch rel-v0.3.1 --single-branch https://github.com/Xilinx/pyxir.git
cd pyxir
sudo python3 setup.py install --use_vart_edge_dpu

10.用 Vitis AI 构建和安装 TVM

bash 复制代码
git clone --recursive https://github.com/apache/tvm
cd tvm
mkdir build
cp cmake/config.cmake build
cd build
echo set(USE_LLVM OFF) >> config.cmake
echo set(USE_VITIS_AI ON) >> config.cmake
cmake ..
make tvm_runtime -j$(nproc)
cd ../python
pip3 install --no-deps  -e .

11.在 Python shell 中检查设置是否成功:

swift 复制代码
python3 -c 'import pyxir; import tvm'

备注 可能会看到有关未找到 "cpu-tf" runtime 的警告,可以忽略。

Versal VCK190 设置

参考 Zynq 设置 设置 Versal VCK190,但在步骤 1 中参考 VCK190 镜像。其他步骤相同。

编译模型

带有 Vitis AI 流的 TVM 包含编译和推理两个阶段。在编译期间,用户可以为当前支持的云或边缘目标设备选择要编译的模型。编译模型生成的文件可用于在 推理 阶段在指定的目标设备上运行模型。目前,采用 Vitis AI 流程的 TVM 支持选定数量的 Xilinx 数据中心和边缘设备。

本节介绍在 TVM 中用 Vitis AI 编译模型的一般流程。

导入

确保导入 PyXIR 和 DPU target(为 DPUCADF8H import pyxir.contrib.target.DPUCADF8H ):

javascript 复制代码
import pyxir
import pyxir.contrib.target.DPUCADF8H

import tvm
import tvm.relay as relay
from tvm.contrib.target import vitis_ai
from tvm.contrib import utils, graph_executor
from tvm.relay.op.contrib.vitis_ai import partition_for_vitis_ai

声明 Target

arduino 复制代码
tvm_target = 'llvm'
dpu_target = 'DPUCADF8H' # options: 'DPUCADF8H', 'DPUCAHX8H-u50', 'DPUCAHX8H-u280', 'DPUCAHX8L', 'DPUCVDX8H', 'DPUCZDX8G-zcu104', 'DPUCZDX8G-zcu102', 'DPUCZDX8G-kv260'

带有 Vitis AI 流的 TVM 目前支持本页顶部表格中列出的 DPU targets。一旦定义了恰当的 target,就会调用 TVM 编译器来为指定的 target 构建计算图。

导入模型

导入 MXNet 模型的示例代码:

ini 复制代码
mod, params = relay.frontend.from_mxnet(block, input_shape)

对模型分区

导入模型后,用 Relay API 为 DPU target 注释 Relay 表达式,并对计算图进行分区。

ini 复制代码
mod = partition_for_vitis_ai(mod, params, dpu=dpu_target)

构建模型

将分区模型传给 TVM 编译器,然后生成 TVM Runtime 的 runtime 库。

ini 复制代码
export_rt_mod_file = os.path.join(os.getcwd(), 'vitis_ai.rtmod')
build_options = {
    'dpu': dpu_target,
    'export_runtime_module': export_rt_mod_file
}
with tvm.transform.PassContext(opt_level=3, config={'relay.ext.vitis_ai.options': build_options}):
    lib = relay.build(mod, tvm_target, params=params)

量化模型

为了用 Vitis AI DPU 加速器来加速神经网络模型的推理,通常要对模型预先量化。在 TVM - Vitis AI 流中,利用动态量化来替代此预处理步骤。在这个流中,可用典型的推理执行调用(module.run)使用提供的前 N 个输入动态量化模型(参见更多信息如下),而不需要预先量化模型。这将设置和校准 Vitis-AI DPU,为后面所有输入加速推理。

注意:边缘流与推理中解释的流略有不同,边缘流在前 N 个输入后模型被量化和编译,但推理不会加速,并且它可以移动到边缘设备进行部署。查看下面的 在 Zynq 上运行 部分了解更多信息。

ini 复制代码
module = graph_executor.GraphModule(lib["default"](tvm.cpu()))

# 前 N 个(默认 = 128)输入用于量化校准,并在 CPU 上执行
# 可以通过设置 "PX_QUANT_SIZE" 来更改此配置(例如,导出 PX_QUANT_SIZE=64)
for i in range(128):
   module.set_input(input_name, inputs[i])
   module.run()

用于量化的图像数量默认设置为 128,可以使用 PX_QUANT_SIZE 环境变量更改动态量化的图像数量。例如,在调用编译脚本之前在终端中执行如下命令,将量化校准数据集减少到八幅图像。

ini 复制代码
export PX_QUANT_SIZE=8

最后将 TVM 编译器的编译输出存储在磁盘上,方便在目标设备上运行模型。云 DPU(Alveo 和 VCK5000)的情况如下:

ini 复制代码
lib_path = "deploy_lib.so"
lib.export_library(lib_path)

对于边缘 target(Zynq 和 VCK190),必须为 aarch64 重建。因此首先必须正常导出模块,并同时序列化 Vitis AI runtime 模块(vitis_ai.rtmod)。之后再次加载此 runtime 模块,为 aarch64 重建和导出。

ini 复制代码
temp = utils.tempdir()
lib.export_library(temp.relpath("tvm_lib.so"))

# 为 aarch64 target 构建和导出库
tvm_target = tvm.target.arm_cpu('ultra96')
lib_kwargs = {
   'fcompile': contrib.cc.create_shared,
   'cc': "/usr/aarch64-linux-gnu/bin/ld"
}

build_options = {
    'load_runtime_module': export_rt_mod_file
}
with tvm.transform.PassContext(opt_level=3, config={'relay.ext.vitis_ai.options': build_options}):
     lib_edge = relay.build(mod, tvm_target, params=params)

lib_edge.export_library('deploy_lib_edge.so', **lib_kwargs)

使用 TVM 和 Vitis AI 编译模型的教程到此结束,有关如何运行已编译的模型,参阅下一节。

推理

带有 Vitis AI 流的 TVM 包含编译和推理两个阶段,在编译期间,用户可以选择为当前支持的任何目标设备编译模型。编译模型后生成的文件可用于在推理阶段在目标设备上运行模型。

查看 在 Alveo 和 VCK5000 上运行 以及 **在 Zynq 和 VCK190 上运行 **部分,分别在云加速卡和边缘板上进行推理。

在 Alveo 和 VCK5000 上运行

按照编译模型部分中的步骤,可以在 Docker 内的新输入上执行如下命令以加速推理:

arduino 复制代码
module.set_input(input_name, inputs[i])
module.run()

或者加载导出的 runtime 模块(在 编译模型 中导出的 deploy_lib.so):

ini 复制代码
import pyxir
import tvm
from tvm.contrib import graph_executor

dev = tvm.cpu()

# input_name = ...
# input_data = ...

# 将模块加载到内存
lib = tvm.runtime.load_module("deploy_lib.so")

module = graph_executor.GraphModule(lib["default"](dev))
module.set_input(input_name, input_data)
module.run()

在 Zynq 和 VCK190 上运行

开始前按照 Zynq 或 Versal VCK190 设置说明进行设置。

在单板上运行模型之前,需要为目标评估单板编译模型,并将编译后的模型传输到板上。如何编译模型,参阅 编译模型 部分。

之后将编译好的模型(deploy_lib_edge.so)传输到评估单板,然后可以在板上使用典型的「load_module」和「module.run」API 来执行。确保以 root 身份运行脚本(在终端中执行 su 登录到 root)。

备注 不要在运行脚本(import pyxir.contrib.target.DPUCZDX8G)中导入 PyXIR DPU targets。

ini 复制代码
import pyxir
import tvm
from tvm.contrib import graph_executor

dev = tvm.cpu()

# input_name = ...
# input_data = ...

# 将模块加载到内存
lib = tvm.runtime.load_module("deploy_lib_edge.so")

module = graph_executor.GraphModule(lib["default"](dev))
module.set_input(input_name, input_data)
module.run()
相关推荐
中关村科金2 分钟前
中关村科金智能客服机器人如何解决客户个性化需求与标准化服务之间的矛盾?
人工智能·机器人·在线客服·智能客服机器人·中关村科金
逸_5 分钟前
Product Hunt 今日热榜 | 2024-12-25
人工智能
Luke Ewin11 分钟前
基于3D-Speaker进行区分说话人项目搭建过程报错记录 | 通话录音说话人区分以及语音识别 | 声纹识别以及语音识别 | pyannote-audio
人工智能·语音识别·声纹识别·通话录音区分说话人
DashVector26 分钟前
如何通过HTTP API检索Doc
数据库·人工智能·http·阿里云·数据库开发·向量检索
说私域29 分钟前
无人零售及开源 AI 智能名片 S2B2C 商城小程序的深度剖析
人工智能·小程序·零售
Calvin88082837 分钟前
Android Studio 的革命性更新:Project Quartz 和 Gemini,开启 AI 开发新时代!
android·人工智能·android studio
Jamence1 小时前
【深度学习数学知识】-贝叶斯公式
人工智能·深度学习·概率论
feifeikon1 小时前
机器学习DAY4续:梯度提升与 XGBoost (完)
人工智能·深度学习·机器学习
凡人的AI工具箱2 小时前
每天40分玩转Django:实操多语言博客
人工智能·后端·python·django·sqlite
Jackilina_Stone2 小时前
【自动驾驶】3 激光雷达③
人工智能·自动驾驶