Diffusers 文档

扰动注意力指导

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

扰动注意力指导

Perturbed-Attention Guidance (PAG) 是一种新的扩散采样引导方法,可以提高无条件和有条件设置下的样本质量,且无需额外训练或集成外部模块即可实现。PAG 的设计旨在通过考虑自注意力机制捕获结构信息的能力,在去噪过程中逐步增强合成样本的结构。它涉及通过将扩散 U-Net 中选定的自注意力图替换为单位矩阵来生成结构退化的中间样本,并将去噪过程引导远离这些退化样本。

本指南将向您展示如何在各种任务和用例中使用 PAG。

通用任务

您可以将 PAG 应用于 StableDiffusionXLPipeline,用于文本到图像、图像到图像和图像修复等任务。要为特定任务启用 PAG,请使用 AutoPipeline API 加载 pipeline,并使用 enable_pag=True 标志和 pag_applied_layers 参数。

🤗 Diffusers 目前仅支持将 PAG 与选定的 SDXL pipelines 和 PixArtSigmaPAGPipeline 一起使用。但是,如果您想为新的 pipeline 添加 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` 方法在 pipeline 创建后更新这些层。查看 pag_applied_layers 部分,了解有关将 PAG 应用于其他层的更多信息。

如果您已经创建并加载了 pipeline,则可以使用带有 `enable_pag` 标志的 `from_pipe` API 在其上启用 PAG。在内部,PAG pipeline 是根据您指定的 pipeline 和任务创建的。在下面的示例中,由于我们使用了 `AutoPipelineForText2Image` 并传递了 `StableDiffusionXLPipeline`,因此会相应地创建 `StableDiffusionXLPAGPipeline`。请注意,这不需要额外的内存,您将同时加载 `StableDiffusionXLPipeline` 和 `StableDiffusionXLPAGPipeline` 并准备好使用。您可以在此处阅读有关 `from_pipe` API 以及如何在 diffusers 中重用 pipelines 的更多信息。

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 pipeline 并想启用 PAG,则可以使用 `from_pipe` API:`AutoPipelineForText2Image.from_pipe(pipeline_controlnet, enable_pag=True)`

您可以像平常使用 ControlNet pipelines 一样使用该 pipeline,但增加了一个选项来指定 `pag_scale` 参数。请注意,PAG 在无条件生成方面表现良好。在本例中,我们将生成一个没有 prompt 的图像。

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 的 pipeline 上启用 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` 方法在 pipeline 创建后调整 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
< > Update on GitHub