本文來自 網易雲社區 。 Dolphin 是猛獁平臺里的一個機器學習功能模塊,提供給數據科學家進行機器學習的演算法開發、模型訓練和服務發佈,提供分散式全功能深度學習框架,易學易用,高效靈活,支持 Tensorflow、MXNet、Caffe、Spark 等多種機器或深度學習框架,最大可能的挖掘出數據的 ...
本文來自 網易雲社區 。
Dolphin 是猛獁平臺里的一個機器學習功能模塊,提供給數據科學家進行機器學習的演算法開發、模型訓練和服務發佈,提供分散式全功能深度學習框架,易學易用,高效靈活,支持 Tensorflow、MXNet、Caffe、Spark 等多種機器或深度學習框架,最大可能的挖掘出數據的價值。
Dolphin 是基於 Kubernetes 和 Docker 構建的機器學習的底層架構,通過 OVS (或 Calico)構建了容器的扁平化網路,通過 Harbor 進行容器管理,系統還實現了 GPU 監控管理、存儲、日誌、監控、許可權管理等功能。
Architecture
- 基礎設施
整個系統基礎設施中包括了 GPU 和 CPU 的混合計算服務節點,伺服器之間通過 InfiniBand 構建高速的數據交換網路,數據存儲在 HDD 和 SSD 盤的 HDFS 文件系統中 - 容器集群
dolphin 通過 Docker 對多種機器學習框架、用戶開發環境進行實例化和運行,完全通過 Kubernetes 提供計算集群的部署、維護、 擴展機制等功能 - 計算框架
Tensorflow 和 Kubernetes 均是由 Google 開源,Tensorflow 可以原生態的支持 Kubernetes 的調度和監控管理。Kubernetes 是高度可配置和可擴展的系統,我們通過擴展 CustomResourceDefinition 實現 MXNet 等其他機器學習框架的接入 - 開發平臺
數據科學家在開發平臺進行數據管理、特征管理、可視化演算法開發和計算流程圖設計,一鍵式服務發佈 - 數據安全
dolphin 具有欄位級別的細粒度數據許可權控制能力,能夠對 IMPALA、SPARK、HIVE 實現一致性的 SQL 執行許可權校驗和對應的 HDFS 文件訪問控制,保障了標簽數據、訓練數據和模型數據的數據安全 - 任務管理
開發了基於隊列的任務調度系統,解決了 Kubernetes 沒有隊列服務的問題
開發了計算節點的 GPU 監控服務,解決了 Kubernetes 目前無法監控 GPU 的資源使用情況的問題
開發了 Kubernetes 中訓練服務的參數服務的生命周期管理模塊,解決了 Tensorflow 的參數服務在訓練完畢無法自我關閉的問題 - 監控中心
通過 Heapster+Influxdb+Grafana 進行集群的監控,通過 Fluentd+Elasticsearch+Kibana 進行日誌的收集
Kubernetes Cluster
Master
- API Server:提供了資源對象的唯一 REST 操作入口,其他所有組件都必須通過它提供的API來操作 NODE、POD、Service 資源數據
- Controller Manager:作為集群內部的管理控制中心,負責集群內的 Node、Pod 副本、Endpoint、Namespace、服務賬號、資源定額的管理,當某個 Node 意外宕機時,Controller Manager 會及時發現並執行自動化修複流程,確保集群始終處於預期的工作狀態
- Scheduler:收集和分析當前 Kubernetes 集群中所有 Minion 節點的資源(記憶體、CPU)負載情況,然後依此分發新建的 Pod 到 Kubernetes 集群中可用的節點
- Etcd:保存了整個 Kubernetes 集群的狀態
Minion
- Kubelet:節點上的 Pod 管家,負責 Node 節點上 pod 的創建、修改、監控、刪除等全生命周期的管理
- Proxy:解決外部網路能夠訪問跨機器集群中容器提供的應用服務
Kubernetes Master
Kubernetes Node
Etcd - Distributed reliable key-value store
Etcd 服務發現是一個基於 Raft 協議的強一致性、高可用的鍵值對存儲,用於 集群中的服務註冊、監控服務健康狀態 和共用服務配置,在 Etcd 中 存儲了 kubernetes 集群所有的數據。
kubernetes NetWork Model
谷歌內部的基礎設施已經保障了所有的容器之間通過平行網路實現互聯互通,Kubernetes 預留了網路插件介面,由使用者自行構建網路,目前社區也給出了 Flannel、Calico、OVS 等網路方案,機器學習是一個計算密度型系統,對數據傳輸性能要求非常高,所以需要慎重考慮使用哪種網路模型。
- Flannel:是使用橋接介面轉髮網絡包的 overlay 網路,從一個容器發往另一個容器的網路包將歷經兩個網路棧,網路傳輸性能存在一定的損耗,所以沒有採納該方案
- Calico:是使用了基於 BGP 路由方式的網路模型,數據通過 Linux Kernel 查找路由表直接轉發到對方容器所在的宿主機,避免了 Flannel 網路存在的數據從內核態到用戶態的 2 次處理,效率損耗最小,Calico 部署十分的方便快捷,非常適合在私有化的環境中進行部署使用
- OVS:在公有雲的部署直接使用網易雲的 OVS 網路
Calico
- Felix,主要負責配置路由及ACLs等信息來確保endpoint的連通狀態
- Etcd,主要負責網路元數據一致性,確保Calico網路狀態的準確性
- BGPClient(BIRD),主要負責把 Felix 寫入 kernel 的路由信息分發到當前 Calico 網路,確保 workload 間的通信的有效性
- BGPRouteReflector(BIRD),大規模部署時使用,摒棄所有節點互聯的 mesh 模式,通過一個或者多個 BGPRouteReflector 來完成集中式的路由分發
- Calico 在每一個計算節點利用 Linux kernel 實現了一個高效的 vRouter 來負責數據轉發,而每個 vRouter 通過 BGP 協議負責把自己上運行的 workload 的路由信息向整個 Calico 網路內傳播,小規模部署可以直接互聯,大規模下可通過指定的 BGProutereflector 來完成
NVidia Docker
因為 GPU 屬於特定的廠商產品,需要特定的 Driver,Docker 本身並不支持 GPU。以前如果要在 Docker 中使用 GPU,就需要在 Container 中安裝主機上使用 GPU 的 Driver,然後把主機上的 GPU 設備(例如:/dev/nvidia0)映射到 Container 中,所以這樣的 Docker image 並不具備可移植性。
英偉達公司的 Nvidia-docker 項目就是為瞭解決這個問題,它讓 Docker image 不需要知道底層 GPU 的相關信息,而是通過啟動 Container 時 mount 設備和驅動文件來實現的,通過查看 Nvidia-docker 的源代碼,我們可以瞭解到 Nvidia-docker 是對 Docker 的 create
和 run
命令進行了封裝,將驅動信息映射到 Container 中。
通過執行 curl -s http://localhost:3476/docker/cli
命令我們能夠獲取到類似如下 Nvidia 驅動信息:
--device=/dev/nvidiactl --device=/dev/nvida-uvm --device=/dev/nvidia3 --device=/dev/nvidia2 --device=/dev/nvidia1 --device=/dev/nvidia0 --volume-drivre=nvidia-docker --volume=/usr/local/nvidia/nvidia_driver_361.48
那麼我們就可以直接通過 docker run -it -rm curl -s http://localhost:3476/docker/cli nvidia/cuda nvidia-smi
直接啟動一個支持 GPU 的 Docker Container,在瞭解了 Nvidia-docker 的運行原理之後,我們完全可以直接使用原生態的 Docker 而不需要使用 Nvidia-docker 項目。
TensorFlow
TensorFlow 是谷歌開源的深度學習工具包,它將深度學習複雜的計算過程抽象成了數據流圖(Data Flow Graph),並提供簡介靈活的高級抽象介面,通過簡單的學習就可以使用「高大上」的深度學習了。
上圖中的示例顯示了從數據 Input 開始,沿著有向圖進行計算,圖中每個節點都是一次計算,稱為 option,TensorFlow 中數據以 Tensor 為格式,輸入一個 Tensor ,經過一次 op 後輸出另一個 Tensor,然後根據數據流圖進入下一個 op 作為輸入,因此,整個計算過程其實是一個 Tensor 數據的流動過程,所以谷歌將這個系統形象的叫做 TensorFlow。
有了數據流圖後下一個問題是如何在各種設備上很好的運行,TensorFlow 通過一個會話 Session 來控制整個數據流圖的執行。TensorFlow 一個很大的優點是將複雜的運算(如矩陣運算,softmax)封裝成了高級函數,用戶只要使用就好了,在內部,TensorFlow 將這些函數轉化成可以高效在 CPU 或 GPU 執行的機器碼。Session 的主要作用是將這張數據流圖合理的切分(儘量減少 Session 與 CPU 或 GPU 之間的交互,因為很慢),按照一定的順序提交給 CPU 或者 GPU,然後(可能)還進行一些容錯的機制,Session 負責高效地讓數據流圖被 CPU 或 GPU 執行完成的。
Tensorflow on Kubernetes
如果讓數據科學家直接使用 Tensorflow 的時候,會遇到例如租戶隔離、資源隔離、網路隔離、難以指定 GPU 進行任務調度等等一系列軟體工程問題,這也是為什麼需要引入 Kubernetes 的原因。
- Tensorflow 資源無法隔離
Kubernetes 提供租戶隔離,容器資源隔離和網路隔離等多種機制 - Tensorflow 缺乏 GPU 資源的調度
Kubernetes-v1.4 開始支持 GPU 調度 - Tensorflow 存在進程遺留問題、無法區分正常完成還是故障退出
Kubernetes 提供容器生命周期管理,進程和容器共生死
不過在進行分散式 Tensorflow 訓練的時候,社區仍然沒有解決 Work 已經工作完畢,Parameter Server 無法自行退出的問題,需要自己開發訓練任務進度監控讓 Parameter Server 退出 - Tensorflow 集群伺服器定位
Kubernetes 提供 DNS 伺服器提供伺服器位置,省去了 Tensorflow 的計算集群的服務節點 IP 地址配置 - Tensorflow 不方便日誌查看
Kubernetes 提供了較為完善的 Monitoring 和 Logging 功能 - Tensorflow 存在訓練數據和模型存儲問題
Kubernetes 支持對接 Cephfs,GlusterFS 等 Read 性能更好的分散式存儲系統 - 多種機器學習框架支持
通過定製化開發 Kubernetes 的 Custom Resource 和 Operator 介面支持 MXNet 等其他機器學習框架
Dolphin
作為數據科學家的開發工具,如何讓數據科學家能夠在演算法編寫、參數調整的時候能夠直接獲取互動式的反饋信息,我們通過深度定製 Jupyter 內核開發了完全在可視化的 dolphin WEB 系統,讓數據科學家在互動式操作界面中所見即所得的編寫演算法、調試參數、輸出可視化圖表並形成演算法報告。
Dolphin 根據數據科學家選用的不同的機器學習演算法框架,通過 Kubernetes 編排出相應的機器學習計算集群,如下圖所示通過 dolphin 調度起來的 Tensorflow 計算集群,創建出 Parameter Server 和 Work 的 POD 以及 SVC,通過 HDFS Mount 模塊將用戶數據空間映射到 Docker Container 中,執行用戶的演算法腳本進行模型訓練和服務發佈。
本文已由作者劉勛授權網易雲社區發佈,原文鏈接:猛獁機器學習開發實踐