LoginSignup
2
6

More than 1 year has passed since last update.

Stable DiffusionをChatGPT APIを用いたSlack botに追加してみた。

Last updated at Posted at 2023-04-01

今回は、ChatGPT APIを用いたSlack botに画像生成AIのStable diffusionの機能を追加してみました。

製作するものとしては、SlackからChatGPTと話しながら、Stable diffusionで画像生成を出来る botです。

今回もGoogle Colabを使ってpythonでコードを書いています。

製作プロセスとしては、⒈Google colabでStable diffusionを使えるようにする、⒉ChatGPTを用いたSlack botにStable diffusionの機能を実装する、です。

⒈Google colabでStable diffusionを使えるようにする

まず、Google colabで新規ノートブックを作成して、上部のメニューから「ランタイム」を選択して、「ランタイムのタイプを変更」を押して、ハードウェア アクセラレータをGPUに変更して保存します。D6CF6852-219D-45DD-8F78-030C9C0A6B05.jpeg

次に、Stable diffusionを使えるようにコードを用意します。何故か、Stable diffusionのコードはChatGPTが書けないので、今回は、こちらのサイトのプロセスとコードを参考にしています。

はじめに、Hugging Faceのアカウントを作成して、ログインして、左のメニューから「Settings」を選択して、メニューが切り替わったら「Access Tokens」を押します。
開いたページで、New tokenを押して、Roleはreadでトークンを作成します。名前はなんでも良いです。
トークンを作成したら、コピーしてメモします。

ここまできたら、必要なインストールを行います。

!pip install torch diffusers transformers scipy ftfy

最後に、下記のコードをコピペして、先程取得したHugging Faceのトークンを入力して、全てのセルを実行します。
画像が生成されたら、⒈Google colabでStable diffusionを使えるようにするは完了です!

import torch
from torch import autocast
from diffusers import StableDiffusionPipeline

hugging_token = '<取得したトークン>'

ldm = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5",
                                              torch_dtype=torch.float32,
                                              use_auth_token=hugging_token
                                              ).to("cuda")

prompt = '<生成したい画像を表現した、文字列>'

# 5枚画像を作りたい場合
num_images = 5

i = 0  # 初期値を 0 とする

for j in range(num_images):
    with autocast("cuda"):
               image = ldm(prompt,
                    height=400,  # 縦サイズ(px)
                    width=400,  # 横サイズ(px)
                    guidance_scale=7.5,  # プロンプトの重み(生成画像の類似度(0〜20))
                    num_inference_steps=50,  # 画像生成に費やすステップ数
                    ).images[0]

    i += 1  # ループの最後で i をインクリメントする

    image.save(f"./image_{i}.png")

補足
⒈生成された画像は、左のメニューのファイル内に保存されます。上のメニューのファイルとは別です。セルを再度実行したり、ランタイムを更新すると生成した画像が消えてしまうので、注意してください。16848130-4215-4B09-A0B0-90DD316E7AC7.jpeg

⒉Stable diffusionのバージョンの変更には、コード内のrunwayml/stable-diffusion-v1-5を変更します。変更するには、Hugging Faceで使用したいバージョンを検索して、使用したいバージョンのページに行き、コードをコピーします。Stable Diffusion v2-1を使用する場合には、こちらのページからstabilityai/stable-diffusion-2-1をコピーしてコードを変更します。A900E15F-99B8-441F-ADE5-10D0EBED7BE6.jpeg

⒊画像のサイズの指定は縦も横も8の倍数にしてください。

⒉ChatGPTを用いたSlack botにStable diffusionの機能を実装する

まず、新規ノートブックを作成して、⒈の手順でGPUに設定を変更します。

次にSlack APIのスコープにfiles:writeを追加します。(ChatGPTを用いたSlack bot自体に必要なSlack APIの設定は、こちらを参照してください。)

スコープを設定したら、次はインストールです。
openai、 slack、Stable diffusionに必要なインストールを下記のように行います。

!pip install --upgrade pip
!pip install setuptools wheel
!pip install openai

!pip install slack-bolt

!pip install torch diffusers transformers scipy ftfy

インストール出来たら、openaiと slackに必要なインポートと、情報の入力などをします。

import openai
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
import os

#Bot User OAuth Token
os.environ["SLACK_BOT_TOKEN"] =  ""

#Signing Secret
os.environ["SLACK_SIGNING_SECRET"] = ""

#Token 
os.environ["SLACK_APP_TOKEN"] =  ""

#openaiの APIキー
openai_api_key = ""

app = App(
    token=os.environ.get("SLACK_BOT_TOKEN"),
    signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)

openai.api_key = openai_api_key

ここまで出来たら、Stable diffusionに関するコードを書きます。Hugging Faceのトークンも入力します。

import torch
from torch import autocast
from diffusers import StableDiffusionPipeline

hugging_token = '<取得したトークン>'

ldm = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5",
                                              torch_dtype=torch.float32,
                                              use_auth_token=hugging_token
                                              ).to("cuda")

次に botのコードを下記のように書きます。
この botでは、写真という言葉がある場合には、ChatGPTでユーザーの発言を処理して画像を生成して、ChatGPTのコメント付きでSlackからレスポンスしています。写真という言葉が含まれない場合には、普通に botと話せます。コメントと普通の会話には、assist1で一つ前の botの発言を記憶させているので、ある程度、文脈を維持するようにしています。

# botと話しながらプロンプトを作成して画像生成

assist1 = ""

@app.event("message")
def handle_message(event, say):
    global assist1
    if "写真" in event["text"]:
        text = event["text"]
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "以下を簡潔な英単語にして英単語のみ,区切りで答えてください。"},
                {"role": "user", "content": text},
            ]
        )
        assist2 = response["choices"][0]["message"]["content"]  

        prompt = f"{assist2},任意のプロンプト"

        with autocast("cuda"):
            image = ldm(prompt,
                        height=480,  # 縦サイズ(px)
                        width=640,  # 横サイズ(px)
                        guidance_scale=7.5,  # プロンプトの重み(生成画像の類似度(0〜20))
                        num_inference_steps=50,  # 画像生成に費やすステップ数
                        ).images[0]

        image.save(f"./image.png")

        # 写真のコメントを生成
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "写真を送付する際のメッセージを作成して下さい。設定:任意の設定"},
                {"role": "assistant", "content": assist1},
                {"role": "user", "content": text},
            ]
        )
        assist1 = response["choices"][0]["message"]["content"]  # assist1を更新

        # 画像を送信する
        try:
            image_path = "./image.png"  # 送信する画像のパスを指定する
            response = app.client.files_upload(
                channels=event["channel"],
                file=image_path,
                initial_comment= assist1
            )
            print(response)
        except Exception as e:
            print(f"Error: {e}")


    if "写真"  not in event["text"]:
        text = event["text"]
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "コメントと同じ設定"},
                {"role": "assistant", "content": assist1},
                {"role": "user", "content": text},
            ]
        )
        assist1 = response["choices"][0]["message"]["content"]  # assist1を更新
        say(assist1)

ここまで出来たら、下記のようにアプリを起動するコードを書き、全てのセルを実行します。

# 起動
if __name__ == "__main__":
    handler = SocketModeHandler(app,app_token=os.environ.get("SLACK_APP_TOKEN"))
    handler.start()

このプログラムは少し実行に時間がかかります。
アプリを起動するセルが実行された状態で botに話しかけて、以下のようなレスポンスがあれば、成功です!

写真という言葉有りF9682F4E-01CB-472C-9495-7276207C1109.jpeg

写真という言葉無しCE2AA0F4-890D-4886-AE37-9CB558FCB925.jpeg

最後に

私がAIにハマるきっかけになったStable diffusionを活用した botを作成出来て感慨深いです。
今回作成した botでは、画像の質を高めている関係ですぐGoogle colabが落ちてしまうので、少し改良が必要です。
また何か作ってみます。

2
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6