ONNX 运行时
Vitis AI Execution Provider (Vitis AI EP) 提供了含 AMD DPU 的硬件加速 AI 推断。它支持用户在目标开发板上直接运行已量化的 ONNX 模型。当前,ONNX Runtime 内的 Vitis AI EP 支持在嵌入式器件上进行神经网络模型推断加速,这类器件包括 Zynq UltraScale+ MPSoC、Versal、Versal AI Edge 和 Kria 卡。
Vitis AI ONNXRuntime Engine (VOE) 充当的是 Vitis AI EP 的实现库。
功能特性
- 支持 ONNX Opset v18、ONNX Runtime 1.16.0 和 ONNX v1.13
- C++ 和 Python API(受 Python v3 支持)
- 除 Vitis AI EP 外,还支持结合其他执行提供程序(如 ACL EP)利用 AMD DPU 来加速推断
- 支持在 ARM64 Cortex®-A72 核上执行计算,受支持的目标为 VAI3.5 中的 VEK280
益处
- 通用性:您可在 AMD DPU 上部署子计算图,同时使用 Arm® NN 和 Arm® ACL 之类的其他执行提供程序来处理其他运算符。这种灵活性支持在目标板上部署目标板不予直接支持的模型。
- 改善性能:您可通用 AMD DPU 之类的专用执行提供程序来处理特定运算,并使用其他提供程序来处理其余运算符,从而为自己的模型实现最优化的性能。
- 扩展模型支持:增强 ONNX Runtime 即可支持部署含有 DPU 原生不支持的运算符的模型。您可通过整合其他执行提供程序来执行多种多样的模型,包括来自 ONNX model zoo 的模型。
运行时选项
Vitis AI ONNX Runtime 集成了编译器,用于将模型计算图和权重编译为微码可执行文件。该可执行文件部署在目标加速器上。
在启动 ONNX Runtime 会话期间进行模型编译,此编译进程必须在成功完成首次推断之前完成。编译时间可能不尽相同,但可能需要几分钟时间。完成模型编译后,即可缓存模型可执行文件。对于后续推断运行,您可使用缓存的可执行模型。
您可设置多个运行时变量用于配置推断会话,如下表所示。config_file
变量并非可选,必须将其设为指向配置文件所在位置。cacheDir
变量和 cacheKey
变量均为可选。
运行时变量 | 默认值 | 详细信息 |
---|---|---|
config_file |
"" | (必需)表示配置文件路径,配置文件 vaip_config.json 包含在 Vitis_ai_2023.1-r3.5.0.tar.gz 内 |
cacheDir |
/tmp/{user}/vaip/.cache/ |
(可选)表示高速缓存目录 |
cacheKey |
{onnx_model_md5} |
(可选)表示高速缓存密钥,用于区分不同模型。 |
最终高速缓存目录为 {cacheDir}/{cacheKey}。此外,还可设置环境变量以自定义 Vitis AI EP。
环境变量 |
默认值 |
详细信息 |
---|---|---|
XLNX_ENABLE_CACHE |
1 |
对应是否使用高速缓存,如果设为 0,则将忽略缓存的可执行文件,并且将重新编译模型。 |
XLNX_CACHE_DIR |
/tmp/$USER/vaip/.cache/{onnx_model_md5} |
(可选)表示配置高速缓存路径 |
Vitis AI 3.5 提供了十多个基于 ONNX Runtime 的部署示例。您可在 https://github.com/Xilinx/Vitis-AI/tree/v3.5/examples/vai_library/samples_onnx 中找到这些示例。以下步骤描述了如何使用 VOE 来部署 ONNX 模型:
- 准备 ONNX 格式的量化模型。使用 Vitis AI 量化器来量化模型,并输出 ONNX 格式的量化模型。
- 下载 ONNX Runtime 包 vitis_ai_2023.1-r3.5.0.tar.gz 并将其安装在目标开发板上。
tar -xzvf vitis_ai_2023.1-r3.5.0.tar.gz -C /
然后,下载 voe-0.1.0-py3-none-any.whl 和 onnxruntime_vitisai-1.16.0-py3-none-any.whl。确保器件已联机,并在线安装这两个包。pip3 install voe*.whl pip3 install onnxruntime_vitisai*.whl
-
Vitis AI 3.5 支持 ONNX Runtime C++ API 和
Python
API。如需了解 ONNX Runtime API 的详细信息,请访问 https://onnxruntime.ai/docs/api/。以下提供了基于 C++ API 的 ONNX 模型部署代码片段:C++ 示例
// ... #include <experimental_onnxruntime_cxx_api.h> // include user header files // ... auto onnx_model_path = "resnet50_pt.onnx" Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "resnet50_pt"); auto session_options = Ort::SessionOptions(); auto options = std::unorderd_map<std::string,std::string>({}); options["config_file"] = "/etc/vaip_config.json"; // optional, eg: cache path : /tmp/my_cache/abcdefg // Replace abcdefg with your model name, eg. onnx_model_md5 options["cacheDir"] = "/tmp/my_cache"; options["cacheKey"] = "abcdefg"; // Replace abcdefg with your model name, eg. onnx_model_md5 // Create an inference session using the Vitis AI execution provider session_options.AppendExecutionProvider("VitisAI", options); auto session = Ort::Experimental::Session(env, model_name, session_options); auto input_shapes = session.GetInputShapes(); // preprocess input data // ... // Create input tensors and populate input data std::vector<Ort::Value> input_tensors; input_tensors.push_back(Ort::Experimental::Value::CreateTensor<float>( input_data.data(), input_data.size(), input_shapes[0])); auto output_tensors = session.Run(session.GetInputNames(), input_tensors, session.GetOutputNames()); // postprocess output data // ...
要利用 Python API,请使用以下示例作为参考:
import onnxruntime # Add other imports # ... # Load inputs and do preprocessing # ... # Create an inference session using the Vitis-AI execution provider session = onnxruntime.InferenceSession( '[model_file].onnx', providers=["VitisAIExecutionProvider"], provider_options=[{"config_file":"/etc/vaip_config.json"}]) input_shape = session.get_inputs()[0].shape input_name = session.get_inputs()[0].name # Load inputs and do preprocessing by input_shape input_data = [...] result = session.run([], {input_name: input_data})
- 创建 build.sh 文件,或者从 Vitis AI Library ONNX 示例复制该文件并对其进行修改。然后,构建该程序:
result=0 && pkg-config --list-all | grep opencv4 && result=1 if [ $result -eq 1 ]; then OPENCV_FLAGS=$(pkg-config --cflags --libs-only-L opencv4) else OPENCV_FLAGS=$(pkg-config --cflags --libs-only-L opencv) fi lib_x=" -lglog -lunilog -lvitis_ai_library-xnnpp -lvitis_ai_library-model_config -lprotobuf -lxrt_core -lvart-xrt-device-handle -lvaip-core -lxcompiler-core -labsl_city -labsl_low_level_hash -lvart-dpu-controller -lxir -lvart-util -ltarget-factory -ljson-c" lib_onnx=" -lonnxruntime" lib_opencv=" -lopencv_videoio -lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc -lopencv_core " if [[ "$CXX" == *"sysroot"* ]];then inc_x="-I=/usr/include/onnxruntime -I=/install/Release/include/onnxruntime -I=/install/Release/include -I=/usr/include/xrt" link_x=" -L=/install/Release/lib" else inc_x=" -I/usr/include/onnxruntime -I/usr/include/xrt" link_x=" " fi name=$(basename $PWD) CXX=${CXX:-g++} $CXX -O2 -fno-inline -I. \ ${inc_x} \ ${link_x} \ -o ${name}_onnx -std=c++17 \ $PWD/${name}_onnx.cpp \ ${OPENCV_FLAGS} \ ${lib_opencv} \ ${lib_x} \ ${lib_onnx}
- 将可执行程序和已量化的 ONNX 模型复制到目标。然后,运行该程序。注释: 对于 ONNX 模型部署,输入模型是已量化的 ONNX 模型。如果环境变量
WITH_XCOMPILER
设为 on,那么您运行该程序时,它会首先在线执行模型编译。模型编译可能需要一段时间。