Mac mini M4(24GB)で27BローカルLLMを動かしたら、動いた。でも快適ではなかった

Mac mini M4(24GB)で27BローカルLLMを動かしたら、動いた。でも快適ではなかった
この記事の概要

何を試したか

以前の記事で、M4 Mac mini(24GB)を買った話を書いたとき、「24GBでも軽量モデルなら動く。ただし30B級以上を快適に回すには厳しい」という印象論を書きました。

今回はその仮説を実際に確かめてみました。Qwen3.8-27Bの4bit量子化版をOllamaに入れて、生成速度を素の状態で測ってみたのです。

結論を先に言うと、27Bは24GBのMac miniで動きました。ただし「快適」ではありませんでした。 起動できることと、日常で使えることは別物です。この記事は、その差がどこから来るのかを数値で追った記録です。

環境

測定に使った環境です。

項目 値
本体 Mac mini(2024、Mac16,10)
チップ Apple M4(ベース版、Pコア4 + Eコア6)
メモリ 24GBユニファイドメモリ
実行ソフト Ollama 0.32.14
モデル orcarouter/Qwen3.8-27B-Uncensored:mlx-4bit(16GB)
比較用 qwen3.5:9b(Q4_K_M、6.6GB)

モデルはOllamaのページからmlx-4bitタグを取得しました。Qwen3.8-27Bは2026年8月リリースの27B Denseモデルで、画像入力にも対応し、コンテキストは262Kです(HuggingFaceのモデルカードより)。

なお、このモデルを選んだ理由は後の節で書きます。今回のような1トークンずつの生成では、モデルの実効サイズとメモリ帯域が速度を大きく左右します。ただし、アーキテクチャや量子化方式、実行エンジン、コンテキスト長でも差が出るため、同じ27Bなら必ず同じ速度になるわけではありません。

この記事の数値は、私の環境で測った1例です。速度はOllamaやモデルの更新、同時に動かすアプリ、プロンプトの長さによって変わります。

結果

まず数値から

同じ短い質問(「日本の首都はどこですか? 地名だけで答えてください。」)を投げたときの実測値です。

測定 合計時間 生成速度
初回(コールドスタート) 27.1秒 6.43トークン/秒
2回目(メモリに常駐した直後) 10.7秒 6.17トークン/秒
thinking無効で実行 2.0秒 6.63トークン/秒

初回はモデルのロードに12.3秒かかりました。16GBをディスクからメモリへ展開する時間です。2回目以降はモデルがメモリに残っているのでロードは25ミリ秒で済みます。

しかし生成速度はどちらも6.2〜6.7トークン/秒でほぼ変わりません。ロードの遅さは一度だけ我慢すれば済みますが、生成の遅さはずっとついてきます。

「動く」の実態

生成がどの程度の速さなのか、体感を説明します。

6.7トークン/秒は、日本語ではおおよそ毎分数百字です。文字数への換算は内容やトークナイザーで変わりますが、チャット画面で返答がじわじわと伸びていくのを、読む速度で追いかけるような感覚でした。文字は出てくる。止まっているわけではない。でも待たされる。

長い出力で測るとよりはっきりします。「ローカルLLMのメリットを500字程度で説明してください」と依頼したところ、859トークンの生成に2分9秒かかりました。

thinkingがさらに遅くする

Qwen3.8はthinkingモードがデフォルトで有効になっています。上記の長文測定では、最終的な回答に加えて内部の思考トークンを生成していたため、出力量が膨らんでいました。

OllamaのAPIでthink: falseを指定して同じ質問を投げ直すと、248トークンで38秒に短縮されました。生成速度そのものは6.63トークン/秒と変わりません。

今回のプロンプトに限れば、速度の構造はこうです。

  • thinkingを切っても、1秒あたりの生成量はほぼ変わらない
  • thinkingを有効にすると生成トークン数が約3.4倍になり、所要時間もほぼ同じ比率で伸びた
  • 単発の質問に短く答えさせたいだけなら、think: falseでかなり体感が改善する

「地名だけ」のような短い質問だと、thinking無効なら2秒で返ってきます。有効だと10.7秒。中身は同じ「東京」という回答です。

なぜ6.7トークン/秒なのか

メモリは足りている。でも帯域が足りない

24GBメモリに対して16GBのモデルなので、ギリギリ収まっています。実際、Ollamaはモデル全体をGPU(ユニファイドメモリ)に載せ、CPUへのオフロードやスワップなしで動いていました。ollama psで確認すると100% GPUです。

ここまでは成功です。「動く」のはこの通りでした。

問題は速度です。LLMの逐次生成では、各トークンを出すたびにモデルの重みを大きく読み出すため、メモリ帯域が効きやすくなります。Apple SiliconのベースM4チップのメモリ帯域は120GB/秒です(Appleのスペックページより)。

モデルファイルの16GBを重みの実効サイズとみなして単純計算すると、

120GB/s ÷ 16GB ≈ 7.5トークン/秒

となります。これはKVキャッシュ、演算、量子化の展開、メモリアクセス効率などを無視した帯域だけの概算上限です。厳密な物理上限ではありません。それでも、実測の6.2〜6.7トークン/秒が概算の7.5に近いことから、今回の条件ではメモリ帯域が主なボトルネックだと考えられます。

帯域が違えば結果も違う

この見立ては他の実測とも方向が合います。

  • 手元の9Bモデル(6.6GB)は同じ質問で17.4トークン/秒でした。単純計算の120÷6.6≈18.2トークン/秒に近い値です
  • 帯域400GB/秒のM1 MaxでQwen3.8-27Bの4bit版を測った外部ベンチマークでは、1Kコンテキストで18.9トークン/秒という報告があります(oMLX Benchmark)

M1 Maxの例はベースM4より速い一方、帯域比どおりに3.3倍にはなっていません。実装やチップ構成など他の要因もあるため、帯域÷モデル容量は機種間の性能を正確に予測する式ではなく、手元の結果を説明する目安として使うのが安全です。

9Bにするとどうなるか

比較として、ローカルにあったqwen3.5:9b(6.6GB)を同じ条件で測りました。

項目 Qwen3.8-27B(mlx-4bit) Qwen3.5 9B(Q4_K_M)
モデルサイズ 16GB 6.6GB
生成速度 6.7トークン/秒 17.4トークン/秒
プロンプト評価 9.9トークン/秒 81.2トークン/秒
初回ロード 12.3秒 4.0秒
帯域概算値との比 約88% 約96%

生成速度は9Bが約2.6倍です。毎分1300字程度の出力になり、待ち時間というよりストリーミングとして自然に読める速さです。

同じM4 Mac miniで、16GBの27Bモデルは毎秒6.7トークン、6.6GBの9Bモデルは毎秒17.4トークン。モデルが小さいほど同じ120GB毎秒の帯域を1秒に多く巡回できることを示す図

同じ120GB/秒のメモリ帯域でも、読み出すモデルが小さいほど1秒あたりに生成できるトークンは増えました。

1つ面白い失敗も見つかりました。9Bは「500字程度で」という指示を守らず、4070トークンの長文を3分57秒かけて書き続けました。速くても指示に従うかは別の話で、こればかりはモデルの性能の問題です。

Uncensoredに憧れた話

このモデルを選んだ理由の半分は、正直に言うと「Uncensored」という響きへの憧れでした。ローカルLLMの世界を覗いていると、たまにこういう名前のモデルを見かけます。「なんでも答えてくれるAIを自宅に持てる」という言い方に、心が動いたのです。

そして実際に使い込んでみて、気がつきました。私の生活には、そもそも検閲を回避したい場面が存在しなかったのです。

  • 日常の質問(技術、文章、調べもの)は、Cloudモデルでも困ったことがない
  • 「いつもつかってるモデルでは答えてくれない質問」を思いつこうとしてみたが、具体例が浮かばなかった
  • 何より生成が6.7トークン/秒なので、そういう用途を試す前に速度の壁に当たった

使いこなすほど「Uncensoredに頼る要素が考え付かなかった」という結果そのものが、今回いちばん新しい発見でした。ローカルLLMの魅力は「何でも聞けること」ではなく、「自分のマシンを好きなだけ使えること」の方だった、ということだと思います。

速度の話と構造は同じです。響きに憧れて選ぶと、動かしてから現実が返ってきます。 モデル選びは、スペック表の名前ではなく、自分が実際に使う用途から逆算するのが正解でした。

もちろん、Uncensoredモデルが本当に必要な人は必要なはずです。研究や創作など、用途が明確な場合です。私はそうではなかった。それだけの話ですね。

良かった点

  • 27Bが24GBで本当に動く。 スワップせず、GPUに100%載るところまでは確認できた。数年前のMacでは考えられなかったことで、Apple Siliconのユニファイドメモリは確かに強いです
  • MLX版のロード時間は、同サイズのGGUFを扱った印象より短く感じました。Ollama公式もMLXエンジンの性能向上を発表しています
  • ネット接続なしで動く・料金がかからない・好きなだけ使える、というローカルLLMの本質的な利点は、速度の遅さと切り離して存在します

微妙だった点

  • 生成が6.7トークン/秒。 返答を追って読める一方、チャットとしては待たされます
  • thinkingがデフォルトで有効です。今回の長文プロンプトでは出力トークン数と所要時間が約3.4倍になりました。しかも思考の中身はUI上にほとんど見えません
  • プロンプトの評価も遅い。 長いコンテキストを与える用途(Claude Codeのようなエージェント運用)には、この点がさらに響きます
  • 24GBのメモリのうち16GBをモデルが占めるので、並行して動かせる他の作業が限られます

継続するか

27Bは手元に残しますが、常用はしないかなと思います。

用途を分けるのが現実的だと考えました。

  • 単発の重い質問(プライベートな内容、オフラインでじっくり考えたいこと)→ 27Bでも待てば動く
  • 日常のチャット・下書き・ちょっとした質問 → 9B前後が快適圏
  • エージェント運用・長文往復 → 27Bローカルは現実的でないので、Cloudを使う

私自身は普段、Ollama Cloud経由でClaude Codeを使っています。ローカルの27Bが遅いのは雲のせいではなく物理のせいだと分かったので、この使い分けはしばらく変えないつもりです。

次に試すこと

  • メモリを増やしても、それだけでは速くならないという認識の確認。 ベースM4は24GBから32GBへ増やしても帯域は120GB/秒のままです。余裕は増えますが、同じモデルの生成速度が大きく伸びるとは考えにくいです
  • 帯域のあるマシンでの検証。 M4 Proは273GB/秒なので、単純計算では27Bの帯域上限が約17トークン/秒になります。実測はこれより下がるはずですが、27Bを快適に動かすにはメモリ容量だけでなく帯域も見た方がよさそうです
  • 同じ27Bでもっと軽い量子化(2bit版は9.4GB)を試して、品質と速度のバランスを見る

まとめ

「27BローカルLLMは24GBのMacで動く。」これは事実です。Ollamaに入れて、スワップせず、ちゃんと日本語で答えてくれました。

ただし生成速度は6.7トークン/秒でした。帯域だけの概算上限(120GB/秒÷16GB≈7.5トークン/秒)に近く、今回の条件ではベースM4のメモリ帯域が主な制約だと考えられます。設定だけで2倍を狙うより、モデルを小さくするか、thinkingで余分に生成するトークンを減らす方が現実的です。

前回の記事の「30B級は厳しい」という印象は、体感として正しかった。少なくとも今回の条件では、主な理由がメモリ容量不足ではなく帯域不足だと考えられたのは、実際に測ってみたからです。「動く」と「快適に使える」の間にあるのはスペック表の数字ではなく、帯域の帳簿でした。「Uncensored」への憧れと、実際の用途の間にも、同じ距離がありました。