ラベル riscv の投稿を表示しています。 すべての投稿を表示
ラベル riscv の投稿を表示しています。 すべての投稿を表示

2023年5月7日日曜日

TensorFlow Lite + XNNPACKをRISC-V Vector Extension Intrinsics を有効にしてクロスコンパイルしてみる

 目的


TensorFlow LiteをRISC-Vターゲットにクロスコンパイルしてみる。

TensorFlow Liteに組み込まれているXNNPACKは、RISC-VターゲットにRISC-V Vector Extension Intrinsicsをサポートしている。RISC-V Vector Extension IntrinsicsはGCCはバージョン13から、LLVMも14あたりからRISC-V Vector Extension Intrinsics(rvv-intrinsics)をサポートしている。

今回は、GCC 13でクロスコンパイラのツールチェインをビルドし、TensorFlow Lite + XNNPACKをrvv-intrinsicsを有効としてクロスコンパイルできることを確認する。
GCC 13で対応しているrvv-intrinsicsはv0.11である。

なお、LLVMはバージョン16でないとビルドできないようである(XNNPACKで使用されるRVVのAPI名による)。LLVMを用いたクロスコンパイルは別の機会とする。

ビルドできることまでを確認として、実機やエミュレーターによる確認は別の機会とする。


環境


ホスト
  • WSL 2のUbuntu 22.04

ツールチェイン

TensorFlow Lite + XNNPACK


ビルド


TensorFlow Lite + XNNPACKをクロスコンパイルする。
大まかな手順としては、
  1. GCC 13としたRISC-V GNU Compiler Toolchainをビルド
  2. TensorFlow Lite + XNNPACKのビルド(libtensorflow-lite.a、benchmark_model)


クロスコンパイラのビルド


RISC-V GNU Compiler Toolchainのリポジトリをcloneし、必要なパッケージをインストールする。
必要なパッケージはリポジトリのREADMEに記載されている。
$ sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build
$ mkdir ${HOME}/riscv
$ git clone https://github.com/riscv-collab/riscv-gnu-toolchain.git
$ cd riscv-gnu-toolchain

git submoduleをcloneし、GCCを13.1にbump upする。
$ git submodule update --init --recursive
$ cd gcc
$ git checkout releases/gcc-13.1.0
$ cd ..

ツールチェインをビルドする。
ビルドが成功した場合、${HOME}/riscv/toolchainにインストールされる。
$ ./configure --prefix=${HOME}/riscv/toolchain $ make linux -j$(nproc)
$ ls ${HOME}/riscv/toolchain
bin  include  lib  libexec  riscv64-unknown-linux-gnu  share  sysroot

これでRISC-Vのクロスコンパイラが用意できた。


TensorFlow Liteのビルド


次にTensorFlow Liteをビルドする。

リポジトリをcloneする。
$ cd ${HOME}/riscv
$ git clone https://github.com/tensorflow/tensorflow.git

一部ソースを修正する。
$ git diff tensorflow/lite/kernels/internal/spectrogram.cc
diff --git a/tensorflow/lite/kernels/internal/spectrogram.cc b/tensorflow/lite/kernels/internal/spectrogram.cc
index a832962a38d..3ee2d036dd4 100644
--- a/tensorflow/lite/kernels/internal/spectrogram.cc
+++ b/tensorflow/lite/kernels/internal/spectrogram.cc
@@ -17,6 +17,7 @@ limitations under the License.

 #include <assert.h>
 #include <math.h>
+#include <cstdint>

 #include "third_party/fft2d/fft.h"

修正しない場合、以下のビルドエラーが発生してしまう。
spectrogram.cc:46:22: error: 'uint32_t' was not declared in this scope
   46 | inline int Log2Floor(uint32_t n) {

あとはcmakeでconfigure後、ビルドすればよい。
(rvv-intrinsicをサポートしていないGCCの場合、XNNPACKのビルドでエラーとなってしまう)

TensorFlow Lite(libtensorflow-lite.a)のビルド
$ mkdir tflite_build && cd tflite_build
$ cmake \
    -DCMAKE_C_COMPILER=${HOME}/riscv/toolchain/bin/riscv64-unknown-linux-gnu-gcc \
    -DCMAKE_CXX_COMPILER=${HOME}/riscv/toolchain/bin/riscv64-unknown-linux-gnu-g++ \
    -DCMAKE_SYSROOT=${HOME}/riscv/toolchain/sysroot/ \
    -DCMAKE_SYSTEM_PROCESSOR="riscv64" \
    -DCMAKE_C_FLAGS="-march=rv64gcv" \
    -DCMAKE_CXX_FLAGS="-march=rv64gcv" \
    -DCMAKE_VERBOSE_MAKEFILE=ON \
    -DCMAKE_SYSTEM_NAME=Linux \
    ../tensorflow/tensorflow/lite/
$ cmake --build . -j$(nproc)
$ ls libtensorflow-lite.a
libtensorflow-lite.a

TensorFlow Lite Benchmark Tool(benchmark_model)のビルド
$ cmake --build . -j$(nproc) -t benchmark_model
$ ls tools/benchmark/benchmark_model
tools/benchmark/benchmark_model

libtensorflow-lite.a と benchmark_model がビルドできた。


最後に


Yoctoのmeta-tensorflow-liteのビルドエラーの際にXNNPACK_ENABLE_RISCV_VECTORフラグを知ってからようやく、ビルドができるようになった。
ただ、rvv-intrinsicsを有効としてみてどの程度違いがあるのかはよくわからない。
現在(2023.05時点)、個人が入手可能な利用できる実機もない気もする。。。
まずは、エミュレーターで動作確認してみる。


参考


2023年4月1日土曜日

VisionFive 2(Debian Image 202302 Released)でTensorFlow Lite EdgeTPU delegate

目的


前回のブログでは、RISC-VのSBCであるVisionFive 2でTensorFlow LiteのXNNPACK delegateを実行してみた。
今回はRISC-VのSBCであるVisionFive 2にGoogle Coral USB Acceleratorを組み合わせてTensorFlow LiteのEdgeTPU delegateを実行してみる。


環境


  • VisionFive 2 Debian Image 202302 Released
  • OpenCV 4.7.0(build from source)
  • TensorFlow Lite v2.12 Python Interpreter(build from source)
  • libedgetpu Grouper Release(build from source)


つまづきポイント


  • libedgetpuはTensorFlow Lite v2.12に未対応&プラットフォーム特有の問題がある。
    このため、Makefileを変更する。
  • Plag&Playデバイスの権限を追加しないとUSB Acceleratorにアクセス画で拒否される。
    (Debianユーザーだと当たり前の問題?)


構築


前回のブログと同様、今回はOpenCVを使ってUSBカメラのキャプチャした画像を物体検出してみる。
なお、動作させてみるPythonコードは自分のリポジトリを使用。



OpenCV、TensorFlow Lite Python Interpreterのソースビルド&インストール


ここまでは、前回のブログと同じ手順。


libedgetpuのソースビルド&インストール


Edge TPU runtime libraryのリポジトリをcloneして、Makefileでのビルドを行う。

ただ、公式のリポジトリそのままではいろいろと問題があり、ビルドできない。
  • TensorFlow Lite v2.12ではビルドエラーが発生する。
    libedgetpuはTensorFlow Lite v2.5対応でアップデートがないため。。。
    主にTensorFlow Liteのファイル、ディレクトリ構造が変更になったため。
  • ライブラリファイルが生成されない。
    オブジェクトファイルとリンクするTensorFlow Liteのライブラリの順番に問題がある。
    x86やARMのnative buildでは発生しない。RISC-V native build特有?
    ただ、リンクの順番は間違っている気がする。
  • undefined symbol: __atomic_exchange_1 が発生する。
    RISC-V native buildではlibatomicを明示的に指定(-latomic)する必要がある。
    (ちょっと前のARM native buildも同様だったのでGCCの問題?)

そこで、Makefile、ソースコードを修正することで対応する。
パッチをGitHub gistにアップしたのでそれを利用。

まずはTensorFlow Lite Python Interpreterをビルド&インストールしておく。
次にlibedgetpuのリポジトリをclone、パッチをあててビルドする。
$ sudo apt install libabsl-dev libflatbuffers-dev xxd libusb-1.0-0-dev
$ git clone https://github.com/google-coral/libedgetpu.git
$ cd libedgetpu/
$ git apply ~/visionfive2_libedgetpu_build.patch
$ cd makefile_build/
$ TFROOT=/home/user/tensorflow/ make -j$(nproc) libedgetpu
$ sudo cp ../out/direct/k8/libedgetpu.so.1 /usr/local/lib
$ cd ..
$ sudo cp debian/edgetpu-accelerator.rules /etc/udev/rules.d/99-edgetpu-accelerator.rules


SSDLite MobileDet EdgeTPUをEdge TPU Modelにエクスポート


Coralで公開されているSSDLite MobileDet EdgeTPUのEdge TPU Modelを利用する。

エクスポートしたEdge TPU ModelをボードにSCPなどで転送しておく。


USBデバイスのPlug&Playの許可


Debian Imageのユーザー(user)で操作する際、Plug&Playデバイスにアクセスする権限が不足している。
userをplugdevグループに追加しておく。
$ sudo usermod -aG plugdev $USER

権限を追加後、念の為再起動しておく。

当初、アクセス権がないことに気がつかず、次のようなエラーで困っていた。
Traceback (most recent call last):
  File "/home/user/.local/lib/python3.10/site-packages/tflite_runtime/interpreter.py", line 166, in load_delegate
    delegate = Delegate(library, options)
  File "/home/user/.local/lib/python3.10/site-packages/tflite_runtime/interpreter.py", line 104, in __init__
    raise ValueError(capture.message)
ValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/tflite-cv-example/benchmark/benchmark_tflite.py", line 107, in <module>
    main()
  File "/home/user/tflite-cv-example/benchmark/benchmark_tflite.py", line 58, in main
    interpreter = make_interpreter(args.model, args.thread, args.delegate)
  File "/home/user/tflite-cv-example/benchmark/utils/tflite_util.py", line 44, in make_interpreter
    tflite.load_delegate(EDGETPU_SHARED_LIB)
  File "/home/user/.local/lib/python3.10/site-packages/tflite_runtime/interpreter.py", line 168, in load_delegate
    raise ValueError('Failed to load delegate from {}\n{}'.format(
ValueError: Failed to load delegate from libedgetpu.so.1

そこで、以前のissueを参考にlibedgetpuのLOG_LEVELを変更、動作させた結果、USBデバイスにアクセスが拒否されていたことから権限にないことに気がついた。
I /home/user/libedgetpu/makefile_build/../driver/usb/local_usb_device.cc:60] ConvertLibUsbError: USB error -3 [OpenDevice]
I /home/user/libedgetpu/makefile_build/../driver/usb/local_usb_device.cc:1013] OpenDevice: [/sys/bus/usb/devices/2-2]
I /home/user/libedgetpu/makefile_build/../driver/usb/local_usb_device.cc:1050] OpenDevice: checking bus[2] port[2]
I /home/user/libedgetpu/makefile_build/../driver/usb/local_usb_device.cc:60] ConvertLibUsbError: USB error -3 [OpenDevice]
I /home/user/libedgetpu/makefile_build/../tflite/edgetpu_context_direct.cc:401] Failed to open device [Apex (USB)] at [/sys/bus/usb/devices/2-2]: Permission denied: USB error -3 [OpenDevice]


動作確認


前回と同様、自分のリポジトリのPythonコードを実行してみる。

Edge TPUを接続して、実行


$ cd ~
$ git clone https://github.com/NobuoTsukamoto/tflite-cv-example.git 
$ cd tflite-cv-example/detection/python
$ python3 object_detection_tflite_capture_opencv.py \
    --model /home/user/models/ssdlite_mobiledet_edgetpu_320x320_quant_coco_edgetpu.tflite \
    --label ../models/coco_labels.txt 






最後に


VisionFive 2はM.2 KeyのIFもあるから、M.2 Acceleratorを接続できればおもしろいんじゃないかな?

つぎはGPU delegate。

2023年3月30日木曜日

VisionFive 2(Debian Image 202302 Released)でTensorFlow Lite XNNPACK delegate

目的


RISC-VのSBCであるVisionFive 2でTensorFlow LiteのXNNPACK delegateを実行してみる。
RISC-V CPUでTensorFlow Lite。


環境


  • VisionFive 2 Debian Image 202302 Released
  • OpenCV 4.7.0(build from source)
  • TensorFlow Lite v2.12 Python Interpreter(build from source)


つまづきポイント


  • RISC-V CPU向けのTensorFlow Lite Python Interpreterは提供されていない。
    このため、ソースからビルド(CMakeを使う)が必要。
    ただし、バグがありビルドできないためパッチをあてて対処。


構築


今回はOpenCVを使ってUSBカメラのキャプチャした画像をEfficientDet Liteを使って物体検出してみる。
なお、動作させてみるPythonコードは自分のリポジトリを使用。



OpenCVのビルド&インストール


まず、OpenCVをソースビルドし、インストールする。
これは、自分の前回のブログを参照。


TensorFlow Lite(Python Interpreter)のビルド&インストール


TensorFlow v2.12.0でビルドを行う。
CMakeでビルドする必要があるが、r2.12ブランチではバグがありビルドできない。。。(masterブランチでは修正済みの模様)
このため、tensorflow/lite/CMakeLists.txtを修正する。
自分がやっているTensorFlow Liteのyoctoのレシピであるmeta-tensorflow-liteにあるパッチをあてて対処。


TensorFlowのリポジトリをcloneし、パッチをあてて、ビルドしてみる。
ビルドはおおよそ30分ぐらい?

$ sudo apt install swig libjpeg-dev zlib1g-dev python3-dev python3-numpy
$ sudo apt install python3-pybind11
$ sudo apt install python3-setuptools
$ sudo apt install python3-wheel
$ sudo apt install python3-pip

$ cd ~
$ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ git clone https://github.com/tensorflow/tensorflow.git
$ cd tensorflow/
$ git checkout v2.12.0
$ git apply ~/meta-tensorflow-lite/recipes-framework/tensorflow-lite/files/001-v2.12-Fix-CMAKE_Build_Error.patch

$ export BUILD_NUM_JOBS=4
$ ./tensorflow/lite/tools/pip_package/build_pip_package_with_cmake.sh
pip3 install /home/user/tensorflow/tensorflow/lite/tools/pip_package/gen/tflite_pip/python3/dist/tflite_runtime-2.12.0-cp310-cp310-linux_riscv64.whl


EfficientDet LiteをTensorFlow Lite Modelにエクスポート


モバイル向けの物体検出モデルであるEfficentDet LiteをTensorflow Liteにエクスポートする。
これはホストPC(やGoogle Colaboratory)で実行する。
以前、自分が作成したエクスポート用のノートブックを利用。
エクスポートしたモデル(今回はEfficientDet-Lite0)をボードにSCPなどで転送しておく。
今回は/home/user/modelsの配下に格納。


動作確認


USBカメラを接続して動作確認してみる。

$ cd ~
$ git clone https://github.com/NobuoTsukamoto/tflite-cv-example.git 
$ cd tflite-cv-example/detection/python
$ python3 object_detection_tflite_capture_opencv.py --model /home/user/models/efficientdet-lite0_fp32.tflite --label ../models/coco_labels.txt --thread 4

なお、コードではカメラIDを0固定で指定しているので、適宜書き換え(いつか直す)。
動作させたときの画面キャプチャ。
EfficientDet Lite0 FP32でだいたい500~600ms(4 Threads)。




最後に


今回はRISC-V CPUでTensorFlow Liteをやってみた。VisionFive 2だと割とサクサク動いて感動!(たしかにラズパイ4と比べるとだけど)。

次はEdgeTPUのアクセラレターとの組み合わせかな?

2023年3月29日水曜日

VisionFive 2(Debian Image 202302 Released)でOpenCVをビルドする

目的


RISC-VのSBCであるVisionFive 2でOpenCVをソースからビルドしてみる。


環境




つまづきポイント


  • additional packagesにあるQtは依存関係のライブラリのバージョンアップデートによりリンクエラーとなってしまうため有効としない。
  • FFmepg、GStreamerのpkgconfigのパスがおかしいためにCMakeでエラーが発生する。
    pkgconfigファイル内のパスを直接編集する。


ライブラリのインストール


OpenCVに必要(とおもわれる)ライブラリを片っ端からインストールする。

$ sudo apt -y install build-essential cmake
$ sudo apt -y install python3-numpy python3-dev python3-matplotlib
$ sudo apt -y install libeigen3-dev libgflags-dev libgoogle-glog-dev
$ sudo apt -y install libopenblas-dev gfortran
$ sudo apt -y install libopenblas-openmp-dev
$ sudo apt -y install libblas-dev libatlas-base-dev libblis-dev
$ sudo apt -y install liblapacke-dev
$ sudo apt -y install liblapack-dev
$ sudo apt -y install libgtk-3-dev
$ sudo apt -y install libhdf5-dev


FFmpeg & GStreamerのpkgconfigの修正


VisionFive 2の開発元が提供するパッケージでFFmpeg、GStreamerなどのpkgconfigファイルでライブラリのパスが誤っている。
  • ライブラリは/usr/localにインストールだが、pkgconfigでは/code_mm/targetを参照している。。。

(69-imageのころからパスを変更したようだけど、pkgconfigファイルの中身はそのままみたい)

一括でパスを置換してしまう。

$ sudo sed -i 's@/code_mm/target/usr@/usr/local@g' /usr/local/lib/pkgconfig/*.pc


OpenCVのビルド


あとはOpenCVのソースコードをダウンロードして、ビルドする。
ビルドは4〜5時間ぐらいだったかも。

$ cd
$ mkdir opencv
$ cd opencv
$ git clone -b 4.7.0 https://github.com/opencv/opencv.git
$ git clone -b 4.7.0 https://github.com/opencv/opencv_contrib.git
$ mkdir build
$ cd build
$ cmake  \
    ../opencv \
    -DOPENCV_EXTRA_MODULES_PATH=~/opencv/opencv_contrib/modules/ \
    -DOPENCV_ENABLE_NONFREE=ON \
    -DBUILD_EXAMPLES=ON \
    -DOPENCV_ENABLE_NONFREE=ON \
    -DWITH_OPENMP=ON \
    -DBUILD_EXAMPLES=ON \
    -DWITH_QT=OFF \
    -DWITH_VULKAN=ON
$ make -j3
$ sudo make install

最後に


これで色々とできるようになった。つぎはTensorFlow Liteをやってみる。


2022年7月10日日曜日

YoctoでGoogle CoralのEdgeTPU

 目的


今更ながらGoogle Coralのライブラリgoogle-coral/libedgetpuがbazelでなくてもビルドできることを知った。


なので、これをYoctoのレシピ化して見ることにした。


libedgetpuのレシピ


TensorFlow Liteをレシピ化しているmeta-tensorflow-liteに追加。


レシピ化するときにつまづいた点


すべてではないが、レシピかするときにつまずいた点、ちょっとだけ工夫した点を列挙。


ビルドのワーキングディレクトリの指定

今回、Makefileベースのレシピで作成したが、Makefileはトップディレクトリにない。
このため、${B}でMakefileがあるディレクトリを指定が必要。
ただ、Yoctoのドキュメントには

とあり、タスク[dirs]で指定して、${B}は有効でないとある。

しかしながら、タスク[dirs]で指定してもワークディレクトリは変更されなかった。。。
base.bbclassで上書き${B}で上書きされているので、${B}は必要なんじゃないのかな?
わたしの指定方法がまちがっているかもしれないが。。。


abseil-cppの必要なリンクするライブラリの不足


libedgetpuはabseil-cppのライブラリをいくつかリンクする。
Yoctoのkirkstoneにあるabseil-cppのバージョン( 20211102.0+gitX)はlibedgepuのGrouper(2021.7.27リリース)より新しい。
これが影響してか、ライブラリのリンクに不足(undefined symbol)が発生、パッチで修正した。

また、当初、Yoctoではなく、x86のubuntu22.04上でビルドしてリンク不足の修正を確認していた。その中でabseil-cppをソースビルド&スタティックリンクライブラリ(*.a)をリンクしたところ、undefined symbolが解消できないことがわかった(スタティックリンクだとabseeil-cppの一部がビルドされない?)。
Yoctoのabseil-cppのレシピは共有ライブラリ(*.so)を生成するオプションのため問題はなかったが、この違いによってハマってしまった。

libedgetpuのリポジトリにも同じようなissueがあり、解決できていなかったようなのでコメントしてみた。

gold リンカーを指定するとリンクエラー(risc-v)


RISC-V(meta-riscv)ターゲット向けにビルド時、goldリンカーはないとのエラーが発生する。
libedgetpuのMakefileでは -fuse-ld=gold が指定されている。
ARMターゲット(meta-raspberrypi)ではエラーにならないので、クロスコンパイラの違いが原因と思われる。
なので、Makefileから指定を削除した。



TensorFlow v2.9への対応


もともと、libedgetpuはTensorFlow v2.5のころのソースを一部利用している。
このなかでもcommon.cはC言語のソースだった。

TensorFlow v2.9では、common.cはcommon.ccに変更になっている。

これにあわせて、Makefileを修正している。


xxd: command not foundの解決


edgetpuのfirmwareをビルドする際にxxd(16進数のダンプコマンド)をつかっている。
このxxdコマンド、Yoctoでどのレシピを追加すればよいのかよくわからなかった、、、
OpenEmbedded Layer Indexをつかって検索してもよくわからず、、、

最終的にvim-nativeのレシピ(openembedded-core )を追加することで解決した。
(いつも使うコマンドがどんなパッケージにあるか?ってあまり意識しない時もある。こういうケースでは検索がなかなか大変。。。)


libedgetpu-maxとlibedgetpu-std


libedgetpuには動作周波数を変更する二つのライブラリが存在する。

この2つをレシピ化することにした。
方針としては以下にした。
  • レシピはlibedgetpu-std、libedgetpu-maxとする。
  • 共通部分をcommon.incに切り出して、EXTRA_OEMAKEに指定するフラグとインストールパス(do_install)を定義
  • お互いのレシピは同時に指定されたくないので、RCONFLICTSでコンフリクトするように指定。


ターゲットのBSP


今回は2つのBSPで動作させてみた。

Sipeed Lichee RV Dock向けについては、前回のブログを参照。
meta-riscvからforkしたリポジトリをつかう。

なお、Sipeed Lichee RV Dock向けについては、後述のとおり物体検出やセグメンテーションのモデルはうまく動いていない、、、


イメージの作成


いつもどおり、bitbakeしてみる。
Yoctoのバージョンはkirkstone。


Raspberry Pi 4


まずは、必要なリポジトリをclone。
$ git clone -b kirkstone git://git.yoctoproject.org/poky.git
$ git clone -b kirkstone git://git.yoctoproject.org/meta-raspberrypi
$ git clone -b kirkstone git://git.openembedded.org/meta-openembedded
$ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ source poky/oe-init-build-env rpi-build

$ bitbake-layers add-layer ../meta-openembedded/meta-oe/
$ bitbake-layers add-layer ../meta-openembedded/meta-python/
$ bitbake-layers add-layer ../meta-openembedded/meta-networking/
$ bitbake-layers add-layer ../meta-openembedded/meta-multimedia/
$ bitbake-layers add-layer ../meta-raspberrypi/
$ bitbake-layers add-layer ../meta-tensorflow-lite/

conf/auto.confに必要なパッケージを追加。
FORTRAN:forcevariable = ",fortran"
MACHINE ?= "raspberrypi4-64"
IMAGE_INSTALL:append = " \
  python3-tensorflow-lite \
  libedgetpu-max \
  opencv \
"
VIDEO_CAMERA = "1"

bitbake。
$ bitbake core-image-weston
...
Build Configuration:
BB_VERSION           = "2.0.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi4-64"
DISTRO               = "poky"
DISTRO_VERSION       = "4.0.1"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa72"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "kirkstone:4aeda14352a9fa9dd5ba50cf940a2b514fd1ac3c"
meta-oe              
meta-python          
meta-networking      
meta-multimedia      = "kirkstone:fcc7d7eae82be4c180f2e8fa3db90a8ab3be07b7"
meta-raspberrypi     = "kirkstone:0135a02ea577bd39dd552236ead2c5894d89da1d"
meta-tensorflow-lite = "main:4299e649292a9471732e1fff2dc0eb776aba68f5"
...

イメージをSDカードに書き込む。


Sipeed Lichee RV Dock


こちらも同様に必要なリポジトリをclone。
$ git clone -b kirkstone git://git.yoctoproject.org/poky.git
$ git clone -b kirkstone https://github.com/openembedded/openembedded-core.git
$ git clone -b kirkstone https://github.com/openembedded/meta-openembedded.git
$ git clone -b kirkstone_licheerv https://NobuoTsukamoto/riscv/meta-riscv.git
$ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ source poky/oe-init-build-env licheerv-build

$ bitbake-layers add-layer ../meta-openembedded/meta-oe/
$ bitbake-layers add-layer ../meta-openembedded/meta-python/
$ bitbake-layers add-layer ../meta-openembedded/meta-networking/
$ bitbake-layers add-layer ../meta-openembedded/meta-multimedia/
$ bitbake-layers add-layer ../meta-riscv/
$ bitbake-layers add-layer ../meta-tensorflow-lite/

conf/auto.confに必要なパッケージ・オプションを追加。
FORTRAN:forcevariable = ",fortran"
MACHINE ?= "licheerv"
IMAGE_INSTALL:append = " \
  python3-tensorflow-lite \
  libedgetpu-std \
  opencv \
"

bitbake。
$ bitbake core-image-minimal
...
Build Configuration:
BB_VERSION           = "2.0.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "riscv64-poky-linux"
MACHINE              = "licheerv"
DISTRO               = "poky"
DISTRO_VERSION       = "4.0.1"
TUNE_FEATURES        = "riscv64"
meta                 
meta-poky            
meta-yocto-bsp       = "kirkstone:4aeda14352a9fa9dd5ba50cf940a2b514fd1ac3c"
meta-oe              
meta-python          
meta-networking      
meta-multimedia      = "kirkstone:fcc7d7eae82be4c180f2e8fa3db90a8ab3be07b7"
meta-riscv           = "kirkstone_licheerv:9083c701acede92b2378eb3f0df77fefb8ae29a0"
meta-tensorflow-lite = "main:4299e649292a9471732e1fff2dc0eb776aba68f5"
...

イメージを書き込む。


動作確認


こちらのPythonスクリプトを使っての動作確認。
(レシピ化していないのでSDカードに直接コードとモデルをコピーした)


Raspberry Pi 4


ラズパイ向けでは正常に動作するようだ。


Sipeed Lichee RV Dock


Lichee RV Dockの場合、
  • USBの電力供給の関係で動作しないので、電源供給つきのUSB-HUBが必要。
    device descriptor read/64, error -71 が発生した場合は、電力の不足を疑う。
    (libedgetpu-stdの場合はHUBがなくてもいけるかもしれない)
  • 画像分類モデルはうまく動きそうだが、物体検出やセマンティクス・セグメンテーションのモデルはうまく動作しない。。。
    • 物体検出は結果がすべてNG。
    • セマンティクス・セグメンテーションはポツポツと点のように結果がおかしい。

2つ目の事象は現時点では解決できていない。。。
(なんだかUSBの通信の関係の気がするが、、、)
RISC-V特有でない気もしている。






最後に


ちょっと遅くなったけど、libedgetpuをYoctoのレシピにしてみた。
ラズパイ向けはうまく動いたが、LICHEE RV DOCK向けはおかしい部分がある。

RISC-VのSBCで動けば、おもしろくなってくると思う。
EdgeTPUに限らず、RISC-V+アクセラレーターの構成がEdge AIとしてはありえるんじゃないかな?

2022年7月9日土曜日

YoctoでSipeed Lichee RV Dock

 目的


前回のブログではYoctoのmeta-riscvmeta-tensorflow-liteをつかって、Sipeed Lichee RV DockでOSイメージのビルドとTensorFlow-Liteの動作確認を行った。
ただし、meta-riscvにLichee RV Dock向けの対応(DTSなど)がないためUSBは使えない。

今回は、meta-riscvをforkしてU-Bootやカーネルなどを追加してLichee RV Dock向けBSPを作成して、USBが動作するところまで確認する。


参照


もともと、meta-riscvにはnezha allwinner d1の対応が含まれている。
Yocto Project Summit 2022.05で詳細が発表されていた模様。

これをもとにlinux-sunxiの情報と、 Archlinux Image Builderの情報をもとにBSPを作成してみる。


レシピ(BSP)の作成


meta-riscvをforkして作成。

ブランチは「kirkstone_licheerv」。

コミットはこちら。

おおきくわけて
  • machine configuration
  • boot0
  • opensbi
  • u-boot
  • linux kernel
  • wis
のレシピを変更・追加している。


machine configuration


machine/nezha-allwinner-d1.conf を参考にLichee RV 向けに変更している。

machineは「licheerv」。


boot0


nezha-allwinner-d1向けのレシピに対して修正。
COMPATIBLE_MACHINEに「licheerv」を追加している。


OpenSBI


OpenSBIもnezha-allwinner-d1と同様のであるため、レシピにlicheerv向けの追加を行っているのみ。


U-Boot


こちらはlicheerv向けに作成。

U-Bootのコードはsmaeul/u-bootを利用(ブランチは「d1-wip」)。
他、uEnvやtoc.cfgはnezha-allwinner-d1と同じものを利用。


Linux kernel


こちらもsmaeul/linuxを利用(ブランチは「riscv/d1-wip」)。
defconfigはsehraf/riscv-arch-image-builderのものを利用した(スクリプトから生成)。


wis


nezha-allwinner-d1と同じものを利用。
ただし、いつも参考にしているブログにあるとおりnezha-allwinner-d1のwisではイメージのサイズが大きい(約14GB)。

なので、今回はイメージサイズを約8GB程度にした。

--fixed-size 8000の部分。


イメージ作成(Bitbake)


core-image-minimalでbitbakeしてみる。
まずは、必要なリポジトリをclone。
$ git clone -b kirkstone git://git.yoctoproject.org/poky.git
$ git clone -b kirkstone https://github.com/openembedded/openembedded-core.git
$ git clone -b kirkstone https://github.com/openembedded/meta-openembedded.git
$ git clone -b kirkstone_licheerv https://NobuoTsukamoto/riscv/meta-riscv.git
$ source poky/oe-init-build-env licheerv-build

$ bitbake-layers add-layer ../meta-openembedded/meta-oe/
$ bitbake-layers add-layer ../meta-openembedded/meta-python/
$ bitbake-layers add-layer ../meta-openembedded/meta-networking/
$ bitbake-layers add-layer ../meta-openembedded/meta-multimedia/
$ bitbake-layers add-layer ../meta-riscv/

あとは、bitbake。
MACHINE=licheerv bitbake core-image-minimal

成功したら、*.wic.gzファイルをSDカードに書き込んでブートさせてみる。


動作確認




core-image-westonもやってみる


bitbakeでcore-image-westonをビルドして動かしてみた。



最後に


今回はRISC-V SBCのSipeed Lichee RV Dock向けのBSPをmeta-riscvのnezha-allwinner-d1を参考にやってみた。


2022年6月11日土曜日

Sipeed Lichee RV DockのYoctoでTensorFlow Lite v2.9

 目的


いつも参考にさせていただいているブログでRISC-V CPUのSipeed Lichee RV DockがYoctoで動くことを知った。


meta-tensorflow-liteはいままでQEMUでしか動かしたことがなかった。
Sipeed Lichee RV Dockは案外お安いというのもあり、一つ購入して実際に動かしてみたくなった。

購入したのは
  • Sipeed Lichee RV Dock Allwinner D1 Development Board RISC-V Linux Starter Kit
    without wifi 512M


イメージの作成


Yoctoでビルドする。
  • BSPにはmeta-riscv、バージョンはkikstone。
  • TensorFlow Liteのレシピにはmeta-tensorflow-lite。
  • TensorFlow Liteのバージョンはv2.9。
    • XNNPACK delegateしたいのでkirkstoneではなくて、mainブランチを使用。
  • ほんとうはCROPSを使いたかったけど、Fedora 36のpodmanだとうまくいかなかった。

まずは、必要なリポジトリをclone。
$ git clone -b 2.0 https://github.com/openembedded/bitbake.git
$ git clone -b kirkstone https://github.com/openembedded/openembedded-core.git
$ git clone -b kirkstone https://github.com/openembedded/meta-openembedded.git
$ git clone -b kirkstone https://github.com/riscv/meta-riscv.git
$ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ cd meta-tensorflow-lite
$ git checkout a58e5f1efbf5de17580e1f9f65f70d76715003b2

oe-init-build-env
$ source openembedded-core/oe-init-build-env build

auto.confに必要な情報(MACHINEとIMAGE_INSTALL)を追加。
$ cat conf/auto.conf 
FORTRAN:forcevariable = ",fortran"
MACHINE = "nezha-allwinner-d1"
IMAGE_INSTALL:append = "\
  python3-tensorflow-lite \
  libtensorflow-lite \
  python3-tensorflow-lite-example \
  tensorflow-lite-label-image \
  tensorflow-lite-minimal \
  tensorflow-lite-benchmark \
"

後はbitbake!
$ bitbake core-image-full-cmdline

...

Build Configuration:
BB_VERSION           = "2.0.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "ubuntu-20.04"
TARGET_SYS           = "riscv64-oe-linux"
MACHINE              = "nezha-allwinner-d1"
DISTRO               = "nodistro"
DISTRO_VERSION       = "nodistro.0"
TUNE_FEATURES        = "riscv64"
meta                 = "kirkstone:4eb0b7468383a1d0314b3bfd43ea37c95de464d9"
meta-oe              
meta-python          
meta-networking      
meta-multimedia      = "kirkstone:0b78362654262145415df8211052442823b9ec9b"
meta-riscv           = "kirkstone:70e099d7ceca52a1dde2c978713012f6b20a9891"
meta-tensorflow-lite = "main:a58e5f1efbf5de17580e1f9f65f70d76715003b2"

出来上がったイメージ(tmp-glibc/deploy/images/nezha-allwinner-d1配下の*.wic.gz)をmicro sdカードに書き込む。

USBシリアル変換ケーブルを接続して、起動してみる。



補足:FORTRANの追加


meta-tensorflow-liteのレシピでTensorFlow Lite v2.9からビルド時にFortranコンパイラが必要となった模様。
おそらく、XNNPACKのビルドで必要。

YoctoではデフォルトでFortranコンパイラがないため、ビルドに失敗する。
このため、confに以下を追加する必要がある。
FORTRAN:forcevariable = ",fortran"


動作


起動した後、TensorFlow Liteが動作することを確認してみる。
meta-tensorflow-liteで追加できるサンプル・ツールは以下のとおり(kirkstone)。

TensorFlow Lite C++ image classification demo(label_image)のサンプルを動かしてみる。
# cd /usr/share/tensorflow/lite/examples/label_image/
# ./labe 
  --tflite_model ./mobilenet_v1_1.0_224.tflite \                              
  --labels ./labels.txt \                                                     
  --image ./grace_hopper.bmp \                                                
  --xnnpack_delegate 1 \                                                      
  --threads 1                                                                 
INFO: Loaded model ./mobilenet_v1_1.0_224.tflite                                
INFO: resolved reporter                                                         
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.                         
XNNPACK delegate created.                                                       
INFO: Applied XNNPACK delegate.                                                 
INFO: invoked                                                                   
INFO: average time: 3214.8 ms                                                   
INFO: 0.860175: 653 653:military uniform                                        
INFO: 0.0481016: 907 907:Windsor tie                                            
INFO: 0.00786705: 466 466:bulletproof vest                                      
INFO: 0.00644932: 514 514:cornet, horn, trumpet, trump                          
INFO: 0.0060802: 543 543:drumstick 

XNNPACK delegateしていることを確認。

なお、label_imageにはxnnpack_delegateの引数を指定するとAbortする問題がある。
このため、レシピでパッチをあてて修正している。


ベンチマーク


さて、Sipeed Lichee RV DockのRISC-V CPUで画像分類モデルのベンチマーク(推論処理時間)をやってみる。
MobileNet V1、V2、V3 Small、V3 Largeでどの程度なのかを確認する。

ベンチマークはTFLite Model Benchmark Tool with C++ Binary(benchmark_model)を使用。
詳細の結果は以下のリポジトリにアップ。

CPUの情報を確認。
# cat /proc/cpuinfo 
processor       : 0
hart            : 0
isa             : rv64imafdc
mmu             : sv39
uarch           : thead,c906

ベンチマークの結果:Inference (avg) 、単位はms。
まあ、CPUのスペックもあるし、最適化もこれからと思う(INT8は全然最適化されていなさそう?)。

Model name Input Kind Lichee RV Dock
XNNPACK delegate
Mobilenet V1 dm=1.0 224x224 FP32 2874.29
INT8 10091.20
Mobilenet V2 dm=1.0 224x224 FP32 978.40
INT8 6210.03
Mobilenet V3 Large dm=1.0 224x224 FP32 754.20
INT8 4853.66
Mobilenet V3 Small dm=1.0 224x224 FP32 241.70
INT8 1444.20

最後に


はじめて、RISC-V の実機でTensorFlow Liteを動かしてみた。

きっとRISC-V CPUベースのSoCだと、きっと、GPUやアクセラレーターを使う方が主流になるはず?CPUで推論はメインではないとは思うのだけど、かなりおもしろかった。

処理時間はラズパイなどとは比べようもないのだけど、はじめてラズパイでTensorFlow Liteを動かした時のような感覚をおもいだした気がする。

これからもRISC-Vがあつくなるといいなぁ!!

2022年2月5日土曜日

YoctoでTensorFlow Lite v2.8.0(Microchip PolarFire SoC Yocto BSP + meta-tensorflow-lite)

目的


meta-tensorflow-lite(python3-tensorflow-lite)でTensorFlow Lite v2.8.0のビルドにRISC-Vを対応する。
先日、v2.8.0がリリースされたので対応することと、こちらのissue(RISC-Vでビルドできない)であったBSPでビルド確認を行う。


Microchip PolarFire SoCって?


RISC-V CPU + FPGAのSoCのよう。
開発元はMicrochip Technology。

CPUはSiFive U54を5コア(セキュアブート用が1つとアプリケーション用が4コアとある)。
メモリはLPDDR4 2GB。

なお、私は実機を所持していない。
どれぐらいなんだろうとのぞいてみたら...リードタイム...

※2022年1月末のつぶやきなので最新の状況はチェックしてください。


環境&準備


ホスト環境および、事前にインストールするパッケージ等は前回のブログと同様。
の該当部分を参照。


リポジトリ


meta-tensorflow-liteおよび、Microchip PolarFire SoC Yocto BSPのリポジトリは以下。

meta-tensorflow-lite




meta-polarfire-soc-yocto-bsp




ビルド


さてここからはビルド。

Microchip PolarFire SoC Yocto BSPをClone、必要なリポジトリを取得する。
なお、このときのリビジョンは"02cb81741a5e1b37f89318d04ebc6b2854bfe736"である。
$ mkdir yocto-dev
$ cd yocto-dev
$ repo init -u https://github.com/polarfire-soc/meta-polarfire-soc-yocto-bsp.git -b master -m tools/manifests/riscv-yocto.xml
$ repo sync
$ repo rebase

meta-tensorflow-liteのCloneする。
v2.8.0対応のリビジョンでチェックアウトする。
$ git clone  https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ cd meta-tensorflow-lite/
$ git checkout b20bc554a30933a65648ee4557ebb48aacd4db54
$ cd ..

polarfire-soc_yocto_setup.shを実行(bitbake-layersやoe-init-build-envなど実行)。
$ . ./meta-polarfire-soc-yocto-bsp/polarfire-soc_yocto_setup.sh

meta-tensorflow-liteを追加する。
$ bitbake-layers add-layer ../meta-tensorflow-lite/

auto.confにpython3-tensorflow-liteを追加する。
$ vi conf/auto.conf
# 最終行に以下を追加
IMAGE_INSTALL:append = " python3-tensorflow-lite"

最後にbitbake!
MACHINE=qemuriscv64を指定するとエラーで怒られてしまう、、、
このため、実機向け(MACHINE=icicle-kit-es)でビルド。
$ MACHINE=icicle-kit-es bitbake mpfs-dev-cli
Loading cache: 100% |#########################################################################################################| Time: 0:00:00
Loaded 3774 entries from dependency cache.
Parsing recipes: 100% |#######################################################################################################| Time: 0:00:01
Parsing of 2437 .bb files complete (2434 cached, 3 parsed). 3777 targets, 169 skipped, 1 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.52.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "riscv64-oe-linux"
MACHINE              = "icicle-kit-es"
DISTRO               = "nodistro"
DISTRO_VERSION       = "nodistro.0"
TUNE_FEATURES        = "riscv64"
meta                 = "HEAD:63a235d86edb5ca628c8601ed06fb04da3186141"
meta-oe              
meta-python          
meta-multimedia      
meta-networking      = "HEAD:77718718cf0eec2c7119d101a353f343e2769b1b"
meta-riscv           = "HEAD:47faa008327abc388c52246b24a8a458b30b6f0d"
meta-polarfire-soc-yocto-bsp = "HEAD:02cb81741a5e1b37f89318d04ebc6b2854bfe736"
meta-tensorflow-lite = "HEAD:b20bc554a30933a65648ee4557ebb48aacd4db54"

Initialising tasks: 100% |####################################################################################################| Time: 0:00:05
Sstate summary: Wanted 1379 Local 0 Network 0 Missed 1379 Current 1506 (0% match, 52% complete)
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 6955 tasks of which 4502 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 110 seconds
NOTE: Build completion summary:
NOTE:   do_populate_sysroot: 0.0% sstate reuse(0 setscene, 106 scratch)
NOTE:   do_package_qa: 0.0% sstate reuse(0 setscene, 351 scratch)
NOTE:   do_package: 0.0% sstate reuse(0 setscene, 281 scratch)
NOTE:   do_packagedata: 0.0% sstate reuse(0 setscene, 285 scratch)
NOTE:   do_package_write_ipk: 0.0% sstate reuse(0 setscene, 351 scratch)

ビルド完了!!!(実機がないのでここまで)


その他

auto.conf、site.conf


前回のブログあたりからYoctoの設定ファイルにauto.confがあることを知った。
いままではlocal.confを変更・修正だけ。
auto.confに設定すれば上書きされるので、複数のビルドとかに便利。

と、つぶやいたところ、site.confもあるということを教えていただいた。
なんと!Interface誌でYocto関連の「MyオリジナルLinuxの作り方」を連載されていたかた!!
(ありがとうございます!!)

site.confはProxyなど共通の設定を記載できるよう。
たしかにこれは便利である。

Yoctoまだまだ知らないことがありすぎる...


ビルドエラーについて


MACHINE=qemuriscv64を指定してビルドすると以下のビルドエラーが発生する。
OpenSBIのレシピがないように見えるけど、、、
今回はここまで。
$ MACHINE=qemuriscv64 bitbake mpfs-dev-cli
Loading cache: 100% |                                                                                                        | ETA:  --:--:--
Loaded 0 entries from dependency cache.
WARNING: /work/yocto-dev/openembedded-core/meta/recipes-bsp/u-boot/u-boot_2021.07.bb: Unable to get checksum for u-boot SRC_URI entry .txt: file could not be found
WARNING: /work/yocto-dev/meta-polarfire-soc-yocto-bsp/recipes-bsp/hss/hss.bb: Unable to get checksum for hss SRC_URI entry ${HSS_PAYLOAD}.yaml: file could not be found
Parsing recipes: 100% |#######################################################################################################| Time: 0:00:30
Parsing of 2437 .bb files complete (0 cached, 2437 parsed). 3777 targets, 168 skipped, 1 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
ERROR: Nothing PROVIDES 'opensbi'. Close matches:
  opensc
  openssh
  openssl
ERROR: Required build target 'mpfs-dev-cli' has no buildable providers.
Missing or unbuildable dependency chain was: ['mpfs-dev-cli', 'opensbi']

Summary: There were 2 WARNING messages shown.
Summary: There were 2 ERROR messages shown, returning a non-zero exit code.

以上!

2022年2月3日木曜日

YoctoでTensorFlow Lite v2.7.0(SiFive Freedom Unleashed SDK + meta-tensorflow-lite)

目的


meta-tensorflow-lite(python3-tensorflow-lite)でTensorFlow Lite v2.7.0のビルドにRISC-Vを対応する。

TensorFlow Liteはv.2.7.0でビルドの方法が大きくかわった。レシピも対応したが、RISC-Vプラットフォーム向けのビルドが失敗していたので対応する。

Microchip PolarFire SoC Yocto BSPでビルドしようとしてエラーになったissueをもらったのが経緯。


(せっかく v2.4.1で対応していただいたのに壊していました...すいません...)


環境


まずは以下のBSPでビルドできるところまで確認(もともとmeta-tensorflow-liteのforkが組み込まれているため)。

なお、Microchip PolarFire SoC Yocto BSPのビルド環境はSiFive Freedom Unleashed SDKから派生している模様。

開発環境(ホスト)は以下。
  • Ubuntu 20.04

なお、実機のSoCは持っていないため、QEMUで行う。
  • qemuriscv64


準備


ホスト環境にYoctoでビルドする環境を構築する。
Yocto Project Mega-Manua - 3. Build Host Package」に加えていくつかのパッケージをイントールする。

$ apt-get install -y sudo gawk wget git diffstat unzip texinfo gcc build-essenn
tial chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutt
ils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylinn
t3 xterm python3-subunit mesa-common-dev vim locales zstd liblz4-tool pythoo
n curl


また、repoもインストール(公式のドキュメントだとパッケージインストールの手順があるのですが、なんでかインストールできなかったです...)。

$ mkdir ~/bin
$ curl https://storage.googleapis.com/git-repo-doo
wnloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
$ PATH="${HOME}/bin:${PATH}"


リポジトリ


meta-tensorflow-liteおよび、SiFive Freedom Unleashed SDKのリポジトリは以下。

なお、SiFive Freedom Unleashed SDKはmeta-tensorflow-liteのリンク、リビジョンを変更するためForkし、修正している。


meta-tensorflow-lite




SiFive Freedom Unleashed SDK



「2021.12.」ブランチをベースにmeta-tensorflow-liteのパス、リビジョンを修正している。


ビルド


上記のリポジトリをCloneする。
repoで関連するレシピやmeta-tensorflow-liteも含めてClone。

$ mkdir riscv-sifive
$ cd riscv-sifive
$ repo init -u git://github.com/NobuoTsukamoto/freedom-u-sdk -b 2021.12_tf-lite2.7 -m tools/manifests/sifive.xml
$ repo sync


ビルド環境のセットアップ。
setup.shを実行すれば、bitbake-layersやoe-init-build-envなど実行してくれる。

$ . ./freedom-u-sdk/setup.sh


あとはbitbake。qemuriscv64を指定。

$ MACHINE=qemuriscv64 bitbake demo-coreip-cli


動作確認


SiFive Freedom Unleashed SDKにはTensorFlow Liteの動作確認用のスクリプトが用意してある。bitbakeでビルドしたイメージにも組み込まれている。

QEMUを起動する。

$ MACHINE=qemuriscv64 runqemu nographic slirp
...
...
...
FreedomUSDK 2021.12.00 qemuriscv64 ttyS0

qemuriscv64 login: 

ログインユーザーはroot、パスワードはsifive
詳細は以下。

ログイン後、TensorFlow Liteのサンプルが格納されているディレクトリに移動、実行している。
# cd /usr/share/doc/python3-tensorflow-lite-demo/example
# python3 mnist.py

TensorFlow Lite v2.7.0で動いたーーーーーー!!!!




meta-tensorflow-liteの修正点


これは、v2.7.0でのレシピ修正の概要。忘れないようにメモ。


シンタックスの変更


いままで
    SRC_URI_append_riscv64
のように _(ハイフン)でシンタックスを記載していたが古い記載だったようだ。   

このため、新しいシンタックスに変更した。
  SRC_URI:append:riscv64


ダウンロードURLの変更


TensorFlow LiteのCMakeがCloneするthird partyリポジトリのURLを変更。
git cloneする際、"https://〜"のURLではダウンロードできない(Yoctoの仕組み)。
"git://〜"とする必要がある。


tensorflow/tensorflow/lite/tools/cmake/modules配下にあるcmakeのURLを変更してパッチとしておく。

ただ、gitlabからcloneするeigne、submoduleもcloneが必要なruyはもう一工夫が必要。
  • eigneはgitlabからはGit Fetcherでcloneができなかったため、リビジョン指定のアーカイブのダウンロード(curl経由)に変更。
  • ruyは現状有効としないため、本体だけcurl経由でリビジョン指定のアーカイブをダウンロードする。submoduleはダウンロードしない。
    aarch64はXNNPACKが有効、aarch32はruyは公式もOFFなので...(力技)

ただ、腑に落ちないのはmeta-raspberrypiでビルドするとき(poky)はダウンロードでエラーにならない...
なにが違うんだっけ???


libatomicの追加


リンクライブラリにlibatomicを追加する。
でないと、ビルドは成功するがtflite_runtimeのロード時にエラーが発生する。

/usr/lib/python3.10/site-packages/tflite_runtime/_pywrap_tensorflow_interpreter_wrapper.so: undefined symbol: __atomic_compare_exchange_1

RISC-Vプラットフォームではlibatomicを明示的にリンクしないとだめのようだ。
以前もパッチをもらっていたが、今回のCMakeの対応で漏れてしまった(すいません)。


simple_memory_arena_debug_dump.ccのコンパイルエラー対応


GCC11だと、ヘッダの変更に伴いコンパイルエラーが発生する。

error: 'numeric_limits' is not a member of 'std'

これはよく当たる問題。以下の対応を参考。
ヘッダを追加するパッチを作成。


DTFLITE_ENABLE_XNNPACKはOFF


google/XNNPACKのリポジトリにはサポートアーキテクチャに「RISC-V」がある。
なので、riscv64のビルド時にXNNPACK=ONでビルドしたところ、ビルドエラーとなってしまった。
v2.7の時点ではRISC-Vは対応していないリビジョンの模様。
(つぶやいたら中の人から反応があった!)



次回以降、riscv64でXNNPACK=ONとしてみる。


最後に


issueをきっかけにv2.7.0をRISC-Vで動作するところまで確認した。
やっぱり、実機で動かしてみたいよね。
とくにXNNPACK=ONにしたらどうなるのかね?

2020年2月2日日曜日

TensorFlow Lite for microのHello worldサンプルをM5StickVで動かす(その2)

前回


前回のブログでは、TensorFlow Lite for microのサンプル(Hello world)をM5StickV向けにビルド、動作させるところまでを書いた。出力はコンソール出力だけで、M5StickVのLCDには何も表示しない。


目的


今回は、M5StickVのLCDに表示を行うところをメインにする。
こんな感じである。




参考



LCDに表示するまでの道のり


LCDに表示するにはHWの制御がかなり必要である。自前でやるのもよいが、今回はsipeedが提供するMaixPyに含まれるライブラリを使用することにする。

前回のプロジェクトに追加・変更する方針とする。




sipeed / MaixPyのMaixPyのSDK


もともと、Micropython 用の環境であるが、SDKと利用して独自のcプロジェクトをビルドすることができる。


ただ、C++はビルドできないため、SDKのみを利用することにした。

components配下のSDKの部分を利用する。以下のフォルダを利用した。
  • boards
  • drivers
  • kendryte_sdk
  • utils


sipeed/MaixPyのSDKをプロジェクトに追加


プロジェクトに追加する。


sipeed/MaixPyのSDKをC++から呼び出せるように変更


sipeed/MaixPyのSDKはC++から呼び出すことを考慮していない箇所が多数ある。このため、使用する部分のヘッダを変更する。

extern "C" の追加し、呼び出し可能とする。

今回は以下のヘッダを修正。

TensorFlow lite for microのソース変更


以下の処理を追加する。
  • main.ccでLCDを含むHWの初期化
  • output_handler.ccで描画の更新


HWの初期化


src/micro/tensorflow/tensorflow/lite/micro/examples/hello_world/main.ccで行う。
  • HWの初期化を行う。
    m5stick_init()
    (BUTTON B長押しの電源OFFもできるようになったりする)
  • setup_lcd()でLCD初期化を行う。

man.ccはこのような感じになる。



出力値に応じた点の描画


src/micro/tensorflow/tensorflow/lite/micro/examples/hello_world/output_handler.ccで行う。

STM32F746の実装を参考。LCD出力用の関数をsipeed/MaixPyのSDKを使用する。ただ、元の実装では円を描画しているが、sipeed/MaixPyのSDKには用意されていない。今回は矩形描画で代替えした。

使用した関数は以下。
  • lcd_get_width ... LCDの幅を取得
  • lcd_get_height ... LCDの高さを取得
  • lcd_clear ... LCDのクリア
  • lcd_fill_rectangle ... 矩形を描画

output_handler.ccはこのような感じになる。


最後に


前回、今回とM5StickVでTensorFlow Lite for microのサンプルをビルドするやり方を記載した。M5StickVには6軸センサやカメラがあるので、他のサンプルも行けると思うのでチャレンジしてみたい。