RaspberryPi OS/Ubuntu armhf/aarch64 TensorFlowLite v2.4.0 FlexDelegateやXNNPACKを有効化したwheelインストーラの生成手順

<a href="https://github.com/PINTO0309/TensorflowLite-bin"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/PINTO0309/TensorflowLite-bin.png" width="460px"></a>
# 1. はじめに
TensorFlow v2.4.0 の TensorFlow Lite スタンドアロンインストーラをクロスコンパイルで生成する手順を共有します。 最近の手順はかなり簡単になりました。 **`v2.3.0`** からですが、 Docker がインストールされていれば、特殊なカスタマイズを入れない限り環境に依存することなくコマンド一発でビルドが通せるようになっています。 では、今回は **`FlexDelegate`** というオプション機能とFloat32推論をかなり高速化してくれる **`XNNPACK`** というオプション機能を有効にした状態でインストーラを生成してみたいと思います。 **`FlexDelegate`** は、 TensorFlowLite が非対応のオペレーションを TensorFlow 側へオフロードして実行できる機能です。

# 2. 環境
クロスコンパイル環境の一例です。 Dockerがインストールされていれば良いです。

1. Ubuntu 18.04 x86_64
2. Docker
3. TensorFlow v2.4.0　※2020.12.02時点で公式のリリースが間に合わなかったようです

# 3. 手順
## 3-1. TensorFlow の Clone

```console:TensorFlowのClone
$ cd ~
$ git clone -b v2.4.0 https://github.com/tensorflow/tensorflow.git
　or
$ git clone -b v2.4.0-rc3 https://github.com/tensorflow/tensorflow.git
$ cd tensorflow
```

## 3-2. ビルドシーケンスに **`FlexDelegate`** と **`XNNPACK`** を含める
**`FlexDelegate`** と **`XNNPACK`** を有効にしない場合はこの手順は不要です。 手を加えない場合、ビルドはかなり早く終わります。

```console:ビルドシーケンスのカスタマイズ
$ nano tensorflow/lite/tools/pip_package/build_pip_package_with_bazel.sh

# Build python interpreter_wrapper.
cd "${BUILD_DIR}"
case "${TENSORFLOW_TARGET}" in
  armhf)
    BAZEL_FLAGS="--config=elinux_armhf
      --copt=-march=armv7-a --copt=-mfpu=neon-vfpv4
      --copt=-O3 --copt=-fno-tree-pre --copt=-fpermissive
      --define tensorflow_mkldnn_contraction_kernel=0
      --define=raspberry_pi_with_neon=true"
    ;;
  aarch64)
    BAZEL_FLAGS="--config=elinux_aarch64
      --define tensorflow_mkldnn_contraction_kernel=0
      --copt=-O3"
    ;;
  *)
    ;;
esac

　↓

# Build python interpreter_wrapper.
cd "${BUILD_DIR}"
case "${TENSORFLOW_TARGET}" in
  armhf)
    BAZEL_FLAGS="--config=elinux_armhf
      --copt=-march=armv7-a --copt=-mfpu=neon-vfpv4
      --copt=-O3 --copt=-fno-tree-pre --copt=-fpermissive
      --define tensorflow_mkldnn_contraction_kernel=0
      --define=raspberry_pi_with_neon=true
      --define=tflite_pip_with_flex=true
      --define=tflite_with_xnnpack=true"
    ;;
  aarch64)
    BAZEL_FLAGS="--config=elinux_aarch64
      --define tensorflow_mkldnn_contraction_kernel=0
      --define=tflite_pip_with_flex=true
      --define=tflite_with_xnnpack=true
      --copt=-O3"
    ;;
  *)
    ;;
esac
```

## 3-3. TensorFlowLite の Wheelインストーラビルド
PythonのバージョンとCPUアーキテクチャごとに下記から適切なコマンドを選択して実行します。 Docker上に適切なビルド環境が自動的に構築されたうえでビルドが実行されますので特につまづく要素は無いと思います。 ただ、**`FlexDelegate`** をビルドオプションで有効にしていますので、通常のビルドよりも時間が掛かります。 6 Core 12スレッド の Core i7 で概ね１時間20分掛かりました。 **`FlexDelegate`** を有効にしない場合は５分で終わります。

```console:インストーラビルド用のコマンド例
### Python 3.7
$ sudo CI_DOCKER_EXTRA_PARAMS="-e CI_BUILD_PYTHON=python3.7 -e CROSSTOOL_PYTHON_INCLUDE_PATH=/usr/include/python3.7" \
  tensorflow/tools/ci_build/ci_build.sh PI-PYTHON37 \
  tensorflow/lite/tools/pip_package/build_pip_package_with_bazel.sh aarch64

$ sudo CI_DOCKER_EXTRA_PARAMS="-e CI_BUILD_PYTHON=python3.7 -e CROSSTOOL_PYTHON_INCLUDE_PATH=/usr/include/python3.7" \
  tensorflow/tools/ci_build/ci_build.sh PI-PYTHON37 \
  tensorflow/lite/tools/pip_package/build_pip_package_with_bazel.sh armhf

### Python 3.8
$ sudo CI_DOCKER_EXTRA_PARAMS="-e CI_BUILD_PYTHON=python3.8 -e CROSSTOOL_PYTHON_INCLUDE_PATH=/usr/include/python3.8" \
  tensorflow/tools/ci_build/ci_build.sh PI-PYTHON38 \
  tensorflow/lite/tools/pip_package/build_pip_package_with_bazel.sh aarch64

$ sudo CI_DOCKER_EXTRA_PARAMS="-e CI_BUILD_PYTHON=python3.8 -e CROSSTOOL_PYTHON_INCLUDE_PATH=/usr/include/python3.8" \
  tensorflow/tools/ci_build/ci_build.sh PI-PYTHON38 \
  tensorflow/lite/tools/pip_package/build_pip_package_with_bazel.sh armhf

### Python 3.5
$ sudo CI_DOCKER_EXTRA_PARAMS="-e CI_BUILD_PYTHON=python3.5 -e CROSSTOOL_PYTHON_INCLUDE_PATH=/usr/include/python3.5" \
  tensorflow/tools/ci_build/ci_build.sh PI-PYTHON3 \
  tensorflow/lite/tools/pip_package/build_pip_package_with_bazel.sh aarch64

$ sudo CI_DOCKER_EXTRA_PARAMS="-e CI_BUILD_PYTHON=python3.5 -e CROSSTOOL_PYTHON_INCLUDE_PATH=/usr/include/python3.5" \
  tensorflow/tools/ci_build/ci_build.sh PI-PYTHON3 \
  tensorflow/lite/tools/pip_package/build_pip_package_with_bazel.sh armhf
```

はい。 終わり。 進化していてめちゃくちゃ簡単になっています。
![Screenshot 2020-11-20 23:43:11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194769/9f058733-162a-5199-7e27-876eea8f2d82.png)