本文轉載自微信公衆號:半輕人
做者:王詠剛
王詠剛 AI科技大本營算法
AI 時代,咱們總說作科研的 AI 科學家、研究員、算法工程師離產業應用太遠,這其中的一個含義是說,搞機器學習算法的人,有時候會由於缺少架構(Infrastructure)方面的知識、能力而難以將一個好的算法落地。咱們招的算法工程師裏,也有同窗說,我發的頂會 paper 一級棒,或者我作 Kaggle 競賽一級棒,拿了很多第一名的,不懂架構就不懂唄,我作出一流算法,天然有其餘工程師幫我上線、運行、維護的。
鑑於此,我給創新工場暑期深度學習訓練營 DeeCamp (ps:這個訓練營太火了,只招生 36 名,總共有 1000 多計算機專業同窗報名,同窗們來自 CMU、北大、清華、交大等最好的大學)設計培訓課程時,就刻意把第一節課安排爲《AI 基礎架構:從大數據到深度學習》,後續纔給你們講《TensorFlow 實戰》、《天然語言處理》、《機器視覺》、《無人駕駛實戰》等框架和算法方向的課。
爲何我要說,AI 工程師都要懂一點架構呢?大概有四個緣由吧:
緣由一:算法實現 ≠ 問題解決
學生、研究員、科學家關心的大可能是學術和實驗性問題,但進入產業界,工程師關心的就是具體的業務問題。簡單來講,AI 工程師扮演的角色是一個問題的解決者,你的最重要任務是在實際環境中、有資源限制的條件下,用最有效的方法解決問題。只給出結果特別好的算法,是遠遠不夠的。
好比一些算法作得特別好,得過 ACM 獎項或者 Kaggle 前幾名的學生到了產業界,會驚奇地發現,原來本身的動手能力還差得這麼遠。作深度學習的,不會裝顯卡驅動,不會修復 CUDA 安裝錯誤;搞機器視覺的,沒能力對網上爬來的大規模訓練圖片、視頻作預處理或者格式轉換;精通天然語言處理的,不知道該怎麼把本身的語言模型集成在手機聊天 APP 裏供你們試用……
固然能夠說,作算法的專一作算法,其餘作架構、應用的幫算法工程師作封裝、發佈和維護工做。但這裏的問題不只僅是分工這麼簡單,若是算法工程師徹底不懂架構,其實,他根本上就很難在一個團隊裏協同工做,很難理解架構、應用層面對本身的算法所提出的需求。
緣由二:問題解決 ≠ 現場問題解決
有的算法工程師疏於考慮本身的算法在實際環境中的部署和維護問題,這個是很讓人頭疼的一件事。面向 C 端用戶的解決方案,部署的時候要考慮 serving 系統的架構,考慮本身算法所佔用的資源、運行的效率、如何升級等實際問題;面向 B 端用戶的解決方案要考慮的因素就更多,由於客戶的現場環境,哪怕是客戶的私有云環境,都會對你的解決方案有具體的接口、格式、操做系統、依賴關係等需求。
有人用 Python 3 作了算法,無法在客戶的 Python 2 的環境中作測試;有人的算法只支持特定格式的數據輸入,到了客戶現場,還得手忙腳亂地寫數據格式轉換器、適配器;有人作了支持實時更新、自動迭代的機器學習模型,放到客戶現場,卻發現實時接收 feature 的接口與邏輯,跟客戶內部的大數據流程根本不相容……
部署和維護工程師會負責這些麻煩事,但算法工程師若是徹底不懂得或不考慮這些邏輯,那隻會讓團隊內部合做愈來愈累。
緣由三:工程師須要最快、最好、最有可擴展性地解決問題
AI 工程師的首要目的是解決問題,而不是顯擺算法有多先進。不少狀況下,AI 工程師起碼要了解一個算法跑在實際環境中的時候,有哪些可能影響算法效率、可用性、可擴展性的因素。
好比作機器視覺的都應該瞭解,一個包含大量小圖片(好比每一個圖片 4KB,一共 1000 萬張圖片)的數據集,用傳統文件形式放在硬盤上是個怎樣的麻煩事,有哪些更高效的可替代存儲方案。作深度學習的有時候也必須瞭解 CPU 和 GPU 的鏈接關係,CPU/GPU 緩存和內存的調度方式,等等,不然多半會在系統性能上碰釘子。
擴展性是另外一個大問題,用 AI 算法解決一個具體問題是一回事,用 AI 算法實現一個可擴展的解決方案是另外一回事。要解決將來可能出現的一大類類似問題,或者把問題的邊界擴展到更大的數據量、更多的應用領域,這就要求 AI 工程師具有最基本的架構知識,在設計算法時,照顧到架構方面的需求了。
緣由四:架構知識,是工程師進行高效團隊協做的共同語言
AI 工程師的確能夠在工做時專一於算法,但不能不懂點兒架構,不然,你跟其餘工程師該如何協同工做呢?
別人在 Hadoop 裏搭好了 MapReduce 流程,你在其中用 AI 算法解決了一個具體步驟的數據處理問題(好比作了一次 entity 抽取),這時其餘工程師裏讓你在算法內部輸出一個他們須要監控的 counter——不懂 MapReduce 的話,你總得先去翻查、理解什麼是 counter 吧。這個例子是芝麻大點兒的小事,但小麻煩是會日積月累,慢慢成爲團隊協做的障礙的。往大一點兒說,系統內部到底該用 protocol buffers 仍是該用 JSON 來交換數據,到底該用 RPC 仍是該用 message queue 來通訊,這些決定,AI 工程師真的都逆來順受、不發表意見了?
Google 的逆天架構能力是 Google AI 科技強大的重要緣由
這個不用多解釋,你們都知道。幾個現成的例子:
(1)在前 AI 時代,作出 MapReduce 等大神級架構的 Jeff Dean(其實嚴格說,應該是以 Jeff Dean 爲表明的 Google 基礎架構團隊),也是如今 AI 時代裏的大神級架構 TensorFlow 的開發者。
(2)在 Google 作無人駕駛這類前沿 AI 研發,工程師的幸福感要比其餘廠的工程師高至少一個數量級。好比作無人駕駛的團隊,輕易就能夠用已有的大數據架構,管理超海量的 raw data,也能夠很簡單的在現有架構上用幾千臺、上萬臺機器快速完成一個代碼更新在全部已收集的路況數據上的迴歸測試。離開這些基礎架構的支持,Google 這幾年向 AI 的全面轉型哪會有這麼快。
課
件分享:AI 基礎架構——從大數據到深度學習
下面是我給創新工場暑期深度學習訓練營 DeeCamp 講的時長兩小時的內部培訓課程《AI 基礎架構:從大數據到深度學習》的所有課件。所有講解內容過於細緻、冗長,這裏就不分享了。對每頁課件,我在下面只作一個簡單的文字歸納。
注:如下這個課件的講解思路主要是用 Google 的架構發展經驗,對大數據到機器學習再到近年來的深度學習相關的典型系統架構,作一個原理和發展方向上的梳理。由於時間關係,這個課件和講解比較偏重 offline 的大數據和機器學習流程,對 online serving 的架構討論較少——這固然不表明 online serving 不重要,只是必須有所取捨而已。
![](http://static.javashuo.com/static/loading.gif)
這個 slides 是最近三四年的時間裏,逐漸更新、逐漸補充造成的。最先是英文講的,因此後續補充的內容就都是英文的(英文水平有限,錯漏不免)。
![](http://static.javashuo.com/static/loading.gif)
如何認識 AI 基礎架構的問題,直到如今,仍是一個見仁見智的領域。這裏提的,主要是我的的理解和經驗,不表明任何學術流派或主流觀點。
![](http://static.javashuo.com/static/loading.gif)
上面這個圖,不是說全部 AI 系統/應用都有這樣的 full stack,而是說,當咱們考慮 AI 基礎架構的時候,咱們應該考慮哪些因素。並且,更重要的一點,上面這個架構圖,是把大數據架構,和機器學習架構結合在一塊兒來討論的。
架構圖的上層,比較強調雲服務的架構,這個主要是由於,目前的 AI 應用有很大一部分是面向 B 端用戶的,這裏涉及到私有云的部署、企業雲的部署等雲計算相關方案。
![](http://static.javashuo.com/static/loading.gif)
上面這個圖把機器學習和深度學習並列,這在概念上不太好,由於深度學習是機器學習的一部分,但從實踐上講,又只好這樣,由於深度學習已經枝繁葉茂,不得不單提出來介紹了。
![](http://static.javashuo.com/static/loading.gif)
先從虛擬化講起,這個是大數據、AI 甚至全部架構的基礎(固然不是說全部應用都須要虛擬化,而是說虛擬化目前已經太廣泛了)。
![](http://static.javashuo.com/static/loading.gif)
這個是 Docker 本身畫的 VM vs. Container 的圖。我跟 DeeCamp 學員講這一頁的時候,是先從 Linux 的 chroot 命令開始講起的,而後纔講到輕量級的 container 和重量級的 VM,講到應用隔離、接口隔離、系統隔離、資源隔離等概念。
![](http://static.javashuo.com/static/loading.gif)
給 DeeCamp 學員展現了一下 docker(嚴格說是 nvidia-docker)在管理 GPU 資源上的靈活度,在搭建、運行和維護 TensorFlow 環境時爲何比裸的系統方便。
![](http://static.javashuo.com/static/loading.gif)
嚴格說,Kubernetes 如今的應用遠沒有 Docker 那麼普及,但不少作機器學習、深度學習的公司,包括創業公司,都比較須要相似的 container-management system,須要自動化的集羣管理、任務管理和資源調度。Kubernetes 的設計理念其實表明了 Google 在容器管理、集羣管理、任務管理方面的總體思路,特別推薦這個講背景的文章:http://queue.acm.org/detail.cfm?id=2898444
![](http://static.javashuo.com/static/loading.gif)
講大數據架構,我基本上會從 Google 的三架馬車(MapReduce、GFS、Bigtable)講起,儘管這三架馬車如今看來都是「老」技術了,但理解這三架馬車背後的設計理念,是更好理解全部「現代」架構的一個基礎。
![](http://static.javashuo.com/static/loading.gif)
講 MapReduce 理念特別經常使用的一個例子,論文引用計數(正向計數和反向計數)問題。
![](http://static.javashuo.com/static/loading.gif)
統計一篇論文有多少參考文獻,這個超級簡單的計算問題在分佈式環境中帶來兩個思考:(1)能夠在不用考慮結果一致性的狀況下作簡單的分佈式處理;(2)能夠很是快地用增量方式處理數據。
![](http://static.javashuo.com/static/loading.gif)
可是,當咱們統計一篇文獻被多少篇論文引用的時候,這個事情就不那麼簡單了。這主要帶來了一個分佈式任務中常見的數據訪問一致性問題(咱們說的固然不是單線程環境如何解決這個問題啦)。
![](http://static.javashuo.com/static/loading.gif)
好久之前咱們是用關係型數據庫來解決數據訪問一致性的問題的,關係型數據庫提供的 Transaction 機制在分佈式環境中,能夠很方便地知足 ACID(Atomicity, Consistency, Isolation, Durability) 的要求。可是,關係型數據庫明顯不適合解決大規模數據的分佈式計算問題。
![](http://static.javashuo.com/static/loading.gif)
Google 的 MapReduce 解決這個問題的思路很是巧妙,是計算機架構設計歷史上絕對的經典案例:MapReduce 把一個可能帶來 ACID 困擾的事務計算問題,拆解成 Map 和 Reduce 兩個計算階段,每一個單獨的計算階段,都特別適合作分佈式處理,並且特別適合作大規模的分佈式處理。
![](http://static.javashuo.com/static/loading.gif)
MapReduce 解決引用計數問題的基本框架。
![](http://static.javashuo.com/static/loading.gif)
MapReduce 在完美解決分佈式計算的同時,其實也帶來了一個不大不小的反作用:MapReduce 最適合對數據進行批量處理,而不是那麼適合對數據進行增量處理。好比早期 Google 在維護網頁索引這件事上,就必須批量處理網頁數據,這必然形成一次批量處理的耗時較長。Google 早期的解決方案是把網頁按更新頻度分紅不一樣的庫,每一個庫使用不一樣的批量處理週期。
![](http://static.javashuo.com/static/loading.gif)
用 MapReduce 帶來的另外一個問題是,常見的系統性問題,每每是由一大堆 MapReduce 操做連接而成的,這種連接關係每每造成了複雜的工做流,整個工做流的運行週期長,管理維護成本高,關鍵路徑上的一個任務失敗就有可能要求整個工做流從新啓動。不過這也是 Google 內部大數據處理的典型流程、常見場景。
![](http://static.javashuo.com/static/loading.gif)
Flume 是簡化 MapReduce 複雜流程開發、管理和維護的一個好東東。
![](http://static.javashuo.com/static/loading.gif)
Apache 有開源版本的 Flume 實現。Flume 把複雜的 Mapper、Reducer 等底層操做,抽象成上層的、比較純粹的數據模型的操做。PCollection、PTable 這種抽象層,還有基於這些抽象層的相關操做,是大數據處理流程進化道路上的重要一步(在這個角度上,Flume 的思想與 TensorFlow 對於 tensor 以及 tensor 數據流的封裝,有殊途同歸的地方)。
![](http://static.javashuo.com/static/loading.gif)
Flume 更重要的功能是能夠對 MapReduce 工做流程進行運行時的優化。
![](http://static.javashuo.com/static/loading.gif)
更多關於 Flume 運行時優化的解釋圖。
![](http://static.javashuo.com/static/loading.gif)
Flume 並無改變 MapReduce 最適合於批處理任務的本質。那麼,有沒有適合大規模數據增量(甚至實時)處理的基礎架構呢?
![](http://static.javashuo.com/static/loading.gif)
談到大規模數據增量(甚至實時)處理,咱們談的實際上是一個兼具關係型數據庫的 transaction 機制,以及 MapReduce 的可擴展性的東西。這樣的東西有不一樣的設計思路,其中一種架構設計思路叫 notification/monitor 模式。
![](http://static.javashuo.com/static/loading.gif)
Google percolator 的論文給出了 notification/monitor 模式的一種實現方案。這個方案基於Bigtable,實際上就是在 Bigtable 超靠譜的可擴展性的基礎上,增長了一種很是巧妙實現的跨記錄的 transaction 機制。
![](http://static.javashuo.com/static/loading.gif)
percolator 支持相似關係型數據庫的 transaction,能夠保證同時發生的分佈式任務在數據訪問和結果產出時的一致性。
![](http://static.javashuo.com/static/loading.gif)
percolator 實現 transaction 的方法:(1)使用 timestamp 隔離不一樣時間點的操做;(2)使用 write、lock 列實現 transaction 中的鎖功能。詳細的介紹能夠參考 percolator 的 paper。
![](http://static.javashuo.com/static/loading.gif)
Google 的網頁索引流程、Google Knowledge Graph 的建立與更新流程,都已經完成了增量化處理的改造,與之前的批處理系統相比,能夠達到很是快(甚至近乎實時)的更新速度。——這個事情發生在幾年之前,目前 Google 還在持續對這樣的大數據流程進行改造,各類新的大數據處理技術還在不停出現。
![](http://static.javashuo.com/static/loading.gif)
大數據流程創建了以後,很天然地就會出現機器學習的需求,須要適應機器學習的系統架構。
![](http://static.javashuo.com/static/loading.gif)
MapReduce 這種適合批處理流程的系統,一般並不適合於許多複雜的機器學習任務,好比用 MapReduce 來作圖的算法,特別是須要屢次迭代的算法,就特別耗時、費力。
![](http://static.javashuo.com/static/loading.gif)
Spark 以及 Spark MLlib 給機器學習提供了更好用的支持框架。Spark 的優點在於支持對 RDD 的高效、屢次訪問,這幾乎是給那些須要屢次迭代的機器學習算法量身定作的。
![](http://static.javashuo.com/static/loading.gif)
Spark 的集羣架構,和 YARN 的集成等。
![](http://static.javashuo.com/static/loading.gif)
Google Pregel 的 paper 給出了一種高效完成圖計算的思路。
![](http://static.javashuo.com/static/loading.gif)
Spark GraphX 也是圖計算的好用架構。
![](http://static.javashuo.com/static/loading.gif)
深度學習的分佈式架構,實際上是與大數據的分佈式架構一脈相承的。——其實在 Google,Jeff Dean 和他的架構團隊,在設計 TensorFlow 的架構時,就在大量使用以往在 MapReduce、Bigtable、Flume 等的實現中積累的經驗。
![](http://static.javashuo.com/static/loading.gif)
TensorFlow 經典論文中對 TensorFlow 架構的講解。
![](http://static.javashuo.com/static/loading.gif)
TensorFlow 中的同步訓練和異步訓練。
![](http://static.javashuo.com/static/loading.gif)
TensorFlow 中的不一樣的並行策略。
![](http://static.javashuo.com/static/loading.gif)
可視化是個與架構有點兒關係,但更像一個 feature 的領域。對機器學習特別是深度學習算法的可視化,將來會變得愈來愈重要。
![](http://static.javashuo.com/static/loading.gif)
這個對決策樹算法進行可視化的網站,很是好玩。
![](http://static.javashuo.com/static/loading.gif)
TensorFlow 本身提供的可視化工具,也很是有意思(固然,上圖應用屬於玩具性質,不是真正意義上,將用戶本身的模型可視化的工具)。
![](http://static.javashuo.com/static/loading.gif)
有關架構的幾篇極其經典的 paper 在這裏了。