機械学習の勉強でTensorflowをCPU環境で動かしていたけど、GPU環境で動かすとどれくらい変わるのか確かめたかった、程度だけど思ったより色々とハードルがあったので今後のためのメモ
GCPで挫折
初期登録時に無料枠があったので、最初にGCPを試した。
CPUインスタンスでサンプルが動いたのでGPUインスタンスを立ち上げようとしたら
Quota 'GPUS_ALL_REGIONS' exceeded. Limit: 0.0 globally
とお断りされた
ここを見るとリソースの割り当てを要求しないといけないらしい
ということで、GPU1個要求したら
Unfortunately, we are unable to grant you additional quota at this time. If
this is a new project please wait 48h until you resubmit the request or
until your Billing account has additional history.
と言われて即お断りされた
48時間待ってもう一度リクエストしても無料枠の一部を別のインスタンスで消費してからリクエストしてもやっぱりお断りされたので諦めた。
実際に課金が発生しないとダメなんだろうか
EC2を使ってみる
GCPが無理だったのでEC2を試す。こっちはサービスへの課金履歴があるので同じ問題があっても大丈夫のはず
同じようにCPUインスタンスでサンプルスクリプトの動作確認した後、GPUインスタンスを試した
インスタンスの種類は色々あるが、Tesla T4が接続されたg4dn.xlargeを選択。こちらも同じように制限に引っかかったので上限割り当て変更をリクエスト(GPUインスタンスで使うvCPUの個数を緩和する、という内容のリクエストだった)
課金履歴があるからなのか、こちらのリクエストはすぐ通った
前準備
CUDA Toolkitやらtensorflowやらでそこそこディスクを消費するので、ストレージの容量はデフォルトの8GBだと足りない。16GBあればギリギリなんとかなりそうだけど、20GBにした
125GBのエフェメラルディスクがついてるという説明があったが、使い方がわからなかったのでAWSのインスタンスストアボリューム(エフェメラルストレージ)を参考に設定
- インスタンス停止時に揮発するが、ソースコードや学習データはこっちにおいて都度ダウンロードで問題なさそう
$ sudo mkfs.ext4 /dev/nvme1n1
$ sudo mkdir /workspace
$ sudo mount /dev/nvme1n1 /workspace
念の為GPUの存在を確認
$ lspci
...
00:1e.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1)
...
CUDAのインストール
CUDA Toolkitを公式の手順に沿ってインストール
ここでGPUの確認をするとエラー
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
ドライバが必要らしいのでこちらも公式からダウンロード
GPUのシリーズとToolkitのバージョンを選択するのでインスタンスのGPU、CUDA Toolkitのバージョンと一致させる
CUDA Toolkitを2020/07/07時点での最新版11.0-rcにすると、ここで対応するバージョンが見つからなかったのでToolkitを10.2で導入した
sudo ./NVIDIA-Linux-x86_64-418.152.00.run
ここでDKMS経由でインストールしないと再起動時にドライバがロストするという問題が起こるらしい
インスタンスを止めるとドライバ再インストールはまずいのでDKMSを使うように選択する
すると今度は次のエラーに遭遇
Your kernel headers for kernel XXX cannot be found at /lib/modules/XXX/build or /lib/modules/XXX/source.
該当のリンクをたどると確かにリンク切れを起こしている
kernel-develはCUDA Toolkitの依存ライブラリとしてインストールされているのだが、最新版がインストールされてしまうため、必要なカーネルソースと一致しないという状況なのでバージョンが一致するカーネルソースを取得する
sudo yum install "kernel-devel-uname-r == $(uname -r)"
Python/Tensorflow環境
ここはGPUでもCPUでもあまり変わらない。パッケージでtensorflow-gpuがあるのでこちらをpipで入れる
$ sudo yum install python3-pip
$ sudo pip3 install --upgrade pip
$ pip3 install tensorflow-gpu
$ python3
>> import tensorflow as tf
>> hello = tf.constant("Hello World!!")
いくつかのWarningが発生
2020-07-07 08:30:28.910462: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libcudart.so.10.1'; dlerror: libcudart.so.10.1: cannot open shared object file: No such file or directory
2020-07-07 08:30:28.916972: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libcudnn.so.7'; dlerror: libcudnn.so.7: cannot open shared object file: No such file or directory
2020-07-07 08:30:28.916984: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1598] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.
一部のライブラリのリンクに失敗している
最初のWarningは10.1を要求しているのに実際には10.2をインストールしていてそこでバージョン不整合を起こしていたので、
CUDA Toolkit 10.1をインストールし直して解決した
2つ目のWarningは公式でlibcudnnの各バージョン向けのアーカイブが配布されているのでこれを導入する
ここでダウンロードしようとしたところでNVIDIAへの開発者登録が要求される、fxxk!
心を落ち着けてユーザ登録を済ませてダウンロード・インストール
$ sudo rpm -i libcudnn7-7.6.4.38-1.cuda10.1.x86_64.rpm
$ sudo yum install libcudnn7
$ ls -al /usr/lib64/libcudnn*
lrwxrwxrwx 1 root root 17 7月 7 09:14 /usr/lib64/libcudnn.so.7 -> libcudnn.so.7.6.4
-rwxrwxr-x 1 root root 430101144 9月 21 2019 /usr/lib64/libcudnn.so.7.6.4
Toolkitが導入するライブラリパスは/usr/local/cuda/lib64
だけど、
単独で導入したlibcudnnのインストール先は/usr/lib64
になっていた
これで、Hello Worldを実行するとWARNINGが解消されてGPUが使える状態に。
サンプルスクリプトを実行してnvidia-smiで確認すると
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 31327 C python3 14405MiB |
+-----------------------------------------------------------------------------+
と確かにGPUを使った処理が動いてる!!!
体感的な処理速度もかなり改善していたので無事動作確認することができた
最終的な環境
- ホスト: Amazon EC2(g4dn.xlarge)
- OS: Amazon Linux2
- GPUドライバ: CUDA Toolkit 10.1
- スクリプト: Python3.7.6 + tensorflow-gpu 2.2.0
感想
cudaとtensorflowのバージョン組み合わせは非常にトラップ満載
動く環境でどこかをバージョンアップするとリカバリが大変な状況に陥る予感がすごいので、
動く組み合わせごとにコンテナ化するなり、インスタンスを分けるなりして環境を切り分けた方が良さそう