下面从几个方面介绍下自己的采坑之路:
- NCNN自带模型的benchmark
- NCNN交叉编译到rk3288(armv7架构)和rk3399(armv8架构)的方法
- NCNN转换其他模型并加入benchmark中
NCNN自带模型的benchmark
1. 下载NCNN
NCNN这类开源引擎都可以从github上下载下来,下载下来的整个文件夹就像一个完整的软件或者生态系统一样,之后的所有操作都会在这个文件夹里完成。下载方式可以直接去官方的github上下载,我的是ubuntu系统,也可以直接git。如下:
git clone https://github.com/Tencent/ncnn
下载完成之后,其实是一个完整的文件夹,里面有很多源码可以查看,也可以直接编译使用。可以先来感受一下,整个文件夹下载后是这个样子。
benchmark中包含了跑benchmark的源码benchncnn.cpp,感兴趣的可以先看一下里面的内容。
2. 编译benchmark
在ncnn的文件根目录下,新建一个build文件夹并进入,当然也可以不叫build,随便你自己起。
mkdir build && cd build
进入之后就可以进行编译了,编译之后在build文件夹下会生成一个叫benchmark的文件夹,之后的工作会在这里进行。编译用的是cmake,这里如果有问题的话可以注意一下cmake的版本,我用的版本是3.12.3。具体命令如下:
cmake ..
make -j8
这里cmake编译实际上是要根据上一层文件夹的CMakeLists.txt的文本来的,这里的..其实就是表示的上一层文件夹。 Make -j后面的数字是开几个核,根据自己电脑的实际情况来。执行完成之后就可以看到build里有了benchmark的文件夹。如下图所示。
进入这个文件夹,可以看到一个benchncnn的可执行文件已经编译好了,运行这个可执行文件就可以测试模型的速度。但是这个可执行文件默认的是找到当前文件夹下的param格式的文件。所有自带的模型文件都在ncnn根目录下的benchmark的文件夹中,把里面所有的param文件都拷贝到现在的benchmark文件夹,然后执行如下命令
./benchncnn 4 2 0 -1
第一个数字表示测试次数,第二个表示开的线程数(这一点ncnn做的不错),最后一个数字-1表示只测cpu。跑出的结果如下图所示:
NCNN交叉编译到rk3288(armv7架构)和rk3399(armv8架构)的方法
在本机跑出结果之后,后面就是上板子跑了,目标也是在rk3288和rk3399上进行测试。但是并不是个人的设备,所以没有直接在板卡上编译,采用了交叉编译的方式。交叉编译的意思就是在本机上完成整个编译的过程,生成可执行文件。但是这个可执行文件在本机上是执行不了的,必须在编译器指定的环境下运行。rk3288是armv7架构的,rk3399是armv8架构的。话说想从官网上下一个新一点交叉编译工具的网速真是慢,好几次没成功。为什么下新的?因为本人之前随便找到交叉编译工具,好像是2014年的,然后明明步骤没错,编译后总是显示缺少一个动态库,好像是什么libzo1.so,具体名字记不清了,大概是这个。查了很久,发现应该是是交叉编译链里没有这个,下了2018的版本就没有问题。坑啊。我把我下载的两个架构的交叉编译工具共享在下面了,有需求的小伙伴可以下载。
https://download.csdn.net/download/weixin_41232202/12960889
https://download.csdn.net/download/weixin_41232202/12960807
编译工具链下载之后,需要设置环境变量,其方法如下:
gedit ~/.bashrc
export PATH=$PATH:/your/path/to/toolchains/bin
注意需要定位到bin下,这样系统就能够找到对应的交叉编译工具了。
NCNN的交叉编译比较的方便,cmake都已经写好,在ncnn根目录下的toolchains中。现在可以新建一个文件夹用作交叉编译,如
mkdir build-armv7 && cd build-armv7
cmake -DNCNN_BUILD_TOOLS=0 -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-liunx-gnueabihf.toolchain.cmake
make -j8
make install
这里要注意,cmake这后面 build_tools这个一定要设置,否则编译不通过。之后就会同样生成benchmark文件夹,并且里面有一个叫benchncnn的可执行文件,但是这个文件在本机是执行不了的。只能放到板卡上运行。armv8的架构类似,只需要讲toolchains后面的内容换成aarch64-linux-gnu.toolchain.cmake就可以了。感兴趣的可以尝试看一下这个cmake文件,其实这部分也可以按照自己的需求来写,不一定要用现成的。
NCNN转换其他模型并加入benchmark中
NCNN可以将其他格式的模型文件转换成NCNN识别的格式,同样可以进行benchmark的测试。NCNN识别的格式是param和bin,其中.param格式存放的是模型的框架,bin是权重等信息。对于跑benchmark来说,只需要param格式的文件。
步骤按照第一节中的来,在本机编译完成后,会在build文件夹下生成一个tools文件夹,里面有NCNN支持的文件转换格式,如下图所示
以onnx为例,其中包含里一个可执行文件onnx2ncnn,这就是可以将onnx转换为NCNN识别的模型格式的工具,具体操作如下:
进入到onnx文件路径下,./onnx2ncnn path/to/your/model/your_model.onnx model_name.param model_name.bin这样生成的两个文件就会在当前目录下。
最后,将.param文件拷贝到之前生成的benchmark的路径下,但是要注意的是,ncnn之前已经编译好的benchmark可执行文件不会自动去识别文件夹下所有的.param文件。需要我们找到根目录下benchmark文件夹下的benchmark.cpp的源文件,增加我们的模型,然后重新编译。增加的内容如下图所示
benchmark(“转换后模型的文件名”, ncnn::Mat(模型的输入尺寸),opt)
之后按照上面两节的步骤重新编译一遍,就能够测出新加入的模型的benchmark了。