ローカルでPyTorchを使うとき、GPUが認識されない場合の対処法

# 目的
ChatGPTやClaudeなどの生成AIはブラウザやAPI経由で簡単に使えるようになりました。
次のステップではローカルLLMの実装がブームになるかも？

ということでローカルでいろいろと機械学習ができる環境を整える際にぶち当たった問題への備忘録になります。

結論、NVIDIAドライバーのバージョンを上げれば直りました。
ただ最新バージョンにした場合にGPUが機能しなくなる不具合があったためその対処法を残します。

# 何が起きたか
ローカルのコンテナ環境でPyTorchを使おうとしたが、PyTorchがGPUを認識してくれなくて泣いていました。

```python
import torch

print("-----------app.py実行--------------")
# GPUが利用可能か確認
print(torch.__version__)
print(torch.cuda.is_available())
```

```terminal
-----------app.py実行--------------
2.4.0+cu121
False
```

`torch.cuda.is_available()` の結果がTrueでなければGPUを認識できていないことになります。

# 原因
どうやらPyTorchはバージョンによって扱えるCUDAのバージョンが決まっているらしいです。
現在のGPUの情報をコンテナ内で下記コマンドを実行することで確認できます。

```terminal
/# nvidia-smi
Wed Jul 24 13:59:58 2024
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 510.47.03    Driver Version: 511.65       CUDA Version: 11.6     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0 Off |                  N/A |
| N/A   54C    P8     3W /  N/A |    349MiB /  4096MiB |      8%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

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

```
| NVIDIA Driver Version | CUDA Version |
|:-:|:-:|
| 511.65 | 11.6 |

でした。
注意点なのがここのCUDA Versionは実際にインストールされているCUDAのことではなく、このNVIDIAドライバーが対応しているCUDAの最大バージョンのことです。

次にPyTorchのバージョンを確認します。

```python
import torch

# PyTorchのバージョン確認
print(torch.__version__)
```

```terminal
2.4.0+cu121
```

ちょっと特殊な書き方されていますが、これは下記を意味します。

| PyTorch Version | CUDA Version |
|:-:|:-:|
| 2.4 | 12.1 |

つまり、PyTorchないで扱われるCUDAはバージョン12.1なのに対し、NVIDIAドライバーが対応しているCUDAバージョンは11.6までということになります。

この差がPyTorchでGPUを使うことができない原因となります。

:::note info
PyTorchでGPUを使うためにはPyTorchのCUDAバージョンとNVIDIAドライバーの対応CUDAバージョンをそろえる必要がある。
つまりNVIDIAドライバーのバージョンアップが必要になります。
:::


# NVIDIA ドライバーをインストール
インストール先はいくつかあります。
どれも公式なのでお好きなところからドライバーをダウンロードしましょう。

https://www.nvidia.com/ja-jp/drivers/
https://www.nvidia.com/ja-jp/geforce/drivers/
https://www.nvidia.com/Download/Find.aspx?lang=jp

ドライバーの検索欄に自身の環境で使っているGPU情報などを入れ、検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/cb9bd6e1-5ba1-8a42-c2d1-47a4e1218d0b.png)

検索結果に複数のバージョンのドライバーが表示されます。
がっつり最新ゲームのためにGPUを使わけでなければ、「Studio ドライバー」でいいかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/5eb46470-0251-674b-77f1-ba790e3349bd.png)

ちなみに、「詳細を見る」から追加情報のリリースノートを見ることができ、対応可能なCUDAバージョンについても確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/9c07034f-849a-1998-2826-ecba7d2dd9df.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/1972bc2c-e24d-6d4f-ac46-a37fd6295124.png)


対象のドライバーを選択するとexeファイルがダウンロードされますので、そのままインストールまで行っていきましょう。
インストール手順はインストーラーに従うだけなので割愛します。


# NVIDIAドライバーの更新確認
ドライバーアップデートが完了したら再度、GPU情報を確認しましょう

```
> nvidia-smi
Tue Aug  6 19:10:14 2024
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 528.02       Driver Version: 528.02       CUDA Version: 12.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name            TCC/WDDM | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ... WDDM  | 00000000:01:00.0 Off |                  N/A |
| N/A   45C    P0     6W /  35W |      0MiB /  4096MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

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

`CUDA Version: 12.0` となっていることが確認できましたね。
PyTorchの方もGPUを認識してくれています。

```python
import torch

print("-----------app.py実行--------------")
# GPUが利用可能か確認
print(torch.__version__)
print(torch.cuda.is_available())
```

```terminal
-----------app.py実行--------------
2.4.0+cu121
True
```

以上で無事PyTorchの実行環境でもGPUを扱うことができるようになりました。

# トラブルシューティング
実はここに至るまでに四苦八苦していました。
以降はそのトラブルシューティングになります。

## NVIDIAドライバーを最新にしたらPC自体がGPUを使わなくなってしまった
当時の最新バージョン `560.70` をインストールしたのですが、その後にGPUがウンともスンとも言わなくなってしまいました。

タスクマネージャーを見ても、認識はされど重い処理をぶん回しても使われるのはCPUのみ。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/2dabd078-ba55-861a-1701-a4d24825e589.png)

ターミナルから確認すると`[Unknown Error]`が出る始末。。。
```terminal
PS C:\Users\user> nvidia-smi --query-gpu=timestamp,name,utilization.gpu,memory.used --format=csv -l 3
timestamp, name, utilization.gpu [%], memory.used [MiB]
2024/08/06 03:51:31.701, NVIDIA GeForce RTX 3050 Ti Laptop GPU, 0 %, 0 MiB
2024/08/06 03:51:34.706, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:51:37.722, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:51:40.734, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:51:43.744, NVIDIA GeForce RTX 3050 Ti Laptop GPU, 0 %, 0 MiB
2024/08/06 03:51:46.746, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:51:49.750, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:51:52.753, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:51:55.755, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:51:58.758, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:52:01.759, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:52:04.762, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
2024/08/06 03:52:07.764, NVIDIA GeForce RTX 3050 Ti Laptop GPU, [Unknown Error], 0 MiB
```

もちろんPyTorchからもGPUは認識できていません。


### 対処①: ドライバーの再インストールおよびクリーンインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/f998ef58-bf04-767b-dc59-36db7eec39a2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/c4700f4e-12c5-cc54-290a-26d5a51b46f9.png)

ダメでした。

### 対処②: NVIDIAドライバーのダウングレード
先ほどの公式サイトの中では下記サイトが一番過去のドライバーまで検索できました。
https://www.nvidia.com/Download/Find.aspx?lang=jp

この中から `CUDA Version: 12.0` に対応しつつ、できるだけ過去のドライバー（`528.02`）をインストールしました。
結果無事動作させることができました。

# まとめ
ローカルに機械学習の環境を構築するのに結構手間取ってしまいました。
今回はPyTorchに関する部分でしたが、今後も他に問題が起きた際に備忘録を残していければと思います。

コンテナでローカルLLMを動かす環境を構築する際は以下の記事もご参考ください。
https://qiita.com/eiji-noguchi/items/a73d476f6ff33be2a63e