網易易盾深度學習模型工程化實踐

網易易盾發表於2019-12-14

深度學習大熱之後受到大量關注,大部分剛接觸深度學習的同學,注意力大都集中在如何調整引數/資料/網路結構,如何達到預期的精度/召回率/準確率等。

然而,深度學習模型應用的整個流程裡面還有一個重要的環節,就是模型部署上線。一個模型只有部署上線了,這個模型的價值才能得到體現。

所以我們今天不討論如何訓練模型,我們關注一下如何將訓練好的模型部署上線。

網易易盾深度學習模型工程化實踐

模型生命週期

模型部署上線,就是將模型封裝成一個線上服務,並分配相應的資源,將線上服務執行在伺服器上,實時接收請求,返回predict結果。封裝線上服務的方式有很多,可以選擇一些成熟的框架比如http / thrift / gRPC等,選擇一款適合自己專案的即可,我們重點關注怎麼部署。

模型部署 v0.1 - 裸機部署
顧名思義,就是直接在物理伺服器上安裝配置好相應的環境,直接將工程程式碼/模型檔案部署到物理伺服器上執行,看起來好像很簡單直接,但是實際操作起來問題很多。實際伺服器可能會有2塊GPU甚至4塊GPU,所以一臺伺服器通常需要部署多個模型應用,而在同一臺伺服器上部署多個應用碰到的最常見的問題,就是環境問題。
環境問題的複雜性表現在以下幾個方面:

  • 依賴管理複雜:由於各種原因,線上伺服器的作業系統版本可能會不一致,比如系統有CentOS6/7、Debian8/9,甚至核心版本也會有一些差異,依賴包管理工作變得非常複雜;
  • 容易產生依賴衝突:各個模型應用依賴的包版本很容易產生衝突,比如一個應用依賴了opencv2,另一個應用依賴了opencv3,在沒有很好的隔離的情況下,會出現各種相容性問題;
  • 配置/部署效率低下:某一臺伺服器部署了A應用,某一天A應用下線了,想要部署B應用,可能會面臨遺留環境衝突問題,甚至需要重灌系統從零開始。碰上線上服務需要緊急擴容的情況,這種環境問題更是容易讓人手忙腳亂。

網易易盾深度學習模型工程化實踐

模型部署複雜的環境/依賴

模型部署v0.2 - 容器技術

為了將開發運維從複雜的環境管理工作中解放出來,我們引入了容器技術。容器是一種輕量級、可移植、自包含的軟體打包技術,使應用程式可以在幾乎任何地方以相同的方式執行。

簡單的說,容器包含兩部分:

  • 程式
  • 程式依賴的環境

每個程式都自帶依賴環境,並且相互隔離,這很好的解決了裸機部署帶來的各個應用之間的依賴衝突問題,對宿主機的環境依賴很小,真正實現了 “Build Once, Run Anywhere” 的口號。藉助nvidia官方提供的 nvidia-docker 元件,將nvidia裝置對映到容器內部,我們可以很容易的實現快速的模型應用部署上線。

網易易盾深度學習模型工程化實踐

容器化環境隔離

但容器技術並沒有解決所有問題,其中一個問題就是資源管理和排程問題,由於一臺伺服器需要部署多個應用,每個應用都需要分配1塊GPU,這就要求我們手動維護好分配記錄,例如:

  • 應用 A 部署在 Server0 伺服器上,分配了第0塊GPU
  • 應用B部署在Server0 / Server1伺服器上,分配了第1塊GPU
  • ...

這種管理工作在叢集規模小的時候可以手動管理,但是在叢集規模大了之後就很混亂、很複雜了,而且也容易錯——尤其是當今天易盾日均請求量達到十億量級以上的時候,僅靠手動管理已無法想象。

更為嚴峻的是,因為沒有對應用的資源做隔離,透過這種方式部署的應用,相互之間會產生資源競爭問題。例如一臺伺服器上執行了 A / B / C 應用,此時A應用由於程式Bug將CPU資源耗盡,此時在同一臺伺服器上的B / C應用也會受到牽連影響。

模型部署v0.3 - Kubernetes

為了解決資源排程問題,我們引入了Kubernetes。Kubernetes 是一個開源系統,用於容器化應用的自動部署、擴縮和管理。在Kubernetes裡有一個“資源”的概念,比如CPU和記憶體都是資源型別,我們可以透過Kubernetes對執行的容器進行資源管理,例如:

apiVersion: v1

kind: Pod

metadata:      

name: nginx

spec: 

containers:

 - name: nginx   

image: nginx      

resources:     

requests:       

memory: "64Mi"       

cpu: "1"     

limits:       

memory: "128Mi"       

cpu: "2"


我們對執行的nginx容器申請了64M記憶體和1核CPU,並且限制這個容器最多隻能使用128M記憶體和2核CPU,如果nginx程式嘗試申請超過128M記憶體,就會被kubernetes系統kill掉重新拉起來,確保不會影響其他應用。藉助nvidia官方提供的 k8s-device-plugin 外掛,nvidia GPU也被抽象成一種資源型別,這時候我們就可以像申請CPU/記憶體一樣申請GPU資源。

apiVersion: v1

kind: Pod

metadata: 

name: model-app

spec: 

containers: 

- name: model-app   

image: model-app:v0.3   

resources:      

requests:       

cpu: 4       

memory: "8Gi"       

nvidia.com/gpu: "1"     

limits:       

cpu: 4       

memory: "10Gi"       

nvidia.com/gpu: "1"


上述示例中我們為 model-app這個應用申請了4核CPU、8G記憶體、1塊GPU,申請提交之後,Kubernetes會分配好對應的資源,並自動排程。開發運維人員的視角從“某臺服務部署了xx應用”轉換為“這個kubenetes叢集的資源使用情況”,這極大的簡化了運維管理工作。

Kubernetes自帶了dashboard元件,監控方案可以用prometheus+grafana,基本的運維和監控管理都可以實現,但畢竟是開源版本,部分功能還不能滿足我們的運維開發需求,經過一番定製開發,我們基於Kubernetes開發出了適合自己的集開發運維於一體的一站式管理平臺。

網易易盾深度學習模型工程化實踐

易盾某專案的資源彙總資訊


總結
由於易盾業務發展迅猛,網易安全部商業化易盾僅僅三年多一點的時間,網易易盾就已擁有超過26萬的開發者,服務客戶達數千家。這也使得這塊技術,從最早的裸機手動部署,到半自動的容器部署,再到全自動的kubernetes部署。

每一次進步都伴隨著效率的提升,解放了大量的開發運維人員精力,讓開發運維人員可以投入更多的精力到值得關注的產品功能上。與此同時,也使得易盾的機器學習模型,從訓練完成到上線應用,僅需要數分鐘就可以實現落地,從而及時幫助某些有緊急需求的客戶。


參考資料

https://www.docker.com/

https://github.com/NVIDIA/nvidia-docke

rhttps://github.com/NVIDIA/k8s-device-plugin

https://kubernetes.io/zh/



點選免費體驗網易易盾安全服務。

相關文章