Diffusers documentation
Inpainting
Inpainting
Inpainting thay thế hoặc chỉnh sửa các khu vực cụ thể của một hình ảnh. Điều này biến nó thành một công cụ hữu ích cho việc phục hồi hình ảnh như loại bỏ các khuyết điểm và hiện tượng nhiễu, hoặc thậm chí thay thế một khu vực của hình ảnh bằng một thứ gì đó hoàn toàn mới. Inpainting dựa vào một mask để xác định các vùng của hình ảnh cần được lấp đầy; khu vực cần inpaint được biểu diễn bằng các pixel màu trắng và khu vực cần giữ lại được biểu diễn bằng các pixel màu đen. Các pixel màu trắng được lấp đầy bởi prompt.
Với 🤗 Diffusers, đây là cách bạn có thể thực hiện inpainting:
- Tải checkpoint inpainting bằng lớp AutoPipelineForInpainting. Lớp này sẽ tự động phát hiện lớp pipeline phù hợp để tải dựa trên 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()Bạn sẽ nhận thấy trong suốt hướng dẫn, chúng tôi sử dụng enable_model_cpu_offload() và enable_xformers_memory_efficient_attention() để tiết kiệm bộ nhớ và tăng tốc độ suy luận. Nếu bạn đang sử dụng PyTorch 2.0, không cần thiết phải gọi enable_xformers_memory_efficient_attention() trên pipeline của bạn vì nó đã sử dụng scaled-dot product attention bản địa của PyTorch 2.0.
- Tải ảnh nền và ảnh mặt nạ:
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")- Tạo một prompt để inpaint hình ảnh và truyền nó vào pipeline cùng với hình ảnh gốc và hình ảnh 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)
Tạo một hình ảnh mặt nạ
Trong suốt hướng dẫn này, hình ảnh mask được cung cấp trong tất cả các ví dụ mã để tiện lợi. Bạn có thể inpaint trên các hình ảnh của riêng mình, nhưng sẽ cần tạo một hình ảnh mask cho nó. Sử dụng Space bên dưới để dễ dàng tạo một hình ảnh mask.
Tải lên một hình ảnh nền để inpaint và sử dụng công cụ phác thảo để vẽ mặt nạ. Khi hoàn tất, nhấp vào Run để tạo và tải xuống hình ảnh mặt nạ.
Làm mờ mặt nạ
Phương thức blur() cung cấp tùy chọn về cách trộn lẫn giữa ảnh gốc và khu vực inpaint. Mức độ làm mờ được xác định bởi tham số blur_factor. Việc tăng blur_factor sẽ tăng lượng làm mờ được áp dụng lên các cạnh của mask, làm mềm sự chuyển tiếp giữa ảnh gốc và khu vực inpaint. Một blur_factor thấp hoặc bằng không sẽ giữ cho các cạnh của mask sắc nét hơn.
Để sử dụng tính năng này, hãy tạo một mặt nạ mờ bằng trình xử lý ảnh.
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
Các mô hình phổ biến
Stable Diffusion Inpainting, Stable Diffusion XL (SDXL) Inpainting và Kandinsky 2.2 Inpainting là một trong những mô hình inpainting phổ biến nhất. SDXL thường tạo ra các hình ảnh có độ phân giải cao hơn so với Stable Diffusion v1.5, và Kandinsky 2.2 cũng có khả năng tạo ra các hình ảnh chất lượng cao.
Stable Diffusion Inpainting
Stable Diffusion Inpainting là một latent diffusion model được finetune trên các ảnh 512x512 cho tác vụ inpainting. Đây là một điểm khởi đầu tốt vì nó tương đối nhanh và tạo ra các ảnh có chất lượng tốt. Để sử dụng model này cho inpainting, bạn cần truyền một prompt, ảnh base và ảnh mask vào 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 là phiên bản lớn hơn và mạnh hơn của Stable Diffusion v1.5. Mô hình này có thể tuân theo quy trình mô hình hai giai đoạn (mặc dù mỗi mô hình cũng có thể được sử dụng riêng lẻ); mô hình cơ sở tạo ra một hình ảnh, và mô hình tinh chỉnh nhận hình ảnh đó để nâng cao thêm chi tiết và chất lượng. Hãy xem hướng dẫn SDXL để có hướng dẫn toàn diện hơn về cách sử dụng SDXL và cấu hình các tham số của nó.
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
Họ model Kandinsky tương tự SDXL vì cũng sử dụng hai model; model image prior tạo ra image embeddings, và model diffusion tạo hình ảnh từ chúng. Bạn có thể nạp riêng model image prior và model diffusion, nhưng cách dễ nhất để sử dụng Kandinsky 2.2 là nạp nó vào lớp AutoPipelineForInpainting, lớp này sử dụng KandinskyV22InpaintCombinedPipeline bên trong.
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)
Các checkpoint không dành riêng cho inpainting
Cho đến nay, hướng dẫn này đã sử dụng các checkpoint dành riêng cho inpaint như stable-diffusion-v1-5/stable-diffusion-inpainting. Nhưng bạn cũng có thể sử dụng các checkpoint thông thường như stable-diffusion-v1-5/stable-diffusion-v1-5. Hãy so sánh kết quả của hai checkpoint này.
Hình ảnh bên trái được tạo từ một checkpoint thông thường, còn hình ảnh bên phải được tạo từ một checkpoint inpaint. Bạn sẽ ngay lập tức nhận thấy hình ảnh bên trái không sạch sẽ bằng, và vẫn có thể nhìn thấy đường viền của khu vực mà mô hình cần inpaint. Hình ảnh bên phải sạch sẽ hơn nhiều và khu vực được inpaint trông tự nhiên hơn.
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)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, image], rows=1, cols=2)
Tuy nhiên, đối với các tác vụ cơ bản hơn như xóa một đối tượng khỏi hình ảnh (ví dụ như những tảng đá trên đường), một checkpoint thông thường cho kết quả khá tốt. Không có sự khác biệt đáng kể nào giữa checkpoint thông thường và checkpoint 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)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/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)
Nhược điểm khi sử dụng checkpoint không chuyên về inpaint là chất lượng tổng thể của hình ảnh có thể thấp hơn, nhưng nó thường có xu hướng giữ nguyên vùng mask (đó là lý do bạn có thể thấy đường viền của mask). Các checkpoint chuyên về inpaint được huấn luyện có chủ đích để tạo ra các hình ảnh inpaint có chất lượng cao hơn, bao gồm việc tạo ra sự chuyển tiếp tự nhiên hơn giữa vùng bị mask và vùng không bị mask. Do đó, các checkpoint này có khả năng cao hơn trong việc thay đổi vùng không bị mask của bạn.
Nếu việc giữ nguyên vùng không bị che (unmasked) là quan trọng đối với tác vụ của bạn, bạn có thể sử dụng phương thức VaeImageProcessor.apply_overlay() để buộc vùng không bị che của hình ảnh giữ nguyên, với cái giá là một số chuyển tiếp kém tự nhiên hơn giữa vùng bị che và vùng không bị che.
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)Cấu hình tham số pipeline
Đặc điểm của hình ảnh - như chất lượng và “sáng tạo” - phụ thuộc vào các tham số của pipeline. Việc hiểu rõ các tham số này hoạt động như thế nào là rất quan trọng để đạt được kết quả mong muốn. Hãy cùng xem xét các tham số quan trọng nhất và cách việc thay đổi chúng ảnh hưởng đến đầu ra.
Độ mạnh
strength là thước đo mức độ nhiễu được thêm vào ảnh gốc, ảnh hưởng đến mức độ tương đồng giữa ảnh đầu ra và ảnh gốc.
- 📈 giá trị
strengthcao hơn có nghĩa là nhiều nhiễu hơn được thêm vào hình ảnh và quá trình khử nhiễu mất nhiều thời gian hơn, nhưng bạn sẽ nhận được các hình ảnh có chất lượng cao hơn và khác biệt hơn so với hình ảnh gốc - 📉 giá trị
strengththấp có nghĩa là ít nhiễu được thêm vào hình ảnh hơn và quá trình khử nhiễu diễn ra nhanh hơn, nhưng chất lượng hình ảnh có thể không cao và hình ảnh tạo ra sẽ giống với hình ảnh gốc hơn
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)
Thang độ dẫn
guidance_scale ảnh hưởng đến mức độ khớp giữa prompt văn bản và hình ảnh được tạo ra.
- 📈 giá trị
guidance_scalecao có nghĩa là prompt và hình ảnh được tạo ra khớp sát nhau, do đó kết quả là một diễn giải chặt chẽ hơn của prompt - 📉 giá trị
guidance_scalethấp có nghĩa là prompt và hình ảnh được tạo ra ít liên kết chặt chẽ hơn, do đó kết quả có thể đa dạng hơn so với prompt
Bạn có thể sử dụng strength và guidance_scale cùng nhau để kiểm soát tốt hơn mức độ biểu cảm của mô hình. Ví dụ, sự kết hợp giữa giá trị strength và guidance_scale cao sẽ mang lại cho mô hình sự tự do sáng tạo lớn nhất.
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)
Negative prompt
Prompt âm đóng vai trò ngược lại với prompt; nó hướng mô hình tránh tạo ra một số yếu tố nhất định trong hình ảnh. Điều này hữu ích để nhanh chóng cải thiện chất lượng hình ảnh và ngăn mô hình tạo ra những thứ bạn không mong muốn.
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)
Cắt theo mặt nạ đệm
Một phương pháp để tăng chất lượng ảnh inpainting là sử dụng tham số padding_mask_crop. Khi được bật, tùy chọn này sẽ cắt vùng bị mask với một lượng padding do người dùng chỉ định và cũng cắt cùng vùng đó từ ảnh gốc. Cả ảnh và mask đều được upscale lên độ phân giải cao hơn để inpainting, sau đó được ghép đè lên ảnh gốc. Đây là cách nhanh chóng và dễ dàng để cải thiện chất lượng ảnh mà không cần sử dụng một pipeline riêng biệt như StableDiffusionUpscalePipeline.
Thêm tham số padding_mask_crop vào lệnh gọi pipeline và đặt nó thành giá trị padding mong muốn.
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
Các pipeline inpainting được nối tiếp
AutoPipelineForInpainting có thể được kết nối với các pipeline 🤗 Diffusers khác để chỉnh sửa đầu ra của chúng. Điều này thường hữu ích để cải thiện chất lượng đầu ra từ các pipeline khuếch tán khác của bạn, và nếu bạn đang sử dụng nhiều pipeline, việc kết nối chúng lại với nhau có thể tiết kiệm bộ nhớ hơn bằng cách giữ các đầu ra trong không gian tiềm ẩn và tái sử dụng các thành phần pipeline giống nhau.
Từ văn bản sang hình ảnh sang inpaint
Việc kết nối (chaining) một pipeline text-to-image và một pipeline inpainting cho phép bạn inpaint hình ảnh đã được tạo ra, và bạn không cần cung cấp một hình ảnh nền ban đầu. Điều này giúp việc chỉnh sửa các kết quả text-to-image yêu thích của bạn trở nên thuận tiện mà không cần phải tạo ra một hình ảnh hoàn toàn mới.
Bắt đầu với pipeline text-to-image để tạo một lâu đài:
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]Tải ảnh mask của đầu ra từ trên:
mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/inpaint_text-chain-mask.png")Và hãy inpaint vùng bị mask bằng một thác nước:
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)
Inpaint-to-image-to-image
Bạn cũng có thể nối một pipeline inpainting trước một pipeline khác như image-to-image hoặc upscaler để cải thiện chất lượng.
Bắt đầu bằng cách inpainting một hình ảnh:
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))Bây giờ, hãy truyền ảnh vào một pipeline inpainting khác với mô hình refiner của SDXL để tăng cường chi tiết và chất lượng của ảnh:
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]Việc chỉ định
output_type="latent"trong pipeline là quan trọng để giữ tất cả các đầu ra trong không gian latent, tránh bước decode-encode không cần thiết. Điều này chỉ hoạt động nếu các pipeline được nối tiếp sử dụng cùng một VAE. Ví dụ, trong phần Text-to-image-to-inpaint, Kandinsky 2.2 sử dụng một lớp VAE khác với mô hình Stable Diffusion nên sẽ không hoạt động. Nhưng nếu bạn sử dụng Stable Diffusion v1.5 cho cả hai pipeline, thì bạn có thể giữ mọi thứ trong không gian latent vì cả hai đều sử dụng AutoencoderKL.
Cuối cùng, bạn có thể truyền ảnh này vào một pipeline image-to-image để hoàn thiện nó. Việc sử dụng phương thức from_pipe() để tái sử dụng các thành phần pipeline hiện có sẽ hiệu quả hơn, và tránh việc tải lại tất cả các thành phần pipeline vào bộ nhớ một cách không cần thiết.
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)
Image-to-image và inpainting thực chất là những tác vụ rất tương đồng. Image-to-image tạo ra một hình ảnh mới có nét giống với hình ảnh được cung cấp sẵn. Inpainting cũng làm điều tương tự, nhưng chỉ biến đổi vùng hình ảnh được xác định bởi mask, trong khi phần còn lại của hình ảnh giữ nguyên. Bạn có thể xem inpainting như một công cụ chính xác hơn để thực hiện những thay đổi cụ thể, còn image-to-image có phạm vi rộng hơn để tạo ra những thay đổi mang tính tổng quát hơn.
Kiểm soát tạo ảnh
Việc khiến hình ảnh trông chính xác như mong muốn là một thách thức vì quá trình khử nhiễu mang tính ngẫu nhiên. Mặc dù bạn có thể kiểm soát một số khía cạnh của quá trình tạo hình bằng cách cấu hình các tham số như negative_prompt, nhưng có những phương pháp tốt hơn và hiệu quả hơn để kiểm soát việc tạo hình ảnh.
Trọng số prompt
Prompt weighting cung cấp một cách định lượng để điều chỉnh mức độ biểu diễn của các khái niệm trong prompt. Bạn có thể sử dụng nó để tăng hoặc giảm độ lớn của vector nhúng văn bản cho từng khái niệm trong prompt, từ đó xác định mức độ mà mỗi khái niệm được tạo ra. Thư viện Compel cung cấp cú pháp trực quan để điều chỉnh trọng số prompt và tạo ra các embedding. Tìm hiểu cách tạo các embedding trong hướng dẫn Prompt weighting.
Sau khi bạn đã tạo các embeddings, hãy truyền chúng vào tham số prompt_embeds (và negative_prompt_embeds nếu bạn đang sử dụng negative prompt) trong AutoPipelineForInpainting. Các embeddings này thay thế cho tham số 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
Mô hình ControlNet được sử dụng cùng với các mô hình khuếch tán khác như Stable Diffusion, và chúng cung cấp một cách linh hoạt và chính xác hơn để kiểm soát cách một hình ảnh được tạo ra. Một ControlNet nhận vào một đầu vào hình ảnh điều kiện bổ sung, giúp định hướng mô hình khuếch tán để giữ lại các đặc điểm có trong hình ảnh đó.
Ví dụ, hãy điều kiện hóa một hình ảnh bằng ControlNet được huấn luyện trước trên các hình ảnh 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)Bây giờ hãy tạo một hình ảnh từ các hình ảnh base, mask và control. Bạn sẽ nhận thấy các đặc điểm của hình ảnh base được giữ lại mạnh mẽ trong hình ảnh được tạo ra.
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)Bạn có thể đi xa hơn một bước và kết nối nó với một pipeline image-to-image để áp dụng một phong cách mới:
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)
Tối ưu
Việc chạy các mô hình diffusion có thể khó khăn và chậm nếu bạn bị giới hạn về tài nguyên, nhưng điều đó không nhất thiết phải xảy ra nếu áp dụng một số mẹo tối ưu hóa. Một trong những tối ưu hóa lớn nhất (và dễ nhất) mà bạn có thể bật là chuyển sang cơ chế attention tiết kiệm bộ nhớ. Nếu bạn đang sử dụng PyTorch 2.0, scaled-dot product attention sẽ được bật tự động và bạn không cần làm gì thêm. Đối với người dùng không dùng PyTorch 2.0, bạn có thể cài đặt và sử dụng bản triển khai attention tiết kiệm bộ nhớ của xFormers. Cả hai tùy chọn đều giúp giảm mức sử dụng bộ nhớ và tăng tốc suy luận.
Bạn cũng có thể offload mô hình sang CPU để tiết kiệm thêm bộ nhớ:
+ pipeline.enable_xformers_memory_efficient_attention()
+ pipeline.enable_model_cpu_offload()Để tăng tốc mã suy luận của bạn hơn nữa, hãy sử dụng torch_compile. Bạn nên bọc torch.compile quanh thành phần tiêu tốn tài nguyên nhất trong pipeline, thường là UNet:
pipeline.unet = torch.compile(pipeline.unet, mode="reduce-overhead", fullgraph=True)Tìm hiểu thêm trong các hướng dẫn Giảm mức sử dụng bộ nhớ và Tăng tốc suy luận.
Update on GitHub