[教程1]使用GPU
[教程1]使用GPU
支持的設備
在典型的系統中,有多個計算設備。在TensorFlow中,支持的設備類型是CPU
和GPU
。它們被表示為strings
。例如:
"/cpu:0"
:機器的CPU。"/gpu:0"
你的機器的GPU,如果你有一個。"/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/gpu:0 -> device: 0, name: Tesla K40c, pci bus id: 0000:05:00.0 b: /job:localhost/replica:0/task:0/gpu:0 a: /job:localhost/replica:0/task:0/gpu:0 MatMul: /job:localhost/replica:0/task:0/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
操作明確指定設備,所以TensorFlow運行時將根據操作和可用設備(gpu:0
在本示例中)選擇一個設備,如果需要,可以在設備之間自動復制張量。
Device mapping: /job:localhost/replica:0/task:0/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/gpu:0 [[ 22. 28.] [ 49. 64.]]
允許GPU內存增長
默認情況下,TensorFlow將幾乎所有GPU的GPU內存映射 CUDA_VISIBLE_DEVICES
到該進程可見。這樣做可以通過減少內存碎片來更有效地使用設備上相對寶貴的GPU內存資源。
在某些情況下,該過程只需要分配可用內存的一個子集,或只是根據進程需要增加內存使用情況。TensorFlow在會話中提供了兩個配置選項來控制此功能。
第一個是allow_growth
選項,它試圖基於運行時分配分配只有GPU內存:它開始分配很少的內存,並且隨著Sessions的運行和更多的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僅通過以下方式分配每個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(‘/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 ‘/gpu:2‘ [[Node: b = Const[dtype=DT_FLOAT, value=Tensor<type: float shape: [3,2] values: 1 2 3...>, _device="/gpu:2"]()]]
如果您想TensorFlow自動選擇現有的支持機構運行的情況下,指定一個不存在的操作,您可以設置allow_soft_placement
以True
創建會話時的配置選項。
# Creates a graph. with tf.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 [‘/gpu:2‘, ‘/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/gpu:0 -> device: 0, name: Tesla K20m, pci bus id: 0000:02:00.0 /job:localhost/replica:0/task:0/gpu:1 -> device: 1, name: Tesla K20m, pci bus id: 0000:03:00.0 /job:localhost/replica:0/task:0/gpu:2 -> device: 2, name: Tesla K20m, pci bus id: 0000:83:00.0 /job:localhost/replica:0/task:0/gpu:3 -> device: 3, name: Tesla K20m, pci bus id: 0000:84:00.0 Const_3: /job:localhost/replica:0/task:0/gpu:3 Const_2: /job:localhost/replica:0/task:0/gpu:3 MatMul_1: /job:localhost/replica:0/task:0/gpu:3 Const_1: /job:localhost/replica:0/task:0/gpu:2 Const: /job:localhost/replica:0/task:0/gpu:2 MatMul: /job:localhost/replica:0/task:0/gpu:2 AddN: /job:localhost/replica:0/task:0/cpu:0 [[ 44. 56.] [ 98. 128.]]
該cifar10教程是一個很好的例子演示了如何做多GPU訓練。
[教程1]使用GPU