西川和久の不定期コラム

M4 Max搭載「MacBook Pro 14」のメモリ128GBをLLMでほぼ使い切ってみた!

 前回はM4 Max/ユニファイドメモリ128GB搭載MacBook Pro 14の製品紹介とベンチマークテスト中心だったが、今回は(まだ模索中だが)ユニファイドメモリ128GBの使い道を具体的に紹介したいと思う。

Apple Siliconと生成AI画像について

 本論へ入る前にXでもコメントがあったので、Apple Siliconと画像生成AIについて述べておこう。前編の最後触れているが、M4 Maxに限らずApple Siliconは画像生成AI(動画も)が苦手だ。

 理由としては、GeForceのように高いクロックで回せない、ライブラリが最適化されていないなどいろいろ挙げられる。従ってMac上で生成AI画を高速化するには外付けGPU=dGPUを接続可能にするしか現状手がないものの、物理的に接続できても、ドライバを含めて、ソフトウェア的な環境が揃わないとうまく行かない。この辺りAppleはどう考えているのか聞きたいところだ。

 とは言え、ローカルで生成AI画像環境作っても、筆者のようにろくなものしか出力しないので、同社が嫌がってるという話があるとかないとか(笑)。近々クラウドに思いっきり検閲ありの生成AI画像環境用意するから、それを使って……となるかも!?

 いずれにしてもGeForce RTX 4090ですら8秒かかるFLUX.1 [dev]をMacで……というのは到底無理。どうしてもであればSDXLやStable Diffusion 3.5 Large Turboなど、比較的生成が速いのを使うことをお勧めしたい。それでも1枚10〜20秒かかるのだが……。

MacとLLMについての余談

 上記のような理由から、128GBメモリを活用する本命はLLMとなる。もちろん数B(illion)程度ならほかのGPU環境でも動くが、100B前後になると、何をしてもご家庭用Windows PC/GPUではまず動かない。その夢を叶えるのが、128GB搭載MacBook Pro 14と言うわけだ。個人的に動かしたいのは以下の辺りだろうか!?

  • Qwen/Qwen2.5-72B-Instruct
  • meta-llama/Meta-Llama-3.1-70B-Instruct
  • deepseek-ai/DeepSeek-V2.5 (238B)

 ここにちょっと面白いサイトがあって、メモリ容量と量子化ビット数を指定すると何BのLLMが動くか?簡単な計算ツールとなっている。これによれば、ざっくり4bit量子化で24GBだと41.95Bまで。GeForce RTX 5090は32GBと噂されているが、それでも57.95Bだ。つまり、1bitや2bitなど思いっきり精度落とすのはなしとした場合、上記はどう頑張っても家庭用GPUでは動かない。

LLM RAM CALCULATOR。4bit / 24GBの場合、41.95B
HuggingChat。モデル一覧

 ただしチャットするだけなら、HuggingChatを使えばことは足りる。執筆時、対応しているのは、

  • Qwen/Qwen2.5-72B-Instruct
  • meta-llama/Meta-Llama-3.1-70B-Instruct
  • CohereForAI/c4ai-command-r-plus-08-2024
  • nvidia/Llama-3.1-Nemotron-70B-Instruct-HF
  • Qwen/Qwen2.5-Coder-32B-Instruct
  • meta-llama/Llama-3.2-11B-Vision-Instruct
  • NousResearch/Hermes-3-Llama-3.1-8B
  • mistralai/Mistral-Nemo-Instruct-2407
  • microsoft/Phi-3.5-mini-instruct

と、結構有名どころが並んでいる。加えて少し前にツールが追加され、Web検索や画像生成、PDFパーサーなど数多くが登録され勝手も向上。これが無料なのだから試さない手はない。

 LLM目的で大容量VRAM搭載GPU(もしくはユニファイドメモリ)を考えている方はまずこれでいろいろ遊んでほしい。70Bクラスでどの程度使えるか?分かるはずだ。

mlx_lmとLM Studio

 さてここから本論なのだが、OS起動直後と筆者の標準的な環境を起動(PhotoshopやDockerなどは含まず)した後のメモリ状態を見ると以下のような感じだ。

OS起動直後。14.1GB使用
筆者の標準的な環境を起動(PhotoshopやDockerなどは含まず)した後。28.5GB使用

 OS起動直後で14.1GB、筆者の環境を起動すると28.5GB。PhotoshopやDockerが加わるので、やはり最低32GBは欲しいところ。これをベースにLLMなどをロードすることになる。

 以降、システムモニタは「asitop」を使用する。ご覧の様にE-CPU / P-CPU / GPU / Memory / Powerが一目瞭然で分かるモニタリングアプリだ。インストールと実行は簡単!

% pip install asitop
% sudo asitop

これでOK。刻一刻と状態が変わるのをモニタリングできる。

 次にLLMの簡易チャットとしてmlx_lmを試してみた。名前の通りAppleのMLX対応となる。インストールは

% pip install mlx
% pip install mlx_lm

これだけ。実行は以下の通り。

% mlx_lm.generate --prompt "Create a Python program to create a snake game" --model Qwen/Qwen2.5-Coder-32B-Instruct --max-tokens 8000

 該当するモデルが「~/.cache/huggingface/hub」にない場合は自動的にダウンロードが始まる。huggingfaceにログインしないとダウンロードできないものもあるため、huggingface-cli loginを使い事前にログインを済ませておいた方が無難だ。

 MLX非対応のQwen2.5-Coder-32B-Instructをまんま実行した場合。

% mlx_lm.generate --prompt "Create a Python program to create a snake game" --model Qwen/Qwen2.5-Coder-32B-Instruct --max-tokens 8000
MLX非対応のモデルで実行
このケースのシステムモニタリング
Prompt: 38 tokens, 55.439 tokens-per-sec
Generation: 1177 tokens, 7.401 tokens-per-sec
Peak memory: 65.875 GB

 次にMLX対応のmlx-community/Qwen2.5-Coder-32B-Instruct-6bitを実行した場合。

% mlx_lm.generate --prompt "Create a Python program to create a snake game" --model mlx-community/Qwen2.5-Coder-32B-Instruct-6bit --max-tokens 8000
MLX対応のモデルで実行
このケースのシステムモニタリング
Prompt: 38 tokens, 71.576 tokens-per-sec
Generation: 1181 tokens, 16.480 tokens-per-sec
Peak memory: 26.975 GB

 6bit化しているので単純比較でないが、速度もメモリ使用量も全然違うことが分かる。mlx-communityには、MLX化したモデルが1,077登録されており(執筆時)、Apple Siliconユーザーにとってありがたい存在になってる。

違うお題で生成中の動画
mlx_lm.generate --prompt "Create a Python program for quicksort. Explanation is in Japanese" --model mlx-community/Qwen2.5-Coder-32B-Instruct-6bit --max-tokens 4000

 mlx_lmコマンドは、サーバーモードもあり、mlx_lm.server --model <path_to_model_or_hf_repo> とすれば、http://localhost:8080/v1でOpenAI API互換となる。ただ後述するVSCodeのExtensionがうまく動かなかったので、サーバーモードは何か不都合があるのかも知れない。

 次はお馴染みLM Studio。GUIで使いやすいこともあり、以降はこちらがベースになっている。

LM Studio / Server(OpenAI API互換)
qwen2.5-coder-32b-instruct-q4_0.ggufとTiger-Gemma-9B-v3-Q4_K_M.ggufをロードした場合。約半分のメモリを使用

 筆者が日頃使うのは

  • qwen2.5-coder-32b-instruct-q4_0.gguf
    ※ もしくはmlx-community/Qwen2.5-Coder-32B-Instruct-4bit | -8bit。模索中
  • Tiger-Gemma-9B-v3-Q4_K_M.gguf

この2つ。前者はプログラミング用、後者は生成AI画像のPrompt用となる。また設定しているコンテキスト長は8Kと4K。

 Qwen2.5は128Kまで対応しているものの、さすがにそこまでするとメモリを食い遅くなる。加えて筆者の用途的にせいぜいファンクションの骨組み+α程度。8Kあれば特に問題はない。

 Tiger-Gemma-9B-v3はGemmaの非検閲改造版なので、LM Studio / Server / OpenAI API経由で、Open WebUIを使いPromptの生成、確認をComfyUI APIで画像生成と言うコンビネーションで使用。

Open WebUIを使い、日本語で指示した内容でPromptを作り、それに沿った画像をComfyUIで生成。この程度なら検閲ありでも問題ない(笑)

 Open WebUIは、画像生成だけでなく、RAGやPipelines Plugin Frameworkなどにも対応しており、かなり本格的に利用できる。

 この2つをロードした状態でメモリは約半分使用。まだ半分残っている(笑)。

VSCodeのExtension、ContinueとCline

 前置きが長くなってしまったが、ここからが本命!VSCodeの拡張(Extension)、「Continue」と「Cline」を使った例となる。どちらもLM StudioのServer / OpenAI API経由でqwen2.5-coder-32b-instruct-q4_0.ggufを使用している(もしくはMLX対応版)。

 Continueは、プログラミング支援的な機能を持ち、例えばあるコードを開き”このコードは何をしていますか?”と聞くと以下の動画となる。

VSCode + Continueでコードが何をしてるかを聞く

 “このスクリプトは、ユーザーが画像をアップロードすると、その画像からキャプションを生成し表示する単純なウェブアプリケーションを作成します。”

 という回答が出たが、正解。このコードはJoyCaptionと呼ばれるVLLMをGradioで作動させるコードだ。

 次にCUDA用に書かれているのでMacで作動するよう、CPU用に書き換える。基本CUDAの部分をCPUへ、bfloat16はないのでfloat32へとなる(速度的に後でfloat16へ変更)。

VSCode + ContinueでCUDA用からCPU用に書き換え

 うまく動くか?実行してみる。

40秒ほどかかるが、無事キャプションが生成された
出力結果

woman standing indoors, possibly in an office or modern living room. The woman has long, straight black hair that falls just past her shoulders, and she has a fair complexion with a light dusting of makeup, including pink blush and subtle eyeliner. She is wearing a black blazer over a white collared shirt, giving her a professional appearance.

In the foreground, she holds a black rectangular sign with white text that reads "PC Watch" in a casual, handwritten style. Her expression is neutral, with a slight smile, and she gazes directly at the camera, creating a sense of engagement with the viewer.

The background is softly blurred but suggests a modern, minimalist setting with large floor-to-ceiling windows on the left side of the image. Through the windows, a blurred view of greenery and a car outside can be seen, indicating a possibly urban or suburban location. A potted plant with large green leaves is visible on the right side of the image, adding a touch of nature to the otherwise sleek and contemporary environment. The lighting is natural, suggesting the photograph was taken during the day.

翻訳(Google翻訳)

おそらくオフィスかモダンなリビングルームの屋内に立つ女性。女性は、肩を少し超えるくらいの長くて真っ直ぐな黒髪をしており、ピンクのチークや繊細なアイライナーなど、軽くメイクを落とした色白の肌をしています。彼女は白い襟付きシャツの上に黒いブレザーを着ており、プロフェッショナルな印象を与えています。

前景で、彼女はカジュアルな手書きスタイルで「PC Watch」と白い文字で書かれた黒い長方形の看板を持っています。彼女の表情は、ほんのり微笑みを浮かべたニュートラルで、カメラをまっすぐに見つめており、見る者との関わりを感じさせます。

背景は柔らかくぼかされていますが、画像の左側に床から天井までの大きな窓があるモダンでミニマルな環境を示唆しています。窓を通して、ぼやけた緑と外の車が見え、おそらく都市部または郊外の場所であることがわかります。画像の右側には大きな緑の葉を持つ鉢植えが見え、洗練された現代的な環境に自然のタッチを加えています。照明は自然であり、写真が日中に撮影されたことを示唆しています。

 コード変換にしてもJoyCaption実行にしても、もう少し速く動いて欲しいところだが、GPUコア40基だとこの程度なのだろう。実際はこんな長いコードを扱わず、ファンクションの雛形を作る程度なので、それほど速度面は気にならない。

 その後、Apple Silicon用のPyTorchをインストールし、cpuをmpsへ変更、実行したところ13秒ほどになった。

pip install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cpu

 次はCline。これは最近流行りのtask型。コードを生成し、実行までできる。ある意味、夢の環境だ(笑)。

 今回はpythonでquick sortのコードを生成、ファイルへ保存、そして実行してみる。以下の動画をご覧いただきたい。

VSCode + Clineを使い、pythonでquick sortのコードを生成、ファイルへ保存、そして実行

 動きを見ていると分かると思うが、保存や実行時などには確認が入るので、人間が判断する。実行結果はもちろんOKだった。

 さて、こうなるとプログラマー不要論にすぐなるが、それは違う。ContinueにしてもClineにしても、実用的なコードをAIに作ってもらうには、仕様を整理しPromptにしなければならない。つまりプログラムが分かってないと指示できないのだ。

 ネットなどでプログラムしたことない人でもできた!的なのを見かけるが、コードで何をしているのか分からない状態でたまたま動いている的な感じだろう。趣味ならいいが、仕事では怖くて使えないコードとなる。

 いずれにしても現状のAIは指示するのも確認/実行するのも人間の役目。つまりプログラマー不要ではなく、より熟練されたプログラマーが必要になるのでは?と筆者は思っている。

 以上のように、VSCodeと組み合わせて使えば便利なAI系ExtensionのContinueやCline、実は、プロバイダにOpenAIやAnthropicのAPI対応しており、API課金さえすれば同じ(以上)のことができ、MacBook Pro 14に約75万円も払う必要はない(笑)。API課金してもなかなかこの金額には届かないだろう。

 最後に。M4 Maxと128GBの環境でVRAMとして使える最大容量はメモリの75% = 96GBとなっているが、これは標準設定というだけで変更可能だ。ただ128GB全部にしてしまうと、最大時アプリが動かなくなるため、8GB残して120GBとするには

% sudo sysctl iogpu.wired_limit_mb=122880
Password:
iogpu.wired_limit_mb: 0 -> 122880
※ デフォルト:0(75%)。120×1024=122880

と設定。これだと236BのDeepSeek-V2.5が動く。

 実際はLM Studioでダウンロード/実行可能な「DeepSeek-V2.5-i1-GGUF」を使ったが、238Bがローカルで動くのはちょっと感動!

 ただi1なのであまり賢くなく、LP生成“Create an LP for an IT company using bootstrap.”、1と2 take目はカッコいいのができず、動画は3 take目。Open WebUIもArtifacts機能があり、ご覧のように生成したコードの表示ができる。メモリは約110GB使用。ほぼギリギリ。加えてこの時、ファンの音を初めて聞いた(高出力設定)。相当負荷がかかるようだ。

DeepSeek-V2.5作動中(DeepSeek-V2.5-i1-GGUF)。この時、メモリは約110GB使用

後で分かったのだが、同じお題ならqwen2.5-coder-32b-instruct-q4_0.ggufの方がカッコいいLPができた(笑)。


 以上のようにM4 Max 128GBを搭載したMacBook Pro 14は、一般的な家庭用GPU搭載PCでは実行不可能なLLMを実行可能だった。

 大規模LLMをローカルで動かす旨みは、以前なら無検閲が挙げられたものの、今ではほぼ全て検閲あり。ほかにあるとすればコンテキスト長を大きくできる程度。+αで、新しいモデルが出た時、即試せることだろうか。

 筆者の場合は、まだ知らない使い方や次々出てくるモデルを即試せる……という意味で将来に投資した感じとなる。従って現状、高い買い物だったのか、安い買い物だったのかは不明。数年後に振り返ってどう思うか!?……となる。時期が来たら、また感想を書いてみたい。