1
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?

Mac mini (M4 Pro) で Qwen3.8-27B + DFlash2 を 33 tok/s で動かすまで — 性能が出ないときの3つの落とし穴

1
Posted at

Mac mini (M4 Pro) で Qwen3.8-27B + DFlash2 を 33 tok/s で動かすまで — 性能が出ないときの3つの落とし穴

はじめに

M4 Pro(48GB)の Mac mini で、Gemma-4-31B や Qwen3.8-27B 級のローカル LLM を動かし、話題の DFlash2(投機的デコーディング)で高速化を目指した記録です。

結論から言うと、最終的に Qwen3.8-27B-4bit + DFlash2 で 33 tok/s(decode) を達成しました。ただし、そこに至るまでに3つの落とし穴がありました。

ちなみにこの構成のモデルは、あの「ドイツ人が魚を飼う」アインシュタインの謎解き(ゼブラパズル)をちゃんと解けるレベルの推論力があります。ローカルモデルがここまで賢い時代なのだな、と実感しました。

環境

  • Mac mini M4 Pro / 48GB / 16-core GPU
  • mlx-dspark 0.15.1(MLX 版 DSpark / DFlash)
  • モデル: mlx-community/Qwen3.8-27B-4bit + drafter incoai/Qwen3.8-27B-DFlash2

落とし穴1: llama.cpp + gemma-4-31B + DFlash は逆効果だった

最初は llama.cpp + gemma-4-31B で試しました。

./build/bin/llama-server \
  -hf unsloth/gemma-4-31B-it-GGUF:UD-Q4_K_XL \
  -hfd Anbeeld/gemma-4-31B-it-DFlash-GGUF:Q4_K_M \
  --spec-type draft-dflash --spec-draft-n-max 7 \
  -ngl 999 -fa on -c 8192 --parallel 1

結果: 1.78 tok/s。DFlash なしの baseline(4.33 tok/s)より 2.4 倍遅い。加速どころか大惨事です。

受け入れ率は 21%・平均 2.41 token と正常なのに、なぜ遅いのか。測ってみたら原因がはっきりしました。

投機的デコーディングは「N token の検証 ≈ 1 token のデコード」という前提に立っています。しかし Metal バックエンドで「一度の前向き計算で N token 処理する」コストを実測すると:

batch 1回の前向き 相対コスト
1 153 ms 1.0×
2 351 ms 2.3×
4 666 ms 4.3×
8 1303 ms 8.5×
16 761 ms 5.0×

batch 2〜8 の範囲には専用の小バッチパスがあり、コストがまったく償却されません。8.5 倍のコストを払って 2.4 token 得ても損なのです。

コミュニティでも同現象が llama.cpp issue #23752 として報告されています(M1 Max で受け入れ率 100% でも 11% 遅い)。Metal バックエンドの構造的な問題で、設定で直るものではありません。しかも DFlash2 はそもそも llama.cpp の mainline にまだマージされていない PR ブランチでした。

落とし穴2: 「フレームワークを変える」が正解だった

同じ投機的デコーディングのアルゴリズムでも、MLX は検証をひとつの計算グラフに融合するため、トークンごとの kernel dispatch ペナルティがありません。

MLX 移植版の mlx-dspark に乗り換えて Qwen3.8-27B-4bit + DFlash2 を試すと:

シナリオ baseline +DFlash2
一般文 7.1 tok/s 8.0(1.13×)
数学 7.1 tok/s 10.9(1.54×)

初めて正の利益が出ました。数学プロンプトでは 1 ラウンドあたり平均 4.47 token 受け入れ、160 token の生成にわずか 37 回の検証で済んでいます。

ちなみに 8bit 版も試しました。加速「倍率」は大きい(1.57〜1.68×)ものの、絶対速度は 4bit に及ばず、48GB では swap が膨らみました。実用は 4bit 一択です。

しかし、それでも公式ベンチマークの半分程度の数字しか出ていませんでした。

落とし穴3(本当の元凶): macOS の「低電力モード」

あれこれ疑いました。

  • Multipass の VM が 1 コアを 100% 占有していた → 消してみた → +10% だけ
  • GPU のコア数違い(16 コア vs 20 コア版)を疑った → 誤診だった

正解は、macOS のシステム設定 > エネルギー > エネルギーモードが「低電力」になっていたことでした。

Apple Silicon は低電力モードだと無言でスループットを約 45% も落とします。エラーメッセージは一切出ない。デスクトップの Mac mini は常時給電なので、低電力にする理由はないのです。

「高出力」に切り替えた瞬間:

低電力 高出力
baseline 8.8 decode 15.1
DFlash2 17.6 decode 33.0

公式ベンチマーク(baseline 14.7 / DFlash2 33.8)とほぼ一致。 しかも Zoom 会議を開いたままの数字なので、余力はまだあります。

各要因の実際の寄与はこうでした:

要因 影響
macOS 低電力モード 約 −45%
100% 稼働中の VM 約 −10%
GPU コア数(16 vs 20) なし

学び

  1. 投機的デコーディングは実行コスト次第。 アルゴリズムが悪いのか、バックエンドの実行コストが悪いのかを切り分けること。受け入れ率が正常なのに遅いなら、まず検証コスト(小バッチ前向き)を測りましょう。
  2. Apple Silicon で性能測定する前に pmset -g | grep powermode を確認(2 = 高出力)。低電力モードは無言で性能を半減させます。
  3. ベンチマークは公表条件をよく読む。 decode と end-to-end は別物。単発の数字はノイズ(±14%)なので複数回の中央値を。
  4. 48GB の M4 Pro はローカル LLM の実用ラインを超えている。 27B を 33 tok/s で回し、エージェントも動かせる。プライベートなデータを手元で処理したい人には十分魅力的な選択肢です。
1
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
1
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?