Stable Diffusionなどの画像生成モデルを動かすとき、特に問題になるのが「VRAM不足」です。
この記事では、Diffusersでよく使われるメモリ最適化機能と、その仕組み・注意点をまとめます。
メモリ最適化機能の概要
enable_model_cpu_offload()
モデル全体をGPUに常駐させず、必要なときだけCPUからGPUへ転送する仕組みです。
- 使う直前にGPUへロード
- 使い終わったらCPUへ戻す
特徴
- VRAM使用量:大きく削減
- 実行速度:低下(転送コストがある)
enable_sequential_cpu_offload()
enable_model_cpu_offload()の強化版で、モデルをレイヤー単位で扱います。
- レイヤーごとにGPUへロード
- 計算後すぐCPUへ戻す
特徴
- VRAM使用量:最小レベル
- 実行速度:かなり遅い(毎回転送が発生)
enable_attention_slicing()
Attention計算を分割して処理することで、メモリ使用量を抑える機能です。
特徴
- VRAM使用量:中程度削減
- 実行速度:やや低下
enable_vae_slicing()
画像を生成する最後の段階(VAEデコーダ)を分割処理する機能です。
特徴
- VRAM使用量:少し削減
- 実行速度:ほぼ影響なし
Attention計算とは何か
Attentionとは、画像生成モデルが「どの部分に注目するか」を決める仕組みです。
テキスト(プロンプト)と画像の対応関係を計算する際に使われます。
簡単に言うと:
- 「この単語は画像のどこに影響するか」
- 「このピクセルはどの情報を参照するか」
を計算しています。
ただし、この処理は非常にメモリを消費します。
そのため attention_slicing によって分割して処理することで、メモリ使用量を抑えます。
VAE(デコーダ)処理とは何か
Stable Diffusionでは、最終的な画像は直接生成されているわけではありません。
- まず「潜在空間(latent)」と呼ばれる圧縮された状態で画像を生成
- それをVAEデコーダで実際の画像に変換
この「潜在→画像」の変換がVAEデコーダ処理です。
- 解像度が高いほど負荷が大きい
- 一度に処理するとメモリを消費する
vae_slicing はこの処理を分割して実行します。
accelerate と bitsandbytes
Accelerate
Accelerate は、CPUやGPUの管理を簡単にするライブラリです。
主な役割:
- デバイス間(CPU / GPU)のデータ転送管理
- メモリ最適化(offload機能)
- 分散処理のサポート
今回紹介した cpu_offload 系機能は、このライブラリによって実現されています。
bitsandbytes
bitsandbytes は、モデルを低精度化(量子化)するライブラリです。
- 32bit → 8bit / 4bit に変換
特徴
- VRAM使用量:大幅削減
- 速度:ほぼ維持(環境による)
- 精度:若干低下する場合あり
それでもメモリが足りない場合
すべての最適化を有効にしても、環境によってはメモリ不足が発生します。
起こる主な問題
- CUDA out of memory エラー
- 処理の強制終了
- 極端な速度低下(スワップ発生)
対処方法
優先度順に:
- 解像度を下げる(例:512 → 256)
- バッチサイズを1にする
- ステップ数を減らす
- 軽量モデルを使う
- bitsandbytesで量子化する
限界状態の挙動
- CPU RAMも不足するとスワップが発生
- 数分〜数十分かかることもある
- 場合によってはフリーズに近い状態になる
CPUのみ環境での挙動
結論
CPUのみの環境では、これらの最適化はほぼ意味がありません。
理由
CPU offload系
- GPUが存在しないため、オフロード先がない
- 結果として無駄な処理が増えるだけ
slicing系
- CPUでも動作はする
- ただし元々遅いため、さらに遅くなる可能性がある
実際の挙動
| 環境 | 結果 |
|---|---|
| GPUあり(低VRAM) | 効果大 |
| GPUなし(CPUのみ) | 遅くなるだけ |
まとめ
- cpu_offload系:VRAM節約効果が大きいが遅い
- sequential_offload:さらに節約できるがかなり遅い
- attention_slicing:バランス型
- vae_slicing:軽い最適化
- bitsandbytes:根本的な軽量化
- accelerate:これらを支える基盤
おすすめ構成
- VRAM 8GB以上:attention_slicingのみ
- VRAM 4〜6GB:cpu_offload + slicing
- VRAM 2〜4GB:sequential_offload + 量子化
- CPUのみ:基本的に使用しない


