0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nvidia-smiの出力だけでLLM推論のボトルネックを特定する — 3つの数値と判断フローチャート

0
Posted at

「遅い」の原因が分からないまま設定を変えていないか

ローカルLLMが遅い。-nglを上げてみる。コンテキスト長を下げてみる。量子化を変えてみる。どれかで速くなったらラッキー、ならなかったら「8GBでは限界」と諦める。

これは問題の切り分けができていない。

nvidia-smiの出力には、ボトルネックがGPU演算なのかメモリ帯域なのかVRAM容量なのかを判別するのに十分な情報がある。3つの数値を読むだけで、次に何をすべきかが決まる。この記事はそのフローチャートを提供する。


読むべき3つの数値

nvidia-smiの出力から注目すべきはこの3つだけ:

+-------------------------+
| GPU-Util:        XX%    |  ← ① GPU使用率
| Memory-Usage: XXXX/8188MiB |  ← ② VRAM使用量
| Power:          XX.XW   |  ← ③ 消費電力
+-------------------------+

この3つの組み合わせで、ボトルネックの種類が特定できる。


判断フローチャート

① GPU-Util を確認
  │
  ├─ 90%以上 → GPU演算律速(正常。これ以上はハードウェア上限)
  │   └─ ③ Power確認
  │       ├─ TDP近い(140-150W) → サーマルスロットリング確認
  │       └─ TDP未満 → 正常動作。速度はこれが上限
  │
  ├─ 50-90% → 部分的ボトルネック
  │   └─ ② VRAM確認
  │       ├─ 95%超 → VRAM枯渇。KVキャッシュかモデルを縮小
  │       └─ 95%未満 → CPU-GPU転送律速。-nglを上げるべき
  │
  └─ 50%未満 → GPUが遊んでいる
      └─ ② VRAM確認
          ├─ 95%超 → VRAM枯渇でGPUに仕事が来ない。-nglを下げるかctxを縮小
          └─ 50%未満 → モデルの大半がCPU上。-nglが低すぎる

パターン別: 何が起きていて何をすべきか

パターンA: GPU-Util 95%、Power 68W、VRAM 5.2/8GB

診断: 正常動作。GPUが全力で推論しており、VRAMにも余裕がある。

意味: これがこの構成の最大速度。もし「遅い」と感じるなら、ハードウェアの限界に達している。量子化を下げる(Q4_K_M → IQ4_XS等)か、モデルサイズを下げる以外の選択肢はない。

RTX 4060 + Qwen2.5-7B Q4_K_Mの場合: GPU-Util 90%超、VRAM ~5.3GB、残り~2.7GB。この状態で60-75 tok/s前後が出ていれば正常。


パターンB: GPU-Util 40%、Power 45W、VRAM 7.8/8GB

診断: VRAM枯渇。GPUは仕事をしたいが、VRAMが足りずにデータを待っている。

原因: KVキャッシュがVRAMを圧迫している。コンテキスト長を上げすぎたか、エージェントのツール呼び出しでトークンが蓄積している。

対処:

  1. コンテキスト長を下げる(-c 8192-c 4096
  2. KVキャッシュを量子化する(--cache-type-k q8_0 --cache-type-v q8_0
  3. FlashAttentionを有効化する(--flash-attn
  4. それでもダメなら-nglを2-3下げてGPU上のモデル層を減らし、KVキャッシュにVRAMを譲る

見分け方: nvidia-smiを1秒間隔で監視しながら推論すると、VRAM使用量がトークン生成とともに漸増していく。これが見えたらKVキャッシュ膨張。

# 1秒間隔でVRAMを監視
nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits --loop=1

パターンC: GPU-Util 30%、Power 35W、VRAM 3.5/8GB

診断: GPU-CPU転送律速。GPUに載っている層が少なすぎて、大半の演算がCPU上で行われている。

原因: -nglの値が低い。モデルの重みの多くがCPU RAM上にあり、GPU→CPU→GPUのデータ転送がボトルネックになっている。

対処: -nglを段階的に上げる。OOMが出る直前の値が最適。

14Bハイブリッドの場合: Qwen2.5-14B Q4_K_M (48層) で-ngl 30だとGPU-Util 40%程度。-ngl 35に上げるとGPU-Util 70%以上に跳ね上がることが多い。この差が速度に直結する。


パターンD: GPU-Util 95%、Power 148W、VRAM 6.0/8GB

診断: サーマルスロットリング寸前。GPUは全力で動いているが、TDP上限に張り付いており、温度が上がるとクロックが落ちる。

原因: ラップトップGPUに多い。RTX 4060 Laptopの定格TDPは115-140W(メーカー設定による)。長時間推論で筐体内温度が上昇すると、GPUがクロックを自動的に下げて発熱を抑える。

対処:

  1. ラップトップの排熱を改善する(冷却台、室温管理)
  2. GPU温度を監視する: nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader --loop=1
  3. 83℃を超えてクロックが下がるようなら、バッチサイズを下げるか、推論の間にクールダウン時間を入れる
  4. 根本的にはデスクトップGPUへの移行が解決策

Sustained性能の重要性: ピーク75 tok/sが出ても、5分後にサーマルスロットリングで50 tok/sに落ちるなら、実効速度は50 tok/s。ベンチマーク(短時間測定)と実運用(30分以上の連続推論)で速度が違うのはこれが原因。


パターンE: GPU-Util 0%、Power 15W、VRAM 500/8MB

診断: GPUがLLM推論に使われていない。CPU上で全演算が行われている。

原因:

  • CUDAが認識されていない(ドライバの問題)
  • llama.cppがCPU版ビルドで動いている
  • -ngl 0で起動している

確認方法:

# CUDAが使えるか確認
nvidia-smi
# llama-serverのログでGPUオフロードを確認
# "offloaded X/Y layers to GPU" が出ていれば正常

対処: CUDA対応バイナリを使っているか確認。GitHub Releasesのcuda付きZIPをダウンロードする。


監視の自動化

手動でnvidia-smiを見る代わりに、推論中に自動判定するスクリプト:

import subprocess
import time

def diagnose_gpu(threshold_util=50, threshold_vram_pct=95):
    """nvidia-smiの出力からボトルネックを診断"""
    result = subprocess.run(
        ["nvidia-smi", 
         "--query-gpu=utilization.gpu,memory.used,memory.total,power.draw,temperature.gpu",
         "--format=csv,noheader,nounits"],
        capture_output=True, text=True
    )
    
    if result.returncode != 0:
        return "ERROR: nvidia-smi failed"
    
    values = result.stdout.strip().split(", ")
    gpu_util = float(values[0])
    mem_used = float(values[1])
    mem_total = float(values[2])
    power = float(values[3])
    temp = float(values[4])
    vram_pct = mem_used / mem_total * 100
    
    # 診断
    if gpu_util >= 90:
        if temp >= 83:
            return f"⚠ サーマルスロットリング (GPU {temp}℃, {power}W)"
        return f"✅ 正常 (GPU-Util {gpu_util}%, VRAM {vram_pct:.0f}%, {power}W)"
    elif gpu_util >= threshold_util:
        if vram_pct >= threshold_vram_pct:
            return f"🔴 VRAM枯渇 (VRAM {vram_pct:.0f}%, GPU-Util {gpu_util}%)"
        return f"🟡 CPU転送律速 (GPU-Util {gpu_util}%, VRAM {vram_pct:.0f}%) → -ngl上げるべき"
    else:
        if vram_pct >= threshold_vram_pct:
            return f"🔴 VRAM枯渇でGPU遊休 (GPU-Util {gpu_util}%, VRAM {vram_pct:.0f}%)"
        return f"🟡 GPU未活用 (GPU-Util {gpu_util}%, VRAM {vram_pct:.0f}%) → -ngl低すぎ"

# 推論中に5秒間隔で診断
for _ in range(12):
    print(f"{time.strftime('%H:%M:%S')} {diagnose_gpu()}")
    time.sleep(5)

nvidia-smiが暴く「意外なVRAM消費者」

フローチャートでVRAM枯渇と診断されたとき、「モデルもKVキャッシュも計算上は入るはずなのに」と思ったら、LLM以外の何かがVRAMを食っている。nvidia-smiのプロセスリストを見ると犯人が見つかる。

# VRAMを使っているプロセスを全表示
nvidia-smi --query-compute-apps=pid,name,used_memory --format=csv

8GB環境で実際にハマりがちな犯人たち:

犯人1: LM Studio / Ollama のバックグラウンド常駐

LM StudioやOllamaは、UIを閉じてもモデルをVRAMに保持し続ける。7Bモデルをロードしたまま忘れていると、それだけで4-5GBが消費される。llama-serverを起動した時点でVRAMが足りずにOOMになる。

発見方法: nvidia-smiのプロセスリストにollama_llama_serverLM Studioが残っている。

対処: 使い終わったらOllamaはollama stop、LM Studioはモデルをアンロード。タスクマネージャーでプロセスが残っていないか確認。

犯人2: ブラウザのGPU加速

Chrome、Edge、FirefoxはデフォルトでGPU加速が有効。タブを大量に開いていると200-500MBのVRAMを消費する。YouTubeやGoogle Mapsを開いたタブがあるとさらに増える。

発見方法: nvidia-smichrome.exemsedge.exeが表示される。

対処: LLM推論中はブラウザを閉じるか、GPU加速を無効にする(chrome://flags/#use-angle → Disabled)。ただし常時無効にするとブラウザ描画が遅くなる。

犯人3: Windows DWM(デスクトップ合成)

Windowsのデスクトップウィンドウマネージャー(dwm.exe)は、ディスプレイ合成にGPUを使う。これだけで200-400MBのVRAMを常時消費する。消せない。

意味: 8GBのうち「LLMに使える量」は実質7.5-7.6GB。よく「8GBに4.7GBのモデルを載せるとKVキャッシュに3.3GB使える」と計算するが、実際は2.9-3.1GB。この差がctx 8192で効いてくる。

犯人4: 画面共有・録画ツール

Discord、OBS、GeForce Experienceの画面キャプチャやオーバーレイはGPUリソースを消費する。Discordの画面共有中にLLM推論を回すと、目に見えて速度が落ちる。

対処: LLM推論中はDiscordの画面共有を切る。GeForce Experienceのインスタントリプレイも同様。

犯人5: 前回のllama-serverが残っている

llama-serverをCtrl+Cで止めたつもりが、プロセスが残っていることがある。次のllama-serverを起動するとVRAMが二重消費される。

# llama関連プロセスを確認
tasklist /fi "imagename eq llama*"

このフローチャートで解決できないケース

すべてが正常に見える(GPU-Util 90%、VRAM余裕あり、サーマルOK)のに遅い場合:

  1. モデルが本当に遅い: 一部のモデルはアーキテクチャ上、同パラメータ数の他モデルより遅い。別モデルで比較する
  2. prefill律速: 長いプロンプトを処理するprefillフェーズはcompute律速。GPU-Utilが高いのは正常だが、prefill中はトークン生成が始まらない。--prompt-cacheでprefillを省略できる
  3. バックグラウンドプロセス: ゲーム、ブラウザ(GPU加速)、動画再生がVRAMを消費している。nvidia-smiのプロセスリストで確認

結論: 「遅い」の前にnvidia-smiを開け

nvidia-smiの3つの数値(GPU-Util、VRAM使用量、Power)を見れば、次に何をすべきかが分かる。設定を闇雲に変えるのは時間の無駄だ。

  1. GPU-Util 90%超: 正常。これ以上はハードウェア限界。モデルを小さくするか、GPUを買い替える
  2. VRAM 95%超: KVキャッシュかモデルサイズを削る。--flash-attn--cache-type-k q8_0を試す
  3. GPU-Util 50%未満: -nglを上げる。GPUに仕事を与える

このフローチャートを頭に入れておけば、ローカルLLMの「遅い」を体系的に潰せる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?