ローカルLLMが動かない。モデルを疑う前に、実行系を疑う

ロードは成功したのに推論だけ500が返る(ローカルLLM 実測)
mausu110

ローカルLLMがロードは成功するのに推論で必ず HTTP 500 を返すとき、モデルではなくバックエンド(実行系)を疑ってください。 私の環境では、llama.cpp のバックエンドを既定の vulkan から rocm に替えただけで、同じモデル・同じ設定が 500 → 200、40.4秒 → 0.8秒 に変わりました。

きっかけは、Qwen3.8-27B の GGUF(Unsloth の UD-Q4_K_XL 量子化・17.2GB)を入れたら、ロードは status: success なのに、推論を投げると毎回エラーが返ってきたことです。私は最初、「このモデルが壊れているんだろう」で片付けかけました。それが原因の1つ手前で止まっていた、というのが今回の話です。

自宅マシンでローカルLLMを動かしていて、「特定のモデルだけ動かない」に当たっている方向けの記事です。

今回の環境と使ったもの

実測はすべて自動取得した値です(手で測ったものではありません)。

  • AMD Ryzen AI MAX+ 395(Radeon 8060S 統合GPU・gfx1151・16コア/32スレッド・物理メモリ 64GB / Windows 11 Home Build 26200)
  • Lemonade 11.6.0 — ローカルLLM を動かすサーバーです。OpenAI 互換の API を出してくれるので、curlchat/completions を叩けます。無料。
  • llama.cpp のビルド — vulkan が b10375、rocm が b10394。これは応答に含まれる system_fingerprint で確認した、実際に動いていた版です。(サーバーの system-info は rocm を b10397 と報告しますが、そちらはダウンロードできる版であって、稼働中の版ではありませんでした。ここも実測しないと分かりません。)
  • llama.cpp — Lemonade が裏で使う推論エンジン。今回の版は vulkan・cpu が b10375/rocm が b10397
  • Qwen3.8-27B-GGUF UD-Q4_K_XL — 今回の問題児。17.2GB・コンテキスト窓 262,144・vision と tool-calling と MTP の3つ持ちという、カタログ値だけ見れば手元のマシンに載る中で一番強そうなモデルでした。
  • Gemma-4-26B-A4B-it-GGUF — 環境が壊れていないかを確かめる比較用。

実測日は 2026-08-24 です。

ロードは成功する。でも推論だけ 500 が返る

まずロード。何の問題もなく通ります。

$ curl -s -X POST $B/api/v1/load -d '{"model_name":"Qwen3.8-27B-GGUF-UD-Q4_K_XL","ctx_size":4096}'
{"status": "success", "model_name": "Qwen3.8-27B-GGUF-UD-Q4_K_XL", "recipe": "llamacpp"}

status: success と言われたら、そりゃ「入った」と思います。ところが推論を投げると、こうです。

$ curl -s $B/api/v1/chat/completions -d '{"model":"...","messages":[...],"max_tokens":32}'
{"error":{"details":{"backend":"llama-server",
  "code":"backend_watchdog_reset",
  "reason":"backend connection failed during request: CURL error: Failure when receiving data from the peer",
  "retryable":true},
  "message":"llama-server was unresponsive and has been reset by the backend watchdog.",
  "type":"backend_error"}}

backend_watchdog_reset。推論の実体である llama-server が応答しなくなり、ウォッチドッグ(応答が無いプロセスを見張って強制的に再起動する仕組み)にリセットされています。

ここが最初の教訓でした。load の成功は「メモリに置けた」だけで、「使える」を意味しません。 実際に1トークン生成させるまで、動いているかどうかは分かりません。

メモリでもなく、環境でもなかった

コンテキスト長を 64分の1にしても変わらない

17.2GB のモデルでコンテキスト窓が 262,144。真っ先に疑ったのはメモリです。コンテキスト長を 4096 まで落として再試行しました。

$ curl -s -X POST $B/api/v1/unload -d '{"model_name":"Qwen3.8-27B-GGUF-UD-Q4_K_XL"}'
$ curl -s -X POST $B/api/v1/load   -d '{"model_name":"Qwen3.8-27B-GGUF-UD-Q4_K_XL","ctx_size":4096}'
# → 推論はやはり 500(backend_watchdog_reset)

262,144 から 4096 へ、64分の1です。それで結果が1ミリも変わらない。メモリ量の問題ではないと、ここで切れました。

なお、この過程で1つ引っかかったところがあります。ロード済みのモデルに load を投げ直しても、ctx_size は上書きされません。 一度 unload してから load し直す必要があります。これを知らずに「下げたのに変わらない」と言っていると、切り分けそのものが嘘になります。

別のモデルなら、同じ環境で普通に動く

次に、Lemonade や GPU ドライバ側が死んでいる可能性を潰します。別のモデルで同じ質問を投げました。

$ # Gemma-4-26B に切り替えて同じ質問
{"choices":[{"finish_reason":"stop","message":{"content":"2"}}], ...}
# → HTTP 200・49.3 tok/s

きれいに返ってきます。49.3 tok/s。環境は正常で、落ちるのは特定のモデルだけ。

……ここで私は「やっぱりこのモデルが悪い」に傾きました。これが早とちりでした。

バックエンドを替えたら、あっさり動いた

「LM Studio では動く」が決定的なヒントだった

一応、モデルの配布元(Hugging Face)の discussion を読みに行きました。同じ症状の報告は複数ありました。

  • llama.cpp を使うとトークン生成中にクラッシュする」という報告が複数
  • ただし同じ人が「LM Studio では動く」とも書いていた
  • 配布元からの回答や修正版の案内は無し

この2行目です。落ち着いて考えると、話が変わります。

モデルのファイルが壊れているなら、どの実行系で開いても読めないはずです。 実行系によって結果が変わるなら、壊れているのはモデルではなく、モデルと実行系の組み合わせの側ということになります。

私が持っていた切り分けの軸は「モデル」と「メモリ」の2本だけでした。ここでようやく 3本目の軸=実行系(バックエンド) が出てきます。

rocm に替えて、同じ質問を投げる

Lemonade は load のときに llamacpp_backend を指定できます。既定の vulkan から rocm に替えてみました。

$ curl -s -X POST $B/api/v1/load \
    -d '{"model_name":"Qwen3.8-27B-GGUF-UD-Q4_K_XL","ctx_size":4096,"llamacpp_backend":"rocm"}'
{"status": "success"}

$ # 同じ質問を投げる
{"choices":[{"finish_reason":"stop","message":{"content":"2"}}],
 "system_fingerprint":"b10394-680a9ae63"}
# → HTTP 200・0.8秒

拍子抜けするほど普通に返ってきました。同じモデル・同じ ctx_size: 4096・同じマシン・同じ日で並べるとこうです。

バックエンドロード推論所要
rocm成功(21.9秒)HTTP 200・正答0.8秒
vulkan(既定)成功(22.5秒)HTTP 50040.4秒
バックエンドを替えただけで結果が分かれた実測の比較
バックエンドを替えただけで結果が分かれた実測の比較

念のため、rocm 側は続けて3回投げました。3回とも 200 で、3回とも正しく答えます(0.8秒 / 0.4秒 / 0.4秒)。たまたま通ったわけではありません。

違いはバックエンドだけです。 ロード時間は 21.9秒 と 22.5秒 でほぼ同じ、つまり「読み込めているかどうか」では両者に差が無い。それが推論の瞬間に 200 と 500 に分かれます。

「動かないモデル」ではなく「このバックエンドでは動かないモデル」だったわけです。

念のため書いておくと、これはこの環境(gfx1151)で、このモデルで、この日の版でそうだった、という話です。rocm が vulkan より常に優れている、という一般化はできません。逆のケースもあり得ます。大事なのは「どちらが優れているか」ではなく「軸を1つずつ動かして確定させる」ことです。

同じ罠を踏まないための4つ

  1. load が成功しても「入った」と判断しない。 必ず短い推論を1回通してから判断します。今回の症状は、ロードだけ見ていると絶対に見つかりません。
  2. 動かないとき、モデルを疑う前に実行系を疑う。 同じ GGUF ファイルでも、バックエンドが違えば結果が違います。
  3. 「別のツールでは動く」という報告は、モデルではなく実行系が原因だという強い手がかり。 私はこの1行を読むまで、モデルのせいにして終わるところでした。
  4. 切り分けは1軸ずつ変える。 モデル・コンテキスト長・バックエンドを1つずつ動かして、どれが効いているかを確定させます。2つ同時に動かすと、何が効いたのか永遠に分かりません。

この記事が役に立つ人・そうでもない人

こういう人に効きます今のままでいい人
ローカルLLMで「特定のモデルだけ動かない」に当たっているクラウドのAPIだけ使っている
AMD の統合GPU(Radeon / gfx1151)で動かしている使っているモデルが全部そのまま動いている
GUIツールではなく API 経由で回しているLM Studio など、実行系が固定された GUI で満足している
新しいモデルを次々試したい動くモデル1本で用が足りている

特に4行目です。新しいモデルほど、実行系側の対応が追いついていない可能性があります。 カタログ値が魅力的なモデルほど新しく、新しいほどこの罠に当たりやすい、という構図になっています。

まとめ

カタログ値だけ見れば最適に見えたモデルが、既定の設定では1文字も生成しませんでした。一方で、設定を1つ替えるだけで 0.8秒で答えます。この差はカタログのどこにも載っていません。実際に動かしてみるしかない、というのが今回の結論です。

一番の収穫は、切り分けの軸が1本増えたことでした。「モデル」「メモリ」に加えて「実行系」。ローカルLLMは、モデルのファイルとエンジンとドライバが積み重なった上で動いているので、どの層で壊れているかを分けて考えないと、平気で1つ手前の結論に着地します。

次は、rocm と vulkan で動くモデル同士の速度がどう違うのかを測ってみようと思っています。今回は「動く/動かない」の差が大きすぎて、性能の比較になっていないので。

ABOUT ME
やまさん
やまさん
へっぽこITエンジニア
ねずみさんを愛するインフラエンジニア。 とにかく最新が好きで、ココロオドル体験を日夜求め続けています! 直近だとドローンにハートを撃ち抜かれてます。 空を自由に飛びたいな♪
記事URLをコピーしました