TensorFlow on Kubernetes (上)

TensorFlow on Kubernetes (上)

在 2016 年一場圍棋『人機大戰』中,人類李世乭敗給了 Google 的人工智慧(AI) AlphaGo,這為全球掀起了熱烈討論,甚至讓人聯想到『人工智慧將逐漸取代人』的想法。然而在大家為之震驚時,全球許多科技巨頭早已紛紛投入 AI 相關研發,如 Google、Amazon、Microsoft、Facebook 等知名科技業,及Intel、Qualcomm、NVIDIA等硬體供應商,投入AI相關硬體加速之開發,而在汽車業甚至已有研發自駕車,無庸置疑 AI 已成為各產業的全民運動之一。

然而隨著各家科技巨頭紛紛透過開放原始碼方式,釋出自家的深度學習與機器學習框架後,使許多中小型企業得以參與這場AI全民運動,並希望透過該技術從既有的公司資源中,萃取出有價值的模型,來增加公司產品的優勢。其中在開源碼深度學習框架中,又以Google Brain Team開源的 TensorFlow 最受歡迎,其利用開源方式獲得社群共享的力量,在短短時間內加速了機器學習的進展。

本篇將基於TensorFlow說明如何進行分散式資料訓練,另外,隨著企業間採納 Container 技術趨勢增加,導致傳統 IT 架構漸漸被取代,因此本篇亦將說明如何利用Google容器管理系統Kubernetes與TensorFlow進行整合。

TensorFlow

TensorFlow為利用資料流圖(Data Flow Graphs)描述數值運算過程的函式庫。其中資料流圖中的節點(Nodes)表示數學運算,而邊(Edges)則表示節點之間互相關聯的多維資料陣列,即為張量(Tensor)。它靈活的架構能讓使用者在不同平台上執行運算,例如PC中的一或多個CPU(或GPU)、智慧手持裝置與伺服器等。

TensorFlow在字面上應分兩個部分來解釋,Tensor與Flow:

  • Tensor:指一個n維度的陣列或列表。如一維Tensor就是向量,二維Tensor就是矩陣等等。
  • Flow:指一張圖(Graph)中的運算過程資料流。

以下為一簡單範例,說明如何建立一張圖來描述運算:

上面範例程式描述之圖(Graph)運算,執行結果如下圖所示。

分散式運算

TensorFlow叢集裡包含了一或多個工作(Job),各工作又可拆分成一或多個任務(Task),簡單說Cluster是Job的集合,而Job是Task的集合。叢集概念主要用在特定層次對象,如訓練神經網路、平行操作多台機器等,一個叢集物件可透過tf.train.ClusterSpec來定義。

如上所述,TensorFlow的叢集就是一組工作任務,每項任務是一個服務,而服務又分成Master Service與Worker Service兩種,並提供給Client進行操作。

  • Master Service:一項RPC服務行程,用來遠端連線一系列分散式裝置,主要提供tensorflow::Session介面,並負責透過Worker Service與工作的任務進行溝通。
  • Worker Service:一個可使用本地裝置(CPU或GPU)對部分Graph進行運算的RPC邏輯,透過worker_service.proto介面來實作,所有 TensorFlow伺服器均包含Worker Service邏輯。

TensorFlow 伺服器為運行tf.train.Server實例的行程,其為叢集一員,並有Master與Worker之分。

而TensorFlow的工作(Job)可拆成多個相同功能的任務(Task),這些工作又分成Parameter server與Worker,兩者功能說明如下:

  • Parameter server:主要根據梯度更新變數,並儲存於tf.Variable,可解釋為僅儲存模型的變數,並存放Variable副本。
  • Worker:通常稱為計算節點,主要執行密集型的Graph運算資源,並根據變數運算梯度,亦能儲存Graph副本。

在TensorFlow中的副本擁有In-graph和Between-graph模式,其差異如下所示:

  • In-graph:只有一個Client(主要呼叫tf::Session行程),並將裡面變數與op指定給對應的Job完成,因此資料分發只由一個Client完成。此方式設定簡單,其他節點只需join操作,並提供一個gRPC位址來等待任務。但訓練資料只在單一節點,因此要分發資料到不同機器時,會影響平行訓練效能。可理解成所有op都在同一個Graph中,伺服器只需做join()功能。
  • Between-graph:多個獨立Client建立相同Graph(包含變數),並透過tf.train.replica_device_setter將這些參數映射到ps上,即訓練的變數儲存在Parameter Server;而資料不用分發,資料分片(Shards)會存在各計算節點,因此各節點能各自計算。計算完成後,將欲更新變數告知Parameter Server進行更新。適合在TB級別的資料量使用,節省大量資料傳輸時間,亦是深度學習推薦模式。

TensorFlow除了在副本模式有所差異外,其訓練模式也進一步區分了同步與非同步方式,以下將說明兩者的差異:

  • Synchronous:每個Graph副本讀取相同Parameter Server值,平行計算梯度(gradients),將所有計算完的梯度一同處理,每次更新梯度時,需等所有分發的資料計算完成,並回傳結果將梯度累加計算平均,再進行更新變數。好處在於使用損失下降時,較於穩定,壞處則為需等最慢的分片計算時間。
  • Asynchronous:自行計算梯度後,即可更新paramenter,不同副本下不會進行協調進度,因此計算資源將被充分利用。缺點是loss的下降較不穩定。

分散式計算問題

在原生的TensorFlow中,雖已支援分散式運算的功能實現,但卻存有三大問題:

  • 叢集管理:在管理叢集時,任何過程皆需手動方式進行啟動或關閉,當故障無法第一時間得知問題點時,不具Monitoring與Logging功能,且無法進行作業排程。
  • 行程生命週期管理:無法區別行程為正常完成或故障退出而結束等問題。所有行程需要手動方式進行管理,當遇到大型叢集時,將會造成維運人員的過度負荷。
  • 共享式儲存:由於TensorFlow預設並無共享式儲存系統,因此資料需手動匯入或透過網際網路下載,而造成資料之間的傳遞問題,並且沒有任何的資料安全措施,一旦故障將導致資料遺失問題。

綜合上述問題,TensorFlow若要在有規模的訓練叢集中進行管理,即需要利用相關工具來達成。然而從問題的瓶頸點來看,容器叢集管理系統 Kubernetes正是最佳的選擇。

<未完待續>

撰文: 白凱仁/迎棧科技軟體工程師

訂閱電子報

Select list(s)*

 

Loading