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をコピーしました