nvidia-driver の最新版へのアップデートメモ

# 記事概要
nvidiaドライバの更新方法です。2023年1月30日時点で有効であることを確認しています。

# 方法
[nvidia公式のダウンロードページ](https://developer.nvidia.com/cuda-toolkit-archive)に自分のマシンの情報とダウンロード方法を入力すると更新コマンドが表示されます。必要な情報は以下の通りです。

- OS
- Architecture
- Distribution[^distribution]
- Version
- Installer Type

Linuxにおけるそれぞれの調べ方は以下の通りです。

[^distribution]:Windowsの場合はDistributionはないようです。

## Architecture
```bash
uname -m
```

## Distribution/Version
```bash
cat /etc/os-release
```

# サンプル
- Linux
- x86_64
- Ubuntu
- 18.04
- deb(network)

の場合、以下のようなコマンドが得られます。得られたコマンドをコピペして実行すればドライバの更新が完了します。古いドライバは更新の際に勝手に削除されるのでマニュアルで消す必要はありません。

```bash
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-keyring_1.0-1_all.deb
sudo dpkg -i cuda-keyring_1.0-1_all.deb
sudo apt-get update
sudo apt-get -y install cuda
```

## 参考画像
![スクリーンショット 2023-01-30 11.04.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238125/724daf5a-f6ad-989e-fd78-ba6dc44e22b6.png)


<details>
<summary>旧記事内容</summary>

# 記事概要
special case っぽいですが備忘録を兼ねて nvidia-driver をアップデートした時のことを書きました。
アップデートの発端は pytorch を `1.5.0` にバージョンアップしたら GPU が使えなくなったことです。

<font color="red">2022/11/14追記
nvidia-driver のアップデート手順は現在でも有効でした。</font>

# 環境
- OS: ubuntu 16.04
- GPU: Tesla K80

# 症状
pytorch を `1.4.0` から `1.5.0` に上げたら `Is CUDA available: No` となってしまい、 GPU が使えなくなりました。バージョンを `1.4.0` に下げたら (+ torchvision を `0.5.0` に下げたら) 問題なく動きましたが、最新版が動かないのは気持ち悪いので直すことにしました。　

```bash
$ python -m torch.utils.collect_env
Collecting environment information...
PyTorch version: 1.5.0
Is debug build: No
CUDA used to build PyTorch: 10.2
OS: Ubuntu 18.04.3 LTS
GCC version: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
CMake version: version 3.10.2
Python version: 3.8
Is CUDA available: No
CUDA runtime version: 10.1.243
GPU models and configuration: GPU 0: Tesla K80
Nvidia driver version: 384.130
cuDNN version: /usr/lib/x86_64-linux-gnu/libcudnn.so.7.6.5
Versions of relevant libraries:
[pip3] numpy==1.18.5
[pip3] torch==1.5.0
[pip3] torchvision==0.6.0
[conda] Could not collect
```

# やったこと
## driver のバージョン確認
nvidia-driver のバージョンは `nvidia-smi` で確認できます。
アップデート前はドライバのバージョンが `384.130` でした。(化石かな？) 
戻り値の上段中央ないし左に書いてある数字が nvidia-driver のバージョンです。

```bash
$ nvidia-smi
Thu Jul  2 03:15:10 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.130                Driver Version: 384.130                   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 00000001:00:00.0 Off |                    0 |
| N/A   60C    P0    61W / 149W |      0MiB / 11441MiB |     88%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
```

普段自分が GPU を使って機械学習をする際は docker を使っているのですが、CUDA や cudnn がコンテナのなかで個別に設定できる一方で、 **nvidia-driver はコンテナの外で設定する必要があるらしいです。** なので、「著者実装の Dockerfile 使ってんのに GPU 使えねえ〜」みたいな時は nvidia-driver のバージョンが古いことなどを疑いましょう。

## 古い nvidia-driver を消す
すでに nvidia-driver が導入されている場合、これらを消した方が依存関係などの面から丸い気がします。とはいえ、最終的に nvidia 公式の謎実行ファイルを動かしてドライバをインストールするので、実はこのステップがいらない (実行ファイルの中でやってくれてる) という説はあります。

```bash
$ sudo apt remove -y --purge nvidia*
$ sudo apt remove -y --purge libnvidia*
```

自分は今回初めて知ったのですが、`--purge` は設定ファイルも含めて消すオプションです。これをしないと無駄な設定ファイルが残り続けるので消した方が丸い気がします。`dpkg -l | grep nvidia` で何も出てこないことを確認できたら次のステップに進みます[^1]。

```bash
$ dpkg -l | grep nvidia
```

[^1]: 経験上、上記のコマンドだと nvidia 関連のパッケージがいくつか消えないで残ることが多いです。その場合ワイルドカードを指定せずパッケージ名を具体的に指定して remove すると消えてくれます。

## 公式の CUDA Toolkit から自分のプラットフォームにあった実行ファイルを探す
「CUDA Toolkit ではなく nvidia-driver が欲しいのですが……」と思ってしまうのですが、(思うだろふつう) CUDA Toolkit の実行ファイルから nvidia-driver の最新版が勝手に入ります。以下のリンクから欲しい CUDA のバージョンを選んでプラットフォーム情報を入れると実行ファイルのダウンロードコマンドが出てきます。

https://developer.nvidia.com/cuda-toolkit-archive

Architecture, Distribution, Version は `cat /etc/lsb-release` と `uname -m` で確認可能です。

```bash
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu  # distribution
DISTRIB_RELEASE=16.04  # version
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
```

```bash
$ uname -m
x86_64  # architecture
```

以上の情報を入力した結果、僕の場合はこんな感じのコマンドが表示されました[^3]。

```bash
$ wget http://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda_10.2.89_440.33.01_linux.run
$ sudo sh cuda_10.2.89_440.33.01_linux.run
```

[^3]: 手元の環境やインストールしたい CUDA バージョンによってコマンドは異なるため注意してください。

## CUDA Toolkit (with nvidia-driver) をダウンロードする
先ほど表示されたコマンドを打っていきます。まずは `wget` から。

```bash
simossyi@gpu:~$ wget http://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda_10.2.89_440.33.01_linux.run
--2020-07-02 02:23:36--  http://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda_10.2.89_440.33.01_linux.run
Resolving developer.download.nvidia.com (developer.download.nvidia.com)... 152.195.19.142
Connecting to developer.download.nvidia.com (developer.download.nvidia.com)|152.195.19.142|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2645419389 (2.5G) [application/octet-stream]
Saving to: ‘cuda_10.2.89_440.33.01_linux.run’

cuda_10.2.89_440.33.01_linux.run      100%[=========================================================================>]   2.46G   108MB/s    in 18s

2020-07-02 02:23:54 (142 MB/s) - ‘cuda_10.2.89_440.33.01_linux.run’ saved [2645419389/2645419389]
```

次に落としたファイルを実行します。この時「ライセンスに同意するか？」的なことを聞かれるので `accept` を入力します。その後、インストールオプションが現れますが、僕はデフォルトの設定 (driver と Toolkit のみ) のまま `install` を実行しました。ちなみにこのファイルは沈黙のままログも吐かず長時間動き続けるので、固まったように見えてもお使いの PC は正常です。

```bash
$ sudo sh cuda_10.2.89_440.33.01_linux.run
===========
= Summary =
===========

Driver:   Installed
Toolkit:  Installed in /usr/local/cuda-10.2/
Samples:  Installed in /home/simossyi/, but missing recommended libraries

Please make sure that
 -   PATH includes /usr/local/cuda-10.2/bin
 -   LD_LIBRARY_PATH includes /usr/local/cuda-10.2/lib64, or, add /usr/local/cuda-10.2/lib64 to /etc/ld.so.conf and run ldconfig as root

To uninstall the CUDA Toolkit, run cuda-uninstaller in /usr/local/cuda-10.2/bin
To uninstall the NVIDIA Driver, run nvidia-uninstall

Please see CUDA_Installation_Guide_Linux.pdf in /usr/local/cuda-10.2/doc/pdf for detailed information on setting up CUDA.
Logfile is /var/log/cuda-installer.log
```

以上の操作で nvidia-driver が最新のものに更新されます。 `nvidia-smi` で確認しましょう[^2]。

[^2]: `sudo reboot` が必要になる場合もあります。

```bash
$ nvidia-smi
Thu Jul  2 02:50:36 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.33.01    Driver Version: 440.33.01    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  Tesla K80           Off  | 00000001:00:00.0 Off |                    0 |
| N/A   60C    P0    61W / 149W |      0MiB / 11441MiB |     88%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
```

CUDA Toolkit を介して nvidia-driver を入れ直したので `nvidia-smi` で CUDA のバージョンが表示されるようになりました。docker で動かす分には CUDA はコンテナの外に入れる必要はないのですがまあいいでしょう。

最後に pytorch から GPU が見えてるかも確認します。 `Is CUDA available: Yes` になってますね。

```bash
$ python -m torch.utils.collect_env
Collecting environment information...
PyTorch version: 1.5.0
Is debug build: No
CUDA used to build PyTorch: 10.2
OS: Ubuntu 18.04.3 LTS
GCC version: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
CMake version: version 3.10.2
Python version: 3.8
Is CUDA available: Yes
CUDA runtime version: 10.1.243
GPU models and configuration: GPU 0: Tesla K80
Nvidia driver version: 440.33.01
cuDNN version: /usr/lib/x86_64-linux-gnu/libcudnn.so.7.6.5
Versions of relevant libraries:
[pip3] numpy==1.18.5
[pip3] torch==1.5.0
[pip3] torchvision==0.6.0
[conda] Could not collect
```

## For nvidia-docker2 users
上の　nvidia　関連コマンド一括削除で nvidia 関連のライブラリを全削除してしまったので `nvidia-docker2` も消えてしまっています。(`nvidia-docker2` 以外を消すようにコマンドを直した方がいいかもしれない) なのでこのパッケージが必要な場合は以下のコマンドで再インストールします。

```bash
$ sudo apt-get install -y nvidia-docker2
$ sudo pkill -SIGHUP dockerd
```

ちなみに最近は `nvidia-driver2` の使用は [推奨されないっぽい](https://qiita.com/ksasaki/items/b20a785e1a0f610efa08) です。

# 参考サイト
[NVIDIA Docker って今どうなってるの？ (19.11版)](https://qiita.com/ksasaki/items/b20a785e1a0f610efa08)
[nvidia-docker wiki](https://github.com/nvidia/nvidia-docker/wiki/Installation-(version-2.0))
[pytorch1.5 does not support CUDA？](https://github.com/pytorch/pytorch/issues/37212)
[Ubuntuアップデートしたらおかしくなった件](https://www.yoshiislandblog.net/2018/06/06/ubuntu_update/)

</details>