一套标准系统中通常有多台计算设备,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: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.]]
手动分配设备
如果希望特定指令在特定设备上运行,而不是通过系统自动选择设备,可以使用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