2026年10月4日 / 投稿

VRAM 2 GBのGPUでローカルLLMは速くなる? Proxmoxで試した結果と次の改善策

ProxmoxのLXCに構築した日本語チャット環境へ、VRAM 2 GBの旧世代NVIDIA GPUを追加した。OllamaとQwen3 1.7Bで日本語を生成でき、ホストを再起動してもコンテナとチャットサービスが復帰するところまで確認した。

結果は「GPUを使えたが、今回の比較では速くならなかった」。CPU専用が約11.8トークン/秒、GPU併用が約10.4トークン/秒だった。GPUがあることと、LLMが快適になることは別の条件だった。今回は追加設定の流れ、つまずいた点、次に試したい改善を記録する。

前回の日本語LLM構築記事の続編。内部IP、ホスト名、コンテナ番号、MACアドレス、利用者名、内部文書URLなど、環境を特定する情報は省いている。

2 GBのVRAMでもLLMを動かせる。ただし全体が載るとは限らない

モデルファイルだけを見て「2 GB未満ならGPUに収まる」と考えると、実際の必要メモリを見誤る。推論にはモデルの重みに加え、会話の情報を保持するKVキャッシュや作業領域も必要になる。コンテキスト長や同時処理数によっても必要量が変わる。

今回のQwen3 1.7Bは量子化モデルだが、Ollamaの表示では43%/57% CPU/GPUの部分割り当てとなった。この57%はGPUの利用率や速度向上率を意味しない。モデルの処理をCPUとGPUに分けているという確認材料になる。

設定は、GPU確認・ホストのドライバー・コンテナへの接続の順に

まずProxmoxホストでGPUの世代と現在のドライバーを調べる。既存環境ではオープンソースのnouveauが使われていた。Vulkan方式も試したが、導入したMesaとGPUの組み合わせでは実GPUが列挙されず、CPUのソフトウェア実装しか見えなかった。この結果は、Vulkan方式全般が使えないという意味ではない。

lspci -nnk | grep -A3 -E "VGA|3D|Display"
ls -l /dev/dri/by-path

最終的にはCUDA方式を選んだ。対象はMaxwell世代なので、580系列のプロプライエタリ・ドライバーを使用した。GPUの世代と対応系列は、導入時にOllamaのGPU対応表とNVIDIAのカーネルモジュール選択資料で確認する。新しいドライバーを選べば旧GPUも使えるとは限らない。

ホストには動作中のProxmoxカーネルに対応するヘッダーとDKMS、ビルド環境を用意し、対応するNVIDIA公式ドライバーを組み込む。コンテナにはホストと同じバージョンのユーザー空間ライブラリを入れる。LXCはホストのカーネルを共有するため、コンテナ内にカーネルモジュールを重ねて入れる構成にはしない。

その後、Proxmoxのデバイス割り当てでNVIDIAのGPU本体・制御・UVM用デバイスを接続する。コンテナ内のOllamaユーザーが必要なグループに所属し、読み書きできることも確認する。デバイス番号やグループ番号は環境によって異なるので、実際の値を調べて指定する。今回は非特権LXCを維持し、特権化やnestingの有効化は行っていない。

# 以下はOllamaを動かす環境で実行
nvidia-smi
ollama ps

つまずき1:パッケージがあることと、署名が検証できることは別

旧系列のドライバーを探す過程で、公式リポジトリの署名がOSの現在の検証ポリシーに拒否された。古い署名方式が理由で、鍵を取得するだけでは解消しなかった。署名チェックを無効化する方法は使わず、今回はNVIDIA公式の対応版インストーラーへ切り替えた。

公式インストーラー方式は、通常のAPTパッケージ管理とは更新・削除方法が異なる。DKMSで登録しても、将来のカーネルとの互換性やヘッダーの準備は必要になる。ドライバー更新を自動で任せられる構成になった、とは考えない方がよい。

つまずき2:既存ドライバーがGPUを保持していた

最初の導入では、ビルドが進んでもNVIDIAモジュールを読み込めなかった。nouveauがGPUを使用していたためだった。再起動時にドライバーを切り替える設定と起動イメージを整え、ホストを再起動してから導入を完了した。Proxmox本体の再起動は、そのノードで動くサービスも一時停止するため、作業時間を確保して行う。

また、再起動で一時ディレクトリのインストーラーが消え、再取得が必要になった。再起動を挟む作業では、ファイルの保存場所まで手順に含めておくと再作業を減らせる。

つまずき3:手動では動いても、再起動後にコンテナが止まる

最も大切だったのは、ホストを再起動した後の確認だった。GPUの起動準備サービスはactiveでも、必要なデバイスファイルがすべて作られておらず、LXCが起動に失敗した。UVMの補助デバイスだけでは足りず、GPU本体と制御用デバイスも必要だった。

最終的にはGPUデバイスの作成とnvidia-smiによる初期化を、Proxmoxのゲスト起動処理より前に実行するsystemdサービスへ整理した。修正後に再起動し、コンテナ自動起動、Ollama/Open WebUIの稼働、日本語API応答、Web画面のHTTP 200を確認した。サービスのactive表示だけで完了とせず、利用する側が動くことまで確認するのが重要だった。

速度比較:今回はGPU併用が約12%遅かった

条件は同じモデル、コンテキスト2048、思考モード無効、temperature=0、出力上限64トークン。CPU専用ではnum_gpu=0、GPU併用ではnum_gpu=16を指定した。「ローカルLLMの利点を日本語で3文説明する」という同じ指示を使用した。

条件生成時間生成速度全体時間
CPU専用5.41秒11.83 tok/s11.82秒
GPU併用・切替後6.15秒10.41 tok/s13.23秒
GPU併用・継続実行6.17秒10.37 tok/s6.41秒

各回とも生成数は64トークン。生成速度はeval_count ÷(eval_duration / 1,000,000,000)で求めた。全体時間はモデル読み込みや入力処理なども含むtotal_durationで、生成速度と分けて見る。GPUの継続実行で全体時間が短くても、それだけでCPUより生成が速いという結論にはならない。

比較の途中では、CPU専用の試験設定を次の呼び出しも引き継ぎ、GPUと名付けた試験がCPUで動く問題もあった。GPU条件を明示し、ollama psの割り当てを確かめて再測定した。ラベルより実際の使用状態を確認する必要がある。

この結果は短い単一プロンプトによる少数試行で、統計的な性能評価ではない。出力上限で文章が切れるため、品質評価とも分けて扱う。初回ロード、CUDA初期化、キャッシュ、温度、swap、他のサービスの負荷が影響し得る。旧GPUの性能やCPU/GPU間の処理が制約になった可能性はあるが、原因ごとの寄与を実測したわけではない。

今後の展望:小さいモデル、設定の見直し、推論の分離

まずは普段の日本語質問を揃え、CPU/GPUを複数回測る。モデルをロードした直後と継続実行を分け、生成速度だけでなく最初の応答までの時間、全体時間、メモリや温度も記録する。CPU専用の方が用途に合うなら、GPUを使わず運用する判断もできる。現在の設定はGPU有効のままで、CPU運用への切り替えはまだ実施していない。

次に、より小さな量子化モデルで全体をGPUへ載せられるか試したい。例えば0.6B級を比較候補にできるが、日本語の自然さや指示への追従も一緒に評価する必要がある。小さいモデルなら必ず速く、十分な品質になるとは限らない。この比較は今後の作業になる。

設定面では、短い会話で思考モードを省くこと、必要以上にコンテキストを増やさないこと、モデルの再読み込みを減らすことが候補になる。今回think=falseはAPI試験だけで、ブラウザチャットの既定設定は変更していない。思考表示を隠すだけでは計算量は減らない。keep_aliveによる保持も、主にロード待ちを減らす調整である。設定の基準はOllama公式FAQで確認できる。

より大きな改善が必要なら、対象モデルに十分なVRAMとメモリ帯域を持つGPU、あるいは強いCPUの推論専用機を検討する。必要な容量はモデル、量子化、会話の長さ、同時利用から決める。今回の結果だけを理由に機器を購入する段階ではない。

Open WebUIと会話履歴を現在の環境に残し、Ollamaの推論だけ別マシンへ移す構成も有力だ。接続元の制限や認証を含めて設計すれば、画面と計算資源を別々に更新できる。今回その移行は行っていない。

今回得られたのは、次の判断に使える実測

VRAM 2 GBの旧GPUでも、日本語LLMへ計算を割り当てることはできた。再起動後の復旧まで確認し、CPUとGPUを比較できる土台も整った。一方で、高速化は達成していない。長時間運転、複数ユーザー負荷、バックアップの復元、将来のカーネル更新への追従は未検証として残っている。

次は「GPUが動いた」という確認から、用途に合う応答時間と品質を選ぶ段階へ進みたい。手元の機器を測って使い分け、必要になった時点でモデルや推論マシンを変える。その順番が、今回の実験から見えた現実的な道筋だった。