ローカルLLMとは、OpenAIやAnthropicなどの外部サーバーへ文章を送信せず、自分のパソコン上で動かす大規模言語モデルです。

今回は、M1 Max・64GBのMacBook Proと、M4 Pro・64GBのMac miniにローカルLLM環境を構築します。

目的は、ブログ記事の下書きや要約、リライト、SNS投稿文などを、外部APIの料金を気にせず生成できるようにすることです。

ローカルLLMでできること

ローカルLLMは、次のような用途に利用できます。

  • ブログ記事の構成案作成
  • 本文の下書き
  • タイトル案の作成
  • 文章の要約
  • リライト
  • 校正
  • SNS投稿文の作成
  • 画像生成用プロンプトの作成
  • 入力データの分類や整形

外部の高性能モデルと比べると、複雑な推論や最新情報の正確性では劣る場合があります。

一方で、定型的な記事生成や文章加工では、ローカルモデルでも実用的な結果を得られる可能性があります。

OllamaとMLX

AppleシリコンMacでローカルLLMを動かす方法として、今回はOllamaとMLXを候補にします。

Ollama

Ollamaは、ローカルLLMを比較的簡単に導入できる実行環境です。

モデルの取得、起動、API経由の呼び出しなどを一つの仕組みで扱えます。

向いている用途は次のとおりです。

  • 手早くローカルLLMを試したい
  • 複数のモデルを簡単に切り替えたい
  • 自作プログラムからHTTP APIで呼びたい
  • MacBook ProとMac miniで同じ構成を使いたい

今回のように、VPSから届いたジョブをPythonワーカーが処理する構成では、OllamaのローカルAPIが扱いやすいと考えています。

MLX

MLXは、Appleシリコン向けに最適化された機械学習フレームワークです。

Appleシリコンのユニファイドメモリを活用し、LLMや画像生成モデルなどを動かせます。

MLXは、Ollamaよりも細かな調整や独自実装に向いています。

ただし、最初からMLXで仕組みを組むと、モデル管理やAPI化の部分を自分で用意する範囲が増えます。

そのため、初期構築ではOllamaを使い、性能や制御に不満が出た場合にMLXを検討する方針にします。

モデルのサイズとメモリ

ローカルLLMでは、モデルのパラメータ数と量子化方式によって必要なメモリが変わります。

一般に、モデルが大きいほど文章の品質や知識量が向上する可能性がありますが、必要なメモリと生成時間も増えます。

64GBのユニファイドメモリがあれば、多くの小型・中型モデルを動かせます。

ただし、macOSや他のアプリも同じメモリを使用します。

重要なのは、単純なメモリ使用量だけではなく、次の状態です。

  • メモリプレッシャー
  • スワップ使用量
  • モデル読み込み時間
  • 文章生成速度
  • 生成中のアプリ応答
  • モデルやワーカーの異常終了

例えば、Mac miniが普段の仕事で45GB程度を使用していても、そのすべてが即座に必要なメモリとは限りません。

キャッシュとして使われている領域は、必要に応じてmacOSが解放します。

生成中もメモリプレッシャーが緑であれば、そのまま利用できる可能性があります。

黄色や赤になる場合は、ブラウザ、Docker、IDEなど、メモリ消費の大きいアプリを終了します。

最初に試すモデルの条件

初期テストでは、いきなり最大級のモデルを使う必要はありません。

まずは次の条件で選びます。

  • 日本語の生成品質が一定以上ある
  • Ollamaから利用しやすい
  • 量子化版が用意されている
  • 64GBのMacで無理なく動く
  • 商用利用条件が確認できる

モデルの公開状況やライセンスは変わる可能性があるため、導入時点で公式のモデルカードを確認します。

記事生成のテスト方法

M1 MaxとM4 Proの性能を比較するため、同じモデルと同じプロンプトを使用します。

例えば、次のような指示を与えます。

MacでローカルLLMを動かすメリットとデメリットについて、初心者向けのブログ記事を作成してください。見出しを付け、1,500文字程度にまとめてください。

測定する項目は次のとおりです。

  • モデル読み込み時間
  • 最初の文字が出るまでの時間
  • 1秒あたりの生成量
  • 全体の生成時間
  • メモリ使用量
  • スワップ使用量
  • 本体温度
  • ファンの動作
  • 生成された文章の品質

速度だけでなく、文章の自然さや事実関係も確認します。

ローカルLLMをAPIとして使う

今回の最終目的は、チャット画面で手動入力することではありません。

VPSから受け取ったジョブを、自動的にローカルLLMへ渡す必要があります。

構成は次のようになります。

```text
VPS

Mac上のPythonワーカー

OllamaのローカルAPI

生成結果

VPSへ返却
```

OllamaをMac内だけで使用する場合、インターネットへAPIを公開する必要はありません。

PythonワーカーとOllamaは同じMac内で通信し、外部との通信はPythonワーカーがVPSへ行うHTTPS通信だけにします。

モデルを常駐させるか

モデルを常にメモリへ読み込んでおけば、ジョブが来たときにすぐ文章を生成できます。

ただし、モデルを常駐させると、Macのメモリを継続的に使用します。

今回の用途では、運用方法を次の2つから選べます。

常駐方式

ジョブへの応答が速くなります。

記事生成を頻繁に行う時間帯に向いています。

必要時だけ読み込む方式

メモリを節約できます。

ジョブが少ない夜間や、画像生成モデルとメモリを共有する場合に向いています。

最初は必要時に読み込む方式で動作確認し、応答速度に不満があれば常駐時間を調整します。

ローカルLLMの注意点

ローカルLLMから出力された文章を、そのまま公開するのは危険です。

次の確認が必要です。

  • 事実関係が正しいか
  • 存在しない機能や製品を作っていないか
  • 引用や出典が必要な内容ではないか
  • 同じ内容を繰り返していないか
  • 不自然な日本語になっていないか
  • モデルのライセンス上、目的の利用が可能か

初期運用では、自動公開ではなくPayload CMSへ下書きとして保存し、人間が確認してから公開する構成にします。

まとめ

M1 MaxとM4 Pro、どちらも64GBのメモリがあれば、ローカルLLMを動かす環境として十分活用できます。

最初はOllamaを使い、記事の構成案や下書きを生成します。

同じモデルを2台で試し、速度、メモリ使用量、文章品質を比較したうえで、それぞれの役割を決めます。

次回は、同じ2台のMacを使い、ブログのアイキャッチなどをローカルで画像生成する方法を検討します。