DiffEdit
DiffEdit:基于扩散的语义图像编辑,带掩码引导 是由 Guillaume Couairon、Jakob Verbeek、Holger Schwenk 和 Matthieu Cord 撰写。
论文的摘要是
图像生成领域近期取得了巨大的进步,扩散模型能够根据各种各样的文本提示合成令人信服的图像。本文提出了一种名为 DiffEdit 的方法,利用文本条件扩散模型进行语义图像编辑任务,该任务的目标是根据文本查询编辑图像。语义图像编辑是图像生成的扩展,但增加了额外的约束条件,即生成的图像应尽可能与给定的输入图像相似。目前基于扩散模型的编辑方法通常需要提供掩码,通过将其视为条件修复任务来简化任务。相比之下,我们的主要贡献在于能够自动生成突出显示需要编辑的输入图像区域的掩码,方法是对比在不同文本提示下扩散模型的预测结果。此外,我们依靠潜在推理来保留感兴趣区域的内容,并展示了与基于掩码的扩散模型的出色协同作用。DiffEdit 在 ImageNet 上实现了最先进的编辑性能。此外,我们还在更具挑战性的环境中评估了语义图像编辑,使用了来自 COCO 数据集的图像以及基于文本生成的图像。
原始代码库可以在 Xiang-cd/DiffEdit-stable-diffusion 找到,你可以在这个 演示 中尝试它。
此管道由 clarencechen 贡献。 ❤️
提示
- 该管道可以生成可以馈送到其他修复管道的掩码。
- 为了使用此管道生成图像,在调用管道生成最终编辑图像时,**必须**提供图像掩码(可以手动指定或生成源和目标提示,并传递给 generate_mask())和一组部分反转的潜在变量(使用 invert() 生成)作为参数。
- 函数 generate_mask() 公开了两个提示参数,
source_prompt
和target_prompt
,它们允许您控制最终生成的图像中语义编辑的位置。例如,您想将“猫”转换为“狗”。在这种情况下,编辑方向将是“猫 -> 狗”。为了在生成的掩码中反映这一点,您只需将包含“猫”的短语相关的嵌入设置为source_prompt
,将“狗”相关的嵌入设置为target_prompt
。 - 使用
invert
生成部分反转的潜在变量时,将描述整体图像的标题或文本嵌入分配给prompt
参数,以帮助指导逆潜在采样过程。在大多数情况下,源概念具有足够的描述性以产生良好的结果,但请随意探索其他方案。 - 调用管道生成最终编辑图像时,将源概念分配给
negative_prompt
,将目标概念分配给prompt
。以上述示例为例,您只需将包含“猫”的短语相关的嵌入设置为negative_prompt
,将“狗”相关的嵌入设置为prompt
。 - 如果您想反转上面示例中的方向,即“狗 -> 猫”,则建议:
- 在
generate_mask
的参数中交换source_prompt
和target_prompt
。 - 将 invert() 中的输入提示更改为包含“狗”。
- 在调用管道以生成最终编辑图像的参数中交换
prompt
和negative_prompt
。
- 在
- 源和目标提示,或其相应的嵌入,也可以自动生成。请参阅 DiffEdit 指南以了解更多详细信息。
StableDiffusionDiffEditPipeline
类 diffusers.StableDiffusionDiffEditPipeline
< 源代码 >( vae: AutoencoderKL text_encoder: CLIPTextModel tokenizer: CLIPTokenizer unet: UNet2DConditionModel scheduler: KarrasDiffusionSchedulers safety_checker: StableDiffusionSafetyChecker feature_extractor: CLIPImageProcessor inverse_scheduler: DDIMInverseScheduler requires_safety_checker: bool = True )
参数
- vae (AutoencoderKL) — 用于将图像编码和解码为潜在表示的变分自动编码器 (VAE) 模型。
- text_encoder (CLIPTextModel) — 冻结的文本编码器 (clip-vit-large-patch14)。
- tokenizer (CLIPTokenizer) — 用于分词文本的
CLIPTokenizer
。 - unet (UNet2DConditionModel) — 用于对编码图像潜在变量进行去噪的
UNet2DConditionModel
。 - scheduler (SchedulerMixin) — 用于结合
unet
对编码图像潜在变量进行去噪的调度器。 - inverse_scheduler (DDIMInverseScheduler) — 用于结合
unet
填充输入潜在变量中未掩盖部分的调度器。 - safety_checker (
StableDiffusionSafetyChecker
) — 用于评估生成图像是否可能被认为具有攻击性或有害的分类模块。请参阅模型卡片,了解有关模型潜在危害的更多详细信息。 - feature_extractor (CLIPImageProcessor) — 用于从生成图像中提取特征的
CLIPImageProcessor
;用作safety_checker
的输入。
这是一个实验性功能!
使用 Stable Diffusion 和 DiffEdit 进行文本引导图像修复的管道。
此模型继承自 DiffusionPipeline。请查看超类文档以了解为所有管道实现的通用方法(下载、保存、在特定设备上运行等)。
该管道还继承了以下加载和保存方法
- load_textual_inversion() 用于加载文本反转嵌入
- load_lora_weights() 用于加载 LoRA 权重
- save_lora_weights() 用于保存 LoRA 权重
generate_mask
< 源代码 >( image: Union = None target_prompt: Union = None target_negative_prompt: Union = None target_prompt_embeds: Optional = None target_negative_prompt_embeds: Optional = None source_prompt: Union = None source_negative_prompt: Union = None source_prompt_embeds: Optional = None source_negative_prompt_embeds: Optional = None num_maps_per_mask: Optional = 10 mask_encode_strength: Optional = 0.5 mask_thresholding_ratio: Optional = 3.0 num_inference_steps: int = 50 guidance_scale: float = 7.5 generator: Union = None output_type: Optional = 'np' cross_attention_kwargs: Optional = None ) → List[PIL.Image.Image]
或 np.array
参数
- image (
PIL.Image.Image
) — 用于计算掩码的图像批次的Image
或张量。 - target_prompt (
str
或List[str]
, 可选) — 用于指导语义掩码生成的提示或提示。如果未定义,则需要传递prompt_embeds
。 - target_negative_prompt (
str
或List[str]
, 可选) — 用于指导图像生成中不应包含什么的提示或提示。如果未定义,则需要改为传递negative_prompt_embeds
。在不使用引导时被忽略 (guidance_scale < 1
)。 - target_prompt_embeds (
torch.Tensor
,可选) — 预生成的文本嵌入。可用于轻松调整文本输入(提示加权)。如果未提供,则从prompt
输入参数生成文本嵌入。 - target_negative_prompt_embeds (
torch.Tensor
,可选) — 预生成的负文本嵌入。可用于轻松调整文本输入(提示加权)。如果未提供,则从negative_prompt
输入参数生成negative_prompt_embeds
。 - source_prompt (
str
或List[str]
,可选) — 用于使用 DiffEdit 指导语义掩码生成的提示或提示。如果未定义,则需要改为传递source_prompt_embeds
或source_image
。 - source_negative_prompt (
str
或List[str]
,可选) — 用于引导语义掩码生成避免使用 DiffEdit 的提示或提示。如果未定义,则需要改为传递source_negative_prompt_embeds
或source_image
。 - source_prompt_embeds (
torch.Tensor
,可选) — 预生成的文本嵌入,用于指导语义掩码生成。可用于轻松调整文本输入(提示加权)。如果未提供,则从source_prompt
输入参数生成文本嵌入。 - source_negative_prompt_embeds (
torch.Tensor
,可选) — 预生成的文本嵌入,用于负向引导语义掩码生成。可用于轻松调整文本输入(提示加权)。如果未提供,则从source_negative_prompt
输入参数生成文本嵌入。 - num_maps_per_mask (
int
,可选,默认为 10) — 使用 DiffEdit 生成语义掩码时采样的噪声图数量。 - mask_encode_strength (
float
,可选,默认为 0.5) — 使用 DiffEdit 生成语义掩码时采样的噪声图的强度。必须在 0 到 1 之间。 - mask_thresholding_ratio (
float
,可选,默认为 3.0) — 在掩码二值化之前,用于对语义引导图进行钳位以限制其最大值的平均绝对差的倍数。 - num_inference_steps (
int
,可选,默认为 50) — 降噪步骤的数量。更多的降噪步骤通常会导致更高的图像质量,但推理速度会变慢。 - output_type (
str
, 可选, 默认为"pil"
) — 生成的图像的输出格式。在PIL.Image
或np.array
之间选择。 - cross_attention_kwargs (
dict
, 可选) — 如果指定,则传递给 AttnProcessor 的关键字参数字典,如self.processor
中定义。
返回值
List[PIL.Image.Image]
或 np.array
当返回 List[PIL.Image.Image]
时,该列表包含一批尺寸为 (height // self.vae_scale_factor, width // self.vae_scale_factor)
的单通道二值图像。如果是 np.array
,则形状为 (batch_size, height // self.vae_scale_factor, width // self.vae_scale_factor)
。
给定掩码提示、目标提示和图像生成潜在掩码。
>>> import PIL
>>> import requests
>>> import torch
>>> from io import BytesIO
>>> from diffusers import StableDiffusionDiffEditPipeline
>>> def download_image(url):
... response = requests.get(url)
... return PIL.Image.open(BytesIO(response.content)).convert("RGB")
>>> img_url = "https://github.com/Xiang-cd/DiffEdit-stable-diffusion/raw/main/assets/origin.png"
>>> init_image = download_image(img_url).resize((768, 768))
>>> pipeline = StableDiffusionDiffEditPipeline.from_pretrained(
... "stabilityai/stable-diffusion-2-1", torch_dtype=torch.float16
... )
>>> pipeline.scheduler = DDIMScheduler.from_config(pipeline.scheduler.config)
>>> pipeline.inverse_scheduler = DDIMInverseScheduler.from_config(pipeline.scheduler.config)
>>> pipeline.enable_model_cpu_offload()
>>> mask_prompt = "A bowl of fruits"
>>> prompt = "A bowl of pears"
>>> mask_image = pipeline.generate_mask(image=init_image, source_prompt=prompt, target_prompt=mask_prompt)
>>> image_latents = pipeline.invert(image=init_image, prompt=mask_prompt).latents
>>> image = pipeline(prompt=prompt, mask_image=mask_image, image_latents=image_latents).images[0]
反转
< source > ( prompt: Union = None image: Union = None num_inference_steps: int = 50 inpaint_strength: float = 0.8 guidance_scale: float = 7.5 negative_prompt: Union = None generator: Union = None prompt_embeds: Optional = None negative_prompt_embeds: Optional = None decode_latents: bool = False output_type: Optional = 'pil' return_dict: bool = True callback: Optional = None callback_steps: Optional = 1 cross_attention_kwargs: Optional = None lambda_auto_corr: float = 20.0 lambda_kl: float = 20.0 num_reg_steps: int = 0 num_auto_corr_rolls: int = 5 )
参数
- prompt (
str
或List[str]
, 可选) — 指导图像生成的提示或提示。如果未定义,则需要传递prompt_embeds
。 - image (
PIL.Image.Image
) — 表示图像批次的Image
或张量,用于生成由prompt
指导的反转潜在变量。 - inpaint_strength (
float
, 可选, 默认为 0.8) — 指示潜在反转运行噪声过程的程度。必须介于 0 和 1 之间。当inpaint_strength
为 1 时,反转过程将针对num_inference_steps
中指定的完整迭代次数运行。image
用作反转过程的参考,添加更多噪声会增加inpaint_strength
。如果inpaint_strength
为 0,则不会发生修复。 - num_inference_steps (
int
, 可选, 默认为 50) — 降噪步骤的数量。更多的降噪步骤通常会导致更高的图像质量,但会以更慢的推理为代价。 - guidance_scale (
float
, 可选,默认为 7.5) — 更高的引导尺度值鼓励模型生成与文本prompt
密切相关的图像,但会以降低图像质量为代价。当guidance_scale > 1
时启用引导尺度。 - negative_prompt (
str
或List[str]
, 可选) — 用于指导图像生成中不包含什么的提示或提示。如果未定义,则需要传递negative_prompt_embeds
。在不使用引导(guidance_scale < 1
)时忽略。 - generator (
torch.Generator
, 可选) — 用于使生成确定性的torch.Generator
。 - prompt_embeds (
torch.Tensor
, 可选) — 预生成的文本嵌入。可用于轻松调整文本输入(提示加权)。如果未提供,则从prompt
输入参数生成文本嵌入。 - negative_prompt_embeds (
torch.Tensor
, 可选) — 预生成的负文本嵌入。可用于轻松调整文本输入(提示加权)。如果未提供,则从negative_prompt
输入参数生成negative_prompt_embeds
。 - decode_latents (
bool
, 可选,默认为False
) — 是否将反转的潜在变量解码为生成的图像。将此参数设置为True
会将每个时间步长的所有反转潜在变量解码为生成的图像列表。 - output_type (
str
, 可选,默认为"pil"
) — 生成的图像的输出格式。在PIL.Image
或np.array
之间选择。 - return_dict (
bool
, 可选,默认为True
) — 是否返回~pipelines.stable_diffusion.DiffEditInversionPipelineOutput
而不是普通元组。 - callback (
Callable
, 可选) — 在推理过程中每隔callback_steps
步调用一次的函数。该函数使用以下参数调用:callback(step: int, timestep: int, latents: torch.Tensor)
。 - callback_steps (
int
, 可选,默认为 1) — 调用callback
函数的频率。如果未指定,则在每个步骤都调用回调。 - lambda_kl (
float
,可选,默认为 20.0) — 控制 Kullback-Leibler 散度输出的 Lambda 参数。 - num_reg_steps (
int
,可选,默认为 0) — 正则化损失步骤的数量。 - num_auto_corr_rolls (
int
,可选,默认为 5) — 自动校正滚动步骤的数量。
根据提示和图像生成反转后的潜变量。
>>> import PIL
>>> import requests
>>> import torch
>>> from io import BytesIO
>>> from diffusers import StableDiffusionDiffEditPipeline
>>> def download_image(url):
... response = requests.get(url)
... return PIL.Image.open(BytesIO(response.content)).convert("RGB")
>>> img_url = "https://github.com/Xiang-cd/DiffEdit-stable-diffusion/raw/main/assets/origin.png"
>>> init_image = download_image(img_url).resize((768, 768))
>>> pipeline = StableDiffusionDiffEditPipeline.from_pretrained(
... "stabilityai/stable-diffusion-2-1", torch_dtype=torch.float16
... )
>>> pipeline.scheduler = DDIMScheduler.from_config(pipeline.scheduler.config)
>>> pipeline.inverse_scheduler = DDIMInverseScheduler.from_config(pipeline.scheduler.config)
>>> pipeline.enable_model_cpu_offload()
>>> prompt = "A bowl of fruits"
>>> inverted_latents = pipeline.invert(image=init_image, prompt=prompt).latents
__call__
< source > ( prompt: Union = None mask_image: Union = None image_latents: Union = None inpaint_strength: Optional = 0.8 num_inference_steps: int = 50 guidance_scale: float = 7.5 negative_prompt: Union = None num_images_per_prompt: Optional = 1 eta: float = 0.0 generator: Union = None latents: Optional = None prompt_embeds: Optional = None negative_prompt_embeds: Optional = None output_type: Optional = 'pil' return_dict: bool = True callback: Optional = None callback_steps: int = 1 cross_attention_kwargs: Optional = None clip_skip: int = None ) → StableDiffusionPipelineOutput 或 tuple
参数
- prompt (
str
或List[str]
,可选) — 指导图像生成的提示或提示列表。如果未定义,则需要传递prompt_embeds
。 - mask_image (
PIL.Image.Image
) — 表示用于遮蔽生成图像的图像批次的Image
或张量。掩码中的白色像素会被重新绘制,而黑色像素会被保留。如果mask_image
是 PIL 图像,则在使用前将其转换为单通道(亮度)。如果它是张量,则它应该包含一个颜色通道(L)而不是 3,因此预期的形状将是(B, 1, H, W)
。 - image_latents (
PIL.Image.Image
或torch.Tensor
) — 来自反演过程的部分噪声图像潜变量,用作图像生成的输入。 - inpaint_strength (
float
, 可选,默认为 0.8) — 指示修复蒙版区域的程度。必须介于 0 和 1 之间。当inpaint_strength
为 1 时,降噪过程将在蒙版区域上运行num_inference_steps
中指定的完整迭代次数。image_latents
用作蒙版区域的参考,并且向区域添加更多噪声会增加inpaint_strength
。如果inpaint_strength
为 0,则不会进行修复。 - num_inference_steps (
int
, 可选,默认为 50) — 降噪步骤的数量。更多的降噪步骤通常会导致更高质量的图像,但会以推理速度变慢为代价。 - guidance_scale (
float
, 可选,默认为 7.5) — 更高的引导尺度值鼓励模型生成与文本prompt
密切相关的图像,但会以降低图像质量为代价。当guidance_scale > 1
时启用引导尺度。 - negative_prompt (
str
或List[str]
, 可选) — 指导图像生成中不包含什么的提示或提示。如果未定义,则需要传递negative_prompt_embeds
。在不使用引导(guidance_scale < 1
)时忽略。 - num_images_per_prompt (
int
, 可选,默认为 1) — 每个提示生成的图像数量。 - eta (
float
, 可选,默认为 0.0) — 对应于来自 DDIM 论文的参数 eta (η)。仅适用于 DDIMScheduler,并在其他调度器中被忽略。 - generator (
torch.Generator
, 可选) — 用于使生成确定性的torch.Generator
。 - latents (
torch.Tensor
, 可选) — 从高斯分布中采样的预生成噪声潜在变量,用作图像生成的输入。可用于使用不同的提示调整相同的生成。如果未提供,则通过使用提供的随机generator
采样生成潜在变量张量。 - prompt_embeds (
torch.Tensor
, 可选) — 预生成的文本嵌入。可用于轻松调整文本输入(提示加权)。如果未提供,则从prompt
输入参数生成文本嵌入。 - negative_prompt_embeds (
torch.Tensor
, 可选) — 预生成的负文本嵌入。可用于轻松调整文本输入(提示加权)。如果未提供,则从negative_prompt
输入参数生成negative_prompt_embeds
。 - 输出类型 (
str
, 可选, 默认为"pil"
) — 生成的图像的输出格式。在PIL.Image
或np.array
之间选择。 - 返回字典 (
bool
, 可选, 默认为True
) — 是否返回 StableDiffusionPipelineOutput 而不是普通元组。 - 回调函数 (
Callable
, 可选) — 在推理过程中每隔callback_steps
步调用一次的函数。该函数使用以下参数调用:callback(step: int, timestep: int, latents: torch.Tensor)
。 - 回调步长 (
int
, 可选, 默认为 1) — 调用callback
函数的频率。如果未指定,则在每个步骤都调用回调函数。 - 交叉注意力关键字参数 (
dict
, 可选) — 如果指定,则传递给self.processor
中定义的AttentionProcessor
的关键字参数字典。 - CLIP 跳过层数 (
int
, 可选) — 计算提示嵌入时应跳过的 CLIP 层数。值为 1 表示将使用倒数第二层的输出计算提示嵌入。
返回值
StableDiffusionPipelineOutput 或 tuple
如果 return_dict
为 True
,则返回 StableDiffusionPipelineOutput,否则返回一个 tuple
,其中第一个元素是一个包含生成图像的列表,第二个元素是一个包含 bool
值的列表,指示相应的生成图像是否包含“不适合工作场所”(nsfw)内容。
用于生成图像的管道调用函数。
>>> import PIL
>>> import requests
>>> import torch
>>> from io import BytesIO
>>> from diffusers import StableDiffusionDiffEditPipeline
>>> def download_image(url):
... response = requests.get(url)
... return PIL.Image.open(BytesIO(response.content)).convert("RGB")
>>> img_url = "https://github.com/Xiang-cd/DiffEdit-stable-diffusion/raw/main/assets/origin.png"
>>> init_image = download_image(img_url).resize((768, 768))
>>> pipeline = StableDiffusionDiffEditPipeline.from_pretrained(
... "stabilityai/stable-diffusion-2-1", torch_dtype=torch.float16
... )
>>> pipeline.scheduler = DDIMScheduler.from_config(pipeline.scheduler.config)
>>> pipeline.inverse_scheduler = DDIMInverseScheduler.from_config(pipeline.scheduler.config)
>>> pipeline.enable_model_cpu_offload()
>>> mask_prompt = "A bowl of fruits"
>>> prompt = "A bowl of pears"
>>> mask_image = pipeline.generate_mask(image=init_image, source_prompt=prompt, target_prompt=mask_prompt)
>>> image_latents = pipeline.invert(image=init_image, prompt=mask_prompt).latents
>>> image = pipeline(prompt=prompt, mask_image=mask_image, image_latents=image_latents).images[0]
编码提示
< source > ( 提示 设备 每个提示的图像数量 是否使用分类器免费引导 负面提示 = None 提示嵌入: Optional = None 负面提示嵌入: Optional = None LoRA 比例: Optional = None CLIP 跳过层数: Optional = None )
参数
- 提示 (
str
或List[str]
, 可选) — 要编码的提示 device — (torch.device
): torch 设备 - 每个提示的图像数量 (
int
) — 每个提示应生成的图像数量 - do_classifier_free_guidance (
bool
) — 是否使用分类器免费引导 - negative_prompt (
str
或List[str]
, 可选) — 不引导图像生成的提示或提示列表。如果未定义,则必须传递negative_prompt_embeds
。在不使用引导时忽略(即,如果guidance_scale
小于1
,则忽略)。 - prompt_embeds (
torch.Tensor
, 可选) — 预生成的文本嵌入。可用于轻松调整文本输入,例如提示加权。如果未提供,则将从prompt
输入参数生成文本嵌入。 - negative_prompt_embeds (
torch.Tensor
, 可选) — 预生成的负文本嵌入。可用于轻松调整文本输入,例如提示加权。如果未提供,则将从negative_prompt
输入参数生成negative_prompt_embeds
。 - lora_scale (
float
, 可选) — 如果加载了 LoRA 层,则将应用于文本编码器所有 LoRA 层的 LoRA 比例。 - clip_skip (
int
, 可选) — 在计算提示嵌入时要从 CLIP 跳过的层数。值为 1 表示将使用倒数第二层的输出计算提示嵌入。
将提示编码为文本编码器隐藏状态。
StableDiffusionPipelineOutput
类 diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput
< 源代码 >( images: Union nsfw_content_detected: Optional )
Stable Diffusion 管道的输出类。