こんにちは、パレイド技術部です。
5 週間前、シリーズ (4) で「mlx-lm が gemma4 にまだ未対応、Ollama は qwen3.5:27b は安定しない。」と書いて記事を締めくくりました。今回はその後のバージョンアップを踏まえた答え合わせと、改めて同条件で 7パターン分のベンチを取り直した結果をお届けします。
結論を先に言うと、mlx-lm 側は予定通り gemma4 を取り込み、qwen3.5:35b の OOM もメモリが空いていれば回避できる状態になりました。一方 Ollama 側の qwen3.x 性能問題は依然として存在します。そして同条件で並べてみると、エンジンと相性のいいモデルは分かれていることが見えてきました。
本記事はローカル LLM による自動執筆パイプラインで生成されました。現段階ではクラウド AI(Claude 等)の補助や人間の編集が介在していますが、pareido.jp では最終的に AI が自律的にコンテンツを制作できる仕組みの構築を目指しています。
(4) の宿題は片付いたか
(4) の末尾で挙げた 2 つの宿題と、5 週間後の状況を並べます。
| (4) で書いた予想 | 5/11 時点の実際 |
|---|---|
| mlx-lm の gemma4 対応 (PR #1093) は main にマージ済みだが未リリース | v0.31.2 (2026-04-07) でリリース済。記事公開の翌日。続く v0.31.3 (2026-04-22) で tool parser や KV-shared layers の追加修正も入った |
| Ollama の MLX バックエンドが qwen3.5:27b (Dense) に非対応、#14579 で議論中 | 依然 OPEN。最新コメント (3/27) でユーザーから --n-cpu-moe 相当のフラグ要求が出ているが本体未対応。Ollama 本体は v0.20.2 → v0.23.2 (5/7) まで 8 リリースぶん進んだものの、qwen3.x の最適化は据え置き |
mlx-lm 側の v0.31.2 リリースノートには、ついでに Fix missing cache advance from qwen 3.5 (#1024) もぶら下がっており、qwen3.5 系の挙動が前バージョンと変わっている可能性があるため、こちらも検証対象に含めることにしました。
検証マトリクス
(4) 掲載時点では「mlx-lm が gemma4 未対応 / Ollama が qwen3.5:27b の MLX 加速未対応」だったため、モデルごとに使えるエンジンが分かれ apple-to-apple の比較ができません。今回はその制約が緩和したため、同じモデルを 2 つのエンジンで動かす横断比較ができるようになりました。
| モデル | タイプ | Ollama | mlx-lm 直接 | 備考 |
|---|---|---|---|---|
| gemma4:26b | MoE (活性 4B) | ✓ | ✓ NEW | mlx-community/gemma-4-26B-A4B-it-OptiQ-4bit |
| gemma4:31b | Dense | ✓ | × | mlx-community に 4bit 量子化版が無く BF16 のみ。検証環境の 32GB Mac では BF16 (約 62GB) は乗らないため Ollama のみ |
| qwen3.5:35b | MoE (活性 3B) | ✓ | ✓ 再挑戦 | (4) で mlx-lm 直接実行は Metal OOM。今回は memory hygiene を整えて再挑戦 |
| qwen3.6:35b-a3b | MoE (活性 3B) | ✓ | ✓ | 4/17 / 4/18 の検証では Ollama 側のみ |
Dense の gemma4:31b はエンジン横断比較ができないですが、それも結論の一部なので参考値として残します。
検証環境
- MacBook Air (M5, 32GB Unified Memory)
- macOS Tahoe 26.4
- Ollama v0.23.2 ((4) 時点は v0.20.2)
- mlx-lm 0.31.3 ((4) 時点は v0.31.1 で gemma4 未対応)
- Python 3.12
- パイプライン: pareido.jp 編集システムの記事生成 3-Pass 構成 (A: 骨子 → B: セクション執筆 6 本 → C: アセンブル)
- thinking OFF、RAG オフ、参考記事なしの固定シナリオ
- 各セル 1 run
結果
7 パターンの生成時間と文字数を並べます。Pass B/C それぞれの時間は内訳を見るために残しています。
| # | モデル | エンジン | Pass A (s) | Pass B (s) | Pass C (s) | 合計 (s) | 文字数 |
|---|---|---|---|---|---|---|---|
| 1 | gemma4:26b | Ollama | 36 | 137 | 129 | 307 | 4486 |
| 2 | gemma4:26b | mlx-lm | 54 | 138 | 121 | 316 | 3961 |
| 3 | qwen3.5:35b | Ollama | 58 | 310 | 324 | 698 | 7239 |
| 4 | qwen3.5:35b | mlx-lm | 23 | 155 | 145 | 326 | 7718 |
| 5 | qwen3.6:35b-a3b | Ollama | 60 | 312 | 309 | 687 | 8330 |
| 6 | qwen3.6:35b-a3b | mlx-lm | 22 | 156 | 147 | 328 | 7531 |
| 7 | gemma4:31b (Dense) | Ollama | 269 | 1097 | 841 | 2212 | 4315 |
品質評価は (4) と同じく Claude (sonnet 4.6) で 4 軸 × 5 段階。プロンプトも (4) と揃えて再現性を確保しています。
| # | モデル | エンジン | 自然さ | 正確さ | 読みやすさ | 指示遵守 | 合計 /20 |
|---|---|---|---|---|---|---|---|
| 1 | gemma4:26b | Ollama | 3 | 3 | 4 | 3 | 13 |
| 2 | gemma4:26b | mlx-lm | 4 | 2 | 4 | 3 | 13 |
| 3 | qwen3.5:35b | Ollama | 3 | 2 | 4 | 3 | 12 |
| 4 | qwen3.5:35b | mlx-lm | 3 | 2 | 3 | 3 | 11 |
| 5 | qwen3.6:35b-a3b | Ollama | 3 | 2 | 3 | 3 | 11 |
| 6 | qwen3.6:35b-a3b | mlx-lm | 4 | 2 | 4 | 4 | 14 |
| 7 | gemma4:31b (Dense) | Ollama | 4 | 3 | 5 | 4 | 16 |
読み取れたこと
1. エンジン適性はモデルで割れる
MoE 3 モデルそれぞれで Ollama と mlx-lm を直接比較すると、得意な相手が違います。
| モデル | Ollama 合計 | mlx-lm 合計 | 速い方 |
|---|---|---|---|
| gemma4:26b | 307s | 316s | 僅差で Ollama (約 3% 差) |
| qwen3.5:35b | 698s | 326s | mlx-lm 圧勝 (約 2.1 倍) |
| qwen3.6:35b-a3b | 687s | 328s | mlx-lm 圧勝 (約 2.1 倍) |
gemma4:26b は Ollama 側の MLX バックエンド経由でほぼ同等の速度が出ます。一方、qwen3.x は Ollama 経由だと mlx-lm 直接の約 2 倍時間がかかる。issue #14579 で議論されている「qwen3.x は Ollama の Go ランナーに強制され、MoE 向けの最適化フラグが効かない」という制約が、Mac 上でもそのまま体感速度に現れた形です。
つまり 「Ollama でいいモデル」「mlx-lm で動かすべきモデル」を分けるのが現実解 ということになります。gemma4 系統は Ollama の利便性を取り、qwen3.x は mlx-lm に逃がす。
2. 品質はエンジンでほとんど動かない
同じモデルを違うエンジンで動かしても、4 軸合計の差は ±1 点に収まりました (gemma4:26b で 13 同点、qwen3.x では mlx-lm の方がやや高い)。品質はモデル選定の話で、エンジン選定の話ではないという整理がつきます。
ここで読みたい数字は次の組み合わせです。
| 軸 | スイートスポット |
|---|---|
| 最高品質 (時間度外視) | gemma4:31b (Dense, Ollama) 16/20、約 37 分 |
| 速度×品質のバランス | mlx:qwen3.6:35b-a3b 14/20、約 5.5 分 |
| とにかく速い | gemma4:26b (Ollama) 13/20、約 5 分 |
(4) では「日常のデフォルトは gemma4:26b、最高品質は qwen3.5:27b + thinking」という整理でした。今回は mlx:qwen3.6:35b-a3b が「速度×品質のスイートスポット」として割り込んだ形です。
3. 全モデルが正確さで足踏み
ここは予想していなかった発見でした。正確さの軸はどのモデルも 2〜3/5 で、エンジン差以前にパイプライン側の問題が支配的です。Claude のジャッジコメントを抜き出すと:
Gemma 4 の実際のモデルラインナップは 1B/4B/12B/27B であり、記事で扱う 2B・9B バリアントは存在しないため、表のモデルサイズに事実誤認がある
「ロースト関数」は「ロス関数 (loss function)」の誤記と思われる重大ミス
MacBook Pro (M2) のメモリ帯域を 100 GB/s と記載しているが、M2 Pro/Max は 200〜400 GB/s
固定ベンチ用シナリオは RAG オフ・参考記事なしで実行しているので、ハルシネーションが減衰されません。速度を取り直す前にやるべきは、RAG 側の前提知識注入と Pass A 段階での fact pinning という、別軸の宿題が浮かび上がりました。これは (6) 以降のテーマになりそうです。
ハマりどころ: 連続実行はメモリ解放に注意
これは記事の本筋ではないですが、運用上の罠としてメモを残します。
最初、bench_pipeline.py に 7 モデルを一度に渡して --runs 1 で走らせたところ、3 セル目で Pass C が 900 秒タイムアウトしました。Activity Monitor 系で見ると:
| 指標 | 当初実行 (連続) | 今回の cell 別実行 |
|---|---|---|
| PhysMem 使用率 | 31G / 32G (135MB しか空かない) | 11〜17G / 32G |
| Swap 使用 | 41.5GB / 44GB | 19〜27GB |
| Load Avg | 145〜162 (常時) | 2〜10 (各 cell 終端で) |
bench_pipeline.py は同一 Python プロセス内で全モデルを連続実行する設計のため、MLX のメモリは Python プロセス終了まで解放されにくく、累積でスワップを使い切ります。さらに Ollama 側でも前モデルの 17〜23GB がロードされたまま次モデルがロードされる瞬間があり、ピークで詰みます。
cell ごとに osascript -e 'tell application "Ollama" to quit' で Ollama daemon を一度落としてから次の cell を起動する形に作り直したら、全 7 cell が完走するようになりました。Mac 32GB で複数モデルを横並び比較するなら、cell 間で daemon を落とす運用が事実上必須です。
まとめ
- (4) の宿題は半分解消。mlx-lm 0.31.3 で gemma4 が動き、qwen3.5:35b の OOM も memory hygiene で回避可能。Ollama の qwen3.x 性能問題は据え置き (#14579 OPEN)
- エンジン適性はモデルで割れる。gemma4 は Ollama でほぼ同等、qwen3.x は mlx-lm でほぼ 2 倍速。1 つのエンジンに統一する必要はもう無い
- 品質はエンジン非依存、モデル依存。同じモデルなら Ollama でも mlx-lm でも合計点は ±1 に収まる
- 新しいデフォルト候補は mlx:qwen3.6:35b-a3b (品質 14/20、所要時間 5.5 分)。Dense 最強の gemma4:31b (16/20) は約 37 分かかるので、品質を取りに行く時の特注扱い
次の課題は精度ですが、これはモデルではなく RAG / fact pinning 側の話。gemma4/qwenのMoEモデル比較は一旦これくらいにしておきます。



