stylesheet

2023-05-28

diffusers の使い方を調べてGoogle Colab ノートブックファイルを作った

概要: この記事では、Google Colabのフリー版におけるAUTOMATIC1111版WebUIの制限について取り上げ、その代替手段としてHugging Faceのdiffusersを使用する方法について調査します。

最近、Google Colabのフリー版での利用制限が行われ、AUTOMATIC1111版WebUIの使用が禁止されました。さらに悪いことに、この制限はRemoteUI全体に広がっているようです。
この制限によって、以前は簡単にアクセスできていたWebユーザーインターフェース(WebUI)を使用することができなくなりました。AUTOMATIC1111版WebUIは、使いやすく便利なユーザーインターフェースでしたが、これからは別の方法を探さなければなりませんでした。

代替の手段を模索する必要がありました。
その結果、UIを持たないHugging Faceのdiffusersを利用することに決めました。diffusersは、モデルの推論や処理を行うためのPythonライブラリであり、UIを必要としないため、制限を受けずに利用することができます。これは私たちのニーズに合致していると考え、積極的に取り入れることにしました。

diffusersの使い方について詳しく調査しました。Hugging Faceの公式ドキュメンテーションやコミュニティのフォーラムなど、さまざまな情報源を活用しました。

※以下の情報は、diffusers v0.16.1に基づいて記載されています。今後の仕様変更によって、一部または全てが動作しなくなる可能性があります。

safetensor

safetensors形式のモデルのロードは専用の関数が用意されています。 この関数の処理は外部ライブラリに依存しています。pip install safetensorsとしてsafetensorsモジュールをインストールする必要があります。

from diffusers.pipelines.stable_diffusion.convert_from_ckpt import download_from_original_stable_diffusion_ckpt
pipe = download_from_original_stable_diffusion_ckpt(
    checkpoint_path='super_sexy_mix.safetensors',
    from_safetensors=True
)

読み込んだ後は、from_pretrainedで直接読み込める形式に変換して保存しておくことを推奨します。

pipe.save_pretrained('super_sexy_mix')

vae

任意のVAEへ取り替えることができます。

from diffusers.models import AutoencoderKL
from diffusers import StableDiffusionPipeline

pipe = StableDiffusionPipeline.from_pretrained('stabilityai/stable-diffusion-2-1')
pipe.vae = AutoencoderKL.from_pretrained('stabilityai/sd-vae-ft-ema')

AUTOMATIC1111用のpt形式のファイルは、事前にdiffusers形式に変換することで読み込むことができます。diffusersレポジトリscripts/convert_vae_pt_to_diffusers.py を使用してください。

lora

LoRaの追加方法です。

from diffusers import StableDiffusionPipeline

pipe = StableDiffusionPipeline.from_pretrained('stabilityai/stable-diffusion-2-1')
pipe.unet.load_attn_procs('sayakpaul/sd-model-finetuned-lora-t4')

load_attn_procs.safetensors形式を扱えるように見えましたが、v0.16.1ではエラーが発生してうまく動作しませんでした。 かわりにissueで紹介されていたこちらのgistコードがうまく機能しました。こちらはLoRa読み込み時のウェイト指定にも対応しています。

impot kohya_lora_loader

kohya_lora_loader.install_lora_hook(pipe)
lora1 = pipe.apply_lora('lora1.safetensors', 1.0)

Textual Inversion (embeddings)

Textual Inversionの追加も行えます。

pipe.load_textual_inversion("sd-concepts-library/cat-toy")
image = pipe('A <cat-toy> backpack', num_inference_steps=50).images[0]

pt形式やsafetensors形式のファイルは先にダウンロードしてから読み込むとうまくいきます。

pipe.load_textual_inversion('embeddings/EasyNegativeV2.safetensors')
image = pipe('A <cat-toy> backpack', negative_prompt='EasyNegativeV2', num_inference_steps=50).images[0]

seed

シード値の固定はどうでしょうか。torch.Generatorを作成して行うようです。

import torch
generator = torch.Generator('cuda').manual_seed(12345678)
image = pip('Those mobile suits are mass-produced cheap ones.', generator=generator)

hires.fix

AUTOMATIC1111の独自機能なのでdiffusersには存在しませんが、txt2img -> 画像拡大 -> img2img と連続で実行することで、同等の機能を実装できます。

import torch
from diffusers import StableDiffusionPipeline, StableDiffusionImg2ImgPipeline

prompt = 'High quality kitty flying over the stratosphere'
generator = torch.Generator('cuda').manual_seed(12345678)

pipe = StableDiffusionPipeline.from_pretrained(
    'stabilityai/stable-diffusion-2-1',
    torch_dtype=torch.float16,
)
image = pipe(
    prompt=prompt, generator=generator,
    width=512, height=512
)[0]

image = image.resize((1024, 1024))

img2img = StableDiffusionImg2ImgPipeline.from_pretrained(
    'stabilityai/stable-diffusion-2-1',
    torch_dtype=torch.float16,
)
image = img2img(
    prompt=prompt, generator=generator
)[0]

safety_checker

NSFW(Not Safe For Work)画像の検閲フィルターを無効化する方法です。黒塗りの画像が出力されるのは、この機能が原因です。 散々待たされた挙げ句に、完成した画像が真っ黒だったとき。こんなつらい思いをするのは私たちだけで十分なはずです。

import torch
from diffusers import StableDiffusionPipeline

pipe = StableDiffusionPipeline.from_pretrained(
    'stabilityai/stable-diffusion-2-1',
    torch_dtype=torch.float16,
    require_safety_checker=False,
    safety_checker=None,
    feature_extractor=None
)
image = pipe(prompt='naked tribe, women')[0]

パイプライン生成時に以下の値を渡すと無効化できます。

  • require_safety_checker=False
  • safety_checker=None
  • feature_extractor=None

もしくは、単純にpipe.safety_checkerの上書きでも可能なようです。

pipe.safety_checker = lambda images, **kwargs: (images, False)

png info

希望するイメージの画像が出力されるまで何度も繰り返し画像生成を行うことも多いため、画像の管理が大変です。 AUTOMATIC1111のようにプロンプトの内容をメタデータとして埋め込みたいと思いました。 以下のコードが示すように、parametersをキーとしてプロンプトを含む文字列を埋め込むと良いようです。

from PIL import PngImagePlugin

parameters = '''masterpiece, best quality, super detailed skin, 8k, High quality kitty flying over the stratosphere
Negative prompt: EasyNegative
Steps: 20, Sampler: DPM++ 2M Karras, CFG scale: 7, Seed: 3563618074, Size: 512x512, Model hash: 5a93b45622, Model: CounterfeitV30_v30, Clip skip: 2, Version: v1.2.1'''
pi = PngImagePlugin.PngInfo()
pi.add_text('parameters', parameters)

image.save('', pnginfo=pi)

調査の結果、私たちはdiffusersを使ったノートブックの作成に取り掛かりました。diffusersを活用することで、画像生成のタスクを簡単に実行することができます。私たちはモデルの選択やTextual Inversionの読み込みなど、さまざまなタスクをカバーするノートブックを作成しました。

AUTOMATIC1111版WebUIの制限により、私たちは新たな解決策を見つけ、Hugging Faceのdiffusersを代替手段として採用しました。これにより、制約なくモデルを実行し、機械学習タスクに取り組むことができます。diffusersの使用方法についての情報は公式ドキュメンテーションをご参照いただくか、私たちの作成したノートブックを確認してください。

それでは、AUTOMATIC1111版WebUIの代替としてのdiffusersの活用により、皆さんの画像生成AIの研究やプロジェクトがより円滑に進むことを願っています。順調な作業をお祈り申し上げます。

作成したノートブックはこちらより参照できます。

尚、この文章はChatGPTとの共同執筆です。

参照