はじめに
ローカル LLM の高速化の記事を読むと、設定が山ほど出てきます。-b、-ub、-fa、KV キャッシュの量子化、投機デコード、プロンプトキャッシュ……。
実際に全部試してみると、効くものはごく一部でした。効かないものもあれば、逆に遅くなるもの、入れたつもりで最初から無効だったものもあります。
このシリーズで測ってきた結果を、1 枚の早見表にまとめます。
環境: Ryzen AI 9 HX 370 / Radeon 890M(iGPU)/ DDR5-5600 96GB / Windows 11 / llama.cpp b11026(Vulkan)/ Qwen3.6-35B-A3B(Q4_K_XL)。別の機体やモデルでは、結果が変わる可能性があります。
大きく効く: この 2 つで決まる
| 設定 | 結果 | 詳しく |
|---|---|---|
| Vulkan バックエンド | 生成が CPU の 5.2 倍(2.59 → 13.41 t/s)。ROCm(4.76 t/s)より 2.8 倍速い | 構築の回 |
| MoE モデルを選ぶ | 密 27B に比べて生成 5.7 倍、読み込み 9.5 倍 | 〃 |
この 2 つで、速度はほぼ決まります。ほかの設定は、ここから 1〜3 割を上乗せする程度です。
MoE が速いのは、1 トークンごとに読むデータが少ないからです。iGPU の生成速度はメモリの帯域でほぼ決まるので、「総パラメータ数」や「ファイルサイズ」ではなく、**「1 トークンあたり何バイト読むか」**でモデルを選ぶのが正解でした。ファイルが 4.5 GB 大きい MoE のほうが、密モデルより 5.7 倍速かったのはそのためです。
効く: 入れて損はない
| 設定 | 結果 | 詳しく |
|---|---|---|
MTP 投機デコード(--spec-type draft-mtp --spec-draft-n-max 2) |
散文 +12.6%、コード +33.4%。出力は変わらない | 構築の回 |
-b 8192 |
読み込み(プロンプト処理)+26%(281 → 353 t/s)。16384 では微減 | 〃 |
127.0.0.1 で接続する |
接続 1 回あたり 2.1 秒 → 0.05 秒。自分の llm は 5.3 秒 → 1.0 秒 |
下記 |
同じ文書に質問を重ねる(既定の --cache-prompt) |
128K の文書で、初回 17.6 分 → 別の質問は 10.7 秒 | キャッシュの回 |
localhost ではなく 127.0.0.1 に繋ぐ
いちばん手軽で、いちばん見落としやすいものです。
Windows では localhost がまず IPv6(::1)に解決されます。llama-server は IPv4(127.0.0.1)でしか待ち受けていないので、繋がらずに IPv4 へ切り替わるまで 2 秒ほど待たされます。
| 接続先 | PowerShell | Python |
|---|---|---|
localhost |
2.10 秒 | 2.29 秒 |
127.0.0.1 |
0.05 秒 | 0.03 秒 |
短い質問なら、応答時間の大半がこの待ち時間になります。クライアント側の URL を書き換えるだけで消えます。
自分の llm コマンドも localhost のままだったので、直して測りました。
localhost |
127.0.0.1 |
|
|---|---|---|
llm "1+1は?"(PowerShell) |
5.1〜5.6 秒 | 1.0〜1.2 秒 |
| dev-orchestra 用の CLI(Python) | 4.9 秒 | 0.8 秒 |
縮んだのは 2 秒ではなく 4 秒でした。どちらも「サーバが動いているかの確認」と「質問の送信」で 2 回接続していて、その両方で 2 秒ずつ待たされていたためです。
同じ文書に質問を重ねる
長い文書の読み込みは重く、128K トークンで 17.6〜24.2 分かかりました。ただし、同じ文書に別の質問をするなら、読み直すのは末尾の 515 トークンだけです。
これは既定で有効な --cache-prompt の働きで、何も設定しなくても効きます。効かせるコツは、文書を先に、質問を最後に置くこと。文書の途中を書き換えると、全部読み直しになります。
条件つき: 場面によって得になる
| 設定 | 結果 | 詳しく |
|---|---|---|
K だけ q8_0(-ctk q8_0) |
128K では +6〜11%。32K では差なし(−3.5〜+2.0%)。正答率は変わらない | 128K の回、読み取り品質の回 |
| thinking | 定型の課題では正答率が同じで、時間 3.1 倍・トークン 3.9 倍 | thinking の回 |
K の量子化は、100K を超える長い文書を扱うときだけ得になります。普段の 2 万トークン前後では速くならないので、既定では入れていません。
thinking は、定型の課題(計算、日付、単位変換)では正答率が変わらず、時間だけが 3 倍になりました。既定では切り、難しそうな質問のときだけ有効にしています。難しい問題で差が出るかは、まだ測っていません。
効かない: 入れても変わらない
| 設定 | 結果 | 詳しく |
|---|---|---|
-ub(マイクロバッチ) |
512〜2048 のどれでも横ばい | 構築の回 |
-fa on(FlashAttention) |
速度は誤差の範囲 | 〃 |
mmproj を外す(--no-mmproj) |
速度の差は 3% 未満。メモリは 1.1 GiB 減る | mmproj の回 |
-b と -ub はセットで紹介されることが多いのですが、効いていたのは -b のほうだけでした。
mmproj は画像を読むための部品です。テキストしか使わないなら外しても困らず、メモリが 1 GiB 浮きます。速くはなりません。
逆効果: 入れると遅くなる
| 設定 | 結果 | 詳しく |
|---|---|---|
| MTP の n-max を上げる(4、6) | n-max 6 で散文が −28%。投機なしより遅い | 構築の回 |
V を q8_0(-ctv q8_0) |
測ったどの深さでも遅い(32K で −9.7%、128K で −5.4%) | ベンチのぶれの回、128K の回 |
投機デコードは「たくさん先読みするほど速い」わけではありません。外れた先読みは捨てるので、予測しにくい散文では、先読みを増やすほど無駄な計算が増えます。2 が最適でした。
KV キャッシュを量子化するなら、K だけにします。V まで量子化すると遅くなります。
使えない: 入れたつもりで無効
| 設定 | 結果 | 詳しく |
|---|---|---|
--cache-reuse |
このモデルでは最初から無効。起動ログに not supported と出る |
キャッシュの回 |
| スロットのディスク保存・復元 | 保存・復元はできるが、復元後は全部読み直し | 〃 |
| NPU | llama.cpp に NPU のバックエンドが無い | NPU の回 |
いちばん危ないのがこの段です。
--cache-reuse は、私も「効いている」と記事に書いていました。実際には起動ログにこう出ていて、最初から無効でした。
srv load_model: cache_reuse is not supported by multimodal, it will be disabled
画像用の mmproj を外しても、今度は not supported by this context で無効になります。Qwen3.6-35B-A3B は SSM とのハイブリッド構成で、KV をずらして使い回す仕組みとは両立しないためです。ディスクへの保存が効かないのも、同じ構造が理由でした。
設定を入れたら、起動ログを見る
最後に、この表を作って得た一番の教訓です。
入れた設定が本当に有効かは、起動ログで確かめる。
llama-server は、使えない設定を黙って無効にすることがあります。エラーにはならず、起動もするので、ログを読まない限り気づけません。私は --cache-reuse で 4 日間気づきませんでした。
llama-server ... 2>&1 | Select-String 'not supported|disabled|ignor'
この表の「使えない」段は、そうやって見つけたものです。
まとめ
- 速度は Vulkan(5.2 倍) と MoE(5.7 倍) でほぼ決まる。残りは 1〜3 割の上乗せ
- 手軽に効くのは MTP(n-max 2)、
-b 8192、127.0.0.1で接続、文書を先・質問を後 - K の量子化と thinking は場面による。V の量子化と大きな n-max は逆効果
-
--cache-reuseは、このモデルでは無効。設定は起動ログで確かめる
この記事は tk3.biz のブログ からの転載です。