前回までの
LinuxとNVIDIA
最近の生成AIブームの追い風に乗って株価や収益が爆上げ中のNVIDIAですが、筆者のような古くからのLinuxユーザはあまりいい印象を持っていません。というのも、かってのNVIDIAはOSSに非協力的で、GPUに関する情報をほとんど公開せず、OSSなドライバの開発が困難だったためです。当時のLinuxユーザの間では
Linusさん自身がNVIDIAを名指しで罵しったことすらあります
この状況が大きく変わったのが2022年です。この年、NVIDIAは従来の方針を大きく変更し、Linux用ドライバのソースコードを公開すると発表、"open-gpu-kernel-module"という名称でGitHub上にリポジトリを公開しました。
後述するようにNVIDIAのGPUを利用するにはこのドライバ・
一方、同じ2022年にStableDiffusionという画像生成AIがOSSとして公開され、一大センセーションを巻き起こしました。"StableDiffusion"は、従来は大規模なクラウドサービス経由でしか実現できなかったキーワードからの画像生成を、そこそこの性能のグラボを持つPCで実行可能にした画期的なソフトウェアで、ブラウザ経由で簡単に操作できる"StableDiffusion-webui"と相俟って急速に普及しました。
"StableDiffusion"自身は特定のグラボを前提とはしていないものの、現状ではNVIDIAが提供するCUDA環境をPyTorch経由で利用するのが一番簡単そうです。そこで筆者も、StableDiffusionで遊ぶために型落ちのGeForce RTX 3060を入手し、それを使うためにPlamo LinuxをNVIDIAに対応させることにしたのでした
Open-GPU-kernel-module
さて、それではNVIDIAが公開している"Open-GPU-kernel-module"を見てみましょう。GitHubで公開されている"Open-GPU-kernel-module"は、"555.
どれを使うのがいいのかな、としばらく悩んだものの、NVIDIA自身で公開しているUNIX用ドライバのアーカイブ・
GitHubからダウンロードした"550.
$ ls 550.78.tar.gz open-gpu-kernel-modules-550.78/ $ ls open-gpu-kernel-modules-550.78/ CHANGELOG.md COPYING SECURITY.md nv-compiler.sh* version.mk CODE_OF_CONDUCT.md Makefile kernel-open/ src/ CONTRIBUTING.md README.md nouveau/ utils.mk
これらの中にはMakefileも含まれており、"make"を実行するだけでカーネル・
$ make -j4 make -C src/nvidia make -C src/nvidia-modeset ... [ nvidia-modeset ] XZ _out/Linux_x86_64/pascal_shaders.xz [ nvidia-modeset ] XZ _out/Linux_x86_64/maxwell_shaders.xz ... LD [M] ./open-gpu-kernel-modules-550.78/kernel-open/nvidia-peermem.ko make[2]: ディレクトリ '/usr/src/linux-6.6.30' から出ます make[1]: ディレクトリ './open-gpu-kernel-modules-550.78/kernel-open' から出ます $ ls open-gpu-kernel-modules-550.78/kernel-open/*ko open-gpu-kernel-modules-550.78/kernel-open/nvidia-drm.ko open-gpu-kernel-modules-550.78/kernel-open/nvidia-modeset.ko open-gpu-kernel-modules-550.78/kernel-open/nvidia-peermem.ko open-gpu-kernel-modules-550.78/kernel-open/nvidia-uvm.ko open-gpu-kernel-modules-550.78/kernel-open/nvidia.ko
作成したモジュールをインストールするルールも定義されており、"make modules_
$ make -n modules_install make -C kernel-open modules_install make[1]: ディレクトリ './open-gpu-kernel-modules-550.78/kernel-open' に入ります make "LD=ld" "CC=cc" "OBJDUMP=objdump" KBUILD_OUTPUT=/lib/modules/6.6.30-plamo64/build -C /lib/modules/6.6.30-plamo64/source ... NV_KERNEL_OUTPUT=/lib/modules/6.6.30-plamo64/build NV_KERNEL_MODULES="nvidia nvidia-uvm nvidia-modeset nvidia-drm nvidia-peermem" INSTALL_MOD_DIR="kernel/drivers/video" NV_SPECTRE_V2=0 modules_install ...
このようにソースコードからのビルド、インストールは簡単にできそうなものの、これらモジュールをコンパイル済みのパッケージとして提供するには工夫が必要です。というのも、カーネル・
当初は対応するカーネルのバージョンをパッケージ名に併記して、"nvidia_
詳細は省きますが、カーネルパッケージ作成用のPlamoBuildスクリプトを改造し、カーネルをビルド後、指定したバージョンのNVIDIA用ドライバ・
こうしておけばカーネルパッケージをインストールすれば対応するNVIDIA用モジュールもインストールされるので、バージョンの不一致等を気にする必要はなくなります。一方、NVIDIA用モジュールのバージョン
$ sudo modinfo nvidia [sudo] kojima のパスワード: filename: /lib/modules/6.6.30-plamo64/extramodules/nvidia.ko.xz import_ns: DMA_BUF alias: char-major-195-* version: 550.78 supported: external license: Dual MIT/GPL firmware: nvidia/550.78/gsp_tu10x.bin firmware: nvidia/550.78/gsp_ga10x.bin softdep: pre: ecdh_generic,ecdsa_generic ...
ドライバ・
NVIDIA-Linux-x86_64など
さて、NVIDIA GPU用のカーネル・
ここで提供されている"NVIDIA-Linux-x86_
$ sh ./NVIDIA-Linux-x86_64-550.78.run -x Creating directory NVIDIA-Linux-x86_64-550.78 Verifying archive integrity... OK Uncompressing NVIDIA Accelerated Graphics Driver for Linux-x86_64 550.78.... ... $ ls NVIDIA-Linux-x86_64-550.78 10_nvidia.json libnvidia-opticalflow.so.550.78* 10_nvidia_wayland.json libnvidia-pkcs11-openssl3.so.550.78* 15_nvidia_gbm.json libnvidia-pkcs11.so.550.78* ... libEGL.so.550.78* nvidia-application-profiles-550.78-rc libEGL_nvidia.so.550.78* nvidia-bug-report.sh* libGL.so.1.7.0* nvidia-cuda-mps-control* ...
上記のように、このアーカイブの中にはOpenGLやlibGLXといったX Window System用の共有ライブラリに加え、設定ファイルや各種ツール、OpenCL、CUDAといったGPUの機能を使うためのファイル類が収められています。
lddでこれらライブラリの依存関係を調べたところ、Plamo Linuxのデフォルト環境内で解決できました。そこでArch Linux等を参考に、これらファイルを適切な場所に配置するスクリプトを書き、"nvidia_
このアーカイブに含まれているツールの中にはNVIDIAからOSSとして公開されているものもあります。"nvidia-settings"は動作中のGPUの各種情報を確認するためのツール、"nvidia-persistenced"はGPUの初期化や動作状態を管理するためのツールです。
両者をざっと試したところ、"nvidia-settings"はlibX11を参照する一般的なX用アプリ、"nvidia-persistenced"はシステム起動時に自動起動が必要なデーモンでしたので、これらは通常のソフトウェア同様、PlamoBuildスクリプトでビルド、パッケージ化して、"nvidia_
以上をまとめると、Plamo-8.
$ ls /home/ftp/pub/Plamo-8.x/x86_64/contrib/Nvidia/*tzst /home/ftp/pub/Plamo-8.x/x86_64/contrib/Nvidia/nvidia_persistenced-550.78-x86_64-B1.tzst /home/ftp/pub/Plamo-8.x/x86_64/contrib/Nvidia/nvidia_settings-550.78-x86_64-B1.tzst /home/ftp/pub/Plamo-8.x/x86_64/contrib/Nvidia/nvidia_utils-550.78-x86_64-B2.tzst
NVIDIA GPUの使用例
さて、これらパッケージをインストールしてNVIDIAグラボの動作を確認してみます。手配したのはGigaByte製のGeForce RTX 3060です。装着したマシンのCPUはGPU内蔵のAMD Ryzen 3400Gなので、ビデオ回りが競合するかも、と心配したものの、問題なく認識、利用できました。
$ lspci -v ... 1:00.0 VGA compatible controller: NVIDIA Corporation GA104 [GeForce RTX 3060] (rev a1) (prog-if 00VGA controller]) Subsystem: Gigabyte Technology Co., Ltd GA104 [GeForce RTX 3060] Flags: bus master, fast devsel, latency 0, IRQ 77, IOMMU group 8 Memory at f5000000 (32-bit, non-prefetchable) [size=16M] Memory at c0000000 (64-bit, prefetchable) [size=256M] Memory at d0000000 (64-bit, prefetchable) [size=32M] I/O ports at f000 [size=128] Expansion ROM at 000c0000 [virtual] [disabled] [size=128K] Capabilities: <access denied> Kernel driver in use: nvidia Kernel modules: nouveau, nvidia_drm, nvidia ...
カーネルモジュールも問題なく組み込まれています。
$ dmesg ... [ 10.137411] loop: module loaded [ 10.342824] nvidia: loading out-of-tree module taints kernel. [ 10.397797] nvidia-nvlink: Nvlink Core is being initialized, major device number 239 [ 10.398713] nvidia 0000:01:00.0: vgaarb: VGA decodes changed: olddecodes=io+mem,decodes=none:owns=io+mem [ 10.441252] NVRM: loading NVIDIA UNIX Open Kernel Module for x86_64 550.78 Release Build (kojima@pl82_b1.linet.gr.jp) 2024年 5月 17日 金曜日 21:52:33 JST [ 10.649463] nvidia-uvm: Loaded the UVM driver, major device number 237. ...
Xも無事立ち上がり、nvidia-settingsも動作しました。
さて、それでは"StableDiffusion"も試してみましょう。"nvidia-settings"で動作状況を調べつつ、"StableDiffusion-webui"から
"nvidia_
$ nvidia-smi Tue May 28 11:58:21 2024 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.78 Driver Version: 550.78 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ | 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 RTX 3060 On | 00000000:01:00.0 On | N/A | | 83% 57C P2 162W / 170W | 4068MiB / 12288MiB | 98% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 0 N/A N/A 1922 G /usr/libexec/Xorg 235MiB | | 0 N/A N/A 2311 G firefox 0MiB | | 0 N/A N/A 9873 C python3 3348MiB | | 0 N/A N/A 10571 G nvidia-settings 2MiB | +-----------------------------------------------------------------------------------------+
今回は"StableDiffusion"を動かしたい一心で
まずはNVIDIAを対象にしたものの、当初からOSSに親和的だったAMDやIntelでは、OSSのみで同等の機能が実現できるはずです。ROCmやOneAPIなど、調べないといけないことは多々あるものの、今後はAMDやIntelのGPUにも対応していきたい思っています。