图像到图像
图像到图像转换与文本到图像类似,但除了提示词之外,您还可以传入一张初始图像作为扩散过程的起点。初始图像会被编码到潜在空间,并添加噪声。随后,潜在扩散模型接收提示词和带噪声的潜在图像,预测所添加的噪声,并从初始潜在图像中去除预测的噪声,从而得到新的潜在图像。最后,解码器将新的潜在图像解码回图像。
使用 🤗 Diffusers,只需 1-2-3 三步即可轻松完成:
- 将检查点加载到 AutoPipelineForImage2Image 类中;该流水线会根据检查点自动处理加载正确的流水线类:
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import load_image, make_image_grid
pipeline = AutoPipelineForImage2Image.from_pretrained(
"kandinsky-community/kandinsky-2-2-decoder", dtype=torch.float16, 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()在整个指南中,您会注意到我们使用了 enable_model_cpu_offload() 和 enable_xformers_memory_efficient_attention() 来节省内存并提升推理速度。如果您使用的是 PyTorch 2.0,则无需在 pipeline 上调用 enable_xformers_memory_efficient_attention(),因为它已经在使用 PyTorch 2.0 原生的 scaled-dot product attention。
- 加载一张图像以传递给流水线:
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat.png")- 将提示词和图像传入管道以生成图像:
prompt = "cat wizard, gandalf, lord of the rings, detailed, fantasy, cute, adorable, Pixar, Disney, 8k"
image = pipeline(prompt, image=init_image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
热门模型
最受欢迎的图生图模型是 Stable Diffusion v1.5、Stable Diffusion XL (SDXL) 和 Kandinsky 2.2。由于架构和训练流程的差异,Stable Diffusion 和 Kandinsky 模型的生成结果各不相同;通常可以预期 SDXL 生成的图像质量高于 Stable Diffusion v1.5。下面快速介绍如何使用这些模型,并对比它们的生成结果。
Stable Diffusion v1.5
Stable Diffusion v1.5 是一个从早期检查点初始化,并在 512x512 图像上进一步微调了 595K 步的潜在扩散模型。若要使用此流水线进行图像到图像的转换,您需要准备一张初始图像并传递给流水线。然后,您可以将提示词和该图像传递给流水线以生成新图像:
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image
pipeline = AutoPipelineForImage2Image.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()
# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
Stable Diffusion XL (SDXL)
SDXL 是 Stable Diffusion 模型的更强大版本。它使用更大的基础模型,并额外引入一个精修模型来提升基础模型输出的质量。请阅读 SDXL 指南,以获取有关如何使用该模型以及其用于生成高质量图像的其他技术的更详细说明。
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image
pipeline = AutoPipelineForImage2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-refiner-1.0", 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()
# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-sdxl-init.png"
init_image = load_image(url)
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image, strength=0.5).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
Kandinsky 2.2
Kandinsky 模型与 Stable Diffusion 模型不同,因为它使用图像先验模型来生成图像嵌入。这些嵌入有助于更好地对齐文本和图像,从而使潜在扩散模型能够生成质量更高的图像。
使用 Kandinsky 2.2 最简单的方法是:
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image
pipeline = AutoPipelineForImage2Image.from_pretrained(
"kandinsky-community/kandinsky-2-2-decoder", dtype=torch.float16, 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()
# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
配置流水线参数
在 pipeline 中,您可以配置多个重要参数,它们会影响图像生成过程和图像质量。让我们仔细看看这些参数的作用,以及更改它们如何影响输出结果。
强度
strength 是最重要的参数之一,它会对生成的图像产生巨大影响。它决定了生成图像与初始图像的相似程度。换句话说:
- 📈
strength值越高,模型在生成与初始图像不同的图像时就越具“创造性”;strength值为 1.0 时,初始图像基本上会被忽略 - 📉
strength值越低,生成的图像与初始图像越相似
strength 和 num_inference_steps 参数是相关的,因为 strength 决定了要添加的噪声步数。例如,如果 num_inference_steps 为 50,且 strength 为 0.8,则意味着向初始图像添加 40(50 * 0.8)步噪声,然后进行 40 步去噪,以得到新生成的图像。
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image
pipeline = AutoPipelineForImage2Image.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()
# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image, strength=0.8).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
引导比例
guidance_scale 参数用于控制生成的图像与文本提示之间的贴合程度。guidance_scale 值越高,生成的图像就越贴合提示;而 guidance_scale 值越低,生成的图像就越有空间偏离提示。
你可以将 guidance_scale 与 strength 结合使用,以实现对模型表现力更精确的控制。例如,将较高的 strength + guidance_scale 组合起来以获得最大的创造力,或者将较低的 strength 和较低的 guidance_scale 组合起来,以生成一张与初始图像相似但并非严格受提示词约束的图像。
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image
pipeline = AutoPipelineForImage2Image.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()
# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image, guidance_scale=8.0).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
负面提示
负面提示词用于指示模型在图像中不要包含某些内容,可用于提升图像质量或修改图像。例如,你可以添加诸如“细节差”或“模糊”等负面提示词,以引导模型生成更高质量的图像。或者,你也可以通过指定需要从图像中排除的内容来修改图像。
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image
pipeline = AutoPipelineForImage2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-refiner-1.0", 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()
# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
negative_prompt = "ugly, deformed, disfigured, poor details, bad anatomy"
# pass prompt and image to pipeline
image = pipeline(prompt, negative_prompt=negative_prompt, image=init_image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
链式图像到图像流水线
除了生成图像(这本身已经相当酷了),你还可以用图像到图像(image-to-image)流水线实现其他一些有趣的用途。你可以更进一步,将其与其他流水线串联起来。
文本到图像到图像
将文本生成图像和图像生成图像流水线串联起来,可以让你从文本生成一张图像,并将该生成的图像作为图像生成图像流水线的初始图像。如果你希望完全从零开始生成图像,这种方法非常有用。例如,我们可以将 Stable Diffusion 和 Kandinsky 模型串联起来。
首先,使用文本到图像流水线生成一张图像:
from diffusers import AutoPipelineForText2Image, AutoPipelineForImage2Image
import torch
from diffusers.utils import 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("Astronaut in a jungle, cold color palette, muted colors, detailed, 8k").images[0]
text2image现在,您可以将此生成的图像传递给图像到图像流水线:
pipeline = AutoPipelineForImage2Image.from_pretrained(
"kandinsky-community/kandinsky-2-2-decoder", dtype=torch.float16, 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()
image2image = pipeline("Astronaut in a jungle, cold color palette, muted colors, detailed, 8k", image=text2image).images[0]
make_image_grid([text2image, image2image], rows=1, cols=2)图像到图像到图像
您还可以将多个图像到图像流水线串联起来,以生成更有趣的图像。这在迭代执行图像风格迁移、生成短 GIF、为图像恢复色彩或修复图像缺失区域时非常有用。
首先,生成一张图像:
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image
pipeline = AutoPipelineForImage2Image.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()
# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image, output_type="latent").images[0]在流水线中指定
output_type="latent"非常重要,这样可以使所有输出都保持在潜在空间中,从而避免不必要的解码-编码步骤。这仅在串联的流水线使用相同的 VAE 时才有效。
将此管道的潜在输出传递给下一个管道,以生成漫画艺术风格的图像:
pipeline = AutoPipelineForImage2Image.from_pretrained(
"ogkalu/Comic-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()
# need to include the token "charliebo artstyle" in the prompt to use this checkpoint
image = pipeline("Astronaut in a jungle, charliebo artstyle", image=image, output_type="latent").images[0]再重复一次,以生成最终的像素艺术风格图像:
pipeline = AutoPipelineForImage2Image.from_pretrained(
"kohbanye/pixel-art-style", 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()
# need to include the token "pixelartstyle" in the prompt to use this checkpoint
image = pipeline("Astronaut in a jungle, pixelartstyle", image=image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)图像到上采样器到超分辨率
另一种将图像到图像流水线串联起来的方法,是结合上采样器和超分辨率流水线,从而显著提升图像的精细程度。
从图像到图像(image-to-image)流水线开始:
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image
pipeline = AutoPipelineForImage2Image.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()
# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
# pass prompt and image to pipeline
image_1 = pipeline(prompt, image=init_image, output_type="latent").images[0]在流水线中指定
output_type="latent"非常重要,这样可以使所有输出保持在 latent 空间中,从而避免不必要的解码-编码步骤。这仅在串联的流水线使用相同的 VAE 时有效。
将其连接到上采样器流水线以提高图像分辨率:
from diffusers import StableDiffusionLatentUpscalePipeline
upscaler = StableDiffusionLatentUpscalePipeline.from_pretrained(
"stabilityai/sd-x2-latent-upscaler", dtype=torch.float16, use_safetensors=True
)
upscaler.enable_model_cpu_offload()
upscaler.enable_xformers_memory_efficient_attention()
image_2 = upscaler(prompt, image=image_1).images[0]最后,将其链接到超分辨率流水线,以进一步提升分辨率:
from diffusers import StableDiffusionUpscalePipeline
super_res = StableDiffusionUpscalePipeline.from_pretrained(
"stabilityai/stable-diffusion-x4-upscaler", dtype=torch.float16, variant="fp16", use_safetensors=True
)
super_res.enable_model_cpu_offload()
super_res.enable_xformers_memory_efficient_attention()
image_3 = super_res(prompt, image=image_2).images[0]
make_image_grid([init_image, image_3.resize((512, 512))], rows=1, cols=2)控制图像生成
想要生成一张完全符合预期的图像可能颇具挑战,这正是受控生成技术和模型如此有用的原因。虽然你可以使用 negative_prompt 来部分控制图像生成,但还有更稳健的方法,例如提示词加权(prompt weighting)和 ControlNets。
提示词加权
提示词加权(Prompt weighting)允许你调整提示词中每个概念的表达强度。例如,在提示词“Astronaut in a jungle, cold color palette, muted colors, detailed, 8k”中,你可以选择增加或减少“astronaut”和“jungle”的嵌入(embeddings)。Compel 库提供了一种简洁的语法,用于调整提示词权重并生成嵌入。你可以在Prompt weighting指南中了解如何创建这些嵌入。
AutoPipelineForImage2Image 提供了一个 prompt_embeds 参数(如果使用负面提示词,则还有 negative_prompt_embeds 参数),你可以传入嵌入向量来替代 prompt 参数。
from diffusers import AutoPipelineForImage2Image
import torch
pipeline = AutoPipelineForImage2Image.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()
image = pipeline(prompt_embeds=prompt_embeds, # generated from Compel
negative_prompt_embeds=negative_prompt_embeds, # generated from Compel
image=init_image,
).images[0]ControlNet
ControlNet 提供了一种更灵活、更精确的图像生成控制方式,因为您可以使用额外的条件图像。条件图像可以是 canny 图像、深度图、图像分割,甚至是涂鸦!无论您选择哪种类型的条件图像,ControlNet 都会生成一张保留其中信息的图像。
例如,我们可以使用深度图对图像进行条件化,以保留图像中的空间信息。
from diffusers.utils import load_image, make_image_grid
# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)
init_image = init_image.resize((958, 960)) # resize to depth image dimensions
depth_image = load_image("https://huggingface.co/lllyasviel/control_v11f1p_sd15_depth/resolve/main/images/control.png")
make_image_grid([init_image, depth_image], rows=1, cols=2)加载一个以深度图为条件的 ControlNet 模型以及 AutoPipelineForImage2Image:
from diffusers import ControlNetModel, AutoPipelineForImage2Image
import torch
controlnet = ControlNetModel.from_pretrained("lllyasviel/control_v11f1p_sd15_depth", dtype=torch.float16, variant="fp16", use_safetensors=True)
pipeline = AutoPipelineForImage2Image.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5", controlnet=controlnet, 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()现在根据深度图、初始图像和提示词生成一张新图像:
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image_control_net = pipeline(prompt, image=init_image, control_image=depth_image).images[0]
make_image_grid([init_image, depth_image, image_control_net], rows=1, cols=3)
让我们通过将其与图生图流水线串联,将新的风格应用于由 ControlNet 生成的图像:
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 astronaut in a jungle" # include the token "elden ring style" in the prompt
negative_prompt = "ugly, deformed, disfigured, poor details, bad anatomy"
image_elden_ring = pipeline(prompt, negative_prompt=negative_prompt, image=image_control_net, strength=0.45, guidance_scale=10.5).images[0]
make_image_grid([init_image, depth_image, image_control_net, image_elden_ring], rows=2, cols=2)
优化
运行扩散模型在计算上开销大且资源密集,但借助一些优化技巧,完全可以在消费级 GPU 和免费层 GPU 上运行。例如,你可以使用更节省内存的注意力机制,如 PyTorch 2.0 的 scaled-dot product attention 或 xFormers(两者选其一即可,无需同时使用)。此外,你还可以将模型卸载到 GPU 上,而其他流水线组件则留在 CPU 上等待。
+ pipeline.enable_model_cpu_offload()
+ pipeline.enable_xformers_memory_efficient_attention()使用 torch.compile,你可以将其包裹你的 UNet,从而进一步提升推理速度:
pipeline.unet = torch.compile(pipeline.unet, mode="reduce-overhead", fullgraph=True)