AWS Lambdaで動かすStable Diffusion（ネガティブプロンプト対応 Diffusers v0.4.2）

# はじめに
先日(2022/10/7)、Diffusers v0.4.0がリリースされました。
9月にリリースされたv0.3.0ではONNXがサポートされてCPUでの実行がやりやすくなり、今回のv0.4.0ではポジティブプロンプトとネガティブプロンプトの両方を指定できるようになるなどの機能が追加されています。
これまでCPUでStable Diffusionを使用する場合はopenvino版を使用していましたが、本記事ではこれらの追加された機能を活用し、openvinoを使わずにAWS Lambdaにて動作確認をしてみたいと思います。

:::note alert
費用に関する注意、および、免責事項
- 注意事項
本記事ではLambda関数に設定可能なメモリ上限の割り当てを行います。
また、画像の作成には1枚に数分程度かかるなど費用が高額になる可能性があるため内容を検証する場合は十分ご注意ください。
- 免責事項
当方はこの記事を使用して生成されたコンテンツについて責任を負うものではなく、また、このプロジェクトを違法、有害、攻撃的なコンテンツの作成に使用しないでください。
:::

# 前提
本記事で紹介する内容を実行するためには、事前に次のものをご準備ください。
- Hugging Faceのユーザー名＆アクセストークン
Hugging Faceの **Username** 、および、 **Access Token** をご確認ください。
    - https://huggingface.co/settings/account
    - https://huggingface.co/settings/tokens
    
    もしまだHugging Faceのアカウントがない場合は、以下のサイトにてアカウントを作成してください。

https://huggingface.co/

- ビルド環境
本記事ではコンテナ形式のAWS Lambdaを作成します。
そのためDockerイメージのビルドを行うのですが、メモリの少ない環境ではエラーとなる場合があります。
参考までに当方がビルド環境として使用したAWS Cloud9のインスタンスタイプとボリュームサイズを示します。
（十分なメモリとディスクを搭載したPCを利用可能な場合はAWS Cloud9を使用する必要はありません）

   * インスタンスタイプ　：  m6a.4xlarge
   * ボリュームサイズ (GiB)： 80GB

    なお、ビルド環境においてはDocker、AWS CLIのインストールおよび設定もお願いします。
   
# ソースコード一式
ソース一式はGitHubに置いています。
クローン or ダウンロードしてご利用ください。

```
$ git clone https://github.com/densenkouji/stable_diffusion.lambda.git
$ cd stable_diffusion.lambda
```

# インストール
インストール用のスクリプト(install.sh)を実行します。
スクリプトを実行すると次の3項目について入力を求められます。
- 作成するLambda関数名：任意の名称でOK
- Hugging Faceのユーザー名：Hugging Faceで設定したユーザー名
- アクセストークン：Hugging Faceにて発行されたアクセストークン

入力完了後、Lambda関数の作成やデプロイが行われます。
所要時間はネットワークの混雑状況やPCのスペックなどにより変動しますが、数十分程度を見込んでください。

```terminal:実行例（Lambda関数名やユーザー名などは例です）
$ sh ./install.sh 
(Create New) Input AWS Lambda Function Name [ex.mySdFunction]:myOnnxFunction
[Hugging Face] Username:example
[Hugging Face] User Access Tokens:hf_abcdefghijklmnopqrstuvwxyz
```

# テスト
インストールが問題なく終了したらテストを行います。
ここではプロンプトおよびシードを固定して、ネガティブプロンプトのみ変更した結果を以下に記載します。

先ずは、ネガティブプロンプトを指定せずに実行します。

■コマンド実行例：ネガティブプロンプトなし
```terminal:実行例
$ aws lambda invoke \
   --function-name myOnnxFunction-mwi1ywi5nthin2m3 \
   --invocation-type 'RequestResponse' \
   --payload '{"prompt":"Street-art painting of Tower with flower in Tokyo", "negative_prompt":"", "seed": 3686246505}' \
   --cli-read-timeout 600 \
   --cli-binary-format raw-in-base64-out \
   output.text
```
■実行結果
![sd_3686246505_2022-10-14-01-43-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741318/aeea8ba4-0f73-20f1-04b3-e23e815cec57.png)

続いて、ネガティブプロンプトを指定します。

■コマンド実行例：ネガティブプロンプトあり(payloadにてnegative_promptに"pink"を指定)
```terminal:実行例
$ aws lambda invoke \
   --function-name myOnnxFunction-mwi1ywi5nthin2m3 \
   --invocation-type 'RequestResponse' \
   --payload '{"prompt":"Street-art painting of Tower with flower in Tokyo", "negative_prompt":"pink", "seed": 3686246505}' \
   --cli-read-timeout 600 \
   --cli-binary-format raw-in-base64-out \
   output.text
```
■実行結果：ネガティブプロンプト(pink)を指定
![sd_3686246505_2022-10-14-01-48-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741318/d6868639-7c1c-0ac4-0253-00151a5286fd.png)

# アンインストール
「install.sh」を実行すると、アンインストール用のスクリプト「uninstall-XXXXXXXXXXXXXXXX.sh」(XXX…の部分はランダムな16桁の英数字)が作成されます。
実行するとインストール時に作成した次のリソースについて削除するため、検証終了時にご利用ください。
- Lambda関数
- ロール
- ECRリポジトリ
- S3バケット

以上です。

# 謝辞/Acknowledgements
- Original implementation of Stable Diffusion: https://github.com/CompVis/stable-diffusion
- diffusers library: https://github.com/huggingface/diffusers