【PyTorch】Windows10にPyTorchを導入してGPUの演算性能を評価する
自分用のメモ。
LinuxマシンとかAWSとかではやっているのをよく見かけるPyTorchのGPU利用ですが、Windows10の場合はどうするんだろう、と調べて実際にやってみた記録。
参考にしたのはこちら。
環境
- Windows10 64bit
- Core i7-6700HQ 2.60GHz 2.60GHz 4Core
- RAM16GB
- GeForce GTX 950M
- VRAM 2GB
5年前位に買ったWindows10マシンで、当時はスペックが良い方だったのだけれど、今となってはやや見劣りする感じ。
実行環境はこんな感じ。
- Anaconda
- Python 3.7.1
- Jupyter Lab
準備
Visual Studio Community2019をインストール
まずはVisual Studioが必要とのこと。インストールは下記より。
Visual Studioそのものを使う、というよりはそのなかのコンポーネントがCUDAを動かすのに必要、ということらしい。
CUDAをインストール
上記リンクからCUDAの最新版をインストールする。
たぶん最新版のが良いのじゃないかな、と思う。ちなみに現時点での最新版は10.1 update 2になっている。下の画像のように自分の環境をポチポチしていってダウンロードすれば良い。
自分はnetworkにしました。localにするとかなり巨大な.exeをダウンロードするので。networkでも大して時間はかからず。10分かからないくらいだったかな?
PyTorchをインストール
PyTorchのインストール方法を上記から選択する。
今回はPython3.7、CUDA10.1、condaでのインストールなので上のような設定になる。するとRun This commandのところに良い感じにインストール用のコマンドが表示されるので、これを実行すれば良い。
conda install pytorch torchvision cudatoolkit=10.1 -c pytorch
pipだろうがcondaだろうが、インストールできればOKなのだけれど、すでにCUDA対応でないPyTorchをインストールしている場合はやり直した方が良い。
性能評価
チュートリアルのサンプルコードを実行する
チュートリアルにある2番目のコードで試してみた。
コードにある通り、バッチサイズ64、入力層のノード数1000、隠れ層のノード数100、出力層のノード数10、活性化関数にReLUを使うシンプルなネットワーク。
なお、実行時間を計測するため、timeライブラリを使い、forループの前後で時間を計測した。
まずはCPUの結果から。
99 350.2883605957031 199 1.6243224143981934 299 0.015767984092235565 399 0.0004199870745651424 499 6.515638960991055e-05 elapsed_time:0.3560447692871094[sec]
実行時間は0.36秒程度。
次に、コードの一部を変更してGPUで実行する。
99 339.7377014160156 199 0.7344891428947449 299 0.003484970424324274 399 0.00013160801609046757 499 3.048904000024777e-05 elapsed_time:1.5827696323394775[sec]
ん?CPUの方が速い?
GPUの演算性能に影響を与える因子
結論から言うと、上のURLにあるように、並列計算できる分量が多ければ多いほど、GPUの性能が際立ってくる。逆に一回当たりの演算の並列化量が少なく、forループなどの並列化できない箇所が多いと、CPUの方が演算速度が速くなる。
上記のテストコードの場合、入力層から隠れ層への行列演算が
(64×1000)(1000×100)
のサイズの行列の積であった。人間が計算するには大きな行列だけれど、GPUから見たらこのサイズは小さくて十分に並列化できない、ということらしい。
なので、テストコードをいじって、行列演算のサイズを変えてみた。
- 入力ノードを増やす
N, D_in, H, D_out = 64, 3500, 100, 10として入力ノードのサイズを変え、積を計算する行列を大きくしてみた。
CPUの結果
99 2738.1865234375 199 1301.2371826171875 299 940.7708129882812 399 786.500732421875 499 706.3295288085938 elapsed_time:1.023407220840454[sec]
GPUの結果
99 14849.46875 199 3840.01416015625 299 1686.515625 399 968.605224609375 499 664.8519287109375 elapsed_time:0.963533878326416[sec]
わずかにGPUの方が速い結果となった。
- バッチ数を減らし、入力ノードと隠れ層のノードを増やす
N, D_in, H, D_out = 8, 10000, 200, 10とした。バッチサイズ64のままで入力ノードを10000にするとうまく実行できなかったのでこの設置としている。
CPUの結果
99 840.8685302734375 199 198.62562561035156 299 103.77583312988281 399 74.15234375 499 61.467132568359375 elapsed_time:3.577970504760742[sec]
GPUの結果
99 241.82785034179688 199 86.19084930419922 299 82.44027709960938 399 82.34451293945312 499 82.33955383300781 elapsed_time:1.187114953994751[sec]