17 ローカル LLM とクラウド LLM¶
前章までは「モデルをどう使うか」の話だった。ここでは一段引いて、そもそもモデルをどこで動かすかを見る。同じ 1 回の呼び出し (第 2 章) でも、ローカル (自分のハードで推論) と クラウド (ベンダー API を叩く) では、コスト / プライバシー / 品質 / 運用のすべてが変わる。
2 つの選択肢¶
| ローカル LLM | クラウド LLM | |
|---|---|---|
| 実体 | モデルの重みが自分のマシンに置かれ、自分の CPU/GPU で推論 | ベンダーのデータセンターに重みがあり、API 経由で結果だけ返る |
| 代表 | Llama / Qwen / Mistral / Gemma / Phi / DeepSeek (open weights) | Claude / GPT / Gemini / Grok (proprietary) |
| ランタイム | Ollama / llama.cpp / vLLM / LM Studio / MLX | 各社 API (+ LiteLLM のような互換レイヤ) |
| プロンプトの行き先 | 自分のマシン内で完結 | プロバイダのネットワークに送信 |
「ローカル vs クラウド」は一見対立軸に見えるが、実務ではハイブリッド(軽いタスクはローカル、重いものはクラウド)が現実解になることが多い。この章ではまず両方の中身と判断軸を整理する。
ローカル LLM の中身¶
モデル形式¶
- GGUF: llama.cpp / Ollama で使う圧縮形式。単一ファイル、量子化情報を含む
- safetensors: Hugging Face 標準。PyTorch / vLLM 系
- MLX: Apple Silicon 向け (Metal 最適化)
ランタイム¶
| ランタイム | 特徴 |
|---|---|
| Ollama | 最も使いやすい。モデルの pull / 切替が ollama run <name> だけ。OpenAI 互換 API 付き。hands-on でもこれを採用 (setup/ollama) |
| llama.cpp | Ollama の土台。C++ 実装、量子化に強い、組込み寄り |
| vLLM | 大規模サーバ向け。batching / PagedAttention でスループット最適化。GPU 必須 |
| LM Studio | GUI 付き。デスクトップで触るなら楽 |
| MLX | Apple Silicon 専用。Mac の unified memory を直接叩く |
hands-on で Ollama をコンテナ化せず ホストに直接入れているのは、macOS の Metal GPU がコンテナから見えないため。GPU サーバ (Linux + NVIDIA) なら vLLM や Ollama のコンテナ版が選択肢に入る。
量子化 (quantization)¶
モデルの重みを低精度で保持することで容量と VRAM を削る技術。精度との引き換え。
| 精度 | サイズ比 | 品質への影響 |
|---|---|---|
| FP16 (原寸) | 1.0x | 劣化なし |
| INT8 | 0.5x | ほぼ劣化なし |
| INT4 (4-bit) | 0.25x | 体感で「わずかに劣化」程度、十分実用 |
| INT3 / INT2 | 0.2x 以下 | 明確に劣化 (目的次第) |
経験則として 4-bit (Q4) が容量と品質のスイートスポット。Ollama のデフォルト tag (llama3.1:8b 等) も概ね 4-bit。
ハードウェア要件の目安¶
モデルサイズ (パラメータ数) と 4-bit 量子化時のメモリ要件:
| モデル | パラメータ | 4-bit 時のメモリ | 動く環境 |
|---|---|---|---|
| 1B-3B | 小 | ~2GB | スマホ / ラップトップ |
| 7B-8B | 中 | ~4-5GB | 普通のノート PC |
| 13B | 中大 | ~8GB | 16GB 以上のメモリ |
| 30B-34B | 大 | ~20GB | M1/M2 Pro/Max、24GB+ の GPU |
| 70B | 特大 | ~40GB | 64GB 以上 or A100 40GB |
| 405B | 巨大 | ~200GB+ | 普通の個人ハードでは厳しい |
Apple Silicon の unified memory は CPU/GPU 共有なので、32GB メモリなら実質 30B 前後まで快適に動く。
クラウド LLM の中身¶
課金モデル¶
トークンあたり従量課金が一般的。input / output で別単価、モデルごとに差が大きい:
- フロンティアモデル (Claude Opus、GPT-5、Gemini Pro 等): input 数ドル〜、output 数十ドル / 1M トークン
- 中堅モデル (Claude Sonnet、GPT-5 mini、Gemini Flash): input $1 前後、output $5-10 / 1M トークン
- 小型 / 高速モデル (Claude Haiku、GPT-5 nano、Gemini Flash Lite): $0.1-1 / 1M トークン程度
プロンプトキャッシュ (第 7 章) を使うとキャッシュヒット分は 11-91% 割引される。長い system prompt が効くのはこれが理由。
レート制限¶
- TPM / RPM (tokens-per-minute / requests-per-minute): 契約 tier ごとの上限
- 同時リクエスト数: 別に上限が付くことがある
- 本番運用では指数バックオフでリトライを入れる前提
データ取扱い¶
- デフォルトの retention policy はベンダーごとに異なる (学習に使う / 使わない、ログ保持日数)
- Enterprise 契約 / zero-retention モードを有効にすれば学習に使われない / ログも残らないオプションが大抵ある
- プロンプトにセンシティブデータを含めて良いかは契約とユースケース次第
何がフロンティアか¶
2026 時点で、以下はまだクラウドのみと言える領域:
- 超長コンテキスト (500K-1M+ tokens)
- 強力な reasoning モード (o 系 / claude extended thinking)
- 高精度のマルチモーダル (第 16 章)
- 最新の tool-calling 精度
open weights モデルは半年〜1年遅れで追いついていく構造。
評価軸 (使い分けの基準)¶
| 軸 | ローカル | クラウド |
|---|---|---|
| コスト構造 | 初期投資 (ハード) + 電気代 | 従量 (per-token) |
| 損益分岐 | 大量バッチ / 長期使用で有利 | 少量 / 不定期で有利 |
| プロンプトの送信先 | 自分のマシン内で完結 | プロバイダのネットワークを通る |
| 品質上限 | ハードウェア制約 + open weights の限界 | フロンティア |
| 応答速度 | 小モデルなら高速、大モデルは遅い (GPU 次第) | 100ms-数秒、ストリーミングあり |
| コンテキスト長 | 8K-128K が実用線 | 100K-1M+ |
| オフライン | 完全に可能 | 不可 |
| 運用負担 | 自分で更新 / 障害対応 / 量子化選定 | ベンダー任せ |
| スケール | ハードウェア上限まで | 事実上無限 (API 枠内) |
| ベンダーロック | なし (open weights は互換多い) | 乗り換え時にプロンプトを再評価する必要 |
使い分けの実務パターン¶
パターン A: 全部クラウド¶
- 小規模な開発、PoC、エンジニア個人の試作
- 初期コストゼロで最新モデルが触れる
- ボリュームが増えてきたら段階的に B/C/D に移行
パターン B: 全部ローカル¶
- 機密データ (医療 / 法務 / 企業内部) で外部に出せない
- オフライン環境 / エアギャップ
- 長期的なコストを固定したい (SaaS の変動課金が読めない)
- フロンティア品質が要らないユースケース
パターン C: ハイブリッド (現実解)¶
- 軽いタスクはローカル: 分類 / 抽出 / 要約 / embedding 生成 / 一次フィルタ
- 重い / フロンティアはクラウド: 長コンテキスト推論、コード生成、複雑な tool calling
- 抽象化レイヤで透過切替: LiteLLM や LangChain のモデル抽象を使い、呼び出し側は同じコードのまま
パターン D: エッジ + センター¶
- クライアント側 (ブラウザ / モバイル) に小型ローカル + センター側にクラウド
- 遅延ゼロで一次応答、重い処理はサーバへ
hands-on は パターン C の最小実装。LiteLLM が OpenAI 互換フロントを付け、Ollama (ローカル) と Claude / GPT / Gemini (クラウド) を透過的にルーティングする。
セキュリティ: 実際のリスク境界はツール層¶
「ローカル = 安全 / クラウド = 危険」という二分法で語られがちだが、これは不正確。実際にリスクを生むのは LLM ではなくツール (第 5 章) であり、配置 (local/cloud) では変わらない部分が大きい。
LLM は決めるだけ、危険なことはツールがやる¶
rm / ファイル書き込み / HTTP 送信 / DB 書き込み / Slack 通知 — これらは全部ツール側の実装。LLM は「どのツールを何の引数で呼ぶか」を JSON で出力するだけで、実際の副作用はツールのコードが担う。
- 「この絶対パスのファイルを消して」→ ツールが
rm -rf相当を実行 - 「この JSON を社外 API に POST して」→ ツールが外部 HTTP 送信
- 「この情報を検索クエリに含めて」→ ツールがクエリ文字列ごと外部検索エンジンへ送信
LLM がローカルで動こうがクラウドで動こうが、ツールが触れるものの危険度は同じ。配置で変わるのはプロンプトとその結果がベンダーのネットワークを通るかどうかだけ。
「ローカル = 漏れない」は誤り¶
よくある誤解: ローカル LLM なら社内情報が漏れない。実際は:
- LLM 呼び出し自体は確かに内部で完結する
- しかしエージェントが使うツールに「外部 Webhook POST」「S3 upload」「メール送信」「ブラウザ自動操作」が入っていれば、LLM がローカルでも、そこから外に出る
- 観測 / ログ (第 8 章) を SaaS に送っていればそれも経路
- embedding API をクラウドで呼んでいればインデックス化したデータもそこを通る
ローカル LLM の実際の利点は プロンプトと入力データそのものがモデルプロバイダに送られない点。それ以外の安全性はツール層とログ層の設計で決まる。
「学習されない」≠「送信されない」¶
クラウドベンダーの API 規約を読むと、多くの場合 「送信データは学習に使わない」 と書いてある (特に有料 API 経由、Enterprise 契約は)。この一文で安心してしまうのが典型的な落とし穴。
学習に使わない = 送信していない、ではない。実態は:
- 送信は確実に発生している。プロンプトはベンダーのネットワークを通り、推論サーバで処理される
- 一定期間の retention がある。典型的には 30 日の保持 (abuse monitoring / 不正検知 / デバッグ用途)。zero retention オプションは別契約のことが多い
- 内部アクセス権限が一定程度存在する。コンプライアンス対応やインシデント調査のためにベンダー従業員がログを閲覧する可能性
- infrastructure 層での経路露出。CDN / ロードバランサ / ログ基盤 / 観測基盤を経由するので、流通経路は思っているより広い
「学習に使われない」は モデル重みに組み込まれない という意味であり、送信そのものが無くなる 話ではない。この区別を理解していないと、「API だから安全」という誤認のまま機密データを流すことになる。
善意のツールでも断片は漏れる¶
ツール自体に悪意がなくても、エージェントが日常的に使う typical なツールは あなたの環境の断片を毎ターン送信している:
- スタックトレース解析ツール: エラーメッセージ = ファイルパス、モジュール構成、環境情報、場合によってはローカル変数名
- ファイル読み込みツール: コード片、コメント、誤って残された TODO、デバッグ用ハードコード
- シェル実行ツール: 環境変数の出力、
ps/env/pwd、パスの階層 - git ツール: commit message、branch 名、author email、diff
- 検索ツール (web search): クエリ文字列にコードやエラーメッセージをそのまま乗せることが多い
- コード補完 / review ツール: 周辺コード片 + 隣接ファイル + 依存関係
個々の送信は無害に見えるが、積み重なるとそこから以下が復元できる:
- システムアーキテクチャの概形
- 使用しているライブラリとバージョン
- 内部ディレクトリ構造とモジュール命名規則
- コーディング規約 / コメントスタイル
- 設定ファイルに書かれた接続先やハンドル名
- 稀にだが うっかりプロンプトに乗ってしまった API キー / 秘密情報 (環境変数の dump、.env のうっかり読み込み、エラー文中の URL 等)
悪意がなくても 断片的に漏れる、という点がポイント。ツールを信用するかどうかの軸 (前節) とは独立に、ツールが何を "普通の動作として" 送信するか を把握しておかないと、気付かないうちに機密が流出する。
対策は基本的に入力サニタイズ (第 14 章 の入力層ガード):
- ファイル読み込み時のシークレットパターン検出 (
AWS_*、*_KEY、password=、Bearer ...) .env/ credentials ファイルの明示的な除外- 環境変数 dump を避ける / フィルタする
- 送信前の pre-processor で PII や秘密情報をマスキング
- ベンダーを信頼しないユースケースではそもそもローカル LLM にする
ツール = 依存ライブラリ問題の再来 (かつ悪化版)¶
エージェントに追加するツールは、コードから見ると外部依存 (npm パッケージ、Python ライブラリ、MCP サーバ) と同じ立ち位置:
- 誰が書いたか
- 何にアクセスできるか
- 悪意や脆弱性が仕込まれていないか
- 更新でふるまいが変わらないか
サプライチェーンリスクの延長というだけなら目新しさはない。ただし LLM エージェントの文脈では以下の理由で 既存のライブラリよりタチが悪い:
- 導入の敷居が極端に低い: MCP サーバや
tools.tsに 1 行追加するだけでエージェントが触れる範囲に入る。npm installより軽く、依存ツリーの監査も未成熟 - 審査プロセスが未整備: npm / PyPI / crate には一応の署名 / CVE DB / socket.dev のような仕組みがある。MCP サーバや自作ツールの大半は無審査
- 発火がタイミング依存で検出困難: ツールは LLM が「そう判断したとき」にしか動かない。単体テストで発火せず、本番の特定シナリオでだけ悪意を発揮する実装が成立する
- 自然言語で動くので挙動が読みにくい: 「この状況で外部に送信」みたいなロジックをプロンプトテンプレートやツール description に埋めると、コードレビューでは気付きにくい
- LLM がツールを組み合わせる: 単体では無害な 2 つのツール (「ファイル読み取り」+「検索クエリに添付」) を LLM が勝手に連鎖させて情報漏洩が起きる合成攻撃が成立する
結果として 既存のサプライチェーン攻撃よりも静的解析が効きにくい。ツールのコードを読んでも「単なる fetch」にしか見えないし、description / prompt に書かれた意図を機械的に検出する手段はまだ貧弱。
画面キャプチャ / computer use 系ツールの特殊性¶
近年普及している以下のカテゴリは、ツール層の危険度が特に高い:
- 画面キャプチャ → LLM 送信: Computer use、screen-to-code、screenshot-debug 等。「画面の文脈を踏まえてアシスト」が売り
- OCR / visual grounding 系: 精度を上げるために定期的にスクリーンショットを取る
このタイプのツールは 全画面情報 = パスワードマネージャ / メール / Slack / バンキング画面も含む を LLM に渡す可能性がある。
- クラウド LLM 経由ならプロバイダにそのまま送信される
- ローカル LLM でも「LLM に見せる = そのターン以降のツールや後続処理から参照可能」な状態に置かれる
- 一度 LLM のコンテキストに入ったものは、後続のツール出力や要約を通じて意図せず外に出る経路が多数ある
対策の方向性:
- 送信前のマスキング: 機密領域のブラー / 特定ウィンドウのみに範囲限定
- 明示的な承認フロー: 「このスクリーンショットを送信します」のユーザ確認
- プロセス / ディスプレイ単位の制限: 1 プロセスだけ、特定ディスプレイだけなど OS レベルの権限で絞る
- 監査ログ: 何を送信したかをあとから辿れるようにする
ここでもリスクは LLM 配置と独立。画面キャプチャツールが悪意や実装ミスを抱えていれば、ローカル LLM でも同じ問題が起きる。
トレードオフの結論¶
エージェントの能力 ∝ ツールの豊富さ ∝ 攻撃面
つまり:
- ツールをたくさん足すほど便利
- ツールをたくさん足すほど攻撃面が広がる
- ツールの出自 / 実装 / 権限 / ログを精査する文化がないと、便利さが素直にリスクで相殺される
- LLM 配置 (local/cloud) はこの計算にほぼ入らない。配置で変わるのは「プロンプトがどこに行くか」だけ
具体的なガード手法 (入力 / tool_calls / 結果 / 出力 の 4 層) は 第 14 章 ガードとプロンプトインジェクション に整理している。第 14 章はインジェクション経由のツール悪用が中心なのに対し、本節はツールそのものの出自と権限に焦点。両方を組み合わせて初めて現実的なガード設計になる。
p1uscode / agent-demo との対応¶
- setup/ollama: Ollama のホスト側インストール手順。Metal GPU の制約でコンテナ化していない理由
- setup/services: LiteLLM が
config.yamlでローカル / クラウドの両方を model list に持つ - hands-on/open-webui: Open WebUI 上でローカル / クラウドモデルを同じ UI で切り替える演習
- agent-demo:
--model <name>で Ollama ローカルモデルとクラウドモデルの切替を試せる。tool calling の精度差 (小型 open weights は苦手、クラウドは安定) を体感できる
つまり hands-on は同じエージェント骨格で両方の動作を見られるように組んである。理論だけでなく体感も含めて使い分けの勘が身に付く。
よくある誤解¶
- 「ローカル = 遅い」 → 7B クラスは最新ハードなら cloud より速いことすらある。大モデル (70B+) は確かに遅い
- 「ローカル = フロンティアに並ぶ」 → 並ばない。GPT-5 / Claude Opus 級は少なくとも数ヶ月〜年単位で open weights には来ない
- 「クラウド = どれでも同じ」 → ベンダー / モデルごとに tool calling 精度、命令追従、コンテキスト効率が大きく違う (第 11 章 評価 で測るのが正しい)
- 「ローカル = 安全」 → LLM 配置ではなくツール層が実際のリスク境界 (上述セキュリティ節を参照)
- 「クラウドはコストが読めない」 → キャッシュ / rate limit / 予算アラートで制御可能。むしろハードウェアの減価償却の方が読みにくいこともある
まとめ¶
- どこで動かすかはコスト / プライバシー / 品質 / レイテンシ / 運用負担すべてに効く独立な選択
- ローカル = open weights + 自前ランタイム (Ollama など) + 量子化で実用化。ハード上限と open weights の限界が品質の天井
- クラウド = 従量課金、フロンティア品質、レート制限と retention を意識
- 実務の現実解はハイブリッド: 軽いものはローカル / 重いものはクラウド / 抽象化レイヤで透過切替
- セキュリティの実際の境界はツール層。LLM の配置 (local/cloud) は「プロンプトの送信先」を変えるだけで、ツール経由のリスクは配置で変わらない
- ツール追加 = サプライチェーンリスクの延長。導入の敷居が低く、発火がタイミング依存で、合成攻撃が成立するため既存のライブラリ問題より検知が難しい
- 画面キャプチャ / computer use 系は特に注意。送信範囲、承認フロー、マスキングの設計が必須
- hands-on は LiteLLM + Ollama + agent-demo でハイブリッドの最小実装を提供。両方の体感を積んでから選べる
- 個別ランタイムやモデル名は流動的だが、「どこで動かすか」「ツールに何を許すか」の判断軸は長く使える