分佈式Tensorflow中同步梯度更新tf.train.SyncReplicasOptimizer解讀(backup_worker的用法)

       在tensorflow的訓練中,分佈式可以大大的加快模型訓練速度,但是分佈式怎麼分配和參數設定,都和SyncReplicasOptimizer這個函數有很大關係。

       操作系統:Ubuntu16.04

       運行環境:python3.6,nvidia384(4塊),tensorflow-gpu1.10+cuda+cudnn(根據自己實際gpu配置)

      現在我們看看SyncReplicasOptimizer這個函數的源碼解讀

     首先這個SyncReplicasOptimizer函數是專門出來分佈式深度學習中的同步梯度下降的(要用異步梯度的可以直接無視)

def __init__(self,
             opt: Any,
             replicas_to_aggregate: Any,
             total_num_replicas: Any = None,
             variable_averages: Any = None,
             variables_to_average: Any = None,
             use_locking: bool = False,
             name: str = "sync_replicas") -> None
Construct a sync_replicas optimizer.
Params:
opt – The actual optimizer that will be used to compute and apply the gradients. Must be one of the Optimizer classes.
replicas_to_aggregate – number of replicas to aggregate for each variable update.
total_num_replicas – Total number of tasks/workers/replicas, could be different from replicas_to_aggregate. If total_num_replicas > replicas_to_aggregate: it is backup_replicas + replicas_to_aggregate. If total_num_replicas replicas_to_aggregate: Replicas compute multiple batches per update to variables.
variable_averages – Optional `ExponentialMovingAverage` object, used to maintain moving averages for the variables passed in `variables_to_average`.
variables_to_average – a list of variables that need to be averaged. Only needed if variable_averages is passed in.
use_locking – If True use locks for update operation.
name – string. Optional name of the returned operation.

       opt:將用於計算和應用梯度的實際優化器。必須是Optimizer類之一。
       variable_averages:可選的`ExponentialMovingAverage`對象,用於保持傳入的變量的移動平均值
       variables_to_average:需要平均的變量列表。只要如果傳入variable_averages則需要。
       use_locking:如果True使用鎖定進行更新操作。
       name:string。返回操作的可選名稱。

      除開opt之外,其他可以先不指定,我們這裏重點看看replicas_to_aggregate和total_num_replicas這兩個參數,這是非常重要的。

      replicas_to_aggregate:是指我們所需要通過分佈式的worker計算完成之後所需要的副本數,這裏可以認爲就是梯度的個數

      total_num_replicas:是指我們指定出入計算樣本的數量(幾個機器就分配幾個batch_size)

      我們看看網上針對SyncReplicasOptimizer用比較多的代碼這一段:

      代碼出處:https://blog.csdn.net/guotong1988/article/details/53927424

#同步模式計算更新梯度
        rep_op = tf.train.SyncReplicasOptimizer(optimizer,
                                                replicas_to_aggregate=len(
                                                  worker_hosts),

                                                total_num_replicas=len(
                                                  worker_hosts),
                                                use_locking=True)
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

       我們可以看出,replicas_to_aggregate和 total_num_replicas都是等於集羣中worker的數量的,但是源碼中對於這兩個參數又添加了額外的解釋,(replicas_to_aggregate以下簡稱副本數,total_num_replicas以下簡稱計算數)

replicas_to_aggregate: number of replicas to aggregate for each variable
        update.
      total_num_replicas: Total number of tasks/workers/replicas, could be
        different from replicas_to_aggregate.
        If total_num_replicas > replicas_to_aggregate: it is backup_replicas +
        replicas_to_aggregate.
        If total_num_replicas < replicas_to_aggregate: Replicas compute
        multiple batches per update to variables.

    什麼意思呢?意思就是說,副本數可以和計算數可以是不相等的。就好比有三個人交了三張試卷一樣,三個人就是計算數,三張試卷就是副本數。

   源碼中說,If total_num_replicas > replicas_to_aggregate: it is backup_replicas + replicas_to_aggregate.

   這是指如果計算數大於副本數,那麼多的那個就是backup worker,即備份工作節點。

   比如:四個人交了三張試卷,沒交試卷的我們就認爲是備份工作節點   

   那這又是什麼玩意兒呢,圖啥呢?

                                               

    在同步梯度下降中,所有worker都要等大家一起計算完成之後才能進行計算,因此會出現等待機制。就像四個人做試卷,但是每個人的速度不一樣,但是要同時交卷,所以我們要等待交卷最慢的那個人算完之後才能算完,這樣很浪費算的很快的那個人的能力,所以就有了backup的提出,4個人交卷我們只要三個人的試卷,最慢的那個我們不要了,直接清除掉,開始下一輪的考試~

因此,加入backup worker的方法可以加速分佈式同步梯度下法的訓練模型,那麼backup取幾個呢?Revisiting Distributed Synchronous SGD這篇論文中認爲是20:1的比例。

    backup worker論文出處:鏈接:https://pan.baidu.com/s/1R22sfGTZcAy_5KEysJGX7Q    提取碼:26zi 

    還有一種情況,那就是計算數大於副本數。當計算數小於副本數,那麼他會多計算其他worker的樣本,就好比三個人(給三人一人發一個試卷,分配的是沒多餘的),但是要交四份試卷,那就先各算各的,先計算完成的再從已知的三份試卷中拿一個計算,然後再等着這三個人一共上交了四份試卷之後,這樣就ok了。有什麼用呢?我也不清楚,我們看下一步

    當我們說這計算數和副本數的時候總是和機器的物理數量有關係(gpu數量),那麼其實這兩個都可以不等於機器的物理數量。例如:

    gpu數量:3           那麼len(worker)就是3

    計算數:10           那麼這10就指的是一次給分10個batch_size,然後讓3個worker去算

     副本數:8             那麼這是個batch_size算完之後我只要8個梯度,然後平均,參數服務器的什麼後續操作

    如果有什麼問題和不對的地方請留言指正,謝謝

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章