ML平臺_小米深度學習平臺的架構與實踐

    (轉載:http://www.36dsj.com/archives/85383)機器學習與人工智能,相信你們已經耳熟能詳,隨着大規模標記數據的積累神經網絡算法的成熟以及高性能通用GPU的推廣,深度學習逐漸成爲計算機專家以及大數據科學家的研究重點。近年來,不管是圖像的分類識別和檢測,仍是語音生成、天然語言處理,甚至是AI下圍棋或者打遊戲都基於深度學習有了很大的突破。而隨着TensorFlow、Caffe等開源框架的發展,深度學習的門檻變得愈來愈低,甚至初中生均可以輕易實現一個圖像分類或者自動駕駛的神經網絡模型,但目前最前沿的成果主要仍是出自Google、微軟等巨頭企業。算法

     Google不只擁有優秀的人才儲備和大數據資源,其得天獨厚的基礎架構也極大推進了AI業務的發展,得益於內部的大規模集羣調度系統Borg,開發者能夠快速申請大量GPU資源進行模型訓練和上線模型服務,而且經過資源共享和自動調度保證總體資源利用率也很高。Google開源了TensorFlow深度學習框架,讓開發者能夠在本地輕易地組合MLP、CNN和RNN等模塊實現複雜的神經網絡模型,但TensorFlow只是一個數值計算庫,並不能解決資源隔離、任務調度等問題,將深度學習框架集成到基於雲計算的基礎架構上將是下一個關鍵任務數據庫

     除了Google、微軟,國內的百度也開源了PaddlePaddle分佈式計算框架,而且官方集成了Kubernetes等容器調度系統,用戶能夠基於PaddlePaddle框架實現神經網絡模型,同時利用容器的隔離性和Kubernetes的資源共享、自動調度、故障恢復等特性,但平臺不能支持更多深度學習框架接口。而亞馬遜和騰訊雲相繼推出了面向開發者的公有云服務,能夠同時支持多種主流的開源深度學習框架,阿里、金山和小米也即將推出基於GPU的雲深度學習服務,還有無數企業在默默地研發內部的機器學習平臺和大數據服務。編程

    面對如此眼花繚亂的雲服務和開源技術,架構師該如何考慮其中的技術細節,從用戶的角度又該如何選擇這些平臺或者服務呢。我將介紹小米雲深度學習平臺的架構設計與實現細節,但願能給AI領域的研發人員提供一些思考和啓示。後端

雲深度學習平臺設計api


     雲深度學習平臺(Cloud Machine Learning),就是基於雲計算的機器學習和深度學習平臺。首先TensorFlow、MXNet是深度學習框架或者深度學習平臺,但並非雲深度學習平臺,它們雖然能夠組成一個分佈式計算集羣進行模型訓練,但須要用戶在計算服務器上手動啓動和管理進程,並沒有云計算中任務隔離、資源共享、自動調度、故障恢復以及按需計費等功能。所以咱們須要區分深度學習類庫以及深度學習平臺之間的關係,而這些類庫實現的隨機梯度降低反向傳播等算法倒是深度學習應用所必須的,這是一種全新的編程範式,須要咱們已有的基礎架構去支持。數組

雲計算和大數據發展超過了整整十年,在業界催生很是多優秀的開源工具,如實現了相似AWS IaaS功能的OpenStack項目,還有Hadoop、Spark、Hive等大數據存儲和處理框架,以及近年很火的Docker、Kubernetes等容器項目,這些都是構建現代雲計算服務的基石。安全

這些雲服務有共同的特色,例如咱們使用HDFS進行數據存儲,用戶不須要手動申請物理資源就能夠作到開箱即用,用戶數據保存在幾乎無限制的公共資源池中,而且經過租戶隔離保證數據安全,集羣在節點故障或者水平擴容時自動觸發Failover且不會影響用戶業務。雖然Spark經過MLib接口提供部分機器學習算法功能,但毫不能替代TensorFlow、Caffe等深度學習框架的做用,所以咱們仍須要實現Cloud Machine Learning服務,而且確保實現雲服務的基本特性服務器

總結爲下面幾條:網絡

  • 屏蔽硬件資源保證開箱即用
  • 縮短業務環境部署和啓動時間
  • 提供「無限」的存儲和計算能力
  • 實現多租戶隔離保證數據安全
  • 實現錯誤容忍和自動故障遷移
  • 提升集羣利用率和下降性能損耗 

相比於MapReduce或者Spark任務,深度學習的模型訓練時間週期長,並且須要調優的超參數更多,平臺設計還須要考慮如下幾點:架構

  • 支持通用GPU等異構化硬件
  • 支持主流的深度學習框架接口
  • 支持無人值守的超參數自動調優
  • 支持從模型訓練到上線的工做流

這是我我的對雲深度學習平臺的需求理解,也是小米在實現cloud-ml服務時的基本設計原則。雖然涉及到高可用、分佈式等頗具實現難度的問題,但藉助目前比較成熟的雲計算框架和開源技術,咱們的架構和實現基本知足了前面全部的需求

雲深度學習平臺架構


遵循前面的平臺設計原則,咱們的系統架構也越發清晰明瞭,爲了知足小米內部的全部深度學習和機器學習需求:

  • 須要有一個多租戶、任務隔離、資源共享、支持多框架和GPU的通用服務平臺
  • 經過實現經典的MLP、CNN或RNN算法並不能知足業務快速發展的需求,所以咱們須要支持TensorFlow等用戶自定義的模型結構
  • 支持高性能GPU和分佈式訓練是這個雲深度學習平臺的必須功能
  • 不只僅是模型訓練,咱們還但願集成模型服務等功能來最大化用戶的使用效益

計算機領域有句名言「任何計算機問題均可以經過增長一箇中間層來解決」。不管是AWS、OpenStack、Hadoop、Spark仍是TCP/IP都是這樣作的,經過增長一個抽象層來屏蔽底層資源,對上層提供更易用或者更可靠的訪問接口。小米的cloud-ml平臺也須要實現對底層物理資源的屏蔽,尤爲是對GPU資源的抽象和調度,但咱們不須要從新實現,由於社區已經有了不少成熟的分佈式解決方案,如OpenStack、Yarn和Kubernetes。目前OpenStack和Yarn對GPU調度支持有所欠缺,虛擬機也存在啓動速度慢、性能overhead較大等問題,而容器方案中的Kubernetes和Mesos發展迅速,支持GPU調度等功能,是目前最值得推薦的架構選型之一

進一步簡化了整個雲深度學習平臺的使用流程,總體架構設計以下圖:

  • 目前小米cloud-ml平臺的任務調度和物理機管理基於多節點的分佈式Kubernetes集羣,對於OpenStack、Yarn和Mesos咱們也保留了實現接口,能夠經過實現Mesos後端讓用戶的任務調度到Mesos集羣進行訓練,最終返回給用戶一致的使用接口。
  • 目前Kubernetes最新穩定版是1.6,已經支持Nvidia GPU的調度和訪問,對於其餘廠商GPU暫不支持但基本能知足企業內部的需求,並且Pod、Deployment、Job、StatefulSet等功能日趨穩定,加上Docker、Prometheus、Harbor等生態項目的成熟,已經在大量生產環境驗證過,能夠知足通用PaaS或者Cloud Machine learning等定製服務平臺的需求。
  • 使用Kubernetes管理用戶的Docker容器,還解決了資源隔離的問題,保證不一樣深度學習訓練任務間的環境不會衝突,而且能夠針對訓練任務和模型服務使用Job和Deployment等不一樣的接口,充分利用分佈式容器編排系統的重調度和負載均衡功能。
  • 可是,Kubernetes並無完善的多租戶和Quota管理功能,難以與企業內部的權限管理系統對接,這要求咱們對Kubernetes API進行再一次「抽象」。咱們經過API Server實現了內部的AKSK簽名和認證受權機制,在處理用戶請求時加入多租戶和Quota配額功能,而且對外提供簡單易用的RESTful API,

雲深度學習平臺實現


     前面提到咱們後端使用Kubernetes編排系統,經過API Server實現受權認證和Quota配額功能。因爲雲深度學習服務是一個計算服務,和我之前作過的分佈式存儲服務有着本質的區別,計算服務離線運算時間較長,客戶端請求延時要求較低並且吞吐很小,所以咱們的API服務在易用性和高性能上能夠選擇前者,目前主流的Web服務器均可以知足需求。基於Web服務器咱們能夠實現集成內部權限管理系統的業務邏輯,小米生態雲提供了相似AWS的AKSK簽名認證機制,用戶註冊登陸後能夠自行建立Access key和Secret key,請求時在客戶端進行AKSK的簽名後發送,這樣用戶不須要把帳號密碼或密鑰加到請求中,即便密鑰泄露也能夠由用戶來禁用,請求時即便籤名被嗅探也只能重放當前的請求內容,是很是可靠的安全機制。除此以外,咱們參考OpenStack項目的體系架構,實現了多租戶和Quota功能,經過認證和受權的請求須要通過Quota配額檢查,在高可用數據庫中持久化相應的數據,這樣平臺管理員就能夠動態修改每一個租戶的Quota,並且用戶能夠隨時查看自身的審計信息。

  • 小米cloud-ml服務實現了深度學習模型的開發、訓練、調優、測試、部署和預測等完整功能,都是經過提交到後端的Kubernetes集羣來實現,
  • 完整的功能介紹能夠查看官方文檔 http://docs.api.xiaomi.com/cloud-ml
  • Kubernetes對外提供了RESTful API訪問接口,經過YAML或者JSON來描述不一樣的任務類型,不一樣編程語言實現的系統也可使用社區開發的SDK來訪問。
  • 對於咱們支持的多個深度學習框架,還有開發環境、訓練任務、模型服務等功能,都須要定製Docker鏡像,提交到Kubernetes時指定使用的容器鏡像、啓動命令等參數。
  • 經過對Kubernetes API的封裝,咱們能夠簡化Kubernetes的使用細節,保證了對Mesos、Yarn等後端支持的兼容性,同時避免了直接暴露Kubernetes API帶來的受權問題以及安全隱患。
  • 除了能夠啓動單個容器執行用戶的訓練代碼,小米cloud-ml平臺也支持TensorFlow的分佈式訓練,使用時只須要傳入ps和worker個數便可
  • 考慮到對TensorFlow原生API的兼容性,咱們並無定製修改TensorFlow代碼,用戶甚至能夠在本地安裝開源的TensorFlow測試後再提交,一樣能夠運行在雲平臺上。
  • 本地運行分佈式TensorFlow須要在多臺服務器上手動起進程,同時要避免進程使用的端口與其餘服務衝突,並且要考慮系統環境、內存不足、磁盤空間等問題,代碼更新和運維壓力成倍增長,
  • Cloud Machine Learning下的分佈式TensorFlow只須要在提交任務時多加兩個參數便可。有人以爲手動啓動分佈式TensorFlow很是繁瑣,在雲端實現邏輯是否更加複雜?其實並非,經過雲服務的控制節點,咱們在啓動任務前就能夠分配不會衝突的端口資源,啓動時經過容器隔離環境資源,而用戶不須要傳入Cluster spec等繁瑣的參數,

咱們遵循Google CloudML標準,會自動生成Cluster spec等信息經過環境變量加入到容器的啓動任務中。這樣不管是單機版訓練任務,仍是幾個節點的分佈式任務,甚至是上百節點的分佈式訓練任務,cloud-ml平臺均可以經過相同的鏡像和代碼來運行,只是啓動時傳入的環境變量不一樣,在不改變任何外部依賴的狀況下優雅地實現了看似複雜的分佈式訓練功能。

  

  • 小米的cloud-ml平臺和Google的CloudML服務,都有點相似以前很火的PaaS(Platform as a Service)或者CaaS(Container as a Service)服務。確實如此,基於Kubernetes或者Mesos咱們能夠很容易實現一個通用的CaaS,用戶上傳應用代碼和Docker鏡像,由平臺調度和運行,但不一樣的是Cloud Machine Learning簡化了與機器學習無關的功能。咱們不須要用戶瞭解PaaS的全部功能,也不須要支持全部編程語言的運行環境,暴露提交任務、查看任務、刪除任務等更簡單的使用接口便可,而要支持不一樣規模的TensorFlow應用代碼用戶須要以標準的Python打包方式上傳代碼
  • Python的標準打包方式獨立於TensorFlow或者小米cloud-ml平臺,幸運的是目前Google CloudML也支持Python的標準打包方式,經過這種標準接口,咱們甚至發現Google CloudML打包好的samples代碼甚至能夠直接提交到小米cloud-ml平臺上訓練。這是很是有意思的嘗試,意味着用戶可使用原生的TensorFlow接口來實現本身的模型,在本地計算資源不充足的狀況下能夠提交到Google CloudML服務上訓練,同時能夠一行代碼不用改直接提交到小米或者其餘雲服務廠商中的雲平臺上訓練。若是你們在實現內部的雲深度學習平臺,不妨也參考下標準的Python打包方式,這樣用戶同一份代碼就能夠兼容全部雲平臺,避免廠商綁定
  • 除了訓練任務,Cloud Machine Learning平臺最好也能集成模型服務、開發環境等功能。

  • 對於模型服務,TensorFlow社區開源了TensorFlow Serving項目,能夠加載任意TensorFlow模型而且提供統一的訪問接口

  • Caffe社區也提供了Web demo項目方便用戶使用。

  • 目前KubernetesMesos都實現了相似Deployment的功能,經過製做TensorFlow Serving等服務的容器鏡像,咱們能夠很方便地爲用戶快速啓動對應的模型服務。

  • 經過對Kubernetes API的封裝,咱們在暴露給用戶API時也提供了replicas等參數,這樣用戶就能夠直接經過Kubernetes API來建立多副本的Deployment實例,而且由Kubernetes來實現負載均衡等功能。

  • 除此以外,TensorFlow Serving自己還支持在線模型升級和同時加載多個模型版本等功能,咱們在保證TensorFlow Serving容器正常運行的狀況下,容許用戶更新分佈式對象存儲中的模型文件就能夠輕易地支持在線模型升級的功能。

   對於比較小衆但有特定使用場景的深度學習框架,Cloud Macine Learning的開發環境、訓練任務和模型服務都支持Bring Your Own Image功能,也就是說用戶能夠定製本身的Docker鏡像並在提交任務時指定使用。這種靈活的設置極大地下降了平臺管理者的維護成本,咱們不須要根據每一個用戶的需求定製通用的Golden image,事實上也不可能有完美的鏡像能夠知足全部需求,用戶不一樣的模型可能有任意的Python或者非Python依賴,甚至是本身實現的私有深度學習框架也能夠直接提交到Cloud Machine Learning平臺上訓練。內測BYOI功能時,咱們還驚喜地發現這個功能對於咱們開發新的深度學習框架支持,以及提早測試鏡像升級有很是大的幫助,同時用戶本身實現的Caffe模型服務和XGBoost模型服務也能夠完美支持。

   固然Cloud Machine Learning平臺還能夠實現不少有意思的功能,例如經過對線上不一樣GPU機型打label,經過NodeSelector功能能夠容許用戶選擇具體的GPU型號進行更細粒度的調度,這須要咱們暴露更底層Kubernetes API實現,這在集羣測試中也是很是有用的功能。而不管是基於GPU的訓練任務仍是模型服務,咱們都製做了對應的CUDA容器鏡像,經過Kubernetes調度到對應的GPU計算節點就能夠訪問本地圖像處理硬件進行高性能運算了。

   小米cloud-ml還開放了前置命令和後置命令功能,容許用戶在啓動訓練任務前和訓練任務結束後執行自定義命令,對於不支持分佈式存儲的深度學習框架,能夠在前置命令中掛載S3 fuse和FDS fuse到本地目錄,或者初始化HDFS的Kerberos帳號,靈活的接口能夠實現更多用戶自定義的功能。

   還有超參數自動調優功能,與Google CloudML相似,用戶能夠提交時指定多組超參數配置,雲平臺能夠自動分配資源起多實例並行計算,爲了支持讀取用戶自定義的指標數據,咱們實現了相似TensorBoard的Python接口直接訪問TensorFlow event file數據,並經過命令行返回給用戶最優的超參數組合。最後還有TensorFlow Application Template功能,在Cloud Machine Learning平臺上用戶能夠將本身的模型代碼公開或者使用官方維護的開源TensorFlow應用,用戶提交任務時能夠直接指定這些開源模板進行訓練,模板已經實現了MLP、CNN、RNN和LR等經典神經網絡結構,還能夠經過超參數來配置神經網絡每一層的節點數和層數,並且能夠支持任意稠密和稀疏的數據集,這樣不須要編寫代碼就能夠在雲平臺上訓練本身的數據快速生成AI模型了。

   在前面的平臺設計和平臺架構後,要實現完整的雲深度學習服務並不困難,尤爲是集成了Docker、Etcd、Kubernetes、TensorFlow等優秀開源項目,組件間經過API鬆耦合地交互,須要的重複工做主要是打通企業內部權限系統和將用戶請求轉化成Kubernetes等後端請求而已,而支持標準的打包方式還可讓業務代碼在任意雲平臺上無縫遷移。

雲深度學習平臺實踐


    目前小米雲深度學習平臺已經在內部各業務部門推廣使用,相比於直接使用物理機,雲服務擁有超高的資源利用率、快速的啓動時間、近乎「無限」的計算資源、自動的故障遷移、支持分佈式訓練和超參數自動調優等優勢,相信能夠獲得更好的推廣和應用。

    管理GPU資源和排查GPU調度問題也是至關繁瑣的,尤爲是須要管理不一樣GPU設備和不一樣CUDA版本的異構集羣,咱們統一規範了CUDA的安裝方式,保證Kubernetes調度的容器能夠正常訪問宿主機的GPU設備。固然對於GPU資源的調度和釋放,咱們有完善的測試文檔能夠保證每個GPU均可以正常使用,根據測試需求實現的NodeSelector功能也幫忙咱們更快地定位問題。

    因爲已經支持幾十個功能和十幾個深度學習框架,每次升級均可能影響已有服務的功能,所以咱們會在多節點的分佈式staging集羣進行上線演習和測試,而且實現smoke test腳本進行完整的功能性測試。服務升級須要更新代碼,可是爲了保證不影響線上業務,不管是Kubernetes仍是咱們實現的API Server都有多副本提供服務,經過高可用技術先遷移服務進行滾動升級,對於一些單機運行的腳本也經過Etcd實現了高可用的搶主機制,保證全部組件沒有單點故障。

相關文章
相關標籤/搜索