問題
随着機器學習對模型運算速度的需求越來越強烈,
一直想進行GPU程式設計,但一直以來這些都是c++的專利
一想到c++裡的各種坑,就提不起勁來,畢竟這樣來來回回填坑的投入産出,生産效率就會大打折扣
解決方案
讓人欣喜的是,随着Python陣營的不斷發展壯大,使用python進行GPU程式設計也越來越便捷了
那麼具體有些什麼樣的包,能針對GPU做些啥事呢?
看看一些具體的代碼,就能大概明白:
首先是pycuda,這是它的一個例子:
mod = SourceModule("""
__global__ void multiply_them(float *dest, float *a, float *b)
{
const int i = threadIdx.x;
dest[i] = a[i] * b[i];
}
""")
由上面的代碼我們可以看出,pycuda将調用gpu的c++代碼做了包裝,可以在python裡直接使用
再看看numba:
@cuda.jit
def increment_by_one(an_array):
pos = cuda.grid(1)
if pos < an_array.size:
an_array[pos] += 1
我們可以發現,numba更進一步,直接使用裝飾器的辦法讓調用GPU的過程更簡潔友善
再看看cupy:
import numpy as np
import cupy as cp
x_gpu = cp.array([1, 2, 3])
l2_gpu = cp.linalg.norm(x_gpu)
cupy的調用方法看起來更加簡單清晰,直接将np替換為cp即可
比較
是以,從機器學習全流程的角度我做了下彙總:
原始架構 | GPU替代包 | 支援GPU | C/C++核函數 | 表達式核函數 | 裝飾器 & Python |
---|---|---|---|---|---|
cuda | pycuda | n卡 | √ | × | |
opencl | pyopencl | n卡 + a卡 | |||
numpy | numba | ||||
scipy | cupy | ||||
pandas | cudf & modin | 無(自動) | |||
sklearn | cuml & scikit-cuda |
目前cupy和numba對numpy的支援都不全面,可兩者結合使用
從上面可以看出,基本上已經涵蓋了機器學習的全流程,大部分包隻支援cuda,主要都是為友善使用n卡加速
部分包還是隻能使用c/c++語言建構核函數,主要還是受限于cuda驅動的capability
是以實際使用門檻并沒有降低,隻是将核函數包裝到python裡使用
GPU的主要優勢在于大規模的并行計算,是以我又收集了一些并行計算架構,友善日後使用
架構 | CPU并行計算 | 分布式并行計算 | GPU并行計算 |
---|---|---|---|
Multiprocess | |||
joblib | |||
dask | |||
ray |
至于機器學習/深度學習架構,那就更不用說了:
xgboost已經開始支援GPU,RandomForest也有GPU的版本,
tensorflow, pytorch預設就是支援GPU的,這裡就不再贅述
結論
沒有架構時,我們希望有效率的python包能快速解決問題,可架構多了,又會出現選擇困難症
各種架構都宣稱自己效率高,靈活好用,各種benchmark也讓人眼花缭亂,目不暇接
到底用哪個架構合适,我把自己的一些經驗也總結下,希望能讓大家少踩一些坑:
1.對于一般的并行計算任務,使用joblib就能友善完成;
2.對于需要叢集或GPU的計算任務,可以選擇dask或ray;
這裡推薦下dask,dask于機器學習/深度學習的計算包結合的更緊密,推出了dask_ml用于處理分布式機器學習;
3.如果想快速遷移numpy/pandas的代碼到gpu,可以使用cupy + cudf的組合方式;
4.如果有複雜自定義的計算以及為了追求性能,可以使用pycuda + numba的形式;
5.對于numpy的替換到底選用cupy還是numba?
這裡沒有嚴格的界限,兩者對GPU的調用方式設計,實際都會有一定的編碼成本
從cupy的基本例子中可以看出,對于部分調用來說cupy更簡潔,但是犧牲了cpu并行和分布式并行的功能為代價
是以目前可以持續關注這兩個架構
6.對于替換pandas到底選用cudf還是modin?
modin本身并不是專為cuda并行化而設計,它隻是底層支援了dask和ray,由此間接的支援了GPU
且到目前為止對pandas方法的支援還不全面,是以這裡推薦選擇cudf
思考
總之,python作為機器學習的首選語言,正在不斷的開疆拓土,不斷的降低并行計算的門檻
短短幾年前,還隻能用xgboost + spark的方式進行分布式訓練,轉眼現在就有了多種python解決方案
短短幾年前,還隻能用c++ cuda的方式進行GPU程式設計,轉眼現在也有了多種純python的架構支援
短短幾年前,将GPU進行叢集化、虛拟化管理幾乎是不可能的,轉眼現在也有了可靠的解決方案
……
但是,到目前為止,還沒有一款真正能充分智能化的利用并行能力計算的架構:它能綜合cpu+gpu+分布式的計算能力,目标就是為了加速計算,得到結果。期待這樣的架構誕生!
相信不久的将來,會有更多更強大的python架構出現,不斷的加速自動化的程序
讓更多的生産力能從原始的輪子中解放出來,加快人工智能的進化!