はじめに
こんにちは。技術開発チームの矢澤です。
皆さんは、GPUを使ったことがありますか? 最近の画像処理などの機械学習アルゴリズムでは、学習データやモデルパラメーターの数が膨大になっているため、限られた時間で試行錯誤を行うためにはGPUが必須となってきています。
技術開発チームでもこの度、モデル検証や社外ツール調査などのR&D用途として、GPU付きのノートPC(俗に言うゲーミングPC)を購入することとなりました。 普段は、既に環境構築済みの分析サーバーや仮想マシンなどで業務を行なっているため、当たり前のようにGPUを使っていましたが、自分で一から環境構築を行おうとするとなかなか大変なことが分かりました。 そこで今回は、自身のハマりポイントを踏まえながら、Windows PCでGPUを使うための環境構築方法を紹介したいと思います。
マシンについて
今回購入したGPU付きマシンは、MSI製の以下のノートPCです。
https://jp.msi.com/Laptop/PS42_8RC
価格の割に性能が高いのに加え、本体が非常に軽いため持ち運びに便利だと思い、購入を決めました。
※ セキュリティリスクを考えて、今回購入したマシンは社内ネットワークに接続せず、個人情報を一切入れないことを想定しています。
内蔵GPUとして、NvidiaのGeForce® GTX 1050というものが付いています。 GPUの種類としては、他にも業務用のTESLAシリーズなどがあり、またGeForceシリーズの中でも様々なラインナップがあります。 本マシンは、GTX 1050によって比較的高速に計算を行うことが可能ですが、GPUのメモリが4GBしか無いため、そのままではサイズの大きいニューラルネットワークモデルなどを読み込むことができません(これについては後ほど説明します)。
元々はWindowsのPCですが、OSごと入れ替えてLinuxマシンとして使用することもできると思います。 しかし、普段の業務で使用しているマシンがMacやLinuxであるため、今回はWindowsの使い方や環境構築方法などを勉強したいと思い、あえてそのままでGPUの環境構築を行いました。 Linuxの場合、Nvidia Docker というツールを利用してホストのGPUをコンテナで使うこともできますが、Windowsではそのようなことができないため、今回はDockerを使わずにAnacondaで仮想環境を作っています。
環境構築(失敗編)
ここから具体的にGPU環境の構築方法を説明していくのですが、初めに自分が失敗した方法について話したいと思います(成功編については、記事の後半で説明します。)。 新たに環境構築を行なってみようという方は、本記事を反面教師として参考にしていただければ幸いです。
WindowsでGPUを使って機械学習モデルを動かすためには、最低限以下のようなツールをインストールする必要があります。
- CUDA
- cuDNN
- (Anaconda)
- Python
- TensorFlow
始めに自分が考えたのは、「新しいバージョンのツールほど機能が豊富なのだから、全て最新のバージョンをインストールすれば良いのではないか?」ということでした。 そのため、特にバージョンを気にせず、現時点での最新バージョンを順にインストールしていくこととしました。
CUDAのインストール
CUDAとは、NVIDIAが開発しているGPU向けの汎用並列演算プラットフォームとプログラミングモデルのことです。
NVIDIAの公式HPのページから、該当するOSやインストール方法を選択します。 上述したように、今回は特に深く考えず、最新のバージョン(10.2)をインストールしました。
インストール方法は「ネットワーク」と「ローカル」の二つがありますが、今回はネットワークに接続できる環境だったので「ネットワーク」を選びました。 ダウンロードが完了すると、インストーラーが起動するので、画面の指示に従って進んでいきます。
無事にインストールが完了したら、ターミナルで以下のコマンドを実行することで、バージョンを確認できます。
nvcc -V
ターミナルの最後の行に「Cuda compilation tools, release 10.2, V10.2.89」などと表示されれば、正しくインストールが行われています。
cuDNNのインストール
続いて、深層学習用のGPU高速化ライブラリであるcuDNNをインストールします。 cuDNNも、NVIDIAの公式ページからダウンロードすることができます(アカウント登録が必要です)。
https://developer.nvidia.com/rdp/cudnn-download
CUDAのバージョンやOSごとに対応するパッケージが用意されているので、先ほどインストールしたCUDA 10.2向けのcuDNN(v7.6.5)の中から、Windows 10向けのものを選択します。
zipファイルとしてダウンロードされるので、解凍してCUDAのプログラム内にある同名のファイルとディレクトリごと入れ替えます。 CUDAのプログラムは、インストーラーでデフォルトの場所を選択していれば、以下にあるかと思います。
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2
これでCUDAとcuDNNのインストールが完了し、ホストマシンでGPUを使えるようになりました。
Anacondaのインストール
続いて、Anacondaの環境構築を行います。 既に知っている方も多いかもしれませんが、AnacondaはPythonでデータ分析を行うためのプラットフォームです。
今回Anacondaを使う理由は、pyenvやDockerの代わりとして仮想環境を作成するためです。 例えば「あるプロジェクトではPython3.8を使用し、別のプロジェクトではPython3.7を使用したい」といった場合に、ホストPCに直接Pythonをインストールし直すと面倒です。 Anacondaを使用することで、このようなPythonのバージョンなどが異なる環境を、簡単に切り替えられるようになります。
ダウンロードは、公式HPから行うことができます。
Python3とPython2の二つのバージョンがあるので、Python3の該当するOS(今回はWindows 64-Bit)向けのインストーラーをダウンロードします。
EXEファイルを実行し、画面の指示に従って進んでいくと、Anacondaがインストールされます。 スタートメニューに「Anaconda3 (64-bit)」などが追加されていれば、インストールは無事に行われています。
Pythonの環境構築
Anacondaのインストールが完了したらAnaconda Promptを起動し、Pythonの仮想環境を構築します。 Pythonのバージョンは、現在の最新である3.8とします。
以下のコマンドを実行すると、「GPUTest」という名前のPython3.8の入った環境が作成されます。
conda create -n GPUTest python=3.8
作成した仮想環境の一覧は、
conda info -e
で確認できます。
さらに、今作った環境を有効化します(仮想マシンの中に入るようなイメージです)。
conda activate GPUTest
プロンプトの左端が(base)から(GPUTest)に変わったら成功です。
有効化したら、念のためPython3.8が入っていることを確認しておきましょう。
python -V
TensorFlowのインストール
続いて上記の仮想環境に、機械学習プラットフォームであるTensorFlowをインストールします。 深層学習でよく使われるものとしては、他にもKerasやPyTorchなどがあり、それらのプラットフォームで実装されたプログラムを動かしたい場合や、自身で開発を行いたい場合は、別途ライブラリのインストールが必要です。
TensorFlowのバージョンには、大きく分けて1系と2系があります。 今回は、試してみたいプログラムが1系で書かれたものだったので、1系の最新バージョンであるTensorFlow 1.15をインストールしました。
※ TensorFlow 1系のソースコードを2系に変換できるツールなども用意されていますが、完全に自動変換できるわけではないため、今回は使用していません。
TensorFlow 1.xでは、パッケージがCPU版とGPU版とで分かれており、以下のように tensorflow-gpu を指定することでGPU版をインストールできます。
pip install tensorflow-gpu==1.15
完了したら、pip freeze コマンドを実行し、インストール済みのパッケージ一覧に tensoflow-gpu==1.15 があることを確認します。
動作確認
次に、TensorFlowで実際にGPUを使えるかどうかを確認します。 プロンプトでPythonを対話モードで起動し、以下のコマンドを入力します。
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
表示されるデバイス一覧に「GPU」があればOKなのですが、ここでエラーが発生しました。 その後、Web上の情報などを基に原因を調査した結果、TensorFlowではバージョンごとに対応するCUDA, cuDNN, Pythonなどのバージョンが決まっており、適切なバージョンのツールを使用しないと正しく動かないことが分かりました。
バージョンの対応表は、以下のページの「テスト済みのビルド設定」に載っています。
ちなみに、現時点での自分の環境はこのようになっていました。
- CUDA: 10.2
- cuDNN: 7.6
- Python: 3.8
- TensorFlow: 1.15
対応表には何故かtensorflow_gpu-1.15.xの情報がありませんが(2系への移行期間であったため?)、最もバージョンの近い1.14や2.0でもCUDA 10, cuDNN 7.4, Python 3.5~3.7でしか動作確認されていません。 今回構築した環境では、この対応バージョンよりも新しいツールを使用していたため、うまく動かなかったようです。 そこで、適切なバージョンのものをインストールし直すこととしました。
環境構築(成功編)
上記の失敗を踏まえ、使用したいTensorFlowのバージョン(1.15)に対応するツールを再インストールします。 インストールするバージョンは、以下のようになります。
- CUDA: 10.0
- cuDNN: 7.4
- Python: 3.7
- TensorFlow: 1.15
インストール方法などは、既に説明した方法と特に変わりません。 ただし、CUDA 10.0のみインストーラーの置き場を見つけるのに苦労したため、共有しておきます(アーカイブのページにあります)。
正しいバージョンのCUDA, cuDNN, Pythonで環境を構築し、再び確認用のコマンドを実行したところ、無事TensorFlowでGPUを認識することができました。
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
GPUの利用に成功!しかし・・
この環境で、Gitを使用してTensorFlowのプログラムをダウンロードし、学習済みのモデルを動かそうとしたところ、今度は以下のようなエラーが表示されました。
ResourceExhaustedError: OOM when allocating tensor with shape ...
このメッセージは、モデルの実行に必要なだけのGPUメモリを確保できなかったことを意味しています。 最近の複雑な深層学習ネットワークでは、大体1モデル当たり5~10GB程度のメモリを使用する印象があります。 それに対して、今回購入したマシンはGPUのメモリが4GBしか無いため、ハードウェア的にプログラムを実行するのが不可能ということが分かりました。
ただし、基本的なモデル(畳み込み層が3つ程度のもの)であれば、動かすことは可能です。 実際に画像分類用の小さなモデルを自分で組んで学習してみたところ、1エポックあたりの学習時間は以下のようになりました。
- GPUなし:28秒
- GPUあり:256秒
なんとGPUを使うことで、計算速度が1/10程度になってしまいました。 nvidia-smi コマンドで確認すると、GPUありの場合のみメモリを消費しているので、確かに利用できているはずなのですが・・
処理が遅くなった原因としては、使用できるメモリに余裕が無いため、GPUの恩恵をあまり受けることができなかったことが考えられます。 または、今回購入したマシンはCPUのスペックが比較的高いため、CPUだけでも十分な速度を出すことができたのかもしれません。
終わりに
今回は、GPU付きWindows PCの環境構築を行い、TensorFlowでGPUを使えるようにするまでの方法を紹介しました。
冒頭でも少し説明しましたが、LinuxではAnadoncaの代わりにNvidia Dockerを活用して、ホストのGPUを共有したまま仮想環境のみを切り分けることなども可能です。 また、GPU内蔵モバイルデバイスのJetsonのように、CUDAやcuDNNなどのツールがあらかじめパッケージ化されて配布されている場合もあります。 今後は、そのような別の環境でもGPUを使ってみて、環境構築方法の違いや利便性などを実感したいと思います。