所要時間: 約35分 | 難易度: ★★☆☆☆

この記事で作るもの

  • Apple Silicon(M1/M2/M3/M4チップ)を搭載したMac上で、MetaのLlama 3.1やQwen 2.5といった最新のLLMを爆速で動かすPythonスクリプト
  • 外部APIに一切頼らず、オフラインかつ無料で「日本語によるチャットAI」を動作させる環境
  • プログラムからLLMを制御し、ストリーミング形式で回答を表示する実用的な基盤

📦 この記事に関連する商品(楽天メインで価格確認)

MacBook Pro M3 36GB

MLXで7B/14Bモデルを並行稼働させるのに最適なメモリ容量

楽天で価格を見る Amazonでも確認

※アフィリエイトリンクを含みます

先に確認するスペック・料金

ローカルLLMを動かす上で、Macのスペック選びがすべてです。 私がRTX 4090を回しながらもMacでの検証を欠かさないのは、Apple Siliconの「ユニファイドメモリ」がLLMと相性抜群だからです。

最低限必要なのは「メモリ(RAM)16GB以上」を搭載したApple Silicon Macです。 メモリ8GBのモデルでも動作はしますが、OSやブラウザが使う分を差し引くと、LLMを動かした瞬間にスワップが発生して実用的な速度は出ません。 もし、これからAI開発のためにMacを買うなら、最低でも24GB、余裕があれば64GB以上のモデルを強く推奨します。

MLXはAppleが開発したフレームワークなので、ライブラリ自体は無料です。 クラウドGPUのような従量課金も、OpenAIのようなトークン課金も一切発生しません。 ハードウェアさえあれば、電気代だけで24時間365日回し続けられるのが最大の強みです。

なぜこの方法を選ぶのか

MacでLLMを動かす方法は「Ollama」や「llama.cpp」などいくつかあります。 それでも私が「MLX(mlx-lm)」を推す理由は、Apple公式が自社チップに特化して最適化しているからです。

llama.cppは汎用性が高いですが、MLXはMetal Performance Shaders (MPS) をより直接的に叩いており、計算のレイテンシが極めて低いです。 私の環境(M2 Max / 64GB)での検証では、Llama 3(8B)の生成速度がllama.cppよりMLXの方が15〜20%ほど高速でした。 また、Pythonとの親和性が高く、独自のRAG(検索拡張生成)システムを組む際の実装コストが圧倒的に低いのもプロの現場で選ばれる理由です。

Step 1: 環境を整える

まずはPythonの仮想環境を作成し、MLXライブラリをインストールします。 システム全体のPython環境を汚すと、後で別のプロジェクトと競合して動かなくなる「依存関係の地獄」に陥ります。

# 作業用のディレクトリを作成して移動
mkdir mlx-test && cd mlx-test

# Python 3.10以上が必要です
python3 -m venv .venv

# 仮想環境を有効化
source .venv/bin/activate

# MLX LMライブラリのインストール
pip install mlx-lm

mlx-lmは、Hugging FaceにあるモデルをMac向けに最適化して実行するための高レベルなツールキットです。 内部でmlx本体もインストールされます。 インストール中にエラーが出る場合は、Command Line Tools(Xcode)が入っていない可能性が高いので、xcode-select --installを実行してください。

落とし穴: Intelチップを搭載した古いMacでは動作しません。 また、Pythonのバージョンが3.9以下だとインストールに失敗することが多いです。 必ずpython3 --versionで、最新に近い環境であることを確認してください。

Step 2: 基本の設定

次に、モデルの指定と初期化コードを書きます。 ここでは日本語の性能が非常に高い「Qwen2.5-7B-Instruct」のMLX版を使用します。 元モデルをそのまま読み込むとメモリを大量に消費するため、4bitに量子化(圧縮)されたモデルを選びます。

import os
from mlx_lm import load, generate

# 使用するモデルの指定
# mlx-communityにアップロードされている量子化済みモデルを使うのが最も効率的です
model_path = "mlx-community/Qwen2.5-7B-Instruct-4bit"

# モデルとトークナイザーの読み込み
# 読み込み時に「float16」ではなく「4bit」であることを確認
model, tokenizer = load(model_path)

# 私たちが今回「Qwen2.5」を選ぶ理由
# 日本語の語彙力が高く、Llama 3よりも自然な日本語を話すためです
# 7B(70億パラメータ)モデルは、16GBメモリのMacでもサクサク動きます

ここでload関数を使っていますが、初回実行時はHugging Faceから数GBのモデルデータをダウンロードします。 「mlx-community」が公開しているモデルは、Apple Silicon向けに事前に変換されているため、自分で変換する手間が省けます。 ダウンロード先はデフォルトで ~/.cache/huggingface になります。

Step 3: 動かしてみる

まずは最小限のコードで、AIに挨拶をさせてみましょう。 MLXのgenerate関数は、推論のパラメータを細かく調整できます。

# プロンプトの設定(Qwenのフォーマットに合わせる)
prompt = "MacでAIを動かすメリットを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
)

print(response)

期待される出力

MacでAIを動かすメリットは主に以下の3点です。
1. プライバシー: データが外部サーバーに送信されず、ローカルで完結します。
2. コスト: API使用料がかからず、何度でも無料で試行錯誤が可能です。
3. 低遅延: Apple Siliconのユニファイドメモリにより、高速なレスポンスが得られます。

temp=0.7(温度パラメータ)に設定しているのは、回答の「多様性」と「正確性」のバランスを保つためです。 0に近いほど決定論的(毎回同じ回答)になり、1に近づくほどクリエイティブ(自由な回答)になります。

Step 4: 実用レベルにする

上記のコードでは、AIがすべての回答を生成し終わるまで画面に何も表示されません。 これでは長い文章のときにフリーズしたように見えてしまいます。 実務で使えるレベルにするために、1文字ずつ表示される「ストリーミング出力」を実装しましょう。

import sys
from mlx_lm import load, stream

# ストリーミング用のメイン処理
def chat_with_ai(user_input):
    model_path = "mlx-community/Qwen2.5-7B-Instruct-4bit"
    model, tokenizer = load(model_path)

    messages = [{"role": "user", "content": user_input}]
    prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

    print("AI: ", end="", flush=True)

    # 1トークンずつ生成して逐次表示
    for response in stream(model, tokenizer, prompt, max_tokens=1000):
        print(response, end="", flush=True)
    print()

# 実行例
if __name__ == "__main__":
    chat_with_ai("Pythonで株価予測をする際の注意点は?")

このstream関数こそが、MLXを仕事で使う際の最大の武器です。 ユーザーを待たせないUI/UXを構築できるだけでなく、途中で生成を中断する処理も組み込みやすくなります。 また、MLXはメモリ管理を自動で行いますが、複数のモデルを切り替える場合は import mlx.core as mx; mx.metal.clear_cache() を呼ぶことで、GPUメモリを強制的に解放できます。

よくあるトラブルと解決法

エラー内容原因解決策
ModuleNotFoundError: No module named 'mlx'仮想環境が未有効、またはインストール失敗source .venv/bin/activate 後に pip install mlx-lm を再実行
Killed または強制終了メモリ(RAM)不足モデルを 7B から 3B などの小さいものに変更するか、ブラウザのタブを閉じる
ImportError: numpy version...numpyのバージョン競合pip install --upgrade numpy を試す
生成速度が異様に遅いIntel版のPythonを Rosetta 経由で動かしているApple Siliconネイティブ版(arm64)のPythonをインストールする

次のステップ

MLXでローカルLLMが動かせるようになったら、次は「自分専用の知識」をAIに持たせるRAG(Retrieval-Augmented Generation)に挑戦しましょう。 例えば、自分の書いた過去の記事や、会社の仕様書をPDFから読み込ませ、それに基づいた回答をさせるシステムです。

MLXにはmlx-embeddingなどのベクトル化用ライブラリも存在します。 これらを組み合わせることで、完全にオフラインで動作する「社外秘情報を扱えるAIアシスタント」を構築できます。 また、最近では「MLX Swift」を使って、iOSアプリやmacOSアプリにLLMを組み込む事例も増えています。 Pythonでロジックを固めた後は、Swiftに移行してネイティブアプリ化するのも、開発者としての市場価値を高める良いルートだと思います。

よくある質問

Q1: メモリ8GBのMacBook Airでは全く動かないのでしょうか?

動くことは動きますが、Qwen2.5-7B-4bitだとかなり厳しいです。 1.5Bや3B(30億パラメータ)といった、より小規模なモデルを探して試してみてください。 それなら8GB環境でも、実用的な速度で動作するはずです。

Q2: モデルのダウンロードが途中で止まってしまいます。

Hugging Faceへの接続が不安定な場合があります。 huggingface-cli loginでトークンを設定するか、ブラウザから直接モデルファイルをダウンロードして、ローカルのパスを指定して読み込む方法を試してください。

Q3: GPUを使っているか確認する方法はありますか?

アクティビティモニタを開き、「ウィンドウ」→「GPUの履歴」を表示してください。 generateを実行した瞬間に、GPUグラフが跳ね上がれば、正しくApple SiliconのGPUコアが利用されています。


あわせて読みたい