MacでTensorFlow Lite + Coral USB Acceleratorを動かしてみる

TensorFlow LiteとCoral USB Acceleratorを使う機会があり、物体検出(Object Detection)を試してみました。Mac環境でCoral USB ACceleratorを動かせるようになったので動作手順を紹介します。
2020.02.04

福岡のyoshihitohです。

最近業務でラズパイとCoral USB アクセラレータ(Edge TPU)を使ったシステムを構築する機会がありました。Coral USBアクセラレータを動かす場合はEdge TPUランタイムが必要なんですが、2020年1月の更新でこのランタイムをMacおよびWindows環境で利用できるようになりました。

January Updates | Coral

今回はMac環境でTensorFlow LiteとCoral USBアクセラレータを使って物体検出のサンプルアプリを動かしてみます。

前提環境

  • macOS: 10.14.6
  • Python: 3.7.6
  • TensorFlow Lite: 2.1.0

Coral USBアクセラレータとは

The Coral USB Accelerator is a USB device that provides an Edge TPU as a coprocessor for your computer. It accelerates inferencing for your machine learning models when attached to either a Linux, Mac, or Windows host computer. This page is your guide to get started.

公式サイトドキュメント より引用

Edge TPUプロセッサを動作させるためのUSBデバイスで、IoTデバイスなどエッジ側での推論を高速化できます。試した感じ体感でわかるぐらい推論速度が違ってきそうです。測定結果は後半に載せてます。

環境構築

以下の手順で環境を構築していきます。

  1. Python仮想環境
  2. TensorFlow Lite
  3. Edge TPUランタイム

最後のEdge TPUランタイムはグローバルにインストールするのでご注意ください。アンインストール用のスクリプトが用意されているので、気になる場合は動かし終わったあとにアンインストールしましょう。

Python仮想環境

venv モジュールを使ってPythonの仮想環境を作成し、ここに依存ライブラリをインストールしていきます。

# 作業ディレクトリ作成
$ mkdir tflite-coral-example && cd tflite-coral-example

# 仮想環境作成
$ python3 -m venv ./venv37

# 仮想環境有効化
$ source ./venv37/bin/activate

以降の手順はこの仮想環境を利用する前提です。

EdgeTPUランタイム

公式サイトの手順 どおりにインストールします。使っているOSの手順に従い操作しましょう。環境ごとに 必要条件 が異なるので、条件を満たしているか確認してください。

以降はMac環境の場合の操作です。OSのバージョンが違っていましたが、特にハマること無く動かすことができました。

$ curl -O https://dl.google.com/coral/edgetpu_api/edgetpu_runtime_20200128.zip
$ unzip edgetpu_runtime_20200128.zip
$ cd edgetpu_runtime
$ sudo bash install.sh
Password:
Warning: During normal operation, the Edge TPU Accelerator may heat up,
depending on the computation workloads and operating frequency. Touching the
metal part of the device after it has been operating for an extended period of
time may lead to discomfort and/or skin burns. As such, when running at the
default operating frequency, the device is intended to safely operate at an
ambient temperature of 35C or less. Or when running at the maximum operating
frequency, it should be operated at an ambient temperature of 25C or less.

Google does not accept any responsibility for any loss or damage if the device
is operated outside of the recommended ambient temperature range.
................................................................................
Would you like to enable the maximum operating frequency for the USB Accelerator? Y/N
N
Using default operating frequency for USB Accelerator.
Warning: libusb 1.0.23 is already installed and up-to-date
To reinstall 1.0.23, run `brew reinstall libusb`
Installing Edge TPU runtime library [/usr/local/lib]...
Installing Edge TPU runtime library symlink [/usr/local/lib]...
$ # ここまででインストール完了

最後に動作周波数についての設定を確認されます。最大周波数で動作させる場合は Y を、通常の周波数で動作させる場合は N を入力してください。 以下、最大周波数で動作せる場合の注意事項です。あくまで意訳なので原文を確認することをオススメします。

  • 計算ワークロードと動作周波数次第でアクセラレータが熱くなることがある
  • 長期間動作中のアクセラレータの金属部分に触れると火傷につながる恐れがある
  • 通常の周波数の場合、35度以下の環境で安全に動作することを意図している
  • 最大周波数の場合、25度以下の環境で動作させるべき

動作周波数の設定は要件によって変わってきそうです。今回は検証目的なので、いったん N を指定し通常の周波数で動かしてみます。

TensorFlow Lite

公式サイトの手順に従いpip3コマンドでインストールします。インストール大変そうなイメージもってましたけどめっちゃ簡単ですね。

$ pip3 install https://dl.google.com/coral/python/tflite_runtime-2.1.0-cp37-cp37m-macosx_10_14_x86_64.whl
$ python3
>>> import tflite_runtime
>>> tflite_runtime.__version__
'2.1.0'

pythonを起動して tflite_runtime をimportできればOKです。

ここまでで環境構築は完了です。サンプルアプリケーションの物体検出を動かしてみましょう。

物体検出してみる

まずリポジトリをクローンします。

$ mkdir google-coral && cd google-coral
$ git clone https://github.com/google-coral/tflite --depth 1

依存ライブラリ・推論用のデータをインストールします。Pythonのパッケージをインストールするので、Pythonの仮想環境を使っているか確認してから実行しましょう。

$ cd tflite/python/examples/detection
$ ./install_requirements.sh

準備完了です。物体検出アプリを実行してみます。

$ python3 detect_image.py \
      --model models/mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite \
      --labels models/coco_labels.txt \
      --input images/grace_hopper.bmp \
      --output images/grace_hopper_processed.bmp

人物(グレース・ホッパーさん)とネクタイを検出すれば成功です。また、検出位置を確認できるように検出位置を赤枠で囲んだ画像が表示されます。

推論速度について

以下の場合について測定し比較してみました。

  • 通常周波数の場合
  • 最大周波数の場合
  • アクセラレータ無しの場合

通常周波数で動作する場合

ここまでの操作で通常周波数のEdge TPUランタイムをセットアップ済みなのでそのまま試していきます。

$ python3 detect_image.py \
  --model models/mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite \
  --labels models/coco_labels.txt \
  --input images/grace_hopper.bmp \
  --output images/grace_hopper_processed.bmp
----INFERENCE TIME----
Note: The first inference is slow because it includes loading the model into Edge TPU memory.
34.53 ms
12.47 ms
18.58 ms
13.86 ms
15.36 ms
-------RESULTS--------
person
  id:     0
  score:  0.83984375
  bbox:   BBox(xmin=2, ymin=5, xmax=513, ymax=596)
tie
  id:     31
  score:  0.83984375
  bbox:   BBox(xmin=228, ymin=421, xmax=293, ymax=545)

初回: 34ms、2回目以降:12ms〜18msとなりました。だいぶ速いですね!

最大周波数で動作する場合

Edge TPUランタイムを再インストールして、最大周波数モードで動作するようにします。この場合プログラムおよび起動オプションの変更は不要です。

$ python3 detect_image.py \
  --model models/mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite \
  --labels models/coco_labels.txt \
  --input images/grace_hopper.bmp \
  --output images/grace_hopper_processed.bmp
----INFERENCE TIME----
Note: The first inference is slow because it includes loading the model into Edge TPU memory.
31.13 ms
10.14 ms
9.14 ms
8.92 ms
8.98 ms
-------RESULTS--------
person
  id:     0
  score:  0.83984375
  bbox:   BBox(xmin=2, ymin=5, xmax=513, ymax=596)
tie
  id:     31
  score:  0.83984375
  bbox:   BBox(xmin=228, ymin=421, xmax=293, ymax=545)

初回:31ms、2回目以降: 8〜10msと、さらに速くなりましたね!

アクセラレータ無しの場合

サンプルアプリケーションはアクセラレータを必ず使う前提なので、以下の変更を加えます。

  • プログラムを書き換えて推論時にEdge TPUを使わないようにする
  • 非Edge TPU用の推論モデルを使うようにする

まず、プログラムを書き換えます。 detect_image.py の55行目付近にある make_interpreter 関数の実装を変更します。引数に experimental_delegates を指定するとEdge TPUを利用するので、この引数をごっそり削除します。

--- a/python/examples/detection/detect_image.py
+++ b/python/examples/detection/detect_image.py
@@ -54,12 +54,7 @@ def load_labels(path, encoding='utf-8'):

 def make_interpreter(model_file):
   model_file, *device = model_file.split('@')
-  return tflite.Interpreter(
-      model_path=model_file,
-      experimental_delegates=[
-          tflite.load_delegate(EDGETPU_SHARED_LIB,
-                               {'device': device[0]} if device else {})
-      ])
+  return tflite.Interpreter(model_path=model_file)

コマンドラインオプションの --model が推論モデルの指定なので、これを変更して実行します。 models//mobilenet_ssd_v2_coco_quant_postprocess.tflite が非EdgeTPU用の推論モデルです。

$ python3 detect_image.py \
  --model models/mobilenet_ssd_v2_coco_quant_postprocess.tflite \
  --labels models/coco_labels.txt \
  --input images/grace_hopper.bmp \
  --output images/grace_hopper_processed.bmp
----INFERENCE TIME----
Note: The first inference is slow because it includes loading the model into Edge TPU memory.
89.03 ms
77.68 ms
81.14 ms
78.90 ms
75.99 ms
-------RESULTS--------
tie
  id:     31
  score:  0.83984375
  bbox:   BBox(xmin=228, ymin=418, xmax=293, ymax=544)
person
  id:     0
  score:  0.83984375
  bbox:   BBox(xmin=2, ymin=5, xmax=513, ymax=596)

初回89ms、2回目以降: 75〜81msとなりました。十分に速いと思いますがアクセラレータ利用時と比べると少し落ちますね。なお推論結果 tieperson の出現順序が変わっていますが、検出位置とスコアはアクセラレータ利用時と一致しています。

推論速度比較

# 通常周波数 最大周波数 アクセラレータなし
1回目 34.742 ms 32.52 ms 84.626 ms
2回目 15.608 ms 9.84 ms 76.624 ms
3回目 14.638 ms 8.84 ms 78.202 ms
4回目 14.272 ms 8.87 ms 76.148 ms
5回目 13.984 ms 8.77 ms 77.078 ms

上記3パターンについて各5回測定した結果の比較です。今回はMac環境で測定したのでアクセラレータ無しの場合もそれなりの速度が出ていますが、マシンパワーが弱めのエッジデバイスで動作させる場合はアクセラレータを利用することでパフォーマンスを大きく改善できそうです。

おわりに

機械学習周りは難しそうだなぁというイメージで敬遠していましたが、学習済みのモデルを使う場合は手軽に物体検出を試すことができて驚きました。Coral USB Acceleratorを利用するとエッジデバイスでも高速な推論を行えそうです。面白そうな分野なので色々と試していきたいと思います!