📜  TensorFlow单和多GPU

📅  最后修改于: 2021-01-11 11:08:52             🧑  作者: Mango

TensorFlow单GPU和多GPU

我们通常的系统可以包含用于计算的多个设备,并且我们已经知道TensorFlow支持CPU和GPU,我们将其表示为字符串。

例如:

  • 如果我们有一个CPU,它的地址可能是“ / cpu:0”。
  • TensorFlow GPU字符串的索引从零开始。
  • 同样,第二个GPU是“ / device:GPU:1”。

设备放置日志

我们可以通过创建一个会话来查找哪些设备处理特定操作,该会话中预先设置了log_device_placementconfiguration选项。

# Graph creation.
x = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='x')
y = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='y')
z = tf.matmul(x, y)
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Running the operation.
print(sess.run(z))

TensorFlow GPU设备放置日志的输出如下所示:

/log:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: Tesla K40c, pci bus
id: 0000:05:00.0
b: /job:localhost/replica:0/task:0/device:GPU:0
a: /job:localhost/replica:0/task:0/device:GPU:0
MatMul: /job:localhost/replica:0/task:0/device:GPU:0
[[ 22.  28.]
[ 49.  64.]]

手动放置设备

有时,我们可能想确定我们的操作应该在哪台设备上运行,我们可以通过使用tf.device创建一个上下文来完成此操作,在该上下文中我们分配特定设备,例如应该执行计算的CPU或GPU,如下所示:

# Graph Creation.
with tf.device('/cpu:0'):
x = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='x')
y = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='y')
z = tf.matmul(x, y)
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Running the operation.
print(sess.run(z))

上面的TensorFlow GPU代码将常量a和b分配给cpu:o。在代码的第二部分中,由于没有明确声明要执行该任务的设备,因此默认情况下会选择GPU(如果有),并在设备之间复制多维数组。

Device mapping:
/job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: Tesla K40c, pci bus
id: 0000:05:00.0
y: /job:localhost/replica:0/task:0/cpu:0
x: /job:localhost/replica:0/task:0/cpu:0
MatMul: /job:localhost/replica:0/task:0/device:GPU:0
[[ 22. 28.]
[ 49. 64.]]

优化TensorFlow GPU内存

通过映射几乎所有处理器可见的TensorFlow GPU内存,完成了内存碎片化操作以优化内存资源,从而节省了大量潜在资源。 TensorFlow GPU提供了两个配置选项来控制内存的分配(如果处理器在需要时以及何时保存内存),这些TensorFlow GPU优化如下所述:

ConfigProto用于此目的:

config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config, ...)

per_process_gpu_memory_fraction是第二个选择,它决定应为使用中的每个GPU分配总内存的段。下面给出的示例将在tensorflow中用于分配40%的内存:

config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.4
session = tf.Session(config=config, ...)

仅在我们已经指定计算并且确保在处理期间不会更改的情况下才使用它。

多GPU系统中的单个GPU

在多TensorFlow GPU系统中,默认情况下已选择身份最低的设备,用户不需要它。

# Creates a graph.
with tf.device('/device:GPU:2'):
x = tf.constant([1, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='x')
y = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='y')
z= tf.matmul(x, y)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print(sess.run(c=z))

当用户指定的TensorFlow GPU不存在时,将获得InvalidArgumentError,如下所示:

InvalidArgumentError: Invalid argument: Cannot assign a device to node 'y':
Could not satisfy explicit device specification '/device:GPU:2'
[[Node: b = Const[dtype=DT_FLOAT, value=Tensor, _device="/device:GPU:2"]()]]

如果我们要指定默认值

在TensorFlow中使用多个GPU

我们已经知道TensorFlow中的塔架以及可以分配给GPU的每个塔架,从而为使用TensorFlow多个GPU制作了多塔架结构模型。

z= []
for d in ['/device:GPU:2', '/device:GPU:3']:
with tf.device(d):
x = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3])
y = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2])
z.append(tf.matmul(x, y))
with tf.device('/cpu:0'):
sum = tf.add_n(z)
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Running the operations.
print(sess.run(sum))

TensorFlow GPU的输出如下:

/job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: Tesla K20m, pci bus
id: 0000:02:00.0
/job:localhost/replica:0/task:0/device:GPU:1 -> device: 1, name: Tesla K20m, pci bus
id: 0000:03:00.0
/job:localhost/replica:0/task:0/device:GPU:2 -> device: 2, name: Tesla K20m, pci bus
id: 0000:83:00.0
/job:localhost/replica:0/task:0/device:GPU:3 -> device: 3, name: Tesla K20m, pci bus
id: 0000:84:00.0
Const_3: /job:localhost/replica:0/task:0/device:GPU:3
Const_2: /job:localhost/replica:0/task:0/device:GPU:3
MatMul_1: /job:localhost/replica:0/task:0/device:GPU:3
Const_1: /job:localhost/replica:0/task:0/device:GPU:2
Const: 2/job:localhost/replica:0/task:0/device:GPU:2
MatMul: /job:localhost/replica:0/task:0/device:GPU:2
AddN: /job:localhost/replica:0/task:0/cpu:0
[[ 44. 56.]
[ 98.  128.]]

我们可以使用简单的数据集(例如CIFAR10)测试此多个GPU模型,以进行实验并了解如何使用GPU。