Edge TPU の July 2021 Updates を追う

こんにちは、R&D チームの奥村(@izariuo440)です。

前回の Edge TPU の記事から1年4ヶ月ほど空いてしまいました。その間、Windows 向けの PCIe ドライバのβ版が公開されたり Edge TPU ランタイムが OSS になったりPython/C++ 向けの API が整理されたり MobileDet が利用可能になったりしました。今回の更新では、コンパイラや修正ツールの更新でより多くのモデルがコンパイルできるようになったり、物体検出の EfficientDet-Lite や単一人物姿勢推定の MoveNet などのモデルが追加されたりしています。この記事では July 2021 Updates | Coral をベースに、意訳・追記をしています。

Edge TPU に関しては、過去記事も参考になるかもしれません。

  1. 2019インターン紹介: Edge TPU向けPoseNetのリアルタイム姿勢推定 - OPTiM TECH BLOG
  2. Edge TPU の性能を引き出すためには? - OPTiM TECH BLOG
  3. Edge TPU の September 2019 Updates を追う - OPTiM TECH BLOG
  4. Edge TPU の January 2020 Updates を追う - OPTiM TECH BLOG
  5. Edge TPU の April 2020 Updates を追う - OPTiM TECH BLOG

意訳

Edge TPU Compiler v16

最新の Edge TPU コンパイラでは、新たに以下のオペレータをサポートしました。

  • LSTM
    • 単方向のみ。現在の TFLite は双方向 LSTM やカスタマイズされた LSTM をサポートしていません。その他の RNN オプションについては、後述する append_recurrent_links ツールを参照してください。
  • Reduce-max
  • Reduce-min
  • Rsqrt
  • Squared difference
  • Transpose

また、コンパイラのエクスペリエンスと成功率を向上するための機能をいくつか追加しました。

  • グラフをコンパイルするときに、サポートされていないオペレータにでくわすと、コンパイルが失敗することがあります。新しく追加されたデリゲート検索機能は、これを防ぐために、コンパイルするグラフを後方から切り詰めながら、コンパイルが停止する箇所を繰り返し探します。--search_delegate オプションで有効にできます。--delegate_search_step で切り詰めるステップサイズを指定できます。
    • 訳者注:グラフのうち、Edge TPU に処理を移譲できる部分をできるだけ大きくするためのもの?
  • --timeout_sec オプションでコンパイルのタイムアウトの指定可能に(既定は 180 秒)
  • コンパイルの失敗を分かりやすく(エラーメッセージなしでのクラッシュの軽減)
  • SSD モデルの分割に対応(が、後述する profiling-based partitioner を使うべきかもしれない)

コンパイラのフラグについての詳細は Edge TPU Compiler guide を参照してください。

最新のコンパイラを入手するには、installation guide を参照してください(Debian Linux のみ)。

profiling-based partitioner の更新

このツールは、パラメータのデータサイズではなく区分の遅延に基づいてモデルを区分けすることでパイプライン化されたモデルのスループットを改善するためのもので、2020 年 11 月 にリリースされました。今回の更新では、以下の変更が加えられています。

  1. SSD モデルや、大きな CPU セグメント・グラフブランチを持つモデルのサポートを追加
    • Edge TPU コンパイラ v16 も必要
  2. 既定では、前述したコンパイラの新しい search_delegate オプションが有効になる
  3. 実行ファイルを partition_with_profiling に名称変更
  4. フラグ追加
    1. delegate_search_step
      • Edge TPU コンパイラ v16 で追加された delegate_search_step オプションと同様
    2. partition_search_step
      • delegate_search_step オプションに似ているが、グラフ全体のデリゲートではなく各セグメントの検索に適用される
    3. initial_lower_bound_nsinitial_upper_bound_ns
      • モデルのセグメントの既知の最小/最大遅延。指定されていない場合、Edge TPU コンパイラがヒューリスティックベースなアプローチでモデルをセグメントしてその遅延を記録するというベンチマークによって決定される。

詳細は the profiling based partitioner を参照してください。

RNN モデルを構築するための新しいツール

append_recurrent_links と呼ばれる新しいツールを作成しました。Edge TPU 向けに一つ以上の隠れ保存状態を持つような回帰型ネットワークを作成するのに役立ちます。このツールがない場合(や TensorFlow の LSTM オペレータを使用していない場合)、Edge TPU 向けにコンパイルできる回帰型ネットワークを作成するには、モデルが保存された状態を出力するようにして、アプリケーションが各イテレーションでその保存された状態をモデルに与え直す必要があります。その代わりに、(Edge TPU 向けにコンパイル済みの)そのようなモデルを append_recurrent_links に引き渡すことで、保存された状態を再び隠れ保存状態にして、アプリケーションコードが最終的な出力にフォーカスできるようにできます。

巨大な全結合層を含むモデルをコンパイルするための新しいツール

巨大な全結合層のあるモデルを扱う場合、以前の Edge TPU コンパイラはその層に適用される重みのサイズが原因で、その層を Edge TPU デリゲートから切り取り、代わりに CPU で実行する可能性がありました。そこで、新しい split_fc ツールは、ブロック単位の行列乗算を使用して、その層の重み行列をより小さなブロックに分割します(分割の比率は制御可能です)。split_fc ツールは、Edge TPU コンパイラに引き渡すことができる新しい .tflite ファイルを出力します。出力されたファイルには、Edge TPU デリゲートの中に全結合層が含まれます。

PyCoral API 2.0

2020 年 11 月に、開発を簡素化し、TensorFlow Lite API 上に機能を追加するための PyCoral API を導入しました。今回の更新では大きな変更はないものの、いくつかの API の振る舞いが変更されたことで既存のコードが動かなくなる可能性があるため、メジャーバージョンを上げています。

API の変更点は以下のとおりです。

  • PipelinedModelRunner のエラー報告を改善しました。TensorFlow Lite ランタイムからのエラーメッセージが出力されるようになりました。
  • 破壊的な API 変更
    • PipelinedModelRunner.push() は、input_tensors にリストではなく辞書を必要とするようになったので、各入力テンソルについて、対応するテンソル名を辞書のキーとして提供する必要があります。このメソッドの戻り値は bool ではなく void になりました。失敗すると RuntimeError を発します。
    • PipelinedModelRunner.pop() も上記と同様です。
  • 更新された API
    • make_interpreter() はオプションとして delegate 引数を受け取るようになり、使用したい Edge TPU デリゲートオブジェクトを指定できるようになりました。
    • get_objects() が出力テンソルの次数が異なる SSD モデルをサポートしました。
  • 新しい API

公式サポートに Python 3.9 を追加しました。

PyCoral ライブラリをインストールまたは更新する方法は以下のとおりです。

Coral Dev Board や Raspberry Pi を含む Debian Linux システムの場合(パッケージレポジトリのインストールを忘れずに):

sudo apt-get update 
sudo apt-get install python3-pycoral

Mac や Windows など他のシステムの場合:

python3 -m pip install --index-url https://google-coral.github.io/py-repo/ \
                       --extra-index-url=https://pypi.python.org/simple pycoral

libcoral API の更新

C++ ライブラリを更新し、PyCoral と似たような変更をしています。

  • PipelinedModelRunner の更新
    • Push()Pop() は true/false ではなく absl::OkStatusabsl::InternalError を返すようになりました。
    • PipelineTensor にテンソルの name を追加しました。
    • GetInputTensorNames()GetInputTensor()tflite_utils.h に引っ越しました。
  • GetDetectionResults() が出力テンソルの次数が異なる SSD モデルをサポートしました。

最新の libcoral API でプロジェクトをビルドするには libcoral GitHub readme を参照してください。

新しい訓練済みモデル

coral.ai/models から以下の訓練済みモデルを入手できるようになりました。

タスク モデル名称 データセット 入力サイズ 遅延 mAP 容量
画像分類 Popular Products V1 スーパー商品十万種 224x224x3 7.0 N/A 9.8
物体検出 EfficientDet-Lite0 COCO 320x320x3 37.4 30.4 5.7
EfficientDet-Lite1 384x384x3 56.3 34.3 7.6
EfficientDet-Lite2 448x448x3 104.6 36.0 10.2
EfficientDet-Lite3 512x512x3 107.6 39.4 14.4
EfficientDet-Lite3x 640x640x3 197.0 43.9 20.6
SSD/FPN MobileNet V1 640x640x3 229.4 31.1 37.7
SSD MobileNet V2 300x300x3 7.6 22.4 6.7
領域分割 EdgeTPU-DeepLab-slim Cityscapes 513x513x3 65.9 N/A 3.1
姿勢推定 MoveNet.SinglePose.Lightning ? 192x192x3 7.1 N/A 3.1
MoveNet.SinglePose.Thunder ? 256x256x3 13.8 N/A 7.5
  1. 「遅延」の単位はミリ秒。詳細は coral.ai/models 参照
  2. 「容量」の単位は MB。

MoveNet による姿勢推定の Python サンプルも追加されていました。

まとめ

コンパイラや周辺ツールが整ってきて、より多くのモデルがより多く処理を Edge TPU に投げられるようになった結果、EfficientDet-Lite や MoveNet などのモデルがサポートされるようになったという印象を受けました。物体検出はこれまで 300x300 や 320x320 といった低解像度のモデルしか公式にサポートされていませんでしたが、今回の更新では 512x512 や 640x640 など高めの解像度が選択できるようになったのは素晴らしいですね。

オプティムでは、こうした技術に興味がある・作ってみたい・既に作っている、というエンジニアを募集しています。興味のある方は、こちらをご覧ください。

www.optim.co.jp