目的
PC(Ubuntu)にクロスコンパイル環境を構築して、ディープラーニングフレームワークのncnnとベンチマークソフトウェアのbenchmarkビルドし、LicheeRV Nano
で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 pkg-config build-essential ninja-build automake autoconf libtool wget curl git gcc libssl-dev bc slib squashfs-tools android-sdk-libsparse-utils android-sdk-ext4-utils jq cmake python3-distutils tclsh scons parallel ssh-client tree python3-dev python3-pip device-tree-compiler libssl-dev ssh cpio squashfs-tools fakeroot libncurses5 flex bison
ツールチェインをダウンロードして、解凍します。
$ cd /opt/
$ sudo wget https://sophon-file.sophon.cn/sophon-prod-s3/drive/23/03/07/16/host-tools.tar.gz
$ sudo tar xvf host-tools.tar.gz
$ sudo chmod +r /opt/host-tools/
ツールチェインへのパスを通します。
$ export RISCV_ROOT_PATH="/opt/host-tools/gcc/riscv64-linux-musl-x86_64/"
以下のコマンドを実行して、コンパイラのバージョン情報が出てれくれば、ツールチェインのインストールが完了です。
$ ${RISCV_ROOT_PATH}bin/riscv64-unknown-linux-musl-g++ -v
Using built-in specs.
COLLECT_GCC=/opt/host-tools/gcc/riscv64-linux-musl-x86_64//bin/riscv64-unknown-linux-musl-g++
COLLECT_LTO_WRAPPER=/opt/host-tools/gcc/riscv64-linux-musl-x86_64/bin/../libexec/gcc/riscv64-unknown-linux-musl/10.2.0/lto-wrapper
Target: riscv64-unknown-linux-musl
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (Xuantie-900 linux-5.10.4 musl gcc Toolchain V2.6.1 B-20220906)
ncnnのインストール
ncnnは、Tencentが開発しているモバイルプラットフォーム向けに最適化された高性能なニューラルネットワーク推論コンピューティングフレームワークです。
このシェルスクリプトで、ARMプロセッサ向けにncnnライブラリをgitからクローン、ビルド、そしてインストールします。
$ git clone https://github.com/Tencent/ncnn.git -b 20240410 --depth 1
$ cd ncnn/
LicheeRV Nanoのc906用のビルド設定ファイルを作成します。
$ gedit ./toolchains/c906-v240.toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR riscv64)
set(C906 True)
if(DEFINED ENV{RISCV_ROOT_PATH})
file(TO_CMAKE_PATH $ENV{RISCV_ROOT_PATH} RISCV_ROOT_PATH)
else()
message(FATAL_ERROR "RISCV_ROOT_PATH env must be defined")
endif()
set(RISCV_ROOT_PATH ${RISCV_ROOT_PATH} CACHE STRING "root path to riscv toolchain")
set(CMAKE_C_COMPILER "${RISCV_ROOT_PATH}/bin/riscv64-unknown-linux-musl-gcc")
set(CMAKE_CXX_COMPILER "${RISCV_ROOT_PATH}/bin/riscv64-unknown-linux-musl-g++")
set(CMAKE_FIND_ROOT_PATH "${RISCV_ROOT_PATH}/riscv64-unknown-linux-gnu")
set(CMAKE_SYSROOT "${RISCV_ROOT_PATH}/sysroot")
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
endif()
set(CMAKE_C_FLAGS "-march=rv64gcv0p7_zfh_xtheadc -mabi=lp64d -mtune=c906 -DC906=1 -static")
set(CMAKE_CXX_FLAGS "-march=rv64gcv0p7_zfh_xtheadc -mabi=lp64d -mtune=c906 -DC906=1 -static")
# cache flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")
$ cmake -B build/c906 -DCMAKE_TOOLCHAIN_FILE=../toolchains/c906-v240.toolchain.cmake -DCMAKE_BUILD_TYPE=release -DNCNN_BUILD_TESTS=ON -DNCNN_OPENMP=OFF -DNCNN_THREADS=OFF -DNCNN_RUNTIME_CPU=OFF -DNCNN_RVV=ON -DNCNN_SIMPLEOCV=ON -DNCNN_BUILD_EXAMPLES=OFF .
$ cmake --build build/c906
$ cmake --install build/c906 --prefix install/c906
ncnn benckmarkのインストール
ncnnディレクトリ内でbenckmarkのファイルを整理し、それをzip圧縮します。
$ cd ncnn
$ mkdir install/c906/benchmark
$ cp ./build/c906/benchmark/benchncnn ./install/c906/benchmark
$ cp ./benchmark/*.param ./install/c906/benchmark
$ zip -r ./install/c906/riscv_c906_ncnn_benchmark.zip ./install/c906/benchmark
LicheeRV Nanoでのベンチマークの実行
zipファイルをLicheeRV Nanoにscpでコピー、LicheeRV Nanoでncnn benchmarkを実行します。
# unzip riscv_c906_ncnn_benchmark.zip
# cd benchmark
# ./benchncnn 4 1 0 -1 1
loop_count = 4
num_threads = 1
powersave = 0
gpu_device = -1
cooling_down = 1
squeezenet min = 258.75 max = 265.83 avg = 260.87
squeezenet_int8 min = 9659.92 max = 9667.19 avg = 9665.30
mobilenet min = 398.63 max = 401.00 avg = 399.75
mobilenet_int8 min = 14793.44 max = 14806.26 avg = 14798.42
mobilenet_v2 min = 297.37 max = 299.08 avg = 298.39
mobilenet_v3 min = 243.94 max = 244.84 avg = 244.30
shufflenet min = 441.43 max = 444.05 avg = 442.29
shufflenet_v2 min = 281.79 max = 282.26 avg = 281.99
mnasnet min = 298.63 max = 299.22 avg = 298.87
proxylessnasnet min = 349.01 max = 356.01 avg = 350.96
efficientnet_b0 min = 423.65 max = 431.97 avg = 426.17
efficientnetv2_b0 min = 587.97 max = 588.66 avg = 588.39
regnety_400m min = 416.59 max = 418.47 avg = 417.32
blazeface min = 133.46 max = 133.72 avg = 133.57
googlenet min = 995.92 max = 996.87 avg = 996.34
googlenet_int8 min = 21981.34 max = 22006.10 avg = 21994.08
resnet18 min = 709.38 max = 710.55 avg = 709.81
resnet18_int8 min = 22158.76 max = 22167.79 avg = 22161.85
Killed
LicheeRV Nanoでncnnをクロスコンパイルしてbenckmarkを実行することができました。
参考資料