さて、この記事では diffusers v0.6.0 を参考に Inpainting を使ってみます。 公式ドキュメント にも Inpainting のページがありますが、今回は v0.6.0 当時のリリースノートを読みながら進めます。更に Inpainting は ControlNet にもあるようですが、今回は v0.6.0 当時のリリースノートを読みながら進めます
前回は v0.7.0 の Long Prompt Weighting Stable Diffusion を使い、それよりも前は LoRA を使って遊び、そして v0.6.0 に戻ってくるという時系列的にはグチャグチャです。
何もわからないところから始めているのである程度よく使われているネットに転がっているキーワードから調べている感じですね。少しずつ理解が深まっているのか、ちゃんと公式ドキュメントを読んだり、リリースノートを見てみたりするようになりました。
- Inpainting とは?
- StableDiffusionInpaintPipeline を使ってみる
- AutoPipeline 版を使ってみる
- AutoPipelineForInpainting は何をしているのか?
- まとめ
Inpainting とは?
Inpainting は 修正したい画像 と 修正したい箇所(マスク画像) を用意して、Image-to-Image の要領で実行します
StableDiffusionInpaintPipeline を使ってみる
ドキュメント では AutoPipelineForInpainting
を使用していますが、まずは v0.6.0 の StableDiffusionInpaintPipeline
を使ってみます。きっと AutoPipeline
を使っても内部では StableDiffusionInpaintPipeline
を使っているのではないでしょうか?後で調べてみようと思います。
from diffusers.utils import load_image init_image_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo.png" mask_image_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo_mask.png" init_image = load_image(init_image_url ) mask_image = load_image(mask_image_url ) print(init_image.size) print(mask_image.size)
diffusers v0.6.0 を見ると、自分で download_image
のメソッドを用意していますが、今は utils
に load_image
があるのでそれを使わせてもらいましょう。更に resize((512, 512))
を実行していますが、確認してみたところ最初から 512x512 でした。resize しなくていいか!
あとは Pipeline を用意して実行です。
import torch from diffusers import StableDiffusionInpaintPipeline pipe = StableDiffusionInpaintPipeline.from_pretrained( "runwayml/stable-diffusion-inpainting", revision="fp16", torch_dtype=torch.float16, ).to("cuda") prompt = "Face of a yellow cat, high resolution, sitting on a park bench" image = pipe( prompt=prompt, image=init_image, mask_image=mask_image, generator=torch.Generator(device="cuda").manual_seed(67280421310721), ).images[0]
なかなか良き感じですね!
AutoPipeline 版を使ってみる
import torch from diffusers import AutoPipelineForInpainting pipe = AutoPipelineForInpainting.from_pretrained( "runwayml/stable-diffusion-inpainting", revision="fp16", torch_dtype=torch.float16, ).to("cuda") prompt = "Face of a yellow cat, high resolution, sitting on a park bench" image = pipe( prompt=prompt, image=init_image, mask_image=mask_image, generator=torch.Generator(device="cuda").manual_seed(67280421310721), ).images[0]
コードとしては、 StableDiffusionInpaintPipeline
を AutoPipelineForInpainting
に変えただけです。
Seed を固定しているので、全く同じものが生成されました。
AutoPipelineForInpainting は何をしているのか?
AutoPipelineForInpainting の from_pretrained()
の内部では、
inpainting_cls.from_pretrained()
を使っていそうです。inpainting_cls
インスタンスは _get_task_class()
から得ていますが、 こちらのマッピング定数 から選んでいるように見えますので、きっと同じものが使われているのでしょう!
まとめ
Inpainting も簡単に使えました!