← 기사 목록
日本語https://qiita.com/tags/llm/feed

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

추출된 키워드

34
vllm-mlx·5Qwen·5ベンチマーク·5MacStudio·5Qwen3.6-27B·4Qwen3.5-122B-A10B·4Qwen3.6-35B-A3B·4Qwen3.5-9B-MLX·4simple_python·4BFCL·4vllm-mlx-bench·4Function Calling·4Apple M3 Ultra·4ローカル LLM·4OptiQ-4bit·3mxfp4·3bf16·38bit·3nvfp4·34bit·3Qwen3.5-397B-A17B·3TPOT·3TTFT·3量子化モデル·3CLI エージェント·3Playwright·3Python 3.12·2memory bandwidth·2unified memory·2OOM·2Playwright MCP·2mlx-community·2Qwen3-Coder-Next·2Qwen3-VL-8B-Instruct·2

원문

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

はじめに

ローカル 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
Python3.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/sTTFT msTPOT ms総トークン数総時間 s結果
Qwen3.5-9B-MLX4bit114.77128.08.71360.43成功
Qwen3.6-35B-A3Bnvfp4103.47129.99.663693.69成功
Qwen3.6-35B-A3B8bit87.73142.511.403444.05成功
Qwen3.6-35B-A3Bbf1673.85152.513.543414.76成功
Qwen3.5-122B-A10Bmxfp461.18163.116.352985.02成功
Qwen3.5-122B-A10B8bit46.12201.721.6851211.28成功
Qwen3.5-9Bbf1642.56179.123.50290.84成功
Qwen3.6-27Bmxfp441.79188.623.933328.11成功
Qwen3.5-397B-A17B4bit41.14197.024.3151212.62成功
Qwen3.6-27BOptiQ-4bit37.08207.826.973349.19成功
Qwen3.6-27B8bit23.67251.142.2533114.19成功
Qwen3.6-27Bbf1613.58376.073.6132224.01成功
Qwen3.5-122B-A10Bbf16OOM

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

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

速度だけを見ると、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-A10Bmxfp497.059520成功
Qwen3.6-27Bmxfp496.29166成功
Qwen3.5-122B-A10B8bit96.0109930成功
Qwen3.6-27B8bit95.8168028成功
Qwen3.6-27Bbf1695.5286726成功
Qwen3.6-27BOptiQ-4bit94.515814成功
Qwen3.6-35B-A3Bbf1694.26256成功
Qwen3.6-35B-A3B8bit94.07636成功
Qwen3.6-35B-A3Bnvfp493.862826成功
Qwen3.5-9B-MLX4bit93.27096成功
Qwen3.5-9Bbf1669.58846成功
Qwen3.5-122B-A10Bbf16OOM
Qwen3.5-397B-A17B4bit375サーバー終了

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

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-A10Bmxfp497.061.2精度が最も高く、速度も許容しやすい
Qwen3.6-27Bmxfp496.241.8精度重視なら候補に残る
Qwen3.5-122B-A10B8bit96.046.1高精度だが mxfp4 の方が速かった
Qwen3.6-27B8bit95.823.7精度は高いが対話用途では遅い
Qwen3.6-27Bbf1695.513.6精度は高いが待ち時間が大きい
Qwen3.6-27BOptiQ-4bit94.537.127B 系で速度を少し取りたい場合の候補
Qwen3.6-35B-A3Bbf1694.273.9速度と精度のバランスがよい
Qwen3.6-35B-A3B8bit94.087.7速度寄りで使いやすい
Qwen3.6-35B-A3Bnvfp493.8103.5速度重視なら有力
Qwen3.5-9B-MLX4bit93.2114.8最速。精度は少し下がる
Qwen3.5-9Bbf1669.542.6Function Calling 用途では避けたい

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

自分が 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-bf16228 GB
mlx-community/Qwen3.5-397B-A17B-4bit209 GB
mlx-community/Qwen3.5-122B-A10B-8bit122 GB
mlx-community/Qwen3-Coder-Next-bf16119 GB
mlx-community/Qwen3.6-35B-A3B-bf1665 GB
mlx-community/Qwen3.5-122B-A10B-mxfp461 GB
mlx-community/Qwen3.6-27B-bf1651 GB
mlx-community/Qwen3-Coder-Next-mxfp439 GB
mlx-community/Qwen3.6-35B-A3B-8bit35 GB
mlx-community/Qwen3.6-27B-8bit28 GB
mlx-community/Qwen3.6-35B-A3B-nvfp419 GB
mlx-community/Qwen3.5-9B-bf1618 GB
mlx-community/Qwen3.6-27B-OptiQ-4bit15 GB
mlx-community/Qwen3.6-27B-mxfp414 GB
mlx-community/Qwen3.5-9B-8bit9.7 GB
mlx-community/Qwen3.5-9B-MLX-4bit5.6 GB
mlx-community/Qwen3-VL-8B-Instruct-4bit5.4 GB