見出し画像

画像生成モデルのLCMを使ってSlackのコマンドから高速に画像生成を行う


はじめに

この記事は Colorful Palette アドベントカレンダー 12/17 の記事です。

株式会社Colorful Paletteにて、クライアントエンジニアをしている ようさん です。

今回は、最近話題になっている生成AIの技術の中でも高速に生成できることで注目されている 「Latent Consistency Models」通称LCMと呼ばれる数ステップで画像生成ができる画像生成モデルを使って、チャットツール「Slack」に画像生成コマンドの実装の技術検証を行いましたので紹介させていただきます。

画像生成AIについて

画像生成AIは、OpenAI社が出しているDALL-E-3やStability AI社が出しているStable Diffusionなどがあります。

DALL-E-3で生成された画像

LCMとは

今までの画像生成では、画像生成を行う処理で数十ステップの処理を行うことが通常でした。
LCMを用いることで、ずっと少ないステップで高品質な画像を素早く生成することができるようになりました。

LCMモデル

LCMが使えるマージモデルとして、以下の「SimianLuo/LCM_Dreamshaper_v7」があります。
今回はこちらのモデルを使用して画像生成を試していきます。

LCMを使ってテキストから画像を生成

LCMを使用したモデルは、diffusersを使って画像生成ができるため、モデルのダウンロードおよびロードを行った後に pipeにしてプロンプトを指定して画像を生成します。

from diffusers import DiffusionPipeline
import torch

pipe = DiffusionPipeline.from_pretrained("SimianLuo/LCM_Dreamshaper_v7").to(torch_device="cuda",
                                                                                torch_dtype=torch.float16)
# 画像を生成
image = pipe(prompt=prompt, width=512, height=512, num_inference_steps=6, guidance_scale=8, lcm_origin_steps=50, output_type="pil").images[0]

GPUサーバーレスで処理を行う

GPUサーバーを検討

画像生成を行うためには、処理速度を考慮して通常は、GPUで処理を行う必要があります。
クラウドでGPUが使えるサービスは以下のようなものがあります。

今回は比較的手軽に使えるModalを使用していきます。

Modalで画像生成APIを作成

Modalを使って画像生成を行う際は、以下の流れで処理を書いていきます。

  1. ベースのDocker Imageに必要なライブラリをインストールする

  2. Hugging Face(*1)のsecret keyを取得できるようにkeyを取得する

  3. 使用するGPUを指定する(*2)

  4. timeoutを指定する

  5. diffusersのpipeでモデルのロードを行う

  6. pipeで指定したモデルに対して画像生成を行う

  7. Slack SDKを使用して画像をSlack側に送信する

(*1)
Hugging Faceとは、主に機械学習分野でモデル・データセット・アプリケーションを共有および共同開発ができるプラットフォームです

(*2)
Modalでは、任意のGPUを指定することができます。詳細は以下をご参照ください。

上記の流れで作成したModal上に作成する画像生成のAPIコードは、以下のようになります。

from modal import Stub, web_endpoint
import modal

stub = Stub("generate_image")


@stub.function(
    image=modal.Image.debian_slim().pip_install("transformers", "torch", "diffusers==0.24.0", "requests", "accelerate",
                                                "slack_sdk"),
    secret=modal.Secret.from_name("HUGGINGFACE_KEY"),
    gpu="t4",
    timeout=1000)
@web_endpoint()
def run_diffusion(prompt: str, token: str, channel_id: str, num_images: int):
    from diffusers import DiffusionPipeline
    import torch
        from slack_sdk import WebClient

    pipe = DiffusionPipeline.from_pretrained("SimianLuo/LCM_Dreamshaper_v7").to(torch_device="cuda",
                                                                                torch_dtype=torch.float16)

    # 保存した画像のパスを格納するためのリスト
    saved_images_paths = []

    for i in range(num_images):
        # 画像を生成
        image = pipe(prompt=prompt, width=512, height=512, num_inference_steps=6, guidance_scale=8, lcm_origin_steps=50,
                     output_type="pil").images[0]

        # 保存する画像のファイル名を設定
        file_name = f"image_{i + 1}.png"
        # 画像をPNG形式でバイトIOオブジェクトに保存
        image.save(file_name, format="PNG")
        # 保存した画像のパスをリストに追加
        saved_images_paths.append(file_name)
        print(f"saved image: {file_name}")

    

    client = WebClient(token=token)

    for image in saved_images_paths:
        try:
            client.files_upload_v2(
                channel=channel_id,
                file=image,
                title=f"{prompt}",
                initial_comment=f"{prompt}の画像を生成しました!",
            )
        except Exception as e:
            print(f"Error posting message: {e}")

ModalのAPIをデプロイ

Modalに上記で作成したAPIをデプロイして、SlackからAPIを叩けるようにします。
ファイル名を generate_image.pyとしたときに、デプロイは以下のコマンドで行うことができます。

modal deploy generate_image.py

Slackのコマンドについて

SlackのSlash Commandsは Features → Slash Commandsから追加することができます。

以下の画像のようにコマンドの設定を行います。この時のRequest URLは、Modalにデプロイした時に発行されるAPIのURLになります。

Slackからテキストを入力して画像生成を行う

今回は、「夜に海にいる猫」を生成します。
以下のようにSlackのメッセージ欄に以下のようなプロンプトを入力します。

画像生成されるまで少し待つと以下のような画像が生成してSlack上に表示されました!

おわりに

生成AI技術は日々発展しています。LCMもまだ出てきてからあまり時間が経っていないため、記事の内容がどのようなことができるのか・どのような使い方ができるのかの一例になれば幸いです。

他にも色々な使い方があると思いますので、面白いことやワクワクしたことに活用できれば楽しそうです!

最後まで見ていただきありがとうございました!