ラズパイでStable Diffusionを動かすメモ

# はじめに

某社内ハッカソンで人力💪生成AIというテーマで作品を作りました。

https://protopedia.net/prototype/4727

制作過程で人力(手回し発電機)でラズパイを動かして(1.5時間)、Stable Diffusionで画像を1枚生成し、電子ペーパーに表示させました。

https://www.youtube.com/watch?v=JxDZsNAeu4U

この記事はラズパイでStatble Diffusionを動かした時のメモです。

https://ponkichi.blog/stable-diffusion/#st-toc-h-5

# 手順

## SWAP領域を拡大する

```bash
sudo vi /etc/dphys-swapfile
```

(Raspberry Pi 4B(4GB) の場合)

```text
CONF_SWAPSIZE=8192
CONF_MAXSWAP=8192
```

(Raspberry Pi 3B+ の場合)

```text
CONF_SWAPSIZE=10240
CONF_MAXSWAP=10240
```

dphys-swapfileサービスを再起動します。

```bash
sudo systemctl restart dphys-swapfile
```

swaponコマンドで変更を確認します。

```bash
swapon -s
```

## ライブラリをインストールする

```bash
sudo apt install -y python3-pip libjpeg-dev libopenblas-dev libopenmpi-dev libomp-dev
sudo -H pip3 install setuptools==58.3.0 Cython gdown
```

## Pytoachのインストール

```bash
gdown https://drive.google.com/uc?id=1A2Lc-7y3-ATauRa4FntiYGH90b1GjAzx
sudo -H pip3 install torch-1.12.0a0+git67ece03-cp39-cp39-linux_aarch64.whl
```

## Pythonライブラリのインストール

```bash
pip3 install transformers diffusers accelerate scipy safetensors
```

## アクセストークンの取得

https://huggingface.co/settings/tokens

## 初回の描画実行

sd.pyを作成して実行します。

```python: sd.py
import torch
from diffusers import StableDiffusionPipeline
from torch import autocast

MODEL_ID = "CompVis/stable-diffusion-v1-4"
DEVICE = "cpu"
YOUR_TOKEN = "アクセストークン"
SCALE = 7.5
SEED = 1
GENERATOR = torch.Generator(DEVICE).manual_seed(SEED)
WSIZE = 256
HSIZE = 256
STEPS = 10
PROMPT = "raspberry pi painted by Katsushika Hokusai"

pipe = StableDiffusionPipeline.from_pretrained(MODEL_ID, use_auth_token=YOUR_TOKEN)
pipe.to(DEVICE)

image = pipe(PROMPT, height=HSIZE, width=WSIZE, guidance_scale=SCALE, generator=GENERATOR, num_inference_steps=STEPS).images[0]
image.save("image.png")
```

```bash
python3 sd.py 

The cache for model files in Transformers v4.22.0 has been updated. Migrating your old cache. This is a one-time only operation. You can interrupt this and resume the migration later on by calling `transformers.utils.move_cache()`.
0it [00:00, ?it/s]
Downloading (…)ain/model_index.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████| 541/541 [00:00<00:00, 28.5kB/s]
Downloading (…)rocessor_config.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████| 342/342 [00:00<00:00, 18.9kB/s]
Downloading (…)_checker/config.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████| 4.56k/4.56k [00:00<00:00, 233kB/s]
Downloading (…)_encoder/config.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████| 592/592 [00:00<00:00, 32.6kB/s]
Downloading (…)cial_tokens_map.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████| 472/472 [00:00<00:00, 127kB/s]
Downloading (…)nfig-checkpoint.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████| 209/209 [00:00<00:00, 11.5kB/s]
Downloading (…)cheduler_config.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████| 313/313 [00:00<00:00, 15.4kB/s]
Downloading (…)38b/unet/config.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████| 743/743 [00:00<00:00, 199kB/s]
Downloading (…)okenizer_config.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████| 806/806 [00:00<00:00, 194kB/s]
Downloading (…)638b/vae/config.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████| 551/551 [00:00<00:00, 136kB/s]
Downloading (…)tokenizer/merges.txt: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████| 525k/525k [00:01<00:00, 386kB/s]
Downloading (…)tokenizer/vocab.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████| 1.06M/1.06M [00:03<00:00, 302kB/s]
Downloading (…)ch_model.safetensors: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████| 335M/335M [08:09<00:00, 683kB/s]
Downloading model.safetensors: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████| 492M/492M [11:07<00:00, 738kB/s]
Downloading model.safetensors: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.22G/1.22G [20:33<00:00, 986kB/s]
Downloading (…)ch_model.safetensors: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 3.44G/3.44G [34:29<00:00, 1.66MB/s]
Fetching 16 files: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 16/16 [34:31<00:00, 129.48s/it]
Cannot initialize model with low cpu memory usage because `accelerate` was not found in the environment. Defaulting to `low_cpu_mem_usage=False`. It is strongly recommended to install `accelerate` for faster and less memory-intense model loading. You can do so with:                                                              | 524M/3.44G [11:03<49:55, 973kB/s]
nloading (…)ch_model.safetensors:  37%|████████████████████████████████████▉                                                               | 1.27G/3.44G [20:30<25:17, 1.43MB/s]
pip install acceleratel.safetensors: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████| 3.44G/3.44G [34:29<00:00, 2.50MB/s]

Loading pipeline components...:  29%|█████████████████████████████████▏                                                                                  | 2/7 [08:20<20:50, 250.10s/it]`text_config_dict` is provided which will be used to initialize `CLIPTextConfig`. The value `text_config["id2label"]` will be overriden.
`text_config_dict` is provided which will be used to initialize `CLIPTextConfig`. The value `text_config["bos_token_id"]` will be overriden.
`text_config_dict` is provided which will be used to initialize `CLIPTextConfig`. The value `text_config["eos_token_id"]` will be overriden.
Loading pipeline components...: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [10:32<00:00, 90.38s/it]
  2%|██▊                                                                                                                                            | 1/50 [18:36<15:11:42, 1116.37s/it]
  4%|█████▊                                                                                                                                           | 2/50 [25:48<9:30:59, 713.73s/it]
  6%|████████▋                                                                                                                                        | 3/50 [33:43<7:53:39, 604.67s/it]
  8%|███████████▌                                                                                                                                     | 4/50 [41:08<6:55:12, 541.58s/it]
 10%|██████████████▌                                                                                                                                  | 5/50 [49:33<6:36:26, 528.59s/it]
 12%|█████████████████▍                                                                                                                               | 6/50 [57:43<6:18:05, 515.58s/it]

```


## (参考)エラー回避

![スクリーンショット 2023-09-17 8.10.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/2736ec3e-4db5-ab92-86af-a8ec68ea23e1.png)

https://qiita.com/daiarg/items/87b849fda62881c28b99