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。

0 件のコメント:

コメントを投稿