Diffusers 文档

Stable Diffusion XL

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

Stable Diffusion XL

Stable Diffusion XL (SDXL) 是一款强大的文本到图像生成模型,它在先前的 Stable Diffusion 模型的基础上进行了三个关键方面的迭代:

  1. UNet 扩大了 3 倍,并且 SDXL 将第二个文本编码器 (OpenCLIP ViT-bigG/14) 与原始文本编码器结合,显著增加了参数数量
  2. 引入了尺寸和裁剪条件,以保留训练数据不被丢弃,并更好地控制生成图像的裁剪方式
  3. 引入了一个两阶段模型流程;*基础*模型(也可以作为独立模型运行)生成一张图像作为*精炼*模型的输入,精炼模型会添加额外的高质量细节

本指南将向您展示如何使用 SDXL 进行文本到图像、图像到图像和图像修复。

开始之前,请确保已安装以下库:

# uncomment to install the necessary libraries in Colab
#!pip install -q diffusers transformers accelerate invisible-watermark>=0.2.0

我们建议安装 invisible-watermark 库,以帮助识别生成的图像。如果安装了 invisible-watermark 库,它将默认被使用。要禁用水印功能:

pipeline = StableDiffusionXLPipeline.from_pretrained(..., add_watermarker=False)

加载模型检查点

模型权重可能存储在 Hub 上或本地的单独子文件夹中,在这种情况下,您应该使用 from_pretrained() 方法。

from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
import torch

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

refiner = StableDiffusionXLImg2ImgPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0", torch_dtype=torch.float16, use_safetensors=True, variant="fp16"
).to("cuda")

您也可以使用 from_single_file() 方法从 Hub 或本地加载以单文件格式(.ckpt.safetensors)存储的模型检查点。

from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
import torch

pipeline = StableDiffusionXLPipeline.from_single_file(
    "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/sd_xl_base_1.0.safetensors",
    torch_dtype=torch.float16
).to("cuda")

refiner = StableDiffusionXLImg2ImgPipeline.from_single_file(
    "https://huggingface.co/stabilityai/stable-diffusion-xl-refiner-1.0/blob/main/sd_xl_refiner_1.0.safetensors", torch_dtype=torch.float16
).to("cuda")

文本到图像

对于文本到图像任务,传入一个文本提示词。默认情况下,SDXL 会生成 1024x1024 的图像以获得最佳效果。您可以尝试将 heightwidth 参数设置为 768x768 或 512x512,但低于 512x512 的分辨率可能无法正常工作。

from diffusers import AutoPipelineForText2Image
import torch

pipeline_text2image = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = pipeline_text2image(prompt=prompt).images[0]
image
generated image of an astronaut in a jungle

图像到图像

对于图像到图像任务,SDXL 在 768x768 到 1024x1024 之间的图像尺寸上表现尤其出色。传入一张初始图像和一个文本提示词来对图像进行条件化。

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

# use from_pipe to avoid consuming additional memory when loading a checkpoint
pipeline = AutoPipelineForImage2Image.from_pipe(pipeline_text2image).to("cuda")

url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-text2img.png"
init_image = load_image(url)
prompt = "a dog catching a frisbee in the jungle"
image = pipeline(prompt, image=init_image, strength=0.8, guidance_scale=10.5).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
generated image of a dog catching a frisbee in a jungle

图像修复

对于图像修复,您需要原始图像和一张掩码,用于标出您想在原始图像中替换的区域。创建一个提示词来描述您想用什么来替换掩码区域。

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

# use from_pipe to avoid consuming additional memory when loading a checkpoint
pipeline = AutoPipelineForInpainting.from_pipe(pipeline_text2image).to("cuda")

img_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-text2img.png"
mask_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-inpaint-mask.png"

init_image = load_image(img_url)
mask_image = load_image(mask_url)

prompt = "A deep sea diver floating"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, strength=0.85, guidance_scale=12.5).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)
generated image of a deep sea diver in a jungle

精炼图像质量

SDXL 包含一个精炼模型,专门用于对低噪声阶段的图像进行去噪,从而从基础模型生成更高质量的图像。有两种使用精炼模型的方法:

  1. 将基础模型和精炼模型一起使用以生成一张精炼图像
  2. 使用基础模型生成一张图像,然后使用精炼模型为图像添加更多细节(这是 SDXL 最初的训练方式)

基础模型 + 精炼模型

当您将基础模型和精炼模型一起生成图像时,这被称为*专家去噪器集成*。与将基础模型的输出传递给精炼模型相比,专家去噪器集成方法需要的总去噪步骤更少,因此运行速度应该明显更快。然而,您将无法检查基础模型的输出,因为它仍然包含大量噪声。

作为专家去噪器集成,基础模型在高噪声扩散阶段充当专家,而精炼模型在低噪声扩散阶段充当专家。加载基础模型和精炼模型:

from diffusers import DiffusionPipeline
import torch

base = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

refiner = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0",
    text_encoder_2=base.text_encoder_2,
    vae=base.vae,
    torch_dtype=torch.float16,
    use_safetensors=True,
    variant="fp16",
).to("cuda")

要使用这种方法,您需要定义每个模型在各自阶段运行的时间步数。对于基础模型,这由 denoising_end 参数控制,对于精炼模型,则由 denoising_start 参数控制。

denoising_enddenoising_start 参数应该是一个介于 0 和 1 之间的浮点数。这些参数表示为调度器定义的离散时间步的比例。如果您同时使用 strength 参数,它将被忽略,因为去噪步骤的数量由模型训练时使用的离散时间步和声明的分数截止值决定。

让我们设置 denoising_end=0.8,这样基础模型执行前 80% 的**高噪声**时间步去噪,并设置 denoising_start=0.8,这样精炼模型执行后 20% 的**低噪声**时间步去噪。基础模型的输出应为**潜在**空间而不是 PIL 图像。

prompt = "A majestic lion jumping from a big stone at night"

image = base(
    prompt=prompt,
    num_inference_steps=40,
    denoising_end=0.8,
    output_type="latent",
).images
image = refiner(
    prompt=prompt,
    num_inference_steps=40,
    denoising_start=0.8,
    image=image,
).images[0]
image
generated image of a lion on a rock at night
默认基础模型
generated image of a lion on a rock at night in higher quality
专家去噪器集成

精炼模型也可以在 StableDiffusionXLInpaintPipeline 中用于图像修复。

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

base = StableDiffusionXLInpaintPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

refiner = StableDiffusionXLInpaintPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0",
    text_encoder_2=base.text_encoder_2,
    vae=base.vae,
    torch_dtype=torch.float16,
    use_safetensors=True,
    variant="fp16",
).to("cuda")

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)
mask_image = load_image(mask_url)

prompt = "A majestic tiger sitting on a bench"
num_inference_steps = 75
high_noise_frac = 0.7

image = base(
    prompt=prompt,
    image=init_image,
    mask_image=mask_image,
    num_inference_steps=num_inference_steps,
    denoising_end=high_noise_frac,
    output_type="latent",
).images
image = refiner(
    prompt=prompt,
    image=image,
    mask_image=mask_image,
    num_inference_steps=num_inference_steps,
    denoising_start=high_noise_frac,
).images[0]
make_image_grid([init_image, mask_image, image.resize((512, 512))], rows=1, cols=3)

这种专家去噪器集成方法对所有可用的调度器都有效!

基础模型到精炼模型

SDXL 通过使用精炼模型在图像到图像设置中为基础模型的完全去噪图像添加额外的高质量细节,从而提升了图像质量。

加载基础模型和精炼模型:

from diffusers import DiffusionPipeline
import torch

base = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

refiner = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0",
    text_encoder_2=base.text_encoder_2,
    vae=base.vae,
    torch_dtype=torch.float16,
    use_safetensors=True,
    variant="fp16",
).to("cuda")

您可以将 SDXL 精炼模型与其他基础模型一起使用。例如,您可以使用 Hunyuan-DiTPixArt-Sigma pipeline 来生成具有更好提示词遵循度的图像。生成图像后,您可以将其传递给 SDXL 精炼模型以增强最终生成质量。

从基础模型生成一张图像,并将模型输出设置为**潜在**空间。

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"

image = base(prompt=prompt, output_type="latent").images[0]

将生成的图像传递给精炼模型。

image = refiner(prompt=prompt, image=image[None, :]).images[0]
generated image of an astronaut riding a green horse on Mars
基础模型
higher quality generated image of an astronaut riding a green horse on Mars
基础模型 + 精炼模型

对于图像修复,在 StableDiffusionXLInpaintPipeline 中加载基础模型和精炼模型,移除 denoising_enddenoising_start 参数,并为精炼模型选择较少的推理步数。

微条件

SDXL 训练涉及几种额外的条件化技术,这些技术被称为*微条件*。其中包括原始图像尺寸、目标图像尺寸和裁剪参数。这些微条件可以在推理时用于创建高质量、居中的图像。

由于无分类器引导,您可以使用微条件和负微条件参数。它们在 StableDiffusionXLPipelineStableDiffusionXLImg2ImgPipelineStableDiffusionXLInpaintPipelineStableDiffusionXLControlNetPipeline 中均可用。

尺寸条件

有两种类型的尺寸条件:

  • original_size 条件来自训练批次中的上采样图像(因为丢弃占总训练数据近 40% 的较小图像会造成浪费)。通过这种方式,SDXL 学会了高分辨率图像中不应出现上采样伪影。在推理期间,您可以使用 original_size 来指示原始图像分辨率。使用默认值 (1024, 1024) 会产生更高质量的图像,类似于数据集中的 1024x1024 图像。如果您选择使用较低的分辨率,例如 (256, 256),模型仍会生成 1024x1024 的图像,但它们看起来会像数据集中的低分辨率图像(更简单的图案、模糊)。

  • target_size 条件来自对 SDXL 进行微调以支持不同的图像宽高比。在推理期间,如果您使用默认值 (1024, 1024),您将得到一张类似于数据集中方形图像构图的图像。我们建议为 target_sizeoriginal_size 使用相同的值,但欢迎尝试其他选项!

🤗 Diffusers 还允许您指定关于图像尺寸的负条件,以引导生成远离某些图像分辨率:

from diffusers import StableDiffusionXLPipeline
import torch

pipe = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = pipe(
    prompt=prompt,
    negative_original_size=(512, 512),
    negative_target_size=(1024, 1024),
).images[0]
对 (128, 128)、(256, 256) 和 (512, 512) 的图像分辨率进行负条件处理的图像。

裁剪条件

先前 Stable Diffusion 模型生成的图像有时可能看起来被裁剪过。这是因为在训练过程中,图像实际上会被裁剪,以使批次中的所有图像都具有相同的大小。通过对裁剪坐标进行条件化,SDXL *学会*了无裁剪——坐标 `(0, 0)`——通常与居中的主体和完整的面部相关(这是 🤗 Diffusers 中的默认值)。如果您想生成偏离中心的构图,可以尝试不同的坐标!

from diffusers import StableDiffusionXLPipeline
import torch

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = pipeline(prompt=prompt, crops_coords_top_left=(256, 0)).images[0]
image
generated image of an astronaut in a jungle, slightly cropped

您还可以指定负裁剪坐标,以引导生成远离某些裁剪参数。

from diffusers import StableDiffusionXLPipeline
import torch

pipe = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = pipe(
    prompt=prompt,
    negative_original_size=(512, 512),
    negative_crops_coords_top_left=(0, 0),
    negative_target_size=(1024, 1024),
).images[0]
image

为每个文本编码器使用不同的提示词

SDXL 使用两个文本编码器,因此可以为每个文本编码器传递不同的提示词,这可以提高质量。将您的原始提示词传递给 `prompt`,第二个提示词传递给 `prompt_2`(如果您使用负提示词,则使用 `negative_prompt` 和 `negative_prompt_2`)。

from diffusers import StableDiffusionXLPipeline
import torch

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

# prompt is passed to OAI CLIP-ViT/L-14
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
# prompt_2 is passed to OpenCLIP-ViT/bigG-14
prompt_2 = "Van Gogh painting"
image = pipeline(prompt=prompt, prompt_2=prompt_2).images[0]
image
generated image of an astronaut in a jungle in the style of a van gogh painting

双文本编码器还支持文本反演嵌入,需要按照 SDXL 文本反演 部分中的说明单独加载。

优化

SDXL 是一个大型模型,您可能需要优化内存才能在您的硬件上运行它。以下是一些节省内存和加速推理的技巧。

  1. 使用 enable_model_cpu_offload() 将模型卸载到 CPU,以解决内存不足的错误。
- base.to("cuda")
- refiner.to("cuda")
+ base.enable_model_cpu_offload()
+ refiner.enable_model_cpu_offload()
  1. 使用 `torch.compile` 可获得约 20% 的速度提升(您需要 `torch>=2.0`)。
+ base.unet = torch.compile(base.unet, mode="reduce-overhead", fullgraph=True)
+ refiner.unet = torch.compile(refiner.unet, mode="reduce-overhead", fullgraph=True)
  1. 如果 `torch<2.0`,请启用 xFormers 来运行 SDXL。
+ base.enable_xformers_memory_efficient_attention()
+ refiner.enable_xformers_memory_efficient_attention()

其他资源

如果您有兴趣尝试 SDXL 中使用的 UNet2DConditionModel 的简化版本,请查看 minSDXL 实现,该实现使用 PyTorch 编写,并与 🤗 Diffusers 直接兼容。

< > 在 GitHub 上更新