多GPU使用详解
目錄:
介紹
記錄設(shè)備狀態(tài)
手動(dòng)分配狀態(tài)
允許GPU內(nèi)存增長(zhǎng)
在多GPU系統(tǒng)是使用單個(gè)GPU
使用多個(gè) GPU
一、介紹
在一個(gè)典型的系統(tǒng)中,有多個(gè)計(jì)算設(shè)備。在 TensorFlow 中支持的設(shè)備類型包括 CPU 和 GPU。他們用字符串來(lái)表達(dá),例如:
?
- “/cpu:0”: 機(jī)器的 CPU
- “/device:GPU:0”: 機(jī)器的 GPU 如果你只有一個(gè)
- “/device:GPU:1”: 機(jī)器的第二個(gè) GPU
?
如果 TensorFlow 操作同時(shí)有 CPU 和 GPU 的實(shí)現(xiàn),操作將會(huì)優(yōu)先分配給 GPU 設(shè)備。例如,matmul 同時(shí)有 CPU 和 GPU 核心,在一個(gè)系統(tǒng)中同時(shí)有設(shè)備 cpu:0 和 gpu:0,gpu:0 將會(huì)被選擇來(lái)執(zhí)行 matmul。
?
二、記錄設(shè)備狀態(tài)
?
為了確定你的操作和張量分配給了哪一個(gè)設(shè)備,創(chuàng)建一個(gè)把 log_device_placement 的配置選項(xiàng)設(shè)置為 True 的會(huì)話即可。
?
?
創(chuàng)建一個(gè)計(jì)算圖
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)
創(chuàng)建一個(gè) session,它的 log_device_placement 被設(shè)置為 True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
運(yùn)行這個(gè)操作
print(sess.run(c))
你將會(huì)看到一下輸出:
?
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.]]
?
三、手動(dòng)分配設(shè)備
?
如果你希望一個(gè)特定的操作運(yùn)行在一個(gè)你選擇的設(shè)備上,而不是自動(dòng)選擇的設(shè)備,你可以使用 tf.device 來(lái)創(chuàng)建一個(gè)設(shè)備環(huán)境,這樣所有在這個(gè)環(huán)境的操作會(huì)有相同的設(shè)備分配選項(xiàng)。
?
創(chuàng)建一個(gè)會(huì)話
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)
創(chuàng)建一個(gè) session,它的 log_device_placement 被設(shè)置為 True
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
運(yùn)行這個(gè)操作
print(sess.run(c))
?
你將會(huì)看到 a 和 b 被分配給了 cpu:0。因?yàn)闆](méi)有指定特定的設(shè)備來(lái)執(zhí)行 matmul 操作,TensorFlow 將會(huì)根據(jù)操作和已有的設(shè)備來(lái)選擇(在這個(gè)例子中是 gpu:0),并且如果有需要會(huì)自動(dòng)在設(shè)備之間復(fù)制張量。
?
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 內(nèi)存增長(zhǎng)
?
默認(rèn)情況下,TensorFlow 將幾乎所有的 GPU的顯存(受 CUDA_VISIBLE_DEVICES 影響)映射到進(jìn)程。 通過(guò)減少內(nèi)存碎片,可以更有效地使用設(shè)備上寶貴的GPU內(nèi)存資源。
?
在某些情況下,只需要分配可用內(nèi)存的一個(gè)子集給進(jìn)程,或者僅根據(jù)進(jìn)程需要增加內(nèi)存使用量。 TensorFlow 在 Session 上提供了兩個(gè) Config 選項(xiàng)來(lái)控制這個(gè)選項(xiàng)。
?
第一個(gè)是 allow_growth 選項(xiàng),它根據(jù)運(yùn)行時(shí)的需要分配 GPU 內(nèi)存:它開(kāi)始分配很少的內(nèi)存,并且隨著 Sessions 運(yùn)行并需要更多的 GPU 內(nèi)存,我們根據(jù) TensorFlow 進(jìn)程需要繼續(xù)擴(kuò)展了GPU所需的內(nèi)存區(qū)域。請(qǐng)注意,我們不釋放內(nèi)存,因?yàn)檫@會(huì)導(dǎo)致內(nèi)存碎片變得更糟。要打開(kāi)此選項(xiàng),請(qǐng)通過(guò)以下方式在 ConfigProto 中設(shè)置選項(xiàng):
?
?
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config, …)
?
?
第二種方法是 per_process_gpu_memory_fraction 選項(xiàng),它決定了每個(gè)可見(jiàn)GPU應(yīng)該分配的總內(nèi)存量的一部分。例如,可以通過(guò)以下方式告訴 TensorFlow 僅分配每個(gè)GPU的總內(nèi)存的40%:
?
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.4
session = tf.Session(config=config, …)
?
?
如果要真正限制 TensorFlow 進(jìn)程可用的GPU內(nèi)存量,這非常有用。
?
五、在多GPU系統(tǒng)上使用單個(gè)GPU
?
如果您的系統(tǒng)中有多個(gè)GPU,則默認(rèn)情況下將選擇具有最低ID的GPU。 如果您想在不同的GPU上運(yùn)行,則需要明確指定首選項(xiàng):
?
創(chuàng)建一個(gè)計(jì)算圖
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)
創(chuàng)建一個(gè) log_device_placement 設(shè)置為True 的會(huì)話
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
運(yùn)行這個(gè)操作
print(sess.run(c))
?
?
你會(huì)看到現(xiàn)在 a 和 b 被分配給 cpu:0。 由于未明確指定設(shè)備用于 MatMul 操作,因此 TensorFlow 運(yùn)行時(shí)將根據(jù)操作和可用設(shè)備(本例中為 gpu:0)選擇一個(gè)設(shè)備,并根據(jù)需要自動(dòng)復(fù)制設(shè)備之間的張量。
?
如果指定的設(shè)備不存在,將得到 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 在指定的設(shè)備不存在的情況下自動(dòng)選擇現(xiàn)有的受支持設(shè)備來(lái)運(yùn)行操作,則可以在創(chuàng)建會(huì)話時(shí)在配置選項(xiàng)中將 allow_soft_placement 設(shè)置為 True。
?
創(chuàng)建計(jì)算圖
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)
創(chuàng)建一個(gè) allow_soft_placement 和 log_device_placement 設(shè)置為 True 的會(huì)話
?
sess = tf.Session(config=tf.ConfigProto(
allow_soft_placement=True, log_device_placement=True))
運(yùn)行這個(gè)操作
print(sess.run(c))
?
六、使用多個(gè) GPU
?
如果您想要在多個(gè) GPU 上運(yùn)行 TensorFlow ,則可以采用多塔式方式構(gòu)建模型,其中每個(gè)塔都分配有不同的 GPU。 例如:
?
?
創(chuàng)建計(jì)算圖
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)
創(chuàng)建一個(gè) log_device_placement 設(shè)置為 True 的會(huì)話
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
運(yùn)行這個(gè)操作
print(sess.run(sum))
?
你將會(huì)看到以下的輸出:
?
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.]]
?
?
翻譯自:
https://www.tensorflow.org/programmers_guide/using_gpu
總結(jié)
- 上一篇: apache php并发数,apache
- 下一篇: 后Kubernetes时代的微服务