Diffusers documentation

Inpainting

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.42.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Inpainting

Inpainting mengganti atau mengedit area tertentu pada gambar. Hal ini menjadikannya alat yang berguna untuk pemulihan gambar seperti menghilangkan cacat dan artefak, atau bahkan mengganti area gambar dengan sesuatu yang sepenuhnya baru. Inpainting bergantung pada mask untuk menentukan wilayah mana dari gambar yang akan diisi; area yang akan di-inpaint direpresentasikan oleh piksel putih dan area yang akan dipertahankan direpresentasikan oleh piksel hitam. Piksel putih diisi oleh prompt.

Dengan 🤗 Diffusers, berikut cara Anda melakukan inpainting:

  1. Muat checkpoint inpainting dengan kelas AutoPipelineForInpainting. Kelas ini akan secara otomatis mendeteksi kelas pipeline yang tepat untuk dimuat berdasarkan checkpoint:
import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "kandinsky-community/kandinsky-2-2-decoder-inpaint", dtype=torch.float16
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

Sepanjang panduan ini, Anda akan melihat kami menggunakan enable_model_cpu_offload() dan enable_xformers_memory_efficient_attention() untuk menghemat memori dan meningkatkan kecepatan inferensi. Jika Anda menggunakan PyTorch 2.0, tidak perlu memanggil enable_xformers_memory_efficient_attention() pada pipeline Anda karena pipeline tersebut sudah menggunakan scaled-dot product attention bawaan dari PyTorch 2.0.

  1. Muat gambar dasar dan mask:
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")
  1. Buat prompt untuk inpaint gambar dan teruskan ke pipeline dengan gambar dasar dan mask:
prompt = "a black cat with glowing eyes, cute, adorable, disney, pixar, highly detailed, 8k"
negative_prompt = "bad anatomy, deformed, ugly, disfigured"
image = pipeline(prompt=prompt, negative_prompt=negative_prompt, image=init_image, mask_image=mask_image).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)
base image
mask gambar
gambar yang dihasilkan

Buat gambar mask

Sepanjang panduan ini, gambar mask disediakan di semua contoh kode untuk kemudahan. Anda dapat melakukan inpainting pada gambar Anda sendiri, tetapi Anda perlu membuat gambar mask untuknya. Gunakan Space di bawah ini untuk dengan mudah membuat gambar mask.

Unggah gambar dasar untuk di-inpaint dan gunakan alat sketsa untuk menggambar mask. Setelah selesai, klik Run untuk menghasilkan dan mengunduh gambar mask.

Mask blur

Metode blur() menyediakan opsi untuk cara mencampurkan gambar asli dan area inpaint. Jumlah blur ditentukan oleh parameter blur_factor. Meningkatkan blur_factor akan meningkatkan jumlah blur yang diterapkan pada tepi mask, sehingga memperhalus transisi antara gambar asli dan area inpaint. Nilai blur_factor yang rendah atau nol akan mempertahankan tepi mask yang lebih tajam.

Untuk menggunakannya, buat maska blur dengan image processor.

import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image
from PIL import Image

pipeline = AutoPipelineForInpainting.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16).to('cuda')  # or "mps", "xpu", "cpu"

mask = load_image("https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/seashore_mask.png")
blurred_mask = pipeline.mask_processor.blur(mask, blur_factor=33)
blurred_mask
mask tanpa blur
mask dengan blur diterapkan

Model populer

Stable Diffusion Inpainting, Stable Diffusion XL (SDXL) Inpainting, dan Kandinsky 2.2 Inpainting termasuk model inpainting yang paling populer. SDXL umumnya menghasilkan gambar dengan resolusi lebih tinggi daripada Stable Diffusion v1.5, dan Kandinsky 2.2 juga mampu menghasilkan gambar berkualitas tinggi.

Stable Diffusion Inpainting

Stable Diffusion Inpainting adalah model latent diffusion yang finetuned pada gambar 512x512 untuk inpainting. Ini adalah titik awal yang baik karena relatif cepat dan menghasilkan gambar dengan kualitas yang baik. Untuk menggunakan model ini untuk inpainting, Anda perlu meneruskan prompt, gambar dasar, dan gambar mask ke pipeline:

import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-inpainting", dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")

generator = torch.Generator("cuda").manual_seed(92)
prompt = "concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, generator=generator).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)

Stable Diffusion XL (SDXL) Inpainting

SDXL adalah versi yang lebih besar dan lebih kuat dari Stable Diffusion v1.5. Model ini dapat mengikuti proses model dua tahap (meskipun masing-masing model juga dapat digunakan secara terpisah); model dasar menghasilkan gambar, dan model refiner mengambil gambar tersebut untuk meningkatkan detail dan kualitasnya lebih lanjut. Lihat panduan SDXL untuk panduan yang lebih komprehensif tentang cara menggunakan SDXL dan mengonfigurasi parameternya.

import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "diffusers/stable-diffusion-xl-1.0-inpainting-0.1", dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")

generator = torch.Generator("cuda").manual_seed(92)
prompt = "concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, generator=generator).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)

Kandinsky 2.2 Inpainting

Keluarga model Kandinsky mirip dengan SDXL karena juga menggunakan dua model; model image prior membuat image embeddings, dan model diffusion menghasilkan gambar dari embeddings tersebut. Anda dapat memuat model image prior dan model diffusion secara terpisah, tetapi cara termudah untuk menggunakan Kandinsky 2.2 adalah memuatnya ke dalam kelas AutoPipelineForInpainting yang menggunakan KandinskyV22InpaintCombinedPipeline di baliknya.

import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "kandinsky-community/kandinsky-2-2-decoder-inpaint", dtype=torch.float16
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")

generator = torch.Generator("cuda").manual_seed(92)
prompt = "concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, generator=generator).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)
base image
Stable Diffusion Inpainting
Stable Diffusion XL Inpainting
Kandinsky 2.2 Inpainting

Checkpoint yang tidak spesifik untuk inpainting

Sampai sejauh ini, panduan ini telah menggunakan checkpoint khusus inpaint seperti stable-diffusion-v1-5/stable-diffusion-inpainting. Namun, Anda juga dapat menggunakan checkpoint reguler seperti stable-diffusion-v1-5/stable-diffusion-v1-5. Mari kita bandingkan hasil dari kedua checkpoint tersebut.

Gambar di sebelah kiri dihasilkan dari checkpoint reguler, sedangkan gambar di sebelah kanan berasal dari checkpoint inpaint. Anda akan segera menyadari bahwa gambar di sebelah kiri tidak sebersih gambar di sebelah kanan, dan Anda masih dapat melihat garis luar area yang seharusnya di-inpaint oleh model. Gambar di sebelah kanan jauh lebih bersih dan area yang di-inpaint tampak lebih natural.

stable-diffusion-v1-5/stable-diffusion-v1-5
stable-diffusion-v1-5/stable-diffusion-inpainting
import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")

generator = torch.Generator("cuda").manual_seed(92)
prompt = "concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, generator=generator).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
stable-diffusion-v1-5/stable-diffusion-v1-5
stable-diffusion-v1-5/stable-diffusion-inpainting

Namun, untuk tugas yang lebih dasar seperti menghapus objek dari gambar (misalnya batu di jalan), checkpoint reguler menghasilkan hasil yang cukup baik. Tidak ada perbedaan yang terlalu mencolok antara checkpoint reguler dan checkpoint inpaint.

stable-diffusion-v1-5/stable-diffusion-v1-5
stable-diffusion-v1-5/stable-diffusion-inpaint
import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/road-mask.png")

image = pipeline(prompt="road", image=init_image, mask_image=mask_image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
stable-diffusion-v1-5/stable-diffusion-v1-5
stable-diffusion-v1-5/stable-diffusion-inpainting

Kompromi dari penggunaan checkpoint yang tidak spesifik untuk inpainting adalah kualitas gambar secara keseluruhan mungkin lebih rendah, tetapi umumnya cenderung mempertahankan area mask (inilah mengapa Anda dapat melihat outline mask). Checkpoint yang spesifik untuk inpainting sengaja dilatih untuk menghasilkan gambar inpainting dengan kualitas yang lebih tinggi, dan itu termasuk menciptakan transisi yang lebih alami antara area yang di-mask dan tidak di-mask. Akibatnya, checkpoint ini lebih mungkin mengubah area Anda yang tidak di-mask.

Jika mempertahankan area yang tidak dimasker penting untuk tugas Anda, Anda dapat menggunakan metode VaeImageProcessor.apply_overlay() untuk memaksa area yang tidak dimasker pada gambar agar tetap sama, dengan mengorbankan transisi yang sedikit kurang alami antara area yang dimasker dan tidak dimasker.

import PIL
import numpy as np
import torch

from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

device = "cuda"  # or "mps", "xpu", "cpu"
pipeline = AutoPipelineForInpainting.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-inpainting",
    dtype=torch.float16,
    variant="fp16"
)
pipeline = pipeline.to(device)

img_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo.png"
mask_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo_mask.png"

init_image = load_image(img_url).resize((512, 512))
mask_image = load_image(mask_url).resize((512, 512))

prompt = "Face of a yellow cat, high resolution, sitting on a park bench"
repainted_image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image).images[0]
repainted_image.save("repainted_image.png")

unmasked_unchanged_image = pipeline.image_processor.apply_overlay(mask_image, init_image, repainted_image)
unmasked_unchanged_image.save("force_unmasked_unchanged.png")
make_image_grid([init_image, mask_image, repainted_image, unmasked_unchanged_image], rows=2, cols=2)

Konfigurasi parameter pipeline

Fitur gambar - seperti kualitas dan “kreativitas” - bergantung pada parameter pipeline. Memahami apa yang dilakukan parameter-parameter ini penting untuk mendapatkan hasil yang Anda inginkan. Mari kita lihat parameter-parameter terpenting dan bagaimana mengubahnya memengaruhi output.

Kekuatan

strength adalah ukuran seberapa banyak noise yang ditambahkan ke gambar dasar, yang memengaruhi seberapa mirip output dengan gambar dasar.

  • 📈 nilai strength yang tinggi berarti lebih banyak noise ditambahkan ke gambar dan proses denoising memakan waktu lebih lama, tetapi Anda akan mendapatkan gambar dengan kualitas lebih tinggi yang lebih berbeda dari gambar dasar
  • 📉 nilai strength yang rendah berarti lebih sedikit noise yang ditambahkan ke gambar dan proses denoising lebih cepat, tetapi kualitas gambar mungkin tidak sebaik sebelumnya dan gambar yang dihasilkan lebih menyerupai gambar dasar
import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-inpainting", dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")

prompt = "concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, strength=0.6).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)
strength = 0.6
strength = 0.8
strength = 1.0

Skala panduan

guidance_scale memengaruhi seberapa selaras prompt teks dengan gambar yang dihasilkan.

  • 📈 nilai guidance_scale yang tinggi berarti prompt dan gambar yang dihasilkan sangat sejalan, sehingga output merupakan interpretasi yang lebih ketat dari prompt
  • 📉 nilai guidance_scale yang rendah berarti prompt dan gambar yang dihasilkan lebih longgar keselarasan, sehingga output mungkin lebih bervariasi dari prompt

Anda dapat menggunakan strength dan guidance_scale secara bersamaan untuk kontrol yang lebih baik terhadap seberapa ekspresif model tersebut. Misalnya, kombinasi nilai strength dan guidance_scale yang tinggi memberikan kebebasan kreatif paling besar bagi model.

import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-inpainting", dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")

prompt = "concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, guidance_scale=2.5).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)
guidance_scale = 2.5
guidance_scale = 7.5
guidance_scale = 12.5

Prompt negatif

Prompt negatif mengambil peran yang berlawanan dengan prompt; ia memandu model untuk menjauhi penghasilkan elemen tertentu dalam sebuah gambar. Hal ini berguna untuk dengan cepat meningkatkan kualitas gambar dan mencegah model menghasilkan hal-hal yang tidak Anda inginkan.

import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-inpainting", dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")

prompt = "concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k"
negative_prompt = "bad architecture, unstable, poor details, blurry"
image = pipeline(prompt=prompt, negative_prompt=negative_prompt, image=init_image, mask_image=mask_image).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)
negative_prompt = "bad architecture, unstable, poor details, blurry"

Pemotongan mask padding

Salah satu metode untuk meningkatkan kualitas gambar inpainting adalah dengan menggunakan parameter padding_mask_crop. Saat diaktifkan, opsi ini akan memotong area yang dimask dengan padding tertentu yang ditentukan pengguna, dan juga memotong area yang sama dari gambar asli. Baik gambar maupun mask akan di-upscale ke resolusi yang lebih tinggi untuk inpainting, kemudian ditumpangkan kembali ke gambar asli. Ini adalah cara cepat dan mudah untuk meningkatkan kualitas gambar tanpa menggunakan pipeline terpisah seperti StableDiffusionUpscalePipeline.

Tambahkan parameter padding_mask_crop ke panggilan pipeline dan atur ke nilai padding yang diinginkan.

import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image
from PIL import Image

generator = torch.Generator(device='cuda').manual_seed(0)  # or "mps", "xpu", "cpu"
pipeline = AutoPipelineForInpainting.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16).to('cuda')

base = load_image("https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/seashore.png")
mask = load_image("https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/seashore_mask.png")

image = pipeline("boat", image=base, mask_image=mask, strength=0.75, generator=generator, padding_mask_crop=32).images[0]
image
gambar inpaint default
inpaint gambar dengan `padding_mask_crop` diaktifkan

Pipeline inpainting berantai

AutoPipelineForInpainting dapat dirangkai dengan pipeline 🤗 Diffusers lainnya untuk mengedit output mereka. Hal ini sering berguna untuk meningkatkan kualitas output dari pipeline difusi lainnya Anda, dan jika Anda menggunakan beberapa pipeline, merangkainya dapat lebih hemat memori karena output tetap berada di ruang laten dan komponen pipeline yang sama dapat digunakan kembali.

Teks-ke-gambar-ke-inpaint

Menggabungkan pipeline text-to-image dan inpainting memungkinkan Anda melakukan inpainting pada gambar yang dihasilkan, dan Anda tidak perlu menyediakan gambar dasar di awal. Hal ini memudahkan Anda mengedit output text-to-image favorit tanpa harus menghasilkan gambar baru sepenuhnya.

Mulai dengan pipeline teks-ke-gambar untuk membuat kastil:

import torch
from diffusers import AutoPipelineForText2Image, AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

text2image = pipeline("concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k").images[0]

Muat gambar mask dari output di atas:

mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_text-chain-mask.png")

Dan mari kita inpaint area yang dimasker dengan air terjun:

pipeline = AutoPipelineForInpainting.from_pretrained(
    "kandinsky-community/kandinsky-2-2-decoder-inpaint", dtype=torch.float16
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

prompt = "digital painting of a fantasy waterfall, cloudy"
image = pipeline(prompt=prompt, image=text2image, mask_image=mask_image).images[0]
make_image_grid([text2image, mask_image, image], rows=1, cols=3)
teks-ke-gambar
inpaint

Inpaint-ke-gambar-ke-gambar

Anda juga dapat merangkai pipeline inpainting sebelum pipeline lain seperti image-to-image atau upscaler untuk meningkatkan kualitas.

Mulai dengan inpainting sebuah gambar:

import torch
from diffusers import AutoPipelineForInpainting, AutoPipelineForImage2Image
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-inpainting", dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")

prompt = "concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k"
image_inpainting = pipeline(prompt=prompt, image=init_image, mask_image=mask_image).images[0]

# resize image to 1024x1024 for SDXL
image_inpainting = image_inpainting.resize((1024, 1024))

Sekarang, mari kita lewati gambar ke pipeline inpainting lain dengan model refiner SDXL untuk meningkatkan detail dan kualitas gambar:

pipeline = AutoPipelineForInpainting.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0", dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

image = pipeline(prompt=prompt, image=image_inpainting, mask_image=mask_image, output_type="latent").images[0]

Penting untuk menentukan output_type="latent" dalam pipeline agar semua output tetap berada di ruang laten, sehingga menghindari langkah decode-encode yang tidak perlu. Hal ini hanya berfungsi jika pipeline yang dirangkai menggunakan VAE yang sama. Misalnya, pada bagian Text-to-image-to-inpaint, Kandinsky 2.2 menggunakan kelas VAE yang berbeda dari model Stable Diffusion, sehingga tidak akan berfungsi. Namun, jika Anda menggunakan Stable Diffusion v1.5 untuk kedua pipeline, maka Anda dapat mempertahankan semuanya di ruang laten karena keduanya menggunakan AutoencoderKL.

Terakhir, Anda dapat meneruskan gambar ini ke pipeline image-to-image untuk memberikan sentuhan akhir. Lebih efisien menggunakan metode from_pipe() untuk menggunakan kembali komponen pipeline yang sudah ada, dan menghindari pemuatan ulang semua komponen pipeline ke memori secara tidak perlu.

pipeline = AutoPipelineForImage2Image.from_pipe(pipeline)
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

image = pipeline(prompt=prompt, image=image).images[0]
make_image_grid([init_image, mask_image, image_inpainting, image], rows=2, cols=2)
gambar awal
inpaint
image-to-image

Image-to-image dan inpainting sebenarnya adalah tugas yang sangat mirip. Image-to-image menghasilkan gambar baru yang menyerupai gambar yang sudah ada. Inpainting melakukan hal yang sama, tetapi hanya mengubah area gambar yang didefinisikan oleh mask, sementara bagian lain dari gambar tetap tidak berubah. Anda dapat menganggap inpainting sebagai alat yang lebih presisi untuk membuat perubahan spesifik, sedangkan image-to-image memiliki cakupan yang lebih luas untuk membuat perubahan yang lebih besar.

Kontrol generasi gambar

Mendapatkan gambar yang persis seperti yang Anda inginkan menantang karena proses denoising bersifat acak. Meskipun Anda dapat mengontrol beberapa aspek generasi dengan mengonfigurasi parameter seperti negative_prompt, ada metode yang lebih baik dan efisien untuk mengontrol generasi gambar.

Penimbangan prompt

Prompt weighting menyediakan cara yang dapat diukur untuk mengatur skala representasi konsep dalam prompt. Anda dapat menggunakannya untuk meningkatkan atau menurunkan magnitudo vektor embedding teks untuk setiap konsep dalam prompt, yang kemudian menentukan seberapa banyak dari masing-masing konsep yang dihasilkan. Perpustakaan Compel menawarkan sintaks yang intuitif untuk mengatur skala bobot prompt dan menghasilkan embedding. Pelajari cara membuat embedding dalam panduan Prompt weighting.

Setelah Anda menghasilkan embedding, teruskan ke parameter prompt_embeds (dan negative_prompt_embeds jika Anda menggunakan negative prompt) di AutoPipelineForInpainting. Embedding menggantikan parameter prompt:

import torch
from diffusers import AutoPipelineForInpainting
from diffusers.utils import make_image_grid

pipeline = AutoPipelineForInpainting.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-inpainting", dtype=torch.float16,
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

image = pipeline(prompt_embeds=prompt_embeds, # generated from Compel
    negative_prompt_embeds=negative_prompt_embeds, # generated from Compel
    image=init_image,
    mask_image=mask_image
).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)

ControlNet

Model ControlNet digunakan bersama model difusi lain seperti Stable Diffusion, dan menyediakan cara yang lebih fleksibel dan akurat untuk mengontrol bagaimana sebuah gambar dihasilkan. ControlNet menerima input gambar kondisional tambahan yang memandu model difusi untuk mempertahankan fitur-fitur di dalamnya.

Sebagai contoh, mari kita kondisikan sebuah gambar dengan ControlNet yang telah dilatih sebelumnya pada gambar inpaint:

import torch
import numpy as np
from diffusers import ControlNetModel, StableDiffusionControlNetInpaintPipeline
from diffusers.utils import load_image, make_image_grid

# load ControlNet
controlnet = ControlNetModel.from_pretrained("lllyasviel/control_v11p_sd15_inpaint", dtype=torch.float16, variant="fp16")

# pass ControlNet to the pipeline
pipeline = StableDiffusionControlNetInpaintPipeline.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-inpainting", controlnet=controlnet, dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# load base and mask image
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint.png")
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_mask.png")

# prepare control image
def make_inpaint_condition(init_image, mask_image):
    init_image = np.array(init_image.convert("RGB")).astype(np.float32) / 255.0
    mask_image = np.array(mask_image.convert("L")).astype(np.float32) / 255.0

    assert init_image.shape[0:1] == mask_image.shape[0:1], "image and image_mask must have the same image size"
    init_image[mask_image > 0.5] = -1.0  # set as masked pixel
    init_image = np.expand_dims(init_image, 0).transpose(0, 3, 1, 2)
    init_image = torch.from_numpy(init_image)
    return init_image

control_image = make_inpaint_condition(init_image, mask_image)

Sekarang, buat gambar dari gambar dasar, mask, dan kontrol. Anda akan melihat bahwa fitur-fitur dari gambar dasar sangat dipertahankan dalam gambar yang dihasilkan.

prompt = "concept art digital painting of an elven castle, inspired by lord of the rings, highly detailed, 8k"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, control_image=control_image).images[0]
make_image_grid([init_image, mask_image, PIL.Image.fromarray(np.uint8(control_image[0][0])).convert('RGB'), image], rows=2, cols=2)

Anda dapat melangkah lebih jauh dan merangkainya dengan pipeline image-to-image untuk menerapkan gaya baru:

from diffusers import AutoPipelineForImage2Image

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "nitrosocke/elden-ring-diffusion", dtype=torch.float16,
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

prompt = "elden ring style castle" # include the token "elden ring style" in the prompt
negative_prompt = "bad architecture, deformed, disfigured, poor details"

image_elden_ring = pipeline(prompt, negative_prompt=negative_prompt, image=image).images[0]
make_image_grid([init_image, mask_image, image, image_elden_ring], rows=2, cols=2)
gambar awal
ControlNet inpaint
image-to-image

Optimalkan

Menjalankan model difusi bisa menjadi sulit dan lambat jika sumber daya Anda terbatas, tetapi hal ini tidak harus terjadi dengan beberapa trik optimasi. Salah satu optimasi terbesar (dan termudah) yang dapat Anda aktifkan adalah beralih ke perhatian yang hemat memori. Jika Anda menggunakan PyTorch 2.0, scaled-dot product attention diaktifkan secara otomatis dan Anda tidak perlu melakukan hal lain. Untuk pengguna non-PyTorch 2.0, Anda dapat menginstal dan menggunakan implementasi perhatian hemat memori dari xFormers. Kedua opsi ini mengurangi penggunaan memori dan mempercepat inferensi.

Anda juga dapat memindahkan model ke CPU untuk menghemat lebih banyak memori:

+ pipeline.enable_xformers_memory_efficient_attention()
+ pipeline.enable_model_cpu_offload()

Untuk mempercepat kode inferensi Anda lebih lanjut, gunakan torch_compile. Anda harus membungkus torch.compile di sekitar komponen paling intensif dalam pipeline, yang biasanya adalah UNet:

pipeline.unet = torch.compile(pipeline.unet, mode="reduce-overhead", fullgraph=True)

Pelajari lebih lanjut di panduan Reduce memory usage dan Accelerate inference.

Update on GitHub