RTX4060(8GB)構成で、メインメモリを32GBから96GBに増やしても、また全滅した話。ローカルLLM全滅記2
前回の記事の最後に、こう書きました。「次は、メモリを増やしてからかな」。
その「次」を、今回やっと試しました。結論から言うと、また全滅しました。ただ、今回の全滅は前回より収穫が多くて、原因もかなり深いところまで追えました。せっかくなので、吐き出されたエラーメッセージやログの数字を、できるだけそのまま残しておきます。
前回のあらすじ
前回の記事は、8GBのGPU(RTX4060)でローカルLLMにClaude Codeを喋らせようとして、8Bクラスのモデルが軒並み指示に従えず、最後は13GB級のモデルを無理やり動かしてPCごとフリーズさせて終わりました。
原因は「GPUのVRAMが足りない」「逃げ場のメインメモリも薄い」の二重苦。だから「次はメモリを増やしてから」と締めていました。
今回、そのメインメモリを32GBから96GB近くまで増設しました。これで前回の悪夢は終わる、はずでした。
前回の構成
メインメモリ 32GB ホスト10GB ゲスト22GB
今回の構成
メインメモリ 96GB ホスト64GB ゲスト32GB

上の図が今回の一部始終です。フリーズという分かりやすい壁は越えたものの、その先に「無反応」「食い違い」「今度は遅すぎる」という3段の壁が新しく出てきました。順番に見ていきます。
今回はフリーズではなく「無反応」だった

まず試したのは、7Bクラスの多言語対応モデルでした。ロードは無事終わって、画面には「準備完了」の表示。「今日は何日?」と打ち込みました。
返ってきたのは、何もない。画面の隅でスピナーがくるくる回るだけで、いつまで待っても文字が出てこない。前回はPCごとフリーズして操作すらできなくなりましたが、今回はマウスも動くし、他の作業もできる。ただ、この一言への返事だけが、永遠に来ない。
「動いてはいるっぽいけど、なんも喋らない」。この時点では、まだ楽観していました。
ログを見たら、静かに数字だけがおかしくなっていた
裏のログを覗いてみると、地味な数字が並んでいました。実際に吐かれたエラーの全文はこうです。
500 The number of tokens to keep from the initial prompt is greater than the context length (n_keep: 38369 >= n_ctx: 32768). Try to load the model with a larger context length, or provide a shorter input.要するに「最初にAIへ渡す指示書きが、そもそも部屋(コンテキスト)の広さより大きい」というエラーです。部屋の広さは32768(トークンという単位の器の大きさ)に設定していたのに、渡そうとした指示書きは38369。最初から入りきらない量を、無理やり押し込もうとしていたことになります。
そしてClaude Codeは、このエラーを「一時的な不調」だと判断したらしく、1秒後、3秒後、9秒後、27秒後と、間隔を伸ばしながら黙って10回まで再送信していました。何も表示されないまま裏で10回殴り続けていたので、こちらからは「反応がない」としか見えなかった。これが「無反応」の正体でした。

図にすると、こういうことです。32768という器に対して、38369という指示書きを押し込もうとして、はみ出た分がそのままエラーになっていました。
「並列数が怪しい」と思ったら、見事に外れた
最初に疑ったのは、AIサーバー側の「並列処理数」の設定でした。1つの部屋(32768)を、同時に処理できる数(4)で分け合っているせいで、実質は32768÷4=8192くらいしか使えていないんじゃないか、と。
並列数を4から1に変えて、部屋を独り占めさせてみました。もう一度、同じ質問。
結果は、まったく同じ500エラー。この仮説は外れました。試す前にちゃんと裏を取らず、もっともらしい仮説をそのまま口に出してしまったのは、正直な反省点です。

並列数を4から1に変えても、エラーの中身は1文字も変わりませんでした。もっともらしい仮説ほど、検証をサボりたくなるので気をつけたいところです。
会話を始める前から、4万7千使っていた
ここで、Claude Code自身に「今どれだけ部屋を使っているか」を聞いてみました。会話はまだ一言も交わしていない、起動直後の状態です。返ってきた内訳はこうでした。
・基本の指示書き: 8.9k
・道具(ファイル操作など)の説明: 14.1k
・記憶しているメモ類: 19.5k
・使えるスキルの一覧: 4.8k
・合計: 47.3k
会話をまだ何もしていないのに、47,300。さっき見たエラーの38,369よりもさらに大きい数字です。これはもう「渡す指示書きを削れば直る」というレベルの話ではなく、そもそも「会話が始まる前の初期装備だけで、7Bモデルの部屋の広さをとっくに超えている」ということでした。
念のため、Claude Codeの指示書き(いわゆる設定ファイル)を一切置いていない別フォルダでも同じことを試しましたが、結果は同じ500エラー。指示書きの量を減らしても意味がない、というのも確認が取れました。初期装備そのもの(道具の説明やスキル一覧)が、もう十分に重かったということです。

内訳を積み上げてみると、一言も話していない時点で47.3kという厚みがあることが分かります。指示書きを削る努力は、ここでは的外れでした。
同じモデルを、別のサーバーソフトで動かしたら通った
ここで、AIモデルを読み込ませるサーバーソフトを変えてみました。同じモデルファイルを、別のソフトで読み込む形です。部屋の広さの設定は変わらず32768。
すると今度は、エラーが出ずに(嫌な予感がしつつも)応答が返ってきました。実際のサーバー側のログにも、こんな記録が残っていました。
new prompt, n_ctx_slot = 32768, n_keep = 4, task.n_tokens = 3580
...
stop processing: n_tokens = 3580, truncated = 0送られたトークン数は3580、9080、11533、535と、どれも32768より小さく、`truncated`(削って捨てた量)もすべて0。つまり今度はちゃんと部屋に収まる量で送れていました。
ただし、肝心の中身はさんざんでした。「今日は何日?」と聞いているのに、質問には答えず、AIの設定ファイルの断片をそのまま復唱してくるだけ。日本語で聞いているのに、途中から中国語が混ざる始末。
500エラーは消えたのに、中身は使い物にならない。「動く」という言葉の意味が、さっきまでとまるで違っていました。

トークン数もエラー無しも「正常」に見えるのに、返ってくる文章だけが的外れ。数字が正常なことと、会話が成立することは、まったく別の話だと思い知らされました。
犯人は「トークン数を数えるAPI」の食い違いだった
ここが、今回いちばんの発見でした。
さっきの、500エラーを出していた方のサーバーソフトのログを、もう一度見直してみます。すると、こんな一行がありました。
Received request: POST to /v1/messages/count_tokens with body {
Unexpected endpoint or method. (POST /v1/messages/count_tokens?beta=true). Returning 200 anywayClaude Codeは、本番の質問を送る前に「これから送る指示書き、何トークンある?」と事前に数えさせるAPIを呼んでいるようでした。ところが最初のサーバーソフトは、このAPIに対応していません。にもかかわらず、返事の番号は200(「成功」を意味する番号)を返してしまっていました。中身は「対応してないエンドポイントです」というエラー文なのに、番号だけは成功、というちぐはぐな返事です。
一方、応答が返ってきた方のサーバーソフトのログを見返すと、同じAPIへのリクエストが一件も記録されていませんでした。
念のため、両方のサーバーへ直接同じリクエストを送って確かめてみました。
・最初のサーバー: 番号200、中身は「対応してないエンドポイントです」というエラー文
・もう一方のサーバー: 素直に404(「そんなページはありません」)
Claude Codeは、たぶん番号だけを見て成功と失敗を判断しています。404を返すサーバーには「このAPIはないんだな」と正しく理解して、自前の見積もりだけで送信し、結果的に部屋の広さに収まる量で送れていました。一方、200番を返してしまうサーバーには「トークン数、ちゃんと数えられた」と勘違いして、実際には数えられていない状態のまま突っ込んで送ってしまい、部屋の広さを超えていた。そういう筋書きです。
エラーの中身までは見ずに、番号だけで話が成立したりしなかったりする。地味ですが、けっこう怖い食い違いでした。

同じ質問を両方のサーバーへ直接投げて比べると、この食い違いは一目瞭然でした。番号だけを信じると足をすくわれる、という良い実例です。
せっかくなので、大きいモデルも試した(メモリ増設、ここで初登板)
ここでようやく、今回の主役であるメモリ増設の出番です。前回、13GB級のモデルを動かしてPCごとフリーズさせた、あの一件がありました。今回は同じモデルを、メモリを増やした状態で、部屋の広さも最大まで広げて動かしてみました。
結果、フリーズはしませんでした。メモリの使用量は最大でも7割程度で、危険な水域には入りませんでした。ここは素直に、増設の成果です。
ただし「今日は何日?」と聞いてから答えが返ってくるまで、21分かかりました。GPU(8GBのVRAM)には収まりきらず、大部分をCPUとメインメモリで処理していたためです。
しかも答えの中身は、ちゃんと正しい日付でした。質問にきちんと答えて、指示にも従えている。さっきまでの7Bクラスの支離滅裂さとは、はっきり違う出来でした。
21分。フリーズはしない。答えは合っている。でも、実際にコードを書かせる作業では、この往復が何十回も発生します。21分かける何十回は、さすがに現実的ではありません。おまけに、答えが返ってきた後もしばらくGPUが唸り続けていて、裏で別の処理が走っていた形跡もありました。理由は結局分からずじまいです。

フリーズしなくなった代わりに、待ち時間という別の壁に姿を変えただけでした。
21分の正体を、確かめてみた
これだけ待たされると、「このモデル自体が遅いのでは」と思いたくなります。念のため、Claude Codeを介さず、AIモデルを動かすソフト自身のチャット画面で同じモデルに直接「今日は何日ですか?」と聞いてみました。
返ってきたのは9.3秒。しかも正しい日付でした。
21分と9.3秒。同じモデル、同じPCで、これだけ差が出ました。つまり遅かったのはモデルの「頭の回転」ではなく、Claude Codeが毎回律儀に送ってくる、あの4万7千トークン超のシステムプロンプトを読み込む「準備運動」の方だったわけです。以前見たログの処理速度(1秒間に80〜100トークンくらい)から逆算すると、4万7千トークンを読むだけで9〜10分かかる計算になり、実際に見えていた待ち時間ともほぼ一致しました。
モデルを大きいのに変えても、賢いのに変えても、Claude Code側が持ち込む荷物の重さが変わらない限り、この準備運動の時間は消えてくれません。
ついでに、最初にハマった7Bモデルの方も、同じように単体で聞いてみました。すると、また違う顔を見せてきました。
Ollamaで動かした方は、約10秒で「現在の日付は2023年10月25日です」と、自信満々に間違った日付を返してきました。これは単に学習した時点の感覚で答えているだけで、よくあるAIの限界です。破綻はしていません。
ところが、別のサーバーソフト(LM Studio)で同じ系統のモデルを動かして聞くと、0.28秒で「お答えできかねますが、現在の日付や曜日を知るためには、パソコンやスマートフォンなどのデバイスをチェックしてください」と、分からないことを正直に認めてきました。しかもPythonでの取得コードまで添えて。
もう一度Ollama側で聞き直すと、今度は1.7秒で「現在の日付は2023年10月25日です。お QUERY 的您想知道今天的日期是哪一天呢?答案就是2023年10月25日。如果您需要更具体的信息或其他帮助,请告诉我哦!」という、日本語と中国語がぐちゃぐちゃに混ざった返事が来ました。
同じ系統の重みのはずなのに、動かすソフトが変わるだけで、誠実さも言語の一貫性もここまで変わる。Claude Code越しに見えていた「システムプロンプトの断片を復唱する」「中国語が混ざる」という壊れ方は、Claude Codeのせいというより先に、動かし方そのものに埋め込まれていた不安定さだったようです。

3つを並べてみると、それぞれ違う理由で全滅していたのがよく分かります。同じ「ダメ」でも、原因は毎回別物でした。
分かったこと
・メモリを増やせば「フリーズ」は防げる。でも、それだけでは「使い物になる速さ」にはならない
・部屋の広さ(コンテキスト)は、会話を始める前の初期装備だけで軽く使い切れる。指示書きを削っても、初期装備そのものが大きければ意味がない
・サーバーソフトごとに「トークン数を数えるAPI」への対応が違い、その食い違いがそのままエラーの出方の違いになる
・遅さの正体は「モデルの頭の回転」ではなく「Claude Codeが毎回持ち込む荷物(システムプロンプト)の重さ」だった。単体では10〜30秒程度で答えるモデルが、Claude Code経由だと21分かかる
・同じ系統の重みでも、動かすソフトが変わるだけで誠実さや言語の一貫性が変わる。壊れた挙動の一部は、Claude Codeより先に動かし方そのものに埋め込まれていた
そもそも、前提が間違っていたかもしれない
ここまで書いてきて、根っこのところで考え直しました。
「ローカルの小さいモデルは遅くて実用にならない」。今回の調査は、ずっとこの前提の上に立っていました。でも、単体で聞けば10〜30秒程度で答えが返ってくる。これは、実用に値する速さです。
遅かったのは、モデルではなく、Claude Codeという器の方でした。Claude Codeは、クラウドの大きなモデルを前提に組まれた、かなり重装備なハーネスです。ツールの説明、記憶しているメモ、使えるスキルの一覧。これを毎回律儀に全部持ち込む作りは、クラウドの大きなモデルには誤差でも、手元の小さなモデルには致命傷になります。
だとすると、次にやるべきことは、モデル選びではなく器選びなのかもしれません。もっと身軽なコーディング用のエージェント(例えばopencodeのようなもの)を経由すれば、この重装備を持ち込まずに済む可能性があります。そうなれば、今回全滅したモデルたちも、また違う結果を見せてくれるかもしれません。
それでも、まだ諦めきれていない
今回も、結局クラウドのモデルに戻ることになりました。ただ、前回の「全滅」と今回の「全滅」、そしてこの最後の気づきは、それぞれ中身がまったく別物です。フリーズという物理的な限界から、応答速度という実用面の限界へ。そして最後に、そもそも土俵の選び方を間違えていたかもしれない、というところまで来ました。
ちょうど自作しているツールMANY-AI-CLIでローカルLLMを快適に使えることを出発点に始めたこのRTX4060で動かす計画ですが、複数のAIエージェントに役割を割り振って動かす仕組みを実装予定です。AIエージェントの垣根を取っ払った、オーケストレーション機能を今後実装予定なんです。v0.4.0予定です。2026/07/10までにはリリースできればと考えています。
実装役・テスト役・レビュー役、みたいに分担させる機能です。これまでは全部Claude CodeやCodexに任せていましたが、コードを書くだけの実装役なら、身軽なエージェント経由でローカルの小さいモデルに任せてもいいのかもしれません。レビューは今まで通り大きいモデルに厳しく見てもらって。
次は、その役割分担を試してみようと思います。その結果は、また別の記事で。RTX4060(8GB)で快適にローカルLLMを動かす夢はまだ諦めていません。次回に続きます。
※ ヘッダー画像とインフォグラフィックは AI(画像生成)で作成しています。
書いた人: ishizakahiroshi
群馬の北部で、保護猫2匹と暮らす、在宅エンジニア(何でも屋)
https://github.com/ishizakahiroshi
X(業務委託・各種相談はこちら)
バックエンド・インフラ・AI連携まわりで、業務委託のご相談を受け付けています。フルリモートです。スポットや週2〜3時間からでも歓迎で、いろんな案件に携われたらうれしいです。こんな相談、歓迎です。
