從CUDA到Keras,這些年你應該了解的深度學習工具
“風起于青萍之末”,十年前,Nvidia被人工智能(AI)清風拂面,推出CUDA,成功把自己打造成風口上的飛豬。“Nvidia還從沒有搶到過像人工智能這樣強的風口,這意味著我們在GPU領域的成就無以倫比”,在AI淘金熱潮中,N記這家“賣水的”走到了2017CES聚光燈下。“據估計,世界上目前有3000家AI初創公司,大部分都采用了Nvidia提供的硬件平臺”,如果大家最近在某東關注過游戲本,可以直觀感受到N記這種成功。
一切得從GPU說起。GPU(Graphic Processing Unit)即“圖形處理器”,區別于CPU (Central Processing Unit)即“中央處理器”。CPU敢稱“中央”是有道理的,他是電腦的核心大管家,負責各種計算任務,通才多面手,因而其在架構選擇上重控制與緩存、少執行單元,以提升執行單元的效率。GPU則是為圖形渲染而生,特定用于G(Graphics)任務的,磚家能手,其架構上雖然跟CPU同根同源,但選擇輕控制、多執行單元,以提升并行處理能力。說的專業點,就是GPU在浮點運算能力上,相對CPU有數量級上的提升。架構選擇由計算任務的特點決定,CPU面對不同類型的計算任務會有不同的性能表現,而GPU在圖形渲染領域有CPU無法比擬的性能優勢。
GPU為圖形渲染而生,但人們很快發現這個家伙對“運算密集”、“高度并行”、“控制簡單”的其他任務也能得心應手,這是某種程度的“通用”計算,比如矩陣運算與方程求解。在強烈的需求驅動下,GPU向SIMD(Single Instruction Multiple Data,單指令多數據流)處理器方向不斷演化。SIMD 是個什么鬼?簡單說就是一個教官喊“稍息”,大家都稍息,教官再喊“立正”,大家一起立正。對應SIMD,還有MIMD(Multiple Instruction Multiple Data)架構,多個教官,一個教官喊“稍息”,只有你稍息,另一個教官可能已經讓他的兵“臥倒”“匍匐前進”了。MIMD能比較有效率地執行分支程序,而SIMD體系結構運行分支或條件語句時會造成很低的資源利用率。
說到這里,你可能已經覺得GPU這個東西酷斃了,可以像部隊一樣成軍團的戰斗,實現真正意義上的硬件層面的并行。現在我們有這么個大錘子,釘子在哪,在哪啊?打住,還有個重要的問題沒有解決,錘子的比喻不妥,其實我們是有了個大篩子,胃口大得很,你怎么及時喂飽它呢?數據庫天才 Jim Gray曾經打過比方,存在硬盤上的數據離CPU是宇宙距離,遙遠不可及,放到內存里,就變成銀河系內了,放到Cache里,就到了太陽,放到寄存器里,才到手邊。 這些存儲器對于輸運數據到CPU至關重要,也是決定處理能力的關鍵。為此,CPU配置了主存儲器,而GPU則配置了顯存。顯存目前以領先主存兩代的技術配置,加之執行部件的并行存取,其存儲帶寬也是數倍于主存,為強大的浮點運算提供穩定充足的數據吞吐。
GPU火了,但仍是馮諾依曼的處理器架構方式,有通用的執行單元,接受軟件指令,處理復雜的控制邏輯,有繞不開的局限性,SIMD影響靈活并行, MIMD方式教官又不能太多,它并沒有把各司其職的理念推到極致。讓專業的人做專業的事,效率一定是最高的,硬件層面做事,比用軟件效率高、能耗低。為追求極致性能,在一些特定的領域,人們設計了專用集成電路(ASIC)來處理固定的運算邏輯。ASIC邏輯是死的,無法更改,有諸多不便,這催生了介于處理器與ASIC之間的 FPGA.
FPGA學名“現場可編程門陣列”,一頭霧水啊!其實可以簡單理解成可回收利用的專用集成電路,也就是你可以對他編程,知乎網友形象的解釋“你所寫的代碼其實是在描繪一個數字邏輯電路”。這個數字邏輯電路定義好之后,“燒”到FPGA中,他就可以作為專用集成電路用了,下次處理邏輯變了,再編程,再燒。邏輯燒入FPGA中,就是個硬件電路了,沒有指令,按照電路自身邏輯運行,不需要誰來控制。FPGA中邏輯單元之間的通信也是固定的,不需要協商。對于計算與通信密集型任務,FPGA天然能耗更低、效率更高。
到此,聰明的你肯定能夠想到,一個復雜的計算任務,首先交給CPU去控制運算,其中對運算密集、帶寬要求高的部分,分給GPU或者FPGA去做,從而各司其職,優化資源配置,達到最佳的計算效果,(此處應該有掌聲)。N記推出的 CUDA (統一計算設備架構)就是這么干的,科學家比普通人強,不是在于常識,而是在于對常識的組合運用 :D 。
學過計算機原理,大家肯定記得,CPU上有匯編,有硬件驅動,有操作系統內核,有調用的API, 有編譯器,有高級語言,有開發庫,你用高級語言寫程序,然后用編譯器編譯,編譯生成對操作系統API的調用,進一步變成二進制指令,在CPU運行。CUDA 遵循這樣的邏輯,協同CPU與GPU, 并且特別的在GPU上提供硬件驅動,設備操作內核函數,系統調用,編譯器,高級語言(C或Fortran)支持,開發庫(例如用于矩陣運算的cuBLAS,用于快速傅立葉變換的cuFFT等等),你依然用C或Fortran寫程序,用CUDA 編譯器編譯,生成含有CPU端與GPU端邏輯的二進制指令,在CPU與GPU上協同運行。可以想象CUDA程序有兩個蓬勃的心臟。
不過CUDA是N記的,側重于GPU,一騎絕塵。那AMD家咋辦,眾多的FPGA咋辦? 行業需要一個開放的標準,面向CPU、 GPU、FPGA 等異構的系統,提供通用的并行開發與運行環境。OpenCL(全稱Open Computing Language,開放運算語言)就是眾多領導廠商共同努力的結果,從名稱上看,OpenCL分離了硬件核心驅動層與編程開發層,將硬件核心驅動交給不同的廠家自行提供。你用C語言在OpenCL標準上開發編譯的程序,可以透明的跑在從CPU、GPU、到FPGA等設備上。目前OpenCL相對與CUDA在性能、成熟度、易用性以及市場占有率上都有相當大的差距,但跨平臺與開放的通用性是優勢,也是趨勢。
上文中提到CUDA提供了不少類似矩陣運算、FFT等的開發庫,CuDNN就是其中的網紅,江湖地位堪比Papi醬,它是N記充分利用其GPU的性能創建的深度神經網絡加速庫,可以方便的集成到諸如TensorFlow、MXNet、Theano等流行的更高級別的機器學習框架之中。 CuDNN實現了典型的深度學習算法例如,卷積、Pooling、SoftMax、ReLU、Sigmoid、LSTM、RNN等等數據科學家們如數家珍的函數,屏蔽了GPU加速的技術細節,讓深度學習人員專注自己的高層模型,厲害了word CuDNN!
在《站在香農與玻爾茲曼肩上,看深度學習的術與道》一文中,我提到“深度學習領域的三類最典型問題,無監督學習(Unsupervided learning),有監督學習的分類(Classification)與預測(Prediction)歸根結底都是用神經網絡來近似概率分布,訓練的過程就是找到這個近似概率分布函數的過程。”訓練模型求解這些概率分布函數的過程是異常復雜的,無論CNN、RNN還是別的什么NN, 你都得綜合運用各種數學工具,設計調整神經網絡架構、處理正則化與約束、反復優化求極值,這些離不開深度學習框架與工具。可以毫不不夸張的說,人類的歷史就是不斷制造、使用與改進工具的歷史,用工具延伸我們的手、腳、牙齒、眼睛,還有頭腦。
幸運的是,在深度學習領域,人們已經創造了許多優秀的工具,Caffe、CNTK、Theano、Tensorflow、Torch等等,各有千秋,而且蘿卜白菜。由于在IT界,不同的技術特區都帶著濃濃的“宗教色彩”,為避免出現類似“你在PHP社區說Python好,會有人跟你吵上三天三夜”這樣的局面出現,接下來對各種工具的比較盡量不帶個人主觀成分,實在需要“深入探討”,請想辦法與作者直接聯系 :D。
2015年年底,Google開源了其深度學習框架 TensorFlow, 引起業界震動,這無異于當年大數據平臺中的 Hadoop發布。帶著谷歌的光環,TensorFlow也迅速流行。學過SQL的朋友都知道 SQL = Table + Flow, Table是輸入輸出、是Flow中流轉的數據,Flow中的節點對應著不同的處理與加工邏輯。 將這個概念應用于更高維度輸入輸出數據,就是Tensor+Flow。 Tensor 這里可簡單比作多維度Table (或者多維度矩陣,亦或多維度向量),Flow是Graph(計算任務的圖表示),Tensor是輸入輸出、是Flow中流轉的數據,Flow中的節點就是神經網絡的“神經元”,對應著不同的處理與加工邏輯。就是這么簡單。
曾經,性能是TensorFlow廣受質疑的一個點,但集成了CuDNN 充分利用GPU之后,性能大為提升,并通過與Spark的整合,實現大型分布式的模型訓練,回應了人們對其擴展能力的擔心。TensorFlow有強大的谷歌背書,良好的網絡架構與建模能力,豐富的開發語言支持(根植于Python,對R也有不錯的集成),具備活躍的開源社區,因而有著巨大的發展潛力。不過,成也蕭何敗也蕭何,谷歌全力支持,是Tensorflow大發展的基礎,卻使得谷歌的競爭對手們在采用與推動TensorFlow方面就顯得十分糾結了。微軟推出了自己的CNTK, 而亞馬遜則選擇了另外一個優秀的框架 MXNet。
來自MXNet核心團隊的觀點是: MXNet 專注深度學習運行的高效性與定制的靈活性,支持多操作系統與Python、R等多種語言,可以多機、多GPU并行, 同時支持命令式(類似Torch)和符號式(類似TensorFlow)兩種編程模式,因而有較好的遷移能力。“Mxnet 的輕量化路線使得我們可以在花費 Google brain 1/10 的人力的情況下做到類似 TF 技術深度的系統”,MXNet作者李沐如是說。而且這個核心團隊多是這樣有識有為的華人同胞,支持下!
相比MXNet, Keras選擇了對成熟框架Theano與TensorFlow做易用性的封裝,站在巨人的肩膀上,又不讓大家覺得高不可攀。用搭積木的方式組織你的神經網絡模型,易學易用,大大降低了上手的門檻,這就是深度學習領域的樂高啊。傍上老大哥TensorFlow, 對主流模型完美的封裝,加上豐富的示例,十分有利于快速模型搭建。在Lean Startup (精益創業)的MVP (最小化可行產品 Minimum Viable Product)理念盛行的今天,Keras必定有旺盛的生命力,我們拭目以待。
最后提下Jupyter Notebook(原名IPython Notebook), 它是目前一個較為流行的交互式集成開發環境(IDE),支持Python、R等幾十種語言;方便易用,打開瀏覽器,像寫筆記一樣寫代碼、做分析,交互式,幾乎沒有什么學習成本;生成的筆記也是簡潔優雅,人家叫“筆記本”可是名副其實,功能強大而且免費。注意到本文提到的軟件組件都是“功能強大而且免費”,感謝開源打破了技術壁壘,給整個技術社區帶來福利。
從底層硬件到上層框架,啰嗦了一大堆,其實用下面一張簡圖就可以概括常見深度學習組件、工具與其生態關系。不少東西,作者也是道聽途說,本文目的是從關于深度學習平臺的繁雜的信息中,理出些頭緒, 文中難免不嚴謹的地方,僅作交流學習心得用。
