目的
PC(Ubuntu)にクロスコンパイル環境を構築して、ディープラーニングフレームワークのncnnとベンチマークソフトウェアのbenchmarkビルドし、UnitV2でncnn benchmarkを実行します。
また、こちらのリポジトリで、これまでにCoreMP135、Raspberry Pi Zero 2 W、M5Stack_UnitV2、LicheeNano RV、Luckfox Pico Maxでのncnn benchmarkを比較した結果を公開しています。
PC環境
まず以下のバージョンのUbuntuをインストールしたPC環境で、クロスコンパイル環境を構築します。
Ubuntu 22.04.3 LTS(x64)
コンパイルにライブラリのインストール
コンパイルに必要なライブラリを含むパッケージをaptからインストールします
$ sudo apt install crossbuild-essential-armhf crossbuild-essential-arm64
クロスコンパイラのインストール
まず、/opt/ディレクトリの下に「external」フォルダを作成して移動します。
$ sudo mkdir /opt/external
$ sudo chmod 777 /opt/external
$ cd /opt/external
クロスコンパイラのダウンロード
UnitV2に対応しているCortex-Aファミリ用GNUツールチェインは以下のファイルとなります。これをARM社のホームページからダウンロードします。
「gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz」
ここでは、curlでツールチェインをダウンロードします。curlがインストールされてなければ、ブラウザからアクセスしてファイルをダウンロードします。
$ curl -LO https://developer.arm.com/-/media/Files/downloads/gnu-a/10.2-2020.11/binrel/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz
クロスコンパイラのインストール
ダウンロードした圧縮ファイルを解凍します。
$ tar Jxfv gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz
クロスコンパイラへのパスを通す
環境変数を編集して、binフォルダの下にあるクロスコンパイラの本体「arm-none-linux-gnueabihf-g++」、「arm-none-linux-gnueabihf-gcc」へのパスを通します。
$ gedit ~/.bashrc
.bashrcの末尾へ、以下のコマンドを追加します。異なるフォルダにインストールする場合にはご使用の環境に合わせて編集してください。
export PATH="$PATH:/opt/external/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin/"
以下のコマンドを実行して、コンパイラのバージョン情報が出れくれば、ツールチェインのインストールが完了です。
以下のコマンドを実行して、コンパイラのバージョン情報が出てれくれば、ツールチェインのインストールが完了です。
$ arm-none-linux-gnueabihf-g++ --version
arm-none-linux-gnueabihf-g++ (GNU Toolchain for the A-profile Architecture 10.2-2020.11 (arm-10.16)) 10.2.1 20201103
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ncnnのインストール
ncnnは、Tencentが開発しているモバイルプラットフォーム向けに最適化された高性能なニューラルネットワーク推論コンピューティングフレームワークです。
このシェルスクリプトで、ARMプロセッサ向けにncnnライブラリをgitからクローン、ビルド、そしてインストールします。
$ git clone https://github.com/Tencent/ncnn.git -b 20240410 --depth 1
$ cd ncnn/
ncnnのunitv2用のビルド設定ファイルを作成します。
$ gedit ./toolchains/arm-linux-gnueabihf-unitv2.toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER "arm-none-linux-gnueabihf-gcc")
set(CMAKE_CXX_COMPILER "arm-none-linux-gnueabihf-g++")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_C_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon")
set(CMAKE_CXX_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon")
# cache flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")
クロスコンパイラを使ってncnnをビルドします。
$ cmake -B build/arm_unitv2 -DCMAKE_TOOLCHAIN_FILE=./toolchains/arm-linux-gnueabihf-unitv2.toolchain.cmake -DNCNN_SIMPLEOCV=ON -DCMAKE_BUILD_TYPE=Release -DNCNN_VULKAN=OFF -DNCNN_BUILD_EXAMPLES=OFF .
$ cmake --build build/arm_unitv2 && cmake --install build/arm_unitv2 --prefix install/arm_unitv2
ncnn benckmarkのインストール
ncnnディレクトリ内でbenckmarkのファイルを整理し、それをzip圧縮します。
$ cd ncnn
$ mkdir install/arm_unitv2/benchmark
$ cp ./build/arm_unitv2/benchmark/benchncnn ./install/arm_unitv2/benchmark
$ cp ./benchmark/*.param ./install/arm_unitv2/benchmark
$ zip -r ./install/arm_unitv2/arm_unitv2_ncnn_benchmark.zip ./install/arm_unitv2/benchmark
unitv2でのベンチマークの実行
zipファイルをunitv2にscpでコピー、unitv2でncnn benchmarkを実行します。
unitv2% unzip arm_unitv2_ncnn_benchmark.zip
unitv2% cd benchmark
unitv2% ./benchncnn 4 2 0 -1 1
loop_count = 4
num_threads = 2
powersave = 0
gpu_device = -1
cooling_down = 1
squeezenet min = 207.65 max = 208.47 avg = 208.12
squeezenet_int8 min = 149.00 max = 149.16 avg = 149.10
mobilenet min = 348.22 max = 351.24 avg = 349.23
mobilenet_int8 min = 182.69 max = 182.96 avg = 182.88
mobilenet_v2 min = 254.54 max = 270.19 avg = 258.93
mobilenet_v3 min = 203.12 max = 203.81 avg = 203.37
shufflenet min = 136.41 max = 136.70 avg = 136.56
shufflenet_v2 min = 126.79 max = 152.76 avg = 133.42
mnasnet min = 242.26 max = 243.36 avg = 242.58
proxylessnasnet min = 270.56 max = 272.37 avg = 271.54
efficientnet_b0 min = 388.31 max = 389.73 avg = 388.85
efficientnetv2_b0 min = 446.40 max = 448.80 avg = 447.12
regnety_400m min = 286.05 max = 286.55 avg = 286.31
blazeface min = 36.10 max = 36.31 avg = 36.18
googlenet min = 655.90 max = 658.45 avg = 656.65
googlenet_int8 min = 424.22 max = 426.86 avg = 424.95
UnitV2でncnnをクロスコンパイルしてbenckmarkを実行することができました。
参考資料