TensorFlow Lite の GPU デリゲート

画像処理装置(GPU)を使用して機械学習(ML)モデルを実行すると、モデルのパフォーマンスと ML 対応アプリケーションのユーザー エクスペリエンスを大幅に改善できます。TensorFlow Lite では、委譲と呼ばれるハードウェア ドライバを介して GPU やその他の専用プロセッサを使用できます。TensorFlow Lite ML アプリケーションで GPU を使用できるようにすると、次のようなメリットがあります。

  • 速度 - GPU は、超並列ワークロードの高スループットに対応するように構築されています。この設計により、それぞれが並列処理可能な入力テンソルを操作する膨大な数の演算子で構成されるディープ ニューラル ネットに適しており、通常はレイテンシが短縮されます。最適なシナリオでは、GPU でモデルを実行すると、以前は不可能だったリアルタイム アプリケーションを有効にするのに十分な速度になることがあります。
  • 電力効率 - GPU は、非常に効率的かつ最適化された方法で ML 計算を実行します。一般的に、CPU 上で実行される同じタスクよりも消費電力と発熱量が少なくなります。

このドキュメントでは、TensorFlow Lite での GPU サポートの概要と、GPU プロセッサの高度な使用方法について説明します。特定のプラットフォームで GPU サポートを実装する方法について詳しくは、次のガイドをご覧ください。

GPU ML オペレーションのサポート

TensorFlow Lite GPU デリゲートによって TensorFlow ML の演算(op)を高速化できるものにはいくつかの制限があります。このデリゲートは、16 ビットと 32 ビットの浮動小数点精度で次の演算をサポートします。

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGICAL_AND
  • LOGISTIC
  • LSTM v2 (Basic LSTM only)
  • MAX_POOL_2D
  • MAXIMUM
  • MINIMUM
  • MUL
  • PAD
  • PRELU
  • RELU
  • RELU6
  • RESHAPE
  • RESIZE_BILINEAR v1-3
  • SOFTMAX
  • STRIDED_SLICE
  • SUB
  • TRANSPOSE_CONV

デフォルトでは、すべての op はバージョン 1 でのみサポートされます。量子化サポートを有効にすると、ADD v2 などの適切なバージョンが有効になります。

GPU サポートのトラブルシューティング

一部の演算が GPU デリゲートでサポートされていない場合、フレームワークはグラフの一部のみを GPU で実行し、残りの部分は CPU で実行します。CPU/GPU 同期のコストが高いため、このような分割実行モードでは、ネットワーク全体を CPU のみで実行する場合よりもパフォーマンスが低下することがよくあります。この場合、次のような警告が生成されます。

WARNING: op code #42 cannot be handled by this delegate.

これは実際の実行時の失敗ではないため、このタイプの失敗に対するコールバックはありません。GPU デリゲートを使用してモデルの実行をテストする場合は、これらの警告に注意してください。これらの警告の数が多い場合は、モデルが GPU アクセラレーションに最適でなく、モデルのリファクタリングが必要である可能性があります。

サンプルモデル

次のサンプルモデルは、TensorFlow Lite で GPU アクセラレーションを利用するように構築されており、参考とテスト用に提供されています。

GPU の最適化

次の手法は、TensorFlow Lite GPU デリゲートを使用して GPU ハードウェアでモデルを実行する際のパフォーマンスを向上させるのに役立ちます。

  • 形状変更オペレーション - CPU 上で高速に実行されるオペレーションの中には、モバイル デバイスの GPU に対してコストが高くなるものがあります。BATCH_TO_SPACESPACE_TO_BATCHSPACE_TO_DEPTH などの形状変更オペレーションは、特に実行コストが高くなります。形状変更オペレーションの使用について十分に検討し、それがデータの探索またはモデルの初期のイテレーションにのみ適用された可能性があることを考慮する必要があります。これらを削除すると、パフォーマンスが大幅に向上する可能性があります。

  • 画像データ チャネル - GPU では、テンソルデータが 4 チャネルにスライスされます。したがって、形状 [B,H,W,5] のテンソルに対する計算は、形状 [B,H,W,8] のテンソルの場合とほぼ同じですが、[B,H,W,4] より大幅に劣化します。使用しているカメラ ハードウェアが RGBA の画像フレームをサポートしている場合、4 チャンネル入力をフィードすると、3 チャンネル RGB から 4 チャンネル RGBX へのメモリコピーを回避できるため、大幅に高速になります。

  • モバイル用に最適化されたモデル - 最高のパフォーマンスを得るには、モバイル用に最適化されたネットワーク アーキテクチャで分類器を再トレーニングすることを検討してください。デバイス上の推論を最適化することで、モバイル ハードウェア機能を活用することで、レイテンシと消費電力を大幅に削減できます。

高度な GPU サポート

GPU 処理で追加の高度な手法を使用すると、量子化やシリアル化など、モデルのパフォーマンスをさらに向上させることができます。以降のセクションでは、これらの手法について詳しく説明します。

量子化モデルの使用

このセクションでは、GPU デリゲートが 8 ビットの量子化モデルを高速化する方法について説明します。これには次の内容が含まれます。

パフォーマンスを最適化するには、浮動小数点入力テンソルと出力テンソルの両方を持つモデルを使用します。

ルールの仕組み

GPU バックエンドは浮動小数点数の実行のみをサポートしているため、元のモデルの「浮動小数点ビュー」を提供することで量子化モデルを実行します。大まかな流れは次のとおりです。

  • 定数テンソル(重みやバイアスなど)は、GPU メモリで一度量子化解除されます。このオペレーションは、TensorFlow Lite でデリゲートが有効になっている場合に発生します。

  • GPU プログラムへの入力と出力(8 ビットが量子化されている場合)は、推論ごとにそれぞれ量子化解除と量子化されます。この操作は、TensorFlow Lite の最適化されたカーネルを使用して CPU 上で行われます。

  • 量子化シミュレータは、量子化動作を模倣するために演算間に挿入されます。このアプローチは、活性化が量子化中に学習された境界に従うことをオペレーションが期待するモデルに必要です。

GPU デリゲートでこの機能を有効にする方法については、以下をご覧ください。

シリアル化による初期化時間の短縮

GPU デリゲート機能を使用すると、コンパイル済みのカーネルコードと、以前の実行でシリアル化してディスクに保存されたモデルデータを読み込むことができます。このアプローチにより、再コンパイルが回避され、起動時間を最大 90% 短縮できます。この改善は、ディスク容量を時間の節約に引き換えに行われます。この機能を有効にするには、次のコードサンプルに示すように、いくつかの構成オプションを使用します。

C++

    TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
    options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
    options.serialization_dir = kTmpDir;
    options.model_token = kModelToken;

    auto* delegate = TfLiteGpuDelegateV2Create(options);
    if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

Java

    GpuDelegate delegate = new GpuDelegate(
      new GpuDelegate.Options().setSerializationParams(
        /* serializationDir= */ serializationDir,
        /* modelToken= */ modelToken));

    Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
      

シリアル化機能を使用する場合は、コードが次の実装ルールに準拠していることを確認してください。

  • 他のアプリからはアクセスできないディレクトリにシリアル化データを保存します。Android デバイスでは、現在のアプリ専用の場所を指す getCodeCacheDir() を使用します。
  • モデルトークンは、特定のモデルのデバイスに対して一意である必要があります。farmhash::Fingerprint64 などのライブラリを使用して、モデルデータからフィンガープリントを生成することで、モデルトークンを計算できます。