2026年9月4日 金曜日
AI時短ラボ
活用· 約17

ローカルAIの画像生成は単体グラボなしでも動くのか──条件で見る判定

単体グラボを持たないMacBook Air(Apple M2・8GB)で、MLXを使ったStable Diffusion系の画像生成を実際に試みた。ブロッカーになったのはGPUの有無ではなく、SDXL-turboの重みファイル計6.46GB(実測)と、検証時点の空きディスク6GB前後という組み合わせだった。

ローカルAIの画像生成は単体グラボなしでも動くのか──条件で見る判定
執筆・編集:
目次

「画像生成AI ローカル GPUなし」で検索する人の多くは、単体グラフィックボード(NVIDIA製GPU)を積んでいないノートPCで、Stable Diffusion系のツールが動くかどうかを知りたいはずだ。既存のStable Diffusion導入ガイドの多くは「VRAM 6GB以上のNVIDIA GPUがほぼ必須」という前提で書かれている。

手元にあるMacBook Air(Apple M2・メモリ8GB)は、まさにこの「単体グラボなし」の機種だ。実際にAppleのMLXフレームワークを使って画像生成を試み、どこで止まるかを記録した。

3行まとめ

  1. MacBook Air(Apple M2・8GB)で単体グラボの有無を確認すると、内蔵GPU自体はmlxからDevice(gpu, 0)として認識されており、「グラボなし」と「GPUなし」はイコールではなかった
  2. 実際に止まったのはGPUではなくディスク容量。SDXL-turboのfp16重み一式は実測で約6.46GB、検証時点の空き容量は6.1GB〜6.6GBでほぼ足りるか足りない状態だった
  3. 実装コード(txt2image.py)を直接読むと、-q(量子化)オプションはモデルの重みを全量ダウンロードした後にメモリ上で量子化する処理であり、ダウンロードするファイル自体を軽くするものではない。今回のディスク容量の壁は-qでは解消しない

今回の機体と条件

  • 機種: MacBook Air / Apple M2(統合GPU 8コア、Metal 3対応) / 統合メモリ8GB
  • 単体グラボ: なし(system_profiler SPDisplaysDataTypeで確認できるGPUはApple M2内蔵の1つのみ)
  • mlx: 0.32.1(すでにpipでインストール済み)
  • ストレージ空き: 検証時点で6.1GB〜6.6GBの間で変動

「グラボなし」と「GPUなし」は同じではない

まず確認しておきたいのは、この機種に画像生成向けのGPUが本当に存在しないのかという点だ。system_profiler SPDisplaysDataTypeで見ると、Apple M2には8コアのGPUが内蔵されており、Metal 3に対応している。単体グラボ(NVIDIA GeForceのような、CPUと別チップになっている専用グラフィックボード)は無いが、GPU自体は存在する。

AppleのMLXは、このApple Silicon内蔵GPUで動かすことを前提にしたフレームワークだ。MLX公式のGitHubリポジトリには「MLX is an array framework for machine learning on Apple silicon」「Arrays in MLX live in shared memory. Operations on MLX arrays can be performed on any of the supported device types without transferring data.(統合メモリモデルにより、デバイス間でデータをコピーせずに演算できる)」と明記されている。実際にpython3 -c "import mlx.core as mx; print(mx.default_device())"を実行するとDevice(gpu, 0)と返ってきて、mlxがこの内蔵GPUを認識していることが確認できた。

つまり「単体グラボが無い」ことと「画像生成に使えるGPUが無い」ことはイコールではない。ここを混同したまま検索している人は一定数いるはずなので、先に切り分けておく。

MLXでStable Diffusion系を動かそうとした

MLXの公式サンプル集(mlx-examples)にはstable_diffusionというディレクトリがあり、READMEには次のように書かれている。

"Stable Diffusion in MLX. The implementation was ported from Hugging Face's diffusers and model weights are downloaded directly from the Hugging Face hub. The implementation currently supports the following models:"

このあとに続く一覧に挙がっているのはstabilityai/sdxl-turbostabilitiai/stable-diffusion-2-1の2つで、READMEでは--model引数でsdxl(既定、sdxl-turbo)とsd(stable-diffusion-2-1)を選べると説明されている。依存パッケージ(huggingface-hubregextqdmPILnumpy)のうち、numpypillowはすでに入っていたが、モデルの重みはこの時点でまだ手元に無い。

まず重みのサイズを実測した

いきなりpython txt2image.pyを実行してダウンロードを走らせる前に、Hugging Face上の実ファイルサイズをcurl -sILのHEADリクエストで確認した。MLXの実装が読み込むのはfp16版の重みで、内訳は以下の通り。

ファイル サイズ(実測)
unet/diffusion_pytorch_model.fp16.safetensors 5,135,149,760 バイト(約4.78GB)
text_encoder_2/model.fp16.safetensors 1,389,382,176 バイト(約1.29GB)
text_encoder/model.fp16.safetensors 246,144,152 バイト(約0.23GB)
vae/diffusion_pytorch_model.fp16.safetensors 167,335,342 バイト(約0.16GB)
合計 6,938,011,430 バイト(約6.46GB)

対して、検証時点でのこのMacの空きストレージは6.1GB〜6.6GBの間で変動していた(df -hを複数回実行し、実際に増減しているのを確認した)。必要な約6.46GBに対して、空き容量はほぼ同じか、それを下回っている状態だ。この時点で、フルのダウンロードが完走しない可能性が高いことが数字の上で見えた。

実際にダウンロードして確かめた(手前で止めた)

いきなり6.46GB全部をダウンロードして本当にディスクが尽きるのを待つのは、このノートを普段の仕事にも使っている以上避けたかった。そこで、curl-rオプション(バイト範囲指定)で、unetファイルの先頭50MB(52,428,800バイト)だけを実際に取得し、実測の回線速度を測った。

結果は3.009秒で50MB。計算すると約16.6MB/秒(約133Mbps)だった。この速度がダウンロード全体を通して一定だと仮定すると、6.46GB全体の取得には約6分38秒かかる計算になる。だが、この計算はあくまで「ディスクに十分な空きがあれば」という前提の話で、実際には6.46GBを書き切る前に空き容量が尽きる可能性が高い。

念のため、もう一つの選択肢である--model sd(stable-diffusion-2-1)のページも確認した。curl -sILhttps://huggingface.co/stabilityai/stable-diffusion-2-1にアクセスすると、HTTPステータスは401で、API経由でも{"error":"Invalid username or password."}が返ってきた。つまりこちらは検証時点でHugging Face側の認証(ログイン・トークン)なしにはダウンロードできない状態になっており、無条件の代替にはならない。

なお、後日txt2image.py本体のソースコードを直接読み返すと、--model sdが実際に読み込むリポジトリ名はstabilityai/stable-diffusion-2-1ではなくstabilityai/stable-diffusion-2-1-baseだった。念のためstable-diffusion-2-1-baseの方も同じ方法で確認したところ、こちらも同じく401を返しており(2026年8月29日再確認)、「無認証では取得できない」という結論自体は変わらない。ただし、当初参照していたリポジトリ名が実装コードと厳密には一致していなかった点は訂正しておく。

見落としていた選択肢: 量子化オプション

MLX公式READMEには、今回引用した部分より先に「Memory constrained devices」という節があり、txt2image.py-q(--quantize)という引数に対応していることが書かれている。

"The txt2image.py script supports quantization using the -q or --quantize command line arguments. When quantization is used, the script quantizes the text encoder models to 4 bits and the unet to 8 bits. This allows generating images on an 8GB Mac Mini with no-swapping."

今回の検証ではこのオプションを使っていない。README の記載どおりなら、text encoderを4bit・UNetを8bitに量子化することで、8GBメモリのMac miniでもスワップなしに画像生成ができた実績があるということになる。

READMEの記載だけでは、この量子化がダウンロード後にメモリ上で行われる処理なのか、ダウンロードするファイル自体が軽量版に変わるのかを判別できなかったため、後日txt2image.py本体のソースコードをcurlで直接取得して確認した。該当箇所は次のようになっている。

sd = StableDiffusionXL("stabilityai/sdxl-turbo", float16=args.float16)
if args.quantize:
    nn.quantize(
        sd.text_encoder_1, class_predicate=lambda _, m: isinstance(m, nn.Linear)
    )
    nn.quantize(
        sd.text_encoder_2, class_predicate=lambda _, m: isinstance(m, nn.Linear)
    )
    nn.quantize(sd.unet, group_size=32, bits=8)

StableDiffusionXL(...)でモデル(=fp16の重み一式)を読み込んだ後にif args.quantize:の分岐でnn.quantize(...)が呼ばれている。つまり-qは、ダウンロード自体を軽くする仕組みではなく、一度フルサイズの重みをダウンロード・ロードしたうえで、メモリ上で量子化する処理だとコードから確認できた。今回の壁はディスク容量(fp16重み一式で約6.46GB)だったため、-qを使っていたとしても、ダウンロードに必要な約6.46GBという数字自体は変わらず、この壁を回避できなかった可能性が高い。README の「8GB Mac Miniでもスワップなしに動く」という記載は、あくまで実行時のメモリ使用量についての主張であり、ダウンロード時のディスク使用量についての主張ではない、と読み直す方が正確だ。

何が本当のボトルネックだったか

ここまでの実測を整理すると、今回の環境で画像生成が動かなかった直接の原因は次の2つで、どちらも「単体グラボが無いこと」そのものではない。

  1. ディスク容量: SDXL-turboのfp16重み一式が約6.46GBに対し、空き容量が6.1GB〜6.6GBで足りるかどうかのギリギリ、あるいは足りない状態だった
  2. 認証: 代替の軽量モデル(stable-diffusion-2-1)は検証時点でHugging Face側が401を返し、無認証では取得できなかった

GPU自体(Apple M2内蔵の8コアGPU)はmlxから認識されており、Device(gpu, 0)が返ってきている以上、演算そのものを内蔵GPUで行う準備はできていた。単体グラボが無いことがボトルネックになるとすれば、演算速度(1枚の生成に何秒かかるか)の話であって、「動く/動かない」の二択の話ではない。今回はその速度を測る手前で、容量と認証の壁にぶつかった。

この記事の限界

  • -q(量子化)オプションを実際にコマンド実行して試したわけではない。 ソースコード(txt2image.py)を読むことで「ダウンロード後にメモリ上で量子化する処理であり、ダウンロード容量自体は減らない」ところまでは確認できたが、実際に-q付きで実行してディスク使用量・生成速度がどうなるかは、この記事では試していない
  • 実際に1枚も画像を生成できていない。 ダウンロードが完走する前提での生成速度・画質は、この検証では確認できていない
  • ディスクを完全に埋めるところまでは試していない。 業務にも使っているマシンで空き容量をゼロに近づけるのは避けたため、「実際に容量不足でダウンロードが失敗する瞬間」そのものは見ていない。数字の比較(必要6.46GB vs 空き6.1〜6.6GB)からの推定にとどまる
  • stable-diffusion-2-1(および実装コードが実際に参照するstable-diffusion-2-1-base)の401が、恒久的な仕様なのか一時的な状態なのかは確認していない。 2026年8月27日の検証時点、2026年8月29日の再確認時点のいずれも401だったことは確認したが、それ以前・それ以降の変遷は追っていない
  • 回線速度は1回・50MBのみの計測。 時間帯やHugging Face側の混雑で変動する可能性があり、6分38秒という所要時間の見積もりは目安に過ぎない
  • Windows機やLinux機で、内蔵GPUすら無い(オンボードグラフィックのみの)構成では試していない。 今回の結論はApple Silicon(統合メモリ+内蔵GPU)という特定の構成に基づいている

同じ機体でのモデルサイズと速度の実測はローカルAIの最低スペックはどこまで低くて良いか、コーディング用途での実用性はローカルLLMでコーディングエージェントは実用になるかにまとめている。GPU前提の一般的な導入手順はStable Diffusion ローカル導入ガイド、テキスト生成系のローカルLLM全体像はローカルLLMとは何かを参照してほしい。

シェア: ポスト はてブ

出典・参照資料

AIニュースの解説を動画でも

YouTubeでは注目ニュースの背景を解説し、Xでは新着記事をお知らせしています。

コメント

まだコメントはありません。最初のコメントを書いてみませんか?

AIについて聞きたいことはありますか?

質問箱で無料で受け付けています。回答は公開され、他の方の参考にもなります。

質問箱を見る →

新しい記事をメールで受け取る

AIの新しい発表を、出典付きで整理して届けます。

関連記事