結果、初日から派手に転びました。今日はその話です。
まず結論
やったことは2つです。
- Mac miniで35B級のモデルを動かし、別のノートPCのAIコーディングツールから、ネットワーク越しに使う体制を作った(学習プランで「第2幕」と呼んでいた構成の実現)
- そして「こんにちは」と挨拶しただけで、モデルが暴走した
この事故から得た教訓を一行にすると、こうです。
ブレーキは、一番外側に付ける。
手元のアプリを強制終了しても、向こうのマシンは走り続けている。
ついに実現した「机の上の35B」
まず、うれしい部分から。今回組んだのは、こういう構成です。
ノートPC(手元):AIにコードを書かせるツール(aider)
↓ ネットワーク越し
Mac mini(サーバー役):35B級のモデルが常駐
これで、非力なノートPCから、家に置いた大きなモデルを呼んで開発できます。クラウドではなく、自分の家のマシンの中にある知性を、別の端末から使う——学習プランに「所有している知性」と書いた形が、ようやく目に見える形になりました。
ちなみに動かしたのは、Apple Silicon向けに最適化された形式のモデルです。48GBのメモリを買った理由が、ここでやっと使われ始めました。
そして、挨拶しただけで暴走した
感激もつかの間、事故は最初の一言で起きました。「こんにちは」と打っただけで、AIが文字を延々と吐き出し続けて止まらなくなったのです。
慌てて手元のツールを強制終了しました。ところが——Mac mini側のモデルは、動き続けていました。
教訓①:生成は「向こう側」の仕事だった
ここが今回いちばん大事な理解です。初学者向けに構造から説明します。
私は「手元のツールがAIを動かしている」と思っていました。でも実際は違いました。考えて文章を作る作業は、全部Mac mini側で起きています。手元のツールは、お願いを送って、返事を受け取っているだけの窓口です。
だから窓口を閉じても、工場は動き続ける。電話を切っても、向こうで作業が止まるわけではないのと同じです。止めるには、Mac mini側に「やめろ」と言いに行く必要がありました。
これは以前、外出先からスマホで自宅のMac miniを操作したときに学んだ「スマホは窓でしかない、実体は向こうにある」と、まったく同じ構造です。同じ教訓が、今度は事故の形で戻ってきました。
教訓②:なぜ「こんにちは」で暴走したのか
原因は2つ重なっていました。どちらも面白いので書いておきます。
(1) モデルが「型」に引きずられた
コードを書かせるツールは、裏側で毎回「お前はプログラマだ。ファイルの中身を丸ごと出力しろ」という長い指示を送っています。そこに「こんにちは」と来ると——出力すべきファイルが存在しない。すると賢さの足りないモデルは、それっぽいファイルを延々と創作し続けます。「終わり」の合図を出すきっかけを、自分で見失ってしまうわけです。
(2) 手元のツールが、そのモデルを知らなかった
画面には、こんな警告が出ていました。「このモデルの上限が分かりません。適当な初期値を使います」。
有名なクラウドのモデルなら、ツール側が「最大どれだけ出力してよいか」を知っています。でも自分で入れたローカルのモデルは知らない。結果、「何文字で打ち切れ」という指示が送られておらず、モデルは走り放題でした。
教訓③:ブレーキは「一番外側」に付ける
再発防止として3か所を直しましたが、優先順位がはっきりしていました。
- モデル側(サーバー)に、出力の上限を設定する ← 最重要
- 手元のツールに、モデルの素性(上限値)を教える
- そもそも、コードを書かせるツールに雑談を振らない
なぜ1番が最重要か。理由は明快でした。サーバー側で止める仕組みがなければ、どのクライアントから繋いでも、同じ事故が起きるからです。手元のツールの設定は、その端末でしか効きません。
これは「原因究明より検知」「見張り番はどこに置くか」といった、これまで考えてきたことと同じ発想でした。安全装置は、末端ではなく元栓に付ける。
そして3番は設定ではなく運用の話ですが、効果は一番大きいかもしれません。相談はチャット用のモデルへ、コードはコーディングツールへ。道具ごとに役割が違うことを、身をもって学びました。
もう一つの収穫:AIが書いたスクリプトを、遠慮なく実行できる場所
同じ日、もう一つ大きな環境を手に入れました。Dockerで「壊してもいい作業場」を作ったことです。
ローカルのモデルにスクリプトを書かせると、当然ながら怪しいものも出てきます。実行するのが怖い。でも実行しないと確かめられない。この板挟みが、初学者にとって最大の足かせでした。
解決策が、使い捨てのコンテナです。オプションを一つ付けて起動すると、終了した瞬間に、その環境ごと消えます。中で何を壊しても、Mac本体には何も残らない。実際、今日それを1周体験しました。
作って、使って、壊す。
失敗のコストがゼロになると、試す回数が増える。
ただし、ここには重要な線引きがあります。コンテナに「Mac側のフォルダを見せる」設定をすると、そこだけは本物です。中で消せば、本当に消えます。
今日いちばん頭に残った一行が、これでした。
壊れて困るものは、見せない場所に置く。中は好きに壊す。
「コンテナだから安全」ではなく「見せていない部分が安全」。この区別さえ守れば、開発環境は消耗品になります。
おわりに ── 2ヶ月待った意味
ローカルLLMを2ヶ月後回しにしたことを、私はずっと「順番の判断」だと自分に言い聞かせてきました。今日それが、思わぬ形で報われた気がしています。
もしこれを、Mac miniが届いた初日にやっていたら——暴走に慌てて、原因も分からないまま「ローカルLLMは使えない」で終わっていたと思います。
でも今日の私は、この2ヶ月で「サイレント故障」を何件も駆除し、「証拠を切り分ける」型を身につけていました。だから「クライアントを殺しても止まらない=生成は向こう側で起きている」という構造まで、その場で理解できた。道具より先に、道具の壊れ方を読む力のほうが育っていたわけです。
相棒との生活は、こうして始まりました。初日から暴走されましたが、悪くない滑り出しだと思っています。
ローカルLLM / LM Studio / aider / Docker / Mac mini
このブログでは、ローカルLLM・Aider・個人開発の試行錯誤をそのまま記録しています。
