0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ExecuTorchのMLX delegateでQwen3を動かす――M1 Maxで最大4.52倍高速

0
Last updated at Posted at 2026-07-22

こんにちは、皆さん。

MacでLLMを動かす方法は増えましたが、PyTorchのモデルをApple Silicon向けに書き出し、軽いruntimeで実行する経路はまだ発展中です。実際にどこまで速くなり、4-bit量子化で出力は変わるのでしょうか。

さて、今日は2026年5月に公開された、ExecuTorchの実験的なMLX delegateを取り上げます。PyTorchモデルをApple SiliconのGPUで動かせる仕組みです。ExecuTorch 1.3.1でQwen3-0.6Bを動かし、PyTorch MPSと比較します。

先に結果を書くと、文章を続けて生成するdecode速度は、PyTorch MPS BF16の41.8 token/sに対し、MLX BF16が134.8 token/s、MLX INT4が188.9 token/sでした。MLX INT4は4.52倍高速で、ファイルもBF16より71.8%小さくなりました。ただし、INT4は簡単な3問のうち2問で生成結果が変わりました。

ExecuTorch MLX delegateとは

ExecuTorchは、学習済みPyTorchモデルをPC、スマートフォン、組み込み機器などで推論するためのruntimeです。推論は、学習済みモデルへ入力を渡して答えを得る処理を指します。

MLX delegateは2026年5月18日に公開されました。PyTorchの計算graphをAppleのMLXへ渡し、Apple SiliconのGPUで実行します。BF16、FP16、FP32と2/4/8-bit量子化などに対応しますが、現時点ではexperimentalです。APIや対応範囲は変わる可能性があります。

量子化は、重みを少ないbit数で表して、容量や計算量を減らす方法です。今回は通常のBF16と、linear layerとembeddingを4-bitへ縮めたINT4を比較しました。

使用したQwen3-0.6B

Qwen3は、Qwen Teamが2025年4月29日に発表したLLMシリーズです。考える過程を使うthinking modeと、短く答えるnon-thinking modeを1つのモデルで切り替えられ、100以上の言語・方言に対応します。

今回使ったQwen3-0.6Bは、その中でも小さいdenseモデルです。denseは、入力ごとに一部だけを使うMoEと違い、基本的にモデル全体を使って計算する方式です。公称0.6B、つまり約6億parameter、28 layer、context lengthは32,768 tokenです。tokenは文章をAIが処理する細かな単位です。

検証ではthinking modeを無効にしました。モデルのrevisionはc1899de289a04d12100db370d81485cdf75e47caへ固定しています。

ライセンス

対象 ライセンス
Qwen3-0.6Bの重み Apache License 2.0
ExecuTorch BSD 3-Clause License
MLX MIT License
PyTorch BSD 3-Clause License

いずれも商用利用を含めて利用しやすいOSSライセンスですが、再配布時の著作権表示など、それぞれの条件は残ります。利用時にはリンク先の原文も確認してください。

3つの経路とデータの流れ

使った学習済みモデルはQwen3-0.6Bの1つです。同じ重みを3つの実行経路で比べました。

同じprompt
  -> tokenizer: 文章をtoken IDへ変換
  -> Qwen3-0.6B
       ├─ ExecuTorch MLX BF16 -> .pte -> MLX / Metal GPU
       ├─ ExecuTorch MLX INT4 -> 4-bit .pte -> MLX / Metal GPU
       └─ PyTorch MPS BF16 ----------------> MPS / Metal GPU
  -> greedy生成: 毎回もっとも確率の高い次のtokenを選ぶ
  -> tokenizer: token IDを文章へ戻す

.pteはExecuTorch用に書き出したmodel fileです。MLX経路では計算graph全体を1つのMLX subgraphへ変換できました。PyTorch MPS BF16は、同じBF16重みを通常のTransformers/PyTorch経路で動かす比較対象です。

今回検証する内容

  • Qwen3-0.6Bのgraph全体をMLXへ変換して実行できるか
  • MLX BF16とPyTorch MPS BF16が同じtokenを生成するか
  • INT4でmodel size、速度、process memoryがどう変わるか
  • 公開wheelだけで環境を再現できるか

完全なコードとJSON reportは、kiarina/labsのexecutorch-mlx-qwen3 labで公開しています。

検証環境の再現

Apple Silicon Mac、Xcode Command Line Tools、mise、uv、インターネット接続が必要です。初回はQwen3の重みを取得し、合計約1.53 GBのPTEを生成します。

git clone --depth 1 --filter=blob:none --sparse \
  https://github.com/kiarina/labs.git
cd labs
git sparse-checkout set .mise/tasks 2026/07/22/executorch-mlx-qwen3
mise trust . && mise trust 2026/07/22/executorch-mlx-qwen3
mise -C 2026/07/22/executorch-mlx-qwen3 run

個別に実行する場合は、次のtaskを使えます。

mise -C 2026/07/22/executorch-mlx-qwen3 run export
mise -C 2026/07/22/executorch-mlx-qwen3 run benchmark

検証条件

machine: MacBook Pro (Apple M1 Max, 32 GPU cores, 64 GB)
OS: macOS 26.5.2
Python: 3.13.7
ExecuTorch: 1.3.1
PyTorch: 2.12.1
Transformers: 4.56.1
model: Qwen/Qwen3-0.6B
generation: greedy、batch 1、最大16 token
PTE: custom MLX SDPA / KV cache、最大sequence 128を指定

速度は同じ日本語promptから16 tokenを強制生成し、warm-up後に5回測った中央値です。prefillは入力をまとめて読み、最初のtokenを出す処理です。decodeは、その後に1 tokenずつ続きを作る処理です。

各backendは独立processで実行しました。MLXでは試行ごとにforward methodを読み直してKV cacheを初期化し、PyTorchでも試行ごとに新しいcacheを作っています。

検証結果

PTEの容量

PTE Size BF16比 Export time SHA-256
MLX BF16 1,192,264,196 bytes 100.0% 41.61 s 83da47c2…bfb8c0
MLX INT4 335,662,976 bytes 28.2% 54.55 s 0e30a054…71267

INT4はBF16より856,601,220 bytes、71.8%小さくなりました。量子化には時間がかかるため、export自体はINT4の方が約13秒長くなっています。

生成速度

入力は「Apple Silicon上のローカル推論について短く説明してください。」です。

Backend Load Prefill中央値 Decode中央値 16 token合計 Peak RSS増加
ExecuTorch MLX BF16 0.002 s 0.020 s 134.8 token/s 0.131 s 1.27 GiB
ExecuTorch MLX INT4 0.003 s 0.028 s 188.9 token/s 0.108 s 0.47 GiB
PyTorch MPS BF16 0.726 s 0.038 s 41.8 token/s 0.396 s 0.14 GiB

decodeはMLX BF16がPyTorch MPS BF16の3.22倍、MLX INT4が4.52倍でした。INT4はMLX BF16より1.40倍高速で、RSS増加も約63%小さくなりました。

ただし、この表のloadはMLXではPTE programを開く時間だけです。weightがGPUで使える状態になるまでのすべての準備時間ではありません。またRSSはprocessのmain memoryを見た値で、GPU memoryそのものではありません。PyTorch側は測定終了時のMPS driver allocated memoryが1.20 GiBでした。backend間のmemoryを同じ基準で比較できていないため、PyTorchが最も省memoryだとは結論づけられません。

初回だけはMLX BF16のprefillが0.434秒、INT4が1.014秒かかりました。Metalの準備や初回compileを含むcold startは、warm-up後よりかなり遅くなります。

生成結果

3つの短いpromptで、生成したtoken列を比較しました。

質問 PyTorch MPS BF16 MLX BF16 MLX INT4
日本の首都を一語で 日本の首都は、**大阪**です。 完全一致 日本の首都は、**东京**です。
1+1を数字一文字で 1+1=2 完全一致 1
MLXをそのまま複写 MLX 完全一致 完全一致

MLX BF16は3件すべてでPyTorch MPS BF16とtoken単位で一致しました。少なくともこの範囲では、実行経路をMLXへ変えたことによる差は見つかりませんでした。

INT4の完全一致は1件だけです。量子化は数値を粗く表すため、次のtokenの順位が近いと生成結果が変わることがあります。

さらに、首都の回答はBF16もINT4も誤っています。これは0.6Bという小型モデルの品質、prompt、greedy生成などが影響し得ますが、今回の3問だけで原因は特定できません。この確認はbackend間の差を見るためのもので、モデルの知識や回答品質を保証する試験ではありません。

結果を簡単に読む

  1. 同じ小型LLMを、MLX経路でかなり速く動かせました。

    文章の続きを作る速度は、BF16でもPyTorch MPSの3.22倍でした。PyTorchモデルをExecuTorchへ書き出し、Mac向けの軽いruntimeで使う経路として有望です。

  2. 4-bit化は小さく速くなりますが、答えが変わることがあります。

    INT4は約1.19 GBから約336 MBへ縮み、decodeも最速でした。一方、わずか3問でも2問のtoken列が変わりました。実際の用途に近い問題集で品質を測ってから選ぶ必要があります。

  3. 速度差をMLX kernelだけの効果とはいえません。

    比べたのはExecuTorch MLX pipelineとTransformers/PyTorch MPS pipelineです。runtime、cache、実行方法も異なるため、結果はpipeline全体の差です。

試行中にわかったこと

executorch==1.3.1は依存条件上PyTorch 2.13.0も選べましたが、公開済みのExecuTorch extensionをimportするとmaterialize_cow_storage symbol不足で失敗しました。PyTorchを2.12.1へ固定すると動作しました。失敗は次のtaskで再現できます。

mise -C 2026/07/22/executorch-mlx-qwen3 run probe-torch-2-13

また、ExecuTorch付属のPTE inspectorは、同梱されたflatcが--json optionを認識せず実行できませんでした。graph全体がMLXへ渡ったことはexport時のpartitioner logで確認しています。

制限

  • M1 Max 1台、Qwen3-0.6B、batch 1、短い日本語promptだけを測った
  • 5回の短時間測定で、発熱、消費電力、ほかのGPU負荷を管理していない
  • BF16とINT4だけで、FP16、2/8-bit、Core MLなどは比較していない
  • 品質確認は3問だけで、一般的なbenchmarkやperplexityを測っていない
  • 最大sequence 128を指定し、長い文章は試していない
  • memoryはMLXとMPSで同じ方法のGPU使用量を取得できていない
  • cold startは1回だけの観測である
  • MLX delegateはexperimentalである

検証後の感想

Qwen3-0.6Bのgraph全体をMLXへ渡し、BF16の生成を変えずにdecodeを3倍以上へ伸ばせたのは良い結果でした。INT4ではファイルが3分の1以下になり、約189 token/sまで出たため、小型モデルをMac上で組み込むときの速度と容量には魅力があります。

一方、4-bit化による出力変化は、簡単な3問でもすぐ見えました。量子化は無料の高速化ではありません。用途ごとの品質テストと一緒に使えば、ローカルの補助機能や応答の速い小型agentにも活かせそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?