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月2日日曜日

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

目的


RISC-VのSBCであるVisionFive 2でTensorFlow LiteのGPU delegate(OpenCL backend)を実行してみる。
VisionFive 2のGPUはImagination TechnologiesのIMG BXE-4-32 MC1。
OpenCL 3.0対応でVisionFive 2にライブラリも提供されている。
なので、TensorFlow Lite GPU delegateをやってみる。


環境


  • VisionFive 2 Debian Image 202302 Released
  • OpenCV 4.7.0(build from source)
  • TensorFlow Lite v2.12 C++ Library(build from source)


つまづきポイント


  • TensorFlow Lite C++ LibraryをCMakeでビルドする。
    バグがありビルドできないためパッチをあてて対処。
  • userだと権限によりOpenCLが利用できない。
    render groupに追加する必要あり。


構築


前回、前々回のブログと同様、今回はOpenCVを使ってUSBカメラのキャプチャした画像を物体検出してみる。
OpenCL delegateなのでTensorFlow Lite C++ Libraryを使う必要がある。
C++のサンプルを自分のリポジトリに用意。



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


前々回のブログと同じ手順。


OpenCLのテスト


userをrender groupに追加、一応、再起動してみる。
$ sudo adduser $USER render

clinfoをインストール、情報を確認。
$ clinfo
Number of platforms                               1
  Platform Name                                   PowerVR
  Platform Vendor                                 Imagination Technologies
  Platform Version                                OpenCL 3.0
  Platform Profile                                EMBEDDED_PROFILE
  Platform Extensions                             cl_khr_icd cl_khr_fp16 cl_img_spirv cles_khr_int64 cl_img_yuv_image cl_khr_device_uuid cl_khr_depth_images cl_khr_mipmap_image cl_khr_priority_hints cl_img_generate_mipmap cl_khr_3d_image_writes cl_img_cached_allocations cl_khr_mipmap_image_writes cl_khr_create_command_queue cl_khr_suggested_local_work_size cl_img_mem_properties cl_img_mem_properties_relax_alloc_requirements cl_khr_extended_versioning cl_khr_image2d_from_buffer cl_khr_byte_addressable_store cl_khr_local_int32_base_atomics cl_khr_global_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_global_int32_extended_atomics cl_khr_spir cl_khr_il_program cl_khr_egl_image cl_arm_import_memory cl_arm_import_memory_dma_buf cl_img_protected_content cl_img_semaphore cl_img_external_semaphore cl_img_external_semaphore_sync_fd cl_khr_semaphore cl_khr_external_semaphore cl_khr_external_semaphore_sync_fd
  Platform Extensions with Version                cl_khr_icd                                                       0x400000 (1.0.0)
                                                  cl_khr_fp16                                                      0x400000 (1.0.0)
                                                  cl_img_spirv                                                     0x400000 (1.0.0)
                                                  cles_khr_int64                                                   0x400000 (1.0.0)
                                                  cl_img_yuv_image                                                 0x400000 (1.0.0)
                                                  cl_khr_device_uuid                                               0x400000 (1.0.0)
                                                  cl_khr_depth_images                                              0x400000 (1.0.0)
                                                  cl_khr_mipmap_image                                              0x400000 (1.0.0)
                                                  cl_khr_priority_hints                                            0x400000 (1.0.0)
                                                  cl_img_generate_mipmap                                           0x400000 (1.0.0)
                                                  cl_khr_3d_image_writes                                           0x400000 (1.0.0)
                                                  cl_img_cached_allocations                                        0x400000 (1.0.0)
                                                  cl_khr_mipmap_image_writes                                       0x400000 (1.0.0)
                                                  cl_khr_create_command_queue                                      0x400000 (1.0.0)
                                                  cl_khr_suggested_local_work_size                                 0x400000 (1.0.0)
                                                  cl_img_mem_properties                                            0x400000 (1.0.0)
                                                  cl_img_mem_properties_relax_alloc_requirements                   0x400000 (1.0.0)
                                                  cl_khr_extended_versioning                                       0x400000 (1.0.0)
                                                  cl_khr_image2d_from_buffer                                       0x400000 (1.0.0)
                                                  cl_khr_byte_addressable_store                                    0x400000 (1.0.0)
                                                  cl_khr_local_int32_base_atomics                                  0x400000 (1.0.0)
                                                  cl_khr_global_int32_base_atomics                                 0x400000 (1.0.0)
                                                  cl_khr_local_int32_extended_atomics                              0x400000 (1.0.0)
                                                  cl_khr_global_int32_extended_atomics                             0x400000 (1.0.0)
                                                  cl_khr_spir                                                      0x400000 (1.0.0)
                                                  cl_khr_il_program                                                0x400000 (1.0.0)
                                                  cl_khr_egl_image                                                 0x400000 (1.0.0)
                                                  cl_arm_import_memory                                             0x400000 (1.0.0)
                                                  cl_arm_import_memory_dma_buf                                     0x400000 (1.0.0)
                                                  cl_img_protected_content                                         0x400000 (1.0.0)
                                                  cl_img_semaphore                                                 0x400000 (1.0.0)
                                                  cl_img_external_semaphore                                        0x400000 (1.0.0)
                                                  cl_img_external_semaphore_sync_fd                                0x400000 (1.0.0)
                                                  cl_khr_semaphore                                                 0x400000 (1.0.0)
                                                  cl_khr_external_semaphore                                        0x400000 (1.0.0)
                                                  cl_khr_external_semaphore_sync_fd                                0x400000 (1.0.0)
  Platform Numeric Version                        0xc00000 (3.0.0)
  Platform Extensions function suffix             IMG
  Platform Host timer resolution                  0ns

  Platform Name                                   PowerVR
Number of devices                                 1
  Device Name                                     PowerVR B-Series BXE-4-32
  Device Vendor                                   Imagination Technologies
  Device Vendor ID                                0x1010
  Device Version                                  OpenCL 3.0
  Device UUID                                     33362035-3020-3534-2031-383200000000
  Driver UUID                                     36323130-3836-3600-0000-000000000000
  Valid Device LUID                               No
  Device LUID                                     0000-000000000000
  Device Node Mask                                0
  Device Numeric Version                          0xc00000 (3.0.0)
  Driver Version                                  1.17@6210866
  Device OpenCL C Version                         OpenCL C 1.2
  Device OpenCL C all versions                    OpenCL C                                                         0x400000 (1.0.0)
                                                  OpenCL C                                                         0x401000 (1.1.0)
                                                  OpenCL C                                                         0x402000 (1.2.0)
                                                  OpenCL C                                                         0xc00000 (3.0.0)
  Device OpenCL C features                        __opencl_c_int64                                                 0x400000 (1.0.0)
                                                  __opencl_c_pipes                                                 0xc00000 (3.0.0)
                                                  __opencl_c_images                                                0x400000 (1.0.0)
                                                  __opencl_c_subgroups                                             0xc00000 (3.0.0)
                                                  __opencl_c_3d_image_writes                                       0x400000 (1.0.0)
                                                  __opencl_c_read_write_images                                     0x400000 (1.0.0)
                                                  __opencl_c_generic_address_space                                 0xc00000 (3.0.0)
                                                  __opencl_c_program_scope_global_variables                        0xc00000 (3.0.0)
                                                  __opencl_c_work_group_collective_functions                       0xc00000 (3.0.0)
  Latest comfornace test passed                   v2021-10-04-00
  Device Type                                     GPU
  Device Profile                                  EMBEDDED_PROFILE
  Device Available                                Yes
  Compiler Available                              Yes
  Linker Available                                Yes
  Max compute units                               1
  Max clock frequency                             594MHz
  Device Partition                                (core)
    Max number of sub-devices                     1
    Supported partition types                     None
    Supported affinity domains                    (n/a)
  Max work item dimensions                        3
  Max work item sizes                             512x512x512
  Max work group size                             512
  Preferred work group size multiple (device)     32
  Preferred work group size multiple (kernel)     32
  Max sub-groups per work group                   512
  Preferred / native vector sizes
    char                                                16 / 1
    short                                                8 / 1
    int                                                  4 / 1
    long                                                 2 / 1
    half                                                 0 / 0        (cl_khr_fp16)
    float                                                4 / 1
    double                                               0 / 0        (n/a)
  Half-precision Floating-point support           (cl_khr_fp16)
    Denormals                                     No
    Infinity and NANs                             Yes
    Round to nearest                              Yes
    Round to zero                                 No
    Round to infinity                             No
    IEEE754-2008 fused multiply-add               Yes
    Support is emulated in software               No
  Single-precision Floating-point support         (core)
    Denormals                                     No
    Infinity and NANs                             Yes
    Round to nearest                              Yes
    Round to zero                                 No
    Round to infinity                             No
    IEEE754-2008 fused multiply-add               Yes
    Support is emulated in software               No
    Correctly-rounded divide and sqrt operations  No
  Double-precision Floating-point support         (n/a)
  Address bits                                    64, Little-Endian
  Global memory size                              4082995200 (3.803GiB)
  Error Correction support                        No
  Max memory allocation                           1020748800 (973.5MiB)
  Unified memory for Host and Device              Yes
  Shared Virtual Memory (SVM) capabilities        (core)
    Coarse-grained buffer sharing                 Yes
    Fine-grained buffer sharing                   No
    Fine-grained system sharing                   No
    Atomics                                       No
  Minimum alignment for any data type             128 bytes
  Alignment of base address                       1024 bits (128 bytes)
  Preferred alignment for atomics
    SVM                                           0 bytes
    Global                                        0 bytes
    Local                                         0 bytes
  Atomic memory capabilities                      relaxed, work-group scope
  Atomic fence capabilities                       relaxed, acquire/release, work-group scope
  Max size for global variable                    16384 (16KiB)
  Preferred total size of global vars             0
  Global Memory cache type                        Read/Write
  Global Memory cache size                        16384 (16KiB)
  Global Memory cache line size                   64 bytes
  Image support                                   Yes
    Max number of samplers per kernel             16
    Max size for 1D images from buffer            16384 pixels
    Max 1D or 2D image array size                 2048 images
    Base address alignment for 2D image buffers   64 bytes
    Pitch alignment for 2D image buffers          64 pixels
    Max 2D image size                             16384x16384 pixels
    Max 3D image size                             16384x16384x2048 pixels
    Max number of read image args                 8
    Max number of write image args                64
    Max number of read/write image args           64
  Pipe support                                    Yes
  Max number of pipe args                         16
  Max active pipe reservations                    1
  Max pipe packet size                            1024
  Local memory type                               Local
  Local memory size                               4096 (4KiB)
  Max number of constant args                     256
  Max constant buffer size                        1020748800 (973.5MiB)
  Generic address space support                   Yes
  Max size of kernel argument                     1024
  Queue properties (on host)
    Out-of-order execution                        Yes
    Profiling                                     Yes
  Device enqueue capabilities                     (n/a)
  Queue properties (on device)
    Out-of-order execution                        No
    Profiling                                     No
    Preferred size                                0
    Max size                                      0
  Max queues on device                            0
  Max events on device                            0
  Prefer user sync for interop                    Yes
  Profiling timer resolution                      1000ns
  Execution capabilities
    Run OpenCL kernels                            Yes
    Run native kernels                            Yes
    Non-uniform work-groups                       Yes
    Work-group collective functions               Yes
    Sub-group independent forward progress        No
    IL version                                    SPIR-V_1.2
    ILs with version                              SPIR-V                                                           0x402000 (1.2.0)
    SPIR versions                                 1.2
  printf() buffer size                            65536 (64KiB)
  Built-in kernels                                (n/a)
  Built-in kernels with version                   (n/a)
  Device Extensions                               cl_khr_icd cl_khr_fp16 cl_img_spirv cles_khr_int64 cl_img_yuv_image cl_khr_device_uuid cl_khr_depth_images cl_khr_mipmap_image cl_khr_priority_hints cl_img_generate_mipmap cl_khr_3d_image_writes cl_img_cached_allocations cl_khr_mipmap_image_writes cl_khr_create_command_queue cl_khr_suggested_local_work_size cl_img_mem_properties cl_img_mem_properties_relax_alloc_requirements cl_khr_extended_versioning cl_khr_image2d_from_buffer cl_khr_byte_addressable_store cl_khr_local_int32_base_atomics cl_khr_global_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_global_int32_extended_atomics cl_khr_spir cl_khr_il_program cl_khr_egl_image cl_arm_import_memory cl_arm_import_memory_dma_buf cl_img_protected_content cl_img_semaphore cl_img_external_semaphore cl_img_external_semaphore_sync_fd cl_khr_semaphore cl_khr_external_semaphore cl_khr_external_semaphore_sync_fd
  Device Extensions with Version                  cl_khr_icd                                                       0x400000 (1.0.0)
                                                  cl_khr_fp16                                                      0x400000 (1.0.0)
                                                  cl_img_spirv                                                     0x400000 (1.0.0)
                                                  cles_khr_int64                                                   0x400000 (1.0.0)
                                                  cl_img_yuv_image                                                 0x400000 (1.0.0)
                                                  cl_khr_device_uuid                                               0x400000 (1.0.0)
                                                  cl_khr_depth_images                                              0x400000 (1.0.0)
                                                  cl_khr_mipmap_image                                              0x400000 (1.0.0)
                                                  cl_khr_priority_hints                                            0x400000 (1.0.0)
                                                  cl_img_generate_mipmap                                           0x400000 (1.0.0)
                                                  cl_khr_3d_image_writes                                           0x400000 (1.0.0)
                                                  cl_img_cached_allocations                                        0x400000 (1.0.0)
                                                  cl_khr_mipmap_image_writes                                       0x400000 (1.0.0)
                                                  cl_khr_create_command_queue                                      0x400000 (1.0.0)
                                                  cl_khr_suggested_local_work_size                                 0x400000 (1.0.0)
                                                  cl_img_mem_properties                                            0x400000 (1.0.0)
                                                  cl_img_mem_properties_relax_alloc_requirements                   0x400000 (1.0.0)
                                                  cl_khr_extended_versioning                                       0x400000 (1.0.0)
                                                  cl_khr_image2d_from_buffer                                       0x400000 (1.0.0)
                                                  cl_khr_byte_addressable_store                                    0x400000 (1.0.0)
                                                  cl_khr_local_int32_base_atomics                                  0x400000 (1.0.0)
                                                  cl_khr_global_int32_base_atomics                                 0x400000 (1.0.0)
                                                  cl_khr_local_int32_extended_atomics                              0x400000 (1.0.0)
                                                  cl_khr_global_int32_extended_atomics                             0x400000 (1.0.0)
                                                  cl_khr_spir                                                      0x400000 (1.0.0)
                                                  cl_khr_il_program                                                0x400000 (1.0.0)
                                                  cl_khr_egl_image                                                 0x400000 (1.0.0)
                                                  cl_arm_import_memory                                             0x400000 (1.0.0)
                                                  cl_arm_import_memory_dma_buf                                     0x400000 (1.0.0)
                                                  cl_img_protected_content                                         0x400000 (1.0.0)
                                                  cl_img_semaphore                                                 0x400000 (1.0.0)
                                                  cl_img_external_semaphore                                        0x400000 (1.0.0)
                                                  cl_img_external_semaphore_sync_fd                                0x400000 (1.0.0)
                                                  cl_khr_semaphore                                                 0x400000 (1.0.0)
                                                  cl_khr_external_semaphore                                        0x400000 (1.0.0)
                                                  cl_khr_external_semaphore_sync_fd                                0x400000 (1.0.0)

NULL platform behavior
  clGetPlatformInfo(NULL, CL_PLATFORM_NAME, ...)  PowerVR
  clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, ...)   Success [IMG]
  clCreateContext(NULL, ...) [default]            Success [IMG]
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_DEFAULT)  Success (1)
    Platform Name                                 PowerVR
    Device Name                                   PowerVR B-Series BXE-4-32
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_CPU)  No devices found in platform
    Platform Name                                 PowerVR
    Device Name                                   PowerVR B-Series BXE-4-32
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_ACCELERATOR)  No devices found in platform
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_CUSTOM)  Invalid device type for platform
  clCreateContextFromType(NULL, CL_DEVICE_TYPE_ALL)  Success (1)
    Platform Name                                 PowerVR
    Device Name                                   PowerVR B-Series BXE-4-32

ICD loader properties
  ICD loader Name                                 OpenCL ICD Loader
  ICD loader Vendor                               OCL Icd free software
  ICD loader Version                              2.3.1
  ICD loader Profile                              OpenCL 3.0  

最初、clinfoで"Number of platforms  0"でなぜ...となり、フォーラムまで確認してしまった...
あとで権限が足りない!と気づいたのだった...(しかも自己解決)


TensorFlow Lite C++ を使ったサンプルをビルド


リポジトリclone、ビルドする。
ビルドするためsubmoduleにtensorflowのリポジトリを登録してある。
これにyoctoのレシピであるmeta-tensorflow-liteで用意したパッチをあてる。
$ sudo apt install libboost-dev
$ cd ~
$ git clone https://github.com/NobuoTsukamoto/meta-tensorflow-lite.git
$ git clone https://github.com/NobuoTsukamoto/tflite-cv-example.git
$ cd tflite-cv-example
$ git submodule update --init
$ cd tensorflow
$ git apply ~/meta-tensorflow-lite/recipes-framework/tensorflow-lite/files/001-v2.12-Fix-CMAKE_Build_Error.patch
$ cd ../detection/cpp/
$ mkdir build
$ cd build
$ cmake .. -DENABEL_GPU_DELEGATE=ON
$ make -j$(nproc)


動作確認


カメラを接続して実行。
モデルはEfficientDet-Lite0のFP32。
$ ./tflite_detection \
    /home/user/models/efficientdet-lite0_fp32.tflite \
    --label=/home/user/tflite-cv-example/detection/models/coco_labels.txt \
    --thread=3





最後に


これでVisionFive 2でTensorFlow LiteのXNNPACK、EdgeTPU、GPUが動作した。
RISC-VのSBCでここまで動くと面白くなってくる。

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をやってみる。