Using GPUs

来源:互联网 发布:宏基因组数据分析 编辑:程序博客网 时间:2024/06/17 17:19
使用GPU
一、支持的设备
    在典型的系统上,有多个计算设备。 在TensorFlow中,支持的设备类型是CPU和GPU。 他们被表示为字符串。 例如:
"/cpu:0":你的机器的CPU。
"/device:GPU:0":你机器的GPU,如果你有的话。
"/device:GPU:1":你机器的第二个GPU等
    如果TensorFlow操作同时具有CPU和GPU,则在将操作分配给设备时,GPU设备将被赋予优先级。 例如,matmul有CPU和GPU内核。 在具有设备cpu:0和gpu: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.]]

三、手动设备放置
    如果您希望某个特定操作在您选择的设备上运行,而不是自动为您选择,可以使用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))

四、允许GPU内存增长
    默认情况下,TensorFlow将几乎所有GPU(受CUDA_VISIBLE_DEVICES支配)的GPU内存映射到进程。 这样做是为了通过减少内存碎片来更有效地使用设备上相对宝贵的GPU内存资源。
    在某些情况下,进程只需要分配可用内存的一个子集,或者仅根据进程需要增加内存使用量。 TensorFlow在Session上提供了两个Config选项来控制这个选项。
    第一个是allow_growth选项,它根据运行时分配尝试分配尽可能多的GPU内存:它开始分配很少的内存,当Sessions运行,需要更多的GPU内存时,我们扩展GPU所需的内存区域 张量流程。 请注意,我们不释放内存,因为这可能会导致更糟的内存碎片。 要打开此选项,请通过以下方式在ConfigProto中设置选项:
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config, ...)

    第二种方法是per_process_gpu_memory_fraction选项,它决定了每个可见GPU应分配的总内存量的一小部分。 例如,您可以通过以下方式告诉TensorFlow只分配每个GPU的总内存的40%:
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.4
session = tf.Session(config=config, ...)

    如果您想真正限制可用于TensorFlow进程的GPU内存量,这非常有用。
五、在多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设置为True。
# 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.]]

    cifar10教程是演示如何使用多个GPU进行训练的一个很好的例子。


本文主要使用谷歌翻译翻译。

原创粉丝点击