はじめに
UbuntuのNVIDIA GPU driverを430 => 435にアップデートしたらTensorflowがGPUモードで動作しなくなりました。435環境でTensorflowとCUDAを復活させるのに結構苦労したため、Driverのアップデート手順を書いてみました。
既にNVIDA DriverやCUDA一式をインストール済みの状態から始めていますので、クリーンな状態からインストールする場合は挙動が違うかも知れません。
動作環境
- Ubuntu 19.10
- GTX 1080 Ti
- NVIDIA driver 430 <= 今回導入
- CUDA 10.1
- cuDNN 7.6.5
- Tensorflow 2.1.0
- PyTorch 1.4.0
NVIDIA Driverを更新した以外は既に導入済です。TensorflowやPyTorchはCUDA 10.1を要求するため、最新のCUDA 10.2は使えません。
NVIDA Driverの更新
先ずは、以下のコマンドで使用可能なドライバを確認します。
ubuntu-drivers devices
$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00001B06sv00001462sd00003602bc03sc00i00
vendor : NVIDIA Corporation
model : GP102 [GeForce GTX 1080 Ti]
driver : nvidia-driver-390 - distro non-free
driver : nvidia-driver-440 - third-party free recommended
driver : nvidia-driver-435 - distro non-free
driver : nvidia-driver-430 - distro non-free
driver : nvidia-driver-410 - third-party free
driver : xserver-xorg-video-nouveau - distro free builtin
インストール済みのバージョンは435ですが、440が使えます。では、440をインストール。
(注): 440は"third-party"と表記されているため、Ubuntu 19.10のデフォルトリポジトリだけだと見えないと思います。なぜ440が見えるかですが、後述するCUDA再インストールのためにNVIDIAのリポジトリを追加しているためだと思われます。
sudo apt-get install nvidia-driver-440
再起動して、いらなくなった古いパッケージを削除。
sudo apt autoremove
nvidia-smi
を実行するとdriverは440ですが、CUDAのバージョンが10.2だと言っています。435では10.1と表示されていたのですが・・
$ nvidia-smi
Sun Mar 29 11:33:33 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.64.00 Driver Version: 440.64.00 CUDA Version: 10.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 108... On | 00000000:01:00.0 On | N/A |
| 0% 34C P8 12W / 280W | 229MiB / 11171MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
nvccのバージョン(= CUDAのバージョン)は10.1と表示されます。
~$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2019 NVIDIA Corporation
Built on Sun_Jul_28_19:07:16_PDT_2019
Cuda compilation tools, release 10.1, V10.1.243
StackOvlowのポストによると、nvidia-smiコマンドはNVIDIA Driverと一緒にインストールされ、CUDA driver APIのバージョンを表示するようです。一方で、nvcc -V
はCUDA runtime APIのバージョンを表示する。つまり、driver APIとruntime APIを管理しているライブラリが異なるため、NVIDIA DriverとCUDAと別々にインストールするとこうなる模様です。
ということで、この現象に関しては放置としました。
Tensorflowの再構築
ドライバの更新後にtensorflowを動かすと以下のエラーが出てCPUモードになってしまいます。
$ python
Python 3.7.7 (default, Mar 26 2020, 15:48:22)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
2020-03-29 11:32:12.334692: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libnvinfer.so.6'; dlerror: libnvinfer.so.6: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: :/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64
2020-03-29 11:32:12.334773: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libnvinfer_plugin.so.6'; dlerror: libnvinfer_plugin.so.6: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: :/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64
2020-03-29 11:32:12.334784: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:30] Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.
>>>
当初はここで、CUDA 10.1が認識されなくなったと勘違いし、CUDAの再インストールに走って状況を悪化させました。これ、実はCUDAの問題ではなく、TensorRTのライブラリが消えたのが原因でした。以下のエラーメッセージに出てくるライブラリはTensorRTのものです。
・Could not load dynamic library 'libnvinfer.so.6'
・Could not load dynamic library 'libnvinfer_plugin.so.6'
どうも、TensorFlow 2.1はGPUモードでの起動時にTensorRTのライブラリをチェックするようです。
ということでlibnvinferを再インストールします。先ずは、公式の手順で。
$ sudo apt-get install --no-install-recommends libnvinfer6=6.0.1-1+cuda10.1 \
libnvinfer-dev=6.0.1-1+cuda10.1 \
libnvinfer-plugin6=6.0.1-1+cuda10.1
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package libnvinfer6
E: Unable to locate package libnvinfer-dev
E: Unable to locate package libnvinfer-plugin6
登録済みのリポジトリには上記のパッケージがないようです・・
仕方がないので、以下のNVIDAのリポジトリから必要なファイルをダウンロードしてマニュアルでインストールします。
https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/
ダウンロードするファイルはTensorRT 6対応の以下のファイルです(TensorRT 7はCUDA 10.2が必要なため使えません)
- libnvinfer6_6.0.1-1+cuda10.1_amd64.deb
- libnvinfer-dev_6.0.1-1+cuda10.1_amd64.deb
- libnvinfer-plugin6_6.0.1-1+cuda10.1_amd64.deb
- libnvinfer-plugin-dev_6.0.1-1+cuda10.1_amd64.deb
ライブラリには依存関係があるため、適当なサブディレクトリに4つのファイルを格納して、一気にインストールします。
sudo dpkg -i ./libnvinfer/*.deb
これでTensorFlow(Keras)がめでたく復活しました!
CUDA 10.1の再インストール(おまけ)
最初にNVIDIA Driver 435を入れたときは、先の「libnvinfer問題」をCUDAが認識されなくなったと勘違いして、CUDAを一旦消して再インストールに走りました。CUDAを再インストールする手順についても、いつも迷うのでメモとして書いておきます。
NVIDAの公式手順ではCUDAのインストール方法には以下のオプションがあります。
- runfiles(local) : CUDA一式とインストール用のシェルスクリプトをダウンロードしてローカルでインストール → シェルスクリプトがCUDA 10.1でデフォルトのDriver 418をインストールしようとするようで、既に他のドライバをインストール済みの場合は警告が出ます。無視してインストールを強行するとシステムがおかしくなりそうなので止めました。
- deb(local or network) : aptのリポリトリを追加してインストールする
deb方式で、NVIDA公式にあるsudo apt-install cuda
を実行すると、CUDA 10.2をインストールしようとして依存性のチェックでエラーとなります。Driver 440が入っているとデフォルトでは10.2をインストールしようとするのかもしれません。そこで、
sudo apt install cuda-10-1
で、バージョンを指定してインストールします。このコマンドでは依存パッケージとして;
- cuda-toolkit-10-1
- cuda-runtime-10-1
- cuda-demo-suite-10-1
をインストールしようとし、
$ apt show cuda-10-1
Package: cuda-10-1
Version: 10.1.243-1
Priority: optional
Section: multiverse/devel
Source: cuda
Maintainer: cudatools <cudatools@nvidia.com>
Installed-Size: 25.6 kB
Depends: cuda-toolkit-10-1 (>= 10.1.243), cuda-runtime-10-1 (>= 10.1.243), cuda-demo-suite-10-1 (>= 10.1.243)
さらに、cuda-runtime-10-1は依存パッケージとしてcuda-drivers
を含むため、ドライバを再インストールしてしまいます。
$ apt show cuda-runtime-10-1
Package: cuda-runtime-10-1
Version: 10.1.243-1
Priority: optional
Section: multiverse/devel
Source: cuda
Maintainer: cudatools <cudatools@nvidia.com>
Installed-Size: 25.6 kB
Depends: cuda-drivers (>= 418.87), cuda-libraries-10-1 (>= 10.1.243), cuda-license-10-1 (>= 10.1.243)
ただし、apt install cuda-driversでインストールされるドライバは440なので悪さをすることはなさそうです。
$ apt show cuda-drivers
Package: cuda-drivers
Version: 440.64.00-1
Priority: optional
440より前のドライバを使っており、それを更新したくない場合は、cuda-toolkit-10-1
のみをインストールしておく手もありそうです。
$ apt show cuda-toolkit-10-1
Package: cuda-toolkit-10-1
Version: 10.1.243-1
Priority: optional
Section: multiverse/devel
Source: cuda
Maintainer: cudatools <cudatools@nvidia.com>
Installed-Size: 25.6 kB
Depends: cuda-compiler-10-1 (>= 10.1.243), cuda-tools-10-1 (>= 10.1.243), cuda-samples-10-1 (>= 10.1.243), cuda-documentation-10-1 (>= 10.1.243), cuda-libraries-dev-10-1 (>= 10.1.243), cuda-nvml-dev-10-1 (>= 10.1.243), cuda-license-10-1 (>= 10.1.243)
cuda-runtime-10-1のインストールをスキップすると、cuda-libraries-10-1が入りませんが、Tensorflowの動作には影響はなさそう。
おわりに
NVIDIA DriverとCUDA、さらにはTensorflowの依存関係がたまにおかしくなります(余計なアップデートをしなければよいだけの話だと思いますが・・)。そのたびに再インストールでハマるため、メモとして一連の手順をまとめてみました。
この3つは依存関係が複雑ですので、Dockerでサクッとやるのが一番手っ取り早いのかも知れません。