使用Python玩轉GPU

問題

隨着機器學習對模型運算速度的需求越來越強烈,
一直想進行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 n卡
scipy cupy n卡
pandas cudf & modin n卡 無(自動)
sklearn cuml & scikit-cuda n卡 無(自動)

目前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框架出現,不斷的加速自動化的進程
讓更多的生產力能從原始的輪子中解放出來,加快人工智能的進化!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章