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

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

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

一部の op が 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 の画像フレームをサポートしている場合、3 チャンネル RGB から 4 チャンネル RGBX へのメモリコピーを回避できるため、その 4 チャンネル入力にフィードするまでの時間が大幅に短縮されます。

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

高度な 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 などのライブラリを使用してモデルデータからフィンガープリントを生成します。