如何將Numpy加速700倍?用 CuPy 呀

2021-01-11 機器之心Pro

選自towardsdatascience

作者:George Seif

機器之心編譯

參與:杜偉、張倩

作為 Python 語言的一個擴展程序庫,Numpy 支持大量的維度數組與矩陣運算,為 Python 社區帶來了很多幫助。藉助於 Numpy,數據科學家、機器學習實踐者和統計學家能夠以一種簡單高效的方式處理大量的矩陣數據。那麼 Numpy 速度還能提升嗎?本文介紹了如何利用 CuPy 庫來加速 Numpy 運算速度。

就其自身來說,Numpy 的速度已經較 Python 有了很大的提升。當你發現 Python 代碼運行較慢,尤其出現大量的 for-loops 循環時,通常可以將數據處理移入 Numpy 並實現其向量化最高速度處理。

但有一點,上述 Numpy 加速只是在 CPU 上實現的。由於消費級 CPU 通常只有 8 個核心或更少,所以並行處理數量以及可以實現的加速是有限的。

這就催生了新的加速工具——CuPy 庫。

何為 CuPy?

CuPy 是一個藉助 CUDA GPU 庫在英偉達 GPU 上實現 Numpy 數組的庫。基於 Numpy 數組的實現,GPU 自身具有的多個 CUDA 核心可以促成更好的並行加速。

CuPy 接口是 Numpy 的一個鏡像,並且在大多情況下,它可以直接替換 Numpy 使用。只要用兼容的 CuPy 代碼替換 Numpy 代碼,用戶就可以實現 GPU 加速。

CuPy 支持 Numpy 的大多數數組運算,包括索引、廣播、數組數學以及各種矩陣變換。

如果遇到一些不支持的特殊情況,用戶也可以編寫自定義 Python 代碼,這些代碼會利用到 CUDA 和 GPU 加速。整個過程只需要 C++格式的一小段代碼,然後 CuPy 就可以自動進行 GPU 轉換,這與使用 Cython 非常相似。

在開始使用 CuPy 之前,用戶可以通過 pip 安裝 CuPy 庫:

pip install cupy

使用 CuPy 在 GPU 上運行

為符合相應基準測試,PC 配置如下:

i7–8700k CPU1080 Ti GPU32 GB of DDR4 3000MHz RAMCUDA 9.0

CuPy 安裝之後,用戶可以像導入 Numpy 一樣導入 CuPy:

import numpy as npimport cupy as cpimport time

在接下來的編碼中,Numpy 和 CuPy 之間的切換就像用 CuPy 的 cp 替換 Numpy 的 np 一樣簡單。如下代碼為 Numpy 和 CuPy 創建了一個具有 10 億 1』s 的 3D 數組。為了測量創建數組的速度,用戶可以使用 Python 的原生 time 庫:

### Numpy and CPUs = time.time()*x_cpu = np.ones((1000,1000,1000))*e = time.time()print(e - s)### CuPy and GPUs = time.time()*x_gpu = cp.ones((1000,1000,1000))*e = time.time()print(e - s)

這很簡單!

令人難以置信的是,即使以上只是創建了一個數組,CuPy 的速度依然快得多。Numpy 創建一個具有 10 億 1』s 的數組用了 1.68 秒,而 CuPy 僅用了 0.16 秒,實現了 10.5 倍的加速。

但 CuPy 能做到的還不止於此。

比如在數組中做一些數學運算。這次將整個數組乘以 5,並再次檢查 Numpy 和 CuPy 的速度。

### Numpy and CPUs = time.time()*x_cpu *= 5*e = time.time()print(e - s)### CuPy and GPUs = time.time()*x_gpu *= 5*e = time.time()print(e - s)

果不其然,CuPy 再次勝過 Numpy。Numpy 用了 0.507 秒,而 CuPy 僅用了 0.000710 秒,速度整整提升了 714.1 倍。

現在嘗試使用更多數組並執行以下三種運算:

數組乘以 5數組本身相乘數組添加到其自身

### Numpy and CPUs = time.time()*x_cpu *= 5x_cpu *= x_cpux_cpu += x_cpu*e = time.time()print(e - s)### CuPy and GPUs = time.time()*x_gpu *= 5x_gpu *= x_gpux_gpu += x_gpu*e = time.time()print(e - s)

結果顯示,Numpy 在 CPU 上執行整個運算過程用了 1.49 秒,而 CuPy 在 GPU 上僅用了 0.0922 秒,速度提升了 16.16 倍。

數組大小(數據點)達到 1000 萬,運算速度大幅度提升

使用 CuPy 能夠在 GPU 上實現 Numpy 和矩陣運算的多倍加速。值得注意的是,用戶所能實現的加速高度依賴於自身正在處理的數組大小。下表顯示了不同數組大小(數據點)的加速差異:

數據點一旦達到 1000 萬,速度將會猛然提升;超過 1 億,速度提升極為明顯。Numpy 在數據點低於 1000 萬時實際運行更快。此外,GPU 內存越大,處理的數據也就更多。所以用戶應當注意,GPU 內存是否足以應對 CuPy 所需要處理的數據。

原文連結:https://towardsdatascience.com/heres-how-to-use-cupy-to-make-numpy-700x-faster-4b920dda1f56

本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。

相關焦點

  • Numpy應用整理
    現在幾乎各種應用場合都會用到numpy,主要有以下幾個原因:numpy提供了很多數值計算和常用算法的函數numpy歸功了很多線性代數的相關操作numpy的執行效率高首先導入numpy庫import numpy as np常規列表應用用numpy建的列表類型都是ndarray,因此我們首先來看np.array
  • Numpy學習打卡task01
    【1】numpy開源地址:https://github.com/numpy/numpynumpy的局限在數組中插入或追加條目並不像使用 Python 的 list 那樣簡單。用於擴展數組的 np.pad(...) 例程實際上創建了具有所需形狀和填充值的新數組,將給定數組複製到新數組中並返回。
  • 用Numpy手寫各種距離度量
    本文用Numpy實現了常見的幾種距離度量。
  • Numpy學習打卡task03
    第一波浪潮在世紀之交,由Francis Galton和Karl Pearson的工作引領,他們將統計學轉變為一門嚴謹的數學學科,不僅用於科學領域,也用於工業和政治領域的分析。Galton的貢獻包括引入標準差、相關、回歸分析的概念,並將這些方法應用於研究人類的各種特徵--身高、體重、睫毛長度等。
  • Numpy高級操作大全!!!
    該函數需要兩個參數:– numpy.expand_dims(arr, axis)– 其中:import numpy as npx = np.array(([1, 2], [3, 4]))print(x)y = np.expand_dims(x, axis=0)print(y)print(x.shape, y.shape)y
  • Numpy入門教程:10. 統計相關
    axis:坐標軸的方向,一維的就不用考慮了,多維的就用這個調整計算的維度方向,取值範圍0/1。【例】計算加權平均值(將各數值乘以相應的權數,然後加總求和得到總體值,再除以總的單位數。)y = np.var(x, axis=1)print(y)  # [2. 2. 2. 2. 2.]numpy.std(a[, axis=None, dtype=None, out=None, ddof=0, keepdims=np.
  • Python中的Numpy基礎20問
    import numpy as np# 創建二維數組x2 = np.array([[1,2,3],[4,5,6]])# 將x2轉換為三維數組,並且自定義每個軸的元素數量x2.resize((1,2,3))x2'''輸出:array([[[1, 2, 3],[4, 5, 6]]])'''如何對數組進行索引和切片操作?numpy一維數組的索引和切片操作類似python列表,這裡不多講。
  • 如何在Core i5 上實現 20 倍的 Python 運行速度?
    以「加速」為核心的它,相比原生 Python 環境有多大提升呢?並行計算專家、前英特爾高級工程師 James Reinders 對老東家的產品進行了測試。他對外宣布:在配備四核 i5 的 iMAC 上實現了 20 倍的性能加速!
  • 如何在 i5 上實現 20 倍的 Python 運行速度?
    他對外宣布:在配備四核 i5 的 iMAC 上實現了 20 倍的性能加速!至於他是怎麼做到的,請繼續往下看(含代碼)。James ReindersJames Reinders:利用 Intel Distribution for Python,我實現了 Python 的 20 倍加速,並且可用單個命令關閉/啟用。
  • Numpy學習打卡task02
    2019年10月,有學者指出,與經典的偽隨機數發生器(PRNGs)方法相比,將量子隨機數發生器(QRNGs)引入到包括神經網絡和卷積神經網絡在內的機器學習模型中,用於隨機初始權重分布和隨機森林的拆分過程,對其能力產生了深遠的影響。均勻分布在0和1之間的隨機數可以通過所需分布的逆累積分布函數(CDF)來產生任何所需分布的隨機數(見逆變換抽樣)。逆CDF也被稱為分位函數。
  • 值得收藏的 NumPy 小抄表(含主要語法、代碼)
    兩者數據科學最重要的區別是能夠用NumPy數組進行元素級計算。1, 2, axis)沿著數組0軸或者1軸插入數據項https://docs.scipy.org/doc/numpy/reference/generated/numpy.insert.htmlnp.resize((2,4))將數組調整為形狀(2,4)https://docs.scipy.org/doc/numpy/reference/generated/numpy.resize.htmlnp.delete
  • 為什麼要學Numpy,一文總結知識點
    :my_arr[0:2]用字典的方式查詢列:my_arr['age']按條件做篩選:my_arr[my_arr["age"] >= 29]對異構數據的操作一般用pandas更容易處理數組的操作數據查詢基礎索引:X[:2, 2:4]神奇索引:x[[3,4,7]]布爾索引:x[x>5]怎樣增加一個維度arr[np.newaxis, :]np.expand_dims(arr, axis=0)np.reshape
  • 簡約而不簡單|值得收藏的Numpy小抄表(含主要語法、代碼)
    多為很多大型金融公司使用,以及核心的科學計算組織如:Lawrence Livermore,NASA用其處理一些本來使用C++,Fortran或Matlab等所做的任務。兩者數據科學最重要的區別是能夠用NumPy數組進行元素級計算。
  • 「It's my cup of tea」不是「這是我的茶」!說錯虧大了
    你好呀,我是Ada ! 昨天Ada上班的時候發現桌子上出現了一套新的杯子,私心想著:這是哪位帥哥哥送的情侶杯,直接放到桌子上,萬一被人看見了,這多不好意思呀。
  • Python學習第119課——numpy中的broadcasting
    這節課我們學習numpy中的數據的一個多變的特性--broadcasting,broadcasting的官方的說明比較麻煩,我們這裡把它簡化一下,就把它當做「腦補」的意思。我們舉例來說明。例:運行結果:從上例中,我們看到,x的「形狀」是3行2列,y的「形狀」是1行2列,之前我們學習numpy中的四則運算,所舉的例子中,兩個數組都是相同的「形狀」,在相加的時候每個數組對應位置上的元素分別相加,形成新的數組。
  • 數據科學中100個Numpy代碼技巧
    下面的100個練習都是從numpy郵件列表、stack overflow和numpy文檔中收集的。1.以np的名稱導入numpy包(★☆☆)import numpy as np2.列印numpy版本和配置(★☆☆)print(np.
  • Python中NumPy簡介及使用舉例
    it = iter(x); print(it) ## 使用迭代器創建ndarray, fromiter函數從任何可迭代對象構建一個ndarray對象,返回一個新的一維數組y = np.fromiter(it, dtype=float); print(y) # [0. 1. 2. 3. 4.]
  • Python學習第114課——numpy中ndarray的四則運算
    我們為什麼要學習numpy?numpy其實就是number+Python的簡寫,意思就是通過Python對數據進行處理。要對數據進行處理,就少不了最基本的加減乘除等操作。這節我們學習numpy中數組的一些基本的四則運算。●numpy中數組的加法運算我們首先生成x和y兩個float類型的數組,然後把它們進行相加。
  • Python學習第116課——numpy.dot和矩陣相乘的數學運算
    關於numpy中數組的相乘,我們學習了對位相乘(用numpy.multiply、或*直接相乘,比如數組a和b的對位相乘就是numpy.multiply(a,b)或a*b)和一維數組的點乘(dot product,也有人叫inner product,比如一維數組a和b的點乘就是a.b)。
  • Python學習第117課——numpy中dot的運用舉例
    閒話少敘,我們對numpy中的矩陣相乘做一些舉例說明。我們還是使用上節的兩個矩陣為例。上節我們用手寫推導矩陣相乘過程如下:我們現在用代碼演示一下numpy中的矩陣相乘。我們知道如果兩個數組都是2維以上才能用矩陣相乘。用代碼生成兩個2行2列的數組x和y(跟我們手寫推導時的矩陣x和y結構一樣,都是2行2列),然後進行矩陣相乘。