Tensorflow訓練中Worker如何動態伸縮

Tensorflow對於大部分算法用戶來說能夠滿足使用需求 。但是在日常使用過程中也發現有一些bug導致日常生產過程中的訓練異常中斷,影響使用 。尤其是在離線集羣進行大規模訓練時,集羣網絡負載大,機器環境惡劣,導致故障頻發,影響用戶體驗。 因此對於Tensorflow的穩定性改造,在大規模生產中是一項必要工作。

Worker 角色的 Failover 及動態擴縮容改造
爲了提升用戶使用體驗提升集羣資源有效利用率抵消用戶超量配置訓練資源的問題。我們主要對Tensorflow角色運行部分進行了如下改造:

Worker 角色的 Failover 。Worker是分佈式訓練中的計算角色,異常退出的高發戶 。增加Failover機制,做到異常中斷用戶無感知,極大提升用戶的使用體驗。
Worker 角色 動態擴縮容。在線生產過程中數據量生產不是均勻產生的 。如國內業務白天數據量較大,晚上相對較少。國際業務 則正好相反。爲了優化資源利用率,我們增加了Tensorflow動態擴縮容機制,在流程數據生產低谷時段 ,能夠主動釋放計算資源給其他計算任務。數據高峯時段則主動增加資源提高訓練速度。

實現方案介紹
Tensorflow分佈式訓練採用的是PS模式,即參數服務器模式。訓練過程中各個Worker (數據消費和梯度計算的執行者)將計算得到的梯度信息同步到PS上正向計算時Worker負責從PS上拉取參數 。PS與Worker之間的數據通信依賴於GRPC 。GRPC 連接在角色啓動的過程中進行建立 。在原生Tensorflow中GRPC通信通道的建立依賴於每個角色啓動時配置的 cluster_spec文件,是一種靜態構建過程,爲了實現Failover和動態擴縮容,我們需要打破這種靜態機制,構建動態連接關係。

1.原生sparse配置打破worker之間關聯

靜態cluster_spec配置格式如下(以3Worker,2PS爲例)

這種配置方式 Tensorflow 會 在啓動時爲PS&Worker和Worker&Worker之間都建立通信連接,當任意Worker失敗時所有Worker 都會失敗。原生Tensorflow還支持一種Sparse配置,可以打破Worker之間的依賴,這樣任意Worker失敗不會對其他Worker造成 影響。如Worker0啓動配置方式如下:

通過sparse的方式可以切斷Worker之間的相互影響。可以解決Worker縮容的問題。

2.通信通道註冊機制打破PS,Worker角色依賴

在Tensorflow中通信通道建立是在角色啓動時的find device階段 。當任務已經運行時,如果worker發生重啓,PS上的通信通道建立過程不會重複執行 ,新啓動的角色無法被 PS發現。因此這種方式不能夠解決 Failover 和 Worker擴容 的問題。爲了打破這種 限制,需要在Tensorflow中增加通信參數註冊機制。PS中的Worker通信信息不依賴於參數傳入,改由GRPC服務動態註冊 。實現通信信息註冊更新,類調用關係如下圖所示(依據Tensorflow1.8版本源碼結構):

註冊機制實現機制如上所示,在實現過程中也遇到一些問題。Tensorflow在不同層次的通信對象做了緩存,如果在上層找到了通信對象則不會繼續向下查找。這樣在Worker Failover的時候會導致新通信地址無法得到更新因爲上層緩存了舊 的通信對象(緩存 在GrpcWorkerCache中。我們採用的策略是將上層cache全部刪除,只更新最下層的IP和Port信息 。這樣在Worker Failover或者新增節點的時候會有一次通信對象rebuild 。解決了Worker能夠任意重啓和任意擴縮的問題剩下需要解決的問題就是調度策略的 問題 。

整個分佈式任務的啓動依賴於分佈式調度框架,我們是基於yarn和docker實現。因此可以在 AppMaster的實現中結合在線數據源(Kafka)的數據生產速度進行調度具體實現不再贅述。這樣一套資源自適應的Tensorflow分佈式訓練系統就落地了,實際上線效果也非常理想,不僅cover了因爲集羣環境惡劣和Tensorflow bug導致Worker abort問題,又有效提升了集羣利用率 。

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