有了Julia語言,深度學習框架從此不需要計算圖

2020-12-16 機器之心Pro

選自julialang

作者:Mike Innes 等

機器之心編譯

參與:劉曉坤、思源

本文基於 NeurIPS MLSys 的一篇論文《Fashionable Modelling with Flux》,探討開發者們如何使用 Julia 語言從頭開始思考機器學習工具,並提供對於現代機器學習工具所需改進的一些見解,涉及新的可微分編程工具 Flux、求梯度、支持 GPU 和 TPU、自動批處理。為什麼 Julia 式的機器學習不需要計算圖呢?因為 Julia 的機器學習語法就是計算圖。

鑑於機器學習(ML)對程式語言、編譯器和生態系統的眾多需求,現在已經有很多有趣的發展。不僅 TensorFlow 和 PyTorch 等現有系統間的權衡得不到解決,而且這兩個框架都包含不同的「靜態圖」和「eager execution」接口,但它們的形式已經比以前更加清晰。與此同時,機器學習模型基本上是可微分算法的思想(通常稱為可微分編程)已經流行起來。

當前的機器學習框架遇到了阻礙,很多已有的新項目都完全移除了計算圖,從而使可微分編程成為主流。例如,由 Theano 團隊開發的 Myia 可以求微分並編譯 Python 的一個子集為高性能 GPU 代碼。Swift for TensorFlow 作為 Swift 語言的擴展,它可以將兼容的函數編譯為 TensorFlow 計算圖。最後,Flux 生態系統為 Julia 編譯器提供了一些機器學習專用的工具,包括:first-class gradients、即時 CUDA 核編譯、自動批處理(automatic batching)以及對新硬體(例如 TPU)的支持。

所有這些項目都有巨大的潛力,但目前看來 Julia 具有優勢。

Flux 簡介

我們需要一種語言來編寫可微分算法,Flux 使 Julia 變成了這樣的語言。Julia 專為數學和數值計算而設計,非常適合表達機器學習算法。同時,它在編譯器中融合了現代設計和新思想,可以更輕鬆地滿足尖端 ML 的高性能需求。

典型的框架通常包含數十萬行 C++代碼,Flux 卻只有千行 Julia 代碼。只需要一個求梯度的包(Zygote.jl)、一個用於 GPU 支持的包(CuArrays.jl)、再加上一些輕量函數,我們就能得到一個功能齊全的機器學習堆棧。

與其他下一代機器學習系統一樣,Flux 致力於提供直觀(「eager」或「define-by-run」)的接口,並對任何類型的計算圖構建或性能注釋進行嚴格控制。從控制流、數據結構到宏,Flux 支持語言的所有特徵。用戶可以在 Jupyter 筆記本中交互式地寫代碼,並將高性能數值計算與方便的繪圖、可視化相結合。但我們也希望獲得傳統上由「靜態圖」框架所帶來的好處,例如零開銷源到源 AD、OP 融合、多 GPU /分布式訓練和二進位部署等。

我們怎麼能做到這一切?實際上,我們需要直接從 Julia 語法中提取和分析「靜態圖」,這實際完全上是編譯器的正常工作。通過適當的角度來看,大多數機器學習系統問題都是標準的且經過充分研究的編譯器問題。使用編譯語言足以解決許多問題,擴展該編譯器是解決更多問題的最佳方法。本文僅介紹了我們目前在該領域的工作範例,即求梯度、為 GPU 和 TPU 提供代碼編譯,以及自動批處理。

求梯度

推動反向模式求微分的極限,我們將此視為語言層面的問題。求微分是一種符號轉換,屬於編譯器的領域。現有框架通過追蹤(實際上是一種部分評估或抽象解釋)來實現這一目標。人們引入了一種新的張量類型,它記錄了所執行的所有基本數學運算,生成一個計算圖(或符號表達式),其中刪除了宿主語言的控制流和數據結構。然而,這給出了一個艱難的權衡:我們要麼接受解釋器的開銷(eager execution),要麼固定用戶的控制流並限制可以構建的模型種類(靜態圖)。

反之,如果「計算圖」就是 Julia 自己的語法呢?通過將這個想法發揮到極致,我們構建了 Zygote,它直接在 SSA 形式的中間表徵(IR)上工作,支持控制流、遞歸、數據結構和宏等語言功能。然後,我們可以通過 LLVM 之類的編譯器生成 SSA 形式的伴隨代碼,並將傳統編譯器優化的所有優勢應用於前向和後向傳播。此外,這種方法還為擴展該編譯器基礎結構提供了可能,可以使用更高級和特定領域的優化,例如用於 TPU 等加速器的內核融合和編譯。TensorFlow 的 Swift 和 Myia 開發人員在源到源 AD 技術的復興中正在探索類似的方法。

Julia 用於此任務的一個關鍵優勢是它可用於實現基本數值計算庫,如微分方程求解器或優化庫;這巧妙地解決了機器學習社區不斷增長的需求,研究人員通過高性能代碼(如光線追蹤和物理引擎)進行反向傳播,但求梯度仍必須在 C++中手動實現。相比之下,由於 Julia 的實現是用 Julia 編寫的,因此可以輕鬆對從 ODE 到金融定價模型等求微分。將這些強大的工具帶入模型是深度學習真正成為可微分編程的關鍵。

編譯 Julia 到 GPU 上

GPU 編程是現代機器學習的重要組成部分,但 GPU 通常被視為實現細節。因為框架在內部提供內核,但用戶只能使用一組有限的數學運算,無法直接對 GPU 進行編程。相比之下,Julia 中的 GPU 編程一直是一流的 CUDA 內核(可以很好地編寫並從腳本或 notebook 中運行)。如下簡單的向量加法內核看起來類似於 CUDA C:

function kernel_vadd(a, b, c) i = (blockIdx().x-1) * blockDim().x + threadIdx().x c[i] = a[i] + b[i]returnend

但是,Julia 的類型特化可以在 GPU 上實現一組強大的附加抽象。例如,上面的代碼不限於浮點數的密集數組,而是可以給出複數的稀疏數組;Julia 的常規特化機制將動態地生成一組新的 PTX 指令。我們甚至可以將此代碼進一步抽象為可利用「+」函數的「高階內核」,從而在四行代碼內創建一整套函數 map(f,x,y)。

這可以實現一些強大的技巧,即使你自己從不編寫 CUDA 代碼。例如,我們可以透明地將大型廣播(broadcast)表達式(例如 1 /(1 + exp(-x))及其向後傳遞融合到單個 GPU 內核中,從而獲得顯著加速。我們期望原生 GPU 代碼生成能力和生態系統將為各種基於 Julia 的機器學習庫提供支持。

編譯 Julia 到 TPU 上

更進一步,谷歌最近開放了雲 TPU 使用的 XLA IR,使得其他框架和用戶都可以利用這個重量級硬體。XLA 功能強大但有限制:它無法運行 Python 解釋器,當然也沒有良好的性能。

而我們只需要從編寫的 Julia 程序中提取「靜態圖」並將其直接編譯為 XLA,從而允許 Julia 本身在 TPU 上運行。(事實上,這只是 Julia 一般編譯過程的簡單擴展,它在將程序發送到 LLVM 之前從程序中提取最大的「靜態子圖」。)這使我們可以充分利用 Julia 語言的表現力,包括控制流、遞歸、多調度、高階函數、強大的數據結構和抽象、自定義數值類型,以及現有的包,如微分方程求解器和線性代數例程。所有這些都在獲得高性能收縮陣列引擎的優勢的同時,在 TPU 內運行。你今天就可以嘗試,其中包括 ResNet 等大型機器學習模型和 TSVD 等線性代數例程。

項目地址:https://github.com/JuliaTPU/XLA.jl

自動批處理(Automatic Batching)

為了從這些加速器中獲得最大收益(每個內核啟動可能會產生大量開銷,但是在輸入大小上可以很好地擴展),批處理程序通常會同時將前向和反向傳播應用於多個訓練樣本。在簡單的情況下,例如使用卷積網絡,通過在額外的批量維度上拼接 10 張圖像來處理這個問題會變得很簡單。但是,當處理可變結構的輸入(例如樹或圖形)時,此任務變得更加困難。

大多數研究人員通過人工完成批處理代碼來解決這個問題,這樣做的成本非常大。人們已經針對不同的框架提出了不同的解決方案(DyNet、TensorFlow Fold,它試圖在可能的情況下將一些高級 OP 一起批處理,但是這些通常要麼具有其自身的可用性問題,要麼沒有實現手寫代碼的性能。

我們認為這個問題與單程序多數據(SPMD)編程的問題完全相同,單程序多數據編程幾十年來一直被語言和編譯器社區充分研究。實際上,它與 GPU 內部使用的並行模型非常相似,並且已經實現 CPU 的 SIMD 單元的編譯器變換。通過從這項工作中汲取靈感,我們在 Julia 中實現了相同的變換,為標量 SIMD 單元和模型級批處理提供 SPMD 編程。這使我們能夠編寫對單個樣本進行操作的簡單代碼,同時仍然在現代硬體上獲得最佳性能。

結論

我們相信機器學習的未來取決於程式語言和編譯器技術,尤其是擴展新的或現有的語言以滿足機器學習研究的高要求。這不僅適用於機器學習社區,也適用於一般的數值規劃;能夠支持微分、向量化和新型硬體的程式語言將足以推動科學的許多進步。

原文連結:https://julialang.org/blog/2018/12/ml-language-compiler

相關焦點

  • 華為深度學習框架MindSpore正式開源:自動微分不止計算圖
    作為一款「全場景 AI 框架」,MindSpore 是華為人工智慧解決方案的重要組成部分,與 TensorFlow、PyTorch、PaddlePaddle 等流行深度學習框架對標,旨在大幅度降低 AI 應用開發門檻,讓人工智慧無處不在。MindSpore 是一款支持端、邊、雲獨立/協同的統一訓練和推理框架。
  • 谷歌剛發布的深度學習動態計算圖工具TensorFlowFold是什麼?
    2 月 7 日,谷歌通過博客正式發布了 TensorFlow Fold,該庫針對 TensorFlow 1.0 框架量身打造,可以幫助深度學習開發者根據不同結構的輸入數據建立動態的計算圖(Dynamic Computation Graphs),簡化了模型訓練階段對輸入數據的預處理過程,提升了系統的運行效率
  • 機器學習者必知的5種深度學習框架
    它通常包含具有許多節點的神經網絡,並且每個節點都有許多需要在學習過程中必須不斷更新的連接。換句話說,神經網絡的每一層都有成百上千個相同的人工神經元在執行相同的計算。因此,神經網絡的結構適用於GPU(圖形處理單元)可以高效執行的計算類型(GPU是專門為並行計算相同指令而設計的)。隨著深度學習和人工智慧在過去幾年的迅速發展,我們也看到了許多深度學習框架的引入。
  • 深度學習框架太抽象?其實不外乎這五大核心組件
    為了更好地認識深度學習框架,也為了給一些想要自己親手搭建深度學習框架的朋友提供一些基礎性的指導,日前來自蘇黎世聯邦理工學院計算機科學系的碩士研究生Gokula Krishnan Santhanam在博客上撰文,概括了大部分深度學習框架都會包含的五大核心組件,為我們詳細剖析了深度學習框架一般性的內部組織結構。以下由雷鋒網編譯。
  • 谷歌剛發布的深度學習動態計算圖工具TensorFlow Fold是什麼?
    2 月 7 日,谷歌通過博客正式發布了 TensorFlow Fold,該庫針對 TensorFlow 1.0 框架量身打造,可以幫助深度學習開發者根據不同結構的輸入數據建立動態的計算圖(Dynamic Computation
  • 深度學習框架比較,我該選擇哪一個?
    使用深度學習框架完成模型構建有如下兩個優勢: 節省編寫大量底層代碼的精力:屏蔽底層實現,用戶只需關注模型的邏輯結構。同時,深度學習工具簡化了計算,降低了深度學習入門門檻。
  • TensorFlow與PyTorch之爭,哪個框架最適合深度學習
    那麼究竟哪種框架最適宜自己手邊的深度學習項目呢?本文作者從這兩種框架各自的功能效果、優缺點以及安裝、版本更新等諸多方面給出了自己的建議。如果你在讀這篇文章,那麼你可能已經開始了自己的深度學習之旅。如果你對這一領域還不是很熟悉,那麼簡單來說,深度學習使用了「人工神經網絡」,這是一種類似大腦的特殊架構,這個領域的發展目標是開發出能解決真實世界問題的類人計算機。
  • PYTORCH與TENSORFLOW:哪種框架最適合您的深度學習項目?
    為了幫助開發這些架構,諸如Google,Facebook和Uber之類的技術巨頭已經發布了適用於Python深度學習環境的各種框架,從而使學習,構建和訓練多樣化的神經網絡變得更加容易。在本文中,我們將研究兩個流行的框架並進行比較:PyTorch與TensorFlow。簡要地比較一下,最常用和依賴的Python框架TensorFlow和PyTorch。
  • 清華開源Jittor:首個國內高校自研深度學習框架,一鍵轉換PyTorch
    機器之心報導機器之心編輯部繼 Theano、Caffe 之後,又一個由高校主導的深度學習框架開源了,而且還是國產。深度學習框架越來越多,主導的團隊也從高校研究機構漸漸轉向了科技巨頭。清華大學開發了一個名為計圖(Jittor)的深度學習框架。這一框架有望為深度學習社區提供新的方案,也能夠推動深度學習框架國產化的進程。據悉,計圖(Jittor:Just in Time)是一個採用元算子表達神經網絡計算單元、完全基於動態編譯(Just-in-Time)的深度學習框架,其主要特性為元算子和統一計算圖。
  • 掌握深度學習,為什麼要用 PyTorch、TensorFlow 框架?
    甚至可以說,並非每個回歸或分類問題都需要通過機器學習來解決。畢竟,許多數據集可以用解析方法或簡單的統計過程進行建模。另一方面,在某些情況下,深度學習或深度遷移學習可以幫助你訓練更準確的模型。在這些情況下,你可以考慮使用PyTorch和TensorFlow,特別是如果你所需的訓練模型與其中一個框架模型庫中的模型類似。
  • 新語言不焦慮!這裡有一份Julia極簡入門教程
    知乎上的話 Julia 有很多專欄,這個專欄更新的比較勤可以看看,也歡迎大家給這個專欄投稿:https://zhuanlan.zhihu.com/julia然後書的話,我有意願之後等中文社區人多一些組織一個開源圖書的項目,但是這個可能最近還實現不了,一個是我精力有限,第二是人手不足。
  • 清華自研深度學習框架「計圖」開源!多項任務性能超過PyTorch
    值得一提的是,這也是首個來自中國高校科研機構的開源深度學習框架,之前,業內來自「高校」的還有加拿大蒙特婁大學的Theano,UC伯克利的Caffe。與主流的深度學習框架TensorFlow、Pytorch不同,Jittor是一個完全基於動態編譯(Just-in-time)、使用元算子和統一計算圖的深度學習框架。
  • TensorFlow和Caffe、MXNet、Keras等其他深度學習框架的對比
    同時 TensorFlow 不只局限於神經網絡,其數據流式圖支持非常自由的算法表達,當然也可以輕鬆實現深度學習以外的機器學習算法。事實上,只要可以將計算表示成計算圖的形式,就可以使用 TensorFlow 。用戶可以寫內層循環代碼控制計算圖分支的計算,TensorFlow 會自動將相關的分支轉為子圖並執行迭代運算。
  • 大神擼了個暗黑系深度學習框架...
    深度學習神經網絡正步入成熟,而深度學習框架目前眾多,大都可以在圖像識別、手寫識別、視頻識別、語音識別、目標識別和自然語言處理等諸多領域大顯身手。Theano最初誕生於蒙特婁大學 LISA 實驗室,於2008年開始開發,是第一個有較大影響力的Python深度學習框架。由於Theano已經停止開發,不建議作為研究工具繼續學習。TensorFlow在很大程度上可以看作Theano的後繼者,不僅因為它們有很大一批共同的開發者,而且它們還擁有相近的設計理念,都是基於計算圖實現自動微分系統。
  • 深度學習框架搭建之PyTorch
    深度學習框架搭建之PyTorchPyTorch 簡介PyTorch 是由 Facebook 推出,目前一款發展與流行勢頭非常強勁的深度學習框架。PyTorch 與 NumPy 非常相似,可以說是它的替代者,支持 GPU 加速運算,用來搭建和訓練深度神經網絡。如果學習過 NumPy 以及常見的深度學習概念(如卷積層,循環層等),非常容易上手PyTorch。目前主流的深度學習框架主要有 TensorFlow,PyTorch,mxnet,caffe和Keras 等。
  • 「2017深度學習框架大事記」PyTorch成TensorFlow最大競爭對手...
    已經有其他一些不太知名的深度學習框架使用動態計算圖,例如Chainer。動態圖的優點在於,圖(graph)是由run定義(「define by run」),而不是傳統的「define and run」。特別是,在輸入可以變化的情況下,例如文本這樣的非結構化數據,這非常有用而且高效。
  • 我用Python做了一個深度學習框架,秘訣在這裡!
    Theano最初誕生於蒙特婁大學 LISA 實驗室,於2008年開始開發,是第一個有較大影響力的Python深度學習框架。由於Theano已經停止開發,不建議作為研究工具繼續學習。TensorFlow在很大程度上可以看作Theano的後繼者,不僅因為它們有很大一批共同的開發者,而且它們還擁有相近的設計理念,都是基於計算圖實現自動微分系統。
  • Julia語言介紹,與大熱門Python有啥區別呢?
    它是一種動態語言,適合用於科學計算和數值計算,但與傳統的靜態類型語言相比,它的性能也不弱。實際上它的設計初衷就是高性能語言。Julia程序可通過LLVM編譯為多個平臺的高效本地代碼。 因為它是動態類型語言,所以會像Python一樣像一種腳本語言,也對交互使用具有良好的支持。
  • 深度學習10大框架對比分析
    他寫道:「我常聽到人們談論深度學習——我該從哪裡開始呢?TensorFlow 是現在最流行的吧?我聽說 Caffe 很常用,但會不會太難了?在 BEEVA Labs,我們常常需要應對許多不同的深度學習庫,所以我希望能夠將我們的發現和感想分享出來,幫助那些剛剛進入深度學習這一美麗世界的人。
  • AAAI 2017講座:8大主流深度學習框架超詳細對比(90PPT)
    Frameworks》的課程(Tutorial )介紹。這一講座介紹了深度學習框架設計原則的基本知識,其目標是為希望在自己的工作任務中利用深度學習的研究者 和AI 實踐者提供關於選擇合適框架的指導。當下,深度學習中的一些軟體框架,比如 TensorFlow 和 Caffe,已經被許多深度學習系統採納,以加速研究和發展速度。深度學習在 AI 的核心技術中扮演基礎性的作用,其中包括圖像和語音識別、計劃和自然語言處理。