目的
meta-tensorflowliteをv2.8対応+公式サンプルとベンチマークツールのレシピを追加した。
これを使ってmeta-riscvでbitbakeする。qemuriscv64でTensorFlow Liteのサンプル、ベンチマークツールを動作させてみる。
meta-tensorflow-liteにtensorflow liteのbenchmark_modelのレシピを追加。これでいろいろとできるようになった(と思う)。
— nb.o (@Nextremer_nb_o) February 24, 2022
さて、Kirkstoneに向けてやってみよう。https://t.co/nW38OdO5KQ
meta-tensorflowliteの対応
meta-tensorflowliteのリポジトリは以下。
今回、TensorFlow Lite v2.8の対応を含めてレシピの整理・追加を行った。
- ブランチをYoctoバージョンと合わせて管理。
- 今後はTensorFlow Liteのバージョンもブランチで固定。
- Python3 interpreterのレシピのv2.8対応。
- RISC-Vのビルドは以前から対応済み。
- C++ API shared library(libtensorflowflow-lite)のレシピのv2.8対応。
- レシピ名をcpp-tensorflow-liteからlibtensorflow-liteに変更。
- インストール時、ヘッダファイルの不足があったので修正。
-
TensorFlowのリポジトリにあるPython、C++のサンプルをレシピ化&簡単なドキュメントを整理。
(リンクはmeta-tensorflow-liteのドキュメントのリンク) -
python3-tensorflow-lite-example
TensorFlow Lite Python image classification demo -
tensorflow-lite-label-image
TensorFlow Lite C++ image classification demo -
tensorflow-lite-minimal
TensorFlow Lite C++ minimal example - 同じように、ベンチマークツール(benchmark_model)もレシピ化。
-
tensorflow-lite-benchmark
TFLite Model Benchmark Tool with C++ Binary -
GitHub Actionsを導入して、コードの変更&週一でのビルドのCIを導入。
リポジトリのClone
さて、ここからは実際にビルドしてみる。まずは必要なリポジトリをclone。
- Yoctoのバージョンはhonisterとする。
-
meta-tensorflow-liteはcommit idを指定(このあとkirkstoneに移行予定)。
$ git clone -b 1.52 https://github.com/openembedded/bitbake.git $ git clone -b honister https://github.com/openembedded/openembedded-core.git $ git clone -b honister https://github.com/openembedded/meta-openembedded.git $ git clone -b honister https://github.com/riscv/meta-riscv.git $ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git $ cd meta-tensorflow-lite $ git checkout eae1cb93a12fcb1ade71197b99111c2f02f515ef $ cd ..
ビルド環境の設定
ここではmeta-riscvのsetup.shを実行する。
$ . ./meta-riscv/setup.sh
その後、meta-tensorflow-liteを追加。
$ bitbake-layers add-layer ../meta-tensorflow-lite/
conf/auto.confを編集。2行追加する。
-
USER_CLASSES:remove =
"image-prelink" を指定しないとbitbakeでエラーとなる。
これは、setup.shで追加されちゃうので... - IMAGE_INSTALL:appendでtensorflow-liteのレシピを追加。
USER_CLASSES:remove = "image-prelink" IMAGE_INSTALL:append = " python3-tensorflow-lite \ libtensorflow-lite \ python3-tensorflow-lite-example \ tensorflow-lite-label-image \ tensorflow-lite-minimal \ tensorflow-lite-benchmark"
bitbake
bitbake!!!!!!
$ MACHINE=qemuriscv64 bitbake core-image-full-cmdline
このときの結果はこんな感じ。
$ MACHINE=qemuriscv64 bitbake core-image-full-cmdline Loading cache: 100% | | ETA: --:--:-- Loaded 0 entries from dependency cache. Parsing recipes: 100% |#######################################################################################################################################################################################################| Time: 0:00:36 Parsing of 2428 .bb files complete (0 cached, 2428 parsed). 3767 targets, 165 skipped, 0 masked, 0 errors. NOTE: Resolving any missing task queue dependencies Build Configuration: BB_VERSION = "1.52.0" BUILD_SYS = "x86_64-linux" NATIVELSBSTRING = "fedora-35" TARGET_SYS = "riscv64-oe-linux" MACHINE = "qemuriscv64" DISTRO = "nodistro" DISTRO_VERSION = "nodistro.0" TUNE_FEATURES = "riscv64" meta = "honister:eeae63c343c8ebd418679915ee20aa8c02fa0fdc" meta-oe meta-python meta-multimedia meta-networking = "honister:0fb490a08ce30b47a5ccd2fdc3448b08e0d9e4e9" meta-riscv = "honister:9561639c61663a10d8c9c23d26173db499f4c39b" meta-tensorflow-lite = "main:eae1cb93a12fcb1ade71197b99111c2f02f515ef" NOTE: Fetching uninative binary shim http://downloads.yoctoproject.org/releases/uninative/3.5/x86_64-nativesdk-libc-3.5.tar.xz;sha256sum=e8047a5748e6f266165da141eb6d08b23674f30e477b0e5505b6403d50fbc4b2 (will check PREMIRRORS first) Initialising tasks: 100% |####################################################################################################################################################################################################| Time: 0:00:05 Sstate summary: Wanted 1403 Local 0 Network 0 Missed 1403 Current 0 (0% match, 0% complete) NOTE: Executing Tasks WARNING: mtools-native-4.0.35-r0 do_fetch: Failed to fetch URL https://ftp.gnu.org/gnu/mtools/mtools-4.0.35.tar.bz2, attempting MIRRORS if available NOTE: Tasks Summary: Attempted 4090 tasks of which 0 didn't need to be rerun and all succeeded. NOTE: Writing buildhistory NOTE: Writing buildhistory took: 79 seconds NOTE: Build completion summary: NOTE: do_populate_sysroot: 0.0% sstate reuse(0 setscene, 267 scratch) NOTE: do_package_qa: 0.0% sstate reuse(0 setscene, 192 scratch) NOTE: do_package: 0.0% sstate reuse(0 setscene, 192 scratch) NOTE: do_packagedata: 0.0% sstate reuse(0 setscene, 192 scratch) NOTE: do_package_write_ipk: 0.0% sstate reuse(0 setscene, 192 scratch) NOTE: do_populate_lic: 0.0% sstate reuse(0 setscene, 360 scratch) Summary: There was 1 WARNING message shown.
QEMUの実行
qemuを実行。
$ MACHINE=qemuriscv64 runqemu nographic
qemuriscv64が動いた!
OpenSBI v0.9 ____ _____ ____ _____ / __ \ / ____| _ \_ _| | | | |_ __ ___ _ __ | (___ | |_) || | | | | | '_ \ / _ \ '_ \ \___ \| _ < | | | |__| | |_) | __/ | | |____) | |_) || |_ \____/| .__/ \___|_| |_|_____/|____/_____| | | |_| Platform Name : riscv-virtio,qemu Platform Features : timer,mfdeleg Platform HART Count : 4 Firmware Base : 0x80000000 Firmware Size : 124 KB Runtime SBI Version : 0.2 Domain0 Name : root Domain0 Boot HART : 0 Domain0 HARTs : 0*,1*,2*,3* Domain0 Region00 : 0x0000000080000000-0x000000008001ffff () Domain0 Region01 : 0x0000000000000000-0xffffffffffffffff (R,W,X) Domain0 Next Address : 0x0000000080200000 Domain0 Next Arg1 : 0x0000000082200000 Domain0 Next Mode : S-mode Domain0 SysReset : yes Boot HART ID : 0 Boot HART Domain : root Boot HART ISA : rv64imafdcsu Boot HART Features : scounteren,mcounteren,time Boot HART PMP Count : 16 Boot HART PMP Granularity : 4 Boot HART PMP Address Bits: 54 Boot HART MHPM Count : 0 Boot HART MHPM Count : 0 Boot HART MIDELEG : 0x0000000000000222 Boot HART MEDELEG : 0x000000000000b109 [ 0.000000] Linux version 5.14.21-yocto-standard (oe-user@oe-host) (riscv64-oe-linux-gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.37.20210721) #1 SMP PREEMPT Wed Mar 2 12:59:31 UTC 2022 [ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000 [ 0.000000] Machine model: riscv-virtio,qemu [ 0.000000] Memory limited to 256MB [ 0.000000] efi: UEFI not found. [ 0.000000] Zone ranges: [ 0.000000] DMA32 [mem 0x0000000080200000-0x000000008fffffff] [ 0.000000] Normal empty [ 0.000000] Movable zone start for each node [ 0.000000] Early memory node ranges [ 0.000000] node 0: [mem 0x0000000080200000-0x000000008fffffff] [ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x000000008fffffff] [ 0.000000] SBI specification v0.2 detected [ 0.000000] SBI implementation ID=0x1 Version=0x9 [ 0.000000] SBI TIME extension detected [ 0.000000] SBI IPI extension detected [ 0.000000] SBI RFENCE extension detected [ 0.000000] SBI v0.2 HSM extension detected [ 0.000000] riscv: ISA extensions acdfimsu [ 0.000000] riscv: ELF capabilities acdfim
rootでログイン。
OpenEmbedded nodistro.0 qemuriscv64 ttyS0 qemuriscv64 login: root root@qemuriscv64:~#
TensorFlow Liteのサンプル&ツールの実行
実際にビルドしたTensorFlow Liteのサンプル&ツールを実行する。
python3-tensorflow-lite-example
Pythonのサンプル(label_image.py)。
TensorFlow Liteで動作するようにimportするパッケージ名を修正している。
テスト用のモデル、画像も公式と同じもの(mobilenet_v1_1.0_224.tflite &
grace_hopper.bmp)をインストールするようレシピ化している。
# cd /usr/share/tensorflow/lite/examples/python/ # python3 label_image.py \ --image ./grace_hopper.bmp \ --model_file ./mobilenet_v1_1.0_224.tflite \ --label_file ./labels.txt
しばらくすると、結果が出力される。
0.919720: 653:military uniform 0.017762: 907:Windsor tie 0.007507: 668:mortarboard 0.005419: 466:bulletproof vest 0.003828: 458:bow tie, bow-tie, bowtie time: 4925.118ms
Top1スコアは公式結果と同様の「military uniform」。
(スコアの値が違うのは...XNNPACKと何か違うんだっけ?)
tensorflow-lite-label-image
C++のサンプル(label_image)。
こちらはlibtensorflow-liteのレシピでビルドした共有ライブラリ(libtensorflow-lite.so)をリンクするように変更。
テスト用のモデル、画像も公式と同じものを用意。
# cd /usr/share/tensorflow/lite/examples/label_image/ # ./label_image \ --tflite_model ./mobilenet_v1_1.0_224.tflite \ --labels ./labels.txt \ --image ./grace_hopper.bmp
こちらもしばらくすると結果が表示される。
INFO: Loaded model ./mobilenet_v1_1.0_224.tflite INFO: resolved reporter INFO: invoked INFO: average time: 2973.11 ms INFO: 0.860174: 653 653:military uniform INFO: 0.0481021: 907 907:Windsor tie INFO: 0.00786705: 466 466:bulletproof vest INFO: 0.00644936: 514 514:cornet, horn, trumpet, trump INFO: 0.00608029: 543 543:drumstick
スコアは一応、公式と一致。
tensorflow-lite-minimal
こちらもC++のサンプル(minimal)。
tensorflow-lite-label-imageと同じ。
# cd /usr/share/tensorflow/lite/examples/minimal/ # ./minimal ./mobilenet_v1_1.0_224.tflite
結果の表示(出力が多いので一部割愛)。
=== Pre-invoke Interpreter State === Interpreter has 1 subgraphs. -----------Subgraph-0 has 103 tensors and 31 nodes------------ 1 Inputs: [87] -> 602112B (0.57MB) 1 Outputs: [86] -> 4004B (0.00MB) Tensor ID Name Type AllocType Size (Bytes/MB) Shape MemAddr-Offset Tensor 0 MobilenetV1/Conv2d_0/w... kTfLiteFloat32 kTfLiteMmapRo 3456 / 0.00 [32,3,3,3] [16842720, 16846176) Tensor 1 MobilenetV1/Conv2d_10_... kTfLiteFloat32 kTfLiteMmapRo 18432 / 0.02 [1,3,3,512] [6423008, 6441440) Tensor 2 MobilenetV1/Conv2d_10_... kTfLiteFloat32 kTfLiteMmapRo 1048576 / 1.00 [512,1,1,512] [10624920, 11673496) ... Execution plan as the list of 31 nodes invoked in-order: [0-30] --------------Subgraph-0 dump has completed--------------
tensorflow-lite-benchmark
ベンチマークツールのbenchmark_model。
このツールは必須ですね!!
libtensorflow-liteのレシピでビルドした共有ライブラリをリンクするようにしたかったけど、色々と無理があったので、単体でビルドするようにした。
# cd /usr/share/tensorflow/lite/tools/benchmark/ # ./benchmark_model \ --graph=./mobilenet_v1_1.0_224.tflite \ --num_threads=4 \ --enable_op_profiling=true
こちらも結果は一部省略。
STARTING! Log parameter values verbosely: [0] Num threads: [4] Graph: [./mobilenet_v1_1.0_224.tflite] Enable op profiling: [1] #threads used for CPU inference: [4] Loaded model ./mobilenet_v1_1.0_224.tflite The input model file size (MB): 16.9008 Initialized session in 83.064ms. Running benchmark for at least 1 iterations and at least 0.5 seconds but terminate if exceeding 150 seconds. count=1 curr=3470145 ... Number of nodes executed: 31 ============================== Summary by node type ============================== [Node type] [count] [avg ms] [avg %] [cdf %] [mem KB] [times called] CONV_2D 15 2554.810 89.801% 89.801% 0.000 15 DEPTHWISE_CONV_2D 13 289.070 10.161% 99.962% 0.000 13 AVERAGE_POOL_2D 1 0.846 0.030% 99.991% 0.000 1 SOFTMAX 1 0.226 0.008% 99.999% 0.000 1 SQUEEZE 1 0.019 0.001% 100.000% 0.000 1 Timings (microseconds): count=50 first=2936299 curr=2869577 min=2657264 max=3069766 avg=2.84499e+06 std=82794 Memory (bytes): count=0 31 nodes observed
最後に
2022年4月にはYoctoの次のバージョン(kirkstone)がリリースされる。
ようやくmeta-tensorflow-liteのレシピの追加・整理も終わってkirkstoneへの準備ができる状態になった。
また、TensorFlow LiteはXNNPACKがRISC-Vアーキテクチャをサポートしたみたい。
次のv2.9のリリースでは取り込まれると思われる。
meta-tensorflow-liteもRISC-VでXNNPACKを有効にできるようにしたい。
RISC-V CPUでTensorFlow Liteが動くと楽しくなってくるね。