AI 時(shí)代,我們總說做科研的 AI 科學(xué)家、研究員、算法工程師離產(chǎn)業(yè)應(yīng)用太遠(yuǎn),這其中的一個(gè)含義是說,搞機(jī)器學(xué)習(xí)算法的人,有時(shí)候會(huì)因?yàn)槿狈軜?gòu)(Infrastructure)方面的知識、能力而難以將一個(gè)好的算法落地。我們招的算法工程師里,也有同學(xué)說,我發(fā)的頂會(huì) paper 一級棒,或者我做 Kaggle 競賽一級棒,拿了不少第一名的,不懂架構(gòu)就不懂唄,我做出一流算法,自然有其他工程師幫我上線、運(yùn)行、維護(hù)的。
鑒于此,我給創(chuàng)新工場暑期深度學(xué)習(xí)訓(xùn)練營 DeeCamp (ps:這個(gè)訓(xùn)練營太火了,只招生 36 名,總共有 1000 多計(jì)算機(jī)專業(yè)同學(xué)報(bào)名,同學(xué)們來自 CMU、北大、清華、交大等最好的大學(xué))設(shè)計(jì)培訓(xùn)課程時(shí),就刻意把第一節(jié)課安排為《AI 基礎(chǔ)架構(gòu):從大數(shù)據(jù)到深度學(xué)習(xí)》,后續(xù)才給大家講《TensorFlow 實(shí)戰(zhàn)》、《自然語言處理》、《機(jī)器視覺》、《無人駕駛實(shí)戰(zhàn)》等框架和算法方向的課。
為什么我要說,AI 工程師都要懂一點(diǎn)架構(gòu)呢?大概有四個(gè)原因吧:
▌原因一:算法實(shí)現(xiàn) ≠ 問題解決
學(xué)生、研究員、科學(xué)家關(guān)心的大多是學(xué)術(shù)和實(shí)驗(yàn)性問題,但進(jìn)入產(chǎn)業(yè)界,工程師關(guān)心的就是具體的業(yè)務(wù)問題。簡單來說,AI 工程師扮演的角色是一個(gè)問題的解決者,你的最重要任務(wù)是在實(shí)際環(huán)境中、有資源限制的條件下,用最有效的方法解決問題。只給出結(jié)果特別好的算法,是遠(yuǎn)遠(yuǎn)不夠的。
比如一些算法做得特別好,得過 ACM 獎(jiǎng)項(xiàng)或者 Kaggle 前幾名的學(xué)生到了產(chǎn)業(yè)界,會(huì)驚奇地發(fā)現(xiàn),原來自己的動(dòng)手能力還差得這么遠(yuǎn)。做深度學(xué)習(xí)的,不會(huì)裝顯卡驅(qū)動(dòng),不會(huì)修復(fù) CUDA 安裝錯(cuò)誤;搞機(jī)器視覺的,沒能力對網(wǎng)上爬來的大規(guī)模訓(xùn)練圖片、視頻做預(yù)處理或者格式轉(zhuǎn)換;精通自然語言處理的,不知道該怎么把自己的語言模型集成在手機(jī)聊天 APP 里供大家試用……
當(dāng)然可以說,做算法的專注做算法,其他做架構(gòu)、應(yīng)用的幫算法工程師做封裝、發(fā)布和維護(hù)工作。但這里的問題不僅僅是分工這么簡單,如果算法工程師完全不懂架構(gòu),其實(shí),他根本上就很難在一個(gè)團(tuán)隊(duì)里協(xié)同工作,很難理解架構(gòu)、應(yīng)用層面對自己的算法所提出的需求。
▌原因二:問題解決 ≠ 現(xiàn)場問題解決
有的算法工程師疏于考慮自己的算法在實(shí)際環(huán)境中的部署和維護(hù)問題,這個(gè)是很讓人頭疼的一件事。面向 C 端用戶的解決方案,部署的時(shí)候要考慮 serving 系統(tǒng)的架構(gòu),考慮自己算法所占用的資源、運(yùn)行的效率、如何升級等實(shí)際問題;面向 B 端用戶的解決方案要考慮的因素就更多,因?yàn)榭蛻舻默F(xiàn)場環(huán)境,哪怕是客戶的私有云環(huán)境,都會(huì)對你的解決方案有具體的接口、格式、操作系統(tǒng)、依賴關(guān)系等需求。
有人用 Python 3 做了算法,沒法在客戶的 Python 2 的環(huán)境中做測試;有人的算法只支持特定格式的數(shù)據(jù)輸入,到了客戶現(xiàn)場,還得手忙腳亂地寫數(shù)據(jù)格式轉(zhuǎn)換器、適配器;有人做了支持實(shí)時(shí)更新、自動(dòng)迭代的機(jī)器學(xué)習(xí)模型,放到客戶現(xiàn)場,卻發(fā)現(xiàn)實(shí)時(shí)接收 feature 的接口與邏輯,跟客戶內(nèi)部的大數(shù)據(jù)流程根本不相容……
部署和維護(hù)工程師會(huì)負(fù)責(zé)這些麻煩事,但算法工程師如果完全不懂得或不考慮這些邏輯,那只會(huì)讓團(tuán)隊(duì)內(nèi)部合作越來越累。
▌原因三:工程師需要最快、最好、最有可擴(kuò)展性地解決問題
AI 工程師的首要目的是解決問題,而不是顯擺算法有多先進(jìn)。很多情況下,AI 工程師起碼要了解一個(gè)算法跑在實(shí)際環(huán)境中的時(shí)候,有哪些可能影響算法效率、可用性、可擴(kuò)展性的因素。
比如做機(jī)器視覺的都應(yīng)該了解,一個(gè)包含大量小圖片(比如每個(gè)圖片 4KB,一共 1000 萬張圖片)的數(shù)據(jù)集,用傳統(tǒng)文件形式放在硬盤上是個(gè)怎樣的麻煩事,有哪些更高效的可替代存儲方案。做深度學(xué)習(xí)的有時(shí)候也必須了解 CPU 和 GPU 的連接關(guān)系,CPU/GPU 緩存和內(nèi)存的調(diào)度方式,等等,否則多半會(huì)在系統(tǒng)性能上碰釘子。
擴(kuò)展性是另一個(gè)大問題,用 AI 算法解決一個(gè)具體問題是一回事,用 AI 算法實(shí)現(xiàn)一個(gè)可擴(kuò)展的解決方案是另一回事。要解決未來可能出現(xiàn)的一大類相似問題,或者把問題的邊界擴(kuò)展到更大的數(shù)據(jù)量、更多的應(yīng)用領(lǐng)域,這就要求 AI 工程師具備最基本的架構(gòu)知識,在設(shè)計(jì)算法時(shí),照顧到架構(gòu)方面的需求了。
▌原因四:架構(gòu)知識,是工程師進(jìn)行高效團(tuán)隊(duì)協(xié)作的共同語言
AI 工程師的確可以在工作時(shí)專注于算法,但不能不懂點(diǎn)兒架構(gòu),否則,你跟其他工程師該如何協(xié)同工作呢?
別人在 Hadoop 里搭好了 MapReduce 流程,你在其中用 AI 算法解決了一個(gè)具體步驟的數(shù)據(jù)處理問題(比如做了一次 entity 抽?。@時(shí)其他工程師里讓你在算法內(nèi)部輸出一個(gè)他們需要監(jiān)控的 counter——不懂 MapReduce 的話,你總得先去翻查、理解什么是 counter 吧。這個(gè)例子是芝麻大點(diǎn)兒的小事,但小麻煩是會(huì)日積月累,慢慢成為團(tuán)隊(duì)協(xié)作的障礙的。往大一點(diǎn)兒說,系統(tǒng)內(nèi)部到底該用 protocol buffers 還是該用 JSON 來交換數(shù)據(jù),到底該用 RPC 還是該用 message queue 來通信,這些決定,AI 工程師真的都逆來順受、不發(fā)表意見了?
▌Google 的逆天架構(gòu)能力是 Google AI 科技強(qiáng)大的重要原因
這個(gè)不用多解釋,大家都知道。幾個(gè)現(xiàn)成的例子:
(1)在前 AI 時(shí)代,做出 MapReduce 等大神級架構(gòu)的 Jeff Dean(其實(shí)嚴(yán)格說,應(yīng)該是以 Jeff Dean 為代表的 Google 基礎(chǔ)架構(gòu)團(tuán)隊(duì)),也是現(xiàn)在 AI 時(shí)代里的大神級架構(gòu) TensorFlow 的開發(fā)者。
(2)在 Google 做無人駕駛這類前沿 AI 研發(fā),工程師的幸福感要比其他廠的工程師高至少一個(gè)數(shù)量級。比如做無人駕駛的團(tuán)隊(duì),輕易就可以用已有的大數(shù)據(jù)架構(gòu),管理超海量的 raw data,也可以很簡單的在現(xiàn)有架構(gòu)上用幾千臺、上萬臺機(jī)器快速完成一個(gè)代碼更新在所有已收集的路況數(shù)據(jù)上的回歸測試。離開這些基礎(chǔ)架構(gòu)的支持,Google 這幾年向 AI 的全面轉(zhuǎn)型哪會(huì)有這么快。
▌?wù)n件分享:AI 基礎(chǔ)架構(gòu)——從大數(shù)據(jù)到深度學(xué)習(xí)
下面是我給創(chuàng)新工場暑期深度學(xué)習(xí)訓(xùn)練營 DeeCamp 講的時(shí)長兩小時(shí)的內(nèi)部培訓(xùn)課程《AI 基礎(chǔ)架構(gòu):從大數(shù)據(jù)到深度學(xué)習(xí)》的全部課件。全部講解內(nèi)容過于細(xì)致、冗長,這里就不分享了。對每頁課件,我在下面只做一個(gè)簡單的文字概括。
注:以下這個(gè)課件的講解思路主要是用 Google 的架構(gòu)發(fā)展經(jīng)驗(yàn),對大數(shù)據(jù)到機(jī)器學(xué)習(xí)再到近年來的深度學(xué)習(xí)相關(guān)的典型系統(tǒng)架構(gòu),做一個(gè)原理和發(fā)展方向上的梳理。因?yàn)闀r(shí)間關(guān)系,這個(gè)課件和講解比較偏重 offline 的大數(shù)據(jù)和機(jī)器學(xué)習(xí)流程,對 online serving 的架構(gòu)討論較少——這當(dāng)然不代表 online serving 不重要,只是必須有所取舍而已。
這個(gè) slides 是最近三四年的時(shí)間里,逐漸更新、逐漸補(bǔ)充形成的。最早是英文講的,所以后續(xù)補(bǔ)充的內(nèi)容就都是英文的(英文水平有限,錯(cuò)漏難免)。
如何認(rèn)識 AI 基礎(chǔ)架構(gòu)的問題,直到現(xiàn)在,還是一個(gè)見仁見智的領(lǐng)域。這里提的,主要是個(gè)人的理解和經(jīng)驗(yàn),不代表任何學(xué)術(shù)流派或主流觀點(diǎn)。
上面這個(gè)圖,不是說所有 AI 系統(tǒng)/應(yīng)用都有這樣的 full stack,而是說,當(dāng)我們考慮 AI 基礎(chǔ)架構(gòu)的時(shí)候,我們應(yīng)該考慮哪些因素。而且,更重要的一點(diǎn),上面這個(gè)架構(gòu)圖,是把大數(shù)據(jù)架構(gòu),和機(jī)器學(xué)習(xí)架構(gòu)結(jié)合在一起來討論的。
架構(gòu)圖的上層,比較強(qiáng)調(diào)云服務(wù)的架構(gòu),這個(gè)主要是因?yàn)?,目前?AI 應(yīng)用有很大一部分是面向 B 端用戶的,這里涉及到私有云的部署、企業(yè)云的部署等云計(jì)算相關(guān)方案。
上面這個(gè)圖把機(jī)器學(xué)習(xí)和深度學(xué)習(xí)并列,這在概念上不太好,因?yàn)樯疃葘W(xué)習(xí)是機(jī)器學(xué)習(xí)的一部分,但從實(shí)踐上講,又只好這樣,因?yàn)樯疃葘W(xué)習(xí)已經(jīng)枝繁葉茂,不得不單提出來介紹了。
先從虛擬化講起,這個(gè)是大數(shù)據(jù)、AI 甚至所有架構(gòu)的基礎(chǔ)(當(dāng)然不是說所有應(yīng)用都需要虛擬化,而是說虛擬化目前已經(jīng)太普遍了)。
這個(gè)是 Docker 自己畫的 VM vs. Container 的圖。我跟 DeeCamp 學(xué)員講這一頁的時(shí)候,是先從 Linux 的 chroot 命令開始講起的,然后才講到輕量級的 container 和重量級的 VM,講到應(yīng)用隔離、接口隔離、系統(tǒng)隔離、資源隔離等概念。
給 DeeCamp 學(xué)員展示了一下 docker(嚴(yán)格說是 nvidia-docker)在管理 GPU 資源上的靈活度,在搭建、運(yùn)行和維護(hù) TensorFlow 環(huán)境時(shí)為什么比裸的系統(tǒng)方便。
嚴(yán)格說,Kubernetes 現(xiàn)在的應(yīng)用遠(yuǎn)沒有 Docker 那么普及,但很多做機(jī)器學(xué)習(xí)、深度學(xué)習(xí)的公司,包括創(chuàng)業(yè)公司,都比較需要類似的 container-management system,需要自動(dòng)化的集群管理、任務(wù)管理和資源調(diào)度。
講大數(shù)據(jù)架構(gòu),我基本上會(huì)從 Google 的三架馬車(MapReduce、GFS、Bigtable)講起,盡管這三架馬車現(xiàn)在看來都是“老”技術(shù)了,但理解這三架馬車背后的設(shè)計(jì)理念,是更好理解所有“現(xiàn)代”架構(gòu)的一個(gè)基礎(chǔ)。
講 MapReduce 理念特別常用的一個(gè)例子,論文引用計(jì)數(shù)(正向計(jì)數(shù)和反向計(jì)數(shù))問題。
統(tǒng)計(jì)一篇論文有多少參考文獻(xiàn),這個(gè)超級簡單的計(jì)算問題在分布式環(huán)境中帶來兩個(gè)思考:(1)可以在不用考慮結(jié)果一致性的情況下做簡單的分布式處理;(2)可以非??斓赜迷隽糠绞教幚頂?shù)據(jù)。
但是,當(dāng)我們統(tǒng)計(jì)一篇文獻(xiàn)被多少篇論文引用的時(shí)候,這個(gè)事情就不那么簡單了。這主要帶來了一個(gè)分布式任務(wù)中常見的數(shù)據(jù)訪問一致性問題(我們說的當(dāng)然不是單線程環(huán)境如何解決這個(gè)問題啦)。
很久以前我們是用關(guān)系型數(shù)據(jù)庫來解決數(shù)據(jù)訪問一致性的問題的,關(guān)系型數(shù)據(jù)庫提供的 Transaction 機(jī)制在分布式環(huán)境中,可以很方便地滿足 ACID(Atomicity, Consistency, Isolation, Durability) 的要求。但是,關(guān)系型數(shù)據(jù)庫明顯不適合解決大規(guī)模數(shù)據(jù)的分布式計(jì)算問題。
Google 的 MapReduce 解決這個(gè)問題的思路非常巧妙,是計(jì)算機(jī)架構(gòu)設(shè)計(jì)歷史上絕對的經(jīng)典案例:MapReduce 把一個(gè)可能帶來 ACID 困擾的事務(wù)計(jì)算問題,拆解成 Map 和 Reduce 兩個(gè)計(jì)算階段,每個(gè)單獨(dú)的計(jì)算階段,都特別適合做分布式處理,而且特別適合做大規(guī)模的分布式處理。
MapReduce 解決引用計(jì)數(shù)問題的基本框架。
MapReduce 在完美解決分布式計(jì)算的同時(shí),其實(shí)也帶來了一個(gè)不大不小的副作用:MapReduce 最適合對數(shù)據(jù)進(jìn)行批量處理,而不是那么適合對數(shù)據(jù)進(jìn)行增量處理。比如早期 Google 在維護(hù)網(wǎng)頁索引這件事上,就必須批量處理網(wǎng)頁數(shù)據(jù),這必然造成一次批量處理的耗時(shí)較長。Google 早期的解決方案是把網(wǎng)頁按更新頻度分成不同的庫,每個(gè)庫使用不同的批量處理周期。
用 MapReduce 帶來的另一個(gè)問題是,常見的系統(tǒng)性問題,往往是由一大堆 MapReduce 操作鏈接而成的,這種鏈接關(guān)系往往形成了復(fù)雜的工作流,整個(gè)工作流的運(yùn)行周期長,管理維護(hù)成本高,關(guān)鍵路徑上的一個(gè)任務(wù)失敗就有可能要求整個(gè)工作流重新啟動(dòng)。不過這也是 Google 內(nèi)部大數(shù)據(jù)處理的典型流程、常見場景。
Flume 是簡化 MapReduce 復(fù)雜流程開發(fā)、管理和維護(hù)的一個(gè)好東東。
Apache 有開源版本的 Flume 實(shí)現(xiàn)。Flume 把復(fù)雜的 Mapper、Reducer 等底層操作,抽象成上層的、比較純粹的數(shù)據(jù)模型的操作。PCollection、PTable 這種抽象層,還有基于這些抽象層的相關(guān)操作,是大數(shù)據(jù)處理流程進(jìn)化道路上的重要一步(在這個(gè)角度上,F(xiàn)lume 的思想與 TensorFlow 對于 tensor 以及 tensor 數(shù)據(jù)流的封裝,有異曲同工的地方)。
Flume 更重要的功能是可以對 MapReduce 工作流程進(jìn)行運(yùn)行時(shí)的優(yōu)化。
更多關(guān)于 Flume 運(yùn)行時(shí)優(yōu)化的解釋圖。
Flume 并沒有改變 MapReduce 最適合于批處理任務(wù)的本質(zhì)。那么,有沒有適合大規(guī)模數(shù)據(jù)增量(甚至實(shí)時(shí))處理的基礎(chǔ)架構(gòu)呢?
談到大規(guī)模數(shù)據(jù)增量(甚至實(shí)時(shí))處理,我們談的其實(shí)是一個(gè)兼具關(guān)系型數(shù)據(jù)庫的 transaction 機(jī)制,以及 MapReduce 的可擴(kuò)展性的東西。這樣的東西有不同的設(shè)計(jì)思路,其中一種架構(gòu)設(shè)計(jì)思路叫 notification/monitor 模式。
Google percolator 的論文給出了 notification/monitor 模式的一種實(shí)現(xiàn)方案。這個(gè)方案基于Bigtable,實(shí)際上就是在 Bigtable 超靠譜的可擴(kuò)展性的基礎(chǔ)上,增加了一種非常巧妙實(shí)現(xiàn)的跨記錄的 transaction 機(jī)制。
percolator 支持類似關(guān)系型數(shù)據(jù)庫的 transaction,可以保證同時(shí)發(fā)生的分布式任務(wù)在數(shù)據(jù)訪問和結(jié)果產(chǎn)出時(shí)的一致性。
percolator 實(shí)現(xiàn) transaction 的方法:(1)使用 timestamp 隔離不同時(shí)間點(diǎn)的操作;(2)使用 write、lock 列實(shí)現(xiàn) transaction 中的鎖功能。詳細(xì)的介紹可以參考 percolator 的 paper。
Google 的網(wǎng)頁索引流程、Google Knowledge Graph 的創(chuàng)建與更新流程,都已經(jīng)完成了增量化處理的改造,與以前的批處理系統(tǒng)相比,可以達(dá)到非??欤ㄉ踔两鯇?shí)時(shí))的更新速度。——這個(gè)事情發(fā)生在幾年以前,目前 Google 還在持續(xù)對這樣的大數(shù)據(jù)流程進(jìn)行改造,各種新的大數(shù)據(jù)處理技術(shù)還在不停出現(xiàn)。
大數(shù)據(jù)流程建立了之后,很自然地就會(huì)出現(xiàn)機(jī)器學(xué)習(xí)的需求,需要適應(yīng)機(jī)器學(xué)習(xí)的系統(tǒng)架構(gòu)。
MapReduce 這種適合批處理流程的系統(tǒng),通常并不適合于許多復(fù)雜的機(jī)器學(xué)習(xí)任務(wù),比如用 MapReduce 來做圖的算法,特別是需要多次迭代的算法,就特別耗時(shí)、費(fèi)力。
Spark 以及 Spark MLlib 給機(jī)器學(xué)習(xí)提供了更好用的支持框架。Spark 的優(yōu)勢在于支持對 RDD 的高效、多次訪問,這幾乎是給那些需要多次迭代的機(jī)器學(xué)習(xí)算法量身定做的。
Spark 的集群架構(gòu),和 YARN 的集成等。
Google Pregel 的 paper 給出了一種高效完成圖計(jì)算的思路。
Spark GraphX 也是圖計(jì)算的好用架構(gòu)。
深度學(xué)習(xí)的分布式架構(gòu),其實(shí)是與大數(shù)據(jù)的分布式架構(gòu)一脈相承的?!鋵?shí)在 Google,Jeff Dean 和他的架構(gòu)團(tuán)隊(duì),在設(shè)計(jì) TensorFlow 的架構(gòu)時(shí),就在大量使用以往在 MapReduce、Bigtable、Flume 等的實(shí)現(xiàn)中積累的經(jīng)驗(yàn)。
TensorFlow 經(jīng)典論文中對 TensorFlow 架構(gòu)的講解。
TensorFlow 中的同步訓(xùn)練和異步訓(xùn)練。
TensorFlow 中的不同的并行策略。
可視化是個(gè)與架構(gòu)有點(diǎn)兒關(guān)系,但更像一個(gè) feature 的領(lǐng)域。對機(jī)器學(xué)習(xí)特別是深度學(xué)習(xí)算法的可視化,未來會(huì)變得越來越重要。
這個(gè)對決策樹算法進(jìn)行可視化的網(wǎng)站,非常好玩。
TensorFlow 自己提供的可視化工具,也非常有意思(當(dāng)然,上圖應(yīng)用屬于玩具性質(zhì),不是真正意義上,將用戶自己的模型可視化的工具)。
-
架構(gòu)
+關(guān)注
關(guān)注
1文章
506瀏覽量
25430
原文標(biāo)題:為什么 AI 工程師要懂一點(diǎn)架構(gòu)?
文章出處:【微信號:AItists,微信公眾號:人工智能學(xué)家】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論