【TF-2-5】Tensorflow-分布式訓練


目錄

  1. 簡介
  2. 構建步驟
  3. 實現方式
  4. Demo演示

一、簡介

1) 使用單台機器或者單個GPU/CPU來進行模型訓練,訓練速度會受資源的影響,因為畢竟單個的設備的計算能力和存儲能力具有一定的上限的,針對這個問題,TensorFlow支持分布式模型運算,支持多機器、多GPU、多CPU各種模型的組合運行方案的設計。(默認情況下,TensorFlow程序會將程序運行在第一個GPU上<如果有GPU,並且安裝的TensorFlow支持GPU運行>)

2)TensorFlow的分布式支持單機多GPU、單機GPU+CPU、多機GPU等結構,不過所有結構的構建方式基本類似。

3) 除了TensorFlow外,Caffe、DeepLearning4j等也支持分布式訓練,TensorFlow中的集群(Cluster)指的是一系列能夠對TensorFlow中的圖(graph)進行分布式計算的任務(task)。每個任務是同服務(server)相關聯的。TensorFlow中的服務會包含一個用於創建session的主節點和至少一個用於圖運算的工作節點。另外在TensorFlow中,一個集群可以被拆分為一個或者多個作業(job),每個作業可以包含至少一個任務。

4)cluster(集群)、job(作業)、task(任務)概念:三者可以簡單的看成是層次關系,task可以看成每台機器上的一個進程,多個task組成job;job又有:ps、worker兩種,分別用於參數服務、計算服務,組成cluster。

二、構建步驟

TensorFlow分布式集群的構建主要通過代碼實現,主要步驟如下:

①創建集群(Cluster)

  • 創建一個tf.train.ClusterSpec用於對集群中的所有任務進行描述,該描述內容對於所有內容應該是相同的。
  • 創建tf.train.Server並將tf.train.ClusterSpec中參數傳入構造函數,

②使用tf.device API指定運算的設備,構建計算圖,最后提交運算

備注:TensorFlow負責內部作業之間的數據傳輸

詳細見最后的實驗代碼。

三、實現方式

TensorFlow中主要包含兩個方面

第一:對不同數據大小進行計算的任務(work作業)

第二:用於不停更新共享參數的任務(ps作業)。這樣任務都可以運行不同在機器上,在TensorFlow中,主要實現方式如下:

  • 圖內的拷貝(In-Graph Replication)
  • 圖間的拷貝(Between-Graph Replication)
  • 異步訓練(Asynchronous Training)
  • 同步訓練(Synchronous Training)

3.1)在In-Graph Replication

指定整個集群由一個客戶端來構建圖,並且這個客戶端來提交圖到集群中,worker只負責處理執行任務。In-Graph模式的好處在於解耦了TensorFlow集群和訓練應用之間的關系,這樣可以提前構建好參數服務器和計算服務器,而這些角色本身不需要額外的邏輯代碼,只需要使用join等待即可,真正的訓練邏輯全部位於客戶端,具有足夠高的靈活性。

備注:在小規模數據集的情況下,經常使用。在海量數據的訓練過程中,不建議使用該方式,建議使用Between-Graph Replication模式。

3.2)在Between-Graph Replication

每個客戶端會構建一個相似的圖結構,該結構中的參數均通過ps作業進行聲明並使用tf.train.replica_device_setter方法將參數映射到不同的任務作業中。

3.3Synchronous Training

在同步訓練中,每個graph的副本讀取相同的parameter值,並行的計算,然后將計算完的結果放到一起處理。在TensorFlow中,如果是Betweengraph replication的情況下,可以通tf.train.SyncReplicasOptimizer來處理,如果是In-graph replication情況下,直接對結果進行處理即可(比如平均).

3.4Asynchronous Training

在異步訓練中,每個任務計算完后,就會直接使用計算出的結果更新parameter值。不同的任務之間不存在協調進度。

同步訓練需要等待最慢的一個任務執行完后,才可用更新參數;異步訓練中,可以每執行完一個任務,就更新一次參數。一般情況下,建議使用異步訓練。

四、Demo演示

server-demo.py服務器代碼:

    1 	import tensorflow as tf
    2 	# 1. 配置服務器相關信息
    3 	# 因為tensorflow底層代碼中,默認就是使用ps和work分別表示兩類不同的工作節點
    4 	# ps:變量/張量的初始化、存儲相關節點
    5 	# work: 變量/張量的計算/運算的相關節點
    6 	ps_hosts = ['127.0.0.1:33331', '127.0.0.1:33332']
    7 	work_hosts = ['127.0.0.1:33333', '127.0.0.1:33334', '127.0.0.1:33335']
    8 	cluster = tf.train.ClusterSpec({'ps': ps_hosts, 'work': work_hosts})
    9 	# 2. 定義一些運行參數(在運行該python文件的時候就可以指定這些參數了)
   10 	tf.app.flags.DEFINE_string('job_name', default_value='work', docstring="One of 'ps' or 'work'")
   11 	tf.app.flags.DEFINE_integer('task_index', default_value=0, docstring="Index of task within the job")
   12 	FLAGS = tf.app.flags.FLAGS
   13 	# 2. 啟動服務
   14 	def main(_):
   15 	    print(FLAGS.job_name)
   16 	    server = tf.train.Server(cluster, job_name=FLAGS.job_name, task_index=FLAGS.task_index)
   17 	    server.join()
   18 	if __name__ == '__main__':
   19 	    # 底層默認會調用main方法
   20 	    tf.app.run()

客戶端代碼:client-demo01

    1 	import tensorflow as tf
    2 	import numpy as np
    3 	# 1. 構建圖
    4 	with tf.device('/job:ps/task:0'):
    5 	    # 2. 構造數據
    6 	    x = tf.constant(np.random.rand(100).astype(np.float32))
    7 	# 3. 使用另外一個機器
    8 	with tf.device('/job:work/task:1'):
    9 	    y = x * 0.1 + 0.3
   10 	# 4. 運行
   11 	with tf.Session(target='grpc://127.0.0.1:33335',
   12 	config=tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)) as sess:
   13 	    print(sess.run(y))

執行:

1、通過命令行,進入對應環境:我的是activate tensorflow-gpu,再進入對應server-demo.py所在文件夾,重復打開5個,分別輸入(雖然最后結果只是在最后3335中顯示,但是必須要全部運行,才能運算出結果):

python server-demo.py --job_name=ps --task_index=0

python server-demo.py --job_name=ps --task_index=1

python server-demo.py --job_name=work --task_index=0

python server-demo.py --job_name=work --task_index=1

python server-demo.py --job_name=work --task_index=2

2、運行客戶端,最后結果如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM