"Failed to initialize NVML" を再起動せずに解決する方法
よく忘れるので備忘録代わりに書いておきます.誰かの役に立てれば幸いです.
書いたこと自体を忘れがちなのは触れてはいけない
はじめに
忙しい人のための3行クッキングです.これで解決します.
$ sudo modprobe -r nvidia_drm
$ sudo modprobe -r nvidia_uvm
$ sudo modprobe nvidia
デスクトップ環境の方は注意点もご覧ください.
これはなに
意図しないタイミングでCUDAドライバのアップデートが発生して
Failed to initialize NVML: Driver/library version mismatch
に頭を抱えてしまうことは,誰しも一度は通る道だと思います.
このエラーに遭遇したらマシンを再起動するのが通常の解決方法ですが,どうしても再起動したくないタイミングってありますよね?
この記事ではそんな場合に重宝する,再起動せずにCUDAドライバのバージョンミスマッチを解決する方法を紹介します.
といっても作業自体は冒頭のコマンド3行打つだけです.
原因
CUDAドライバのアップデート時,NVIDIAのGPU用カーネルモジュールは自動的にリロードされません.
このためカーネルモジュールのバージョンが古いまま動き続け,更新されたCUDAドライバに付属するライブラリのバージョンとの整合性が取れなくなってエラーが発生します.
実際にエラーが起きた状態で
$ modinfo nvidia --field=version
を実行すると,この不整合が発生していることが確認できます.
マシンを再起動すると,すべてのカーネルモジュールが確実にリロードされるのでエラーを解決できるというわけです.
そこで今回は,原因となっているカーネルモジュールを特定し,それをリロードすることでマシンを再起動させることなくエラーを解決します.
解決方法
まず,GPUドライバに関連してそうなカーネルモジュールを見つけてきます.
$ lspci -k -d 10de::0300
81:00.0 VGA compatible controller: NVIDIA Corporation TU102GL [Quadro RTX 6000/8000] (rev a1)
Subsystem: NVIDIA Corporation Quadro RTX 6000
Kernel driver in use: nvidia
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
ここで,デバイスとして10de::0300
を指定していますが,それぞれ
- 10de: NVIDIA Corporation のvendor ID
- 0300: VGA compatible controller のclass code
で対象を絞り込んでいます.
これでNVIDIAのGPU関連のカーネルモジュールはnvidia*
と命名されていそうだとわかったので,次にlsmod
で依存関係を確認します.
$ lsmod | grep -ie '^module' -e nvidia
Module Size Used by
nvidia_uvm 1216512 0
nvidia_drm 61440 0
nvidia_modeset 1241088 1 nvidia_drm
nvidia 56291328 2 nvidia_uvm,nvidia_modeset
drm_kms_helper 184320 4 ast,nvidia_drm
drm 495616 7 drm_kms_helper,drm_vram_helper,ast,nvidia,nvidia_drm,ttm
i2c_nvidia_gpu 16384 0
これで
nvidia
├── nvidia_uvm
└── nvidia_modeset
└── nvidia_drm
というような依存関係があることがわかりました.
あとはこの依存関係に沿ってカーネルモジュールをアンロード・ロードするだけです.
このとき,依存関係の上位にあるモジュールは,下位のモジュールがすべてアンロードされると自動的にアンロードされます.
逆に,上位のモジュールをロードすると自動的に下位のモジュールから先にロードされます.
$ sudo modprobe -r nvidia_drm
# nvidia_drmにのみ依存していたnvidia_modesetも自動的にアンロード
$ sudo modprobe -r nvidia_uvm
# nvidia_uvm,nvidia_modesetがアンロードされたので,これらに依存していたnvidiaも自動的にアンロード
$ sudo modprobe nvidia
# これでnvidiaとその依存関係にあるカーネルモジュールがロードされる
これでnvidia-smi
を実行すると,問題なくGPUの情報が表示されるはずです.
このときmodinfo nvidia --field=version
を実行すると,インストールされているCUDAドライバと同じバージョンが表示されます.
注意点
筆者の場合はデスクトップ環境を利用していないのでわかりませんが,デスクトップ環境の方は追加で作業が必要になるかもしれません.
また,おそらくですがカーネルモジュールをアンロードする際は一時的にGUIからCUIに切り替えたほうが良いと思います.
Discussion