プロファイラーを使用してTensorFlowのパフォーマンスを最適化する

このガイドでは、TensorFlowプロファイラーで利用可能なツールを使用してTensorFlowモデルのパフォーマンスを追跡する方法を示します。モデルがホスト(CPU)、デバイス(GPU)、またはホストとデバイスの両方の組み合わせでどのように機能するかを理解する方法を学習します。

プロファイリングは、モデル内のさまざまなTensorFlow操作(ops)のハードウェアリソース消費(時間とメモリ)を理解し、パフォーマンスのボトルネックを解決し、最終的にモデルの実行を高速化するのに役立ちます。

このガイドでは、プロファイラーのインストール方法、使用可能なさまざまなツール、プロファイラーがパフォーマンスデータを収集するさまざまなモード、およびモデルのパフォーマンスを最適化するための推奨されるベストプラクティスについて説明します。

あなたはクラウドのTPUのモデルのパフォーマンスをプロファイルしたい場合は、を参照してくださいクラウドTPUガイド

プロファイラーとGPUの前提条件をインストールします

TensorBoard用のプロファイラープラグインをpipでインストールします。プロファイラーには最新バージョンのTensorFlowとTensorBoard(> = 2.2)が必要であることに注意してください。

pip install -U tensorboard_plugin_profile

GPUでプロファイリングするには、次のことを行う必要があります。

  1. ミートNVIDIA®GPUドライバとに記載されているCUDA®ツールキットの要件TensorFlow GPU支援ソフトウェア要件
  2. 確認してくださいNVIDIA®CUDA®プロファイリングツールインタフェース(CUPTI)がパス上に存在します:

    /sbin/ldconfig -N -v $(sed 's/:/ /g' <<< $LD_LIBRARY_PATH) | \
    grep libcupti
    

あなたが道にCUPTIをお持ちでない場合は、へのインストールディレクトリを付加$LD_LIBRARY_PATH実行することで、環境変数:

export LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH

その後、実行ldconfig CUPTIライブラリが発見されていることを確認するために、再度上記のコマンドを。

特権の問題を解決する

あなたはドッカー環境またはLinux上CUDA®ツールキットでプロファイリングを実行すると、あなたが不足CUPTI権限(に関連する問題が発生する可能性がありCUPTI_ERROR_INSUFFICIENT_PRIVILEGES )。行くNVIDIAの開発者向けドキュメントは、Linux上でこれらの問題を解決する方法について詳しく学ぶこと。

Docker環境でのCUPTI特権の問題を解決するには、

docker run option '--privileged=true'

プロファイラーツール

あなたには、いくつかのモデルデータをキャプチャした後にのみ表示されますTensorBoardの[プロファイル]タブからアクセスプロファイラ。

プロファイラーには、パフォーマンス分析に役立つツールがいくつかあります。

  • 概要ページ
  • 入力パイプラインアナライザー
  • TensorFlow統計
  • トレースビューア
  • GPUカーネル統計
  • メモリプロファイルツール
  • ポッドビューア

概要ページ

概要ページには、プロファイルの実行中にモデルがどのように実行されたかのトップレベルのビューが表示されます。このページには、ホストとすべてのデバイスの概要ページと、モデルトレーニングのパフォーマンスを向上させるためのいくつかの推奨事項が表示されます。 [ホスト]ドロップダウンで個々のホストを選択することもできます。

概要ページには、次のようにデータが表示されます。

画像

  • パフォーマンス・サマリー:表示モデルのパフォーマンスの高レベルな概要。パフォーマンスの概要には2つの部分があります。

    1. ステップ時間の内訳:平均ステップ時間を、時間が費やされた場所の複数のカテゴリに分類します。

      • コンパイル:カーネルのコンパイルに費やされた時間。
      • 入力:入力データの読み取りに費やされた時間。
      • 出力:出力データの読み取りに費やされた時間。
      • カーネルの起動:ホストがカーネルを起動するために費やした時間
      • ホストの計算時間。
      • デバイス間の通信時間。
      • デバイス上の計算時間。
      • Pythonのオーバーヘッドを含む他のすべて。
    2. デバイス計算の精度-16ビットおよび32ビットの計算を使用するデバイス計算時間の割合を報告します。

  • ステップ時間グラフ:サンプリングされた全工程にわたって表示(ミリ秒)デバイス工程時間のグラフ。各ステップは、時間が費やされる場所の複数のカテゴリ(異なる色)に分けられます。赤い領域は、デバイスがホストからの入力データを待機してアイドル状態になっていたステップ時間の部分に対応します。緑の領域は、デバイスが実際に動作していた時間を示しています。

  • デバイス上のトップ10 TensorFlow操作(例えばGPU):最長を実行した表示オンデバイスOPS。

    各行には、操作の自己時間(すべての操作にかかった時間のパーセンテージとして)、累積時間、カテゴリ、および名前が表示されます。

  • 実行環境:ディスプレイを含むモデルの実行環境の高レベルな概要:

    • 使用されたホストの数。
    • デバイスタイプ(GPU / TPU)。
    • デバイスコアの数。
  • 次のステップのための推奨事項:モデルは入力バインドされ、ツールを推奨していますレポートしたときに見つけて解決モデルのパフォーマンスのボトルネックに使用することができます。

入力パイプラインアナライザー

TensorFlowプログラムがファイルからデータを読み取ると、パイプライン方式でTensorFlowグラフの上部から開始されます。読み取りプロセスは、直列に接続された複数のデータ処理ステージに分割され、1つのステージの出力が次のステージへの入力になります。データ読み出しのこのシステムは、入力パイプラインと呼ばれています。

ファイルからレコードを読み取るための一般的なパイプラインには、次の段階があります。

  1. ファイルの読み取り。
  2. ファイルの前処理(オプション)。
  3. ホストからデバイスへのファイル転送。

非効率的な入力パイプラインは、アプリケーションの速度を大幅に低下させる可能性があります。それが入力されたパイプラインで時間の大部分を費やしているときに、アプリケーションは、入力バインドと考えられています。入力パイプラインアナライザーから得られた洞察を使用して、入力パイプラインが非効率的な場所を理解します。

入力パイプラインアナライザーは、プログラムが入力バウンドであるかどうかを即座に通知し、デバイス側とホスト側の分析をガイドして、入力パイプラインの任意の段階でパフォーマンスのボトルネックをデバッグします。

データ入力パイプラインを最適化するための推奨されるベストプラクティスについては、入力パイプラインのパフォーマンスに関するガイダンスを確認してください。

入力パイプラインダッシュボード

入力パイプライン・アナライザは、[プロファイルを開くには、[ツール]ドロップダウンからinput_pipeline_analyzerを選択します。

画像

ダッシュボードには次の3つのセクションがあります。

  1. 概要:どのくらいで、もしそうであれば、あなたのアプリケーションは、入力バインドされているかどうかについての情報と、全体的な入力パイプラインを要約して。
  2. デバイス側の分析:詳細を表示し、デバイス工程時間と、各ステップでコア間の入力データの待機に費やさデバイス時間の範囲を含む装置側解析結果、。
  3. ホスト側解析:ショーのホスト上の入力処理時間の内訳を含め、ホスト側の詳細な分析、。

入力パイプラインの概要

あなたのプログラムは、ホストからの入力待ちに費やさデバイス時間の割合を提示することによって束縛入力された場合の概要を報告します。インストルメント化された標準入力パイプラインを使用している場合、ツールは入力処理時間のほとんどが費やされた場所を報告します。

デバイス側の分析

デバイス側の分析は、デバイスとホストで費やされた時間、およびホストからの入力データの待機に費やされたデバイス時間に関する洞察を提供します。

  1. ステップ時間ステップ数に対してプロット:サンプリングされた全ての工程にわたって(ミリ秒)デバイス工程時間のグラフを表示します。各ステップは、時間が費やされる場所の複数のカテゴリ(異なる色)に分けられます。赤い領域は、デバイスがホストからの入力データを待機してアイドル状態になっていたステップ時間の部分に対応します。緑の領域は、デバイスが実際に動作していた時間を示しています。
  2. ステップ時間統計:平均、標準偏差を報告し、デバイス工程の時間の範囲([最小、最大])。

ホスト側の分析

ホスト側の分析では、入力処理時間(に費やされた時間の内訳を報告しtf.dataいくつかのカテゴリにホスト上のAPIのOPSを):

  • オンデマンドでファイルからデータを読み込む:時間は、キャッシングなしでファイルからデータを読み取るプリフェッチ、およびインターリーブに費やさ。
  • 事前にファイルからデータを読み込む:時間は、キャッシュを含むプリフェッチ、およびインターリーブ、ファイルの読み込み過ごしました。
  • データは前処理:そのような画像伸長としてOPSを、前処理に費やされた時間を。
  • デバイスに転送されるデータをエンキュー:時間は、デバイスにデータを転送する前に、送り込みキューにデータを入れて過ごしました。

実行時間によって破壊個々の入力OPSとそのカテゴリの統計を検査する入力オペアンプ統計を展開します。

画像

ソースデータテーブルが表示され、各エントリには次の情報が含まれています。

  1. 入力オペアンプ:入力オペアンプのショーTensorFlowオペアンプ名。
  2. カウント:ショーOP実行のインスタンスの総数をプロファイリング期間中に。
  3. 合計時間(ミリ秒)は:それらのインスタンスのそれぞれに費やされた時間の累積合計を表示します。
  4. 合計時間は、%:ショー入力処理に費やされた合計時間の割合としてOPに費やされた合計時間を。
  5. (ミリ秒)の合計セルフタイムは:それらのインスタンスのそれぞれに費やさ自己時間の累積合計を表示します。ここでの自己時間は、関数本体内で費やされた時間を測定します。ただし、関数が呼び出す関数で費やされた時間は除きます。
  6. 合計セルフタイム%。合計セルフタイムを、入力処理に費やされた合計時間の一部として表示します。
  7. カテゴリー。入力操作の処理カテゴリを表示します。

TensorFlow統計

TensorFlow Statsツールは、プロファイリングセッション中にホストまたはデバイスで実行されるすべてのTensorFlow op(op)のパフォーマンスを表示します。

画像

このツールは、パフォーマンス情報を2つのペインに表示します。

  • 上部のペインには、最大4つの円グラフが表示されます。

    1. ホスト上の各操作の自己実行時間の分布。
    2. ホスト上の各opタイプの自己実行時間の分布。
    3. デバイス上の各操作の自己実行時間の分布。
    4. デバイス上の各opタイプの自己実行時間の分布。
  • 下のペインには、TensorFlow操作に関するデータをレポートするテーブルが表示されます。操作ごとに1行、データの種類ごとに1列です(列の見出しをクリックして列を並べ替えます)。 CSVファイルとしてこの表からデータをエクスポートするために、上のペインの右側にある[エクスポートCSVとしてボタンをクリックします。

    ご了承ください:

    • いずれかのオペレーションに子オペレーションがある場合:

      • オペレーションの「累積」時間の合計には、子オペレーション内で費やされた時間が含まれます。

      • オペレーションの合計「自己」時間には、子オペレーション内で費やされた時間は含まれません。

    • ホストでopが実行される場合:

      • 操作によって発生したデバイスの合計セルフタイムのパーセンテージは0になります。
      • この操作までのデバイスの合計セルフタイムの累積パーセンテージは0になります。
    • デバイスで操作が実行される場合:

      • この操作によって発生したホストでの合計セルフタイムのパーセンテージは0になります。
      • この操作までのホストでの合計セルフタイムの累積パーセンテージは0になります。

円グラフと表にアイドル時間を含めるか除外するかを選択できます。

トレースビューア

トレースビューアには、次のようなタイムラインが表示されます。

  • TensorFlowモデルによって実行された操作の期間
  • システムのどの部分(ホストまたはデバイス)が操作を実行したか。通常、ホストは入力操作を実行し、トレーニングデータを前処理してデバイスに転送しますが、デバイスは実際のモデルトレーニングを実行します。

トレースビューアを使用すると、モデルのパフォーマンスの問題を特定し、それらを解決するための手順を実行できます。たとえば、大まかに言えば、入力トレーニングとモデルトレーニングのどちらが大部分の時間を費やしているかを特定できます。ドリルダウンすると、実行に最も時間がかかる操作を特定できます。トレースビューアは、デバイスごとに100万イベントに制限されていることに注意してください。

トレースビューアインターフェイス

トレースビューアを開くと、最新の実行が表示されます。

画像

この画面には、次の主要な要素が含まれています。

  1. タイムラインペイン:デバイスとホストは時間をかけて実行することを示しているオプス。
  2. 詳細ペイン:タイムラインパネルで選択したオペレーションのためのショーの追加情報。

タイムラインペインには、次の要素が含まれています。

  1. トップバー:様々な補助コントロールが含まれています。
  2. 時間軸:トレースの先頭にショーの時間を相対的に。
  3. セクションとトラックラベル:各セクションは、複数のトラックが含まれており、セクションを展開したり折りたたんだりするためにクリックすることを左の三角形を持っています。システム内の処理要素ごとに1つのセクションがあります。
  4. ツールセレクタは:なズーム、パン、選択、およびタイミングなどの微量ビューアと対話するためのさまざまなツールが含まれています。タイミングツールを使用して、時間間隔をマークします。
  5. イベント:これらのショーOPが実行された時間や、そのような訓練の手順としてメタイベントの期間。
セクションとトラック

トレースビューアには、次のセクションが含まれています。

  • デバイスチップと、チップ内のデバイスノード(例えば、数で標識された各デバイスノードの一のセクション/device:GPU:0 (pid 0) )。各デバイスノードセクションには、次のトラックが含まれています。
    • ステップは:デバイス上で実行されていた訓練段階の継続時間を表示します
    • TensorFlowオプス:ショーのデバイス上で実行さOPS
    • XLAオプス:ショーXLAのXLAを使用コンパイラである場合、デバイス上のRANがそのオペレーション(OPS)(各TensorFlow OPは1つまたはいくつかのXLAオプスに翻訳されるXLAコンパイラは、デバイス上で実行するコードにXLAオプスを変換します。)。
  • ホストマシンのCPU上で実行中のスレッドの一つのセクションでは、「ホストのスレッドを」ラベル。このセクションには、CPUスレッドごとに1つのトラックが含まれています。セクションラベルの横に表示される情報は無視してかまいません。
イベント

タイムライン内のイベントはさまざまな色で表示されます。色自体には特別な意味はありません。

トレースビューアは、TensorFlowプログラムでPython関数呼び出しのトレースを表示することもできます。あなたが使用している場合はtf.profiler.experimental.start APIを、あなたが使用して、トレースのPythonを有効にすることができProfilerOptionsプロファイリングを開始するときnamedtupleを。あなたがプロファイリングするためのサンプリングモードを使用している場合あるいは、あなたはキャプチャプロファイル]ダイアログボックスのドロップダウンオプションを使用して、トレースのレベルを選択することができます。

画像

GPUカーネル統計

このツールは、すべてのGPUアクセラレーションカーネルのパフォーマンス統計と元の操作を表示します。

画像

このツールは、次の2つのペインに情報を表示します。

  • 上のペインには、合計経過時間が最も長いCUDAカーネルを示す円グラフが表示されます。

  • 下のペインには、一意のカーネルと操作のペアごとに次のデータを含むテーブルが表示されます。

    • カーネルと操作のペアでグループ化された、GPUの合計経過時間の降順でのランク。
    • 起動されたカーネルの名前。
    • カーネルによって使用されるGPUレジスタの数。
    • 使用される共有(静的+動的共有)メモリの合計サイズ(バイト単位)。
    • ブロックの寸法は、として表現blockDim.x, blockDim.y, blockDim.z
    • グリッドの寸法はとして表さgridDim.x, gridDim.y, gridDim.z
    • opが使用する資格があるかどうかテンソルコアを
    • カーネルにTensorCore命令が含まれているかどうか。
    • このカーネルを起動したopの名前。
    • このkernel-opペアの発生数。
    • 経過したGPUの合計時間(マイクロ秒単位)。
    • マイクロ秒単位の平均経過GPU時間。
    • マイクロ秒単位の最小経過GPU時間。
    • マイクロ秒単位の最大経過GPU時間。

メモリプロファイルツール

メモリープロファイルツールを監視プロファイル間隔中にお使いのデバイスのメモリ使用量。このツールを使用して、次のことができます。

  • ピークメモリ使用量とそれに対応するTensorFlowopsへのメモリ割り当てを特定することにより、メモリ不足(OOM)の問題をデバッグします。また、あなたが実行したときに発生する可能性がOOMの問題をデバッグすることができますマルチテナント推論を。
  • デバッグメモリの断片化の問題。

メモリプロファイルツールは、次の3つのセクションにデータを表示します。

  1. メモリプロファイルの概要
  2. メモリタイムライングラフ
  3. メモリ内訳表

メモリプロファイルの概要

このセクションには、以下に示すように、TensorFlowプログラムのメモリプロファイルの概要が表示されます。

メモリプロファイルの概要には、次の6つのフィールドがあります。

  1. メモリID:ドロップダウン使用可能なすべてのデバイスのメモリシステムを示しています。ドロップダウンから表示するメモリシステムを選択します。
  2. #Allocation:プロファイル間隔中に行われたメモリ割り当ての数。
  3. #Deallocation:プロファイル間隔のメモリ割り当て解除の数
  4. メモリ容量:選択したことを、メモリシステムの(ジブ)で総容量。
  5. ピークヒープ使用量:(ジブでの)ピークメモリ使用量モデルが稼働し始めてから。
  6. ピークメモリ使用量:(ジブでの)ピークメモリ使用量プロファイル間隔インチこのフィールドには、次のサブフィールドが含まれています。
    1. タイムスタンプ:ピークメモリ使用量は、タイムライングラフ上で発生した時点のタイムスタンプ。
    2. スタック予約:(ジブ)でスタック上に確保したメモリの量。
    3. ヒープ割り当て:(ジブで)ヒープ上に割り当てられたメモリの量。
    4. 空きメモリ:空きメモリの量(ジブで)。メモリ容量は、スタック予約、ヒープ割り当て、および空きメモリの合計です。
    5. フラグメンテーション:フラグメンテーションの割合(低い方がよいです)。これは、の割合として計算される(1 - Size of the largest chunk of free memory / Total free memory)

メモリタイムライングラフ

このセクションには、メモリ使用量(GiB単位)と時間に対する断片化の割合(ミリ秒単位)のプロットが表示されます。

画像

X軸は、プロファイリング間隔のタイムライン(ミリ秒単位)を表します。左側のY軸はメモリ使用量(GiB単位)を表し、右側のY軸は断片化の割合を表します。 X軸の各時点で、合計メモリは、スタック(赤)、ヒープ(オレンジ)、および空き(緑)の3つのカテゴリに分類されます。特定のタイムスタンプにカーソルを合わせると、その時点でのメモリ割り当て/割り当て解除イベントの詳細が次のように表示されます。

画像

ポップアップウィンドウに次の情報が表示されます。

  • タイムスタンプ(ミリ秒):タイムライン上で選択したイベントの場所。
  • イベント:イベントの種類(割り当てまたは割り当て解除)。
  • requested_size(ジブ):メモリの量は、要求されました。これは、割り当て解除イベントの場合は負の数になります。
  • allocation_size(ジブ):割り当てられたメモリの実際の量。これは、割り当て解除イベントの場合は負の数になります。
  • tf_op:割り当て/割り当て解除を要求TensorFlowオペアンプ。
  • STEP_ID:このイベントが発生した訓練ステップを。
  • region_type:この割り当てられたメモリの元となったデータエンティティタイプ。可能な値はtemp一時ため、 outputアクティベーションおよび勾配のため、およびpersist / dynamic重みと定数のために。
  • DATA_TYPE:テンソル要素のタイプ(例えば、UINT8 8ビットの符号なし整数の場合)。
  • tensor_shape:テンソルの形状が割り当てられる/割り当て解除。
  • memory_in_use(ジブ):この時点で使用されている総メモリ。

メモリ内訳表

この表は、プロファイリング間隔のピークメモリ使用量の時点でのアクティブなメモリ割り当てを示しています。

画像

TensorFlow Opごとに1つの行があり、各行には次の列があります。

  • オペアンプ名前:TensorFlow OPの名前。
  • 割り当てサイズ(ジブ):このオペレーションに割り当てられたメモリの合計量。
  • 要求されたサイズ(ジブ):このオペレーションのために要求されたメモリの総量。
  • 出現:このオペレーションのための割り当ての数。
  • リージョンのタイプ:この割り当てられたメモリの元となったデータエンティティタイプ。可能な値はtemp一時ため、 outputアクティベーションおよび勾配のため、およびpersist / dynamic重みと定数のために。
  • データ型:テンソル要素の型。
  • 形状:割り当てテンソルの形状を。

ポッドビューア

ポッドビューアツールは、すべてのワーカーにわたるトレーニングステップの内訳を表示します。

画像

  • 上部のペインには、ステップ番号を選択するためのスライダーがあります。
  • 下のペインには、積み上げ縦棒グラフが表示されます。これは、上下に配置されたステップタイムカテゴリの内訳の概要です。積み重ねられた各列は、一意のワーカーを表します。
  • 積み重ねられた列にカーソルを合わせると、左側のカードにステップの内訳の詳細が表示されます。

tf.dataボトルネック分析

tf.dataボトルネック分析ツールが自動的にボトルネックを検出しtf.dataあなたのプログラムで入力パイプラインと、それらを解決する方法に関する推奨事項を提供します。これは、使用して任意のプログラムで動作tf.dataプラットフォームに関係なく(CPU / GPU / TPU)の。その分析と提言はこれに基づいているガイド

次の手順に従ってボトルネックを検出します。

  1. 最も入力が多いホストを見つけます。
  2. 最も遅い実行して下さいtf.data入力パイプラインを。
  3. プロファイラートレースから入力パイプライングラフを再構築します。
  4. 入力パイプライングラフでクリティカルパスを見つけます。
  5. クリティカルパス上で最も遅い変換をボトルネックとして特定します。

パフォーマンス分析の概要は、すべての入力パイプライン及び入力パイプライングラフの概要:UIは、3つのセクションに分かれています。

パフォーマンス分析の要約

画像

このセクションでは、分析の概要を説明します。それは遅いについて報告tf.dataプロファイルで検出された入力パイプライン。このセクションでは、入力が最も多いホストと、待ち時間が最大の最も遅い入力パイプラインも示します。最も重要なことは、入力パイプラインのどの部分がボトルネックであり、それを修正する方法を特定することです。ボトルネック情報は、イテレータタイプとそのロングネームで提供されます。

tf.dataイテレータの長い名前の読み方

長い名前は次のようにフォーマットされIterator::<Dataset_1>::...::<Dataset_n>長い名前で、 <Dataset_n>イテレータ型と一致し、長い名前の他のデータセットは、下流の変換を表します。

たとえば、次の入力パイプラインデータセットについて考えてみます。

dataset = tf.data.Dataset.range(10).map(lambda x: x).repeat(2).batch(5)

上記のデータセットのイテレータの長い名前は次のようになります。

イテレータタイプロングネーム
範囲Iterator :: Batch :: Repeat :: Map :: Range
地図Iterator :: Batch :: Repeat :: Map
繰り返すIterator :: Batch :: Repeat
バッチイテレータ::バッチ

すべての入力パイプラインの概要

画像

このセクションでは、すべてのホストにわたるすべての入力パイプラインの概要を示します。通常、入力パイプラインは1つです。配布戦略を使用する場合は、プログラムの実行中のホスト入力パイプラインがあるtf.dataコードとホスト入力パイプラインからデータを取得し、デバイスに転送する複数のデバイスの入力パイプライン。

入力パイプラインごとに、実行時間の統計が表示されます。 50μsより長くかかる場合、通話は低速としてカウントされます。

入力パイプライングラフ

画像

このセクションには、実行時間情報を含む入力パイプライングラフが表示されます。 「ホスト」と「入力パイプライン」を使用して、表示するホストと入力パイプラインを選択できます。入力パイプラインの実行は、あなたがランクドロップダウン使用して選択することができます降順で実行時間によってソートされています。

画像

クリティカルパス上のノードには太字の輪郭があります。クリティカルパス上でセルフタイムが最も長いノードであるボトルネックノードには、赤い輪郭が表示されます。他の重要ではないノードには、灰色の破線の輪郭があります。

各ノードで、開始時間は、実行の開始時間を示します。存在する場合、同じノードは、例えば、複数回実行することができるBatch入力パイプラインのOPが。複数回実行する場合は、最初の実行の開始時刻になります。

合計時間は、実行の壁の時間です。複数回実行された場合は、すべての実行のウォール時間の合計です。

セルフタイムは、その直接の子ノードと重複することなく、時間の合計時間です。

「#Calls」は、入力パイプラインが実行された回数です。

パフォーマンスデータを収集する

TensorFlow Profilerは、TensorFlowモデルのホストアクティビティとGPUトレースを収集します。プログラマティックモードまたはサンプリングモードのいずれかを介してパフォーマンスデータを収集するようにプロファイラーを構成できます。

プロファイリングAPI

次のAPIを使用してプロファイリングを実行できます。

  • TensorBoard Kerasコールバックを使用して、プログラムモード( tf.keras.callbacks.TensorBoard

    # Profile from batches 10 to 15
    tb_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir,
                                                 profile_batch='10, 15')
    
    # Train the model and use the TensorBoard Keras callback to collect
    # performance profiling data
    model.fit(train_data,
              steps_per_epoch=20,
              epochs=5,
              callbacks=[tb_callback])
    
  • 使用して、プログラムモードtf.profilerファンクションAPIを

    tf.profiler.experimental.start('logdir')
    # Train the model here
    tf.profiler.experimental.stop()
    
  • コンテキストマネージャーを使用したプログラムモード

    with tf.profiler.experimental.Profile('logdir'):
        # Train the model here
        pass
    

  • サンプリングモード:オンデマンド使用してプロファイリングを実行tf.profiler.experimental.server.startごTensorFlowモデルの実行とgRPCサーバを起動します。 gRPCサーバを起動し、モデルを実行した後、あなたはTensorBoardプロファイルプラグインでキャプチャプロファイルボタンからプロファイルをキャプチャすることができます。上記の「プロファイラーのインストール」セクションのスクリプトを使用して、TensorBoardインスタンスがまだ実行されていない場合は起動します。

    例として、

    # Start a profiler server before your model runs.
    tf.profiler.experimental.server.start(6009)
    # (Model code goes here).
    #  Send a request to the profiler server to collect a trace of your model.
    tf.profiler.experimental.client.trace('grpc://localhost:6009',
                                          'gs://your_tb_logdir', 2000)
    

    複数のワーカーをプロファイリングする例:

    # E.g. your worker IP addresses are 10.0.0.2, 10.0.0.3, 10.0.0.4, and you
    # would like to profile for a duration of 2 seconds.
    tf.profiler.experimental.client.trace(
        'grpc://10.0.0.2:8466,grpc://10.0.0.3:8466,grpc://10.0.0.4:8466',
        'gs://your_tb_logdir',
        2000)
    

指定するには、キャプチャプロファイル]ダイアログボックスを使用します。

  • プロファイルサービスのURLまたはTPU名のコンマ区切りのリスト。
  • プロファイリング期間。
  • デバイス、ホスト、およびPython関数呼び出しトレースのレベル。
  • 最初に失敗した場合に、プロファイラーがプロファイルのキャプチャを再試行する回数。

カスタムトレーニングループのプロファイリング

あなたのTensorFlowコードでカスタムトレーニングループをプロファイルするには、機器とのトレーニングループtf.profiler.experimental.Trace APIは、プロファイラのためのステップの境界をマークします。

name引数はステップ名の接頭辞として使用され、 step_numキーワード引数は、ステップ名に追加されており、 _rキーワード引数は、このトレース・イベントがプロファイラによってステップイベントとして処理されますなります。

例として、

for step in range(NUM_STEPS):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_data = next(dataset)
        train_step(train_data)

これにより、プロファイラーのステップベースのパフォーマンス分析が有効になり、ステップイベントがトレースビューアーに表示されます。

あなたは内のデータセットのイテレータが含まれていることを確認しますtf.profiler.experimental.Trace入力パイプラインの正確な分析のためのコンテキストを。

以下のコードスニペットはアンチパターンです。

for step, train_data in enumerate(dataset):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_step(train_data)

プロファイリングのユースケース

プロファイラーは、4つの異なる軸に沿った多くのユースケースをカバーしています。現在サポートされている組み合わせもあれば、将来追加される組み合わせもあります。いくつかのユースケースは次のとおりです。

  • ローカル対リモートプロファイリング:これらはあなたのプロファイリング環境の設定の2つの一般的な方法です。ローカルプロファイリングでは、プロファイリングAPIは、モデルが実行しているのと同じマシンで呼び出されます。たとえば、GPUを備えたローカルワークステーションです。リモートプロファイリングでは、プロファイリングAPIは、モデルが実行されているマシンとは別のマシン(Cloud TPUなど)で呼び出されます。
  • 複数の労働者をプロファイリング:TensorFlowの分散訓練機能を使用するときは、複数のマシンをプロファイリングすることができます。
  • ハードウェアプラットフォーム:プロファイルのCPU、GPUは、とのTPU。

以下の表は、上記のTensorFlowでサポートされているユースケースの概要を示しています。

プロファイリングAPI地元リモート複数の労働者ハードウェアプラットフォーム
TensorBoardKerasコールバックサポートされていますサポートされていませんサポートされていませんCPU、GPU
tf.profiler.experimentalスタート/ストップAPIサポートされていますサポートされていませんサポートされていませんCPU、GPU
tf.profiler.experimental client.traceのAPIサポートされていますサポートされていますサポートされていますCPU、GPU、TPU
コンテキストマネージャーAPIサポートされていますサポートされていませんサポートされていませんCPU、GPU

最適なモデルパフォーマンスのためのベストプラクティス

最適なパフォーマンスを実現するには、TensorFlowモデルに該当する次の推奨事項を使用してください。

一般に、デバイスですべての変換を実行し、プラットフォームにcuDNNやIntelMKLなどの最新の互換性のあるバージョンのライブラリを使用していることを確認します。

入力データパイプラインを最適化する

[#input_pipeline_analyzer]のデータを使用して、データ入力パイプラインを最適化します。効率的なデータ入力パイプラインは、デバイスのアイドル時間を短縮することにより、モデルの実行速度を大幅に向上させることができます。で詳述ベストプラクティス組み込むようにしてくださいtf.dataのAPIとのより良い性能データ入力パイプラインは、より効率的にするためのガイドと下のを。

  • 一般に、順次実行する必要のない操作を並列化すると、データ入力パイプラインを大幅に最適化できます。

  • 多くの場合、一部の呼び出しの順序を変更したり、モデルに最適になるように引数を調整したりするのに役立ちます。入力データパイプラインを最適化する一方で、トレーニングとバックプロパゲーションの手順を行わずにデータローダーのみをベンチマークして、最適化の効果を個別に定量化します。

  • 合成データを使用してモデルを実行し、入力パイプラインがパフォーマンスのボトルネックであるかどうかを確認してください。

  • 使用tf.data.Dataset.shardマルチGPUのトレーニングのために。スループットの低下を防ぐために、入力ループの非常に早い段階でシャーディングするようにしてください。 TFRecordを操作するときは、TFRecordの内容ではなく、TFRecordのリストをシャーディングするようにしてください。

  • 動的に値設定することにより、いくつかのオペレーションを並列化num_parallel_calls使用してtf.data.AUTOTUNE

  • 利用制限を検討tf.data.Dataset.from_generator 、それは純粋なTensorFlowオプスに比べて遅くなるよう。

  • 利用制限を検討tf.py_function 、それをシリアル化することができず、分散TensorFlowで実行するためにサポートされていないよう。

  • 使用tf.data.Options入力パイプラインへの静的な最適化を制御します。

また、読みtf.dataパフォーマンス分析ガイドご入力パイプラインの最適化の詳細についてのガイダンスを。

データ拡張を最適化する

画像データを扱う場合、あなたの作るデータの増強など、トリミング、などフリップなどの空間変換を、適用した後に別のデータ型にキャスト回転させることにより、より効率的に

NVIDIA®DALIを使用する

GPUとCPUの比率が高いシステムを使用している場合など、場合によっては、CPUサイクルの制限によって引き起こされるデータローダーのボトルネックを解消するには、上記のすべての最適化では不十分な場合があります。

あなたはコンピュータビジョンとオーディオ深い学習アプリケーションのためのNVIDIA®のGPUを使用している場合は、データのロード・ライブラリー(使用を検討してDALIのデータパイプラインを加速します)。

チェックオペレーション:NVIDIA®DALIサポートDALIオプスのリストのドキュメントを。

スレッド化と並列実行を使用する

複数のCPUスレッドの実行OPS tf.config.threading高速化、それらを実行するためのAPI。

TensorFlowは、デフォルトで並列処理スレッドの数を自動的に設定します。 TensorFlow opsの実行に使用できるスレッドプールは、使用可能なCPUスレッドの数によって異なります。

使用して、単一のオペアンプの最大並列高速化を制御tf.config.threading.set_intra_op_parallelism_threads 。複数のopsを並行して実行する場合、それらはすべて使用可能なスレッドプールを共有することに注意してください。

あなたは独立した非ブロックオプス(グラフ上でそれらの間には有向パスを持つOPS)を持っている場合は、使用tf.config.threading.set_inter_op_parallelism_threads同時に利用できるスレッドプールを使用してそれらを実行します。

その他

NVIDIA®のGPU上の小さいモデルで作業するときは、設定することができtf.compat.v1.ConfigProto.force_gpu_compatible=Trueモデルのパフォーマンスに大きな弾みをつけるためにCUDA固定メモリに割り当てられるために、すべてのCPUテンソルを強制します。ただし、不明なモデルや非常に大きなモデルにこのオプションを使用する場合は、ホスト(CPU)のパフォーマンスに悪影響を与える可能性があるため注意してください。

デバイスのパフォーマンスを向上させる

こことで詳述ベストプラクティスに従って、 GPUのパフォーマンスの最適化ガイド最適化オンデバイスTensorFlowモデルのパフォーマンスにします。

NVIDIA GPUを使用している場合は、次のコマンドを実行して、GPUとメモリ使用率をCSVファイルに記録します。

nvidia-smi
--query-gpu=utilization.gpu,utilization.memory,memory.total,
memory.free,memory.used --format=csv

データレイアウトを構成する

チャネル情報(画像など)を含むデータを操作する場合は、データレイアウト形式を最適化して、チャネルが最後になるようにします(NCHWよりNHWC)。

チャネル・最後のデータフォーマットが改善テンソルコア利用をし、AMPと相まって、特に畳み込みモデルの大幅なパフォーマンス向上を提供します。 NCHWデータレイアウトは引き続きTensorCoreで操作できますが、自動転置操作のために追加のオーバーヘッドが発生します。

あなたは、設定することにより、NHWCレイアウトを好むためにデータレイアウトを最適化することができdata_format="channels_last"のような層にtf.keras.layers.Conv2Dtf.keras.layers.Conv3D 、およびtf.keras.layers.experimental.preprocessing.RandomRotation

使用tf.keras.backend.set_image_data_format KerasバックエンドAPIのデフォルトのデータレイアウトのフォーマットを設定します。

L2キャッシュを最大限に活用する

When working with NVIDIA® GPUs, execute the code snippet below before the training loop to max out the L2 fetch granularity to 128 bytes.

import ctypes

_libcudart = ctypes.CDLL('libcudart.so')
# Set device limit on the current device
# cudaLimitMaxL2FetchGranularity = 0x05
pValue = ctypes.cast((ctypes.c_int*1)(), ctypes.POINTER(ctypes.c_int))
_libcudart.cudaDeviceSetLimit(ctypes.c_int(0x05), ctypes.c_int(128))
_libcudart.cudaDeviceGetLimit(pValue, ctypes.c_int(0x05))
assert pValue.contents.value == 128

Configure GPU thread usage

The GPU thread mode decides how GPU threads are used.

Set the thread mode to gpu_private to make sure that preprocessing does not steal all the GPU threads. This will reduce the kernel launch delay during training. You can also set the number of threads per GPU. Set these values using environment variables.

import os

os.environ['TF_GPU_THREAD_MODE']='gpu_private'
os.environ['TF_GPU_THREAD_COUNT']='1'

Configure GPU memory options

In general, increase the batch size and scale the model to better utilize GPUs and get higher throughput. Note that increasing the batch size will change the model's accuracy so the model needs to be scaled by tuning hyperparameters like the learning rate to meet the target accuracy.

Also, use tf.config.experimental.set_memory_growth to allow GPU memory to grow to prevent all the available memory from being fully allocated to ops that require only a fraction of the memory. This allows other processes which consume GPU memory to run on the same device.

To learn more, check out the Limiting GPU memory growth guidance in the GPU guide to learn more.

Miscellaneous

  • Increase the training mini-batch size (number of training samples used per device in one iteration of the training loop) to the maximum amount that fits without an out of memory (OOM) error on the GPU. Increasing the batch size impacts the model's accuracy—so make sure you scale the model by tuning hyperparameters to meet the target accuracy.

  • Disable reporting OOM errors during tensor allocation in production code. Set report_tensor_allocations_upon_oom=False in tf.compat.v1.RunOptions .

  • For models with convolution layers, remove bias addition if using batch normalization. Batch normalization shifts values by their mean and this removes the need to have a constant bias term.

  • Use TF Stats to find out how efficiently on-device ops run.

  • Use tf.function to perform computations and optionally, enable the jit_compile=True flag ( tf.function(jit_compile=True ). To learn more, go to Use XLA tf.function .

  • Minimize host Python operations between steps and reduce callbacks. Calculate metrics every few steps instead of at every step.

  • Keep the device compute units busy.

  • Send data to multiple devices in parallel.

  • Consider using 16-bit numerical representations , such as fp16 —the half-precision floating point format specified by IEEE—or the Brain floating-point bfloat16 format.

Additional resources

Known limitations

Profiling multiple GPUs on TensorFlow 2.2 and TensorFlow 2.3

TensorFlow 2.2 and 2.3 support multiple GPU profiling for single host systems only; multiple GPU profiling for multi-host systems is not supported. To profile multi-worker GPU configurations, each worker has to be profiled independently. From TensorFlow 2.4 multiple workers can be profiled using the tf.profiler.experimental.client.trace API.

CUDA® Toolkit 10.2 or later is required to profile multiple GPUs. As TensorFlow 2.2 and 2.3 support CUDA® Toolkit versions only up to 10.1, you need to create symbolic links to libcudart.so.10.1 and libcupti.so.10.1 :

sudo ln -s /usr/local/cuda/lib64/libcudart.so.10.2 /usr/local/cuda/lib64/libcudart.so.10.1
sudo ln -s /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.2 /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.1