Numba是一個(gè)適用于Python代碼的開(kāi)源式即時(shí)編譯器。借助該編譯器,開(kāi)發(fā)者可以使用標(biāo)準(zhǔn)Python函數(shù)在CPU和GPU上加速數(shù)值函數(shù)。
什么是NUMBA?
為了提高執(zhí)行速度,Numba會(huì)在執(zhí)行前立即將Python字節(jié)代碼轉(zhuǎn)換為機(jī)器代碼。
Numba可用于使用可調(diào)用的Python對(duì)象(稱為修飾器)來(lái)優(yōu)化CPU和GPU功能。修飾器是一個(gè)函數(shù),它將另一個(gè)函數(shù)作為輸入,進(jìn)行修改,并將修改后的函數(shù)返回給用戶。這種模組化可減少編程時(shí)間,并提高Python的可擴(kuò)展性。
Numba還可與NumPy結(jié)合使用,后者是一個(gè)復(fù)雜數(shù)學(xué)運(yùn)算的開(kāi)源Python庫(kù),專為處理統(tǒng)計(jì)數(shù)據(jù)而設(shè)計(jì)。調(diào)用修飾器時(shí),Numa將Python和/或NumPy代碼的子集轉(zhuǎn)換為針對(duì)環(huán)境自動(dòng)優(yōu)化的字節(jié)碼。它使用LLVM,這是一個(gè)面向API的開(kāi)源庫(kù),用于以編程方式創(chuàng)建機(jī)器原生代碼。Numba針對(duì)各種CPU和GPU配置,提供了多種快速并行化Python代碼的選項(xiàng),有時(shí)僅需一條命令即可。與NumPy結(jié)合使用時(shí),Numba會(huì)為不同的數(shù)組數(shù)據(jù)類型和布局生成專用代碼,進(jìn)而優(yōu)化性能。
為何選擇NUMBA?
Python是一種廣泛應(yīng)用于數(shù)據(jù)科學(xué)的高效動(dòng)態(tài)編程語(yǔ)言。由于其采用簡(jiǎn)潔明了的語(yǔ)法,并具有標(biāo)準(zhǔn)數(shù)據(jù)結(jié)構(gòu)、全面的標(biāo)準(zhǔn)庫(kù)、高水準(zhǔn)的文檔、龐大的庫(kù)和工具生態(tài)系統(tǒng)以及大型開(kāi)放社區(qū),因此深受歡迎。不過(guò),也許最重要的原因是,Python等動(dòng)態(tài)型態(tài)解釋語(yǔ)言能夠帶來(lái)超高效率。
但是,對(duì)于Python來(lái)說(shuō),這既是最大的優(yōu)勢(shì),也是最大的劣勢(shì)。“它的靈活性和無(wú)類型的高級(jí)語(yǔ)法可能會(huì)導(dǎo)致數(shù)據(jù)和計(jì)算密集型程序的性能不佳,因?yàn)檫\(yùn)行本地編譯代碼要比運(yùn)行動(dòng)態(tài)解釋代碼快很多倍。因此,注重效率的Python程序員通常會(huì)使用C語(yǔ)言重寫(xiě)最內(nèi)層的循環(huán),然后從Python調(diào)用已編譯的C語(yǔ)言函數(shù)。許多項(xiàng)目都力求簡(jiǎn)化這種優(yōu)化(例如Cython),但它們通常需要學(xué)習(xí)新的語(yǔ)法。雖然Cython顯著提高了性能,但可能需要對(duì)Python代碼進(jìn)行艱巨的手動(dòng)修改工作。
Numba被視作Cython的替代方案,并且要簡(jiǎn)單得多。它最大的吸引力在于無(wú)需學(xué)習(xí)新的語(yǔ)法,也無(wú)需替換Python解釋器、運(yùn)行單獨(dú)的編譯步驟或安裝C/C++編譯器。只需將@jitNumba修飾器應(yīng)用于Python函數(shù)即可。這樣,在運(yùn)行時(shí)即可進(jìn)行編譯(即“即時(shí)”或JIT編譯)。Numba能夠動(dòng)態(tài)編譯代碼,這意味著,您還可以享受Python帶來(lái)的靈活性。此外,Python程序中由Numba編譯的數(shù)值算法,可以接近使用編譯后的C語(yǔ)言或FORTRAN語(yǔ)言編寫(xiě)的程序的速度;并且與原生Python解釋器執(zhí)行的相同程序相比,運(yùn)行速度最多快100倍。這是一項(xiàng)重要進(jìn)步,推動(dòng)了高效編程與高性能計(jì)算的完美結(jié)合。
Numba執(zhí)行圖
Numba專為面向數(shù)組的計(jì)算任務(wù)而設(shè)計(jì),與應(yīng)用廣泛的NumPy庫(kù)類似。在面向數(shù)組的計(jì)算任務(wù)中,數(shù)據(jù)并行性與GPU等加速器自然契合。Numba理解NumPy數(shù)組類型,并將其用于生成高效的編譯代碼,以在GPU或多核CPU上執(zhí)行。所需的編程工作非常簡(jiǎn)單,只需添加一個(gè)@vectorize函數(shù)修飾器,指示Numba在運(yùn)行時(shí)生成編譯的向量化函數(shù)版本。這樣,它便可用于在GPU上并行處理數(shù)據(jù)數(shù)組了。
除了為CPU或GPU即時(shí)編譯NumPy數(shù)組代碼外,Numba還公開(kāi)了“CUDAPython”:這是適用于NVIDIAGPU的NVIDIA?CUDA?編程模型,采用Python語(yǔ)法編寫(xiě)。加速Python后,它可以從膠水語(yǔ)言擴(kuò)展至可高效執(zhí)行數(shù)字代碼的完整編程環(huán)境。
Numba與Python數(shù)據(jù)科學(xué)生態(tài)系統(tǒng)中其他工具的結(jié)合使用,改變了GPU計(jì)算的體驗(yàn)。JupyterNotebook提供基于瀏覽器的文檔創(chuàng)建環(huán)境,允許結(jié)合使用Markdown文本、可執(zhí)行代碼以及繪圖和圖像的圖形輸出。Jupyter在教學(xué)、記錄科學(xué)分析和交互式原型設(shè)計(jì)領(lǐng)域深受歡迎。
Numba已在200多種不同的平臺(tái)配置下進(jìn)行了測(cè)試。它基于Intel和AMDx86、POWER8/9、ARMCPU以及NVIDIA和AMDGPU上的Windows、AppleMacintosh、Linux操作系統(tǒng)運(yùn)行,大多數(shù)系統(tǒng)均可使用預(yù)編譯的二進(jìn)制文件。
用例
科學(xué)計(jì)算
數(shù)組處理應(yīng)用廣泛,從地理信息系統(tǒng)到計(jì)算復(fù)雜的幾何形狀,無(wú)一不及。電信公司使用數(shù)組來(lái)優(yōu)化無(wú)線網(wǎng)絡(luò)的設(shè)計(jì),而醫(yī)療健康研究人員則使用數(shù)組分析包含內(nèi)臟器官信息的波形。數(shù)組還可用于減少語(yǔ)言處理、天文成像和雷達(dá)/聲納中的外部噪聲。
有了Python等語(yǔ)言,開(kāi)發(fā)者無(wú)需進(jìn)行大量數(shù)學(xué)訓(xùn)練,即可使用這些領(lǐng)域的應(yīng)用程序。但是,Python在數(shù)值密集型計(jì)算中存在性能缺陷,這會(huì)嚴(yán)重影響某些應(yīng)用程序的處理速度。Numba是其中一個(gè)解決方案。許多人都認(rèn)為它易于使用,因此對(duì)于沒(méi)有C語(yǔ)言等比較復(fù)雜語(yǔ)言經(jīng)驗(yàn)的學(xué)生和開(kāi)發(fā)者來(lái)說(shuō),意義重大。
NUMBA對(duì)數(shù)據(jù)科學(xué)家的重要意義
在數(shù)據(jù)科學(xué)中,迭代開(kāi)發(fā)是一種非常實(shí)用的省時(shí)方案,因?yàn)殚_(kāi)發(fā)者能夠通過(guò)觀察結(jié)果來(lái)不斷地改進(jìn)程序。Python等解釋語(yǔ)言在這種情景中尤為有用。但是,Python在高度數(shù)學(xué)運(yùn)算中存在性能限制,這可能會(huì)造成瓶頸,從而減緩整體處理速度并限制開(kāi)發(fā)者的工作效率。
Numba為開(kāi)發(fā)者提供了一種調(diào)用編譯器函數(shù)的簡(jiǎn)單方法,顯著提升了大型計(jì)算和數(shù)組的性能,從而解決了這一問(wèn)題。Numba簡(jiǎn)單易學(xué),并使數(shù)據(jù)科學(xué)家無(wú)需執(zhí)行使用編譯語(yǔ)言編寫(xiě)子程序這一復(fù)雜任務(wù),從而加快速度。
NUMBA為何可在GPU上表現(xiàn)更突出
在架構(gòu)方面,CPU僅由幾個(gè)具有大緩存內(nèi)存的核心組成,一次只可以處理幾個(gè)軟件線程。相比之下,GPU由數(shù)百個(gè)核心組成,可以同時(shí)處理數(shù)千個(gè)線程。
Numba通過(guò)以下方式支持CUDAGPU編程:在CUDA執(zhí)行模型后,直接將受限的Python代碼子集編譯到CUDA內(nèi)核函數(shù)和設(shè)備函數(shù)中。使用Numba編寫(xiě)的內(nèi)核看起來(lái)可以直接訪問(wèn)NumPy數(shù)組,而這些數(shù)組在CPU和GPU之間自動(dòng)傳輸。這為Python開(kāi)發(fā)者提供了一個(gè)輕松進(jìn)行GPU加速計(jì)算的方法,而且無(wú)需學(xué)習(xí)新語(yǔ)法或語(yǔ)言,即可學(xué)會(huì)如何應(yīng)用日益復(fù)雜的CUDA編碼。借助CUDAPython和Numba,您可以一舉兩得:使用Python實(shí)現(xiàn)快速迭代開(kāi)發(fā),同時(shí)達(dá)到針對(duì)CPU和NVIDIAGPU的編譯語(yǔ)言的速度。
我們使用配備NVIDIAP100GPU和IntelXeonE5-2698v3CPU的服務(wù)器進(jìn)行了一次測(cè)試,結(jié)果顯示,使用Numba編譯的CUDAPythonMandelbrot代碼比只使用Python快了近1700倍。與CPU上的單線程Python代碼相比,性能提升是多個(gè)因素的共同作用,包括編譯、并行化和GPU加速。但是,它說(shuō)明單是添加一個(gè)GPU即可實(shí)現(xiàn)加速。
NVIDIAGPU加速的端到端數(shù)據(jù)科學(xué)
基于CUDA-XAI創(chuàng)建的NVIDIARAPIDS?開(kāi)源軟件庫(kù)套件使您完全能夠在GPU上執(zhí)行端到端數(shù)據(jù)科學(xué)和分析流程。此套件依靠NVIDIACUDA基元進(jìn)行低級(jí)別計(jì)算優(yōu)化,但通過(guò)用戶友好型Python接口實(shí)現(xiàn)了GPU并行化和高帶寬顯存速度。
借助RAPIDSGPUDataFrame,數(shù)據(jù)可以通過(guò)一個(gè)類似Pandas的接口加載到GPU上,然后用于各種連接的機(jī)器學(xué)習(xí)和圖形分析算法,而無(wú)需離開(kāi)GPU。這種級(jí)別的互操作性可通過(guò)ApacheArrow等庫(kù)實(shí)現(xiàn),并有助于實(shí)現(xiàn)端到端流程(從數(shù)據(jù)準(zhǔn)備到機(jī)器學(xué)習(xí)再到深度學(xué)習(xí))的加速。
RAPIDS支持在許多熱門(mén)數(shù)據(jù)科學(xué)庫(kù)之間共享設(shè)備內(nèi)存。這樣可將數(shù)據(jù)保留在GPU上,并省去了來(lái)回復(fù)制主機(jī)內(nèi)存的高昂成本。
RAPIDS團(tuán)隊(duì)正在開(kāi)發(fā)和參與許多開(kāi)源項(xiàng)目,并與眾多開(kāi)源項(xiàng)目(包括ApacheArrow、Numba、XGBoost、ApacheSpark、scikit-learn等)密切協(xié)作,確保GPU加速數(shù)據(jù)科學(xué)生態(tài)系統(tǒng)中的所有組件順暢地協(xié)同工作。
*本文轉(zhuǎn)自NVIDIA英偉達(dá)