3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MacStudio 上の vllm-mlx で Qwen 系モデルを動かしたベンチマーク結果

3
Posted at

はじめに

ローカル LLM (Local LLM) をエージェント用途で使う場合、モデルの賢さだけを見ても判断しにくい。ブラウザ操作や CLI 操作では、応答が遅いと待ち時間が積み上がる。一方で、速いだけのモデルを選ぶと、ツール呼び出しの引数を間違えたり、存在しない関数を呼び出したりして、結局リトライが増える。

今回は、Apple M3 UltraMac Studio で、vllm-mlx を使って Qwen 系モデルをローカル実行したときの 速度(token/sec)Function Calling 品質を測った。速度は vllm-mlx-bench、品質は BFCL の simple_python で確認した。Playwright や CLI エージェント用途で、どの量子化モデルを選ぶか判断するための作業メモとして整理した。

測定環境

項目 内容
実施日 2026-05-19
ハードウェア Apple M3 Ultra
256 GB unified memory
800 GB/s memory bandwidth
80 GPU cores
推論ランタイム vllm-mlx
速度測定 vllm-mlx-bench
品質測定 BFCL simple_python
Python 3.12

BFCL の依存関係に合わせるため、このリポジトリでは Python 3.12 を使っている。

uv sync

速度ベンチマークは次の条件で実行した。

PROMPTS=1 MAX_TOKENS=512 TEMPERATURE=0 WARMUP=1 ./benchmarks.sh

各モデルのサーバー起動は、評価ランナー内では次の形になっている。

vllm-mlx serve <model-repo> \
  --port 8000 \
  --continuous-batching \
  --host 0.0.0.0 \
  --served-model-name <model-name> \
  --enable-auto-tool-choice \
  --tool-call-parser qwen3_coder

BFCL は simple_python を対象に実行した。

BFCL_TEST_CATEGORY=simple_python ./bfcl_benchmarks.sh

この BFCL 結果は simple_python だけであり、BFCL 全体のスコアではない。single_turn、multi_turn、REST API 呼び出し、複数関数選択、並列呼び出しはこの表には含めていない。

速度ベンチマークの結果

vllm-mlx-bench から見ているのは、生成速度、TTFT、TPOT、総レイテンシ、生成トークン数、実行成否である。回答品質や Playwright タスク成功率は、この速度測定だけでは判断していない。

モデル 量子化 生成速度 tok/s TTFT ms TPOT ms 総トークン数 総時間 s 結果
Qwen3.5-9B-MLX 4bit 114.77 128.0 8.71 36 0.43 成功
Qwen3.6-35B-A3B nvfp4 103.47 129.9 9.66 369 3.69 成功
Qwen3.6-35B-A3B 8bit 87.73 142.5 11.40 344 4.05 成功
Qwen3.6-35B-A3B bf16 73.85 152.5 13.54 341 4.76 成功
Qwen3.5-122B-A10B mxfp4 61.18 163.1 16.35 298 5.02 成功
Qwen3.5-122B-A10B 8bit 46.12 201.7 21.68 512 11.28 成功
Qwen3.5-9B bf16 42.56 179.1 23.50 29 0.84 成功
Qwen3.6-27B mxfp4 41.79 188.6 23.93 332 8.11 成功
Qwen3.5-397B-A17B 4bit 41.14 197.0 24.31 512 12.62 成功
Qwen3.6-27B OptiQ-4bit 37.08 207.8 26.97 334 9.19 成功
Qwen3.6-27B 8bit 23.67 251.1 42.25 331 14.19 成功
Qwen3.6-27B bf16 13.58 376.0 73.61 322 24.01 成功
Qwen3.5-122B-A10B bf16 OOM

生成速度を並べると、35B-A3B 系と 27B 系の差が見えやすい。

image.png

初回トークンまでの待ち時間は、生成速度ほど大きな差ではないが、Qwen3.6-27B bf16 だけは明確に重い。

image.png

速度だけを見ると、Qwen3.5-9B-MLX 4bit が 114.77 tok/s で最速だった。次に Qwen3.6-35B-A3B nvfp4 が 103.47 tok/s。どちらも TTFT は 130 ms 前後で、対話的に使う前提では待ち始めの遅さが目立ちにくい。

Qwen3.6-35B-A3B 系が Qwen3.6-27B 系より速い。35B という名前だけを見ると重そうだが、A3B は 1 トークン生成時に有効化されるパラメータが約 3B であることを示す命名で、Dense な 27B とは速度の出方が違う。実測でも Qwen3.6-35B-A3B nvfp4 は 103.47 tok/s、Qwen3.6-27B mxfp4 は 41.79 tok/s だった。

Function Calling 品質の結果

品質側は BFCL の simple_python を使った。これは、1つの Python 関数定義に対して正しい1回の関数呼び出しを生成できるかを見るカテゴリである。Playwright MCP や CLI エージェントのすべてを代表するものではないが、ツール呼び出しの基本精度を見るには使いやすい。

モデル 量子化 精度 % 生成時間 sec 評価時間 sec 結果
Qwen3.5-122B-A10B mxfp4 97.0 595 20 成功
Qwen3.6-27B mxfp4 96.2 916 6 成功
Qwen3.5-122B-A10B 8bit 96.0 1099 30 成功
Qwen3.6-27B 8bit 95.8 1680 28 成功
Qwen3.6-27B bf16 95.5 2867 26 成功
Qwen3.6-27B OptiQ-4bit 94.5 1581 4 成功
Qwen3.6-35B-A3B bf16 94.2 625 6 成功
Qwen3.6-35B-A3B 8bit 94.0 763 6 成功
Qwen3.6-35B-A3B nvfp4 93.8 628 26 成功
Qwen3.5-9B-MLX 4bit 93.2 709 6 成功
Qwen3.5-9B bf16 69.5 884 6 成功
Qwen3.5-122B-A10B bf16 OOM
Qwen3.5-397B-A17B 4bit 375 サーバー終了

精度は上位が 93% から 97% 台に固まった。Qwen3.5-9B bf16 だけが大きく離れている。

image.png

Qwen3.5-122B-A10B mxfp4 が 97.0% で最も高かった。Qwen3.6-27B mxfp4 も 96.2% で、速度は控えめだが Function Calling の基本精度は高い。

一方で、Qwen3.5-9B bf16 は 69.5% まで落ちた。同じ 9B 系でも Qwen3.5-9B-MLX 4bit は 93.2% だったため、9B というサイズだけで判断すると危ない。モデル名と量子化の組み合わせで結果が大きく変わった。

BFCL の run_summary.json には tok/s は含まれない。上の生成時間は BFCL 全ケースを処理するのにかかった実時間であり、vllm-mlx-bench の生成速度とは別物として扱っている。

速度と品質を並べて見る

エージェント用途では、速度と Function Calling 精度を別々に見ても決めにくい。そこで、vllm-mlx-bench の tok/s と BFCL simple_python の精度を並べた。

モデル 量子化 BFCL 精度 % 生成速度 tok/s 見方
Qwen3.5-122B-A10B mxfp4 97.0 61.2 精度が最も高く、速度も許容しやすい
Qwen3.6-27B mxfp4 96.2 41.8 精度重視なら候補に残る
Qwen3.5-122B-A10B 8bit 96.0 46.1 高精度だが mxfp4 の方が速かった
Qwen3.6-27B 8bit 95.8 23.7 精度は高いが対話用途では遅い
Qwen3.6-27B bf16 95.5 13.6 精度は高いが待ち時間が大きい
Qwen3.6-27B OptiQ-4bit 94.5 37.1 27B 系で速度を少し取りたい場合の候補
Qwen3.6-35B-A3B bf16 94.2 73.9 速度と精度のバランスがよい
Qwen3.6-35B-A3B 8bit 94.0 87.7 速度寄りで使いやすい
Qwen3.6-35B-A3B nvfp4 93.8 103.5 速度重視なら有力
Qwen3.5-9B-MLX 4bit 93.2 114.8 最速。精度は少し下がる
Qwen3.5-9B bf16 69.5 42.6 Function Calling 用途では避けたい

速度と精度を同じ図に置くと、右上に近いほどエージェント用途では扱いやすい。Qwen3.6-35B-A3B nvfp4 は速度側に寄り、Qwen3.5-122B-A10B mxfp4 は精度側に寄る。

image.png

自分が Playwright や CLI エージェントでまず試すなら、速度重視では Qwen3.6-35B-A3B nvfp4、精度も含めた総合では Qwen3.5-122B-A10B mxfp4 を見る。Qwen3.5-9B-MLX 4bit は最速だが、BFCL simple_python では 122B mxfp4 や 27B mxfp4 より少し下がるため、失敗時のリトライも含めて判断する。

Qwen3.6-27B bf16 は 95.5% と精度は高いが、13.58 tok/s だった。ローカルで対話しながら使うには待ちが長い。検証用にはよいが、普段使いの第一候補にはしにくい。

詰まった点

Qwen3.5-122B-A10B bf16 は OOM で落ちた。速度ベンチマーク側のログではピーク使用量が約 240 GB に達しており、256 GB unified memory の環境でも余裕はなかった。

Qwen3.5-397B-A17B 4bit は vllm-mlx-bench では 41.14 tok/s の結果が取れたが、BFCL simple_python では生成中にサーバープロセスが終了した。速度だけを見ると使えそうに見えるが、少なくともこの BFCL 実行では最後まで通っていない。

もう1つ注意点として、BFCL simple_python は Function Calling の入口だけを見るテストである。ブラウザ操作ではページ状態の把握、複数手順の分解、ツール実行結果を読んだ後の修正が必要になる。ここで高いモデルが、そのまま Playwright などの複雑な操作に対応できるとは限らない。

今回の結論

速度だけなら Qwen3.5-9B-MLX 4bit が最速だった。ただし、Function Calling 精度も合わせると、Playwright や CLI エージェント用途では Qwen3.6-35B-A3B nvfp4 と Qwen3.5-122B-A10B mxfp4 が現実的な候補になった。

Qwen3.6-35B-A3B nvfp4 は 103.47 tok/s で、BFCL simple_python は 93.8%。速度を優先して操作待ちを減らしたい場合に使いやすい。Qwen3.5-122B-A10B mxfp4 は 61.18 tok/s、BFCL simple_python は 97.0%。ツール呼び出しの安定性を重視する場面ではこちらを選びたい。

一方で、Qwen3.6-27B bf16 のように精度は高くても速度が厳しいモデルや、Qwen3.5-9B bf16 のように速度は出ても Function Calling 精度が落ちるモデルもあった。ローカルエージェント用途では、モデルサイズや量子化名だけでなく、速度とツール呼び出し精度を並べて見る必要がある。

Appendix

モデルのサイズ

モデル サイズ
mlx-community/Qwen3.5-122B-A10B-bf16 228 GB
mlx-community/Qwen3.5-397B-A17B-4bit 209 GB
mlx-community/Qwen3.5-122B-A10B-8bit 122 GB
mlx-community/Qwen3-Coder-Next-bf16 119 GB
mlx-community/Qwen3.6-35B-A3B-bf16 65 GB
mlx-community/Qwen3.5-122B-A10B-mxfp4 61 GB
mlx-community/Qwen3.6-27B-bf16 51 GB
mlx-community/Qwen3-Coder-Next-mxfp4 39 GB
mlx-community/Qwen3.6-35B-A3B-8bit 35 GB
mlx-community/Qwen3.6-27B-8bit 28 GB
mlx-community/Qwen3.6-35B-A3B-nvfp4 19 GB
mlx-community/Qwen3.5-9B-bf16 18 GB
mlx-community/Qwen3.6-27B-OptiQ-4bit 15 GB
mlx-community/Qwen3.6-27B-mxfp4 14 GB
mlx-community/Qwen3.5-9B-8bit 9.7 GB
mlx-community/Qwen3.5-9B-MLX-4bit 5.6 GB
mlx-community/Qwen3-VL-8B-Instruct-4bit 5.4 GB
3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?