[Python #26] numpyとcupyを比較

はじめまして。

新しくpythonチームに参加しました。A.Sです。

私は現在、愛知県の大学に通っている大学4年生で、情報学を専攻しています。授業で習った知識を生かして何かできたらいいなと思い、インターンに参加しました。

今回は、pythonのライブラリであるnumpyとcupyの紹介をしたいと思います。

Numpy

Numpyは、数値計算を効率的に行うためのライブラリです。多次元配列を扱うための関数が多く用意されています。

https://numpy.org/

インストールにはpipやcondaを使います。

https://numpy.org/ja/install/

Cupy

Cupyは、NVIDIA GPUで演算することを前提にした計算ライブラリで、Numpyと高い互換性を持ちます。

NumpyはCPU上での計算に特化している一方で、CupyはGPU上での計算に特化しており、大規模な演算を高速に行うことができます。

https://cupy.dev/

なお、cupyを使用するには、NVIDIA GPUが使用できること、CUDAToolkitをインストールしていることなどが必要です。

インストールにはpipやcondaを使います。下はcudaのversionが12.xの場合のコマンド例です。

https://docs.cupy.dev/en/stable/install.html

比較

まずはnumpyとcupyを、それぞれnp、cpとしてインポートします。

import numpy as np
import cupy as cp

続いてサイズの大きい行列(今回は10000×10000)をランダムに生成します。ここで、numpyで計算するものはnumpy.ndarray型、cupyで計算するものはcupy.ndarray型で生成します。

n_array = np.random.random_sample((10000, 10000))
c_array = cp.random.random_sample((10000, 10000))

今回は生成した行列の積を計算してその時間を計測してみます。AとBの行列積は、numpy.dot(A, B)とcupy.dot(A, B)で計算することができます。時間の計測にはtimeモジュールを使用しました。

np.dot(n_array, n_array)
cp.dot(c_array, c_array)

プログラムの全体は以下の通りです。numpyで行列を生成して積をとるときのコードと、cupyで行列を生成して積をとるときのコードが非常に似ていることが分かると思います。

import numpy as np
import cupy as cp
import time

#大規模な行列の生成
n_array = np.random.random_sample((10000, 10000))
c_array = cp.random.random_sample((10000, 10000))

#numpyを使った計算
s_time = time.time()
np.dot(n_array, n_array)
e_time = time.time()
print(f"numpyでの計算時間: {e_time-s_time}")

#cupyを使った計算
s_time = time.time()
cp.dot(c_array, c_array)
e_time = time.time()
print(f"cupyでの計算時間: {e_time-s_time}")

実際に実行してみます。Jupyter notebook上で実行しています。

numpyを用いた際の計算には約140秒かかっていますが、cupyを用いた計算には約0.025秒しかかかっていません。

つまり、numpyで計算したものよりcupyで計算したものの方が5000倍以上はやく実行できています。

おわりに

今回はnumpyとcupyについて紹介し、両者について比較を行いました。

cupyを使うことで、簡単にGPUを使った演算が可能になります。

ただ、使っているGPUの性能や使う場面によってはnumpyを使った方が早くなる場合もあるので、気になった方はぜひ調べてみてください。

参考

https://numpy.org/doc/stable/reference/random/generated/numpy.random.rand.html

https://docs.cupy.dev/en/stable/reference/generated/cupy.random.rand.html