一套标准系统中通常有多台计算设备,Tensorflow支持CPU和GPU两种设备,它们都可以使用strings表示。

  • /cpu:0 机器的CPU

  • /device:GPU:0 机器的GPU(第1个)

  • /device:GPU:1 机器的GPU(第2个)

如果,Tensorflow指令集兼有CPU和GPU,当指令分配到设备时,GPU设备拥有优先权。

例如,matmul 同时存在CPU和GPU的核函数,因此在同时拥有cpu:0gpu:0 设备的系统中,gpu:0 会被用来运行matmul。

要找出指令和张量被分配到哪个设备,需要在创建会话时,将log_device_placement设置为true

# Creates a graph.
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
# 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))

输出内容

Device mapping:
/job: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.]]

手动分配设备

如果希望特定指令在特定设备上运行,而不是通过系统自动选择设备,可以使用with tf.device 创建设备上下文

# Creates a graph.
with tf.device('/cpu:0'):
  a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
  b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
# 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))

这时,可以看到a,b被分配到cpu:0 。而MatMul 指令由于为明确指定,则会做出自动选择。

Device mapping:
/job: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/cpu:0
a: /job:localhost/replica:0/task:0/cpu:0
MatMul: /job:localhost/replica:0/task:0/device:GPU:0
[[ 22.  28.]
 [ 49.  64.]]

GPU内存

默认情况下,Tensorflow会映射进程可见的所有GPU的几乎所有内存,取决于CUDA_VISIBLE_DEVICES

通过减少内存碎片,可以有效使用设备上相对宝贵的GPU内存资源。

某些时候,最理想的进程是只分配可用内存的一个子集,或者是根据进程需要增加内存使用量。因此,Tensorflow Session提供两个Config选项进行控制。

allow_growth 选项是根据运行时的需要分配GPU内存。刚开始会分配很少的内存,随着Session开始运行,GPU内存需要增多。这个过程不会释放内存,因为可能导致严重的内存碎片的情况。开启此选项

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

per_processgpu_memory_fraction选项用来决定每个可见GPU应分配到的内存占总内存量的比例。例如,可以指定Tensorflow仅分配每个GPU总内存的40%

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

在多GPU系统使用单一GPU

如果系统存在多个GPU,默认会选择ID最小的GPU。如果希望在其他的GPU运行,需要显式设置

# Creates a graph.
with tf.device('/device:GPU:2'):
  a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
  b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
  c = tf.matmul(a, b)
# 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))

如果指定的设备不存在,会报InvalidArgumentError

InvalidArgumentError: Invalid argument: Cannot assign a device to node 'b':
Could not satisfy explicit device specification '/device:GPU:2'
   [[Node: b = Const[dtype=DT_FLOAT, value=Tensor<type: float shape: [3,2]
   values: 1 2 3...>, _device="/device:GPU:2"]()]]

当指定设备不存在,如果希望Tensorflow自动选择现有的可支持设备,则可以设置allow_soft_placement

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

使用多个GPU

如果要在多个GPU运行Tensorflow,则可以采用多塔式方式构建模型,每个塔会分配个不同的GPU

# Creates a graph.
c = []
for d in ['/device:GPU:2', '/device:GPU:3']:
  with tf.device(d):
    a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3])
    b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2])
    c.append(tf.matmul(a, b))
with tf.device('/cpu:0'):
  sum = tf.add_n(c)
# 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(sum))

输出内容

Device mapping:
/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: /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.]]

【参考】

1。Tensorflow-->编程人员指南--->使用GPU:https://www.tensorflow.org/programmers\_guide/using\_gpu?hl=zh-cn

results matching ""

    No results matching ""