6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

numpyでGPUを使用する方法と、CPUとの実行時間比較について

Last updated at Posted at 2022-04-03

実行環境

OS: Windows 11
Python: 3.10.2 (インストール済みであることを前提します)

実験条件

スクリプト、使用法等はこれ以外の環境でも同様のはずです。ただしCUDAはGeForceのGPUでないと使えません。
CPU: intel corei7 11700F (ハイエンド(?))
GPU: GeForce GTX1650(4GB) (ローエンド(?))

注意

筆者は一介の学部生です。GPU等について認識が誤っている部分があるかもしれません。
誤り、誤植等ありましたら、ご指摘よろしくお願いいたします。

GPUの利用方法

1.CUDA(GeForce Experience)のインストール

公式サイトからCUDA11.6のインストーラをダウンロード。Installer TypeはLocalで大丈夫です。インストーラをダウンロード後、exeファイルを実行して指示に従ってインストールを進めます。基本的には推奨設定のまま進めて大丈夫だと思います。

2.GPUに適したドライバをインストール

このページからお使いのGPUに適したドライバをインストールしましょう。
ダウンロードタイプについてですが、大雑把にGameReadyはゲーム用(速度優先)、studioはグラフィック処理の精度優先だそうです。筆者もあまり詳しくありませんので、詳細は他の方の記事にお任せします。筆者はとりあえずGameReadyの方をインストールしました。
インストーラをダウンロード後、exeファイルを実行して同様に指示に従って進めます。GeForce Experienceはインストール済みのはずですので、ドライバーのみインストールの方で大丈夫です。

3.numpyとcupyのpipインストール(ローカル環境に入れたくない場合はvenv等の仮想環境を利用できます)
pip install cupy-cuda116
pip install numpy

pip install cupyと書いてある記事が複数ありますが、筆者の環境では失敗しました。
CUDAのバージョンによって適宜116の部分を書き換える(例えば10.1の場合cupy-cuda101)必要があるようです。(すべてのバージョンについて確認したわけではありません。)

cupyはnumpyのほとんどの関数に対応しているようですので、以下のように変更することで簡単にGPUを用いた実行が可能です。

CPU
import numpy as np
arr = np.random.random_sample((10, 10)) 
GPU
import cupy as cp
arr = cp.random.random_sample((10, 10)) 

では最後に、GPUとCPUに速度勝負をさせてみましょう。お題は逆行列計算です。

test.py

import numpy as np
import cupy as cp
import time

def test(size,num=1):
    start=time.time()#時間計測開始
    print(f"size:{size},num:{num}")
    for i in range(num):
        arr = np.random.random_sample((size, size)) #size次の乱数行列生成
        rev = np.linalg.inv(arr) #逆行列計算
    end=time.time()#時間計測終了
    print(f"cpu:{round(end-start,8)}sec")

    start=time.time()#時間計測開始
    for i in range(num):
        arr = cp.random.random_sample((size, size)) #size次の乱数行列生成
        rev = cp.linalg.inv(arr)#逆行列計算
    end=time.time()#時間計測終了
    print(f"gpu:{round(end-start,8)}sec")

Size=[10,10,100,1000,2000,5000,10000]
Num=[5000,5000,500,50,25,10,5]

for s,n in zip(Size,Num):
    test(s,n)

上のプログラムを用いて、行列のサイズと計算回数を適宜変化させて実験しました。
以下の動画は、プログラムをコマンドプロンプトから実行した際のタスクマネージャの様子です。
CPUとGPUが交代で動いている様子がわかっていただけると思います。

ezgif.com-gif-maker (1).gif

以下の表に実験結果を示します。各値は、各サイズの乱数行列についての逆行列の平均計算時間です。
比の値が1以上であれば、GPUの方が高速に計算を実行できたことを示します。

行列サイズ CPU:Corei7 11700 (sec) GPU:GTX1650 (sec) 比(CPU/GPU)
10 0.00018624 0.00029849 0.624
10 0.00018572 0.00016565 1.121
100 0.00522239 0.00090294 5.784
1000 0.08481761 0.05751644 1.475
2000 0.26992218 0.30537095 0.884
5000 1.76327453 3.504635 0.503
10000 10.22772169 7.51856899 1.360

最初に行列サイズを10として実行したときのGPUの実行時間がやや長くなっていますが、これはGPUの起動にかかる時間の影響を含んでいると考えられます。全体としてややGPUの方が速いという印象を受けましたが、行列サイズによっては必ずしもそうではないようです。

何度か実験を行いましたが、サイズが100の時にはGPUが圧倒的に優位であり、サイズが2000の時には拮抗、5000のときにはCPUの方が優位となり、サイズ10000で再びGPUの方が速くなる、という傾向は変化しませんでした。なお、サイズ20000の行列をそのまま計算させようとすると、筆者の環境のGPUではメモリ不足でエラーとなってしまいました。

今回はPython、中でもNumpyで書かれたプログラムをGPUで実行する方法と、CPUとGPUの逆行列計算の実行時間の比較を行いました。Python環境とGPUを積んだPCがあれば簡単に実行できますので、ぜひ試してみてください。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?