MENU

ローカルLLMが遅い原因はHDDだった|プライムセールで買ったM.2にVMごと引っ越したら132秒→9秒、約15倍速に

木の机の上に置かれたM.2 NVMe SSDと奥のHDD・グラフィックボードに、「ローカルLLMが遅い原因はHDD」「132秒→9秒」「約15倍速」「M.2にVMごと引っ越し」の文字と、HDD 132秒・M.2 9秒の横棒グラフを重ねたアイキャッチ画像

プライムセールで、Samsungの990 PRO(1TB)が安くなっていました。「Proxmoxのマシン、M.2の差し込み口が空いてたよな……」と思い出して、深く考えずにポチりました。

買ったのはこちら:Samsung 990 PRO 1TB(MZ-V9P1T0B-IT、ヒートシンクなし)をAmazonで見る

届いたので取り付けて、RTX 3080 TiでローカルLLMを動かしているVMを、HDDからまるごと引っ越してみました。すると、LLMに頼んでから返事が来るまでが132秒 → 9秒。約15倍です。効果てきめんでした。

正直、ここまで変わるとは思っていませんでした。遅かったのはGPUのせいではなく、ディスクからモデルを読み込む時間だったんです。この記事では、引っ越しの手順と、M.2を足したらGPUを渡しているVMが起動しなくなった件もあわせてまとめます。

Proxmoxに3080 Tiをつないだ話は、前回の記事に書いています。

前回の記事
ProxmoxでRTX 3080 TiをGPUパススルー|Ubuntu・OllamaでローカルLLMを動かしてみたProxmoxでRTX 3080 TiをUbuntuへGPUパススルーし、OllamaでQwen3 8Bを動かした記録。PCIマッピングの設定、IOMMUエラーの復旧、日本語要約の実測時間と回答例を紹介します。
目次

ローカルLLM、呼ぶたびに2分以上待たされていた

前回の記事のあと、ローカルLLMを社内のPCからふだん使いするようになりました。そのうえで、構成をいくつか変えています。

項目前回の記事今回
VMの割り当て4 vCPU・メモリ8GiB・ディスク40GiB8コア・メモリ24GB・ディスク100GB
モデルQwen3 8B(qwen3:8b)qwen3.8:27b-iq3-text(27Bを3ビット相当に量子化。GPUメモリを約10.5GB使用)
使い方Ubuntu内だけで利用社内LANのPCから、自作のゲートウェイ経由でAPIを呼ぶ
GPUの使い道LLMの検証用ふだんは別の用途、呼ばれたときだけLLM

いちばん大きいのは最後の行です。LLMを使わない時間にGPUを遊ばせておくのはもったいないので、ふだんは別の用途に回し、LLMの窓口に依頼が来たときだけ切り替える仕組みを自作しました。

  1. LLMの窓口(自作のゲートウェイ)に依頼が来る。
  2. GPUをほかの用途から切り替えて、Ollamaを起動する。
  3. モデルをGPUに読み込んで、答えを返す。
  4. 30分使われなければ、自動で元の用途に戻る。

仕組みとしては気に入っていたのですが、困ったのが待ち時間です。しばらく間が空いてからLLMを呼ぶと、そのたびにモデルの読み込みからやり直しになります。前回の記事の時点でも、初回の約48秒のうち約44秒が読み込みでした。モデルを大きくした今回は、返事が来るまで2分以上。ちょっと要約を頼むたびにこれでは、さすがに使う気が失せます。

ちょっと要約を頼むだけで、毎回2分以上待ちって……。
そりゃ使う気なくなるよね。

ローカルLLMが遅い犯人は、GPUではなくHDDだった

そもそもこのProxmoxのマシンは、昔使っていたパソコンを作り直して組んだものです。なので、ディスクもそのままハードディスクでした。

それまでのディスクは、WD Redの3TB(WD30EFRX)。NAS向けのHDDで、Proxmox本体も、すべてのVMも、この1台に詰め込んでいました。前回の記事のVMや、Codex用の実験領域も同じHDDの上です。

セールで買った990 PROと、読み込みの速さを仕様値で比べるとこうなります。

ディスク読み込みの速さ(仕様値)
WD Red 3TB(WD30EFRX、HDD)最大 毎秒147MB前後(販売店に掲載の仕様値)
Samsung 990 PRO 1TB(NVMe)最大 毎秒7,450MB(Samsung公式データシート)

仕様値どうしで比べると、約50倍の差です(実際のVM上で測った速度ではありません)。10GB超えのモデルを毎秒150MB前後で読めば、それだけで1分を超えます。NVMeなら、計算上は数秒です。GPUの計算がいくら速くても、モデルがGPUに届くまでの時間はディスクで決まっていました。

M.2を取り付けて、VMごと引っ越した

空いていたM.2の差し込み口に990 PROを取り付けて、引っ越し作業です。やったことは次の3つです。

1. LVM-thinのストレージを用途別に2つ作った

用途容量Codexの権限
実験用(Codexが作るVMなど)600GBあり
ふだん使うPC用200GBなし
予備(未割り当て)約130GB-

HDDのときと同じく、AIのエージェント(Codex)に権限を付けたのは実験用の方だけです。ふだん使うPCの領域には触らせません。残りは、あとでどちらかが足りなくなったら広げられるように空けておきました。

2. VMを止めずにディスクを移した

Proxmoxには、VMを動かしたままディスクを別のストレージへ移す機能があります。管理画面のVMの「ハードウェア」で対象のディスクを選び、「ディスクの動作 → ストレージの移動」(英語表示では Disk Action → Move Storage)、コマンドならqm disk moveです(ディスク名はscsi0などの設定名)。今回は、移動後に元のディスクを消すオプションを付けて実行しました。

qm disk move <VM番号> <ディスク名> <移動先ストレージ> --delete 1

せっかくなので、LLMのVM(100GB)だけでなく、スタッフ用のPC(100GB)、Dockerの試験用(40GB)、ネットワークのルーター用(10GB)の4台をまとめて引っ越しました。VMを止めずに移せるので、使っている人に気づかれずに済むのがありがたいところです。

3. 「SSDエミュレーション」をオンにした

移したディスクの設定で「SSDエミュレーション」をオンにすると、VMの中からSSDとして見えるようになります。Ubuntu側でlsblk -d -o NAME,ROTAを実行して、対象ディスクのROTAが0になっていれば、Ubuntuから回転しないディスク(SSD)として認識されています。あくまで「VMの中からどう見えるか」の設定なので、実際の置き場所がSSDかどうかとは別の話です。

結果:132秒 → 9秒。効果てきめん

GPUをほかの用途で使っている状態からLLMを呼んで、返事が来るまでを比べました。

ローカルLLMに頼んでから返事が来るまでの時間の棒グラフ。引っ越し前のHDDは切り替え36秒とモデル読み込み+回答96秒で合計132秒、引っ越し後のM.2は合計9秒
引っ越し前(HDD)引っ越し後(M.2)
ほかの用途→LLMの切り替え(Ollamaが使えるようになるまで)36秒3秒
Ollamaの準備完了→返事が来るまで(モデルの読み込み+答えを作る)96秒6秒
頼んでから返事が来るまで(全体)132秒9秒

ゲートウェイのログはこうなっていました(時刻はVMの時計でUTC)。

引っ越し前(HDD)
07:35:03 wake: switching GPU to llm mode
07:35:39 wake: ollama ready                ← 切り替えに36秒
07:37:15 "POST /api/chat HTTP/1.1" 200     ← 準備完了から96秒(全体で132秒)

引っ越し後(M.2)
09:59:15 wake: switching GPU to llm mode
09:59:18 wake: ollama ready                ← 3秒
09:59:24 "POST /api/chat HTTP/1.1" 200     ← 準備完了から6秒(全体で9秒)

2分以上待っていたものが、10秒かからずに返ってきます。初めてログを見たときは、何かの間違いかと思って二度見しました。「ちょっと要約して」と気軽に投げられるかどうかは、この差でまったく変わります。セールのついで買いとしては、かなり当たりでした。

え、132秒が9秒!?
何かの間違いかと思って、ログ二度見しちゃった。

測り方と、数字の注意点

  • どちらもVMを起動した直後に測りました。メモリにモデルが残っていない状態どうしの比較です。
  • 頼んだ内容は「短い一言を返して」という、ほぼ同じ短いものです。測定は1回ずつなので、平均ではありません。
  • ツールが示した「答えを作る速さ」は、引っ越し前が毎秒18.0トークン、引っ越し後が毎秒37.0トークンでした。ただ、各1回の短いテストなので、この差までディスクを替えた効果とは言い切れません。参考程度にしてください。はっきり言えるのは「待ち時間」の差です。

引っ越しでつまずいたところ

M.2を足したら、GPUを渡しているVMが起動しなくなった

M.2を取り付けてホストを起動し直すと、いきなりLLMのVMが次のエラーで起動しませんでした。

M.2足しただけなのに、なんでGPUのVMが起動しないの……。

PCI device mapping invalid (hardware probably changed):
'iommugroup' does not match for 'codex-3080ti' (14 != 13)

M.2を増設したあと、GPUのIOMMUグループの番号が13から14に変わったのが原因です。

前回の記事でも同じ種類のエラーが出て、そのときは番号がずれた理由まではわかりませんでした。今回は「部品を足した直後」なので、きっかけははっきりしています。

このエラーは、保存していた機器の情報と今の状態が一致しないため、Proxmoxのリソースマッピングが安全確認のために起動を止めてくれた結果です。ハードウェアが変わったことに気づかないまま起動するのを防いでくれます。今回は、新しいグループ14にGPU本体と付属の音声機能の2つだけが入っていることを確かめてから、マッピングを選び直して解決しました。手順は前回の記事と同じです。

PCIeパススルーをしているマシンに部品を足すと、IOMMUグループの番号が変わることがあります。マッピングを使っていたおかげで、中身を確認してから直せました。

スナップショットがあると、元のディスクを消しながら移せない

you can't move a disk with snapshots and delete the source

スナップショットが残っているVMは、「移動後に元のディスクを消す」付きの移動ができません。古いスナップショットを消してから移しました。毎日NASへProxmoxのバックアップを取っているので、戻せる場所は確保した上での判断です。

移動が途中で失敗すると、使われていないディスクが残る

1台だけ、1回目の移動が途中で失敗していて、M.2側に半分だけ書かれたディスクが残っていました。管理画面からは気づきにくいので、ホストでlvsを実行して見つけ、どのVMからも使われていないことを確かめてから消しました。移動に失敗したときは、移動先に残骸がないか確認しておくと安心です。

SSDエミュレーションは、VMの中からの再起動では効かない

設定を変えたあと、Ubuntuの中から再起動しただけでは反映されませんでした。Proxmox側からVMをシャットダウンし、止まったのを確認してから起動し直す必要があります。

まとめ:ローカルLLMが遅いなら、GPUより先にディスクを疑う

プライムセールで買ったM.2にVMごと引っ越しただけで、ローカルLLMの待ち時間が132秒から9秒になりました。GPUもモデルも同じです。

LLMをずっと読み込んだままにしておく使い方なら、ディスクの速さはあまり関係ありません。ただ、今回のようにGPUをほかの用途と使い分けたり、しばらく使わないとモデルが外れたりする使い方では、呼ぶたびにモデルの読み込みからやり直しになります。今回のモデルは10GB前後あるので、OSのキャッシュに残っていなければ、その分をディスクから読むことになります。ローカルLLMのスペックというと、GPUのメモリばかり気にしがちですが、モデルを置くディスクも効いてきます。「ローカルLLMが遅い」と感じたら、GPUを買い替える前に、モデルがどこに置かれているかを確認してみてください。HDDなら、セールでM.2を1枚買うだけで、体感がまるで変わるかもしれません。

それと、PCIeパススルー中のマシンに部品を足すと、IOMMUグループの番号が変わることがあります。リソースマッピングを使っていれば、変わったときに止めてくれるので、慌てずに番号の中身を確認しましょう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

こんにちは、「雑記.com」運営者のTakaです。
実際に買った・使った・困った・直した・試した経験をもとに、IT・ガジェット・投資・教育などの実体験やトラブル解決をまとめています。
使ってわかったこと、試行錯誤した過程、解決までの具体的な手順を、日々の選択や困りごとの解決に役立つ形で紹介します。

目次