このページは Cloud Translation API によって翻訳されました。
Switch to English

GPUを使用する

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

TensorFlowコードとtf.kerasモデルは、コードを変更する必要なく、単一のGPUで透過的に実行されます。

1つまたは複数のマシンで複数のGPUを実行する最も簡単な方法は、 配布戦略を使用することです。

このガイドは、これらのアプローチを試し、TensorFlowがGPUを使用する方法をきめ細かく制御する必要があることに気付いたユーザーを対象としています。

セットアップ

最新のTensorFlow gpuリリースがインストールされていることを確認してください。

 import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
 
Num GPUs Available:  2

概観

TensorFlowは、CPUやGPUなど、さまざまなタイプのデバイスでの計算の実行をサポートしています。それらは、たとえば文字列識別子で表されます。

  • "/device:CPU:0" :マシンのCPU。
  • "/GPU:0" :TensorFlowから見えるマシンの最初のGPUの省略表記。
  • "/job:localhost/replica:0/task:0/device:GPU:1" :TensorFlowから見えるマシンの2番目のGPUの完全修飾名。

TensorFlowオペレーションにCPUとGPUの両方の実装がある場合、デフォルトでは、オペレーションがデバイスに割り当てられるときにGPUデバイスが優先されます。たとえば、 tf.matmulはCPUカーネルとGPUカーネルの両方があります。デバイスCPU:0およびGPU:0を備えたシステムでは、別のデバイスでの実行を明示的に要求しない限り、 GPU:0デバイスが選択されてtf.matmulを実行します。

ロギングデバイスの配置

操作とテンソルが割り当てられているデバイスを確認するには、プログラムの最初のステートメントとしてtf.debugging.set_log_device_placement(True)を配置します。デバイス配置ログを有効にすると、Tensorの割り当てまたは操作が印刷されます。

 tf.debugging.set_log_device_placement(True)

# Create some tensors
a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)

print(c)
 
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

上記のコードは、 MatMul opがGPU:0実行されたという指示をMatMulGPU:0

デバイスの手動配置

自動的に選択されるものではなく、選択したデバイスで特定の操作を実行したい場合はwith tf.deviceを使用してデバイスコンテキストを作成し、そのコンテキスト内のすべての操作を同じ指定されたデバイスで実行できます。 。

 tf.debugging.set_log_device_placement(True)

# Place tensors on the CPU
with tf.device('/CPU:0'):
  a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
  b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])

c = tf.matmul(a, b)
print(c)
 
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

abCPU:0割り当てられていることがわかりCPU:0 。デバイスはMatMulオペレーションに対して明示的に指定されていないため、 MatMulランタイムはオペレーションと使用可能なデバイス(この例ではGPU:0 )に基づいて1つを選択し、必要に応じてデバイス間でテンソルを自動的にコピーします。

GPUメモリの増加を制限する

デフォルトでは、TensorFlowは、プロセスから見えるすべてのGPU( CUDA_VISIBLE_DEVICES )のほぼすべてのGPUメモリをマップします。これは、メモリの断片化を減らすことにより、デバイス上の比較的貴重なGPUメモリリソースをより効率的に使用するために行われます。 TensorFlowを特定のGPUセットに制限するには、 tf.config.experimental.set_visible_devicesメソッドを使用します。

 gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only use the first GPU
  try:
    tf.config.experimental.set_visible_devices(gpus[0], 'GPU')
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPU")
  except RuntimeError as e:
    # Visible devices must be set before GPUs have been initialized
    print(e)
 
2 Physical GPUs, 1 Logical GPU

場合によっては、プロセスで使用可能なメモリのサブセットのみを割り当てるか、プロセスで必要な場合にのみメモリ使用量を増やすことが望ましい場合があります。 TensorFlowはこれを制御する2つの方法を提供します。

最初のオプションは、 tf.config.experimental.set_memory_growthを呼び出してメモリの増加をオンにすることtf.config.experimental.set_memory_growth 。これは、ランタイムの割り当てに必要なだけのGPUメモリの割り当てを試みます。非常に少ないメモリの割り当てを開始し、プログラムが実行されると、より多くのGPUメモリが必要な場合は、TensorFlowプロセスに割り当てられたGPUメモリ領域を拡張します。メモリを断片化する可能性があるため、メモリを解放しないことに注意してください。特定のGPUのメモリ増加をオンにするには、テンソルを割り当てたり、opを実行したりする前に、次のコードを使用します。

 gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  try:
    # Currently, memory growth needs to be the same across GPUs
    for gpu in gpus:
      tf.config.experimental.set_memory_growth(gpu, True)
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Memory growth must be set before GPUs have been initialized
    print(e)
 
2 Physical GPUs, 2 Logical GPUs

このオプションを有効にする別の方法は、環境変数TF_FORCE_GPU_ALLOW_GROWTHtrueに設定することtrue 。この構成はプラットフォーム固有です。

2番目の方法は、 tf.config.experimental.set_virtual_device_configurationを使用して仮想GPUデバイスを構成し、GPUに割り当てる合計メモリにハード制限を設定することです。

 gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only allocate 1GB of memory on the first GPU
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)
 
2 Physical GPUs, 2 Logical GPUs

これは、TensorFlowプロセスで使用可能なGPUメモリの量を本当に制限したい場合に役立ちます。これは、GPUがワークステーションGUIなどの他のアプリケーションと共有される場合のローカル開発の一般的な方法です。

マルチGPUシステムでの単一GPUの使用

システムに複数のGPUがある場合、最小のIDを持つGPUがデフォルトで選択されます。別のGPUで実行する場合は、設定を明示的に指定する必要があります。

 tf.debugging.set_log_device_placement(True)

try:
  # Specify an invalid GPU device
  with tf.device('/device:GPU:2'):
    a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
    b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
    c = tf.matmul(a, b)
except RuntimeError as e:
  print(e)
 
/job:localhost/replica:0/task:0/device:GPU:2 unknown device.

指定したデバイスが存在しない場合、 RuntimeError.../device:GPU:2 unknown deviceます。

指定されたデバイスが存在しない場合にTensorFlowが自動的に既存のサポートされているデバイスを選択して操作を実行するようにしたい場合は、 tf.config.set_soft_device_placement(True)呼び出すことができます。

 tf.config.set_soft_device_placement(True)
tf.debugging.set_log_device_placement(True)

# Creates some tensors
a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)

print(c)
 
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

複数のGPUの使用

複数のGPU用に開発することで、モデルを追加のリソースでスケーリングできます。単一のGPUを備えたシステムで開発する場合、仮想デバイスを使用して複数のGPUをシミュレートできます。これにより、追加のリソースを必要とせずに、マルチGPUセットアップの簡単なテストが可能になります。

 gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Create 2 virtual GPUs with 1GB memory each
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024),
         tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPU,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)
 
2 Physical GPU, 3 Logical GPUs

ランタイムで複数の論理GPUを使用できるようになったら、 tf.distribute.Strategyまたは手動配置で複数のGPUを利用できます。

tf.distribute.Strategy

複数のGPUを使用するためのベストプラクティスは、 tf.distribute.Strategyを使用することtf.distribute.Strategy 。以下に簡単な例を示します。

 tf.debugging.set_log_device_placement(True)

strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
  inputs = tf.keras.layers.Input(shape=(1,))
  predictions = tf.keras.layers.Dense(1)(inputs)
  model = tf.keras.models.Model(inputs=inputs, outputs=predictions)
  model.compile(loss='mse',
                optimizer=tf.keras.optimizers.SGD(learning_rate=0.2))
 
Executing op RandomUniform in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Sub in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Mul in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Add in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarIsInitializedOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op LogicalNot in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Assert in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op ReadVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Identity in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op VarIsInitializedOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op LogicalNot in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op Assert in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op Reshape in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:1

このプログラムは、各GPUでモデルのコピーを実行し、入力データをGPU間で分割します。これは「 データ並列処理 」とも呼ばれます

配布戦略の詳細については、 こちらのガイドをご覧ください

手動配置

tf.distribute.Strategyは、デバイス間で計算を複製することにより、 tf.distribute.Strategy機能します。各GPUでモデルを作成することにより、レプリケーションを手動で実装できます。例えば:

 tf.debugging.set_log_device_placement(True)

gpus = tf.config.experimental.list_logical_devices('GPU')
if gpus:
  # Replicate your computation on multiple GPUs
  c = []
  for gpu in gpus:
    with tf.device(gpu.name):
      a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
      b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
      c.append(tf.matmul(a, b))

  with tf.device('/CPU:0'):
    matmul_sum = tf.add_n(c)

  print(matmul_sum)
 
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op AddN in device /job:localhost/replica:0/task:0/device:CPU:0
tf.Tensor(
[[ 44.  56.]
 [ 98. 128.]], shape=(2, 2), dtype=float32)