使用 Vitis AI 库进行 SSD 和 YOLOv3定制部署
概述
赛灵思® Vitis™ AI 库是面向高效 AI 推断而构建的一系列高级库和 API,并采用深度学习处理器单元 (DPU)。它基于 Vitis AI 运行时构建,带有统一的 API,并全面支持 XRT 2019.2。
Vitis AI 库提供易于使用的统一接口,包含众多高效、高质量的神经网络。该接口简化了深度学习神经网络的使用,使用户能够更加专注于应用开发,而无需为底层硬件分神。
AI 对象检测算法广泛应用于高级驾驶辅助系统 (ADAS)、医疗和智慧城市领域。单发对象检测器是最常见的算法类型。两个单发对象检测器为 SSD和 YOLO。单发检测器 (SSD) 为神经网络模型,这种模型便于训练,即使输入图形尺寸较小也能大幅提高准确性。You Only Look Once (YOLO) 是业界一流的实时对象检测系统。在 YOLO 算法系列中,YOLOv3 在检测小型对象时速度极快,准确度也更高。
Vitis AI 库支持 SSD 和 YOLO 模型部署,并提供经过优化的预处理/后处理库,以提高 E2E 性能。如果用户有其带有标准的预/后处理(SSD或YOLO)的模型,,那么用户可以使用 Vitis AI 库部署自己的 SSD/YOLO 模型。
本文详细介绍了如何在赛灵思 UltraScale+™ MPSoC 器件上使用 Vitis AI库快速部署 SSD 或 YOLOv3 模型。最新的 Vitis AI 库作为赛灵思 Vitis AI 安装包的组成部分提供:https://github.com/Xilinx/Vitis-AI。
Vitis DPU 一体化流程参考材料
如需了解 Vitis™ DPU 一体化流程,请参考以下文档:
- Zynq® UltraScale+ MPSoC DPU TRD for Vitis 2019.2: https://github.com/Xilinx/Vitis-AI/blob/master/DPU-TRD/prj/Vitis/README.md
- ZCU102_DPU and ZCU104_DPU Platform Release Notes: https://github.com/Xilinx/Vitis_Embedded_Platform_Source/blob/2019.2/Xilinx_Official_Platforms/zcu102_dpu/release_notes.md
定制 Vitis AI 库的板级安装包
您可以根据 vitis_ai_library_2019.2-r1.0.deb 定制您自己的 Vitis AI 库Debian 安装包。本安装包的下载地址为: https://github.com/Xilinx/Vitis-AI/tree/master/Vitis-AI-Library.
定制安装包的方法如下:
1. 将 vitis_ai_library_2019.2-r1.0.deb 提取到主机上的vitis_ai_library文件夹:
$mkdir vitis_ai_library
$dpkg -X vitis_ai_library_2019.2-r1.0.deb vitis_ai_library
2. 提取主机上的 Debian 安装包信息文件:
$mkdir vitis_ai_library/DEBIAN
$dpkg -e vitis_ai_library_2019.2-r1.0.deb vitis_ai_library/DEBIAN
注释: Debian 安装包信息可通过编辑控制和预安装文件进行修改。
3. 通过删除 vitis_ai_library 文件夹中不必要的文件夹和文件来定制 Debian安装包:
- usr/share/ 文件夹
- usr/lib/ 文件夹中所有的 Vitis AI 库示例相关 .so文件不含 ssd 和 yolov3 .so 文件。其他 .so 文件保留在文件夹中。
- usr/include/xilinx/ai/ 文件夹中所有 Vitis AI 库示例相关 .hpp文件不含 ssd 和 yolov3 .hpp 文件。其他 .hpp 文件保留在文件夹中。
- usr/include/xilinx/ai/nnpp/ 文件夹中所有 Vitis AI 库示例相关.hpp 文件不含 ssd 和 yolov3 .hpp 文件。
注释: 您可以查阅 Vitis AI 库用户指南 (UG1354) 中“库和样本”一章中的文件示例列表。
4. 再打包:
$dpkg -b vitis_ai_library vitis_ai_library.deb
注释: 新的 vitis_ai_library.deb 文件尺寸相对于原始文件的 123 MB 缩小至 11 MB。
5. 在目标电路板上安装,请通过 scp 将 vitis_ai_library.deb 文件复制到电路板并安装即可:
$dpkg -i vitis_ai_library.deb
主机设置
设置主机的方法如下:
- 根据以下链接中的介绍在主机服务器上安装赛灵思 Vitis AI 工具和运行时docker: https://github.com/Xilinx/Vitis-AI/blob/master/doc/install_docker/load_run_docker.md.
- 从 https://github.com/Xilinx/Vitis-AI 下载赛灵思 Vitis AI 安装包。
SSD 模型部署
您可以使用 Vitis AI 工具 docker 将自己的 SSD 浮动模型转换为 .elf 文件,并使用 Vitis AI 运行时 docker 生成执行程序并在电路板上运行。您的SSD 模型以 Caffe深度学习框架为基础,在本例中称作 ssd_user。
第一步:生成 ssd_user.elf 文件
1. 从 Vitis-AI 文件夹将以下内容复制到您的 SSD 浮动模型项目文件夹:
- The docker_run.sh file
- The script files in the Vitis-AI/mpsoc/vitis-ai-tool-example/ folder
2. 加载 Vitis AI 工具docker并如下输入 conda 环境:
$ ./docker_run.sh xilinx/vitis-ai:tools-1.0.0-gpu
/workspace$ conda activate vitis-ai-caffe
3. 修改并运行量化和编译脚本,按如下方法将浮动模型转换为ssd_user.elf:
/workspace$ bash 1_caffe_quantize.sh
/workspace$ bash 2_caffe_compile.sh
注释: --options "{'mode': 'normal'}" 参数应添加到 2_caffe_compile.sh 脚本,从而在正常模式下制作 .elf 文件。
第二步:准备 ssd_user 模型文件夹
1. 创建 ssd_user.prototxt 文件,并根据您的 SSD 模型参数添加内容。
以下为 SSD_mobilev2 参考。
model {
name : "ssd_mobilenet_v2_480x360"
kernel {
name: "ssd_mobilenet_v2_480x360"
mean: 104.0
mean: 117.0
mean: 123.0
scale: 1.0
scale: 1.0
scale: 1.0
}
model_type : SSD
ssd_param : {
num_classes : 11
nms_threshold : 0.4
conf_threshold : 0.0
conf_threshold : 0.3
conf_threshold : 0.3
conf_threshold : 0.3
conf_threshold : 0.3
conf_threshold : 0.3
conf_threshold : 0.3
conf_threshold : 0.3
conf_threshold : 0.3
conf_threshold : 0.3
conf_threshold : 0.3
keep_top_k : 200
top_k : 400
prior_box_param {
layer_width : 60,
layer_height: 45,
variances: 0.1
variances: 0.1
variances: 0.2
variances: 0.2
min_sizes: 15.0
min_sizes: 30.0
max_sizes: 33.0
max_sizes: 60.0
aspect_ratios: 2.0
offset: 0.5
step_width: 8.0
step_height: 8.0
flip: true
clip: false
}
prior_box_param {
layer_width : 30,
layer_height: 23,
variances: 0.1
variances: 0.1
variances: 0.2
variances: 0.2
min_sizes: 66.0
max_sizes: 127.0
aspect_ratios: 2.0
aspect_ratios: 3.0
offset: 0.5
step_width: 16.0
step_height: 16.0
flip: true
clip: false
}
prior_box_param {
layer_width : 15,
layer_height: 12,
variances: 0.1
variances: 0.1
variances: 0.2
variances: 0.2
min_sizes: 127.0
max_sizes: 188.0
aspect_ratios: 2.0
aspect_ratios: 3.0
offset: 0.5
step_width: 32.0
step_height: 32.0
flip: true
clip: false
}
prior_box_param {
layer_width : 8,
layer_height: 6,
variances: 0.1
variances: 0.1
variances: 0.2
variances: 0.2
min_sizes: 188.0
max_sizes: 249.0
aspect_ratios: 2.0
aspect_ratios: 3.0
offset: 0.5
step_width: 64.0
step_height: 64.0
flip: true
clip: false
}
prior_box_param {
layer_width: 4,
layer_height: 3,
variances: 0.1
variances: 0.1
variances: 0.2
variances: 0.2
min_sizes: 249.0
max_sizes: 310.0
aspect_ratios: 2.0
offset: 0.5
step_width: 100.0
step_height: 100.0
flip: true
clip: false
}
}
}
2. 创建 meta.json 文件并添加如下内容。
{
"target": "DPUv2",
"lib": "libvart_dpu.so",
"filename": "ssd_user.elf",
"kernel": [ "ssd_user" ],
"config_file": "ssd_user.prototxt"
}
3. 将 ssd_user.elf、ssd_user.prototxt 和 meta.json 文件保存到 ssd_user模型文件夹。
第三步:在主机上构建 SSD 示例代码
1. 载入 Vitis-AI 文件夹中的 Vitis-AI 运行时 docker:
./docker_run.sh xilinx/vitis-ai:runtime-1.0.0-cpu
2. 在 Vitis-AI-Library/samples/ssd/ 文件夹中运行构建脚本:
/workspace$sh -x build.sh
The executable program of test_jpeg_ssd is generated.
第四步:在目标电路板上测试 SSD 可执行程序
1. 在目标电路板的 /usr/share/ 下方创建 vitis_ai_library/models/ 文件夹。
2. 使用 scp 命令将以下内容复制到刚刚创建的 vitis_ai_library/models/文件夹:
- ssd_user 模型文件夹
- test_jpeg_ssd 和测试镜像
3. 如下运行可执行程序。
$./test_jpeg_ssd ssd_user samle_image.jpg
将结果保存为 sample_image_result.jpg。
YOLOv3 模型部署
您可以使用 Vitis AI 工具 docker 将自己的 YOLOv3 浮动模型转换为 ELF 文件,并使用 Vitis AI 运行时 docker 生成可执行程序在电路板上运行。您的 YOLOv3 模型以 Caffe 框架为基础,在本例中命名为yolov3_user 。
第一步:生成 yolov3_user.elf 文件
1. 将以下内容复制到您的 YOLOv3 浮动模型项目文件夹:
Vitis-AI 文件夹中的 docker_run.sh 文件
Vitis-AI/mpsoc/vitis-ai-tool-example/ 文件夹中的脚本文件
2. 如下载入 Vitis AI 工具 docker 并输入 conda 环境:
$ ./docker_run.sh xilinx/vitis-ai:tools-1.0.0-gpu
/workspace$ conda activate vitis-ai-caffe
3. 如下修改并运行量化和编译脚本,将浮动模型转换为 yolov3_user.elf 文件:
/workspace$ bash 1_caffe_quantize.sh
/workspace$ bash 2_caffe_compile.sh
注释: --options "{'mode': 'normal'}" 参数应添加到 2_caffe_compile.sh 脚本,从而在正常模式下制作 elf 文件。
第二步:准备“yolov3_user”模型文件夹
1. 创建 yolov3_user.prototxt 文件。
2. 根据 YOLOv3 模型参数添加内容,以下给出 yolov3_coco 作为参考。
model {
name: "yolov3_coco_608"
kernel {
name: "yolov3_coco_608"
mean: 0.0
mean: 0.0
mean: 0.0
scale: 0.00390625
scale: 0.00390625
scale: 0.00390625
}
model_type : YOLOv3
yolo_v3_param {
num_classes: 80
anchorCnt: 3
conf_threshold: 0.05
nms_threshold: 0.45
biases: 10
biases: 13
biases: 16
biases: 30
biases: 33
biases: 23
biases: 30
biases: 61
biases: 62
biases: 45
biases: 59
biases: 119
biases: 116
biases: 90
biases: 156
biases: 198
biases: 373
biases: 326
test_mAP: false
}
}
3. 创建 meta.json 文件并添加如下内容:
{
"target": "DPUv2",
"lib": "libvart_dpu.so",
"filename": "yolov3_user.elf",
"kernel": [ "yolov3_user" ],
"config_file": "yolov3_user.prototxt"
}
4. 将 yolov3_user.elf、yolov3_user.prototxt 和 meta.json 文件放入yolov3_user 模型文件夹。
第三步:在主机上构建 YOLOv3 示例代码
1. 载入“Vitis AI”文件夹下的 Vitis AI 运行时 docker:
./docker_run.sh xilinx/vitis-ai:runtime-1.0.0-cpu
2. 运行 Vitis-AI-Library/samples/yolov3/ 文件夹下的构建脚本:
/workspace$sh -x build.sh
The executable program of test_jpeg_yolov3 is generated.
第四步:在目标电路板上测试 YOLOv3 可执行程序
在目标电路板上测试 YOLOv3 可执行程序的方法如下:
1. 在目标电路板的 /usr/share/ 下方创建 vitis_ai_library/models/ 文件夹.
2. 使用 scp 命令将以下内容复制到刚刚创建的 vitis_ai_library/models文件夹:
- yolov3_user 模型文件夹
- test_jpeg_yolov3 和测试镜像
3. 如下运行可执行程序:
$./test_jpeg_yolov3 yolov3_user samle_image.jpg
The result is saved as sample_image_result.jpg。
更多信息
您也可以通过修改 Vitis AI 运行时docker环境中的 /opt/vitis_ai/petalinux_sdk/sysroots/aarch64-xilinx-linux/usr/include/xilinx/ai 文件夹中的 demo.hpp 文件来衡量前后处理和 DPU 时间,如下所示:
DEF_ENV_PARAM(DEEPHI_DPU_CONSUMING_TIME, "0");
int main_for_jpeg_demo(int argc, char *argv[],
const FactoryMethod &factory_method,
const ProcessResult &process_result,
int start_pos = 1) {
if (argc <= 1) {
usage_jpeg(argv[0]);
exit(1);
}
ENV_PARAM(DEEPHI_DPU_CONSUMING_TIME) = 1;
auto model = factory_method();
for (int i = start_pos; i < argc; ++i) {
auto image_file_name = std::string{argv[i]};
auto image = cv::imread(image_file_name);
if (image.empty()) {
LOG(FATAL) << "cannot load " << image_file_name << std::endl;
abort();
}
xilinx::ai::TimeMeasure::getThreadLocalForDpu().reset();
auto start = std::chrono::steady_clock::now();
auto result = model->run(image);
auto end = std::chrono::steady_clock::now();
auto end2endtime = int(std::chrono::duration_cast
auto dputime = xilinx::ai::TimeMeasure::getThreadLocalForDpu().get();
std::cout << "E2E time: " << end2endtime << " ms " <
std::cout << "DPU time: " << dputime << " ms " <
image = process_result(image, result, true);
auto out_file =
image_file_name.substr(0, image_file_name.size() - 4) + "_result.jpg";
cv::imwrite(out_file, image);
LOG_IF(INFO, ENV_PARAM(DEBUG_DEMO)) << "result image write to " << out_file;
}
LOG_IF(INFO, ENV_PARAM(DEBUG_DEMO)) << "BYEBYE";
return 0;
}
参考材料
以下文档提供额外信息:
- Vitis AI Library User Guide (UG1354)