天天看點

使用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
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架構出現,不斷的加速自動化的程序

讓更多的生産力能從原始的輪子中解放出來,加快人工智能的進化!