Diffusers 文档

扰动注意力引导

Hugging Face's logo
加入 Hugging Face 社区

并获得增强文档体验

开始使用

扰动注意力引导

扰动注意力引导 (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。请注意,这不需要额外的内存,并且您将同时加载 StableDiffusionXLPipelineStableDiffusionXLPAGPipeline 并可以使用它们。您可以在这里 阅读有关 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 生成的图像
使用 PAG 生成的图像

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 生成的图像
使用 PAG 生成的图像

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 生成的图像
使用 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]
down.block_2 + up.block1.attentions_0
down.block_2
< > 在 GitHub 上更新