香肠(Würstchen)
Wuerstchen:一种用于大规模文本到图像扩散模型的高效架构 是由 Pablo Pernias、Dominic Rampas、Mats L. Richter、Christopher Pal 和 Marc Aubreville 撰写。
论文的摘要如下:
我们引入了 Würstchen,这是一种用于文本到图像合成的全新架构,它将具有竞争力的性能与大规模文本到图像扩散模型前所未有的成本效益相结合。我们工作的一个关键贡献是开发了一种潜在扩散技术,其中我们学习了一种详细但极其紧凑的语义图像表示,用于指导扩散过程。与语言的潜在表示相比,这种高度压缩的图像表示提供了更详细的指导,这大大降低了实现最先进结果的计算需求。根据我们的用户偏好研究,我们的方法还提高了基于文本条件的图像生成的质量。我们的方法的训练需求为 24,602 个 A100-GPU 小时——相比之下,Stable Diffusion 2.1 的训练需求为 200,000 个 GPU 小时。我们的方法还需要更少的训练数据才能获得这些结果。此外,我们紧凑的潜在表示使我们能够将推理速度提高两倍以上,大幅降低了最先进 (SOTA) 扩散模型的常规成本和碳足迹,而不会影响最终性能。在与 SOTA 模型的更广泛比较中,我们的方法在效率方面大大提高,并在图像质量方面具有优势。我们认为,这项工作促使人们更加重视性能和计算可访问性的优先级。
香肠概述
Würstchen 是一种扩散模型,其文本条件模型在图像的高度压缩潜在空间中工作。为什么这很重要?压缩数据可以将训练和推理的计算成本降低几个数量级。在 1024x1024 图像上进行训练比在 32x32 图像上进行训练要昂贵得多。通常,其他工作使用相对较小的压缩,空间压缩范围为 4x - 8x。Würstchen 将此推向了极致。通过其新颖的设计,我们实现了 42x 的空间压缩。这以前从未见过,因为常见的方法在 16x 空间压缩后无法忠实地重建详细的图像。Würstchen 采用两阶段压缩,我们称之为 A 阶段和 B 阶段。A 阶段是 VQGAN,B 阶段是扩散自动编码器(更多详细信息可在论文中找到)。在那个高度压缩的潜在空间中学习了第三个模型,即 C 阶段。这种训练只需要当前顶级模型所用计算量的一小部分,同时还允许更便宜、更快的推理。
香肠 v2 进入 Diffusers
在最初的论文发布后,我们在架构、训练和采样方面改进了许多内容,使 Würstchen 在许多方面都能够与当前最先进的模型相媲美。我们很高兴与 Diffusers 一起发布这个新版本。以下是改进列表。
- 更高分辨率(1024x1024 至 2048x2048)
- 更快的推理速度
- 多方面分辨率采样
- 更好的质量
我们为文本条件图像生成模型(C 阶段)发布了 3 个检查点。它们是
- v2-base
- v2-aesthetic
- (默认)v2-interpolated(v2-base 和 v2-aesthetic 之间的 50% 插值)
我们建议使用 v2-interpolated,因为它兼具逼真和美学效果。使用 v2-base 进行微调,因为它没有风格偏差;使用 v2-aesthetic 进行非常艺术化的生成。此处可以进行比较
文本到图像生成
为了易用性,Würstchen 可以与单个管道一起使用。此管道可以按如下方式使用
import torch
from diffusers import AutoPipelineForText2Image
from diffusers.pipelines.wuerstchen import DEFAULT_STAGE_C_TIMESTEPS
pipe = AutoPipelineForText2Image.from_pretrained("warp-ai/wuerstchen", torch_dtype=torch.float16).to("cuda")
caption = "Anthropomorphic cat dressed as a fire fighter"
images = pipe(
caption,
width=1024,
height=1536,
prior_timesteps=DEFAULT_STAGE_C_TIMESTEPS,
prior_guidance_scale=4.0,
num_images_per_prompt=2,
).images
出于解释目的,我们还可以分别初始化 Würstchen 的两个主要管道。Würstchen 由 3 个阶段组成:C 阶段、B 阶段、A 阶段。它们都有不同的工作,并且只能协同工作。在生成文本条件图像时,C 阶段将首先在高度压缩的潜在空间中生成潜在变量。这就是 prior_pipeline
中发生的事情。之后,生成的潜在变量将传递到 B 阶段,该阶段将潜在变量解压缩到 VQGAN 的更大潜在空间中。然后,这些潜在变量可以通过 A 阶段(VQGAN)解码到像素空间。B 阶段和 A 阶段都封装在 decoder_pipeline
中。有关更多详细信息,请查看论文。
import torch
from diffusers import WuerstchenDecoderPipeline, WuerstchenPriorPipeline
from diffusers.pipelines.wuerstchen import DEFAULT_STAGE_C_TIMESTEPS
device = "cuda"
dtype = torch.float16
num_images_per_prompt = 2
prior_pipeline = WuerstchenPriorPipeline.from_pretrained(
"warp-ai/wuerstchen-prior", torch_dtype=dtype
).to(device)
decoder_pipeline = WuerstchenDecoderPipeline.from_pretrained(
"warp-ai/wuerstchen", torch_dtype=dtype
).to(device)
caption = "Anthropomorphic cat dressed as a fire fighter"
negative_prompt = ""
prior_output = prior_pipeline(
prompt=caption,
height=1024,
width=1536,
timesteps=DEFAULT_STAGE_C_TIMESTEPS,
negative_prompt=negative_prompt,
guidance_scale=4.0,
num_images_per_prompt=num_images_per_prompt,
)
decoder_output = decoder_pipeline(
image_embeddings=prior_output.image_embeddings,
prompt=caption,
negative_prompt=negative_prompt,
guidance_scale=0.0,
output_type="pil",
).images[0]
decoder_output
加速推理
您可以使用 torch.compile
函数,并获得大约 2-3 倍的速度提升。
prior_pipeline.prior = torch.compile(prior_pipeline.prior, mode="reduce-overhead", fullgraph=True)
decoder_pipeline.decoder = torch.compile(decoder_pipeline.decoder, mode="reduce-overhead", fullgraph=True)
局限性
- 由于 Würstchen 采用了高压缩,因此生成的结果可能缺乏大量的细节。对于我们人类的眼睛来说,这在面部、手等部位尤其明显。
- 图像只能以 128 像素的步长生成,例如,1024x1024 的下一个更高分辨率是 1152x1152。
- 该模型缺乏在图像中渲染正确文本的能力。
- 该模型通常无法实现照片级真实感。
- 该模型难以处理复杂的构图提示。
原始代码库以及实验性想法可以在dome272/Wuerstchen中找到。
WuerstchenCombinedPipeline
class diffusers.WuerstchenCombinedPipeline
< 源代码 >( tokenizer: CLIPTokenizer text_encoder: CLIPTextModel decoder: WuerstchenDiffNeXt scheduler: DDPMWuerstchenScheduler vqgan: PaellaVQModel prior_tokenizer: CLIPTokenizer prior_text_encoder: CLIPTextModel prior_prior: WuerstchenPrior prior_scheduler: DDPMWuerstchenScheduler )
参数
- tokenizer (
CLIPTokenizer
) — 用于文本输入的解码器分词器。 - text_encoder (
CLIPTextModel
) — 用于文本输入的解码器文本编码器。 - decoder (
WuerstchenDiffNeXt
) — 用于解码器图像生成管线的解码器模型。 - scheduler (
DDPMWuerstchenScheduler
) — 用于解码器图像生成管线的调度器。 - vqgan (
PaellaVQModel
) — 用于解码器图像生成管线的VQGAN模型。 - prior_tokenizer (
CLIPTokenizer
) — 用于文本输入的先验分词器。 - prior_text_encoder (
CLIPTextModel
) — 用于文本输入的先验文本编码器。 - prior_prior (
WuerstchenPrior
) — 用于先验管线的先验模型。 - prior_scheduler (
DDPMWuerstchenScheduler
) — 用于先验管线的调度器。
使用Wuerstchen进行文本到图像生成的组合管道
此模型继承自 DiffusionPipeline。请查看超类文档以了解库为所有管道实现的通用方法(例如下载或保存、在特定设备上运行等)。
__call__
< ( prompt: Union = None height: int = 512 width: int = 512 prior_num_inference_steps: int = 60 prior_timesteps: Optional = None prior_guidance_scale: float = 4.0 num_inference_steps: int = 12 decoder_timesteps: Optional = None decoder_guidance_scale: float = 0.0 negative_prompt: Union = None prompt_embeds: Optional = None negative_prompt_embeds: Optional = None num_images_per_prompt: int = 1 generator: Union = None latents: Optional = None output_type: Optional = 'pil' return_dict: bool = True prior_callback_on_step_end: Optional = None prior_callback_on_step_end_tensor_inputs: List = ['latents'] callback_on_step_end: Optional = None callback_on_step_end_tensor_inputs: List = ['latents'] **kwargs )参数
- prompt (
str
或List[str]
) — 用于引导先验和解码器的图像生成的提示或提示。 - negative_prompt (
str
或List[str]
, 可选) — 不用于引导图像生成的提示或提示。在不使用引导时被忽略(即,如果guidance_scale
小于1
则被忽略)。 - prompt_embeds (
torch.Tensor
, 可选) — 先验的预生成文本嵌入。可用于轻松调整文本输入,例如提示加权。如果未提供,则将从prompt
输入参数生成文本嵌入。 - negative_prompt_embeds (
torch.Tensor
, 可选) — 先验的预生成负文本嵌入。可用于轻松调整文本输入,例如提示加权。如果未提供,则将从negative_prompt
输入参数生成negative_prompt_embeds
。 - num_images_per_prompt (
int
, 可选,默认为 1) — 每个提示生成的图像数量。 - height (
int
, 可选,默认为 512) — 生成的图像的高度(以像素为单位)。 - width (
int
, 可选,默认为 512) — 生成的图像的宽度(以像素为单位)。 - prior_guidance_scale (
float
, 可选,默认为 4.0) — 如 Classifier-Free Diffusion Guidance 中所定义的引导尺度。prior_guidance_scale
定义为 Imagen 论文 公式 2 中的w
。通过设置prior_guidance_scale > 1
来启用引导尺度。较高的引导尺度鼓励生成与文本prompt
密切相关的图像,通常以降低图像质量为代价。 - prior_num_inference_steps (
Union[int, Dict[float, int]]
,可选,默认为 60) — 先验去噪步骤的数量。更多的去噪步骤通常会导致更高的图像质量,但会降低推理速度。 为了更具体的步长间隔,您可以传递自定义的prior_timesteps
- num_inference_steps (
int
,可选,默认为 12) — 解码器去噪步骤的数量。更多的去噪步骤通常会导致更高的图像质量,但会降低推理速度。 为了更具体的步长间隔,您可以传递自定义的timesteps
- prior_timesteps (
List[float]
,可选) — 用于先验去噪过程的自定义时间步长。 如果未定义,则使用等间距的prior_num_inference_steps
时间步长。 必须按降序排列。 - decoder_timesteps (
List[float]
,可选) — 用于解码器去噪过程的自定义时间步长。 如果未定义,则使用等间距的num_inference_steps
时间步长。 必须按降序排列。 - decoder_guidance_scale (
float
,可选,默认为 0.0) — 指导尺度,如 Classifier-Free Diffusion Guidance 中所定义。guidance_scale
定义为 Imagen 论文 公式 2 中的w
。 通过设置guidance_scale > 1
来启用引导尺度。 更高的引导尺度鼓励生成与文本prompt
密切相关的图像,通常以降低图像质量为代价。 - generator (
torch.Generator
或List[torch.Generator]
,可选) — 一个或多个 torch 生成器,用于使生成确定性。 - latents (
torch.Tensor
,可选) — 预生成的噪声潜在变量,从高斯分布中采样,用作图像生成的输入。 可用于使用不同的提示调整相同的生成。 如果未提供,则将通过使用提供的随机generator
采样生成潜在变量张量。 - output_type (
str
,可选,默认为"pil"
) — 生成的图像的输出格式。 在以下选项中选择:"pil"
(PIL.Image.Image
)、"np"
(np.array
) 或"pt"
(torch.Tensor
)。 - return_dict (
bool
,可选,默认为True
) — 是否返回 ImagePipelineOutput 而不是普通元组。 - prior_callback_on_step_end (
Callable
,可选) — 在推理过程中每次去噪步骤结束时调用的函数。 该函数使用以下参数调用:prior_callback_on_step_end(self: DiffusionPipeline, step: int, timestep: int, callback_kwargs: Dict)
。 - prior_callback_on_step_end_tensor_inputs (
List
, 可选) —prior_callback_on_step_end
函数的张量输入列表。列表中指定的张量将作为callback_kwargs
参数传递。您只能包含管道类._callback_tensor_inputs
属性中列出的变量。 - callback_on_step_end (
Callable
, 可选) — 推理过程中每个去噪步骤结束时调用的函数。该函数使用以下参数调用:callback_on_step_end(self: DiffusionPipeline, step: int, timestep: int, callback_kwargs: Dict)
。callback_kwargs
将包含由callback_on_step_end_tensor_inputs
指定的所有张量的列表。 - callback_on_step_end_tensor_inputs (
List
, 可选) —callback_on_step_end
函数的张量输入列表。列表中指定的张量将作为callback_kwargs
参数传递。您只能包含管道类._callback_tensor_inputs
属性中列出的变量。
调用管道进行生成时调用的函数。
使用 accelerate 将所有模型卸载到 CPU,减少内存使用,对性能的影响很小。与 enable_sequential_cpu_offload
相比,此方法在调用模型的 forward
方法时将一个完整的模型一次性移动到 GPU,并且该模型会保留在 GPU 中,直到下一个模型运行。内存节省量低于 enable_sequential_cpu_offload
,但由于 unet
的迭代执行,性能要好得多。
使用 🤗 Accelerate 将所有模型(unet
、text_encoder
、vae
和 safety checker
状态字典)卸载到 CPU,显着减少内存使用。模型被移动到 torch.device('meta')
,并且仅在调用其特定子模块的 forward
方法时才会加载到 GPU 上。卸载在子模块的基础上进行。内存节省量高于使用 enable_model_cpu_offload
,但性能较低。
WuerstchenPriorPipeline
类 diffusers.WuerstchenPriorPipeline
< 源代码 >( tokenizer: CLIPTokenizer text_encoder: CLIPTextModel prior: WuerstchenPrior scheduler: DDPMWuerstchenScheduler latent_mean: float = 42.0 latent_std: float = 1.0 resolution_multiple: float = 42.67 )
参数
- prior (
Prior
) — 用于从文本嵌入近似图像嵌入的规范 unCLIP 先验。 - text_encoder (
CLIPTextModelWithProjection
) — 冻结的文本编码器。 - 分词器 (
CLIPTokenizer
) — 类 CLIPTokenizer 的分词器。 - 调度器 (
DDPMWuerstchenScheduler
) — 用于结合prior
生成图像嵌入的调度器。 - 潜在变量均值 (‘float’, 可选, 默认为 42.0) — 潜在扩散模型的均值。
- 潜在变量标准差 (‘float’, 可选, 默认为 1.0) — 潜在扩散模型的标准差。
- 分辨率倍数 (‘float’, 可选, 默认为 42.67) — 生成多个图像的默认分辨率。
用于生成 Wuerstchen 图像先验的管道。
此模型继承自 DiffusionPipeline。请查看超类文档以了解库为所有管道实现的通用方法(例如下载或保存、在特定设备上运行等)。
该管道还继承了以下加载方法
- load_lora_weights() 用于加载 LoRA 权重
- save_lora_weights() 用于保存 LoRA 权重
__call__
< 源代码 >( 提示: Union = None 高度: int = 1024 宽度: int = 1024 推理步骤数: int = 60 时间步长: List = None 引导尺度: float = 8.0 负向提示: Union = None 提示嵌入: Optional = None 负向提示嵌入: Optional = None 每个提示的图像数量: Optional = 1 生成器: Union = None 潜在变量: Optional = None 输出类型: Optional = 'pt' 返回字典: bool = True 步骤结束回调: Optional = None 步骤结束回调张量输入: List = ['latents'] **kwargs )
参数
- 提示 (
str
或List[str]
) — 指导图像生成的提示或提示列表。 - 高度 (
int
, 可选, 默认为 1024) — 生成的图像的高度(以像素为单位)。 - 宽度 (
int
, 可选, 默认为 1024) — 生成的图像的宽度(以像素为单位)。 - num_inference_steps (
int
,可选,默认为 60) — 降噪步骤的数量。更多的降噪步骤通常会导致更高的图像质量,但会以更慢的推理为代价。 - timesteps (
List[int]
,可选) — 用于降噪过程的自定义时间步长。如果未定义,则使用等间距的num_inference_steps
时间步长。必须按降序排列。 - guidance_scale (
float
,可选,默认为 8.0) — 如 Classifier-Free Diffusion Guidance 中所定义的引导尺度。decoder_guidance_scale
定义为 Imagen 论文 公式 2 中的w
。通过将decoder_guidance_scale > 1
来启用引导尺度。较高的引导尺度鼓励生成与文本prompt
密切相关的图像,通常以降低图像质量为代价。 - negative_prompt (
str
或List[str]
,可选) — 不引导图像生成的提示或提示。在不使用引导时被忽略(即,如果decoder_guidance_scale
小于1
则被忽略)。 - prompt_embeds (
torch.Tensor
,可选) — 预生成的文本嵌入。可用于轻松调整文本输入,例如提示加权。如果未提供,则将根据prompt
输入参数生成文本嵌入。 - negative_prompt_embeds (
torch.Tensor
,可选) — 预生成的负文本嵌入。可用于轻松调整文本输入,例如提示加权。如果未提供,则将根据negative_prompt
输入参数生成negative_prompt_embeds
。 - num_images_per_prompt (
int
,可选,默认为 1) — 每个提示生成图像的数量。 - generator (
torch.Generator
或List[torch.Generator]
,可选) — 一个或一组 torch 生成器,用于使生成确定性。 - latents (
torch.Tensor
,可选) — 预生成的噪声潜在变量,从高斯分布中采样,用作图像生成的输入。可用于使用不同的提示调整相同的生成。如果未提供,则将通过使用提供的随机generator
进行采样来生成潜在变量张量。 - output_type (
str
,可选,默认为"pil"
) — 生成的图像的输出格式。在以下选项中选择:"pil"
(PIL.Image.Image
)、"np"
(np.array
) 或"pt"
(torch.Tensor
)。 - callback_on_step_end_tensor_inputs (
List
, 可选) —callback_on_step_end
函数的张量输入列表。列表中指定的张量将作为callback_kwargs
参数传递。您只能包含管道类._callback_tensor_inputs
属性中列出的变量。
调用管道进行生成时调用的函数。
示例
>>> import torch
>>> from diffusers import WuerstchenPriorPipeline
>>> prior_pipe = WuerstchenPriorPipeline.from_pretrained(
... "warp-ai/wuerstchen-prior", torch_dtype=torch.float16
... ).to("cuda")
>>> prompt = "an image of a shiba inu, donning a spacesuit and helmet"
>>> prior_output = pipe(prompt)
WuerstchenPriorPipelineOutput
类 diffusers.pipelines.wuerstchen.pipeline_wuerstchen_prior.WuerstchenPriorPipelineOutput
< 源代码 >( image_embeddings: Union )
WuerstchenPriorPipeline 的输出类。
WuerstchenDecoderPipeline
类 diffusers.WuerstchenDecoderPipeline
< 源代码 >( tokenizer: CLIPTokenizer text_encoder: CLIPTextModel decoder: WuerstchenDiffNeXt scheduler: DDPMWuerstchenScheduler vqgan: PaellaVQModel latent_dim_scale: float = 10.67 )
参数
- tokenizer (
CLIPTokenizer
) — CLIP 分词器。 - text_encoder (
CLIPTextModel
) — CLIP 文本编码器。 - scheduler (
DDPMWuerstchenScheduler
) — 用于结合prior
生成图像嵌入的调度器。 - latent_dim_scale (float,
optional
, defaults to 10.67) — 用于根据图像嵌入确定 VQ 潜在空间大小的乘数。如果图像嵌入的高度为 24,宽度为 24,则为了匹配训练条件,VQ 潜在形状需要高度为 int(24*10.67)=256,宽度为 int(24*10.67)=256。
用于从 Wuerstchen 模型生成图像的管道。
此模型继承自 DiffusionPipeline。请查看超类文档以了解库为所有管道实现的通用方法(例如下载或保存、在特定设备上运行等)。
__call__
< 源代码 > ( image_embeddings: Union prompt: Union = None num_inference_steps: int = 12 timesteps: Optional = None guidance_scale: float = 0.0 negative_prompt: Union = None num_images_per_prompt: int = 1 generator: Union = None latents: Optional = None output_type: Optional = 'pil' return_dict: bool = True callback_on_step_end: Optional = None callback_on_step_end_tensor_inputs: List = ['latents'] **kwargs )
参数
- image_embedding (
torch.Tensor
或List[torch.Tensor]
) — 从图像中提取或由先验模型生成的图像嵌入。 - prompt (
str
或List[str]
) — 用于指导图像生成的提示或提示列表。 - num_inference_steps (
int
, 可选,默认为 12) — 降噪步骤的数量。更多的降噪步骤通常会导致更高的图像质量,但推理速度会变慢。 - timesteps (
List[int]
, 可选) — 用于降噪过程的自定义时间步长。如果未定义,则使用等间距的num_inference_steps
时间步长。必须按降序排列。 - guidance_scale (
float
, 可选,默认为 0.0) — 在Classifier-Free Diffusion Guidance中定义的引导尺度。decoder_guidance_scale
定义为Imagen 论文公式 2 中的w
。通过设置decoder_guidance_scale > 1
来启用引导尺度。更高的引导尺度鼓励生成与文本prompt
密切相关的图像,通常以降低图像质量为代价。 - negative_prompt (
str
或List[str]
, 可选) — 用于引导图像生成的提示或提示。在不使用引导时忽略(即,如果decoder_guidance_scale
小于1
,则忽略)。 - num_images_per_prompt (
int
, 可选,默认为 1) — 每个提示生成的图像数量。 - generator (
torch.Generator
或List[torch.Generator]
, 可选) — 一个或多个 torch 生成器,用于使生成确定性。 - latents (
torch.Tensor
, 可选) — 预先生成的噪声潜在变量,从高斯分布中采样,用作图像生成的输入。可用于使用不同的提示调整相同的生成。如果未提供,则将通过使用提供的随机generator
进行采样来生成潜在变量张量。 - output_type (
str
, 可选,默认为"pil"
) — 生成的图像的输出格式。在以下选项中选择:"pil"
(PIL.Image.Image
)、"np"
(np.array
) 或"pt"
(torch.Tensor
)。 - return_dict (
bool
, 可选,默认为True
) — 是否返回 ImagePipelineOutput 而不是普通元组。 - callback_on_step_end (
Callable
, 可选) — 在推理过程中每个去噪步骤结束时调用的函数。该函数使用以下参数调用:callback_on_step_end(self: DiffusionPipeline, step: int, timestep: int, callback_kwargs: Dict)
。callback_kwargs
将包含所有张量的列表,如callback_on_step_end_tensor_inputs
中指定。 - callback_on_step_end_tensor_inputs (
List
, 可选) —callback_on_step_end
函数的张量输入列表。列表中指定的张量将作为callback_kwargs
参数传递。您将只能包含管道类._callback_tensor_inputs
属性中列出的变量。
调用管道进行生成时调用的函数。
示例
>>> import torch
>>> from diffusers import WuerstchenPriorPipeline, WuerstchenDecoderPipeline
>>> prior_pipe = WuerstchenPriorPipeline.from_pretrained(
... "warp-ai/wuerstchen-prior", torch_dtype=torch.float16
... ).to("cuda")
>>> gen_pipe = WuerstchenDecoderPipeline.from_pretrain("warp-ai/wuerstchen", torch_dtype=torch.float16).to(
... "cuda"
... )
>>> prompt = "an image of a shiba inu, donning a spacesuit and helmet"
>>> prior_output = pipe(prompt)
>>> images = gen_pipe(prior_output.image_embeddings, prompt=prompt)
引用
@misc{pernias2023wuerstchen,
title={Wuerstchen: An Efficient Architecture for Large-Scale Text-to-Image Diffusion Models},
author={Pablo Pernias and Dominic Rampas and Mats L. Richter and Christopher J. Pal and Marc Aubreville},
year={2023},
eprint={2306.00637},
archivePrefix={arXiv},
primaryClass={cs.CV}
}