前回の記事で、Compel を使って重み付けをしました。
この記事では Compel の他の機能で遊んでみようと思います。
Blending
まずは、前回の記事同様、パイプライン及びスケジューラーを準備します
!pip install -U diffusers["torch"] transformers compel
import torch from diffusers import StableDiffusionPipeline, UniPCMultistepScheduler pipe = StableDiffusionPipeline.from_pretrained( "CompVis/stable-diffusion-v1-4", use_safetensors=True ) pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config) pipe.to("cuda")
次に Compel を使って Blending を行います
from compel import Compel compel_proc = Compel(tokenizer=pipe.tokenizer, text_encoder=pipe.text_encoder) prompt_embeds = compel_proc('("a red cat playing with a ball", "jungle").blend(0.7, 0.8)') generator = torch.Generator(device="cuda").manual_seed(33) image = pipe(prompt_embeds=prompt_embeds, generator=generator, num_inference_steps=20).images[0] image
今のところ一番可愛いと思います。この猫
文字列でメソッド呼び出しみたいなことを書いているのでなんとなく気持ち悪いです。。。
.blend() を使うところがポイントですね
jungle の部分を sea
に変えて、ブレンドパラメータを調整してみました
from compel import Compel from diffusers.utils import make_image_grid compel_proc = Compel(tokenizer=pipe.tokenizer, text_encoder=pipe.text_encoder) prompt_embeds = compel_proc('("a red cat playing with a ball", "sea").blend(0.8, 0.7)') image = pipe( "a red cat playing with a ball, sea", generator=torch.Generator(device="cuda").manual_seed(33), num_inference_steps=20 ).images[0] comple_image = pipe( prompt_embeds=prompt_embeds, generator=torch.Generator(device="cuda").manual_seed(33), num_inference_steps=20 ).images[0] make_image_grid([image, comple_image], rows=1, cols=2)
Conjunction
Conjunction
の意味を調べたら 接続詞 でした!
prompt_embeds = compel_proc('["a red cat", "playing with a", "ball"].and()') generator = torch.Generator(device="cuda").manual_seed(55) image = pipe(prompt_embeds=prompt_embeds, generator=generator, num_inference_steps=20).images[0] image
Conjunction では .and() がポイントのようです
以下を試してみましたが、ドキュメント通りには行かずでした
・torch.Generator(device="cuda").manual_seed(33)
・torch.Generator(device="cpu").manual_seed(55)
・torch.Generator(device="cpu").manual_seed(33)
・torch.Generator(device="cuda").manual_seed(33)
・torch.Generator(device="cpu").manual_seed(55)
・torch.Generator(device="cpu").manual_seed(33)
Textual inversion
import torch from diffusers import StableDiffusionPipeline from compel import Compel, DiffusersTextualInversionManager # パイプラインの準備 pipe = StableDiffusionPipeline.from_pretrained( "runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16, use_safetensors=True, variant="fp16" ).to("cuda") # Textual inversion pipe.load_textual_inversion("sd-concepts-library/midjourney-style") # Compel の準備 textual_inversion_manager = DiffusersTextualInversionManager(pipe) compel_proc = Compel( tokenizer=pipe.tokenizer, text_encoder=pipe.text_encoder, textual_inversion_manager=textual_inversion_manager ) prompt_embeds = compel_proc('("A red cat++ playing with a ball <midjourney-style>")') image = pipe(prompt_embeds=prompt_embeds).images[0] image
シードを設定していないので同じ画像にならないのヨシとして、
同じ雰囲気の画像が出ていますね!
DreamBooth
import torch from diffusers import DiffusionPipeline, UniPCMultistepScheduler from compel import Compel # パイプラインの準備 pipe = DiffusionPipeline.from_pretrained( "sd-dreambooth-library/dndcoverart-v1", torch_dtype=torch.float16 ).to("cuda") pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config) # Compel の準備 compel_proc = Compel(tokenizer=pipe.tokenizer, text_encoder=pipe.text_encoder) prompt_embeds = compel_proc('("magazine cover of a dndcoverart dragon, high quality, intricate details, larry elmore art style").and()') image = pipe(prompt_embeds=prompt_embeds).images[0] image
Stable Diffusion XL
# -------------------------------------------------- # Stable Diffusion XL # -------------------------------------------------- from compel import Compel, ReturnedEmbeddingsType from diffusers import DiffusionPipeline from diffusers.utils import make_image_grid import torch # パイプラインの準備 pipeline = DiffusionPipeline.from_pretrained( "stabilityai/stable-diffusion-xl-base-1.0", variant="fp16", use_safetensors=True, torch_dtype=torch.float16 ).to("cuda") # Compel の準備 compel_proc = Compel( tokenizer=[pipeline.tokenizer, pipeline.tokenizer_2] , text_encoder=[pipeline.text_encoder, pipeline.text_encoder_2], returned_embeddings_type=ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED, requires_pooled=[False, True] ) # apply weights prompt = ["a red cat playing with a (ball)1.5", "a red cat playing with a (ball)0.6"] conditioning, pooled = compel_proc(prompt) # generate image generator = [torch.Generator().manual_seed(33) for _ in range(len(prompt))] images = pipeline(prompt_embeds=conditioning, pooled_prompt_embeds=pooled, generator=generator, num_inference_steps=30).images make_image_grid(images, rows=1, cols=2)
こちらはバッチリ出力されました!
まとめ
物によって Compel インスタンスを生成する際の引数が異なっていたり、
実際の Prompt の渡し方が異なっていたり、
それぞれ使い方が異なっていました!
DreamBooth も派生モデルなのかな?と思って触ってましたが、
既存のモデルに数枚の画像を喰わせてファインチューニングできるもの?なんですかね?
ちゃんと使えるようになったら面白そうだと思いました。
LoRA との違いも謎ですが!!LoRA も自分で作れたら楽しそうです!!