ソースに絡まるエスカルゴ

貧弱プログラマの外部記憶装置です。

【Raspberry Pi】Raspberry Pi 5でStable Diffusion v1-5を動かしてみる

 先日書いたAI Kitの記事とは関係ないのですが、Raspberry Pi 5のCPUのみでStable Diffusionを使って画像生成できることを知ったので今回はその備忘録になります。
 詳しくは参考資料に挙げているページ様を参照していただきたいのですが、色々と注意点などがあるのでそれをまとめたいと思い記事にした次第です。


 では、始めます。


0:128GB以上のSDカードの準備
 まず最初に注意しておいていただきたいのはRaspberry Pi 5で使う「SDカードの容量」です。今回使用するStable Diffusionのモデルがあるリポジトリをcloneするだけで「90GB程度」消費します。

 なので最低「128GB以上のSDカード」を使用するようにしてください。

 amazonで売られているサンディスクの128GBのSDカードであれば2000~3000円程度で購入できると思うので、そのようなものを準備してください。

 以降は「128GBのSDカードにRaspberry Pi OSを書き込み最低限の設定まで終わっている」という前提で進めていきます。


1:git-flsのインストール
 最初にgit-flsをインストールします。

 以下のコマンドを上から順番に実行していけばインストールされます。

curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt-get install git-lfs
git lfs install


2:Stable Diffusionモデルのリポジトリクローン
 Stable Diffusionのモデルのあるリポジトリをクローンしますが、先述したように「90GB程度」をダウンロードする必要があります。なので可能であればWiFiによる無線ではなく、LANケーブルを用いた有線での実行を推奨します。

 1でgit-flsがインストールできたら、作業用ディレクトリとしてstable_diffusionを作成します。

mkdir stable_diffusion

 作業用ディレクトリが作成できたらそこに移動します。

cd stable_diffusion

 移動したら以下のコマンドを実行してStable Diffusionのモデルをクローンします。

git clone https://huggingface.co/runwayml/stable-diffusion-v1-5

 回線環境によって左右されると思いますが、自分の場合はWiFiの無線で3時間程度かかりました。

 また.gitの隠しディレクトリの容量だけで「40GB」ほどあります。このような余計なものをダウンロードしたくない場合は以下のページを開いて、一つ一つのファイルをダウンロードして全く同じディレクトリ構成を作る方が楽かもしれません。

 とにかく頑張ってモデルファイルをダウンロードしてください。

 この作業が終了した後は以下のようなディレクトリ構成になっていると思います。

stable_diffusion/
└── stable-diffusion-v1-5
    ├── README.md
    ├── feature_extractor
    │   └── preprocessor_config.json
    ├── model_index.json
    ├── safety_checker
    . - ※以下様々なファイルとディレクトリが続く
    .
    .


3:必要なpythonライブラリのインストール
 Stable Diffusionのモデルの準備ができたら、作業用ディレクトリに移動します。

cd stable_diffusion

 Raspberry Pi 5が出た頃からpip installコマンドが気軽に叩けなくなったので、pythonの仮想環境を作成する以下のコマンドを実行します。実行すると1分ほど時間がかかるので終了するまで待ちます。

python -m venv --system-site-packages --clear --prompt 'stable_diffusion' --upgrade-deps $(pwd)/.venv

 終了後、以下のコマンドで仮想環境に入ります。

source .venv/bin/activate

 以下のコマンドを上から順番に実行して、必要なライブラリをインストールします。

pip install --upgrade diffusers
pip install transformers
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
pip install accelerate

 ちなみに上から、diffusers、transformers、pytorch、accelerateをインストールしています。

 pytorchについては以下のページを開いてスクロースさせた先にある環境に合わせたコマンドを生成するものを使用しています。


4:Stable Diffusionを呼び出すpythonファイルの作成
 必要なライブラリのインストールが終わったら、Stable Diffusionを呼び出すpythonファイルを作成します。

 今回のサンプルコードは以下のものを参考にして、処理時間を計算するよう追加しています。

 作業用ディレクトリに以下内容をコピペして「generate_image.py」として保存してください。

・generate_image.py

# -*- coding: utf-8 -*-
import datetime

from diffusers import StableDiffusionPipeline
from PIL import Image

# 画像生成するプロンプト
PROMPT_STR = "a black tree with golden leaves painted by Monet, autumn"

# 処理開始時刻を取得
start_time = datetime.datetime.now()

# モデルを読み込み(CPU処理を指定)
pipe = StableDiffusionPipeline.from_pretrained("./stable-diffusion-v1-5", low_cpu_mem_usage=True)
pipe = pipe.to("cpu")

# プロンプトと画像サイズを指定して画像生成
image = pipe(PROMPT_STR, num_inference_steps=31, width=400, height=400).images[0]

# 処理終了時刻を取得
end_time = datetime.datetime.now()

# 生成画像を保存
image.save("output_" + end_time.strftime("%Y%m%d_%H%M%S") + ".png")

# 差分時刻を計算
diff_time = end_time - start_time

# 処理にかかった時間を表示
print("start :" + str(start_time.time()))
print("end   :" + str(end_time.time()))
print("diff  :" + str(diff_time))

 これで以下のようなディレクトリ構造になっているはずです。

stable_diffusion/
├── generate_image.py
└── stable-diffusion-v1-5
    ├── README.md
    ├── feature_extractor
    │   └── preprocessor_config.json
    ├── model_index.json
    ├── safety_checker
    . - ※以下様々なファイルとディレクトリが続く
    .
    .


5:環境変数の設定と画像生成の実行
 画像生成をする前に以下のコマンドで環境変数を設定します。この環境設定を行わないと、画像生成にかなり時間がかかってしまう場合があるので、実行前に設定するようにしてください。

export OPENBLAS_NUM_THREADS=1
export OMP_NUM_THREADS=4

 環境変数の設定ができたらpythonファイルを実行します。

python generate_image.py

 実行すると何やらメッセージが表示されますが、warningなので無視して良いです。

 実行してエラーになった場合は、内容を読んで不足しているライブラリを各自で追加インストールをしてみてください。

 正常終了すると、以下のような出力結果となりgenerate_image.pyと同じ階層に「output_[日時].png」のファイル名で生成画像が保存されます。

$ python generate_image.py
/home/pi/stable_diffusion/.venv/lib/python3.11/site-packages/diffusers/models/transformers/transformer_2d.py:34: FutureWarning: `Transformer2DModelOutput` is deprecated and will be removed in version 1.0.0. Importing `Transformer2DModelOutput` from `diffusers.models.transformer_2d` is deprecated and this will be removed in a future version. Please use `from diffusers.models.modeling_outputs import Transformer2DModelOutput`, instead.
  deprecate("Transformer2DModelOutput", "1.0.0", deprecation_message)
Loading pipeline components...: 100%|█████████████| 7/7 [00:02<00:00,  3.04it/s]
100%|███████████████████████████████████████████| 31/31 [10:50<00:00, 20.97s/it]
start :15:47:33.031459
end   :15:59:24.568573
diff  :0:11:51.537114

 自分の環境では実行して画像が生成されるまでに大体12分~15分程度でした。また同じプロンプトを入力して実行しても、以下のように毎回違った画像が出力されます。


 以上がRaspberry Pi 5でStable Diffusion v1-5を動かしてみた内容になります。

 今のStable Diffusionはv3になっているようなのでかなり古いバージョンを動かしていることになります。

 そもそもStable Diffusionで画像生成を行ったのが今回初めてなのでこの処理速度がどの程度のものなのかはわからないでいますが、Raspberry Piというボードコンピュータで15分程度で1枚生成できるというところにロマンがあると思うので色々試してみたいです。


・参考資料