所要時間: 約30分 | 難易度: ★★☆☆☆
この記事で作るもの
Apple Silicon(M1/M2/M3/M4)のパワーを最大限に引き出すフレームワーク「MLX」を使い、最新のLLM(Qwen2.5等)とチャットができるPythonスクリプトを構築します。
- Pythonの基礎(pipインストールやスクリプト実行)ができること
- Apple Silicon搭載のMacを使用していること
- Hugging FaceのモデルをMac上で直接動かし、ブラウザを介さずオフラインで回答を得る
先に確認するスペック・料金
ローカルLLMを動かす上で、最も重要なのは「メモリ(ユニファイドメモリ)」の容量です。Apple Siliconの最大の特徴はCPUとGPUがメモリを共有している点で、MLXはこの仕組みをフルに活用します。
最低ラインはメモリ16GBです。8GBモデルでも動作はしますが、OSのシステム領域と取り合うため、3B(30億パラメータ)以下の非常に小さなモデルしかまともに動きません。仕事で「使える」レベルの7B(70億パラメータ)クラスを動かすなら、16GBは必須、32GBあれば快適です。
GPUコア数は多いに越したことはありませんが、それ以上にメモリ帯域幅が重要です。M2/M3 ProやMaxチップを搭載したモデルなら、推論速度が飛躍的に向上します。逆に、Intel MacではMLXは一切動作しません。
費用については、ハードウェアさえあれば無料です。API経由の従量課金を気にせず、1日に何万トークン投げても電気代以外はかかりません。Mac miniをローカルLLM専用サーバーとして常時起動させるのも、消費電力が低いApple Siliconならではの賢い選択です。
なぜこの方法を選ぶのか
MacでローカルLLMを動かす手段として、他に「Ollama」や「LM Studio」があります。これらはGUIで使いやすいですが、中身は「llama.cpp」というC++ベースのライブラリで動いています。
一方で「MLX」は、Appleの機械学習チームがApple Siliconのためにゼロから設計したフレームワークです。PyTorchに近い操作感でPythonから直接叩けるため、自分で開発するプログラムに組み込む際、圧倒的に柔軟性が高いのが特徴です。
具体的には、ユニファイドメモリへのアクセスが最適化されており、モデルのロード時間が短く、量子化(モデルの軽量化)されたモデルの実行速度がllama.cppと同等か、条件によってはそれ以上に高速です。「ただ動かす」だけでなく「自分のアプリに組み込む」ことを考えるなら、MLX一択だと私は断言します。
Step 1: 環境を整える
まずはMLXを動かすための専用仮想環境を作ります。グローバル環境を汚すと、後で他のライブラリと衝突して動かなくなる「依存関係地獄」に陥るからです。
# プロジェクト用のディレクトリを作成して移動
mkdir my-mlx-project && cd my-mlx-project
# Python 3.10以上の環境を推奨(MLXの最適化が進んでいるため)
python3 -m venv .venv
# 仮想環境を有効化
source .venv/bin/activate
# MLX関連のライブラリをインストール
# mlx-lmは、Hugging FaceのモデルをMLXで簡単に扱うための高レベルライブラリです
pip install mlx-lm huggingface_hub
MLXは頻繁にアップデートされます。最新のM4チップなどの機能を最大限使うために、常に最新版をインストールするようにしてください。
⚠️ 落とし穴:
Xcode Command Line Toolsがインストールされていないと、インストール中にエラーが出ることがあります。その場合は xcode-select --install を実行してください。また、Pythonのバージョンが古すぎるとMLXのパッケージが見つからないため、必ず3.10以降を使用してください。
Step 2: 基本の設定
MLXでモデルを動かす際、最も重要なのは「どのモデルを、どの精度で読み込むか」です。今回は、日本語能力が高く軽量な「Qwen2.5-7B-Instruct」を、4bit量子化された状態で使用します。
import os
from mlx_lm import load, generate
# モデルの指定
# mlx-communityにあるモデルは、MLX用に最適化(量子化)済みなのでロードが速いです
model_id = "mlx-community/Qwen2.5-7B-Instruct-4bit"
# モデルとトークナイザーのロード
# load関数は、ローカルになければ自動的にHugging Faceからダウンロードします
model, tokenizer = load(model_id)
# 読み込みが完了したことを確認
print(f"Model {model_id} loaded successfully.")
ここで「4bit」という形式を選ぶのがポイントです。元のモデル(16bit)のままだと15GB以上のメモリを消費しますが、4bitに圧縮することで約5GBまでメモリ使用量を抑えられます。これにより、16GBメモリのMacでもサクサク動くようになります。
Step 3: 動かしてみる
最小限のコードで、LLMに質問を投げます。MLXはApple SiliconのGPUを自動的に認識して使用するため、特別なデバイス指定(device="cuda"など)は不要です。
# プロンプトの作成
# Qwenなどのチャットモデルには特定のフォーマットが必要です
prompt = "MacでローカルLLMを動かすメリットを3つ教えてください。"
messages = [{"role": "user", "content": prompt}]
formatted_prompt = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
# テキスト生成の実行
response = generate(
model,
tokenizer,
prompt=formatted_prompt,
max_tokens=500, # 必要以上に長く生成しないための制限
temp=0.7 # 自由度(0に近いほど固く、1に近いほど独創的になる)
)
print(response)
期待される出力
MacでローカルLLMを動かすメリットは以下の3点です:
1. プライバシーの保護:データが外部サーバーに送信されないため、機密情報を扱えます。
2. コスト削減:API料金が発生せず、オフラインで何度でも実行可能です。
3. 低遅延:Apple Siliconのユニファイドメモリにより、高速なレスポンスが得られます。
MLXは「生成が終わってから一括で表示する」のがデフォルトの挙動です。しかし、これでは長い文章のときにフリーズしたように見えてしまいます。実用レベルにするには「ストリーミング出力」が必要です。
Step 4: 実用レベルにする
仕事で使えるレベルにするため、「ストリーミング出力(1文字ずつ表示)」と「継続的な会話」ができるチャットスクリプトを作成します。
import sys
from mlx_lm import load, stream_generate
model_id = "mlx-community/Qwen2.5-7B-Instruct-4bit"
model, tokenizer = load(model_id)
def chat():
# 会話履歴を保持するリスト
history = []
print("AI: こんにちは!何かお手伝いしましょうか? (exitで終了)")
while True:
user_input = input("You: ")
if user_input.lower() == "exit":
break
history.append({"role": "user", "content": user_input})
# チャットテンプレートの適用
prompt = tokenizer.apply_chat_template(
history, tokenize=False, add_generation_prompt=True
)
print("AI: ", end="", flush=True)
full_response = ""
# stream_generateを使うと、トークンが生成されるたびに取得できる
for response in stream_generate(model, tokenizer, prompt, max_tokens=1000):
print(response, end="", flush=True)
full_response += response
print("\n")
history.append({"role": "assistant", "content": full_response})
if __name__ == "__main__":
chat()
このコードでは stream_generate を採用しました。これにより、最初の1文字目が出るまでの時間(Time to First Token)が0.5秒以下になり、体感速度が劇的に向上します。また、履歴を history リストに蓄積することで、文脈を理解した回答が可能になります。
実務で活用する場合、例えばローカルにある議事録ファイルを読み込んで、このスクリプトに「この会議の決定事項をまとめて」と投げるような自動化ツールへの発展が容易です。
よくあるトラブルと解決法
| エラー内容 | 原因 | 解決策 |
|---|---|---|
ModuleNotFoundError: No module named 'mlx' | 仮想環境が未有効、またはインストール失敗 | source .venv/bin/activate を実行後、再度pipインストール。 |
Killed または Memory Error | メモリ不足 | 他の重いアプリ(Chrome等)を閉じるか、より小さいモデル(例:Qwen2.5-1.5B-Instruct-4bit)を試す。 |
| 生成された日本語が文字化けする | トークナイザーの不一致 | mlx-community 以外のモデルを使う際、MLX変換が正しく行われていない可能性があるため、公式変換済みモデルを選ぶ。 |
次のステップ
MLXでローカルLLMが動くようになったら、次は「自分専用のナレッジ」をAIに持たせる「RAG(検索拡張生成)」に挑戦してください。
MLXエコシステムには mlx-embeddings というライブラリもあり、テキストをベクトル化してデータベースに保存することも可能です。例えば、自分の書いた過去の記事や、社内のドキュメントを読み込ませ、その内容に基づいて回答する「プライベートAIアシスタント」を作ることができます。
また、mlx-lm.server コマンドを使えば、このローカル環境をOpenAI互換のAPIサーバーとして公開できます。これにより、CursorなどのAIエディタのバックエンドを自分のMacに差し替えることができ、開発コストをゼロに抑えるといった応用も可能です。
ローカルLLMは、もはや「動いてすごい」の段階を過ぎ、「どう実務に組み込むか」のフェーズに入っています。RTX 4090を回している私から見ても、MacでのMLX体験は「静音性」と「電力効率」の面で、開発者にとって極めて実用的な選択肢です。
よくある質問
Q1: メモリ8GBのMacBook Airでも動きますか?
動きますが、かなり制限されます。Qwen2.5-1.5BやLlama-3.2-1Bといった超軽量モデル(4bit版)であれば動作しますが、推論中にスワップが発生し、速度が低下する可能性があります。実用的な回答精度を求めるなら、16GB以上への買い替えを強くおすすめします。
Q2: MLXで独自のモデルをファインチューニング(学習)できますか?
可能です。mlx-lm にはLoRA(Low-Rank Adaptation)という手法を用いた学習スクリプトが含まれています。自分の過去のメール履歴やブログ記事を読み込ませて、自分の文体を模倣するAIを作ることも、Mac 1台で完結します。
Q3: Hugging Faceにある全てのモデルが動くのですか?
MLX形式に変換されている必要があります。ただし、mlx-lm には自動変換機能があるため、主要なアーキテクチャ(Llama, Mistral, Qwen, Phiなど)であれば、通常のモデルIDを指定するだけでライブラリが内部で変換して動かしてくれます。
📦 この記事に関連する商品(楽天メインで価格確認)
Mac mini M2 (24GBメモリ)MLXを常時稼働させるサーバーとして、コスパとメモリ容量のバランスが最高。
※アフィリエイトリンクを含みます






