在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
後面等板子到了再測試一下是否成功以及運行速度之間的對比。。。。