INTERSPEECH 2014 | 1-Bit Stochastic Gradient Descent and its Application to Data-Parallel Distribute

這篇文章以前也讀過,不過讀的不太仔細,論文中的一些細節並無注意到。最近爲了寫開題報告,又把這篇論文細讀了一遍。據筆者瞭解,這篇論文應該是梯度量化領域的開山之做,首次使用了梯度量化技術來下降分佈式神經網絡訓練的通訊開銷。除此以外,這篇文章還提出了偏差補償機制,這種機制能夠緩解梯度量化的負面影響,下降信息丟失所帶來的模型精度損失。算法

對於數據並行式訓練來講,最佳節點數量\(\hat{K}\)可以使得節點中計算和數據通訊徹底重疊,即同時使通訊和計算資源飽和:服務器

\[T_{calc}(\hat{K}) = T_{comm}(\hat{K}) \]

\(T_{calc}\)\(T_{comm}\)分別是節點上每一個minibatch所須要的計算和通訊時間。若是咱們將計算和通訊開銷細分,就可以求出最優節點數量:網絡

\[\hat{K} = \frac{\frac{N}{2} \cdot T_{calc}^{frm}+C\cdot T_{post}^{calc}}{\frac{1}{Z}\cdot T^{float}_{comm}-T_{upd}^{calc}} \]

符號 含義 與參數量\(M\)的關係
\(T_{calc}^{frm}\) 處理數據的時間,這部分是能夠並行的 \(\propto\frac{M}{\text{FLOPS}}\)
\(T_{calc}^{post}\) 對梯度後處理的時間,如momentum + AdaGrad操做 \(\propto\frac{M}{\text{RAM bindwidth}}\)
\(T_{comm}^{float}\) 傳輸梯度(由單精度浮點數表示)的時間 \(\propto\frac{M}{\text{Network bindwidth}}\)
\(T_{calc}^{upd}\) 模型更新時間,相對於\(K\)來講是固定的 \(\propto\frac{M}{\text{RAM bindwidth}}\)

爲了實現更高的並行度,做者提出了雙緩衝(double buffering)的概念,即在每一個節點上把一個minibatch分紅兩部分,在交換其中一部分的梯度時進行另外一部分的計算。然而,雙緩衝機制會引入額外的更新開銷,當通訊開銷小於更新開銷(即\(T_{comm}^{float} \lt T_{calc}^{upd}\))時,上述公式就再也不成立,雙緩衝機制也就失去了做用。架構

本文的核心思想就是將32位單精度浮點數壓縮成1位,從而下降訓練過程的數據交換開銷。爲了進一步下降通訊開銷,做者設定在節點間只進行梯度的交換,不進行模型參數的交換。爲了下降量化偏差帶來的負面影響,做者使用了偏差補償技術:每次量化時,把上一次迭代的量化偏差加到本次迭代的梯度上,而後再進行量化,接着求出本次量化操做的偏差。這種偏差補償機制能夠確保全部的梯度都會再必定程度上對模型更新產生做用,只不過這種做用分散在不一樣的迭代中——相似於一種延遲更新的形式。做者指出,使用偏差補償後,就能夠在幾乎不損失模型精度的狀況下將梯度由32位量化成1位。分佈式

\[\begin{aligned} \tilde{g}_t &= Q(g_t + \text{Err}_{t-1})\\ \text{Err}_{t} &= g_t - Q^{-1}(\tilde{g}_t) \end{aligned} \]

在具體實現上,一種比較簡單(且有效)的方法是將大於0的梯度值編碼位1,小於等於0的梯度值編碼爲0。在反量化(解碼)時,將1解碼爲+1,將0解碼爲-1,再進行聚合與更新操做。post

本文做者並無使用參數服務器架構,而是使用了一種相似於AllReduce的梯度聚合方法。每一個節點負責聚合\(1/K\)的模型參數子集。也就是說,假設模型參數量爲\(M\),那麼每一個節點都從其餘全部節點接收到\(M\times \frac{K-1}{K^2}\)個值。這些值被反量化後,在節點上進行聚合以及後處理(AdaGrad、momentum),而後進行第二次量化,再把量化後的梯度傳給其餘全部的節點並進行更新操做。學習

根據公式能夠看出,有3種方法能夠提升並行性:(1)增長batchsize,(2)增大壓縮比率Z,(3)下降更新開銷\(T_{calc}^{upd}\)。前面已經介紹如何對梯度進行壓縮,這裏主要介紹方法1和方法3。
對於方法1,一味地增長batchsize並不可取,由於這可能致使模型不收斂。爲了解決較大batchsize下模型不收斂的問題,做者使用了較小的學習率和AdaGrad優化算法。可是通常來講,當batchsize增大時,學習率應該按照必定的比例進行放大[1, 2],多是由於模型不一樣的緣由,做者使用較小的學習率能夠得到不錯的效果。設置全局學習率以後,AdaGrad每次經過全局學習率逐參數地除以歷史梯度平方和的平方根,使得每一個參數的學習率不一樣。AdaGrad的做用是在參數空間較爲平緩的方向學習率會較大(由於平緩,因此累加梯度平方和較小,對應學習降低的幅度較小);參數空間較爲陡峭的方向學習率會較小,從而加快訓練速度。做者指出,咱們能夠在三個不一樣的時間點應用AdaGrad:量化以前在每一個節點上本地使用(可能會有助於量化,但也有可能在節點之間引入不一致的風險);聚合後的數據交換期間(有可能引發量化干擾);動量平滑以後(節省內存和更新開銷,但因爲平滑了峯值會下降了AdaGrad的效果)。經過實驗驗證,做者選擇在梯度聚合後應用AdaGrad算法,(一個可能的)緣由是量化操做將異常值分散在多個minibatch種,這樣它們對標準差估計的影響較小。優化

對於方法3,做者使用了模型並行來下降更新開銷。不過在做者的實驗中,模型並行的效果貌似並非很好,因此這裏就再也不討論了。編碼

參考資料
[1] Goyal P, Dollár P, Girshick R, et al. Accurate, large minibatch sgd: Training imagenet in 1 hour[J]. arXiv preprint arXiv:1706.02677, 2017.
[2] Krizhevsky A. One weird trick for parallelizing convolutional neural networks[J]. arXiv preprint arXiv:1404.5997, 2014.spa

相關文章
相關標籤/搜索