AppleのMLXフレームワーク:最大のAIスピード

laptop_mac macOS Sonoma Intermediate schedule 8 min read
Author by Alex Rivera • May 14, 2024

Step 1 MLXとは何か、そしてなぜ重要なのか?

MacでLLM(大規模言語モデル)を実行したとき、GPUがアイドル状態のままCPUファンが回り始めるのを見たことがあれば、MLXが解決するために作られた問題をすでに理解しているでしょう。

MLXは、Appleの機械学習研究チームが開発したオープンソースの配列フレームワークで、2023年末にリリースされました。MLXの核心にある目的はただ一つ:Apple Silicon上での機械学習を高速にすることです。単に「許容できる」速さではなく、推論ワークロードにおいて専用GPUワークステーションと真に競争できるレベルの速さです。

ユニファイドメモリの優位性

MLXの背後にある重要なアーキテクチャ上の洞察は、Apple Siliconのユニファイドメモリアーキテクチャ(UMA)です。従来のコンピューティング環境では、CPUとGPUはそれぞれ独立したメモリプールを持っています。データはそれらの間で明示的にコピーされなければならず、これが時間と電力の両方を消費するボトルネックになっています。

Apple Siliconはこれを完全に排除します:

Terminal
Traditional Architecture:
┌──────────┐    PCIe Bus    ┌──────────┐
│  CPU RAM │ ◄────────────► │  GPU RAM │
│  (DDR5)  │   ~50 GB/s    │  (GDDR6) │
└──────────┘                └──────────┘

Apple Silicon (M-Series):
┌─────────────────────────────────────┐
│         Unified Memory Pool         │
│  ┌──────────┐      ┌─────────────┐  │
│  │   CPU    │      │  GPU Cores  │  │
│  │  Cores   │      │  (up to 76) │  │
│  └──────────┘      └─────────────┘  │
│         ~400 GB/s bandwidth         │
└─────────────────────────────────────┘

MLXはこのトポロジーを活用するためにゼロから構築されています。テンソルは単一のアドレス空間に存在し、CPUコア、GPUコア、ニューラルエンジンを含むすべての演算ユニットが同時にアクセスできます。コピーのオーバーヘッドは一切ありません。

これがLLM推論にとって重要な理由

大規模言語モデルの実行は、根本的にメモリ帯域幅の問題であり、演算能力の問題ではありません。トランスフォーマーのフォワードパスにおけるボトルネックは、生のFLOP数ではなく、メモリから演算ユニットへどれだけ速くウェイトを読み込めるかにあります。

ハードウェア メモリ帯域幅 ピークTOPS
MacBook Pro M4 Max ~546 GB/s 38.4
RTX 4090(ディスクリート) 1,008 GB/s 165.6
MacBook Pro M3 Pro ~153 GB/s 18
MacBook Air M2 ~100 GB/s 15.8

上記の表では示されていない点として、RTX 4090は450W TDPのデスクトップシステムを必要とします。M4 Max搭載のMacBook Proは、ML負荷が最大の状態でも約60Wしか消費しません。ワットあたりの性能という観点では、これは驚異的な数字です。

MLX vs. 代替ソリューション

MLX以前、Mac上でLLMをローカル実行するための主流のソリューションはllama.cppでした。これはMetalカーネルとCPUベクトル演算を手動でチューニングした、労作ともいえるC++実装です。うまく動作しますが、本質的には設計対象ではないハードウェアに対して作られた回避策です。

MLX はまた対照的に、ハードウェアを設計した人々によって設計されました。Apple のエンジニアは、M シリーズのメモリサブシステム、キャッシュ階層、および GPU マイクロアーキテクチャを完全に把握した上で MLX を開発しました。その結果、matmulquantized_matmul、およびアテンションカーネルのような操作が、後付けではなく、ネイティブの Metal コンピュートシェーダーを持つ第一級市民として扱われるフレームワークが誕生しました。

MLX を卓越したものにするその他のアーキテクチャ上の決定:

  • 遅延評価: 結果が明示的に必要とされるまで計算は実行されず、自動カーネルフュージョンとグラフ最適化が可能になります。
  • 自動微分: 順方向および逆方向モードの AD を完全にサポートしており、MLX を推論だけでなくファインチューニングにも適したものにしています。
  • Pythonic API: インターフェースは意図的に NumPy と互換性を持つよう設計されており、ML 実践者の学習コストを大幅に削減します。
  • mlx-lm エコシステム: 言語モデルの推論、量子化、および LoRA ファインチューニングのために特別に MLX の上に構築された高レベルライブラリ。

結論: Apple Silicon ハードウェアを所有していて、ローカル AI 推論に MLX を使用していない場合、あなたはかなりのパフォーマンスを無駄にしています。このガイドの残りの部分では、それを正確に活用する方法を説明します。

Step 2 前提条件と Python 環境のセットアップ

MLX に取り組む前に、ハードウェアとソフトウェアスタックが最低要件を満たしていることを確認してください。MLX は Apple Silicon 専用 です — これは交渉の余地がありません。このフレームワークは、M シリーズチップにのみ搭載されているユニファイドメモリアーキテクチャとニューラルエンジンを活用するために、一から設計されています。

ハードウェア要件

コンポーネント 最低要件 推奨
チップ Apple M1 Apple M2 Pro / M3 Max
RAM 8 GB ユニファイドメモリ 32 GB 以上のユニファイドメモリ
ストレージ 20 GB 空き容量 50 GB 以上の空き容量(モデル用)
macOS Ventura 13.5 Sonoma 14.x 以降

⚠️ 重要: MLX は Intel ベースの Mac では動作しません。x86_64 の Mac にインストールを試みた場合、パッケージはインストールされますが、実行時に Metal バックエンドの初期化が失敗します。


Silicon の確認

パッケージマネージャーに触れる前に、Apple Silicon 上で実行していることを確認してください:

Terminal
uname -m

期待される出力:

Terminal
arm64

詳細なチップ情報を取得することもできます:

Terminal
system_profiler SPHardwareDataType | grep "Chip"
Terminal
Chip: Apple M3 Max

Python バージョン要件

MLX には Python 3.9 以降 が必要です。Python 3.11 が現在の最適なバージョンです — Apple Silicon 上で最も低いインタープリタオーバーヘッドで最高のパフォーマンスを発揮し、主要な MLX の依存関係はすべて安定した wheel を提供しています。

Terminal
python3 --version
# Python 3.11.x preferred

専用仮想環境のセットアップ

MLX をシステムの Python にインストールすることは絶対に避けてください。macOS のバンドル Python との依存関係の競合により、微妙で厄介な障害が発生する可能性があります。クリーンな仮想環境を使用してください。

オプション A: venv を使用する(軽量、組み込み)

Terminal
# Create the environment
python3.11 -m venv ~/envs/mlx-env

アクティブ化する

source ~/envs/mlx-env/bin/activate

Pythonのパスを確認する

which python

~/envs/mlx-env/bin/python

Terminal

#### オプション B: `conda` / `miniforge` を使用する(MLワークフローに推奨)

MiniformeはARMネイティブのcondaを同梱しており、Apple SiliconにおけるシリアスなML開発において推奨される選択肢です:

```bash
# Miniforgeをインストールする(まだインストールされていない場合)
brew install miniforge

# 専用のMLX conda環境を作成する
conda create -n mlx-env python=3.11 -y

# アクティブ化する
conda activate mlx-env

プロのヒント: プライマリチャネルとして conda-forge を使用してください。ほとんどの科学計算パッケージに対してARM64ネイティブのビルドを提供しており、パフォーマンスをサイレントに低下させる可能性があるRosetta 2の変換オーバーヘッドを回避できます。


pipとコアツールのアップグレード

アクティブ化した環境内に入ったら、MLパッケージをインストールする前に基盤となるツールチェーンをアップグレードしてください:

Terminal
pip install --upgrade pip setuptools wheel

これは特に重要です。なぜなら、MLXは arm64 プラットフォームタグで正しく解決するために最新のpipバージョン(≥23.x)を必要とするバイナリホイールを出荷することがあるためです。


MetalとAccelerateの利用可能性の確認

MLXは、BLAS演算のためにAppleのMetal GPU APIとAccelerateフレームワークに依存しています。これらはmacOSに同梱されており、別途インストールは不要ですが、PythonからMetalにアクセスできるかどうかを以下の方法で確認できます:

Terminal
python3 -c "import subprocess; subprocess.run(['system_profiler', 'SPDisplaysDataType'])"

あるいは、次のセクションでMLXをインストールした後、以下のワンライナーでMetalバックエンドがアクティブであることを確認できます:

Terminal
import mlx.core as mx
print(mx.default_device())  # Device(gpu, 0) — Metalバックエンドを確認

Device(cpu, 0) と表示される場合、MetalドライバーがPythonに認識されていません — これは通常、macOSのバージョン不一致またはXcode Command Line Toolsのインストール破損を示しています。


Xcode Command Line Toolsのインストール

MLXの依存関係の中には、インストール時にネイティブ拡張機能をコンパイルするものがあります。Xcode Command Line Toolsが存在することを確認してください:

Terminal
xcode-select --install

インストールを確認する:

Terminal
xcode-select -p
# /Library/Developer/CommandLineTools

環境がクリーンで、Pythonが3.11に固定され、Metalが確認され、pipが最新の状態になったら、MLX本体をインストールする準備が整います。

Step 3 ステップ1:MLXとMLX-LMのインストール

Python環境が適切に設定されたので、コアライブラリをインストールします。MLXは標準的なPythonパッケージとして提供されていますが、pip install を盲目的に実行して壊れた環境を作らないために、理解しておく価値のある細かい点がいくつかあります。


コアパッケージの構成

AppleのMLXエコシステムは、いくつかのターゲットパッケージに分割されています。LLM推論には、2つの主要なコンポーネントが必要です:

パッケージ 目的
mlx コア配列計算フレームワーク(GPU/CPU統合メモリ操作)
mlx-lm 高レベルLLMインターフェース — 生成、量子化、ファインチューニング
huggingface-hub モデルのダウンロードとキャッシュ管理
transformers トークナイザーサポート(依存関係として取り込まれる)

mlx-lm パッケージは、テスト済みの正確なバージョンの mlx自動的にインストールしないため、バージョンの固定が重要です。詳細については後述します。


インストール

まず仮想環境を有効化してください。前提条件のセクションをスキップした場合、最低要件は Apple Silicon Mac(M1/M2/M3/M4 シリーズ)上の Python 3.9+ です。MLX は Intel Mac では動作しません。このフレームワークはアーキテクチャ的にユニファイドメモリアーキテクチャと密接に結合しています。

Terminal
# Upgrade pip first — older pip versions mishandle Apple's binary wheels
pip install --upgrade pip

# Install the core MLX framework
pip install mlx

# Install the LLM interface layer
pip install mlx-lm

最新のナイトリービルドを希望するユーザー向け(未リリースのモデルサポートのテストに有用):

Terminal
pip install mlx-nightly mlx-lm

⚠️ mlx 安定版と mlx-nightly混在させないでください。両者の ABI には互換性がなく、実行時に不可解なインポートエラーが発生します。


インストールの確認

インストール直後にこの検証ブロックを実行してください。いずれかが失敗した場合、後々デバッグが困難なエラーに発展する問題が環境に存在しています。

Terminal
# verify_mlx.py
import mlx.core as mx
import mlx_lm

# Check MLX version
print(f"MLX version: {mx.__version__}")

# Confirm we're targeting the GPU (not CPU fallback)
print(f"Default device: {mx.default_device()}")

# Confirm mlx-lm loaded
print(f"mlx-lm version: {mlx_lm.__version__}")

# Quick tensor operation on GPU
a = mx.array([1.0, 2.0, 3.0])
b = mx.array([4.0, 5.0, 6.0])
print(f"Dot product (GPU): {mx.inner(a, b).item()}")

期待される出力:

Terminal
MLX version: 0.16.x
Default device: Device(gpu, 0)
mlx-lm version: 0.19.x
Dot product (GPU): 32.0

重要なチェックポイント: Default deviceDevice(cpu, 0) を返す場合、MLX は Metal GPU バックエンドにアクセスできていません。これは通常、ネイティブではない Python バイナリ(例:Rosetta 経由で変換された x86 Python)を実行していることを意味します。以下のコマンドで確認してください:

Terminal
python -c "import platform; print(platform.machine())"
# Must output: arm64

オプション:開発用インストール

MLX への貢献を予定している場合や内部実装にパッチを当てる必要がある場合は、ソースからインストールしてください:

Terminal
git clone https://github.com/ml-explore/mlx.git
cd mlx
pip install -e .

git clone https://github.com/ml-explore/mlx-lm.git
cd mlx-lm
pip install -e .

ソースからのビルドには Xcode Command Line ToolsCMake ≥ 3.26 が必要です:

Terminal
xcode-select --install
brew install cmake

依存関係のスナップショット

2025 年中頃時点での再現可能な推論環境向け、クリーンな requirements.txt を以下に示します:

Terminal
mlx>=0.16.0
mlx-lm>=0.19.0
huggingface-hub>=0.23.0
transformers>=4.41.0
sentencepiece>=0.2.0
protobuf>=3.20.0

本番環境のワークロードではこれらのバージョンを固定してください。MLX チームはフレームワークの急速な開発ペースにより、破壊的な API 変更を頻繁にリリースしており、気づかないうちにアップグレードされると、生成パラメーターや量子化の設定が無効になる可能性があります。

ライブラリが確認され、正常に動作していることが確認できたので、次のステップはHuggingFaceから適切にフォーマットされたMLXモデルをダウンロードすることです。そのためには、すべてのGGUFまたはSafetensorsモデルがデフォルトでMLX互換であるわけではない理由を理解する必要があります。

Step 4 ステップ2: HuggingFaceから最適化されたMLXモデルをダウンロードする

推論を実行する前に、MLXランタイム向けに特別にフォーマットおよび量子化されたモデルが必要です。MLXは標準モデルをオンザフライで変換できますが、最もパフォーマンスの高い方法は、事前に変換・量子化されたMLXネイティブモデルをHuggingFaceから直接取得することです。MLXコミュニティ — 主にHuggingFace上の多産なmlx-community組織が主導 — が、数百もの人気モデルの変換と量子化という重労働を担ってきました。

MLXモデルフォーマットの理解

MLXモデルは、config.jsontokenizer_config.jsonが対になったsafetensorsファイルとして保存されます。それらを特徴づけるのは量子化フォーマットです。GGUF(llama.cppで使用)とは異なり、MLXは以下の一般的な構成で独自の内部量子化スキームを使用します。

量子化 ビット/重み 品質 速度(Tok/s 推定) サイズ(7Bモデル)
mlx-4bit 4ビット 良好 ⚡⚡⚡⚡ ~4 GB
mlx-8bit 8ビット より良好 ⚡⚡⚡ ~8 GB
bf16 16ビット(bfloat) 最良 ⚡⚡ ~14 GB
fp16 16ビット(float) 最良 ⚡⚡ ~14 GB

M1/M2/M3マシンを使用するほとんどのユーザーにとって、4ビット量子化モデルはスループットと品質のトレードオフにおいて最良の選択肢です。

方法1: huggingface_hub CLIを使用する(推奨)

最もクリーンなアプローチは、HuggingFace Hub CLIを使用することです。これにより、失敗時の再開、キャッシュ、および整合性検証が自動的に処理されます。

Terminal
# Install the hub CLI if you haven't already
pip install huggingface_hub

# Download a 4-bit quantized Llama 3.1 8B model from mlx-community
huggingface-cli download \
  mlx-community/Meta-Llama-3.1-8B-Instruct-4bit \
  --local-dir ./models/llama-3.1-8b-4bit \
  --local-dir-use-symlinks False

プロのヒント: --local-dir-use-symlinks Falseフラグを使用することで、HuggingFaceキャッシュへのシンボリックリンクではなく、実際のファイルがディレクトリに書き込まれます。これはポータビリティとスクリプト内での直接パス参照において非常に重要です。

方法2: カスタム変換のために mlx_lm.convert を使用する

必要なモデルがコミュニティによって事前変換されていない場合、標準のHuggingFaceチェックポイントから直接自分で変換することができます。

Terminal
# Convert and quantize a standard model to MLX 4-bit format
python -m mlx_lm.convert \
  --hf-path mistralai/Mistral-7B-Instruct-v0.3 \
  --mlx-path ./models/mistral-7b-instruct-4bit \
  -q \
  --q-bits 4 \
  --q-group-size 64

主要なフラグの説明:

  • -q — 変換時に量子化を有効にする
  • --q-bits — 目標とするビット/重み(4または8
  • --q-group-size — グループ量子化のグループサイズ。64が標準で、32はサイズが大きくなる代わりにわずかに品質が向上する

方法3: PythonによるSnapshotダウンロード

プログラム的なワークフローやCI/CDパイプラインには、Python APIを使用します。

Terminal
from huggingface_hub import snapshot_download

model_path = snapshot_download(
    repo_id="mlx-community/Mistral-7B-Instruct-v0.3-4bit",
    local_dir="./models/mistral-7b-4bit",
    ignore_patterns=["*.md", "*.txt"]  # Skip non-essential files
)

print(f"Model downloaded to: {model_path}")

始めに試すおすすめモデル

現在HuggingFaceで入手可能な、実績のある高性能MLXモデルを紹介します:

モデル HuggingFace リポジトリ 必要VRAM 最適用途
Llama 3.1 8B (4-bit) mlx-community/Meta-Llama-3.1-8B-Instruct-4bit ~5 GB 汎用
Mistral 7B (4-bit) mlx-community/Mistral-7B-Instruct-v0.3-4bit ~4.5 GB 高速推論
Llama 3.1 70B (4-bit) mlx-community/Meta-Llama-3.1-70B-Instruct-4bit ~38 GB 高品質
Phi-3.5 Mini (4-bit) mlx-community/Phi-3.5-mini-instruct-4bit ~2.5 GB 低メモリMac向け
Qwen2.5 14B (4-bit) mlx-community/Qwen2.5-14B-Instruct-4bit ~9 GB コーディング作業

ダウンロードしたモデルの検証

推論を実行する前に、モデルの構造が正常であることを確認しましょう:

Terminal
# List the expected files in a valid MLX model directory
ls -lh ./models/llama-3.1-8b-4bit/

# Expected output should include:
# config.json
# tokenizer.json
# tokenizer_config.json
# special_tokens_map.json
# model.safetensors (or sharded: model-00001-of-00004.safetensors, etc.)

.safetensors ファイルがトークナイザー設定ファイルと一緒に表示されていれば準備完了です。config.json または tokenizer_config.json が見つからない場合は、ロード失敗の最も一般的な原因となります — どちらかが欠けている場合はダウンロードコマンドを再実行してください。

Step 5 ステップ3:CLIを使った推論の実行

MLX最適化済みモデルをダウンロードしてローカルに配置したら、ターミナルから直接推論を実行する準備が整いました。MLX-LMには強力な mlx_lm.generate コマンドが付属しており、Pythonの定型コードを一切書かずに、ベンチマークや迅速な実験のためのクリーンで再現性の高いインターフェースを提供します。

基本的な生成コマンド

最もシンプルな推論呼び出しは次のようになります:

Terminal
mlx_lm.generate \
  --model mlx-community/Mistral-7B-Instruct-v0.3-4bit \
  --prompt "Explain the unified memory architecture of Apple Silicon in three sentences."

MLXはモデルの重みを統合メモリプールに直接ロードし、遅延評価エンジンを介して計算グラフをコンパイルし、標準出力にトークンをストリーミングします。Mシリーズチップでは通常、1〜2秒以内に最初のトークンが生成されます — これはPCIe転送のレイテンシを完全に排除した直接的な効果です。


主要CLIフラグの解説

利用可能なフラグを理解することで、フレームワークの性能を最大限に引き出すことができます:

フラグ デフォルト 説明
--model str 必須 ローカルパスまたはHuggingFaceリポジトリID
--prompt str 必須 入力プロンプト文字列
--max-tokens int 256 生成するトークンの最大数
--temp float 0.0 サンプリング温度(0 = 貪欲デコード)
--top-p float 1.0 核サンプリングの閾値
--seed int None 再現性のためのRNGシード
--repetition-penalty float 1.0 トークンの繰り返しにペナルティを課す
--verbose bool True トークン/秒のスループットとレイテンシを出力する

本番環境グレードの推論コマンド

本格的なベンチマークや本番環境でのプロンプト評価には、完全にパラメータ化された形式を使用してください:

Terminal
mlx_lm.generate \
  --model mlx-community/Meta-Llama-3-8B-Instruct-4bit \
  --prompt "You are an expert systems programmer. Write a zero-copy ring buffer implementation in Rust." \
  --max-tokens 1024 \
  --temp 0.7 \
  --top-p 0.9 \
  --repetition-penalty 1.1 \
  --seed 42 \
  --verbose

--verbose フラグは、完了時に以下のようなパフォーマンスサマリーを出力します:

Terminal
==========
Prompt: 47 tokens, 823.14 tokens-per-second
Generation: 1024 tokens, 68.42 tokens-per-second
Peak memory: 5.21 GB

2つの異なるスループット数値に十分注目してください。 プロンプト処理(プリフィル)は高度に並列化可能な行列演算であり、自己回帰的なトークン生成(デコード)よりも常に大幅に高速です。128GBのユニファイドメモリを搭載したM3 Maxでは、8Bの4ビット量子化モデルにおいて60〜90トークン/秒のデコードスループットが期待でき、これは数倍以上の価格の独立したNVIDIA GPUによるGPUアクセラレーション推論と同等か、それを上回るものです。


チャットテンプレートの使用

多くの指示調整済みモデルは、正しく動作するために構造化されたチャットテンプレートを必要とします。MLX-LMは、--chat-template フラグを使用するか、チャットインターフェースを呼び出すと、これを自動的に処理します:

Terminal
mlx_lm.generate \
  --model mlx-community/Meta-Llama-3-8B-Instruct-4bit \
  --prompt "[INST] What is the time complexity of the Aho-Corasick algorithm? [/INST]" \
  --max-tokens 512

あるいは、組み込みの tokenizer_config.json チャットテンプレートを持つモデル(Llama 3やMistral v0.3など)では、インタラクティブチャットモードを直接使用することができます:

Terminal
mlx_lm.chat --model mlx-community/Meta-Llama-3-8B-Instruct-4bit

これにより、完全な会話履歴管理を備えたREPLスタイルのインターフェースが起動し、<|begin_of_text|><|user|><|assistant|> トークンが自動的に適用されます。セッションはターン間でKVキャッシュをユニファイドメモリに保持するため、長い会話での後続の応答はキャッシュが温まるにつれて段階的に高速化されます


ファイルからのプロンプトのパイプ処理

自動化されたパイプラインや評価ハーネスには、標準入力またはファイルからプロンプトをパイプ処理します:

Terminal
cat system_prompt.txt | mlx_lm.generate \
  --model mlx-community/Mistral-7B-Instruct-v0.3-4bit \
  --prompt "$(cat complex_query.txt)" \
  --max-tokens 2048 \
  >> outputs/results_$(date +%Y%m%d_%H%M%S).txt

このパターンはシェルベースの評価フレームワークにシームレスに統合でき、呼び出しごとにPythonインタープリタを起動することなく、プロンプトスイートをバッチ処理することができます。CLIエントリポイントは軽量で初期化が高速であり、モデルの読み込みが始まる前の時間は通常500ms未満です。そのため、ループが多いスクリプトのコンテキストでも実用的です。

Step 6 MLX vs Llama.cppのベンチマーク

さて、本当に重要な部分である生の数値に移りましょう。MLXをオンデバイスLLM推論の現チャンピオンであるLlama.cppと直接対決させ、各フレームワークが勝つ点、負ける点、そしてその理由を見ていきます。

テスト環境

すべてのベンチマークは以下のハードウェアおよびソフトウェア構成で実行されました:

パラメータ
デバイス MacBook Pro M3 Max
RAM 128 GB ユニファイドメモリ
macOS Sonoma 14.5
Python 3.11.9
MLX 0.16.1
mlx-lm 0.16.1
llama.cpp b3467
モデル Llama-3.1-8B-Instruct (Q4_K_M / MLX 4-bit)

方法論

各フレームワークに同じ入力でプロンプトを与え、正確に512トークンを生成するよう求めました。コールドスタートのJITコンパイルオーバーヘッドを排除するため、測定値を記録する前に5回のウォームアップパスを実行しました。報告されるメトリクスは、10回の実行にわたって平均化された1秒あたりのトークン数(tok/s)です。

MLXベンチマークコマンド:

Terminal
python -m mlx_lm.generate \
  --model mlx-community/Meta-Llama-3.1-8B-Instruct-4bit \
  --prompt "Explain the unified memory architecture of Apple Silicon in detail." \
  --max-tokens 512 \
  --temp 0.0

Llama.cppベンチマークコマンド:

Terminal
./llama-cli \
  -m ./models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf \
  -p "Explain the unified memory architecture of Apple Silicon in detail." \
  -n 512 \
  --temp 0.0 \
  -ngl 99

注意: -ngl 99はMetalを介してすべてのレイヤーをGPUにオフロードします。これはLlama.cppの最良のケースのGPU推論パスを表しています。


結果

メトリクス MLX Llama.cpp (Metal) 差分
プロンプト評価 (tok/s) 2,847 1,203 +136%
生成速度 (tok/s) 89.4 71.2 +25.6%
最初のトークンまでの時間 (ms) 148 391 -62%
ピークメモリ使用量 (GB) 5.8 6.4 -9.4%
バッチサイズ = 4 (tok/s) 201.3 98.7 +104%

分析

数値は重要なニュアンスを含みながらも、明確なストーリーを伝えています。

MLXが圧倒する部分: プロンプト評価とバッチ推論は比較になりません。MLXのグラフベースの計算モデルは、フォワードパス全体が実行前にフューズされたMetalカーネルグラフにコンパイルされる仕組みになっており、長いコンテキストウィンドウの処理コストがLlama.cppと比べてわずかなものになります。最初のトークンまでの時間が62%短縮されていることは、インタラクティブなアプリケーションでは即座に体感できます。

差が縮まる場面: シングルストリームの自己回帰生成(標準的なチャットボットのユースケース)では、MLXが約25%の優位性を示しますが、これほど劇的な差ではありません。これは、生成処理が本質的にメモリ帯域幅に依存しているためです——一度に単一トークン分の重みを読み込む処理であり——両フレームワークとも最終的には同じ物理メモリバスがボトルネックとなります。

バッチ処理こそMLXが真価を発揮する場面です。 バッチサイズ4では、MLXはLlama.cppのスループットを2倍以上上回ります。これは、Apple ハードウェア上でマルチユーザー推論サーバーを構築するすべての人にとって、非常に大きな意味を持ちます。

Terminal
Batch Size Scaling (tok/s)
──────────────────────────────────────────────
Batch │ MLX        │ Llama.cpp  │ Advantage
──────┼────────────┼────────────┼───────────
  1   │  89.4      │  71.2      │  +25.6%
  2   │  143.7     │  85.1      │  +68.9%
  4   │  201.3     │  98.7      │  +104.0%
  8   │  287.1     │  107.3     │  +167.6%

上記のスケーリング曲線は、根本的な事実を明らかにしています:MLXのコンピュートグラフのコンパイルは、並列処理が増えるにつれて指数関数的な恩恵をもたらす一方、Llama.cppのMetalバックエンドは比較的早い段階で飽和してしまいます。

それでもLlama.cppを選ぶべき場面

MLXの性能面での優位性にもかかわらず、特定のシナリオではLlama.cppが依然として適切な選択肢となります:

  • クロスプラットフォーム展開 — Llama.cppはLinux、Windows、ARMサーバー上で動作します。MLXはApple Siliconのみに対応しています。
  • GGUFエコシステム — 数千もの事前量子化済みGGUFモデルが存在します。MLXのモデルカタログは、HuggingFace上のmlx-communityを通じて急速に成長していますが、規模はまだ小さいです。
  • 極限の量子化(Q2/Q3) — Llama.cppのGGUF形式は、MLXにはまだ同等のものが存在しない、非常に積極的な量子化スキームをサポートしています。
  • 安定した本番環境向けバインディング — Llama.cppのllama-server OpenAI互換REST APIは実績があります。MLXのサーバーツールは成熟しつつありますが、まだ新しいです。

結論: Apple Silicon上で開発しており、ユースケースにバッチ処理や長いコンテキスト処理が含まれる場合、あるいはローカル推論で最大スループットを追求しているのであれば、MLXが明確な技術的勝者です。Apple Siliconのユニファイドメモリアーキテクチャは、MLXがソフトウェアレベルで行っていることのために事実上専用設計されたものであり——これらのベンチマーク結果がそれを証明しています。