Numpy・SciPy高速化のためにCuPyのインストール【Python】

Numpy・SciPy高速化のためにCuPyのインストール【Python】 プログラミング

「Numpyを高速化したい」
「SciPyを高速化したい」
「Pythonでの演算処理を速くしたい」

Pythonで処理を高速化したい場合が、多々あるでしょう。
機械学習はもちろん、単純な集計処理でもそのような需要はあります。

そういった場合、ロジックの見直しは効果があります。
しかし、それだけでは限界が来てしまいます。

そのような場合に、GPUの利用は効果的です。
Pythonであれば、CuPyが選択肢の一つとなります。

本記事の内容

  • CuPyとは?
  • CuPyのシステム要件
  • CuPyのインストール
  • CuPyの動作確認

それでは、上記に沿って解説していきます。

CuPyとは?

CuPyは、PythonでGPUアクセラレーションコンピューティングを行うためのライブラリです。
簡単に言うと、CuPyはGPUをPythonから利用するためのライブラリと言えます。

では、GPUを利用したらどんないいことがあるのでしょうか?
「処理(演算)速度が高速になる」という恩恵があります。
それを示しているのが、次のグラフです。

各処理において、どれほどスピードアップするのかを示しています。
処理によっては、200倍ほどの高速化を実現することも可能のようです。

CuPyを使えば、処理が高速化できるのはわかりました。
でも、その使い方が手間であったら、積極的に使おうとは思いません。

CuPyは、そこもカバーしてくれています。
CuPyには、次のライブラリと高い互換性があります。

  • Numpy
  • SciPy

両方とも、Pythonでは超メジャーなライブラリです。

互換性をコードで表現すると、次のようになります。

置き換え前置き換え後
numpycupy
scipycupyx.scipy

上記の対応に従ってコードを書き換えるだけのようです。
これだけであれば、一括置換も可能かもしれません。

最後に、CuPyが対象にしているGPUについて説明しておきます。

GPUと言っても、GPUにはいろいろメーカーのモノがあります。
CuPyが対象にしているのは、NVIDIA製GPUとなります。

そして、NVIDIAはGPUを操作できるためのツールキットを公開しています。
そのツールキットが、CUDAです。

よって、CuPyはCUDAを経由してGPUにアクセスします。
CuPyという名称は、CUDAとPythonを合体させたモノだと推測しています。
本当のところは、わかりませんけどね。

以上、CuPyについて説明しました。
次は、CuPyのシステム要件を確認します。

CuPyのシステム要件

現時点(2021年8月末)でのCuPyの最新バージョンは、9.4.0となります。
この最新バージョンは、2021年8月26日にリリースされています。
高い頻度で更新が行われています。

CuPyのシステム要件は、以下の点を確認しましょう。

  • OS
  • Python
  • CUDA

それぞれを下記で説明します。

OS

サポートOSに関しては、以下となります。

  • Windows
  • Ubuntu
  • CentOS

macOSは、対象外ということです。
そもそも、CUDAがNVIDIA製GPU向けですからね。

Python

サポート対象となるPythonのバージョンは以下。

  • Python 3.6
  • Python 3.7
  • Python 3.8
  • Python 3.9

以下は、Pythonの公式開発サイクルとなります。

バージョンリリース日サポート期限
3.62016年12月23日2021年12月
3.72018年6月27日2023年6月
3.82019年10月14日2024年10月
3.92020年10月5日2025年10月

更新頻度が高いだけあって、公式開発サイクル通りの対応状況です。
CuPyは、安心して利用できるライブラリと言えますね。

古いPythonを使っているなら、Pythonのアップグレードも考えましょう。
次の記事では、Pythonのアップグレードについてまとめています。

CUDA

CuPyではなくてはならないモノになります。
今回は、Windowsを対象に説明します。

Windowsであれば、知らず知らずにインストールしている可能性があります。
そこで、現状を確認します。

まず、コマンドプロンプトかPowerShellのどちらかを起動させます。
そして、次のコマンドを入力して実行します。

nvcc -V 

CUDAがインストールされていれば、次のように表示されます。

>nvcc -V 
nvcc: NVIDIA (R) Cuda compiler driver 
Copyright (c) 2005-2020 NVIDIA Corporation 
Built on Mon_Oct_12_20:54:10_Pacific_Daylight_Time_2020 
Cuda compilation tools, release 11.1, V11.1.105 
Build cuda_11.1.relgpu_drvr455TC455_06.29190527_0

CUDAがインストールされていない場合は、コマンド自体がエラーとなります。
「そんなはコマンドはありません」というエラーですね。

CUDAのインストールについては、次の記事で解説しています。

CUDAのバージョンについては、CUDA 11.1をおススメしておきます。
現在(2021年8月末)であれば、最新のGPU版PyTorchでCUDA11.1がサポートされています。

なお、CuPyは以下のバージョンに対応しています。

何でも来い状態ですね。
もちろん、CUDA 11.1も対応しています。

以上、CuPyのシステム要件について説明しました。
次は、CuPyをインストールしていきます。

CuPyのインストール

まずは、現状のインストール済みパッケージを確認しておきます。

>pip list 
Package    Version 
---------- ------- 
pip        21.2.4 
setuptools 57.4.0

次にするべきことは、pipとsetuptoolsの更新です。
pipコマンドを使う場合、常に以下のコマンドを実行しておきましょう。

python -m pip install --upgrade pip setuptools

では、CuPyのインストールです。
ここでCUDAのバージョンが必要になります。

「nvcc -V」で調べた結果ですね。
私の環境では、CUDA 11.1でした。

したがって、次のようなコマンドになります。

pip install cupy-cuda111

インストールは、すぐに終わります。
では、どんなパッケージがインストールされたのかを確認しましょう。

>pip list 
Package      Version 
------------ ------- 
cupy-cuda111 9.4.0 
fastrlock    0.6 
numpy        1.21.2 
pip          21.2.4 
setuptools   57.4.0

Numpyもインストールされるのですね。
でも、依存するパッケージは多くはありません。
その意味では、既存環境にも気軽にCuPyを導入できそうです。

以上、CuPyのインストールの説明でした。
最後に、CuPyの動作確認を行います。

CuPyの動作確認

CuPyの動作を確認します。
ただ、単純に動いただけなら、正直よくわかりません。

そこで、CPUとGPUの処理を比較するコードを用意しました。
プログラムの内容は、コメントを見てください。

```
import cupy as cp 
import numpy as np 
import random 
import time 

a = [random.randint(0, 100) for i in range(10000000)] 
b = [random.randint(0, 100) for i in range(10000000)] 

# 時間計測開始 
cpu_time_start = time.time() 
# 処理 
ab = np.dot(a, b) 
# 時間計測終了 
cpu_time_end = time.time() 
# 時間計測 
cpu_time = cpu_time_end - cpu_time_start 
print("【CPU】" + str(ab) + " time:" + str(cpu_time)) 
# GPU 0上にnumpy配列を転送 
with cp.cuda.Device(0): 
    a_gpu = cp.asnumpy(a) 
    b_gpu = cp.asnumpy(b) 
    # 時間計測開始 
    gpu_time_start = time.time() 
    # 処理 
    ab_gpu = cp.dot(a_gpu, b_gpu) 
    # 時間計測終了 
    gpu_time_end = time.time() 
    # 時間計測 
    gpu_time = gpu_time_end - gpu_time_start 
    print("【GPU】" + str(ab_gpu) + " time:" + str(gpu_time))
```

上記を実行した結果は、以下。

【CPU】-765111046 time:1.0377445220947266 
【GPU】-765111046 time:0.005981922149658203

1次元配列を二つ用意して、その内積を求める演算を実行しています。
その演算をCPUとGPUのそれぞれで実施しています。

演算結果が、一致していることがわかります。
ここで注目すべきは、それぞれの処理時間(time)です。

上記の結果だけで言うと、約173倍の差があります。
もちろん、GPUの方が圧倒的に高速です。
200倍の高速化は、決して誇張ではないのかもしれません。

CuPyの動作確認としては、これで十分だと思います。

以上、CuPyの動作確認を説明しました。

タイトルとURLをコピーしました