爱笑的小姐姐 · 2020年09月27日

基于Tengine实现yolov4的cpu推理

本期讲解便是基于 Tengine 实现 yolov4的 cpu推理

完成动机:

主要是为了熟悉tengine的推理部署流程

一、模型转换

采用下面链接中yolov4的模型权重和配置文件

https://github.com/ultralytics/yolov3github.com

源模型使用的是darknet格式,因为yolov4新增了mish算子,所以需要增加对应算子的序列化代码才能正常转换,下面是我的代码改动,基本按照tanh算子进行相应增加。

https://github.com/zjd1988/Tengine-Convert-Toolsgithub.com

convert tools增加算子的详细流程,参考官方增加自定义算子步骤:

(1)在operator/include/operator目录下增加mish.hpp 和mish\_param.hpp\_文件,\_由于mish算子不需要额外的参数配置,因此mish\_para.hpp并没有添加。mish.hpp内容可以参考其他类似没有参数配置的算子(比如tanh),在operator/operator 目录下增加mish.cpp,增加算子实现代码;

(2)在operator/operator目录下增加mish算子内存分配的代码,因为mish算子不涉及这部分修改,并未做任何修改

(3)在operator/operator/plugin/init.cpp文件中的operator\_plugin\_init函数中增加算子的注册函数调用

(4)增加mish算子序列化和解析代码

(4-1)在serializer/include/tengine/v2/tm2\_format.h中增加mish的类型宏定义和字符串宏定义 ;
(4-2)在serializer/tengine/v2/tm2\_op\_load.cpp文件中增加LoadTmMishOp函数实现,同时在LoadTmOpFunc函数中增加调用LoadTmMishOp的逻辑代码;
(4-3)在serializer/tengine/v2/tm2\_op\_save.cpp文件中增加SaveTmMishOp函数实现,同时在SaveTmReorgOp函数中增加调用SaveTmMishOp的逻辑代码;
(4-4)在serializer/tengine/v2/tm2\_op\_serializer.hpp,增加LoadTmMishOp和 SaveTmMishOp的函数声明

(4-5)本次转换模型针对darknet,所以需要对tools/darknet/darknet\_serializer.cpp文件中增加mish算子解析的相应逻辑。 因为mish没有单独使用,而是作为conv的激活函数调用,所以是在LoadConv2D函数参照leaky增加相应的代码。其他单独算子的实现也可以参考其他类似算子的实现方式

完成代码改动后,按照如下操作进行编译,即可生成转换工具

mkdir build && cd build
cmake ..
make -j4 && make install

最后执行转换动作(提前准备好模型文件)

./install/bin/tm_convert_tool -f darknet -p yolov4.cfg -m yolov4.weights -o yolov4.tmfile

二、推理

官方代码链接下的readme并没有找到介绍如何新增算子,但是可以参考类似算子进行修改添加,下面是我参考tanh算子的实现,进行的修改

(1-1)在inlcude/tengine\_op.h中增加mish的枚举定义,include/tengine\_op\_name.h中增加mish的字符串宏定义
(1-2)在src/op/mish.c中增加mish算子的注册函数
(1-3)在src/serializer/tm/tm2\_format.h 和src/serializer/tm/op/tm2\_mish.c 中增加序列化相关代码,

note:src/serializer/tm/tm2\_format.h中定义算子的类型数值需要跟convert\_tools下的serializer/include/tengine/v2/tm2\_format.h代码保持一致

(1-4)在src/dev/cpu/op/目录下增加mish算子实现代码目录,包括mish\_ref.c(x86)、mish\_hcl\_arm.c(arm),其中contex-a目录下的文件为具体的kernel实现代码

也可以参考下面的链接,查看有哪些代码改动和文件增加:

https://github.com/zjd1988/Tenginegithub.com

测试

测试图片使用的是标题中的图片(512x384)test.jpg
测试代码使用的官方代码

examples/tm_yolov3_tiny.cpp

做了简单修改。

测试结果如下图

三、后续

(1)合并conv和mish算子
(2)后续抽空新增一个需要配置参数的算子

四、使用感受

(1)模型转换和推理分离,新增算子需要增加两次,官方回复会后续考虑合并,希望会越来越方便
(2)推理引擎编译速度快(本文目的不在于测试性能,只是验证tengine在推理yolov4的正确性)
(3)代码结构清晰,便于阅读和调试

以上便是解答过程以及使用感受。

更多Tengine相关内容请关注Tengine-边缘AI推理框架专栏。
推荐阅读
关注数
3391
内容数
68
Tengine是一款轻量级模块化高性能的神经网络推理引擎 ;欢迎体验Tengine,[链接] 《Tengine开发者入门资料包》[链接]
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息