パフォーマンスの測定

ベンチマーク ツール

LiteRT ベンチマーク ツールは現在、次の重要なパフォーマンス指標の統計情報を測定して計算します。

  • 初期化時間
  • ウォームアップ状態の推論時間
  • 定常状態の推論時間
  • 初期化時のメモリ使用量
  • メモリ使用量の全体像

ベンチマーク ツールは、Android と iOS のベンチマーク アプリと、ビルド済みのコマンドライン バイナリとして提供され、すべて同じコア パフォーマンス測定ロジックを共有します。使用できるオプションと出力形式は、ランタイム環境の違いにより若干異なります。

事前構築済みベンチマーク バイナリ(CompiledModel API を使用)

Android でベンチマーク ツールを使用する方法は 2 つあります。1 つはネイティブ ベンチマーク バイナリ(CompiledModel API ベース)で、もう 1 つはAndroid ベンチマーク アプリ(Interpreter API ベース)です。LiteRT ベンチマーク ツールは、組み込みバイナリ benchmark_model として提供されます。このツールは、Linux、macOS、Windows、Raspberry Pi、組み込みデバイス、GPU アクセラレーションが有効になっている Android デバイスのシェル コマンドラインから実行できます。

バイナリをダウンロードまたはビルドする

次のリンクから、ナイトリー プリビルド コマンドライン バイナリをダウンロードします。

パソコンのソースからベンチマーク バイナリをビルドすることもできます。

bazel build -c opt //litert/tools:benchmark_model

Android NDK ツールチェーンでビルドするには、まずこのガイドに沿ってビルド環境を設定するか、このガイドで説明されているように Docker イメージを使用する必要があります。

bazel build -c opt --config=android_arm64 \
  //litert/tools:benchmark_model

ベンチマークを実行する

パソコンでベンチマークを実行するには、シェルからバイナリを実行します。

path/to/downloaded_or_built/benchmark_model \
  --graph=your_model.tflite \
  --num_threads=4

ビルド済みのコマンドライン バイナリでは、前述の パラメータの同じセットを使用できます。

GPU アクセラレータ

これらの事前構築済みバイナリには、新しい LiteRT GPU アクセラレータが含まれています。Vulkan(Linux)、Metal(MacOS)、Direct3D(Windows)を基盤とする OpenCL と WebGPU をサポートしています。

GPU アクセラレータを使用するには、--use_gpu=true フラグを渡します。

モデルの運用のプロファイリング

ベンチマーク モデルのバイナリを使用すると、モデルのオペレーションをプロファイリングして、各オペレーターの実行時間を取得することもできます。これを行うには、呼び出し時にフラグ --use_profiler=truebenchmark_model に渡します。

Android ベンチマーク アプリ(Interpreter API を使用)

v1 Interpreter API に基づく Android ベンチマーク アプリも提供されています。これは、Android アプリでモデルがどのように動作するかをより正確に測定するものです。ベンチマーク ツールの数値は、実際のアプリでモデルを使用して推論を実行する場合と若干異なります。

この Android ベンチマーク アプリには UI がありません。adb コマンドを使用してインストールして実行し、adb logcat コマンドを使用して結果を取得します。

アプリをダウンロードまたはビルドする

次のリンクを使用して、ナイトリー ビルド済みの Android ベンチマーク アプリをダウンロードします。

Flex デリゲートを介して TF オペレーションをサポートする Android ベンチマーク アプリについては、以下のリンクを使用してください。

こちらの手順に沿って、ソースからアプリをビルドすることもできます。

ベンチマークを準備する

ベンチマーク アプリを実行する前に、アプリをインストールし、次のようにモデルファイルをデバイスにプッシュします。

adb install -r -d -g android_aarch64_benchmark_model.apk
adb push your_model.tflite /data/local/tmp

ベンチマークを実行する

adb shell am start -S \
  -n org.tensorflow.lite.benchmark/.BenchmarkModelActivity \
  --es args '"--graph=/data/local/tmp/your_model.tflite \
              --num_threads=4"'

graph は必須パラメータです。

  • graph: string
    TFLite モデルファイルのパス。

ベンチマークの実行には、オプションのパラメータをさらに指定できます。

  • num_threads: int(デフォルト=1)
    TFLite インタープリタの実行に使用するスレッド数。
  • use_gpu: bool(デフォルト=false)
    GPU デリゲートを使用します。
  • use_xnnpack: bool(デフォルト=false
    XNNPACK デリゲートを使用します。

使用しているデバイスによっては、一部のオプションが利用できないか、効果がない場合があります。ベンチマーク アプリで実行できるパフォーマンス パラメータについては、パラメータを参照してください。

logcat コマンドを使用して結果を表示します。

adb logcat | grep "Inference timings"

ベンチマーク結果は次のように報告されます。

... tflite  : Inference timings in us: Init: 5685, First inference: 18535, Warmup (avg): 14462.3, Inference (avg): 14575.2

iOS ベンチマーク アプリ

iOS デバイスでベンチマークを実行するには、ソースからアプリをビルドする必要があります。LiteRT モデルファイルをソースツリーの benchmark_data ディレクトリに配置し、benchmark_params.json ファイルを変更します。これらのファイルはアプリにパッケージ化され、アプリはディレクトリからデータを読み取ります。詳細な手順については、iOS ベンチマーク アプリをご覧ください。

よく知られているモデルのパフォーマンス ベンチマーク

このセクションでは、一部の Android デバイスと iOS デバイスでよく知られているモデルを実行した場合の LiteRT パフォーマンス ベンチマークを示します。

Android のパフォーマンス ベンチマーク

これらのパフォーマンス ベンチマークの数値は、ネイティブ ベンチマーク バイナリで生成されました。

Android ベンチマークの場合、ばらつきを減らすために、デバイスのビッグコアを使用するように CPU アフィニティが設定されます(詳細を参照)。

モデルがダウンロードされ、/data/local/tmp/tflite_models ディレクトリに解凍されていることを前提としています。ベンチマーク バイナリはこちらの手順でビルドされ、/data/local/tmp ディレクトリにあると想定されています。

ベンチマークを実行するには:

adb shell /data/local/tmp/benchmark_model \
  --num_threads=4 \
  --graph=/data/local/tmp/tflite_models/${GRAPH} \
  --warmup_runs=1 \
  --num_runs=50

GPU デリゲートで実行するには、--use_gpu=true を設定します。

以下のパフォーマンス値は Android 10 で測定されています。

モデル名 デバイス CPU、4 スレッド GPU
Mobilenet_1.0_224(float) Google Pixel 3 23.9 ミリ秒 6.45 ミリ秒
Google Pixel 4 14.0 ミリ秒 9.0 ミリ秒
Mobilenet_1.0_224(量子化) Google Pixel 3 13.4 ミリ秒 ---
Google Pixel 4 5.0 ミリ秒 ---
NASNet mobile Google Pixel 3 56 ミリ秒 ---
Google Pixel 4 34.5 ミリ秒 ---
SqueezeNet Google Pixel 3 35.8 ミリ秒 9.5 ミリ秒
Google Pixel 4 23.9 ミリ秒 11.1 ミリ秒
Inception_ResNet_V2 Google Pixel 3 422 ミリ秒 99.8 ミリ秒
Google Pixel 4 272.6 ミリ秒 87.2 ミリ秒
Inception_V4 Google Pixel 3 486 ミリ秒 93 ミリ秒
Google Pixel 4 324.1 ミリ秒 97.6 ミリ秒

iOS パフォーマンス ベンチマーク

これらのパフォーマンス ベンチマークの数値は、iOS ベンチマーク アプリを使用して生成されました。

iOS ベンチマークを実行するために、ベンチマーク アプリが適切なモデルを含むように変更され、benchmark_params.jsonnum_threads を 2 に設定するように変更されました。GPU デリゲートを使用するために、"use_gpu" : "1" オプションと "gpu_wait_type" : "aggressive" オプションも benchmark_params.json に追加されました。

モデル名 デバイス CPU、2 スレッド GPU
Mobilenet_1.0_224(float) iPhone XS 14.8 ミリ秒 3.4 ミリ秒
Mobilenet_1.0_224(量子化) iPhone XS 11 ミリ秒 ---
NASNet mobile iPhone XS 30.4 ミリ秒 ---
SqueezeNet iPhone XS 21.1 ミリ秒 15.5 ミリ秒
Inception_ResNet_V2 iPhone XS 261.1 ミリ秒 45.7 ミリ秒
Inception_V4 iPhone XS 309 ミリ秒 54.4 ミリ秒

LiteRT の内部をトレースする

Android で LiteRT の内部をトレースする

Android アプリの LiteRT インタープリタからの内部イベントは、Android トレースツールでキャプチャできます。これらは Android Trace API と同じイベントであるため、Java/Kotlin コードからキャプチャされたイベントは LiteRT 内部イベントとともに表示されます。

イベントの例を次に示します。

  • Operator の呼び出し
  • デリゲートによるグラフの変更
  • テンソルの割り当て

トレースをキャプチャするためのさまざまなオプションのうち、このガイドでは Android Studio CPU Profiler と System Tracing アプリについて説明します。その他のオプションについては、Perfetto コマンドライン ツールまたは Systrace コマンドライン ツールを参照してください。

Java コードでのトレース イベントの追加

これは、画像分類のサンプルアプリのコード スニペットです。LiteRT インタープリタは recognizeImage/runInference セクションで実行されます。この手順は省略可能ですが、推論呼び出しが行われた場所を把握するのに役立ちます。

  Trace.beginSection("recognizeImage");
  ...
  // Runs the inference call.
  Trace.beginSection("runInference");
  tflite.run(inputImageBuffer.getBuffer(), outputProbabilityBuffer.getBuffer().rewind());
  Trace.endSection();
  ...
  Trace.endSection();

LiteRT トレースを有効にする

LiteRT トレースを有効にするには、Android アプリを起動する前に Android システム プロパティ debug.tflite.trace を 1 に設定します。

adb shell setprop debug.tflite.trace 1

LiteRT インタープリタの初期化時にこのプロパティが設定されている場合、インタープリタからのキーイベント(演算子の呼び出しなど)がトレースされます。

すべてのトレースをキャプチャしたら、プロパティ値を 0 に設定してトレースを無効にします。

adb shell setprop debug.tflite.trace 0

Android Studio CPU Profiler

次の手順に沿って、Android Studio CPU プロファイラでトレースをキャプチャします。

  1. トップメニューから [Run] > [Profile 'app'] を選択します。

  2. Profiler ウィンドウが表示されたら、CPU タイムラインの任意の場所をクリックします。

  3. CPU プロファイリング モードで [Trace System Calls] を選択します。

    [システムコールのトレース] を選択します

  4. [録画] ボタンを押します。

  5. [停止] ボタンを押します。

  6. トレース結果を調査します。

    Android Studio のトレース

この例では、スレッド内のイベントの階層と各オペレーターの時間の統計情報を確認できます。また、スレッド間のアプリ全体のデータフローも確認できます。

System Tracing アプリ

システム トレース アプリに記載されている手順に沿って、Android Studio を使用せずにトレースをキャプチャします。

この例では、Android デバイスのバージョンに応じて、同じ TFLite イベントがキャプチャされ、Perfetto または Systrace 形式で保存されています。キャプチャしたトレースファイルは Perfetto UI で開くことができます。

Perfetto トレース

iOS で LiteRT の内部をトレースする

iOS アプリの LiteRT インタープリタからの内部イベントは、Xcode に含まれる Instruments ツールでキャプチャできます。これらは iOS のsignpostイベントであるため、Swift/Objective-C コードからキャプチャされたイベントは、LiteRT 内部イベントとともに表示されます。

イベントの例を次に示します。

  • Operator の呼び出し
  • デリゲートによるグラフの変更
  • テンソルの割り当て

LiteRT トレースを有効にする

次の手順に沿って、環境変数 debug.tflite.trace を設定します。

  1. Xcode の上部メニューから [Product] > [Scheme] > [Edit Scheme] の順に選択します。

  2. 左側のペインで [プロフィール] をクリックします。

  3. [Use the Run action's arguments and environment variables] チェックボックスをオフにします。

  4. [環境変数] セクションに debug.tflite.trace を追加します。

    環境変数の設定

iOS アプリのプロファイリング時に LiteRT イベントを除外する場合は、環境変数を削除してトレースを無効にします。

XCode Instruments

以下の手順でトレースをキャプチャします。

  1. Xcode の上部メニューから [Product] > [Profile] を選択します。

  2. Instruments ツールが起動したら、プロファイリング テンプレートの [Logging] をクリックします。

  3. [スタート] ボタンを押します。

  4. [停止] ボタンを押します。

  5. [os_signpost] をクリックして、OS Logging サブシステムの項目を展開します。

  6. [org.tensorflow.lite] OS ロギング サブシステムをクリックします。

  7. トレース結果を調査します。

    Xcode Instruments トレース

この例では、各オペレータ時間のイベントと統計情報の階層を確認できます。

トレースデータを使用する

トレースデータを使用すると、パフォーマンスのボトルネックを特定できます。

プロファイラから得られる分析情報と、パフォーマンスを改善するための解決策の例を次に示します。

  • 使用可能な CPU コアの数が推論スレッドの数よりも少ない場合、CPU スケジューリングのオーバーヘッドにより、パフォーマンスが低下する可能性があります。モデル推論と重複しないように、アプリケーション内の他の CPU 使用率の高いタスクのスケジュールを変更するか、インタープリタ スレッドの数を調整できます。
  • 演算子が完全に委任されていない場合、モデルグラフの一部は想定されるハードウェア アクセラレータではなく CPU で実行されます。サポートされていない演算子は、サポートされている類似の演算子に置き換えることができます。