目錄:
一、TensorFlow使用GPU
二、深度學習訓練與並行模式
三、多GPU並行
四、分布式TensorFlow
4.1分布式TensorFlow的原理
4.2分布式TensorFlow模型訓練
4.3使用caicloud運行分布式TensorFlow
深度學習應用到實際問題中,一個非常棘手的問題是訓練模型時計算量太大。為了加速訓練,TensorFlow可以利用GPU或/和分布式計算進行模型訓練。
一、TensorFlow使用GPU
TensorFlow可以通過td.device函數來指定運行每個操作的設備,這個設備可以是本設備的CPU或GPU,也可以是遠程的某一台設備。
TF生成會話的時候,可願意通過設置tf.log_device_placemaent參數來打印每一個運算的設備。
import tensorflow as tf a = tf.constant([1.0,2.0,3.0],shape=[3],name='a') b = tf.constant([1.0,2.0,3.0],shape=[3],name='b') c= tf.add_n([a,b],name="c") with tf.Session(config=tf.ConfigProto(log_device_placement = True)) as sess: print(sess.run(c)) ######## Device mapping: no known devices. c: (AddN): /job:localhost/replica:0/task:0/device:CPU:0 b: (Const): /job:localhost/replica:0/task:0/device:CPU:0 a: (Const): /job:localhost/replica:0/task:0/device:CPU:0 [2. 4. 6.]
在配置好了GPU環境的TensorFlow中,如果沒有明確指明運行設備,TF會優先選擇GPU。
import tensorflow as tf a = tf.constant([1.0,2.0,3.0],shape=[3],name='a') b = tf.constant([1.0,2.0,3.0],shape=[3],name='b') c= tf.add_n([a,b],name="c") with tf.Session(config=tf.ConfigProto(log_device_placement = True)) as sess: print(sess.run(c)) ######## Device mapping: no known devices. c: (AddN): /job:localhost/replica:0/task:0/device:GPU:0 b: (Const): /job:localhost/replica:0/task:0/device:GPU:0 a: (Const): /job:localhost/replica:0/task:0/device:GPU:0 [2. 4. 6.]
可以通過tf.device 來制定運行操作的設備。
import tensorflow as tf with tf.device("/CPU:0"): a = tf.constant([1.0,2.0,3.0],shape=[3],name='a') b = tf.constant([1.0,2.0,3.0],shape=[3],name='b') with tf.device("/GPU:0"): c= tf.add_n([a,b],name="c") with tf.Session(config=tf.ConfigProto(log_device_placement = True)) as sess: print(sess.run(c))
某些數據類型是不被GPU所支持的。強制指定設備會報錯。為了避免解決這個問題。在創建會還時可以指定參數allow_soft_placement 。當allow_soft_placement為True的時候,如果運算無法在GPU上運行,TF會自動將其放在CPU 上運行。
a_cpu = tf.Variable(0,name='a_cpu') with tf.device('/gpu:0'): a_gpu = tf.Variable(0,name='a_gpu') sess = tf.Session(config=tf.ConfigProto(log_device_placement=True,allow_soft_placement = True)) sess.run(tf.global_variables_initializer())
a_gpu: (VariableV2): /job:localhost/replica:0/task:0/device:CPU:0 a_gpu/read: (Identity): /job:localhost/replica:0/task:0/device:CPU:0 a_gpu/Assign: (Assign): /job:localhost/replica:0/task:0/device:CPU:0 init/NoOp_1: (NoOp): /job:localhost/replica:0/task:0/device:CPU:0 a_cpu: (VariableV2): /job:localhost/replica:0/task:0/device:CPU:0 a_cpu/read: (Identity): /job:localhost/replica:0/task:0/device:CPU:0 a_cpu/Assign: (Assign): /job:localhost/replica:0/task:0/device:CPU:0 init/NoOp: (NoOp): /job:localhost/replica:0/task:0/device:CPU:0 init: (NoOp): /job:localhost/replica:0/task:0/device:CPU:0 a_gpu/initial_value: (Const): /job:localhost/replica:0/task:0/device:CPU:0 a_cpu/initial_value: (Const): /job:localhost/replica:0/task:0/device:CPU:0
實踐經驗:將計算密集型的操作放在GPU上。為了提高程序運行速度,盡量將相關操作放在同一台設備上。
二、深度學習訓練與並行模式
常用的並行化深度學習模型的方法有兩種:同步模式和異步模式。
在異步模式下,不同設備之間是完全獨立的。
異步模型流程圖:
同步模型流程圖:
同步模式時,單個設備不會單獨對參數進行更新,而會等待所有設備都完成反向傳播之后再統一更新參數。
同步模式解決了異步模式中存在參數更新的問題,然而同步模式的效率卻低於異步模式。
三、多GPU並行
一般來說,一台機器上的多個GPU性能相似,所以在這種設置下跟多的是采用同步模式訓練甚多學習模型。
四、分布式TensorFlow
通過多GPU並行的方式固然可以達到很好的訓練效果,但是一台機器上畢竟GPU的個數是有限的。如果需要記憶不提升深度學習模型的訓練效果,就需要將TensorFlow分布式的運行在多台計算機上。
4.1分布式TensorFlow的原理
在第二個小結中,介紹了分布式TensorFlow訓練甚多學習模型的理論。本小節將具體介紹如何使用TF在分布式集群中訓練深度學習模型。TensorFlow集群通過一系列的任務(tasks)來執行TF計算圖中的運算。一般來說,不同的任務跑在不同的機器上。當然,使用GPU時,不同任務可以使用用一太機器上的不同GPU。TF中的任務可以聚合成工作。每個工作可以包含一個或多個任務。當一個TF集群有多個任務的時候,需要使用tf.train.ClusterSpec來指定運行每一個人物的機器。
配置第一個任務集群
import tensorflow as tf c = tf.constant('Hello ,this is the server1!') #生成一個有兩個人物的集群,一個任務跑在本地的2222端口,另一個跑在本地的2223端口 cluster = tf.train.ClusterSpec({"local":['localhost:2998','localhost2999']}) #通過上面生成的集群配置生成Server。並通過job_name和task_index指定當前啟動的任務。 server = tf.train.Server(cluster,job_name='local',task_index=0) #通過server.target生成會話來使用來使用TF集群中的資源。通過log_device_placement可以看到執行每一個操作的任務 sess = tf.Session(server.target,config=tf.ConfigProto(log_device_placement = True)) print(sess.run(c))
配置第二個任務,使用同樣的集群配置
import tensorflow as tf c = tf.constant('Hello ,this is the server2!') #和第一個任務一樣的集群配置 cluster = tf.train.ClusterSpec({"local":['localhost:2998','localhost2999']}) #指定task_index = 1,所以第二個任務是運行在2999端口上 server = tf.train.Server(cluster,job_name='local',task_index=0) sess = tf.Session(server.target,config=tf.ConfigProto(log_device_placement = True)) print(sess.run(c))
當只啟動第一個任務時,程序會停下來等待第二個任務啟動。而且持續輸出failed to connect to “ipv4:127.0.0.1:2999”,當第二個任務啟動后,才會輸出第一個任務的結果。