今回は、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に変更して保存します。
次に、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")
補足
⒈生成された画像は、左のメニューのファイル内に保存されます。上のメニューのファイルとは別です。セルを再度実行したり、ランタイムを更新すると生成した画像が消えてしまうので、注意してください。
⒉Stable diffusionのバージョンの変更には、コード内のrunwayml/stable-diffusion-v1-5を変更します。変更するには、Hugging Faceで使用したいバージョンを検索して、使用したいバージョンのページに行き、コードをコピーします。Stable Diffusion v2-1を使用する場合には、こちらのページからstabilityai/stable-diffusion-2-1をコピーしてコードを変更します。
⒊画像のサイズの指定は縦も横も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に話しかけて、以下のようなレスポンスがあれば、成功です!
最後に
私がAIにハマるきっかけになったStable diffusionを活用した botを作成出来て感慨深いです。
今回作成した botでは、画像の質を高めている関係ですぐGoogle colabが落ちてしまうので、少し改良が必要です。
また何か作ってみます。