yolov4在Nvidia Xavier上部署与性能测试(tkDNN)

本文介绍YoloV4在NVIDIA Jetson平台上的量化部署流程,包括模型训练、权重导出、tkDNN工具使用及INT8量化配置等关键技术环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

yolov4 init8量化下效果图:

git图片
(PS.原始视频取自B站,侵删。)

性能展示(FPS):

平台网络FP32,B=1FP32,B=4FP16,B=1FP16,B=4INT8,B=1INT8,B=4
Xavier AGXyolov419.62139.847.448.558.8

什么是tkDNN?

tkDNN是一个由cuDNN和TensorRT原语构建的深度神经网络库,专门用于NVIDIA Jetson开发板上。它已经在TK1(cudnn2分支),TX1,TX2,AGX Xavier,Nano和多个类型的GPU上进行了测试。该项目的主要目标是尽可能多地利用NVIDIA开发板,以获得最佳的推理性能。

所部署的Xavier环境

nvcc -V		# 查看cudn版本

CUDA10.0.326

cat /usr/include/cudnn.h | grep CUDNN_MAJOR -A 2	# 查看Xavier上cudnn版本

cuDNN7.6.3

OpenCV3
yaml-cpp 0.5.2 (sudo apt install libyaml-cpp-dev)
如果需要安装opencv4 with contrib使用脚本下载编译安装

bash scripts/install_OpenCV4.sh

注意:当使用未与contrib联编的OpenCV时,需要在include/tkDNN/DetectionNN.h中注释掉OPENCV_CUDACONTRIBCONTRIB宏。注释时,网络的预处理将在CPU上运行,否则在GPU上运行(GPU上运行时这样端到端的延迟将节省几毫秒)

如何编译?

使用cmake >= 3.15编译
(如果不用cmake3.15版本或以上的在cmake时会报错cmake:
CUDA_cublas_device_LIBRARY variable set to NOTFOUND #181:

git clone https://github.com/ceccocats/tkDNN.git
cd tkDNN
sudo apt install libyaml-cpp-dev
mkdir build && cd build
cmake ..
make

运行流程(Steps)

  1. 使用所选的框架构建并训练模型
  2. 导出神经网络每一层权重和偏置并将它们保存至一个二进制文件(一个文件对应一层)
  3. 导出网络每一层的输出并保存至二进制文件(一个文件对应一层)
  4. 创建一个新测试,并使用图区的权重和输出来逐层定义网络并检查结果
  5. 开始推理

如何导出权重?

导出yolov4权重(darknet):

git clone https://git.hipert.unimore.it/fgatti/darknet.git
cd darknet
# Makefile里不需要设置,全为0直接编译就可以了
make
mkdir layers debug
./darknet export <path-to-cfg-file> <path-to-weights> layers
# 没有yolo4文件需要自己mkdir一下
# mkdir ${tkDNN_ROOT}/yolo4
mv layers ${tkDNN_ROOT}/build/yolo4   
mv debug ${tkDNN_ROOT}/build/yolo4

在tkDNN/build文件夹中,对于每个测试,都需要按以下方式构建文件结构

 yolo4
        |---- layers/ (导出的每层的权重和偏置二进制文件)
        |---- debug/  (导出的每层的输出的二进制文件)

Darknet解析器

tkDNN工具和darknet的cfg文件的简单解析器,可以使用

tk::dnn::darknetParser

example:

tk::dnn::Network *net = tk::dnn::darknetParser("yolov4.cfg", "yolov4/layers", "coco.names");
net->print();

支持的网络层:
卷积层,最大池化层,平均池化层,shrtcut,上采样层,route,reorg,region,yolo
支持的激活层:
relu层,leaky层,mish层

模型转换(生成RT文件)

export TKDNN_BATCHSIZE=4    # 使用最大可得batch_size.test将仍以batch_size=1进行,但是创建的TRT可以管理所需的批次大小
# 即demo的参数number-of-batches <=4, 默认为1
# build tensorRT files

# export TKDNN_MODE=FP16 # 使用fp16进行推理,默认为fp32
cd ${tkDNN_ROOT}/build
rm yolo4_fp32.rt  # 先删除掉旧的trt文件,若没有可省去此行
./test_yolo4   # 运行生成trt文件,过程比较慢

最后输出以下内容表示转换成功,并且当前目录下生成yolo4_fp32.rt文件(fp指定多少会生成对应的模型,默认fp32)

=== OUTPUT 2 CHECK RESULTS ==
CUDNN vs correct
 | [ 0 ]: 0.883185 0.662701
 | [ 1 ]: 0.537623 0.447494
 | [ 2 ]: 0.419132 0.250892
 | [ 3 ]: 0.512993 0.84352
 | [ 4 ]: 0.394617 0.248717
 | [ 5 ]: 0.543686 0.205057
 | [ 6 ]: 0.56079 0.859086
 | [ 7 ]: 0.362244 0.754671
 | [ 8 ]: 0.568176 0.775207
 | Wrongs: 9748 ~0.02
TRT   vs correct
 | [ 0 ]: 0.883186 0.662701
 | [ 1 ]: 0.537623 0.447494
 | [ 2 ]: 0.419132 0.250892
 | [ 3 ]: 0.512994 0.84352
 | [ 4 ]: 0.394617 0.248717
 | [ 5 ]: 0.543685 0.205057
 | [ 6 ]: 0.560791 0.859086
 | [ 7 ]: 0.362245 0.754671
 | [ 8 ]: 0.568176 0.775207
 | Wrongs: 9748 ~0.02
CUDNN vs TRT     | OK ~0.02

注:使用int8量化需要设置更多的配置:

export TKDNN_MODE=INIT8 

# 图片绝对路径组成的txt文件,每行代表一个图片,用于校准模型,使用训练集
export TKDNN_CALIB_IMG_PATH=/path/to/calibration/imge_list.txt

# 标签文件绝对路径组成的txt文件,每行表示一个文件
export TKDNN_CALIB_LABEL_PATH=/path/to/calibration/label_list.txt

# 使用此脚本下载数据集并创建上述所需的txt文件
bash scripts/download_validation.sh COCO
  • 使用INT8和FP16推理过程中可能会有一些错误。
  • ./test生成rt文件时速度会更慢,主要是在校准图像时非常耗时
  • INT8要求TRT>=6.0
  • 默认使用100张图像作为校准,可在代码中设置

注意:如果上述过程中遇到错误,则在编译tkDNN时使用debug模式,以便于打印错误信息。

cmake .. -DDEBUG=True
make

运行Demo

当成功创建trt文件时,即可运行demo:

./demo yolo4_fp32.rt xxx.mp4 y

./demo有以下7个参数(按序):

  1. network-rt-file:通过./test_yolo4生成的rt文件 (必要)
  2. path-to-video:待检测的视频文件或者摄像头 (必要)
  3. kind-of-network:网络结构类型。当前支持:y (yolo系列)、c(CenterNet系列)、m(MobileNet-SSD系列) (必要)
  4. number-of-classes:网络训练时的类别数
  5. n-batches:推理时用的batch_size(在导出模型时需要指定batch_size)
  6. show-flag:如果设置为0则不可视化显示推理效果,而是保存为mp4格式的视频(此时要求n-batches为1)
  7. conf-thresh:置信度阈值

测试模型的mAP

./map_demo <network rt> <net type [y|c|m]> <labels file path> <config file path>
# example
./map_demo dla32_cnet_FP32.rt c ../demo/COCO_val2017/all_label.txt ../demo/config.yaml

修改部分

demo.cpp

116        //inference
117        std::ofstream ofs ("result.csv");
118        detNN->update(batch_dnn_input, n_batch, true, &ofs);

将save_times 设置为true,并指定一个输出流将平均每帧预处理时间(preprocess)、推理时间(inference)、后处理时间(postprocess)记录下来,上面代码表示写入到当前目录的result.csv文件中。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值