更多互聯(lián)網(wǎng)精彩資訊、工作效率提升關(guān)注【飛魚在浪嶼】(日更新)
在許多機(jī)器學(xué)習(xí)用例中,尤其是在邊緣節(jié)點(diǎn)運(yùn)行 ML 模型時(shí),模型的成功仍然取決于其運(yùn)行的硬件,這使得在生產(chǎn)中使用 ML 模型的人員了解他們的模型如何編譯和優(yōu)化以運(yùn)行非常重要在不同的硬件加速器上。
理想情況下,編譯器是不可見(jiàn)的,一切都會(huì)“正常工作”。然而,我們距離這一點(diǎn)還有很多年。隨著越來(lái)越多的公司希望將 ML 帶到邊緣,并且越來(lái)越多的硬件正在為 ML 模型開(kāi)發(fā),越來(lái)越多的編譯器正在開(kāi)發(fā)以彌合 ML 模型和硬件加速器之間的差距——MLIR、TVM、XLA、 PyTorch Glow、cuDNN 等。 根據(jù) PyTorch 的創(chuàng)建者 Soumith Chintala 的說(shuō)法,隨著 ML 采用的成熟,公司將擇優(yōu)選擇誰(shuí)可以更好地編譯和優(yōu)化他們的模型。
了解編譯器的工作原理可以幫助您選擇正確的編譯器,將模型運(yùn)行在您選擇的硬件上,并診斷性能問(wèn)題并加速您的模型。
ML 的下一個(gè)競(jìng)賽是編譯器(Soumith Chintala,Venture Beat 2020)
這篇文章(希望如此)是對(duì) ML 編譯器的介紹。它始于邊緣計(jì)算,編譯器從系統(tǒng)工程師的領(lǐng)域進(jìn)入了普通 ML 從業(yè)者的領(lǐng)域。
下一部分是關(guān)于在邊緣部署 ML 模型的兩個(gè)主要問(wèn)題:兼容性和性能、編譯器如何解決這些問(wèn)題以及編譯器如何工作。最后提供了一些關(guān)于如何使用幾行代碼顯著加快 ML 模型的資源。
目錄
…… 1. 云計(jì)算與邊緣計(jì)算
…… 2.編譯:兼容性
.... 3. 優(yōu)化:性能
…… 4. 如何優(yōu)化您的 ML 模型
…… 5. 手工設(shè)計(jì)與基于機(jī)器學(xué)習(xí)的編譯器
…… 6. 不同類型的編譯器
…… 7. 編譯器的下一步是什么
1. 云計(jì)算與邊緣計(jì)算
想象一下,您已經(jīng)訓(xùn)練了一個(gè)令人難以置信的 ML 模型,其準(zhǔn)確性超出了您的期望。您很高興能夠部署此模型。
最簡(jiǎn)單的方法是將您的模型打包并通過(guò)托管云服務(wù)(例如 AWS 或 GCP)進(jìn)行部署,云服務(wù)在使公司輕松將 ML 模型投入生產(chǎn)方面做得非常出色。
但是,云部署有很多缺點(diǎn)。首先是成本。ML 模型可能是計(jì)算密集型的,而且計(jì)算成本很高。甚至在 2018 年,像 Pinterest、Infor、Intuit 等大公司每年已經(jīng)在云賬單上花費(fèi)數(shù)億美元 。對(duì)于中小型公司來(lái)說(shuō),這個(gè)數(shù)字每年可能在5 萬(wàn)到200 萬(wàn)美元之間。云服務(wù)的錯(cuò)誤可能導(dǎo)致初創(chuàng)公司破產(chǎn) 。
隨著 AWS 使用量的激增,公司的云賬單
隨著云計(jì)算費(fèi)用的攀升,越來(lái)越多的公司正在尋找將其計(jì)算推向消費(fèi)設(shè)備(邊緣設(shè)備)的方法。在邊緣完成的計(jì)算越多,對(duì)云的需求就越少,他們?yōu)榉?wù)器支付的費(fèi)用也就越少。
除了控制成本外,還有許多特性使邊緣計(jì)算具有吸引力。首先是它允許應(yīng)用程序在云計(jì)算無(wú)法運(yùn)行的地方運(yùn)行。當(dāng)模型位于公共云上時(shí),它們依賴穩(wěn)定的 Internet 連接將數(shù)據(jù)發(fā)送到云并返回。邊緣計(jì)算允許模型在沒(méi)有 Internet 連接或連接不可靠的情況下工作,例如在農(nóng)村地區(qū)或發(fā)展中國(guó)家。
其次,當(dāng)模型已經(jīng)在消費(fèi)者的設(shè)備上時(shí),可以少擔(dān)心網(wǎng)絡(luò)延遲。需要通過(guò)網(wǎng)絡(luò)傳輸數(shù)據(jù)(將數(shù)據(jù)發(fā)送到云上的模型進(jìn)行預(yù)測(cè),然后將預(yù)測(cè)發(fā)送回用戶)可能會(huì)使某些用例變得不可能。在許多情況下,網(wǎng)絡(luò)延遲是比推理延遲更大的瓶頸。例如,可能能夠?qū)?ResNet50 的推理延遲從 30 毫秒減少到 20 毫秒,但網(wǎng)絡(luò)延遲可能高達(dá)數(shù)秒,具體取決于所在的位置。下圖顯示了從佛蒙特州到世界上各個(gè)服務(wù)器中心的網(wǎng)絡(luò)延遲。
Ping 結(jié)果從佛蒙特州到世界各地的服務(wù)器。ping.psa.fun 的結(jié)果
在處理敏感的用戶數(shù)據(jù)時(shí),將模型置于邊緣也很有吸引力。云上的機(jī)器學(xué)習(xí)意味著系統(tǒng)可能必須通過(guò)網(wǎng)絡(luò)發(fā)送用戶數(shù)據(jù),使其容易被攔截。云計(jì)算通常還意味著將多個(gè)用戶的數(shù)據(jù)存儲(chǔ)在同一個(gè)地方,這意味著數(shù)據(jù)泄露會(huì)影響到很多人。據(jù)《安全》雜志 2020 年報(bào)道,近 80% 的公司在過(guò)去 18 個(gè)月中經(jīng)歷了云數(shù)據(jù)泄露。邊緣計(jì)算使遵守有關(guān)如何傳輸或存儲(chǔ)用戶數(shù)據(jù)的法規(guī)(例如 GDPR)變得更加容易。
2.編譯:兼容性
由于邊緣計(jì)算相對(duì)于云計(jì)算具有許多優(yōu)勢(shì),因此公司正在競(jìng)相開(kāi)發(fā)針對(duì)不同 ML 用例進(jìn)行優(yōu)化的邊緣設(shè)備。包括谷歌、蘋果、特斯拉在內(nèi)的老牌公司都宣布了自己制造芯片的計(jì)劃。與此同時(shí),機(jī)器學(xué)習(xí)硬件初創(chuàng)公司已經(jīng)籌集了數(shù)十億美元來(lái)開(kāi)發(fā)更好的人工智能芯片。
人工智能硬件初創(chuàng)公司的一個(gè)子集(Crunchbase 的融資信息)
有了這么多用于運(yùn)行機(jī)器學(xué)習(xí)模型的硬件新產(chǎn)品,一個(gè)問(wèn)題就出現(xiàn)了:我們?nèi)绾问褂萌我饪蚣軜?gòu)建的模型在任意硬件上運(yùn)行?
對(duì)于在硬件上運(yùn)行的框架,它必須得到硬件供應(yīng)商的支持。例如,盡管 TPU 于 2018 年 2 月公開(kāi)發(fā)布,但直到 2020 年 9 月,PyTorch才支持 TPU 。在此之前,如果想使用 TPU,則必須使用 TensorFlow 或 JAX。
在某種類型的硬件(平臺(tái))上為框架提供支持是耗時(shí)且工程密集的。從 ML 工作負(fù)載映射到硬件需要了解并能夠利用硬件的基礎(chǔ)設(shè)施。然而,一個(gè)基本的挑戰(zhàn)是不同的硬件類型具有不同的內(nèi)存布局和計(jì)算原語(yǔ)。.
例如,CPU 的計(jì)算原語(yǔ)曾經(jīng)是一個(gè)數(shù)字(標(biāo)量),GPU 的計(jì)算原語(yǔ)曾經(jīng)是一個(gè)一維向量,而 TPU 的計(jì)算原語(yǔ)是一個(gè)二維向量(張量)。然而,如今許多 CPU 具有向量指令,而一些 GPU 具有二維張量核心。與二維向量相比,一維向量對(duì)一批 256 張圖像 x 3 通道 x 224 W x 224 H 執(zhí)行卷積算子將有很大不同。同時(shí)需要考慮不同的 L1、L2 和 L3 布局和緩沖區(qū)大小以有效地使用它們。
計(jì)算不同硬件后端的原語(yǔ)和內(nèi)存布局
框架開(kāi)發(fā)者往往只專注于為少數(shù)服務(wù)器級(jí)硬件(例如 GPU)提供支持,而硬件供應(yīng)商則傾向于為范圍狹窄的框架提供自己的內(nèi)核庫(kù)(例如 Intel 的 OpenVino 只支持Caffe、TensorFlow、MXNet、Kaldi 和 ONNX。NVIDIA 有 CUDA 和 cuDNN)。將 ML 模型部署到新硬件(例如手機(jī)、嵌入式設(shè)備、FPGA 和 ASIC)需要大量的手動(dòng)工作。
如何在任意硬件后端運(yùn)行使用任意框架構(gòu)建的模型。
中臺(tái)
如果創(chuàng)建一個(gè)中臺(tái)來(lái)橋接框架和平臺(tái),而不是針對(duì)每種新的硬件類型和設(shè)備都針對(duì)新的編譯器和庫(kù)呢?框架開(kāi)發(fā)者將不再需要支持每一種類型的硬件,只需要將他們的框架代碼翻譯成這個(gè)中臺(tái)服務(wù)。那么硬件供應(yīng)商可以支持一個(gè)中間框架而不是支持多個(gè)嗎?
這種類型的“中間人”稱為中間表示(IR)。IR 是編譯器工作方式的核心。根據(jù)模型的原始代碼,編譯器在生成硬件原生代碼以在特定平臺(tái)上運(yùn)行模型之前生成一系列高級(jí)和低級(jí)中間表示。
為了從 IR 生成機(jī)器原生代碼,編譯器通常利用代碼生成器,也稱為代碼生成器。ML 編譯器使用的最流行的代碼生成器是LLVM,由 Vikram Adve 和 Chris Lattner開(kāi)發(fā)。TensorFlow XLA、NVIDIA CUDA 編譯器 (NVCC)、MLIR(用于構(gòu)建其他編譯器的元編譯器)和 TVM 都使用 LLVM。
此過(guò)程也稱為“降低”,因?yàn)閷⒏呒?jí)框架代碼“降低”為低級(jí)硬件本機(jī)代碼。這不是“翻譯”,因?yàn)樗鼈冎g沒(méi)有一對(duì)一的映射。
高級(jí) IR 通常是 ML 模型的計(jì)算圖。對(duì)于熟悉 TensorFlow 的人來(lái)說(shuō),這里的計(jì)算圖類似于您在 TensorFlow 1.0 中遇到的計(jì)算圖,之前 TensorFlow 切換到 Eager Execution。在 TensorFlow 1.0 中,TensorFlow 在運(yùn)行模型之前首先構(gòu)建了模型的計(jì)算圖。此計(jì)算圖允許 TensorFlow 了解模型以優(yōu)化其運(yùn)行時(shí)。
高級(jí) IR 通常與硬件無(wú)關(guān)(不關(guān)心它將在什么硬件上運(yùn)行),而低級(jí) IR 通常與框架無(wú)關(guān)(不關(guān)心模型是用什么框架構(gòu)建的)。
高級(jí) IR 和低級(jí) IR
3.優(yōu)化:性能
在“降低”代碼以將模型運(yùn)行到您選擇的硬件中后,可能會(huì)遇到的一個(gè)問(wèn)題是性能。Codegen 非常擅長(zhǎng)將 IR 降低為機(jī)器代碼,但根據(jù)目標(biāo)硬件后端,生成的機(jī)器代碼可能無(wú)法正常執(zhí)行。生成的代碼可能不會(huì)利用數(shù)據(jù)局部性和硬件緩存,或者可能不會(huì)利用可以加速代碼的高級(jí)功能,例如向量或并行操作。
典型的 ML 工作流由許多框架和庫(kù)組成。例如,可以使用 pandas/dask/ray 從數(shù)據(jù)中提取特征。可以使用 NumPy 來(lái)執(zhí)行矢量化。可以使用 LightGBM 之類的樹(shù)模型來(lái)生成特征,然后使用使用各種框架(如 sklearn、TensorFlow 或 Transformer)構(gòu)建的模型集合進(jìn)行預(yù)測(cè)。
盡管這些框架中的個(gè)別功能可能會(huì)被優(yōu)化,但跨框架幾乎沒(méi)有優(yōu)化。在這些函數(shù)之間移動(dòng)數(shù)據(jù)以進(jìn)行計(jì)算的幼稚方式可能會(huì)導(dǎo)致整個(gè)工作流程的速度下降一個(gè)數(shù)量級(jí)。斯坦福 DAWN 實(shí)驗(yàn)室的研究人員進(jìn)行的一項(xiàng)研究發(fā)現(xiàn),與手動(dòng)優(yōu)化代碼相比,使用 NumPy、Pandas 和 TensorFlow 的典型機(jī)器學(xué)習(xí)工作負(fù)載在一個(gè)線程中的運(yùn)行速度要慢 23 倍(Palkar 等人,'18)。
在生產(chǎn)中通常發(fā)生的是數(shù)據(jù)科學(xué)家/機(jī)器學(xué)習(xí)工程師 pip 安裝他們工作所需的包。事情似乎在開(kāi)發(fā)環(huán)境中運(yùn)行良好,因此他們將模型部署到生產(chǎn)環(huán)境中。當(dāng)他們?cè)谏a(chǎn)中遇到性能問(wèn)題時(shí),他們的公司通常會(huì)聘請(qǐng)優(yōu)化工程師來(lái)為他們運(yùn)行的硬件優(yōu)化他們的模型。
Cruise 優(yōu)化工程師的工作描述
Mythic 優(yōu)化工程師的職位描述
優(yōu)化工程師很難找到,而且招聘成本很高,因?yàn)樗麄冃枰瑫r(shí)具備 ML 和硬件架構(gòu)方面的專業(yè)知識(shí)。優(yōu)化編譯器(也優(yōu)化代碼的編譯器)是一種替代解決方案,因?yàn)樗鼈兛梢宰詣?dòng)化優(yōu)化模型的過(guò)程。在將 ML 模型代碼降級(jí)為機(jī)器代碼的過(guò)程中,編譯器可以查看您的 ML 模型的計(jì)算圖及其包含的運(yùn)算符——卷積、循環(huán)、交叉熵——并找到一種方法來(lái)加速它。
總結(jié)一下目前為止所涵蓋的內(nèi)容,編譯器橋接了 ML 模型和它們運(yùn)行的硬件。優(yōu)化編譯器由兩個(gè)組件組成:降低和優(yōu)化。這兩個(gè)組件不一定是分開(kāi)的。優(yōu)化可以發(fā)生在從高級(jí) IR 到低級(jí) IR 的所有階段。
4. 如何優(yōu)化您的 ML 模型
有兩種方法可以優(yōu)化您的 ML 模型:本地和全局。本地是當(dāng)您優(yōu)化模型的一個(gè)運(yùn)算符或一組運(yùn)算符時(shí)。全局是端到端地優(yōu)化整個(gè)計(jì)算圖時(shí)。
已知有標(biāo)準(zhǔn)的局部?jī)?yōu)化技術(shù)可以加速您的模型,其中大多數(shù)技術(shù)使事物并行運(yùn)行或減少芯片上的內(nèi)存訪問(wèn)。以下是四種常用技術(shù)。
Colfax Research 的循環(huán)平鋪可視化。
Matthias Boehm 的算子融合示例
根據(jù) Weld(另一個(gè)編譯器)的創(chuàng)建者 Shoumik Palkar 的說(shuō)法,這些標(biāo)準(zhǔn)的局部?jī)?yōu)化技術(shù)有望提高約 3 倍的速度。當(dāng)然,這個(gè)估計(jì)是高度依賴于上下文的。
要獲得更大的加速,需要利用計(jì)算圖的更高級(jí)別結(jié)構(gòu)。例如,給定一個(gè)卷積神經(jīng)網(wǎng)絡(luò),計(jì)算圖可以垂直或水平融合,以減少內(nèi)存訪問(wèn)并加速模型。請(qǐng)參閱下面由 NVIDIA 的TensorRT 團(tuán)隊(duì)制作的可視化。
卷積神經(jīng)網(wǎng)絡(luò)計(jì)算圖的縱向和橫向融合
5. 手工設(shè)計(jì)與基于機(jī)器學(xué)習(xí)的編譯器
手工設(shè)計(jì)的規(guī)則
正如上一節(jié)通過(guò)卷積神經(jīng)網(wǎng)絡(luò)的垂直和水平融合所暗示的那樣,有許多可能的方法來(lái)執(zhí)行給定的計(jì)算圖。例如,給定 3 個(gè)運(yùn)算符 A、B 和 C,可以將 A 與 B 融合,將 B 與 C 融合,或者將 A、B 和 C 融合在一起。
傳統(tǒng)上,框架和硬件供應(yīng)商會(huì)聘請(qǐng)優(yōu)化工程師,他們根據(jù)自己的經(jīng)驗(yàn)提出如何最好地執(zhí)行模型計(jì)算圖的啟發(fā)式方法。例如,NVIDIA 可能有一個(gè)工程師或一個(gè)工程師團(tuán)隊(duì)專門研究如何讓 ResNet-50 在他們的 DGX A100 服務(wù)器上真正快速運(yùn)行。(這也是為什么你不應(yīng)該過(guò)多地閱讀MLPerf 的結(jié)果。在某種硬件上運(yùn)行得非常快的流行模型并不意味著任意模型在該硬件上運(yùn)行得非常快。可能只是這個(gè)模型是過(guò)度優(yōu)化)。
手工設(shè)計(jì)的規(guī)則有幾個(gè)缺點(diǎn)。首先是它們不是最佳的。不能保證工程師提出的啟發(fā)式方法是最好的解決方案。
其次,它們是非自適應(yīng)的。在新框架或新硬件架構(gòu)上重復(fù)這個(gè)過(guò)程需要大量的努力。
由于模型優(yōu)化取決于構(gòu)成其計(jì)算圖的一組運(yùn)算符,因此這很復(fù)雜。優(yōu)化卷積神經(jīng)網(wǎng)絡(luò)不同于優(yōu)化循環(huán)神經(jīng)網(wǎng)絡(luò),也不同于優(yōu)化transformer。NVIDIA 和 Google 專注于在其硬件上優(yōu)化 ResNet 和 BERT 等流行模型。但是,作為 ML 研究人員,如果想出一個(gè)新的模型架構(gòu)呢?在被硬件供應(yīng)商采用和優(yōu)化之前,您可能需要自己對(duì)其進(jìn)行優(yōu)化以證明它的速度很快。
使用機(jī)器學(xué)習(xí)加速機(jī)器學(xué)習(xí)模型
目標(biāo)是在所有可能的方法中找到執(zhí)行計(jì)算圖的最快方法。如果嘗試所有可能的方法,記錄他們需要運(yùn)行的時(shí)間,然后選擇最好的方法會(huì)怎樣?
問(wèn)題是有太多可能的方法(路徑)來(lái)探索(組合!),并且嘗試所有方法都被證明是不可行的。如果使用 ML 來(lái):
縮小搜索空間,因此不必嘗試那么多路徑。預(yù)測(cè)一條路徑需要多長(zhǎng)時(shí)間,這樣我們就不必等待整個(gè)計(jì)算圖完成執(zhí)行。估計(jì)通過(guò)整個(gè)計(jì)算圖的路徑運(yùn)行所需的時(shí)間非常困難,因?yàn)樗枰獙?duì)該圖進(jìn)行大量假設(shè)。目前的技術(shù)可能只關(guān)注圖表的一小部分。
如果您在 GPU 上使用 PyTorch,您可能已經(jīng)看到torch.backends.cudnn.benchmark=True. 當(dāng)此設(shè)置為 True 時(shí),將啟用cuDNN 自動(dòng)調(diào)諧。cuDNN 自動(dòng)調(diào)諧搜索一組預(yù)先確定的選項(xiàng)以執(zhí)行卷積算子,然后選擇最快的方式。如果每次迭代都運(yùn)行相同的 convnet 形狀,cuDNN 自動(dòng)調(diào)整會(huì)很有幫助。第一次運(yùn)行卷積算子時(shí)會(huì)很慢,因?yàn)?cuDNN 自動(dòng)調(diào)諧需要時(shí)間來(lái)運(yùn)行搜索。但是在后續(xù)運(yùn)行中,cuDNN 將使用自動(dòng)調(diào)整的緩存結(jié)果來(lái)選擇最快的配置。
cuDNN autotune盡管有效,但僅適用于卷積算子,而且 AFAIK 僅適用于 PyTorch 和 MXNet。一個(gè)更通用的解決方案是autoTVM,它是開(kāi)源編譯器堆棧 TVM 的一部分。autoTVM使用子圖而不僅僅是運(yùn)算符,因此它使用的搜索空間要復(fù)雜得多。autoTVM 的工作方式非常復(fù)雜,但要點(diǎn)如下:
- 它首先將計(jì)算圖分解為子圖。它預(yù)測(cè)每個(gè)子圖有多大。它分配時(shí)間為每個(gè)子圖搜索最佳路徑。它縫合了將每個(gè)子圖運(yùn)行在一起以執(zhí)行整個(gè)圖的最佳方式。
autoTVM 測(cè)量運(yùn)行每條路徑所需的實(shí)際時(shí)間,這為其提供了地面實(shí)況數(shù)據(jù)以訓(xùn)練成本模型以預(yù)測(cè)未來(lái)路徑將花費(fèi)多長(zhǎng)時(shí)間。這種方法的優(yōu)點(diǎn)在于,因?yàn)槟P褪鞘褂眠\(yùn)行時(shí)生成的數(shù)據(jù)進(jìn)行訓(xùn)練的,所以它可以適應(yīng)它運(yùn)行的任何類型的硬件。缺點(diǎn)是成本模型需要更多時(shí)間才能開(kāi)始改進(jìn)。
與 cuDNN 在 NVIDIA TITAN X 上的 ResNet-50 相比,
基于 ML 的 TVM 提供的加速。基于 ML 的 TVM 需要約 70 次試驗(yàn)才能勝過(guò) cuDNN。
TVM 的成本模型如何運(yùn)作
像 TVM 這樣的編譯器是自適應(yīng)的、靈活的,當(dāng)您想嘗試新硬件時(shí)尤其有用。一個(gè)例子是蘋果在 2020 年 11 月發(fā)布了他們的 M1 芯片。M1是基于ARM的片上系統(tǒng),ARM架構(gòu)或多或少都比較好理解。但是,M1 的 ARM 實(shí)現(xiàn)仍然有很多新穎的組件,需要進(jìn)行大量?jī)?yōu)化才能使各種 ML 模型在其上快速運(yùn)行。發(fā)布一個(gè)月后,OctoML 的人們表明,autoTVM 所做的優(yōu)化比 Apple 的 Core ML 團(tuán)隊(duì)手工設(shè)計(jì)的優(yōu)化快了近 30%. 當(dāng)然,隨著 M1 的成熟和手工優(yōu)化變得密集,自動(dòng)優(yōu)化將很難擊敗手工優(yōu)化。但系統(tǒng)工程師可以利用 autoTVM 等工具來(lái)加速優(yōu)化。
雖然自動(dòng)調(diào)整的結(jié)果令人印象深刻,但它們有一個(gè)問(wèn)題:TVM 可能很慢。遍歷所有可能的路徑并找到最優(yōu)化的路徑。對(duì)于復(fù)雜的 ML 模型,此過(guò)程可能需要數(shù)小時(shí)甚至數(shù)天。但是,這是一次性操作,您的優(yōu)化搜索結(jié)果可以緩存并用于優(yōu)化現(xiàn)有模型并為未來(lái)的調(diào)整會(huì)話提供一個(gè)起點(diǎn)。您為一個(gè)硬件后端優(yōu)化一次模型,然后在同一后端的多個(gè)設(shè)備上運(yùn)行它。當(dāng)您有一個(gè)準(zhǔn)備好用于生產(chǎn)的模型并且目標(biāo)硬件可以運(yùn)行推理時(shí),這種優(yōu)化是理想的。
6. 不同類型的編譯器
最廣泛使用的編譯器類型是由主要框架和硬件供應(yīng)商開(kāi)發(fā)的針對(duì)特定框架和硬件組合的特定領(lǐng)域編譯器。不出所料,最受歡迎的產(chǎn)品是由最大的供應(yīng)商開(kāi)發(fā)的。
一般而言,第三方編譯器非常雄心勃勃(例如,您必須非常自信地認(rèn)為您可以比 NVIDIA 更好地針對(duì) GPU 進(jìn)行優(yōu)化)。但是第三方編譯器很重要,因?yàn)樗鼈冇兄诮档托驴蚣堋⑿乱淮布⑿履P偷男阅荛_(kāi)銷,讓小玩家有機(jī)會(huì)與擁有自己的編譯器針對(duì)現(xiàn)有產(chǎn)品進(jìn)行大量調(diào)整的老牌玩家競(jìng)爭(zhēng)。
最好的第三方編譯器是 Apache TVM,它適用于各種框架(包括 TensorFlow、MXNet、PyTorch、Keras、CNTK)和各種硬件后端(包括 CPU、服務(wù)器 GPU、ARM、x86、移動(dòng) GPU 和基于 FPGA 的加速器)。
另一個(gè)令人興奮的項(xiàng)目是MLIR,它最初也是由 Chris Lattner(LLVM 的創(chuàng)建者)在 Google發(fā)起的。但是,它現(xiàn)在屬于 LLVM 組織。MLIR 并不是一個(gè)真正的編譯器,而是一個(gè)元編譯器,構(gòu)建自己的編譯器的基礎(chǔ)設(shè)施。MLIR 可以運(yùn)行多個(gè) IR,包括 TVM 的 IR,以及 LLVM IR 和 TensorFlow 圖。
WebAssembly (WASM)
WASM 是過(guò)去幾年中最令人興奮的技術(shù)趨勢(shì)之一。它性能卓越、易于使用,并且擁有一個(gè)像野火一樣不斷發(fā)展的生態(tài)系統(tǒng)。截至 2021 年 9 月,全球 93% 的設(shè)備都支持它。
我們一直在討論編譯器如何為模型生成機(jī)器原生代碼以在某些硬件后端上運(yùn)行。如果我們想生成一些可以在任何硬件后端上運(yùn)行的代碼怎么辦?
使用了舊瀏覽器。如果可以在瀏覽器中運(yùn)行模型,就可以在任何支持瀏覽器的設(shè)備上運(yùn)行您的模型:Macbook、Chromebook、iPhone、Android 手機(jī)等。無(wú)需關(guān)心這些設(shè)備使用什么芯片。如果蘋果決定從英特爾芯片轉(zhuǎn)向 ARM 芯片,那不是你的問(wèn)題!
WebAssembly 是一個(gè)開(kāi)放標(biāo)準(zhǔn),允許瀏覽器中運(yùn)行可執(zhí)行程序。在 sklearn、PyTorch、TensorFlow 或您使用的任何框架中構(gòu)建模型后,您以將模型編譯為 WASM,而不是編譯模型以在特定硬件上運(yùn)行。你會(huì)得到一個(gè)可執(zhí)行文件,你可以只用 Javascript 來(lái)使用它。
WASM 的主要缺點(diǎn)是因?yàn)?WASM 在瀏覽器中運(yùn)行,所以速度很慢。盡管 WASM 已經(jīng)比 Javascript 快得多,但與在設(shè)備(例如 iOS 或 Android 應(yīng)用程序)上本地運(yùn)行代碼相比,它仍然很慢。Jangda 等人的一項(xiàng)研究。顯示編譯為 WASM 的應(yīng)用程序運(yùn)行速度比原生應(yīng)用程序平均慢 45%(在 Firefox 上)到 55%(在 Chrome 上)。
有許多編譯器可以幫助您編譯為 WASM。最流行的可能是 Emscripten(它也使用 LLVM 代碼生成器),但它只能從 C 和 C++ 編譯成 WASM。scailable應(yīng)該可以從 scikit-learn 模型轉(zhuǎn)換為 WASM,但它在 GitHub 上只有 13 顆星,而且在過(guò)去 3 個(gè)月內(nèi)沒(méi)有更新(它甚至還在維護(hù)嗎?)。TVM 是我所知道的唯一一個(gè)從ML 模型編譯為 WASM 的活動(dòng)編譯器。
提示:如果決定試用 TVM,請(qǐng)使用他們的非官方 conda/pip 命令進(jìn)行快速安裝(https://tlcpack.ai/)。如果需要幫助,他們只有一個(gè) Discord 服務(wù)器!
https://discord.com/invite/8jNs8MkayG
7. 編譯器的下一步是什么
考慮模型如何在不同的硬件后端上運(yùn)行,這樣可以提高它們的性能。Austin Huang在我們的MLOps Discord上發(fā)帖稱,他經(jīng)常通過(guò)使用簡(jiǎn)單的現(xiàn)成工具(量化工具、Torchscript、ONNX、TVM)而無(wú)需太多努力就可以實(shí)現(xiàn) 2倍的加速。
這里有一個(gè)很棒的技巧列表,可以在 GPU 上加速 PyTorch 模型,甚至無(wú)需使用編譯器。
當(dāng)模型準(zhǔn)備好部署時(shí),有必要嘗試不同的編譯器,看看哪一個(gè)能給您帶來(lái)最佳的性能提升。可以并行運(yùn)行這些實(shí)驗(yàn)。一個(gè)推理請(qǐng)求的小幅提升可以累積成數(shù)百萬(wàn)或數(shù)十億推理請(qǐng)求的大回報(bào)。
盡管用于機(jī)器學(xué)習(xí)的編譯器已經(jīng)取得了巨大的進(jìn)步,但在我們完全從一般 ML 從業(yè)者那里抽象出編譯器之前,還有很多工作要做。想想像 GCC 這樣的傳統(tǒng)編譯器。您使用 C 或 C++ 編寫代碼,GCC 會(huì)自動(dòng)將您的代碼降低為機(jī)器代碼。大多數(shù) C 程序員甚至不關(guān)心 GCC 生成什么中間表示。
未來(lái),機(jī)器學(xué)習(xí)編譯器可以采用同樣的方式。您使用框架以計(jì)算圖的形式創(chuàng)建 ML 模型,您的 ML 編譯器可以為您運(yùn)行的任何硬件生成機(jī)器原生代碼。您甚至無(wú)需擔(dān)心中間表示。
TVM 之類的工具是使未來(lái)成為可能的步驟。