SnowflakeコンテナでStable Diffusion WebUIを起動させてみた

Snowflakeコンテナ=Snowpark Container ServicesでGPU付きのコンテナが動かせるということで、AI画像生成ツールのStable Diffusion WebUI(AUTOMATIC1111版)が動作できるのか検証してみた。

結果としては、普通に動いて結構早いのでいちいちEC2インスタンスを立ち上げたりする必要がないのでStable Diffusionの運用的には楽だと思う

しかし、Snowpark Container Servicesのコンピュートリソースの幅がでかいのでコストに注意かもしれない

ちょっと事前準備としてコンテナイメージをどこかで作らないといけないのが面倒なのだが、

目次

流れ

稼働させるまでの流れは以下の通り

  • どこかでコンテナイメージを作成
  • SnowflakeコンテナレジストリにPUSH
  • Volumeマウントして画像保存やプラグインなどを保存できるエリアを作成
  • レジストリ上のイメージやVolumeをマウントしてコンテナ起動
  • URLが生成されるのでアクセス
  • AI画像生成

という流れになる

Stable Diffusion WebUIのコンテナイメージを作成

EC2インスタンスを作る

今回はEC2インスタンス上にStable Diffusion WebUI(AUTOMATIC1111版)のコンテナイメージを作成する

EC2インスタンスにGPUやNVIDIA Toolkitなどは必要ない(動かさないので)

コンテナイメージを作る際にいろいろダウンロードしたりするので、ある程度パワーのあるインスタンスの方がよい

ストレージも8Gでは全く足りないので、30Gくらいあるとよい。コンテナイメージは9Gくらいになる

Gitをインストールする:詳細はこちら

docker compose v2をインストールする:詳細はこちら

Stable Diffusion WebUIのコンテナイメージを取得してビルド

Stable Diffusion WebUIのコンテナイメージを取得してビルドする

https://github.com/AbdBarho/stable-diffusion-webui-docker/wiki/Setup

sudo git clone https://github.com/AbdBarho/stable-diffusion-webui-docker

ビルドする、CRUDのメッセージがいろいろ出るが無視でよい

cd ./stable-diffusion-webui-docker/
sudo docker compose --profile download up --build

Dockerコンテナ自体は立ち上げる必要ないのでUPではなくBUILDでよい
*SnowflakeのガイドではBUILDの際に–platform linux/amd64をつける必要があると書いてあったがなくても動作した

sudo docker compose --profile auto build

ビルドが完成したら、確認

sudo docker image list

sd-autoができているはず、TAGはweb uiのバージョンによって異なると思うが、TAGも覚えておくこと

Snowflakeコンテナレジストリを作成

ロール・DB・Warehouseなどを作成してGRANT

コンテナサービスを起動させる際、AccountAdminでの起動は禁止されているので、個別ロールを作成し、権限を付与していく

USE ROLE ACCOUNTADMIN;
CREATE ROLE test_role;
GRANT ROLE test_role TO USER masayaFCTO;
CREATE DATABASE stable_diffusion_db;
GRANT OWNERSHIP ON DATABASE stable_diffusion_db TO ROLE test_role COPY CURRENT GRANTS;

CREATE OR REPLACE WAREHOUSE stable_diffusion_warehouse WITH
  WAREHOUSE_SIZE='X-SMALL';
GRANT USAGE ON WAREHOUSE stable_diffusion_warehouse TO ROLE test_role;

GRANT BIND SERVICE ENDPOINT ON ACCOUNT TO ROLE test_role;

COMPUTE POOLを作成

コンテナを起動させるためのCOMPUTE POOLを作成する、GPUを使用したいので「GPU_NV_S」を指定

選択できるインスタンス一覧はこちら

CREATE COMPUTE POOL stable_diffusion_pool
  MIN_NODES = 1
  MAX_NODES = 1
  INSTANCE_FAMILY = GPU_NV_S;
GRANT USAGE, MONITOR ON COMPUTE POOL stable_diffusion_pool TO ROLE test_role;

//確認
SHOW COMPUTE POOLS; 
DESCRIBE COMPUTE POOL stable_diffusion_pool;

OAUTH INTEGRATIONを作成

起動したコンテナにログインするためにOAUTH INTEGRATIONを作成する

CREATE SECURITY INTEGRATION IF NOT EXISTS snowservices_ingress_oauth
  TYPE=oauth
  OAUTH_CLIENT=snowservices_ingress
  ENABLED=true;

EXTERNAL ACCESS INTEGRATIONを作成

コンテナから外部にアクセスを許可するルールを作成、本来は0.0.0.0という全部開ける必要はないのだが、どの通信を開けるべきか時間がかかりそうだったので全開けしている

CREATE NETWORK RULE allow_all_rule
  TYPE = HOST_PORT
  MODE= EGRESS
  VALUE_LIST = ('0.0.0.0:443','0.0.0.0:80')
;

CREATE EXTERNAL ACCESS INTEGRATION external_access_integration_sd
  ALLOWED_NETWORK_RULES = (
    allow_all_rule
    )
  ENABLED = true
;

GRANT USAGE ON INTEGRATION external_access_integration_sd TO ROLE test_role;

コンテナレジストリを作成

Snowflakeでコンテナイメージを保管するスキーマとコンテナレジストリを作成する

USE ROLE TEST_ROLE;
USE WAREHOUSE stable_diffusion_warehouse;
CREATE SCHEMA IF NOT EXISTS data_schema;

CREATE IMAGE REPOSITORY IF NOT EXISTS stable_diffusion_repository;

コンテナレジストリのURLを取得

コンテナレジストリのURLを取得する

SHOW IMAGE REPOSITORIES;

SnowflakeコンテナレジストリにPUSH

docker login

EC2インスタンスに戻り、先ほど作成したDocker ImageをSnowflakeレジストリにPUSHするためにdocker loginでログインする

*registry_hostnameは「<orgname>-<acctname>.registry.snowflakecomputing.com」になる。
*ユーザ名はSnowflakeにログインするユーザ名

sudo docker login <registry_hostname> -u <username>

docker tag

先ほど作成したDocker ImageをSnowflakeレポジトリにTAG付けする
*versionはlatestとしている
*registry_urlは先ほど「SHOW IMAGE REPOSITORIES;」で出力したURLになる。

sudo docker tag sd-auto:72 <repository_url>/sd-auto:latest

docker push

TAG付けしたDocker ImageをPUSH

sudo docker push <repository_url>/sd-auto:latest

9Gのイメージ転送になるので結構時間がかかる

Volumeマウントして画像保存やプラグインなどを保存できる内部ステージを作成

Volumeマウント用の内部ステージ作成

Snowflakeコンテナサービスではコンテナを再起動・終了させるとコンテナ上のデータが全て消えるので、AIモデルやプラグイン・完成した画像などは消えない領域に保管しておきたいので、コンテナからVolumeマウントさせる領域を作成する

Stable Diffusion WebUI(AUTOMATIC1111版)ではDATAとOUTPUTという二つの領域をマウントしているのでそれに則って、二つの内部ステージを作成する

内部ステージはDIRECTORY=TRUE、ENCRYPTION=SNOWFLAKE_SSEとしておく

CREATE STAGE IF NOT EXISTS stable_diffusion_models
  DIRECTORY = ( ENABLE = true )
  ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE');//DATA用
CREATE STAGE IF NOT EXISTS stable_diffusion_output
  DIRECTORY = ( ENABLE = true )
  ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE');//OUTPUT用

レジストリ上のイメージやVolumeをマウントしてコンテナ起動

SERVICEの作成と注意諸々

レジストリのイメージやらVolumeマウントやらを指定してSERVICEをCREATEして起動させる

重要:GPUを利用しないと画像生成時にエラーになるので、resourcesにGPUを指定しておくこと

起動OPTIONはenvの配下のCLI_ARGSでコンテナのオプションを渡せる外部プラグインをインストールしたいなら「–enable-insecure-extension-access」をつけておく

CREATE SERVICE df_service
  IN COMPUTE POOL stable_diffusion_pool
  FROM SPECIFICATION $$
    spec:
      containers:
      - name: df
        image: /stable_diffusion_db/data_schema/stable_diffusion_repository/sd-auto:latest
        resources:
          requests:
            memory: 2G
            cpu: 0.5
            nvidia.com/gpu: 1
          limits:
            memory: 32G
            nvidia.com/gpu: 1
        env:
          SERVER_PORT: 7860
          CLI_ARGS: "--allow-code --medvram --xformers --enable-insecure-extension-access --api --no-half --precision full --no-half-vae"
        volumeMounts:
        - name: sd-models
          mountPath: ./data
        - name: sd-output
          mountPath: ./output
      endpoints:
      - name: dfendpoint
        port: 7860
        public: true
      volumes:
      - name: sd-models
        source: "@stable_diffusion_models"
        uid: 1000
        gid: 1000
      - name: sd-output
        source: "@stable_diffusion_output"
        uid: 1000
        gid: 1000
      $$
   EXTERNAL_ACCESS_INTEGRATIONS = (EXTERNAL_ACCESS_INTEGRATION_SD)
   MIN_INSTANCES=1
   MAX_INSTANCES=1
;

GET_SERVICE_STATUS

起動するまでに結構時間がかかるので、ステータス確認コマンドでチェックする

CALL SYSTEM$GET_SERVICE_STATUS('stable_diffusion_db.data_schema.df_service');

PENDINGの場合は、まだアクセスできない。READYになるとアクセス可能となる

Stable Diffusion WebUIにアクセス

アクセス用URLを表示させてアクセス

SHOW ENDPOINTS IN SERVICE df_service;

ちゃんと起動している

モデルなどが保管されているか確認

先ほどDATA Volumeとしてマウントした内部ステージには色々とデータが入ってる、コンテナが起動した際に色々ダウンロードしているようす

あとはモデルをここの「STABLE_DIFFUSION_MODELS/models/Stable-diffusion」に入れればよいが、大きいファイルはWebUIからアップロードできないので、「sd-civitai-browser」プラグインをインストールすると楽

https://github.com/Vetchems/sd-civitai-browser

プラグインの保存先も内部ステージになっているのでWebUIを再起動しても消えない

ようやく生成

あとは好きなモデルをcivitaiからダウンロードして使うと完成!モデルはManiamixを利用している

GPU_NV_Sでの512 x 512の生成で2秒くらいで生成できた、結構早い

Positive

(((masterpiece))), (((best quality))), ((ultra-detailed)), (illustration), (1 girl), (solo), ((an extremely delicate and beautiful)), little girl, ((beautiful detailed sky)), beautiful detailed eyes, side blunt bangs, hairs between eyes, ribbons, bowties, buttons, bare shoulders, (small breast), blank stare, pleated skirt, close to viewer, ((breeze)), Flying splashes,  Flying petals, wind

Negative

nsfw, lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, missing fingers,  bad hands, missing arms, long neck, Humpbacked, shadow, nude

画像を保存したい場合は、保存ボタンをクリックすると内部ステージのOUTPUTに保管される

OUTPUT内部ステージに画像保存とダウンロード

後でダウンロードしたい場合はSnowflakeのWebUIの内部ステージからダウンロードできる

片付け:重要

使い終わったらSnowflake上でSERVICEを終了しておくこと、放っておいてもSUSPENDにならないので終了させておく

DROP SERVICE df_service;

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です