🙆‍♀️

MLX基礎解説 - Appleの次世代MLフレームワーク

に公開

難易度: ★★☆☆☆(初級〜中級)
想定読者: Apple Silicon専用で最大性能を出したい人、LLMをローカルで動かしたい人

TL;DR

  • MLXはApple Silicon専用に設計されたオープンソースMLフレームワーク
  • NumPy/PyTorch風のAPIで学習コストが低い
  • 統合メモリアーキテクチャを活かした遅延評価でメモリ効率が高い
  • LLMのローカル実行に特に強い

MLXとは?

2023年末、Appleが突如としてオープンソースで公開したMLフレームワーク、それがMLX。正直、最初聞いたときは「また新しいフレームワーク?」と思った。PyTorchとTensorFlowでお腹いっぱいだよ、と。

でも使ってみると、これがなかなかどうして侮れない。

Apple Machine Learning Researchの公式サイトでは:

"MLX is an open source array framework that is efficient, flexible, and highly tuned for Apple silicon."

(MLXは、効率的で柔軟性が高く、Apple Silicon向けに高度に最適化されたオープンソースの配列フレームワークです)

出典:Apple Machine Learning Research

GitHubリポジトリには、MLXの設計思想がこう記されている:

"MLX is designed by machine learning researchers for machine learning researchers. The framework is intended to be user-friendly, but still efficient to train and deploy models."

(MLXは機械学習研究者が機械学習研究者のために設計しました。フレームワークはユーザーフレンドリーでありながら、モデルの訓練とデプロイに効率的であることを目指しています)

出典:GitHub - ml-explore/mlx


MLXの設計思想

MLXには明確な設計原則がある。公式ドキュメントから引用しよう:

"Familiar APIs: MLX has a Python API that closely follows NumPy. MLX also has fully featured C++, C, and Swift APIs, which closely mirror the Python API. MLX has higher-level packages like mlx.nn and mlx.optimizers with APIs that closely follow PyTorch to simplify building more complex models."

(馴染みのあるAPI:MLXにはNumPyに準拠したPython APIがあります。C++、C、SwiftのAPIもPython APIと同様に完全な機能を備えています。mlx.nnやmlx.optimizersのような高レベルパッケージはPyTorchに準拠したAPIを持ち、複雑なモデルの構築を簡素化します)

出典:GitHub - ml-explore/mlx

つまり:

  • NumPyを使えるならMLXも使える
  • PyTorchを使えるニューラルネットワークも組める
  • 学習コストが劇的に低い

インストールと基本操作

インストール

pip install mlx

これだけ。依存関係も少ない。

基本操作

import mlx.core as mx

# NumPyとほぼ同じ
a = mx.array([1.0, 2.0, 3.0])
b = mx.array([4.0, 5.0, 6.0])
c = a + b
print(c)  # array([5, 7, 9], dtype=float32)

# 行列演算
x = mx.random.normal((3, 4))
y = mx.random.normal((4, 5))
z = x @ y  # 行列乗算
print(z.shape)  # (3, 5)

NumPyユーザーなら違和感なく使えるはずだ。

ニューラルネットワーク

import mlx.core as mx
import mlx.nn as nn
import mlx.optimizers as optim

# シンプルなMLP
class MLP(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super().__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.fc2 = nn.Linear(hidden_dim, output_dim)
    
    def __call__(self, x):
        x = nn.relu(self.fc1(x))
        x = self.fc2(x)
        return x

model = MLP(784, 256, 10)
optimizer = optim.Adam(learning_rate=0.001)

PyTorchに慣れた人なら、ほぼそのまま書ける。


遅延評価(Lazy Computation):MLXの真骨頂

MLXの面白いところは、計算が「遅延」されること。

"Lazy computation: Computations in MLX are lazy. Arrays are only materialized when needed."

(遅延計算:MLXの計算は遅延されます。配列は必要になったときにのみ実体化されます)

出典:GitHub - ml-explore/mlx

なぜ遅延評価が重要か

import mlx.core as mx

a = mx.random.normal((1000, 1000))
b = mx.random.normal((1000, 1000))
c = a @ b  # ここではまだ計算されない!
d = c + 1
e = mx.sum(d)  # eが必要になって初めて、a〜eまでの計算が最適化されて実行
print(e)

従来のフレームワークだと、各行で即座に計算が走る。でもMLXはprint(e)の瞬間まで待ってから、計算グラフ全体を見て最適化する。

メリット:

  • 無駄な中間結果をメモリに保持しなくて済む
  • 演算の融合(fusion)が可能
  • 使わない計算は実行されない

明示的な評価

どうしても即座に計算させたい場合:

c = a @ b
mx.eval(c)  # ここで強制的に計算

M5チップとNeural Accelerators

2025年、M5チップの登場でMLXはさらに進化した。

Apple Machine Learning Researchの最新記事では:

"The GPU Neural Accelerators introduced with the M5 chip provides dedicated matrix-multiplication operations, which are critical for many machine learning workloads. MLX leverages the Tensor Operations (TensorOps) and Metal Performance Primitives framework introduced with Metal 4 to support the Neural Accelerators' features."

(M5チップで導入されたGPU Neural Acceleratorsは、多くの機械学習ワークロードに不可欠な専用の行列乗算演算を提供します。MLXはMetal 4で導入されたTensor OperationsとMetal Performance Primitivesフレームワークを活用し、Neural Acceleratorsの機能をサポートします)

出典:Apple Machine Learning Research - Exploring LLMs with MLX and M5

M4 vs M5 ベンチマーク

Appleが公開したベンチマークでは、LLM推論での改善が顕著:

モデル M4 (トークン/秒) M5 (トークン/秒) 改善率
Qwen 1.7B (BF16) 基準 向上 〜30%+
Qwen 8B (4bit) 基準 向上 〜25%+
Mixtral 30B (4bit) 基準 向上 〜20%+

特に「最初のトークン生成までの時間」が大幅に短縮された。


MLX-LM:LLMを手軽に動かす

MLXの真価が発揮されるのは、LLM(大規模言語モデル)の推論だ。

mlx-lmパッケージを使えば、Hugging Faceのモデルをそのまま動かせる:

pip install mlx-lm

# ターミナルで直接チャット開始!
mlx_lm.chat --model mlx-community/Qwen2.5-7B-Instruct-4bit

公式サイトによると:

"MLX LM is a package built on top of MLX for generating text and fine-tuning language models. It allows running most LLMs available on Hugging Face."

(MLX LMはMLX上に構築されたパッケージで、テキスト生成と言語モデルの微調整を行います。Hugging Faceで利用可能なほとんどのLLMを実行できます)

出典:Apple Machine Learning Research

Pythonから使う

from mlx_lm import load, generate

model, tokenizer = load("mlx-community/Llama-3-8B-Instruct-4bit")

prompt = "Explain quantum computing in simple terms:"
response = generate(model, tokenizer, prompt=prompt, max_tokens=200)
print(response)

量子化サポート

メモリの節約には量子化が効く:

"MLX natively supports quantization, a compression approach which reduces the memory footprint of a language model by using a lower precision for storing the parameters of the model."

(MLXはネイティブで量子化をサポートしています。量子化はモデルのパラメータを低精度で保存することで、言語モデルのメモリフットプリントを削減する圧縮アプローチです)

# モデルを4bit量子化
mlx_lm.convert --hf-path mistralai/Mistral-7B-Instruct-v0.3 -q

4ビット量子化すれば、7Bパラメータのモデルも16GBのMacで動く。


MLX vs PyTorch (MPS):どっちを使う?

「結局どっちがいいの?」という疑問はもっともだ。

特徴 MLX PyTorch (MPS)
API NumPy/PyTorch風 PyTorch
エコシステム 発展途上 成熟
最適化度 Apple Silicon特化 汎用的
LLM推論 非常に得意 対応
モデル変換 Hugging Face直接 そのまま使える
学習 可能 可能
クロスプラットフォーム Apple専用 マルチプラットフォーム

私の使い分け

  • LLMをローカルで動かしたい → MLX
  • 既存のPyTorchコードを高速化したい → MPS
  • 研究・実験 → MLX(遅延評価が便利)
  • 本番デプロイ → Core ML経由
  • チームで共有するコード → PyTorch(互換性重視)

MLXの制限事項

正直に言うと、MLXには弱点もある:

"Apple exclusivity: MLX only works on Apple hardware, making code portability a challenge."

"Ecosystem maturity: As a newer framework, MLX has fewer pre-built models, tutorials, and community solutions compared to PyTorch or TensorFlow."

出典:F22 Labs - What is MLX

主な制限

  1. Apple専用:Windows/Linuxでは動かない
  2. エコシステムの成熟度:PyTorchに比べるとまだまだ
  3. デプロイオプション:本番環境での選択肢が限られる
  4. ライブラリサポート:全てのML ライブラリがMLXに対応しているわけではない

でも逆に言えば、Apple環境に特化しているからこそ、極限まで最適化できる。トレードオフだ。


実践:MLXでの画像分類

簡単な例として、MLXでCNNを組んでみよう:

import mlx.core as mx
import mlx.nn as nn
import mlx.optimizers as optim

class SimpleCNN(nn.Module):
    def __init__(self, num_classes=10):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(64 * 7 * 7, 128)
        self.fc2 = nn.Linear(128, num_classes)
    
    def __call__(self, x):
        x = self.pool(nn.relu(self.conv1(x)))
        x = self.pool(nn.relu(self.conv2(x)))
        x = x.reshape(x.shape[0], -1)
        x = nn.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# モデルとオプティマイザ
model = SimpleCNN()
optimizer = optim.Adam(learning_rate=0.001)

# 損失関数
def loss_fn(model, x, y):
    logits = model(x)
    return mx.mean(nn.losses.cross_entropy(logits, y))

# 勾配計算と更新
loss_and_grad_fn = nn.value_and_grad(model, loss_fn)

def train_step(model, x, y, optimizer):
    loss, grads = loss_and_grad_fn(model, x, y)
    optimizer.update(model, grads)
    return loss

# トレーニングループ
for epoch in range(10):
    for batch_x, batch_y in data_loader:
        loss = train_step(model, batch_x, batch_y, optimizer)
        mx.eval(loss)  # 計算を実行

MLX Swiftとモバイル対応

MLXはSwiftからも使える:

"MLX Swift builds on the same core library as the MLX Python front-end. It also has several examples to help get you started with developing machine learning applications in Swift."

(MLX SwiftはMLX Pythonフロントエンドと同じコアライブラリ上に構築されています。Swiftで機械学習アプリケーションを開発するための例もいくつか用意されています)

出典:Apple Machine Learning Research

iOSアプリでMLXを直接使いたい場合の選択肢になる(ただし、一般的にはCore MLが推奨)。


まとめ:MLXは「Apple Silicon専用の秘密兵器」

MLXは「PyTorchキラー」を目指しているわけではない。むしろ、Apple Silicon上での機械学習体験を最高のものにするための専用ツールだ。

統合メモリアーキテクチャ、遅延評価、そしてM5のNeural Acceleratorsとの深い統合。これらが組み合わさったとき、MLXは他のフレームワークでは到達できない領域に達する。

もしあなたがApple Siliconユーザーなら、MLXを試さない手はない。


参考文献

Discussion