読み書きプログラミング

日常のプログラミングで気づいたことを綴っています

AndroidでTensorFlow Lite

Android版「囲碁の師匠」の検討の着手をしました。

最初のマイルストーンは、色々なAndroid用SoCで搭載されつつあるNPUをニューラルネットワークの評価に利用できるかどうかです。
Kirin 990搭載のMatePad Proを購入して挑戦しています。
このページはその備忘録です。随時更新します。

  • TensorFlow LiteのC++ APIでNPUを利用するにはNNAPIを使う。このためはtflte::InterpreterのUseNNAPIメソッドでtrueを設定する。デフォルトはfalseなので明示的に呼ぶ必要あり。

システムログを見る

Androidのシステムログを見るコマンドは、リモートのパソコンにて、

adb logcat

NNAPIのログを出力するには、Android側で事前に

setprop debug.nn.vlog 1

引き数1は色々なオプションあり。詳しくはNeural Networks API  |  Android NDK  |  Android Developersを参照してください。

システムログからTensorFlow Liteに関係するものを抽出するにはキーワードでフィルターする。
tflite, Manager, AndroidNN, ModelBuilder, TypeManager, Memory, GraphDump, HiTraceC, CompilationBuilder, ExecutionPlan, HwHiShowManagerService, DPMS_DeviceStatusMonitorという感じ。

ノウハウ

  • NNAPIを使うには明示的にInterpreterインストタンスのUserNNAPI(true)をコールする。
  • ARM GPUを使うにはTfLiteGpuDelegateV2Createを使う方法とArm NNを使う方法の2通りあるらしい。
  • float16モデルはNNAPIは(他のドライバは動かず)nnapi-referenceにフォールバックする。
  • float32モデルでSetAllowFp16PrecisionForFp32(true)ならliteadapter(NPUドライバと思われる)が動くが、出力が複数あるとCPUにフォールバックするパターンがある。また初回出力がおかしい。
  • float32モデルでSetAllowFp16PrecisionForFp32(false)だとarmnnにフォールバックする。

結論として、float32で出力が1つのモデルは、初回推論以外NPUで正しく計算される。