世界を動かす技術を、日本語で。

LinuxでNvidia GPUのVRAMをスワップスペースとして使用する

概要

  • NVIDIA GPUのVRAM をLinuxでスワップ領域として利用する方法の紹介
  • ラップトップのメモリ増設不可問題 を解決するソリューション
  • NBDプロトコル を用いた実装でカーネルモジュール不要
  • zramやSSDスワップとの組み合わせ でアドレス可能メモリを大幅拡張
  • パフォーマンス・動作要件・インストール方法 も解説

NVIDIA GPUのVRAMをLinuxスワップ領域として活用する方法

  • ラップトップのメモリ増設不可問題 を解決する手段として、NVIDIA GPUの VRAMをスワップ領域 として活用

  • 例えば RTX 3070 Laptop (物理メモリ16GB、VRAM 8GB)で7GBをスワップとして割当可能

  • スワップオーバーフロー順序 :RAM → VRAM(高速、PCIe経由)→ zram(CPU圧縮)→ SSD

  • 最終的なアドレス可能メモリ :zramやSSDスワップと組み合わせて約46GB(物理メモリの3倍)

  • NBD(Network Block Device)プロトコル を活用し、カーネルのnbdドライバ経由で/dev/nbdXとして認識

    • データ経路 :カーネルスワップサブシステム → /dev/nbdX → nbdカーネルドライバ → Unixソケット → nbd-vramデーモン → cuMemcpyHtoD/DtoH → GPU VRAM
  • カーネルモジュール不要、NVIDIAカーネルシンボルも未使用、カーネルやドライバ更新時も再構築不要

技術的背景とNBD方式の優位性

  • NVIDIA P2P API (nvidia_p2p_get_pages_persistent)はGeForce等のコンシューマGPUでは RMレベルで無効化
    • Quadro/datacenter SKUのみ有効、ドライババージョンに関係なく制限
  • BAR1物理アドレスへ直接ioremap_wc も不可
    • GPU内部ページテーブルに~16MiBしかBAR1マッピングされていないため
    • mkswapは成功するがswaponで失敗(スワップヘッダーが実際には存在しない)
  • NBD方式 はこれらの制約を回避
    • cuMemcpyHtoD/DtoHは全CUDA対応GPUで動作、特別な権限不要

必要要件

  • CUDA対応NVIDIA GPU (RTX/GTX等の一般向けカード)
  • NVIDIAドライバ(libcuda.so.1)
  • Linuxカーネル3.0+(nbdモジュール組込済み環境)
  • nbd-clientパッケージ
  • gcc, make

インストール手順

  • リポジトリ取得 git clone https://github.com/c0dejedi/nbd-vram

  • ディレクトリ移動 cd nbd-vram

  • インストール実行 sudo ./install.sh

  • サービス起動 sudo systemctl start vram-swap-nbd

  • 動作確認 swapon --show (/dev/nbd0 partition 7G 0B 1500等が表示されれば成功)

    • サービスはインストール時に自動有効化、再起動後も自動起動

設定変更方法

  • /etc/systemd/system/vram-swap-nbd.service を編集
    • Environment=VRAM_SETUP_SIZE_MB=7168 # 使用するVRAM容量(MB単位)
    • Environment=VRAM_SWAP_PRIORITY=1500 # スワップ優先度(高いほど先に利用)
  • 設定反映 sudo systemctl daemon-reload && sudo systemctl restart vram-swap-nbd
  • VRAM_SETUP_SIZE_MB は上限値であり、GPUメモリ状況により自動調整(512MiB刻みで縮小)

電源管理機能

  • インストール時に電源管理有効化を選択可能
    • ACアダプタ切断やバッテリ残量低下時に自動停止、復帰時に自動再開
    • systemctl stopによる手動停止は常に優先
  • 設定変更 /etc/nbd-vram.confを編集し、次回ポーリング(60秒以内)またはAC抜き差し時に反映

インストール不要の動作確認(スモークテスト)

  • テスト実行 sudo bash test-nbd.sh (VRAM割当・NBDデバイス接続・1MiB書込/読戻し・スワップ有効化・手動終了手順表示)
  • 全領域ストレステスト sudo bash test-fill.sh (VRAM全域ゼロ書込・サンプル読戻し検証・終了時に自動でスワップ復帰)

パフォーマンス

  • RTX 3070 Laptop(7GB連続書込、4Mブロック)での測定値
    • シーケンシャルスループット:約1.3GB/s
    • NVMe SSDより低レイテンシ (PCIe経由でGPUに直結するため)
  • zram利用時はVRAMスワップの優先度を高く設定 し、SSDスワップへのアクセスを最小化

アンインストール方法

  • アンインストール実行 sudo bash uninstall.sh

ライセンス

  • MITライセンス
    • 作者:Sean Lobjoit (c0dejedi)

Hackerたちの意見

ソルダーメモリでアップグレードパスがないノートパソコン向けに作られたんだね。もし8GBのVRAMを持ってるRTXカードがあって、SSDにスワップされるなら、そのVRAMを活用できるってことか。うーん、これで高いRAMからさらに高いRAMにスワップする理由が分かった気がする:) ニッチな感じだけど、必要な時にはいいアイデアだね。

もう一つ考えた理由があるんだけど、VRAMがあるのにいつも使ってるわけじゃないってことはない?例えば、ゲームが好きでGPUを買ったとするじゃん。でも、ゲームしてない時はデスクトップを表示するのに16GBのVRAMなんて必要ないよね。別のことに使った方がいいんじゃない?編集:ただし、これはゲームを始めるときにスワップとして使っているVRAMを解放できるシステムが前提なんだけど、できるのかな?

俺の開発マシンは32GBのRAMと32GBのVRAMを積んでるけど、AIモデルを動かしてない時はほとんどアイドル状態なんだ。これ、そんなに悪いアイデアじゃないかも。

これはpcmasterraceの上半身だけムキムキで足が細いみたいなもんだね、笑

16GBが企業レベルのデータベースメインフレームだったのを覚えてる?GPUもめちゃくちゃ計算能力があるから、GPU計算に役立つデータベースフォーマットがあるんじゃないかな。データがすでにVRAMにあるから、GPUは必要に応じてデータをソートしたり、結合したり、操作したりできるし。

おそらくLSMコンパクション。

お願いだから、もっとGPUの需要を生まないでくれ。

GPUアクセラレーテッドデータベースは長い歴史があるよ。2013年にHeavyAI(以前はMapD/OmniSci)を設立したけど、Voltron DataやKinetica、Sqreamなど、他にもこの分野のスタートアップがたくさんあるんだ。今ではIBMやStarburst、Microsoft(今日Fabric SQL on GPUを発表したばかり)みたいな大手も自分たちのGPUアクセラレーテッドシステムを開発してる。GPUはCPUに比べて計算、メモリ、インターコネクトの帯域幅で大きなアドバンテージがあるから、データを供給できればすごく強いと思う。2〜3年以内にGPU上のデータベースやデータウェアハウスが一般的になると思う。データをクエリするためにエージェントを広く使うようになるだろうし、過去のETLやBIのワークロードよりも、もっと低遅延で多くのクエリを実行する必要が出てくるはず。

なんとかして1TBのPCIeで動かせるようにできないかな?もっとデータを処理できるように。

俺は逆のことに興味がある。NvidiaのLinuxドライバーは、持ってるVRAM以上にアドレスを指定するとクラッシュするんだ。そうならないといいんだけど。

もうWindowsではそれやってるけど、ちょっと微妙だよね。LMStudioやComfyUIみたいなものをターゲットにしてるなら、どっちもこれをやるための優れた方法があるよ。

いいアイデアだけど、ここで何かがすごく間違ってる: > シーケンシャルスループット: ~1.3 GB/s [RTX 3070 Laptopで] このRTX 3070チップはPCIe 4.0 x16に接続されてるから、64GB/sが出るはずなのに。8GBのGDDR6は448GB/sだし。NVMeドライブにスワップすれば、倍の速さだけど、レイテンシが高くなるね。

Gen 4.0 x16は各方向で32 GB/sだけど、これを実装する方法は高性能を求めるならあまり良くない。編集:彼らのベンチマークはZRAMを使っていて、スワップに書き込む前にページを圧縮してるんだ。そのパフォーマンスオーバーヘッドがどれくらいかは分からないけど、結構あると思う。まず第一に、nbdドライバーをフックしているユーザースペースプログラムで、遅いことで知られてる。GPUに転送する前にユーザースペースでバウンスバッファを使ってるから、カーネルがページをスワップする必要があるときは、まずそれをユーザースペースのバッファにコピーしなきゃいけない。ユーザースペースプログラムは再び起きて、ページをデバイスメモリにコピーするcuda操作を発行しなきゃならない。nbdは高いキュー深度や隣接アクセスのマージをうまくサポートしてないから、カーネルが4Kページのスワップをたくさん発行しても、コアレッシングなしだと、4 GB/s(4 GB / 4Kページ)を処理するために毎秒少なくとも百万回のカーネル/ユーザースペースのコンテキストスイッチが発生するよ。64 GB/sなんて到底無理だし。それはNBDの部分だけで、NVIDIAドライバーの混乱は無視してね。PCIeは大量のデータを移動できるけど、フル帯域幅に近づけるには長いページリストを持つDMAエンジンを使わなきゃいけない。毎回4Kページの転送を設定するのでは、バスのフルサチュレーションには達しないよ。NVMeにスワップするのは非常に最適化された経路で、スワッパーはページのリストを直接NVMeドライバーに提出できて、コントローラーはRAMから直接DMAできるから、CPU側でのコピーやコンテキストスイッチは全く必要ない。これをublkドライバーに移行することで、ユーザースペースのバウンスバッファを回避できるかもしれないし、少なくともCUDAコピーを並行して設定できる複数の書き込みキューを持つこともできるだろう。

NVMeにスワップすると、NANDのPEサイクルを消費するから、時間が経つにつれて劣化しちゃうよ。RAMやVRAMは使用によって劣化しないけどね。

バックプレッシャーについてはどうなの?VRAMがスワップスペースとして使われている時のVRAM割り当ての要件はどう処理するの?X11だとそんなに悪くないけど(バッファが事前に割り当てられてるから)、Waylandだと割り当てがもっとダイナミックだから、VRAMが足りなくなるとデスクトップ全体がクラッシュしやすいんだ。最近、Hyprland+llama-server+KVMでコンピュータ間を切り替えている時に、VRAMを解放せずに何回かクラッシュしたよ。

"シーケンシャルスループット:~1.3 GB/sはすごく低いね。それに、ランダムな読み書き速度の方がずっと重要じゃない?"

これ、昔LinuxのMTD/phramドライバーを使ってやってたのを思い出すな - https://wiki.archlinux.org/title/Swap_on_video_RAM - 今でも関連があるかは分からないけど、DRMとの相互作用やVRAMの一部を予約する方法がどうなるかは知らないから。xorg.confでの推奨制限は今やかなり古いかも。そのページにはopenclの上にあるfuseファイルシステムの実装もあって - https://github.com/Overv/vramfs - こっちの方が互換性があるかもしれない。

Windows用に、数年前に似たようなものを見たことがあるんだ。NVIDIAカード用のVRAMからRAMドライブを作るための実験的なコンセプトドライバーだよ。シーケンシャルは期待通りに速いけど、ランダムは改善の余地がたくさんあるね。

「GpuRamDrive」 「GPU RAMにバックアップされた仮想ドライブを作成する。」 https://github.com/prsyahmi/GpuRamDrive AMDサポートのフォーク: https://github.com/brzz/GpuRamDrive/

似たような感じだけど、OpenCL APIを使ってるからAMDでも動くよ(「動く」の定義によるけど、彼らのドライバーはかなりバグが多いからね): https://libguestfs.org/nbdkit-vram-plugin.1.html