日付を保存! Google I / Oが5月18日から20日に戻ってきます今すぐ登録
このページは Cloud Translation API によって翻訳されました。
Switch to English

TensorFlowプロファイラー:プロファイルモデルのパフォーマンス

TensorFlow.orgで表示 GoogleColabで実行 GitHubでソースを表示ノートブックをダウンロードする

概要概要

機械学習アルゴリズムは通常、計算コストが高くなります。したがって、機械学習アプリケーションのパフォーマンスを定量化して、モデルの最適化されたバージョンを実行していることを確認することが重要です。 TensorFlow Profilerを使用して、TensorFlowコードの実行をプロファイリングします。

セットアップ

from datetime import datetime
from packaging import version

import os

TensorFlow Profilerには、最新バージョンのTensorFlowとTensorBoard( >=2.2 )が必要です。

pip install -U tensorboard_plugin_profile
import tensorflow as tf

print("TensorFlow version: ", tf.__version__)
TensorFlow version:  2.2.0-dev20200405

TensorFlowがGPUにアクセスできることを確認します。

device_name = tf.test.gpu_device_name()
if not device_name:
  raise SystemError('GPU device not found')
print('Found GPU at: {}'.format(device_name))
Found GPU at: /device:GPU:0

TensorBoardコールバックを使用して画像分類モデルをトレーニングする

このチュートリアルでは、 MNISTデータセット内の画像を分類するためにモデルをトレーニングすることによって取得されたパフォーマンスプロファイルをキャプチャすることにより、TensorFlowプロファイラーの機能を探索します。

TensorFlowデータセットを使用してトレーニングデータをインポートし、トレーニングセットとテストセットに分割します。

import tensorflow_datasets as tfds
tfds.disable_progress_bar()
(ds_train, ds_test), ds_info = tfds.load(
    'mnist',
    split=['train', 'test'],
    shuffle_files=True,
    as_supervised=True,
    with_info=True,
)
WARNING:absl:Dataset mnist is hosted on GCS. It will automatically be downloaded to your
local data directory. If you'd instead prefer to read directly from our public
GCS bucket (recommended if you're running on GCP), you can instead set
data_dir=gs://tfds-data/datasets.
Downloading and preparing dataset mnist/3.0.0 (download: 11.06 MiB, generated: Unknown size, total: 11.06 MiB) to /root/tensorflow_datasets/mnist/3.0.0...
Dataset mnist downloaded and prepared to /root/tensorflow_datasets/mnist/3.0.0. Subsequent calls will reuse this data.

ピクセル値を0から1の間に正規化することにより、トレーニングデータとテストデータを前処理します。

def normalize_img(image, label):
  """Normalizes images: `uint8` -> `float32`."""
  return tf.cast(image, tf.float32) / 255., label

ds_train = ds_train.map(normalize_img)
ds_train = ds_train.batch(128)
ds_test = ds_test.map(normalize_img)
ds_test = ds_test.batch(128)

Kerasを使用して画像分類モデルを作成します。

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28, 1)),
  tf.keras.layers.Dense(128,activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(
    loss='sparse_categorical_crossentropy',
    optimizer=tf.keras.optimizers.Adam(0.001),
    metrics=['accuracy']
)

TensorBoardコールバックを作成してパフォーマンスプロファイルをキャプチャし、モデルのトレーニング中に呼び出します。

# Create a TensorBoard callback
logs = "logs/" + datetime.now().strftime("%Y%m%d-%H%M%S")

tboard_callback = tf.keras.callbacks.TensorBoard(log_dir = logs,
                                                 histogram_freq = 1,
                                                 profile_batch = '500,520')

model.fit(ds_train,
          epochs=2,
          validation_data=ds_test,
          callbacks = [tboard_callback])
Epoch 1/2
469/469 [==============================] - 11s 22ms/step - loss: 0.3684 - accuracy: 0.8981 - val_loss: 0.1971 - val_accuracy: 0.9436
Epoch 2/2
 50/469 [==>...........................] - ETA: 9s - loss: 0.2014 - accuracy: 0.9439WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/summary_ops_v2.py:1271: stop (from tensorflow.python.eager.profiler) is deprecated and will be removed after 2020-07-01.
Instructions for updating:
use `tf.profiler.experimental.stop` instead.
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/summary_ops_v2.py:1271: stop (from tensorflow.python.eager.profiler) is deprecated and will be removed after 2020-07-01.
Instructions for updating:
use `tf.profiler.experimental.stop` instead.
469/469 [==============================] - 11s 24ms/step - loss: 0.1685 - accuracy: 0.9525 - val_loss: 0.1376 - val_accuracy: 0.9595
<tensorflow.python.keras.callbacks.History at 0x7f23919a6a58>

TensorFlowプロファイラーを使用して、モデルのトレーニングパフォーマンスをプロファイリングします

TensorFlowプロファイラーはTensorBoardに組み込まれています。 Colabマジックを使用してTensorBoardをロードし、起動します。 [プロファイル]タブに移動して、パフォーマンスプロファイルを表示します。

# Load the TensorBoard notebook extension.
%load_ext tensorboard

このモデルのパフォーマンスプロファイルは、次の画像のようになります。

# Launch TensorBoard and navigate to the Profile tab to view performance profile
%tensorboard --logdir=logs
<IPython.core.display.Javascript object>

[プロファイル]タブで[概要]ページが開き、モデルのパフォーマンスの概要が表示されます。右側のステップタイムグラフを見ると、モデルが高度に入力バウンドであることがわかります(つまり、データ入力パイプラインで多くの時間を費やしています)。 [概要]ページには、モデルのパフォーマンスを最適化するために実行できる次のステップに関する推奨事項も記載されています。

入力パイプラインのどこでパフォーマンスのボトルネックが発生するかを理解するには、左側の[ツール]ドロップダウンから[トレースビューアー]を選択します。トレースビューアには、プロファイリング期間中にCPUとGPUで発生したさまざまなイベントのタイムラインが表示されます。

トレースビューアには、縦軸に複数のイベントグループが表示されます。各イベントグループには、トレースイベントで満たされた複数の水平トラックがあります。トラックは、スレッドまたはGPUストリームで実行されるイベントのイベントタイムラインです。個々のイベントは、タイムライントラック上の色付きの長方形のブロックです。時間は左から右に移動します。キーボードショートカットW (ズームイン)、 S (ズームアウト)、 A (左スクロール)、およびD (右スクロール)を使用して、トレースイベントをナビゲートします。

単一の長方形はトレースイベントを表します。フローティングツールバーのマウスカーソルアイコンを選択し(またはキーボードショートカット1使用)、トレースイベントをクリックして分析します。これにより、開始時間や期間など、イベントに関する情報が表示されます。

クリックに加えて、マウスをドラッグしてトレースイベントのグループを選択できます。これにより、そのエリアのすべてのイベントのリストとイベントの概要が表示されます。 Mキーを使用して、選択したイベントの期間を測定します。

トレースイベントは以下から収集されます。

  • CPU: CPUイベントは、 /host:CPUという名前のイベントグループの下に表示され/host:CPU 。各トラックはCPU上のスレッドを表します。 CPUイベントには、入力パイプラインイベント、GPU操作(op)スケジューリングイベント、CPU操作実行イベントなどが含まれます。
  • GPU: GPUイベントは、 /device:GPU:プレフィックスが付いたイベントグループの下に表示され/device:GPU: 。各イベントグループは、GPU上の1つのストリームを表します。

デバッグパフォーマンスのボトルネック

トレースビューアを使用して、入力パイプラインのパフォーマンスのボトルネックを特定します。以下の画像は、パフォーマンスプロファイルのスナップショットです。

profiler_trace_viewer_bad_ip

イベントトレースを見ると、 tf_data_iterator_get_nextがCPUで実行されている間、GPUが非アクティブであることがわかります。この操作は、入力データを処理し、トレーニングのためにGPUに送信する役割を果たします。一般的な経験則として、デバイス(GPU / TPU)を常にアクティブにしておくことをお勧めします。

tf.data APIを使用して、入力パイプラインを最適化します。この場合、トレーニングデータセットをキャッシュし、データをプリフェッチして、GPUが処理できるデータが常にあることを確認しましょう。 tf.dataを使用して入力パイプラインを最適化する方法の詳細については、こちらをご覧ください。

(ds_train, ds_test), ds_info = tfds.load(
    'mnist',
    split=['train', 'test'],
    shuffle_files=True,
    as_supervised=True,
    with_info=True,
)
ds_train = ds_train.map(normalize_img)
ds_train = ds_train.batch(128)
ds_train = ds_train.cache()
ds_train = ds_train.prefetch(tf.data.experimental.AUTOTUNE)
ds_test = ds_test.map(normalize_img)
ds_test = ds_test.batch(128)
ds_test = ds_test.cache()
ds_test = ds_test.prefetch(tf.data.experimental.AUTOTUNE)

モデルを再度トレーニングし、以前のコールバックを再利用してパフォーマンスプロファイルをキャプチャします。

model.fit(ds_train,
          epochs=2,
          validation_data=ds_test,
          callbacks = [tboard_callback])
Epoch 1/2
469/469 [==============================] - 10s 22ms/step - loss: 0.1194 - accuracy: 0.9658 - val_loss: 0.1116 - val_accuracy: 0.9680
Epoch 2/2
469/469 [==============================] - 1s 3ms/step - loss: 0.0918 - accuracy: 0.9740 - val_loss: 0.0979 - val_accuracy: 0.9712
<tensorflow.python.keras.callbacks.History at 0x7f23908762b0>

TensorBoardを再起動し、[プロファイル]タブを開いて、更新された入力パイプラインのパフォーマンスプロファイルを確認します。

入力パイプラインが最適化されたモデルのパフォーマンスプロファイルは、次の画像のようになります。

%tensorboard --logdir=logs
Reusing TensorBoard on port 6006 (pid 750), started 0:00:12 ago. (Use '!kill 750' to kill it.)
<IPython.core.display.Javascript object>

[概要]ページから、平均ステップ時間が入力ステップ時間と同様に減少していることがわかります。ステップタイムグラフは、モデルが入力境界が高くないことも示しています。トレースビューアを開いて、最適化された入力パイプラインでトレースイベントを調べます。

profiler_trace_viewer_good_ip

トレースビューアは、 tf_data_iterator_get_nextがはるかに高速に実行されることを示しています。したがって、GPUはトレーニングを実行するためのデータの安定したストリームを取得し、モデルトレーニングを通じてはるかに優れた使用率を実現します。

概要

TensorFlow Profilerを使用して、モデルトレーニングのパフォーマンスをプロファイリングおよびデバッグします。プロファイラーガイドを読み、TensorFlow Dev Summit2020のTF2トークパフォーマンスプロファイリングを見て、TensorFlowプロファイラーの詳細を確認してください。