扰动注意力引导
扰动注意力引导 (PAG) 是一种新的扩散采样引导方法,可在无条件和有条件设置下提高样本质量,而无需进一步训练或集成外部模块。PAG 旨在通过考虑自注意力机制捕获结构信息的能力,在整个去噪过程中逐步增强合成样本的结构。它涉及通过用恒等矩阵替换扩散 U-Net 中选定的自注意力映射来生成具有退化结构的中间样本,并引导去噪过程远离这些退化样本。
本指南将向您展示如何在各种任务和用例中使用 PAG。
常规任务
您可以将 PAG 应用于 StableDiffusionXLPipeline 以执行文本到图像、图像到图像和修复等任务。要为特定任务启用 PAG,请使用 AutoPipeline API 和 enable_pag=True
标志以及 pag_applied_layers
参数加载管道。
🤗 Diffusers 目前仅支持使用选定的 SDXL 管道和 PixArtSigmaPAGPipeline 使用 PAG。但是,如果您想将 PAG 支持添加到新的管道中,请随时打开 功能请求!
from diffusers import AutoPipelineForText2Image
from diffusers.utils import load_image
import torch
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
enable_pag=True,
pag_applied_layers=["mid"],
torch_dtype=torch.float16
)
pipeline.enable_model_cpu_offload()
pag_applied_layers
参数允许您指定将 PAG 应用于哪些层。此外,您可以在创建管道后使用 set_pag_applied_layers
方法更新这些层。查看 pag_applied_layers 部分,以了解有关将 PAG 应用于其他层的更多信息。
如果您已经创建并加载了一个管道,则可以使用 from_pipe
API 和 enable_pag
标志在其上启用 PAG。在内部,将根据您指定的管道和任务创建一个 PAG 管道。在下面的示例中,由于我们使用了 AutoPipelineForText2Image
并传递了一个 StableDiffusionXLPipeline
,因此将相应地创建一个 StableDiffusionXLPAGPipeline
。请注意,这不需要额外的内存,并且您将同时加载 StableDiffusionXLPipeline
和 StableDiffusionXLPAGPipeline
并可以使用它们。您可以在这里 阅读有关 from_pipe
API 以及如何在扩散器中重用管道的更多信息。
pipeline_sdxl = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16)
pipeline = AutoPipelineForText2Image.from_pipe(pipeline_sdxl, enable_pag=True)
要生成图像,您还需要传递一个 pag_scale
。当 pag_scale
增加时,图像会获得更多语义连贯的结构并表现出更少的伪影。但是,过大的引导比例会导致图像纹理更平滑并且略微饱和,类似于 CFG。pag_scale=3.0
用于官方演示,并且在大多数用例中都能很好地工作,但请随意尝试并根据您的需要选择合适的值!当 pag_scale=0
时,PAG 将被禁用。
prompt = "an insect robot preparing a delicious meal, anime style"
for pag_scale in [0.0, 3.0]:
generator = torch.Generator(device="cpu").manual_seed(0)
images = pipeline(
prompt=prompt,
num_inference_steps=25,
guidance_scale=7.0,
generator=generator,
pag_scale=pag_scale,
).images
PAG 与 ControlNet
要将 PAG 与 ControlNet 一起使用,首先创建一个 controlnet
。然后,将 controlnet
和其他 PAG 参数传递到指定任务的 AutoPipeline 的 from_pretrained
方法。
from diffusers import AutoPipelineForText2Image, ControlNetModel
import torch
controlnet = ControlNetModel.from_pretrained(
"diffusers/controlnet-canny-sdxl-1.0", torch_dtype=torch.float16
)
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
controlnet=controlnet,
enable_pag=True,
pag_applied_layers="mid",
torch_dtype=torch.float16
)
pipeline.enable_model_cpu_offload()
如果您已经拥有一个 controlnet 管道并希望启用 PAG,则可以使用 from_pipe
API:AutoPipelineForText2Image.from_pipe(pipeline_controlnet, enable_pag=True)
您可以像平时使用 ControlNet 管道一样使用该管道,并可以选择指定 pag_scale
参数。请注意,PAG 适用于无条件生成。在此示例中,我们将生成没有提示的图像。
from diffusers.utils import load_image
canny_image = load_image(
"https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/pag_control_input.png"
)
for pag_scale in [0.0, 3.0]:
generator = torch.Generator(device="cpu").manual_seed(1)
images = pipeline(
prompt="",
controlnet_conditioning_scale=controlnet_conditioning_scale,
image=canny_image,
num_inference_steps=50,
guidance_scale=0,
generator=generator,
pag_scale=pag_scale,
).images
images[0]
PAG 与 IP-Adapter
IP-Adapter 是一种流行的模型,可以插入扩散模型以启用图像提示,而无需对底层模型进行任何更改。您可以在加载了 IP-Adapter 的管道上启用 PAG。
from diffusers import AutoPipelineForText2Image
from diffusers.utils import load_image
from transformers import CLIPVisionModelWithProjection
import torch
image_encoder = CLIPVisionModelWithProjection.from_pretrained(
"h94/IP-Adapter",
subfolder="models/image_encoder",
torch_dtype=torch.float16
)
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
image_encoder=image_encoder,
enable_pag=True,
torch_dtype=torch.float16
).to("cuda")
pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="sdxl_models", weight_name="ip-adapter-plus_sdxl_vit-h.bin")
pag_scales = 5.0
ip_adapter_scales = 0.8
image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_diner.png")
pipeline.set_ip_adapter_scale(ip_adapter_scale)
generator = torch.Generator(device="cpu").manual_seed(0)
images = pipeline(
prompt="a polar bear sitting in a chair drinking a milkshake",
ip_adapter_image=image,
negative_prompt="deformed, ugly, wrong proportion, low res, bad anatomy, worst quality, low quality",
num_inference_steps=25,
guidance_scale=3.0,
generator=generator,
pag_scale=pag_scale,
).images
images[0]
PAG 减少了伪影并提高了整体构图。
配置参数
pag_applied_layers
pag_applied_layers
参数允许您指定 PAG 应用于哪些层。默认情况下,它仅应用于中间块。更改此设置将显着影响输出。您可以使用 set_pag_applied_layers
方法在管道创建后调整 PAG 层,帮助您找到模型的最佳层。
例如,以下是使用 pag_layers = ["down.block_2"]
和 pag_layers = ["down.block_2", "up.block_1.attentions_0"]
生成的图像。
prompt = "an insect robot preparing a delicious meal, anime style"
pipeline.set_pag_applied_layers(pag_layers)
generator = torch.Generator(device="cpu").manual_seed(0)
images = pipeline(
prompt=prompt,
num_inference_steps=25,
guidance_scale=guidance_scale,
generator=generator,
pag_scale=pag_scale,
).images
images[0]