本文由 「AI前線」原創,原文連結:開發易、通用難,深度學習框架何時才能飛入尋常百姓家?
作者|老師木
編輯|Emily
AI 前線導讀:”深度學習框架正在快速演化,各大公司都推出了自己的框架,TensorFlow, PyTorch, Caffe2, MXNet, PaddlePaddle,大大推動了深度學習的發展,同時也讓使用者有目不暇接無所適從之感。我們認為,深度學習框架使用者有必要去了解深度學習框架的一些基本原理,這有助於我們用好“框架”這個工具,也有助於根據自身需要去選擇合適的框架。
2018 年 1 月 14 日,袁進輝(老師木)代表 OneFlow 團隊在 AICon 北京站做了標題為《深度學習框架技術剖析》的演講,AI 前線第一時間授權整理了老師木個人註解版演講全文。”
作為框架的開發者,OneFlow 團隊(一流科技,老師木的創業公司)發現,雖然框架多種多樣,但框架核心技術正呈現收斂的態勢,經過幾年的發展,在深度學習框架開發者眼裡出現一些“共識”,或所謂“最佳實踐”,幾乎所有框架都去擁抱了這樣技術選型,在架構和技術選擇上趨同。另一方面,也有一些技術在框架開發者眼裡屬於舉棋不定或無計可施的狀態。
這次報告會對已經收斂的技術(“最佳實踐”)做一個梳理,讀者會發現,開發一個深度學習框架沒有那麼難。本報告也會簡要討論目前框架未解決的難題,讀者也會發現,開發一個超越已有技術的框架有很難的問題。最後,我們會從框架開發者的視角去對主流深度學習框架做一句話點評,供使用者在做技術選型時參考。
深度學習框架的定位
首先介紹深度學習框架的背景,然後介紹深度學習框架開發中已經收斂的技術和仍未解決的問題,其次點評主流深度學習框架,最後對 2018 年的深度學習框架技術發展做出展望。
在進入正文前,讓我們首先宣告一些前提,如果這些前提不成立,那麼“深度學習框架”就沒那麼重要。但此次報告不會花時間筆墨去論證每個觀點,讀者若想了解這些觀點背後的邏輯,可以參閱 OneFlow 微信公眾號的歷史文章。
本文僅對第四點做一些闡述,用軟體實現深度學習演算法加速,可分微觀和巨集觀兩個層次。
微觀層次主要聚焦在單個裝置或晶片上的程式碼優化,裝置廠商通常會工作在這個層次,他們會提供高效能的庫,譬如 x86 或 arm CPU 上 MKL, OpenBlas,Nvidia GPU 上的 CuBlas, Cudnn 等,在大部分稠密計算場景都能貼近裝置的理論效能,優化空間不大(當然在終端裝置等低功耗場景有很多發揮空間)。
巨集觀層次,主要是多裝置和多計算節點層面的優化,這要靠分散式框架的支援,是計算力推向更高水平的關鍵,在效能上仍有巨大優化空間。最後,深度學習軟體要解決程式設計不夠快(程式設計師的效率)和程式執行不夠快(計算機的效率)兩個痛點,“兩個痛點的描述”出自尼克著《人工智慧簡史》裡的一句話。
weixin.qq.com/r/KSrexuXEu… (二維碼自動識別)
對深度學習框架感興趣,可關注 OneFlow 公眾號,下面幾頁報告的詳細註解都可以在歷史文章 GIAC 報告《深度學習平臺技術演進》中看到。
神經網路由若干層次構成,每個層次通常都可以表示成對矩陣的處理,這種稠密計算形式特別適合使用高度並行的硬體加速(GPU、TPU 等)。
限於硬體製造工藝水平,單個裝置(GPU、TPU) 不可能無限大,而工業級應用對計算力的渴求是無止境的,此時就必須用高速互聯的多個裝置協同來完成大規模計算。上圖展示了 GPU 叢集和 TPU 叢集,在這種配置裡,通常是 CPU 和 GPU (或 TPU) 一塊兒工作,CPU 負責任務的排程和管理,而 GPU 負責實現稠密計算,這就是經常說的異構計算(Heterogenous computing)。
“硬體越快,軟體越難”這個觀點分享過多次,請參閱《深度學習平臺技術演進》一文。
簡要說:自上而下看,深度學習模型訓練通常使用隨機梯度下降(SGD) 演算法,是更接近流式計算的一種負載:每處理一小片資料,就引起系統內部狀態的變化;自下而上看,深度學習廣泛採用異構計算技術,GPU 此類的裝置吞吐率非常高,是 CPU 的 10 倍以上,意味著同樣大小的計算任務,GPU 可以更快完成。從小粒度和快裝置兩方面看,深度學習訓練中的計算任務粒度非常小,通常是數十毫秒到百毫秒級別。但是,裝置互聯頻寬並沒有實質改進,譬如同機內部 PCIe 或多機互聯使用的高速乙太網或 Infiniband 的傳輸頻寬要低於 GPU 內部資料頻寬一兩個數量級。以上因素給分散式軟體框架帶來巨大壓力,如果處理不好,就會造成裝置利用率低,整體系統效能差的後果。打個比方,雖然高鐵要比普通的列車開起來快很多,但如果讓高鐵每個車站都停兩分鐘,那麼高鐵並不會比普通列車快多少。
軟體層和硬體層都是屬於“計算力”範疇,軟體層扮演了傳統意義上作業系統(OS,如 Windows, Linux),或者網際網路時代瀏覽器,或者移動網際網路時代 Android, IOS,或者大資料時代 Hadoop 的角色,是上層應用的入口。同時軟體生態又定義了底層硬體的角色,會影響底層硬體的發展和命運。
深度學習框架的最佳實踐
我們首先介紹深度學習框架中已經收斂的技術,理解了這些原理,每個人應該能開發出一個自己的深度學習框架。
在進入技術細節之前,讓我們先來理解兩個很重要的概念:控制流(Control flow) 和資料流(Data flow),這倆概念事關後續一些關鍵的技術選擇。以 a = x + y; b = a * a; c = 4 - a; 這樣一段簡單的程式為例,有兩種程式設計模式,一種是以 C 語言為代表的指令式程式設計(imperative programming),語句的排列順序隱式的刻畫了程式的執行順序(左圖中虛線箭頭表示執行順序),有哪些語句可以並行執行,並不太明確,如果要在多個執行緒中執行這幾條語句,為了防止出現多個執行緒間的讀寫衝突,可能要使用鎖 (lock)等技術來保護某一個變數(某一段記憶體)防止出現 data race。
另一種程式設計模式是以 Lisp 為代表的函數語言程式設計(functional programming),程式用一系列表示式來刻畫,程式的執行不是按表示式的宣告順序來執行,而是從表示式中挖掘出各個表示式之間的資料依賴關係,把資料依賴關係用一個有向無環圖來表示,圖顯式刻畫了哪些表示式必須在另一些表示式之前求值,或者哪些表示式之間不存在依賴關係,可以並行執行。在並行和併發越來越多的世界,functional programming 和資料流程式正在越來越受重視。
資料流模型一般表示成有向無環圖(Directed acyclic graph, DAG)。譬如上一頁的 a = x + y; b = a * a; c = 4 - a; 三個表示式可以表示成這樣一張圖,圓圈表示資料,方塊表示運算元。運算元之間靠資料的生產和消費關係產生依賴。資料流模型的優勢主要包括兩方面:
(1) 表示上的好處,顯式描述了程式中的所有並行機會;
(2)實現上的好處,資料流的執行引擎可以用很簡單的方法支援併發和並行,而在控制流程式中對併發和並行的支援就要複雜的多。
比較早的框架 Caffe 通過 Layer 這種抽象,運算和資料是放在一起的。TensorFlow 出現後,有向無環圖中兩個最基本的元素,操作符(運算)和張量(資料)是分開表示的,這種抽象模式也被其它框架所採用。具體地,Operator 一般是運算的描述,Kernel 是運算的具體實現,在實現上還要考慮操作符粒度的問題,理論上如果支援了最基本的加減乘除就可以通過圖計算自動支援更加複雜的運算(如一些神經網路層次的計算),但粒度太細就對編譯器要求特別高,當前編譯器生成的程式碼不一定能超過工程師手工優化的程式碼,因此在多數框架裡都是直接支援一些粗粒度的操作符,譬如卷積操作符,矩陣乘操作符等(值得注意的是 TensorFlow XLA, TVM 在細粒度操作符描述的圖優化方面有一些好的實踐)。對於張量計算的支援,業界也有很多技巧,譬如一般使用 C++ 模板超程式設計來實現,藉助於編譯時計算來提高執行時的效率,TensorFlow 等框架一般基於 Eigen 庫,MXNet 使用自己開發的 Mshadow。
autograd 已經成為深度學習框架的標配。有了 autograd,使用者寫程式時,只需要描述前向計算是怎麼做的,後向計算過程由系統自己推導完成。autograd 通過導數的鏈式法則實現,逆拓撲序搭建反向計算圖。需要注意兩點:
(1)後向計算過程可能會依賴於前向計算產生的中間資料,所以前向計算的中間資料可能要一直保持到對應的後向計算完成才能釋放,否則就需要在後向計算時重新進行前向計算。
(2)如果前向計算過程有多個操作符消費了同一個資料,後向計算圖時就需要把這幾個操作符對應的梯度運算元上傳過來的誤差訊號進行累加。上面的示意圖來自陳天奇在華盛頓大學一門《Deep learning systems》課程的課件,感興趣的讀者可以去課程網站獲取更多資料。
給定使用者輸入的 DAG (稱之為邏輯圖,logical graph), 系統一般會利用編譯器技術對圖進行優化重寫,上圖羅列的一些優化技巧就不一一展開解釋了。經過優化最終送到執行引擎執行的圖叫物理圖(physical graph),物理圖可能和輸入的邏輯圖已經截然不同了。在 TensorFlow, PyTorch, MXNet, Caffe2 中都可以看到這些常見的優化辦法。
執行引擎是深度學習引擎的核心,基本原理是按拓撲序去執行運算元 / 操作符,以上圖為例,剛開始,乘法和減法運算無法執行,因為它們依賴的一個資料 a 還沒有生成,引擎首先執行輸入資料已經就緒的操作符,即加法,當加法完成後,執行引擎會從 DAG 中刪掉已經執行的節點,然後發現乘法和減法的執行條件已經滿足了,再去執行乘法和減法。事實上,當前所有大資料處理引擎的核心都是用這個原理實現的。在深度學習框架裡,需要注意排程器是在 CPU 上執行的,而操作符的真實運算是在 GPU 上完成的,為了高效協調 CPU 和 GPU 之間的工作,在具體實現上有一些技巧。感興趣的讀者可以觀摩 TensorFlow, MXNet, Caffe2 的執行引擎,也許你會發現有更好的實現辦法。
從執行效率考慮,深度學習框架底層一般基於 C++ 開發,從易用性角度出發,也同時提供 Python 前端便於資料科學家使用。上圖來自李飛飛教授在史丹佛的 cs231n 課程課件,展示了 Numpy,TensorFlow 和 PyTorch 對同一個簡單神經網路訓練過程的實現。
最左側是 Numpy 程式碼,它的第一個特色是 imperative programming,是即時求值(eager evaluation),執行完 b = a + z 這條語句,b 的結果就出來了;第二個特色是沒有 autograd,所以使用者不僅要寫前向計算的程式碼,還要把後向梯度下降的程式碼寫出來,而 TensorFlow 和 PyTorch 都支援了 autograd,在程式碼中只需要寫前向計算的過程,而後向計算過程是系統自動構建的。
TensorFlow 和 PyTorch 的區別則是,前者是 lazy evaluation,後者是 eager evaluation。在 TensorFlow 中,a = x + y; b = a + z 只是一些表示式,構建了一個資料流圖,在執行 sess.run 時刻才會被真正執行,而且執行順序不一定和表示式宣告順序一致。在 PyTorch 中,和 Numpy 原理類似,每條語句都是立刻執行,而且按照語句的排列順序執行。看上去,PyTorch 的程式碼的確更加簡潔,後文會進一步討論延遲求值和即時求值的問題。
深度學習框架不只要解決易用性和高效性,還要方便部署運維。當前主流的深度學習框架都是基於檢查點機制實現容錯,Fail fast and warm start。深度學習框架還需要和上下游的開源工具鏈有機銜接,譬如分散式資料儲存和資料預處理依靠 Hadoop 或者 Spark。部署運維,現在比較推崇基於 Docker 和 Kubernetes 相結合的方案。使用者有時需要在多個框架之間切換,隨著 ONNX 標準的推出,也大大便利了各種框架間的遷移,譬如使用 PyTorch 描述或訓練的模型可以按 ONNX 規範匯出,並被 Caffe2 框架使用。除了解決訓練問題,深度學習框架還便於上線部署,為此 TensorFlow 推出了單獨的 serving 模組。
深度學習框架當前技術焦點
下面我們探討一些當前框架開發者還舉棋不定或一籌莫展的技術問題。
Define-and-run 和 Define-by-run 近期關注度比較高,PyTorch 靠 Define-by-run 這個特性吸引了很多開發者。這個技術問題還有其它等價的描述,譬如 define-and-run,基本上和 lazy evaluation, 或 declarative programming, data flow 是一回事,通常意味著效率高。define-by-run 則基本上和 eager evaluation, imperative programming 或 control flow 是一回事,通常意味著靈活性。最近,很多框架在積極的推進支援 define-by-run 的執行模式,譬如 TensorFlow 增加了 eager evaluation,MXNet 推出了 gluon 介面,PaddlePaddle Fluid 也是一種 imperative programming 的用法。那這兩種技術選擇到底是怎麼回事呢? 我們認為:
(1)Imperative programming 只不過是大部分程式設計師更加熟悉的程式設計方式,實現一個 imperative programming 的深度學習框架要比實現一個 declarative programming 的框架簡單(最簡只須實現 autograd,複雜點要支援 JIT)。傳統的 lazy evaluation 框架增加 imperative programming 介面可以做到和 PyTorch 完全一樣的使用者體驗,只不過要費些周章。
(2)只要 declarative programming 解決了除錯困難等問題,就是對使用者更友好的一種程式設計模式,使用者只要在寫程式時描述 what,而不需要關心 how,底層細節對使用者透明,這是現代變程式語言的發展趨勢。
(3)並行和併發代表著未來的趨勢,那麼資料流(宣告式程式設計,函數語言程式設計)代表著未來,data flow 模型在任務描述和系統執行引擎的簡潔性上都有天然優勢。
平行計算可以擴大處理任務的規模,也可以加速計算。具體到深度學習框架,總體情況是:資料並行已經得到解決,無論是哪個框架都能把適合資料並行的任務做到接近理想加速比,譬如計算機視覺領域各種 CNN 模型;資料並行和流水線並行不支援或支援的不好,導致在某些分散式訓練場景,硬體利用率過低,訓練週期過長。在集合通訊(Collective communication operation)上有基於引數伺服器的,MXNet、PaddlePaddle、TensorFlow、也有基於 MPI(或類 MPI)的,譬如 Caffe2。TensorFlow 在巨集觀架構上還區分了 Client、Master、Worker 節點,在重構版的 PaddlePaddle 也使用了類似的架構。
資料並行的原理解釋,可以參見本公眾號《深度學習平臺技術演進》一文,現有框架都能良好支援資料並行。原本限制資料並行的一個問題是隨機梯度下降演算法依賴的 mini-batch 不能太大,太大的 mini-batch 演算法不收斂,這就導致即使有大量的並行裝置,也發揮不出來威力。近期有一系列成果攻克了這個問題,譬如 Facebook 推出的一個小時訓練 ImageNet,以及尤洋做的一系列工作,可以把 mini-batch 推廣到 32K, 保證演算法仍然收斂,這就能充分發揮資料並行的優勢。
模型並行的原理請參見本公眾號《深度學習平臺技術演進》一文。模型並行本身實現複雜度不是特別高,主要困難在於有的場景適合資料並行,有的場景適合資料並行,有的場景同時需要模型並行和資料並行,這就需要根據實際情況正確的對資料重新組織(分裂,合併)和路由(把資料正確的傳送到目的地,scatter 或 broadcast)。再有就是,當資料路由比較複雜時,就很難高效的支援,就需要流水線並行的支援。
當神經網路模型或中間隱狀態體積很大時,譬如超過一張顯示卡視訊記憶體的容量,除了使用模型並行,還可以使用流水線並行。流水線並行有點像接力比賽,上圖展示了一個簡單的例子,第一個 GPU 做完第一層的計算後,把結果傳遞給第二塊 GPU,第二塊 GPU 完成中間四層的計算之後,把結果傳遞給第三塊 GPU 完成計算。通常訓練深度學習模型時,存在多個階段,譬如把資料從磁碟載入到主存,把資料從主存搬運到 GPU, GPU 完成一個階段的計算之後,可能還需要把資料通過網路傳送到另一臺機器。在這樣多階段任務中,流水線並行對於系統效能至關重要。可以注意到,大部分框架在 IO 階段會做流水線並行,而在多個計算階段,或者計算與通訊階段之間都沒有相應支援。基於現有框架去支援模型並行,流水線並行還非常困難。
主流深度學習框架點評
下面分享一些我們對各種框架的理解和判斷,如果觀點有偏差,敬請理解,歡迎批評指正。
以上框架使用者比較多,開發團隊技術實力雄厚。深度學習框架的先驅 Theano 已停止更新,它的 autograd 機制已經被這些現代框架所吸收;我們沒有研究微軟開發的 CNTK;Intel 收購的 Nervana 在開發一個新的框架 NGraph,也值得關注,不過它目前主要聚焦在單裝置優化;DMLC 的 NVVM 和 TVM 放在 MXNet 內;有一個來自日本研究人員的框架 Chainer 也比較有特色,Python 前端非常清爽。
TensorFlow
TensorFlow 是系統完整度最高的,支援 training 和 inference (serving),支援影像常用的 CNN,也支援自然語言和語音常用的 RNN/LSTM, 還有移動端的 TensorFlow Lite,支援 lazy execution 也支援 eager execution,社群生態最強大,Google 在深度學習演算法和應用方向的研究也是冠絕天下(參見 Jeff Dean 寫的 Google Brain 2017 年度回顧:zhuanlan.zhihu.com/p/32905123 )深度學習領域很多新的研究成果都是以 TensorFlow 程式碼釋出的。
但 TensorFlow 的效能也是廣受詬病,我們不大清楚 TensorFlow 在 Google 內部是不是效能卓越,在外部使用者那裡經常能聽到使用者抱怨 TF 慢,在學界和工業界很多 Benchmark 裡,大家也喜歡拿 TensorFlow 做 baseline,譬如 CMU Eric Xing 教授團隊發表的 Poseidon 論文,基於 TF 做了一系列優化之後,效能提高非常顯著;Uber 團隊改造了 TensorFlow 的分散式實現後(把 PS 換成 MPI),CNN 資料並行場景還能提高一倍的效能 (見 Uber Horovod github.com/uber/horovo…) 。
從框架開發者的角度看,我們以為 TensorFlow 要解決效能問題,須有壯士斷腕的決心,推翻一系列原有設計和實現。最後,TensorFlow 畢竟是功能最完整的框架,如果要訓練大規模 RNN/LSTM,目前只能選擇它,儘管要忍受一下很長的訓練週期。
PyTorch
Facebook AI Lab 出品的 PyTorch 是深度學習框架的一匹黑馬,靠 Eager evaluation 博得了大批深度學習研究人員的青睞。基於 Imperative programming 的理念和基於 Python 的語言構造(控制流)來搭建神經網路,靈活性高。NLP 領域常有一些動態圖的需求,PyTorch 是首選。
我們認為在單機場景下,易用性和靈活性是最重要的使用者需求,其它框架為了滿足這樣的需求,必須在原本為分散式設計的技術架構上做一些妥協,難以和 PyTorch 的最簡核心競爭。PyTorch 為了克服 Eager evaluation 的一些問題,也在通過 JIT 來享受一些 Lazy evaluation 的優點,同時也在向分散式場景進軍。如前文所述,在大規模分散式應用場景下,使用者程式只能是 Lazy evaluation 風格,資料流的執行引擎在高併發高並行的場景有天然的優勢,PyTorch 現在的設計實現距離這個目標還比較遙遠。
MXNet
MXNet 開發團隊實力雄厚,現在是 Apache 孵化專案,有 Amazon 官方支援加持。MXNet 的特點是包含很多正對 Geek 品味的實現技巧, 很值得喜歡鑽研前沿技術的人去觀摩。但不好的地方是,給人一種比較“雜”的感覺,讓開發者感到困惑,譬如矩陣庫有兩套實現 Mshadow 和 NDArray。MXNet 在計算機視覺領域總是能緊跟前沿應用,一些新的模型出來社群總是第一時間支援。MXNet 有一些關聯專案,譬如 NNVM 和 TVM,目前來看 TVM 更獨特,NNVM 裡實現的一些圖優化技術在其它框架裡也是有對應實現的,而 TVM 和 TensorFlow XLA 應該是處於一個層次:聚焦於單裝置程式效能優化。基於 TVM、Halide、TensorFlow XLA ,使用者可以在單裝置上使用宣告式程式設計,編譯器自動生成高效的後端程式碼。
Caffe2
Caffe 的使用者還非常多,第二代 Caffe2 和第一代已經迥然不同了,但繼承了一些簡潔的品質在裡面。框架的抽象非常簡潔,不厚重,Op/Kernel 和引擎主要在 C++ 層實現,而複雜的圖拓撲結構在 Python 層面處理。Caffe2 借鑑了 TensorFlow 對 Op/Kernel 的抽象,沒有再使用之前 Layer 那種把資料和操作放在一起的設計。同樣是 Op/Kernel 抽象,Caffe2 也不是簡單的模仿, 程式碼看上去更加舒服。Caffe2 目前支援資料並行,曾創造了一個小時訓練 ImageNet 的記錄,對 Caffe 有感情的使用者可以嘗試。據瞭解,Caffe2 在 Facebook 內部承擔了“工業級應用”和“部署”的重任,也開發了很好的移動端支援,這應該是 Caffe2 的特色。Caffe2 還有一個很有特色的技術,gloo 網路庫是定製的 MPI 實現,有“去中心化”叢集通訊的味道,也便於支援流水線。
PaddlePaddle
PaddlePaddle 最大的優勢是百度內部在廣泛使用,經受了實戰檢驗。第一代 PaddlePaddle 是比較接近 Caffe,分散式並行也依賴於 Parameter server。最近一年,Paddle 團隊在開展非常激進的重構。以我們的理解,重構版 PaddlePaddle 借鑑了很多 TensorFlow 的設計,所以 Paddle 能否解決 TensorFlow 面臨的問題呢? 重構後的 PaddlePaddle 主推指令式程式設計介面,正像我們評價 PyTorch 時所說的,指令式程式設計介面固然親民,但資料流表示在大規模分散式執行場景有天然的優勢(表示能力和引擎實現複雜度方面),要很好的支援大規模分散式場景,深度學習框架最終要把“控制流”程式碼翻譯成“資料流”程式碼在後臺執行。
總體來看,深度學習框架開發的絕大部分技術祕密已經公開了,開發一個簡單的深度學習框架沒有那麼難。但從另一方面看,要開發一個易用性和高效性都很卓越的框架是非常困難的,即使是世界上最優秀的開發團隊也感到困難重重,克服這些問題需要艱苦卓絕的創新和堅持。
展 望
展望未來一年
(1) 我們認為在計算機視覺領域也將迎來模型更大的場景,譬如把 Hinton 的 Capsule net 從 Cifar 推向 ImageNet 規模,模型大小就遠超當前各種常見的 CNN, 這種情況必須把模型分裂到多個裝置上去完成,也就是所謂的模型並行。而且學界很關心神經網路結構學習,元學習,也有必要去探索 CNN 之外的架構,在人腦視皮層儘管存在 CNN 這種神經元分層組織和區域性感受野的神經元,但並沒有所謂 weight sharing(神經元功能柱有類似的特異選擇性,但不是嚴格一樣),這種神經元之間的連線規模非常龐大,如果去掉這個約束會發生什麼?如果深度學習框架不能支援模型並行,那麼這種設想就只能在 Cifar, MNIST 這種資料集合上去探索,並不能在 ImageNet 甚至更大規模的資料上去探索,而有些規律是在大規模資料上才會“湧現”出來。
(2)未來,通用的深度學習框架會支援模型並行,而且使用者使用模型並行易如探囊取物。
(3)深度學習向更多場景滲透,自然而然。
(4)一旦一項技術被驗證,各種深度學習框架都會去擁抱它,支援它,正如今天很多框架在提供 imperative programming 介面一樣,同質化是比較嚴重的,未來需要一些新的空氣,新的思路去解決那些懸而未決的問題。
(5)在大資料和人工智慧時代,資料積累到了臨界點,工業界除了有資料儲存,資料篩選這些需求,將普遍需要一個大腦(Brain),作為資料驅動業務的引擎,深度學習框架會像 Hadoop 一樣經歷一個從“舊時王謝堂前燕,飛入尋常百姓家”的過程。
更多幹貨內容,可關注AI前線,ID:ai-front,後臺回覆「AI」、「TF」、「大資料」可獲得《AI前線》系列PDF迷你書和技能圖譜。