所要時間: 約30分 | 難易度: ★★☆☆☆
この記事で作るもの
Apple Silicon(M1/M2/M3/M4)に最適化されたフレームワーク「MLX」を使い、Llama 3 8B Instructなどの最新モデルを爆速で動かすPythonスクリプトを構築します。 Pythonの基本的な文法がわかれば、ライブラリのインストールから推論の実行、そしてチャットUIでの対話までを自分のローカル環境だけで完結させることが可能です。 外部APIを一切使わないため、機密情報の漏洩を気にせず、完全に無料でローカルLLMを実務に組み込む第一歩を踏み出せます。
先に確認するスペック・料金
ローカルLLMを動かす上で、最も重要なのはGPUの型番ではなく「Unified Memory(統合メモリ)」の容量です。 Apple Siliconの最大の特徴は、CPUとGPUが同じメモリ空間を共有している点にあり、MLXはこの構造をフルに活用します。
最低ラインはメモリ16GBです。 8GBのMacBook Airでも動くことは動きますが、OSのシステム領域で数GB占有されるため、7B〜8Bクラスのモデルを動かすとスワップが発生し、レスポンスが極端に低下します。 実務でストレスなく動かすなら、24GBまたは32GB以上のメモリを積んだ個体が理想的です。
私はM3 Maxの128GBモデルとRTX 4090の2枚挿し自作PCを併用していますが、MLXで動かす8Bモデルの軽快さは、RTX環境に匹敵する「手馴染みの良さ」があります。 費用面では、一度Macを買ってしまえば電気代以外は0円です。 ChatGPT Plusに月額3,000円払うのを1年やめれば、メモリ増設分の差額は回収できる計算になります。
なぜこの方法を選ぶのか
ローカルLLMを動かす手段には、他にもllama.cppやOllama、LM Studioなど、便利なGUIツールが山ほどあります。 それでも私がMLXを推奨するのは、Appleの機械学習チームが直接開発しており、Apple Siliconのハードウェア性能を限界まで引き出せるからです。
llama.cppは汎用性が高い一方で、ビルドのオプション設定が複雑だったり、新しいアーキテクチャへの対応にラグが生じたりすることがあります。 対してMLXは、PyTorchに近い記法で記述できるため、エンジニアにとってカスタマイズ性が非常に高いのが魅力です。 また、MLX-LMというラッパーライブラリを使えば、Hugging Faceにある数千のモデルを変換作業なしで、そのまま4-bit量子化された状態で実行できます。 「とりあえず動く」のその先にある、自作アプリへの組み込みやファインチューニングを見据えるなら、現時点ではMLX一択だと断言します。
Step 1: 環境を整える
まずはPython環境の構築から始めます。 Mac標準のPythonを汚さないよう、仮想環境を作成するのが鉄則です。
# プロジェクト用のディレクトリを作成
mkdir mlx-test && cd mlx-test
# Python 3.10以上の環境を用意(uvを使うのが最速でおすすめです)
# なければ python3 -m venv .venv でも代用可能
uv venv --python 3.11
source .venv/bin/activate
# MLX-LMをインストール
# これ一つでmlx本体と、LLM操作用の便利ツールがすべて入ります
pip install mlx-lm
各コマンドの意図を解説します。
mlx-lmは、Apple公式のmlxをLLM(大規模言語モデル)向けにラップしたライブラリです。
これを入れることで、モデルのダウンロード、量子化、推論のコードを大幅に簡略化できます。
Pythonのバージョンは3.10以上が必須ですが、最新の3.12だと稀に依存ライブラリで詰まることがあるため、私は安定している3.11を好んで使っています。
落とし穴:
Intelチップ搭載のMacでは、この手順は一切動きません。
pip install自体は通るかもしれませんが、実行時に「ライブラリが見つからない」あるいは「CPUでしか動かない」という事態になります。
自分のMacがM1/M2/M3/M4のいずれかであることを、左上のAppleメニュー「このMacについて」から必ず事前に確認してください。
Step 2: 基本の設定
次に、Pythonスクリプトを作成します。 ここでは、世界的に評価の高い「Meta-Llama-3.1-8B-Instruct」を、4-bit量子化された状態でロードする設定を書きます。
# main.py という名前で保存してください
from mlx_lm import load, generate
# 使用するモデルの指定
# Hugging Face上のレポジトリ名を指定します
# 4bit量子化版を直接指定することで、メモリ消費を大幅に抑えられます
model_path = "mlx-community/Meta-Llama-3.1-8B-Instruct-4bit"
# モデルとトークナイザーをロード
# load関数は、ローカルにモデルがなければ自動でダウンロードしてくれます
model, tokenizer = load(model_path)
# システムプロンプトの設定
# 「なぜこの設定にするのか」:モデルに役割を与え、回答の質を安定させるためです
system_prompt = "あなたは優秀なエンジニアです。簡潔かつ正確に回答してください。"
モデル名に 4bit と入っているものを選ぶのが最大のポイントです。
8Bモデルをそのまま(FP16)で読み込むと約15GBのメモリを消費しますが、4bit量子化版なら約5GB程度で済みます。
これにより、メモリ16GBのMacBook Airでも、ブラウザやSlackを開きながら裏でLLMを常駐させることが可能になります。
load関数は初回実行時のみダウンロードに時間がかかりますが(約5GB)、2回目以降はキャッシュから高速に読み込まれます。
Step 3: 動かしてみる
最小限の推論コードを書き足して、実際に動かしてみましょう。
# main.py の末尾に追記
prompt = "Pythonでフィボナッチ数列を生成するコードを書いてください。"
# Llama 3のテンプレートに合わせて整形
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt}
]
formatted_prompt = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
# 生成の実行
# max_tokens: 出力される最大文字数。最初は短めにしてテストします
# temp: 0に近づけるほど決定的(真面目)、1に近づけるほど創造的になります
response = generate(
model,
tokenizer,
prompt=formatted_prompt,
max_tokens=500,
verbose=True # 生成過程をリアルタイムで表示する
)
print(f"\n--- 最終回答 ---\n{response}")
期待される出力
Fetching 5 files: 100%|██████████████████| 5/5 [00:00<00:00, 24513.78it/s]
...
Pythonでフィボナッチ数列を生成する最も効率的な方法は、ジェネレータを使用することです。
以下にコード例を示します。
[コードが表示される...]
結果の読み方を解説します。
verbose=Trueに設定していると、1秒間に何トークン生成されたか(tokens/sec)が表示されます。
Apple Siliconであれば、8Bモデルで秒間30〜60トークン程度は出るはずです。
これは人間が読む速度よりも遥かに速く、ChatGPTの無料版よりも圧倒的にレスポンスが良いと感じるはずです。
Step 4: 実用レベルにする
単発の質問で終わっては面白くありません。 実務で使うためには、過去の対話履歴を保持し、連続したチャットができるように拡張する必要があります。 メモリ管理を意識しつつ、ストリーミング出力(文字がタイピングされるように出てくる形式)を実装します。
from mlx_lm import load, generate
def run_chat():
model_path = "mlx-community/Meta-Llama-3.1-8B-Instruct-4bit"
model, tokenizer = load(model_path)
# 対話履歴を保持するリスト
history = [
{"role": "system", "content": "あなたは技術的な質問に答えるAIアシスタントです。"}
]
while True:
user_input = input("\nユーザー: ")
if user_input.lower() in ["exit", "quit", "bye"]:
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)
# generate関数をカスタマイズして、ストリーミングに近い体験を作る
# mlx_lmのgenerateは一括生成ですが、内部のstream関数を使うとより実用的です
# ここではシンプルにgenerateのverbose機能を利用します
response = generate(
model,
tokenizer,
prompt=prompt,
max_tokens=1000,
verbose=False # 自分で制御するためFalse
)
print(response)
history.append({"role": "assistant", "content": response})
# 履歴が長くなりすぎるとメモリを圧迫するため、直近10件のみ保持する
if len(history) > 11:
history = [history[0]] + history[-10:]
if __name__ == "__main__":
run_chat()
このコードの重要なポイントは、対話履歴の管理です。 ローカルLLMには「コンテキストウィンドウ」という、一度に扱える情報の限界があります。 Llama 3.1は非常に大きい窓を持っていますが、履歴を無限に送り続けると、計算量が指数関数的に増えてレスポンスが重くなります。 実務で使うスクリプトにするなら、このように「直近の10件だけを送る」といった制御を入れるのが、安定運用のコツです。
よくあるトラブルと解決法
| エラー内容 | 原因 | 解決策 |
|---|---|---|
ImportError: DLL load failed | Pythonのアーキテクチャ不一致 | Intel版Pythonを使っている可能性大。Arm版Pythonを再インストールしてください。 |
MemoryError または動作停止 | メモリ不足(Unified Memoryの枯渇) | 他の重いアプリ(Chromeのタブ等)を閉じるか、より小さいモデル(1Bや3Bクラス)に変更してください。 |
| 出力が文字化けする、または止まらない | トークナイザーの不整合 | apply_chat_template を使っているか確認。モデル独自の書式を守らないと制御不能になります。 |
次のステップ
MLXでローカルLLMを動かすことに成功したら、次は「RAG(検索拡張生成)」に挑戦してみてください。 自分の持っているPDFファイルや、社内のドキュメントをベクトルデータベース(ChromaDBやFAISS)に入れ、MLXと組み合わせることで、あなた専用の知識を持ったAIを構築できます。
また、MLXは推論だけでなく、LoRA(Low-Rank Adaptation)という手法を使ったファインチューニングも非常に得意です。 例えば、自分の過去のブログ記事を学習させて、自分の文体そっくりに下書きを書いてくれるAIを作ることも、Mac 1台で可能です。 Apple Siliconのパワーは、単に消費するだけではなく、自分専用のモデルを「育てる」ために使うのが、最もクリエイティブな活用法だと私は考えています。
よくある質問
Q1: M1 Macのメモリ8GBモデルでも、工夫すれば動きますか?
動きますが、Llama 3 8Bはかなり厳しいです。Qwen2.5-1.5Bや、Gemma-2-2Bといった軽量なモデルを選んでください。4-bit量子化を適用すれば、メモリ消費を2GB程度に抑えられるため、8GB環境でも実用的な速度が出せます。
Q2: モデルのダウンロード先を変更したいのですが、どうすればいいですか?
環境変数 HF_HOME を設定してください。デフォルトではホームディレクトリの .cache/huggingface に保存されますが、外付けSSDなどにモデルを置きたい場合は、.bashrc や .zshrc でパスを指定すれば解決します。
Q3: MLXとOllama、どちらをメインで使うべきですか?
「とにかく手軽にチャットしたい」ならOllamaです。しかし「Pythonコードに組み込みたい」「独自のロジックでLLMを制御したい」「ファインチューニングを試したい」というエンジニアリングが目的であれば、MLXを強くおすすめします。
📦 この記事に関連する商品(楽天メインで価格確認)
MacBook Pro M3 Max36GB以上のメモリがあれば、中規模モデルも余裕で動作し、MLXの真価を体感できるため
※アフィリエイトリンクを含みます




