【ITニュース解説】I Built a Self-Hosted ChatGPT on My Laptop. Here's What Broke.
2026年11月02日に「Dev.to」が公開したITニュース「I Built a Self-Hosted ChatGPT on My Laptop. Here's What Broke.」について初心者にもわかりやすく解説しています。
ITニュース概要
ノートPCに自己ホスト型LLMプラットフォームを構築した経験談。サイレントなプロンプト切り捨て、Webサーバーとは異なるLLMのスケーリング特性など、構築中に直面した課題とその解決策を詳細に解説する。
ITニュース解説
あるDevOpsエンジニアが、AI技術の経験を問われることが増えたことから、単にAIのAPIを呼び出すだけでなく、大規模言語モデル(LLM)を自身でホストし、本格的なサービスのように提供するプラットフォームを構築するという目標を立てた。これは、APIキーの発行、利用制限、使用状況の記録など、プロのシステム構築経験を積むことを目的とした挑戦である。この挑戦は「OzAI」と名付けられ、MacBook Pro M1 Pro(16GB RAM)というラップトップ上で、オープンウェイトのLLM(Qwen3 8BとQwen2.5-Coder 3B)を利用して進められた。自らモデルを訓練したわけではなく、既存の優れたモデルをいかに効率良く、そして安定して提供するかに焦点が当てられた。
OzAIプラットフォームは、いくつかの主要なソフトウェアで構成される。まず「Ollama」はLLMを実行する役割を担う。Macの性能を最大限に引き出すため、Dockerコンテナ内ではなくmacOS上で直接Ollamaを動かし、MacのGPU(Metal)を利用して高速な処理を実現した。次に「LiteLLM」は、外部からのアクセスを管理するゲートウェイとして機能する。これはOpenAIのAPIと互換性があり、ユーザーごとの仮想APIキー発行、特定のモデルへのアクセス許可・制限、利用頻度の上限設定、リクエストログの記録機能を提供する。そして「Open WebUI」は、ユーザーがChatGPTのようにLLMと対話するためのインターフェースである。さらに、モデルが最新の情報に基づいて回答できるよう、「SearXNG」という自己ホスト型の検索エンジンも組み込まれた。これらのコンポーネントは、Ollamaを除いてDocker Composeでまとめて起動され、外部に公開されずにラップトップの内部ネットワークでのみアクセス可能になっている。
構築を始める前に、LLMの基本的な性能測定が行われた。これにより、モデルがどれくらいの速さで応答を生成できるかが明らかになった。特に、より大きな「8B」モデルが小さな「3B」モデルよりも遅いことが判明した。これは、モデルがトークンを生成する際に、モデルのデータ(重み)をメモリから読み出す頻度が高く、メモリの読み書き速度(メモリ帯域幅)が処理のボトルネックとなるためである。また、「量子化」という技術により、本来16GBのRAMが必要な8Bモデルが5.2GBという小さなサイズに圧縮され、16GBのRAMを持つラップトップでも動作可能になったことも説明されている。
このプロジェクトでは、多くの課題に直面し、そのたびに解決策を模索していった。 一つ目の課題は、Qwen3モデルが回答の前に内部で「思考」プロセスを行うことで、応答に時間がかかりすぎることだった。さらに、生成するトークンの上限を低く設定すると、思考だけでトークンを使い切り、肝心の回答が空になってしまう問題も発生した。これに対する解決策として、同じQwen3モデルに対し、「思考をオフにした高速なバージョン」と「思考をオンにした深く考えるバージョン」という二つの別名(エイリアス)を設定した。これにより、ユーザーは質問の性質に応じて適切なモデルを選べるようになった。
二つ目の課題は、LiteLLMのキー管理で「最大予算:0ドル」と設定したテストキーが、ローカルモデルへのアクセスまで全て拒否してしまうことだった。これは、「0ドル以上の費用は認めない」という設定が、「現在の費用が0ドルである=予算を超過している」と誤って判断されたためである。この問題は、セルフホスト型のモデルでは予算設定を空にするか、トークンあたりのカスタム価格を設定することで回避された。
三つ目の課題は、チャットUI(Open WebUI)が、ユーザーの次の入力の邪魔をしているように感じられたことだ。ログを調べると、UIがユーザーへの回答後、チャットのタイトル生成、タグ付け、追従質問の提案といったバックグラウンドタスクを同じLLMに送っていたことがわかった。これにより、ユーザーが次の質問を入力しようとしても、モデルがこれらのバックグラウンドタスクで占有され、応答が遅れていたのである。解決策として、Open WebUIの設定を変更し、これらのバックグラウンドタスクを小型の3Bモデルに振り向け、不要な機能はオフにすることで、応答速度を改善した。
四つ目の課題は、ユーザーが複数になった場合のスケーラビリティの問題である。負荷テストの結果、ユーザーが増えてもLLM全体のトークン生成速度はほぼ一定で、ユーザーが増えれば増えるほど、個々のユーザーの待ち時間が増加することが判明した。これは、LLMサーバーが一度に一つのリクエストしか処理できないような動作をしているためであり、一般的なウェブサーバーのようにユーザーが増えれば処理能力が自動的に向上するわけではないという、DevOpsエンジニアにとって重要な教訓となった。
五つ目の課題は、LLMが自信満々に間違った情報を答えたり、学習データが古いために最新の出来事を知らなかったりする点である。この問題に対処するため、「RAG(Retrieval Augmented Generation)」という手法が導入された。これは、モデルが質問に答える際に、事前に外部の情報源(SearXNGによるWeb検索)から関連する情報を取得し、それをモデルに与えて回答を生成させる方法である。これにより、モデルは自分の記憶だけに頼らず、与えられた最新の事実に基づいて回答できるようになり、回答の正確性が大幅に向上した。
六つ目の課題は、Web検索を有効にしてもモデルが「ライブデータにアクセスできない」と回答し続けるという、原因不明の現象だった。ログを詳しく調べると、プロンプトのトークン数が常に2,050トークンで固定されていることが分かった。これは、本来のプロンプトがもっと長いにもかかわらず、Ollamaがプロンプトの先頭部分を警告なしに「サイレントに切り捨てていた」ためであることが判明した。Open WebUIは検索結果をプロンプトの先頭に配置していたため、検索結果が常に切り捨てられ、モデルに届いていなかったのである。この問題は、ゲートウェイのモデル設定に num_ctx: 8192 を追加し、Ollamaのコンテキストウィンドウを拡張することで解決した。この経験から、「LLMサービングでは、エラーが出ないからといって正しく動作しているとは限らない」という重要な教訓が得られた。つまり、トークン数や回答の品質を常に監視することが不可欠である。
七つ目の課題は、IDE(統合開発環境)との連携、特にコード補完機能において発生した。VS CodeのContinue拡張機能を使ってLLMをコード補完に利用しようとした際、チャット機能はゲートウェイ経由で問題なく動作したが、コード補完が期待通りの振る舞いをしなかった。これは、LiteLLMゲートウェイがコード補完に必要な特殊なパラメータをOllamaに適切に渡していなかったためであることが分かった。この問題を解決するため、チャット機能はゲートウェイ経由で利用しつつ、コード補完については直接Ollamaを呼び出すように経路を分けるというトレードオフの選択がされた。
この一連の経験を通じて、DevOpsエンジニアとしてLLMインフラに携わる者への重要なアドバイスがいくつか示されている。APIキー、利用制限、ルーティング、リクエストログといったゲートウェイの管理は、DevOpsエンジニアがすでに持っているスキルが直接活かせる領域である。また、最適化を行う前に必ず性能を測定することの重要性、そしてLLMは「エラーを出さずに静かに失敗する」(例えばプロンプトの切り捨てや誤った回答)ため、単なるステータスコードだけでなく、トークン数や回答の品質に注目した監視が不可欠であるという教訓が強調されている。さらに、小型のローカルモデルは高速で安価だが、事実の信頼性には限界があるため、モデルの記憶に頼らず、Web検索やドキュメントを通じて外部からコンテキストを与えるRAGのような仕組みが重要であることも指摘されている。
このプロジェクトはまだ途中であり、今後はシステムの監視体制の強化や負荷テストの実施、そして最終的にはラップトップ上のプラットフォームをAmazon EKS上のGPUノードへ移行し、より大規模な運用に対応するための計画が立てられている。