![19703028d4d4075345a2e9389f3b0961.png](https://i-blog.csdnimg.cn/blog_migrate/38489dd5e730aba5f5bd8ba4ce1ad978.jpeg)
YOLOV4又快又好,论文发出后nvidia官方也跟进推出了相应的插件来支持Deepstream的部署,现在给大家总结部署流程。
部署流程
- 训练好yolov4的模型,准备.weights文件和cfg文件;
- 使用pytorch把
.weights
文件转成onnx模型; - 在目标设备上使用TensorRT把onnx模型转成
.engine
文件; - 在目标设备上编译YoloV4插件;
- 运行测试。
其中1、2点在你自己服务器上执行,3、4、5在需要部署deepstream的目标设备上执行。
生成onnx模型
在服务器上自己的账号底下执行
git clone https://github.com/Tianxiaomo/pytorch-YOLOv4.git
cd pytorch-YOLOv4
安装所需要的python库
pytorch <= 1.4 # 一定要小于或等于1.4版本,详情到pytorch官网看怎么安装
onnx
onnxruntime
opencv-python
当所有要求的库安装之后,在项目目录下执行:
python demo_darknet2onnx.py <cfgFile> <weightFile> <imageFile> <batchSize>
第三个参数233.png是一张用来测试的图,随便找一张你的模型训练集的图片就行。第四个参数是batchsize,0代表这是dynamic batchsize。
python demo_darknet2onnx.py cfg/yolov4-hat.cfg yolov4-hat_7000.weights 233.png 0
这个命令会生成onnx文件,如果你最后的参数是0,你会得到类似yolov4_-1_3_416_416_dynamic.onnx
的文件;如果你最后的batchsize参数大于0(如8),就会得到两个模型文件,文件名分别为:yolov4_1_3_416_416_static.onnx
和yolov4_8_3_416_416_static.onnx
, 当中一个默认batchsize为1用来进行demo的运行,一个是你设置的batchsize,这两个都是静态batchsize,推理的时候必须组成相应的batchsize才能推理,否则会报错。因此还是推荐动态batchsize。
生成TRT模型(.engine文件)
在你想要部署deepstream的设备上,把上一步的.onnx文件复制过去,执行:
/usr/src/tensorrt/bin/trtexec --onnx=<onnx_file>
--minShapes=input:1x3x416x416 --optShapes=input:<batchsize>x3x416x416 --maxShapes=input:<max_batchsize>x3x416x416
--workspace=<size_in_megabytes> --saveEngine=<tensorRT_engine_file> --fp16
参数说明
--onnx:上一步生成的onnx文件
--minShapes:最小的batchsize x 通道数 x 输入尺寸x x 输入尺寸y
--optShapes:最佳输入维度,跟maxShapes一样就好
--maxShapes:最大输入维度
--workspace:默认4096即可
--saveEngine:输出的engine名
--fp16:使用fp16精度
例子:
/usr/src/tensorrt/bin/trtexec --onnx=yolov4_uniform-1_3_416_416_dynamic.onnx
--minShapes=input:1x3x416x416 --optShapes=input:8x3x416x416 --maxShapes=input:8x3x416x416
--workspace=4096 --saveEngine=yolov4-uniform-dynamic-max8.engine --fp16
经过漫长的等待之后,如果你看到以下日志,证明转换成功,你就可以获得一个.engine
文件:
----------------------------------------------------------------
[10/29/2020-06:07:07] [W] [TRT] onnx2trt_utils.cpp:198: Your ONNX model has been generated with INT64 weights, while TensorRT does not natively support INT64. Attempting to cast down to INT32.
[10/29/2020-06:07:07] [W] [TRT] onnx2trt_utils.cpp:198: Your ONNX model has been generated with INT64 weights, while TensorRT does not natively support INT64. Attempting to cast down to INT32.
[10/28/2020-12:55:30] [I] [TRT] Some tactics do not have sufficient workspace memory to run. Increasing workspace size may increase performance, please check verbose output.
[10/28/2020-13:12:28] [I] [TRT] Detected 1 inputs and 8 output network tensors.
[10/28/2020-13:12:34] [I] Warmup completed 0 queries over 200 ms
[10/28/2020-13:12:34] [I] Timing trace has 0 queries over 3.65968 s
[10/28/2020-13:12:34] [I] Trace averages of 10 runs:
[10/28/2020-13:12:34] [I] Average on 10 runs - GPU latency: 224.415 ms - Host latency: 236.691 ms (end to end 455.919 ms)
[10/28/2020-13:12:34] [I] Host latency
[10/28/2020-13:12:34] [I] min: 233.869 ms (end to end 440.656 ms)
[10/28/2020-13:12:34] [I] max: 240.808 ms (end to end 518.528 ms)
[10/28/2020-13:12:34] [I] mean: 236.161 ms (end to end 453.082 ms)
[10/28/2020-13:12:34] [I] median: 235.465 ms (end to end 446.822 ms)
[10/28/2020-13:12:34] [I] percentile: 240.808 ms at 99% (end to end 518.528 ms at 99%)
[10/28/2020-13:12:34] [I] throughput: 0 qps
[10/28/2020-13:12:34] [I] walltime: 3.65968 s
[10/28/2020-13:12:34] [I] GPU Compute
[10/28/2020-13:12:34] [I] min: 218.841 ms
[10/28/2020-13:12:34] [I] max: 228.87 ms
[10/28/2020-13:12:34] [I] mean: 223.998 ms
[10/28/2020-13:12:34] [I] median: 223.521 ms
[10/28/2020-13:12:34] [I] percentile: 228.87 ms at 99%
[10/28/2020-13:12:34] [I] total compute time: 3.35997 s
&&&& PASSED TensorRT.trtexec # /usr/src/tensorrt/bin/trtexec --onnx=yolov4_-1_3_416_416_dynamic.onnx --minShapes=input:1x3x416x416 --optShapes=input:32x3x416x416 --maxShapes=input:32x3x416x416 --workspace=4096 --saveEngine=yolov4-hat-dynamic.engine --fp16
上面有测试的推理时间,比如上面的mean为223.52ms,意思是平均每个batch推理耗时223.52毫秒。详细的讨论可以看这个链接:What kind of hardware rigs can support 100+ videos analytics using deepstream?
在deepstream上使用TRT模型
生成模型后,我们需要编译能够解析yolov4算子的层插件。我们在服务器上克隆一下nvidia官方的YOLOV4插件项目:
git clone https://github.com/NVIDIA-AI-IOT/yolov4_deepstream
cd yolov4_deepstream/
里面有一个deepstream_yolov4/
的文件夹,把这个deepstream_yolov4/
文件夹复制到目标设备上的这个位置:/opt/nvidia/deepstream/deepstream-5.0/sources/
,一定要放到这个位置,否则编译失败。
接下来修改deepstream_yolov4/nvdsinfer_custom_impl_Yolo/nvdsparsebbox_Yolo.cpp
中的NUM_CLASSES_YOLO为你自己的类别数,然后在deepstream_yolov4/
中执行:
export CUDA_VER=10.2
make -C nvdsinfer_custom_impl_Yolo
会编译得到一个动态编译库:libnvdsinfer_custom_impl_Yolo.so
然后根据需要添加并且修改两个配置文件和label.txt文件,它们都在DeepStream文件夹中。
你需要修改:
deepstream_app_config_yoloV4.txt
中的:
- model-engine-file = 你生成的engine文件
- labelfile-path = labels.txt
- 以及其它配置,如source、sink等,按照自己任务来修改。
2. config_infer_primary_yoloV4.txt
中的:
- model-engine-file=<onnx_engine_file>
3. labels.txt
中的标签名字,一行一个标签名,顺序要按照训练时的标签顺序。
具体的文件目录如下:
├── deepstream_yolov4
│ ├── config_infer_primary_yoloV4.txt
│ ├── deepstream_app_config_yoloV4.txt
│ ├── labels.txt
│ ├── nvdsinfer_custom_impl_Yolo
│ │ ├── libnvdsinfer_custom_impl_Yolo.so
│ │ ├── Makefile
│ │ ├── nvdsparsebbox_Yolo.cpp
│ └── Readme.md
最后在deepstream_yolov4/
目录下执行
deepstream-app -c deepstream_app_config_yoloV4.txt
大功告成,App run successfully。
参考项目
项目可能会随着时间发生变化,可查看以下项目repo以获得最新的版本:
NVIDIA-AI-IOT/yolov4_deepstream
Tianxiaomo/pytorch-YOLOv4