DEV Community

plasmon
plasmon

Posted on • Originally published at qiita.com

llama.cppの設定で8GBの性能が5倍変わる — 主要オプションの最適値を出した

llama.cppの設定で8GBの性能が5倍変わる — 主要オプションの最適値を出した

llama.cppの起動オプションは50以上ある。そのほとんどはデフォルトのままでいい。だが8GB VRAMでは、5つのオプションの設定ミスが推論速度を半分にする。

以下は、RTX 4060 8GB (GDDR6 272 GB/s) での推定値(公開ベンチマーク・公式ドキュメント・VRAM使用量の理論計算から算出)に基づく設定ガイドだ。個別環境で数値は変動する。


最重要: -ngl (GPUレイヤー数)

-ngl はTransformerレイヤーのうちいくつをGPU VRAMに載せるかを決める。デフォルトは0(全レイヤーCPU = 最も遅い)。999を指定すると全レイヤーGPU(VRAMに収まれば最速)。モデルごとの総レイヤー数: Qwen2.5-7B = 28、Llama-3-8B = 32、Qwen2.5-32B = 64。

8GB VRAMでの最適値

モデル                              -ngl   VRAM使用    速度       備考
────────────────────────────────────────────────────────────────────────────
Qwen2.5-7B Q4_K_M (4.7GB)          999    ~5.4 GB    ~32 t/s    全28レイヤーGPU
Mistral-Nemo-12B Q4_K_M (7.2GB)    999    ~7.5 GB    ~20 t/s    KVでOOMの可能性。-c 2048推奨
Qwen2.5-32B Q4_K_M (18.5GB)         25    ~7.4 GB    ~10.8 t/s  64層中25をGPU、残りCPU
Enter fullscreen mode Exit fullscreen mode

-ngl を1変えるだけで速度が数%変わる。最適値は「VRAMをぎりぎりまで使い切る」値だ。

最適値の探し方(二分探索):

  1. -ngl 999 で起動。OOMなら次へ
  2. -ngl {総レイヤー数/2} で起動
  3. OOMなければ増やす、OOMなら減らす
  4. VRAMが7.0-7.5GB使用で安定する値が最適

RTX 4060 8GBの場合、0.5GBはCUDAコンテキスト+フレームワークに取られるため、実質7.5GBをモデルに使える。nvidia-smi でVRAM使用量を監視しながら調整するのが確実。7.8GB以上は推論中のOOMリスクがある。


-c (コンテキスト長)

-c は推論時に参照できるトークン数の上限。デフォルトは4096(llama.cpp v b8233)。KVキャッシュのVRAM消費に直結する。

KVキャッシュの計算式: KV cache = 2 × n_layers × n_kv_heads × head_dim × context_len × dtype_bytes

KVキャッシュのVRAM消費 (FP16)

コンテキスト長    Qwen2.5-7B (28層, 4 KV heads)    Qwen2.5-32B (64層, 8 KV heads)
─────────────────────────────────────────────────────────────────────────────────
4,096 tokens     0.22 GB                            1.00 GB
8,192 tokens     0.44 GB                            2.00 GB
32,768 tokens    1.75 GB                            8.00 GB
131,072 tokens   7.00 GB                            —
Enter fullscreen mode Exit fullscreen mode

-ngl で部分オフロード時、KVキャッシュもレイヤー単位でCPU/GPUに分散される。-ngl 25 の場合、GPU上のKV = 25/64 × 上記値。

8GB VRAMでの推奨:

  • 7Bモデル: -c 8192(KV 0.44GB、安全)、-c 32768(KV 1.75GB、flash-attn推奨)
  • 32Bモデル(-ngl 25): -c 4096(GPU上KV ~0.39GB)、それ以上はKV量子化必須

コンテキスト長を倍にするとKVキャッシュのVRAMも倍になる。8GBでは -c の設定が載せられるモデルサイズを直接決める。


--cache-type-k / --cache-type-v (KVキャッシュ量子化)

量子化オプション: f16(デフォルト、2 bytes/element)、q8_0(1 byte、VRAM半減)、q4_0(0.5 bytes、VRAM 1/4)。

推奨組み合わせ

プロファイル          K cache    V cache    VRAM倍率    品質劣化
──────────────────────────────────────────────────────────────────
品質重視              f16        f16        1x          なし
バランス (推奨)       q8_0       q8_0       0.5x        ほぼなし (一般タスク)
容量優先              q4_0       q8_0       0.375x      数学・推論で劣化あり*
最大圧縮              q4_0       q4_0       0.25x       顕著。長コンテキストで悪化

* V cacheはK cacheより量子化に弱い
Enter fullscreen mode Exit fullscreen mode

実例: Qwen2.5-32B + -ngl 25 + 8Kコンテキスト on 8GB

-ngl 25 ではGPU上のレイヤーが25/64、KVも25/64がGPU上に置かれる。

  • KV全体 (f16, 8K): 2.00 GB → GPU上: 2.00 × 25/64 = 0.78 GB
  • GPU合計 (f16): 重み7.4 + KV 0.78 + overhead 0.3 = 8.48 GB → OOM
  • KV q8_0にすると: 0.78 × 0.5 = 0.39 GB → 7.4 + 0.39 + 0.3 = 8.09 GB → 動く
  • 32Kコンテキスト (f16): GPU上KV = 3.13 GB → 不可能。q4_0でも8.48 GB → ギリギリ

起動コマンド:

llama-server -m model.gguf -ngl 25 -c 8192 --cache-type-k q8_0 --cache-type-v q8_0
Enter fullscreen mode Exit fullscreen mode

--flash-attn (Flash Attention)

Flash Attentionはメモリ効率の高いAttention計算アルゴリズム。Attentionの中間バッファが不要になり数百MB節約、長コンテキストで高速化する(32Kで約10%)。4Kトークン以下では効果は小さい。要件はCUDA backend + RTX 20xx以降。KVキャッシュ量子化と併用可能。

設定 (Qwen2.5-7B Q4_K_M)      速度          VRAM       差分
──────────────────────────────────────────────────────────────
-c 8192, flash-attn OFF        31.8 t/s      5.6 GB     —
-c 8192, flash-attn ON         32.1 t/s      5.3 GB     +1%, -0.3 GB
-c 32768, flash-attn OFF       28.5 t/s      7.2 GB     —
-c 32768, flash-attn ON        31.5 t/s      6.5 GB     +10.5%, -0.7 GB
Enter fullscreen mode Exit fullscreen mode

常に有効にすべき。デメリットなし。

--flash-attn はデメリットがない。常に付けておくべきオプションだ。


-b (バッチサイズ) と -t (スレッド数)

-b (batch size): prompt evaluation時に一度に処理するトークン数。デフォルト2048。8GBでは512推奨——バッチが大きいとprompt eval中のVRAMスパイクでOOMリスクがある。-ub (micro batch) はデフォルト512で変更不要。

-t (threads): CPU演算に使うスレッド数。デフォルトは全コア。推奨は物理コア数(HTなし)。HTの論理スレッドはメモリ帯域を食い合うだけ。例: i7-13700Hなら -t 6(Pコア6つ)。

スレッド数の影響 (Qwen2.5-32B Q4_K_M, -ngl 25)

-t 設定                  速度
──────────────────────────────
-t 6  (Pコア数)          10.8 t/s
-t 8  (P+Eコア)          10.5 t/s
-t 14 (全物理コア P+E)    9.8 t/s
-t 20 (HT含む全スレッド)  9.2 t/s
Enter fullscreen mode Exit fullscreen mode

スレッド数を増やせば速くなるという直感は間違っている。HTの論理スレッドはL1/L2キャッシュとメモリ帯域を分け合うため、LLM推論ではオーバーヘッドになる。


サーバー用オプション (llama-server)

基本コマンド: llama-server -m model.gguf -ngl 999 -c 4096 --host 0.0.0.0 --port 8080

推奨追加オプション:

  • --flash-attn — メモリ効率化(常にON)
  • --metrics — Prometheus形式のメトリクス公開
  • --parallel 1 — 同時リクエスト数(8GBでは1推奨)
  • --cont-batching — Continuous batching(--parallel 2 以上で有効)

Function calling

--chat-template はGGUF内のテンプレートを自動検出する。function callingの tools パラメータはモデルのchat templateに依存する。推奨モデル: Qwen2.5-3B-Instruct Q4_K_M(2.0GB、軽量高速)、Qwen2.5-7B-Instruct Q4_K_M(4.7GB、品質と速度のバランス)。

構造化出力

--grammar-file でGBNF文法ファイルを指定すると、出力形式を強制できる。JSON出力の構文エラーが0%になる。ただし文法に合わない出力を生成しようとすると推論が遅くなることがある。llama.cpp b7000以降では --json-schema でJSON Schemaを直接指定する方法もある。


設定テンプレート集

テンプレート1: 7Bモデル、会話用 (最速)

llama-server \
  -m qwen2.5-7b-instruct-q4_k_m.gguf \
  -ngl 999 \
  -c 8192 \
  --flash-attn \
  -t 6 \
  --host 127.0.0.1 --port 8080
# 期待速度: ~32 t/s, VRAM: ~5.4 GB
Enter fullscreen mode Exit fullscreen mode

テンプレート2: 32Bモデル、品質重視 (部分オフロード)

llama-server \
  -m qwen2.5-32b-instruct-q4_k_m.gguf \
  -ngl 25 \
  -c 4096 \
  --cache-type-k q8_0 --cache-type-v q8_0 \
  --flash-attn \
  -t 6 \
  -b 512 \
  --host 127.0.0.1 --port 8080
# 期待速度: ~10.8 t/s, VRAM: ~7.4 GB
Enter fullscreen mode Exit fullscreen mode

テンプレート3: 7Bモデル、長コンテキスト (32K)

llama-server \
  -m qwen2.5-7b-instruct-q4_k_m.gguf \
  -ngl 999 \
  -c 32768 \
  --cache-type-k q8_0 --cache-type-v q8_0 \
  --flash-attn \
  -t 6 \
  -b 512 \
  --host 127.0.0.1 --port 8080
# 期待速度: ~31 t/s, VRAM: ~6.9 GB (flash-attn有効時)
Enter fullscreen mode Exit fullscreen mode

テンプレート4: 3Bモデル、function calling用 (軽量高速)

llama-server \
  -m qwen2.5-3b-instruct-q4_k_m.gguf \
  -ngl 999 \
  -c 4096 \
  --flash-attn \
  -t 6 \
  --host 127.0.0.1 --port 8080
# 期待速度: ~50 t/s, VRAM: ~2.5 GB
# 7Bと併用可能(合計VRAM ~8GB)
Enter fullscreen mode Exit fullscreen mode

よくある失敗と対処

問題                    症状                          原因                                対処
──────────────────────────────────────────────────────────────────────────────────────────────
-ngl 0 (GPU未使用)     推論速度 3-5 t/s              全レイヤーCPU。DDR5がボトルネック    -ngl 999 → OOMなら減らす
-c が大きすぎる        推論開始直後にOOM              KVキャッシュがVRAM圧迫              -c 4096 or --cache-type-k q8_0
-t が多すぎる          CPU 100%なのに遅い             HT論理スレッドが帯域を食い合い      -t を物理コア数に
--mlock 使用           起動時メモリエラー             モデル全体RAMロック→物理メモリ不足   --mlock を外す (Windows特に不要)
バッチサイズ過大       長プロンプトでOOM              prompt eval中のVRAMスパイク          -b 512
Enter fullscreen mode Exit fullscreen mode

設定による速度差のまとめ

設定変更                          速度影響        VRAM影響
──────────────────────────────────────────────────────────
-ngl 0 → 999 (全GPU)             +5-10x          +4-7 GB
-ngl 最適値の探索 (±5)           +10-20%         ±0.5 GB
--flash-attn 有効化               +1-10%          -0.3 GB
--cache-type q8_0                 ±0%             -50%
-t 全スレッド → 物理コア数        +5-15%          ±0
-c 32K → 4K (7B model)            +5%             -1.5 GB
-b 2048 → 512                    ±0%*            -0.2 GB**

* 生成速度には影響しない (prompt eval時間のみ)
** prompt eval中の一時的なVRAMスパイクを抑制
Enter fullscreen mode Exit fullscreen mode

最も影響が大きいのは -ngl。次に -t。その他は微調整。8GB VRAMでは「-nglを最大化し、-cとKVキャッシュ量子化でVRAMを確保する」が基本戦略だ。


参考文献

  1. llama.cpp — github.com/ggerganov/llama.cpp
  2. llama.cpp Server documentation — github.com/ggerganov/llama.cpp/tree/master/examples/server
  3. GGUF format specification — github.com/ggerganov/ggml/blob/master/docs/gguf.md
  4. Flash Attention — "FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning" (2023) arXiv:2307.08691

Top comments (0)