在Ubuntu18.04上为Tensorflow、Tensorflow lite配置Arm NN SDK编译环境
注:本文主要参考了ARM NN:Ubuntu 14.04 Caffe和TensorFlow的ARM NN SDK编译环境搭建及MNIST程序测试和Configure the Arm NN SDK build environment for TensorFlow Lite的两篇文章然后在Young Ge的指导下完成,文中主要对环境搭建以及碰到的问题进行总结。
开始之前:为方便移植请新建文件夹专用于环境搭建,本文所用为/home/ArmNN(在此处创建的文件夹对其操作需要使用root权限)
环境版本配置
- scons:官方测试2.4.1,本文2.4.1(下载所需版本)
- cmake:官方测试3.5.1,本文3.7.2(下载所需版本)
- computerlibrary:本文19.08(git clone)
- boost:官方测试1.64.0,本文1.64.0(下载所需版本)(git clone)
- protobuf:官方测试3.5.0,本文3.10.0(git clone)
- tensorflow:本文2.0.0(git clone)
- flatbuffers:本文1.11.0(git clone)
- armnn:本文19.08(git clone)
各个版本之间存在差异,可能会出现不同的问题,推荐使用官方测试过的版本。关于tensorflow的版本建议采用1.14.0,flatbuffers建议采用1.10.0,因为使用1.11.0在后续的单元测试中有人出现过错误。
一、安装scons
因为笔者以前没有安装过scons,所以直接下载后,将其解压至/home/ARMNN运行命令:
sudo python setup.py install
如果以前有安装过(即便没有也可以),可以运行下面的代码进行卸载:
rm /usr/local/bin/scons*
rm -r /usr/local/lib/scons*
不出意外的就可以安装成功了。
二、安装cmake
在安装相应版本的cmake前先卸载以前安装的cmake,如果是通过apt安装的运行下面代码:
sudo apt-get autoremove cmake
通过安装包安装的删除安装目录即可。
将下载好的cmake安装包解压到/home/ARMNN然后进入文件夹,如果是.sh文件直接运行:
sh cmake-version-Linux-x86_64.sh
如果下载的.gz文件,解压后进入目录运行:
ln -s /home/ARMNN/cmake-version-Linux-x86_64/bin/* /usr/bin/
这样就安装好了cmake,使用命令 cmake -version 查询版本,如果不能使用设置一下环境变量。
三、构建Arm Compute库
先克隆源码:git clone https://github.com/ARM-software/ComputeLibrary.git
cd /home/ARMNN/ComputeLibrary
# 对于Armv7-A
scons extra_cxx_flags =“-fPIC”
# 对于Armv8-A
scons arch = arm64-v8a extra_cxx_flags =“-fPIC”
命令后面可以的参数:(启用基准测试设置为1)Benchmark_tests=1
(启用验证测试设置为1)validation_tests=1
(若需添加Arm Mali GPU支持OpenCL)opencl=1 embed_kernels=1
(CPU上启用对NEON的支持)neon=1
使用的编译器如果和系统设置的不一样时,在SConstruct文件下进行修改:
系统默认armv7a编译器为arm-linux-gnueabuhf-,arm64-v8a编译器为aarch64-linux-gnu-,如需更换编译器,修改图中prefix即可。
编译时间较长,用时将近一个小时,编译成功如下显示:
四、构建Boost库
下载好boost库解压至/home/ARMNN/boost
cd /home/ARMNN/boost
./booststrap.sh
此时会生成b2配置文件,首先修改project-config.jam文件:
//注意修改的编译器为你自己使用的编译器,还有冒号之间有空格
if ! gcc in [ feature.values <toolset>]
{
using gcc : arm : aarch64-linux-gnu-gcc --sysroot=$SDKTARGETSYSROOT ;
}//如果为32位平台则如下修改
if ! gcc in [ feature.values <toolset>]
{
using gcc : arm : arm-linux-gnueabihf-gcc ;
}
修改好之后运行b2配置文件:
./b2 --build-dir=/home/ARMNN/boost/build toolset=gcc link=static cxxflags=-fPIC --with-filesystem --with-test --with-log --with-program_options --with-system install --prefix=/home/ARMNN/boost_root
运行上面代码,如下图所示显示为64位的arm平台:
后续如果报错缺失boost库使用--with添加即可。
五、构建Google protobuf库
首先进行本机编译:
cd /home/ARMNN/protobuf
./autogen.sh
mkdir x86_64_build
cd x86_64_build
../configure -prefix=/home/ARMNN/protobuf_x86_64_root
make install -j32
完成后如下所示:
然后用本机编译的protoc可执行文件交叉编译protobuf:
mkdir arm64_build
cd arm64_build
# 对于arm64-v8a
CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ ../configure -host=aarch64-linux -prefix=/home/ARMNN/protobuf_arm64_root -with-protoc=/home/ARMNN/protobuf_x86_64_root/bin/protoc
#对于armv7a,更改编译器即可
CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++
六、生成tensorflow protobuf库
下载源码复制到/home/ARMNN,进入目录后运行:
../armnn/script/generate_tensorflow_protobuf.sh ../tensorflow-2.0.0_protobuf ../prtobuf_arm64_root
正常完成之后,应该什么都不会显示,并且在/home/ARMNN下创建了目录tensorflow-2.0.0_protobuf
七、构建Google flatbuffers库
克隆源码,进入目录后先修改CMakeList.txt(这里是个坑,如果不先修改后面就会报错),更改FLATBUFFERS_BUILD_TEST为OFF,否则之后运行会出现错误:
[ 44%] Building CXX object CMakeFiles/flatc.dir/grpc/src/compiler/go_generator.cc.o
[ 46%] Building CXX object CMakeFiles/flatc.dir/grpc/src/compiler/java_generator.cc.o
[ 47%] Linking CXX executable flathash
[ 47%] Built target flathash
[ 50%] Linking CXX static library libflatbuffers.a
[ 50%] Linking CXX executable flatc
[ 50%] Built target flatbuffers
[ 50%] Built target flatc
[ 52%] Generating tests/monster_test_generated.h
./flatc: 8: ./flatc: Syntax error: "(" unexpected
make[2]: *** [CMakeFiles/flattests.dir/build.make:62:tests/monster_test_generated.h] error 2
make[1]: *** [CMakeFiles/Makefile2:289:CMakeFiles/flattests.dir/all] error 2
[ 55%] Generating samples/monster_generated.h
[ 55%] Generating samples/monster_generated.h
[ 57%] Generating samples/monster_generated.h
./flatc: 8: ./flatc: ./flatc: 8: ./flatc: Syntax error: "(" unexpected
Syntax error: "(" unexpected
make[2]: *** [CMakeFiles/flatsamplebinary.dir/build.make:62:samples/monster_generated.h] error 2
make[2]: *** [CMakeFiles/flatsampletext.dir/build.make:62:samples/monster_generated.h] eroor 2
make[1]: *** [CMakeFiles/Makefile2:141:CMakeFiles/flatsamplebinary.dir/all] error 2
make[1]: *** [CMakeFiles/Makefile2:215:CMakeFiles/flatsampletext.dir/all] error 2
./flatc: 8: ./flatc: Syntax error: "(" unexpected
make[2]: *** [CMakeFiles/flatsamplebfbs.dir/build.make:62:samples/monster_generated.h] error 2
make[1]: *** [CMakeFiles/Makefile2:252:CMakeFiles/flatsamplebfbs.dir/all] error 2
make: *** [Makefile:161:all] error
继续修改CMakeList.txt,在 #NOTE:Code converage only works in Linux & OSX 前加上代码:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -Wall -Wno-unused-variable -Wold-style-cast -Wno-missing-braces -pthread")
如果缺失-pthread在后面构建armnn时会出现错误:
修改完CMakeList.txt之后运行:
CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
make -j32
成功后如下图所示:
八、构建Arm NN
克隆好源码之后进入目录:
cd /home/ARMNN/armnn
mkdir build
cd build
CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ cmake .. -DARMCOMPUTE_ROOT=/home/ARMNN/ComputeLibrary -DARMCOMPUTE_BUILD_DIR=/home/ARMNN/ComputeLibrary/build -DBOOST_ROOT=/home/armnn/boost-root -DTF_GENERATED_SOURCES=/home/ARMNN/tensorflow-2.0.0_protobuf -DBUILD_TF_PARSER=1 -DBUILD_TF_LITE_PARSER=1 -DBUILD_TESTS=1 -DTF_LITE_GENERATED_PATH=/home/ARMNN/tensorflow-2.0.0/tensorflow/lite/schema -DPROTOBUF_ROOT=/home/ARMNN/protobuf_arm64_root -DPROTOBUF_LIBRARY_DEBUG=/home/ARMNN/protobuf_arm64_root/lib/libprotobuf.so -DPROTOBUF_LIBRARY_RELEASE=/home/ARMNN/protobuf_arm64_root/lib/libprotobuf.so -DPROTOBUF_INCLUDE_DIRS=/home/ARMNN/protobuf_arm64_root/include -DFLATBUFFERS_ROOT=/home/ARMNN/flatbuffers -DFLATBUFFERS_LIBRARY=/home/ARMNN/flatbuffers/libflatbuffers.a
make -j32
这里一定要记得加 -DBUILD_TESTS=1 ,因为后面例程会用到inferencetest.so,所以要构建测试的静态库。完成之后如下所示:
编译完成后,在build文件夹下会生成以下库文件:
到这里,整个环境差不多算搭建完成了,接下来将几个库文件(libarmnn.so、libarmnnTFLiteParser.so、libarmnnTFParser.so、libflatbuffers.a、libprotobuf.so)和测试程序 UnitTests 移到板子上,全部放入到板子的 /根目录/lib 下即可。
然后在板子上运行:./UnitTests进行测试
九、MNIST测试
先克隆官方例程:
然后进入/ML-examples/armnn-mnist,先编辑Makefile如下所示:
然后 make 就能生成mnist_tf,将其移入板子运行即可。
十、mobilenetv1_quant_tflite测试
进入/ML-examples/armnn-mobilenet-quant,编辑Makefile如下:
然后 make 就能生成mobilenetv1_quant_tflite,使用姿势如下:
./mobilenetv1_quant_tflite -m <ModelPath> -d <DataPath> -p <ModelOutputLabels> [-c <ComputeDevices>] -h [ --help ] Display help messages -m [ --model-path ] arg Path to armnn format model file -d [ --data-dir ] arg Path to directory containing the ImageNet test data -p [ --model-output-labels ] arg Path to model output labels file. -c [ --compute ] arg (=[CpuAcc CpuRef ]) Which device to run layers on by default. Possible choices: CpuAcc, GpuAcc, CpuRef
例:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./mobilenetv1_quant_tflite -m ./models/mobilenetv1_1.0_quant_224.tflite
-d ./data/Dog.JPEG -p ./models/labels.txt -c GpuAcc CpuAcc
后面等板子到了再测试一下是否成功以及运行速度之间的对比。。。。