跳到正文
原文
Hugging Face Blog·· 2023-11-09精选AI 评分80

用 Latent Consistency LoRA 让 SDXL 4 步出图

SDXL in 4 steps with Latent Consistency LoRAs

AI 导读

Hugging Face 发布 LCM LoRA,把 SDXL 的推理步数从 25 到 50 步降到 4 到 8 步,方法是不蒸馏整个模型,只训练少量 LoRA 适配器,再配合 LCMScheduler 使用。

推荐理由

原文给出了 LCM LoRA 的原理、代码和跨硬件基准,读者可据此评估在现有 SDXL 流程中提速的可行性。

正文 · AI 翻译

潜在一致性模型(LCM)是一种通过蒸馏原始模型来减少使用稳定扩散(或 SDXL)生成图像所需步骤的方法,蒸馏后的模型需要更少的步骤(4 到 8 步,而不是原来的 25 到 50 步)。蒸馏是一种训练过程,试图使用新模型复制源模型的输出。蒸馏后的模型可能被设计得更小,如 DistilBERT 或最近发布的 Distil-Whisper;或者在本例中,需要更少的运行步骤。这通常是一个漫长且昂贵的过程,需要大量数据、耐心和几块 GPU。

好吧,那是今天之前的情况!

我们很高兴地宣布一种新方法,它基本上可以让稳定扩散和 SDXL 变得更快,就像它们使用 LCM 过程进行了蒸馏一样!在 3090 上运行任何 SDXL 模型只需约 1 秒而不是 7 秒,或在 Mac 上快 10 倍,听起来怎么样?请继续阅读了解详情!

内容

方法概述

那么,诀窍是什么? 对于潜在一致性蒸馏,每个模型需要单独蒸馏。LCM LoRA 的核心思想是仅训练少量适配器,即 LoRA 层,而不是整个模型。这样得到的 LoRA 可以应用于任何微调版本的模型,而无需单独蒸馏。如果您迫不及待想看到实际效果,请直接跳到下一节来运行推理代码。如果您想训练自己的 LoRA,可以使用以下流程:

  1. 从 Hub 选择一个可用的教师模型。例如,您可以使用 SDXL(基础版),或任何您喜欢的微调或 dreambooth 版本。
  2. 在该模型上训练一个 LCM LoRA。LoRA 是一种性能高效的微调方法,即 PEFT,比完整模型微调便宜得多。有关 PEFT 的更多详细信息,请查看这篇博客文章或diffusers LoRA 文档。
  3. 将 LoRA 与任何 SDXL 扩散模型和 LCM 调度器一起使用;瞧!您只需几个步骤就能获得高质量推理。

有关过程的更多详细信息,请下载我们的论文。

为什么这很重要?

稳定扩散和 SDXL 的快速推理开启了新的用例和工作流。举几个例子:

  • 可访问性:生成工具可以被更多人有效使用,即使他们没有最新的硬件。
  • 更快的迭代:在极短的时间内获得更多图像和多种变体!这对艺术家和研究人员来说非常棒;无论是个人还是商业用途。
  • 生产工作负载可能可以在不同的加速器上运行,包括 CPU。
  • 更便宜的图像生成服务。

为了让大家了解我们所说的速度差异,在 M1 Mac 上使用 SDXL(基础版)生成一张 1024x1024 的图像大约需要一分钟。而使用 LCM LoRA,仅需约 6 秒(4 步)就能获得出色的结果。这是数量级的速度提升,无需等待结果可谓游戏规则的改变。如果使用 4090,几乎可以瞬间响应(不到 1 秒)。这为 SDXL 在需要实时事件的应用中打开了大门。

使用 SDXL LCM LoRA 进行快速推理

今天发布的diffusers版本使得使用 LCM LoRA 变得非常简便:

from diffusers import DiffusionPipeline, LCMScheduler
import torch

model_id = "stabilityai/stable-diffusion-xl-base-1.0"
lcm_lora_id = "latent-consistency/lcm-lora-sdxl"

pipe = DiffusionPipeline.from_pretrained(model_id, variant="fp16")

pipe.load_lora_weights(lcm_lora_id)
pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
pipe.to(device="cuda", dtype=torch.float16)

prompt = "close-up photography of old man standing in the rain at night, in a street lit by lamps, leica 35mm summilux"
images = pipe(
    prompt=prompt,
    num_inference_steps=4,
    guidance_scale=1,
).images[0]

注意代码如何:

  • 实例化了一个带有 SDXL 1.0 基础模型的标准扩散管道。
  • 应用了 LCM LoRA。
  • 将调度器更改为 LCMScheduler,这是潜在一致性模型中使用的调度器。
  • 就是这么简单!

这将产生以下全分辨率图像:

SDXL in 4 steps with LCM LoRA
使用 LCM LoRA 在 4 步内通过 SDXL 生成的图像。

质量对比

让我们看看步数如何影响生成质量。以下代码将生成包含 1 到 8 个总推理步骤的图像:

images = []
for steps in range(8):
    generator = torch.Generator(device=pipe.device).manual_seed(1337)
    image = pipe(
        prompt=prompt,
        num_inference_steps=steps+1,
        guidance_scale=1,
        generator=generator,
    ).images[0]
    images.append(image)

这是以网格形式展示的 8 张图像:

LCM LoRA generations with 1 to 8 steps
使用 1 到 8 步的 LCM LoRA 生成结果。

如预期,仅使用1步生成的图像只有大致形状,缺乏可辨识的特征和纹理。然而,结果会迅速改善,通常在 4 到 6 步内就非常令人满意。个人而言,我发现前一个测试中的 8 步图像对我来说色彩过于饱和且“卡通化”,因此在这个例子中,我可能会在 5 步和 6 步之间选择。生成速度如此之快,你可以仅用 4 步创建多个不同的变体,然后选择喜欢的,并通过增加几步和使用精炼的提示进行迭代。

引导比例与负向提示

请注意,在前面的示例中我们使用了guidance_scale的1,实际上禁用了它。这对于大多数提示都很有效,而且速度最快,但会忽略负向提示。你也可以尝试通过提供介于1和2之间的引导比例来使用负向提示——我们发现更大的值并不起作用。

与基础 SDXL 的质量对比

在质量方面,这与标准 SDXL 管道相比如何?让我们看一个例子!

我们可以通过卸载 LoRA 权重并切换到默认调度器,迅速将管道恢复为标准 SDXL 管道:

from diffusers import EulerDiscreteScheduler

pipe.unload_lora_weights()
pipe.scheduler = EulerDiscreteScheduler.from_config(pipe.scheduler.config)

接着,我们可以像往常一样对 SDXL 进行推理。我们将采用不同的步数来收集结果:

images = []
for steps in (1, 4, 8, 15, 20, 25, 30, 50):
    generator = torch.Generator(device=pipe.device).manual_seed(1337)
    image = pipe(
        prompt=prompt,
        num_inference_steps=steps,
        generator=generator,
    ).images[0]
    images.append(image)

SDXL results for various inference steps
SDXL 管道结果(相同的提示和随机种子),分别使用 1、4、8、15、20、25、30 和 50 步。

如你所见,此示例中的图像在约 20 步(第二行)之前几乎毫无用处,而随着步数增加,质量仍有显著提升。最终图像的细节令人惊叹,但达到这一效果花了 50 步。

LCM LoRA 与其他模型

此技术同样适用于任何其他微调过的 SDXL 或 Stable Diffusion 模型。为了演示,我们来看看如何在collage-diffusion上运行推理,这是一个基于Stable Diffusion v1.5并使用 Dreambooth 微调的模型。

代码与我们之前示例中看到的类似。我们加载微调后的模型,然后加载适用于 Stable Diffusion v1.5 的 LCM LoRA。

from diffusers import DiffusionPipeline, LCMScheduler
import torch

model_id = "wavymulder/collage-diffusion"
lcm_lora_id = "latent-consistency/lcm-lora-sdv1-5"

pipe = DiffusionPipeline.from_pretrained(model_id, variant="fp16")
pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
pipe.load_lora_weights(lcm_lora_id)
pipe.to(device="cuda", dtype=torch.float16)

prompt = "collage style kid sits looking at the night sky, full of stars"

generator = torch.Generator(device=pipe.device).manual_seed(1337)
images = pipe(
    prompt=prompt,
    generator=generator,
    negative_prompt=negative_prompt,
    num_inference_steps=4,
    guidance_scale=1,
).images[0]
images

LCM LoRA technique with a Dreambooth Stable Diffusion v1.5 model, allowing 4-step inference.
使用 Dreambooth Stable Diffusion v1.5 模型的 LCM LoRA 技术,实现 4 步推理。

完整的 Diffusers 集成

将 LCM 集成到 diffusers 中,可以让你利用 diffusers 工具箱中的许多功能和工作流。例如:

  • 开箱即用的 mps 对搭载 Apple Silicon 的 Mac 的支持。
  • 内存和性能优化,如 flash attention 或 torch.compile()。
  • 面向低内存环境的额外内存节省策略,包括模型卸载。
  • ControlNet 或图像到图像等工作流。
  • 训练和微调脚本。

基准测试

本节并非旨在穷尽所有情况,而是为了展示我们在各种计算机上实现的生成速度。让我们再次强调,如此轻松地探索图像生成是多么自由。

硬件 SDXL LoRA LCM(4 步) SDXL 标准(25 步)
Mac, M1 Max 6.5s 64s
2080 Ti 4.7s 10.2s
3090 1.4s 7s
4090 0.7s 3.4s
T4(Google Colab 免费层) 8.4s 26.5s
A100(80 GB) 1.2s 3.8s
Intel i9-10980XE CPU(使用 1/36 核心) 29s 219s

这些测试在所有情况下均使用批大小为 1,并使用 此脚本 由 Sayak Paul 运行。

对于容量较大的显卡,如 A100,一次性生成多张图像时性能会显著提升,这通常是生产工作负载的情况。

今日发布的 LCM LoRA 和模型

额外内容:将 LCM LoRA 与常规 SDXL LoRA 结合使用

使用 diffusers + PEFT 集成,你可以将 LCM LoRA 与常规 SDXL LoRA 结合,赋予它们仅在 4 步内运行 LCM 推理的超能力。

这里我们将把 CiroN2022/toy_face LoRA 与 LCM LoRA 结合:

from diffusers import DiffusionPipeline, LCMScheduler
import torch

model_id = "stabilityai/stable-diffusion-xl-base-1.0"
lcm_lora_id = "latent-consistency/lcm-lora-sdxl"
pipe = DiffusionPipeline.from_pretrained(model_id, variant="fp16")
pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)

pipe.load_lora_weights(lcm_lora_id)
pipe.load_lora_weights("CiroN2022/toy-face", weight_name="toy_face_sdxl.safetensors", adapter_name="toy")

pipe.set_adapters(["lora", "toy"], adapter_weights=[1.0, 0.8])
pipe.to(device="cuda", dtype=torch.float16)

prompt = "a toy_face man"
negative_prompt = "blurry, low quality, render, 3D, oversaturated"
images = pipe(
    prompt=prompt,
    negative_prompt=negative_prompt,
    num_inference_steps=4,
    guidance_scale=0.5,
).images[0]
images

Combining LoRAs for fast inference
标准 LoRA 和 LCM LoRA 结合,实现快速(4 步)推理。

需要探索一些 LoRA 的灵感吗?看看我们的实验性 LoRA the Explorer(LCM 版本) Space,测试社区的惊艳创作并获取灵感!

如何训练 LCM 模型和 LoRA

作为今天 diffusers 发布的一部分,我们提供了与 LCM 团队作者合作开发的训练和微调脚本。它们允许用户:

  • 在 Laion 等大型数据集上对 Stable Diffusion 或 SDXL 模型进行全模型蒸馏。
  • 训练 LCM LoRA,这是一个简单得多的过程。正如我们在本文中所展示的,它还可以让你在 Stable Diffusion 上运行快速推理,而无需经过蒸馏训练。

更多详情,请查看仓库中 SDXL 或 Stable Diffusion 的说明。

我们希望这些脚本能激发社区尝试自己的微调。如果你将它们用于你的项目,请务必告诉我们!

资源

致谢

Latent Consistency Models 的出色工作由 LCM 团队完成,请务必查看他们的代码、报告和论文。本项目是 diffusers 团队、LCM 团队以及社区贡献者 Daniel Gu 合作的成果。我们相信这证明了开源 AI 的赋能力量,它是让研究人员、从业者和爱好者探索新想法并开展协作的基石。我们还要感谢 @madebyollin 对社区的持续贡献,包括我们在训练脚本中使用的 float16 自编码器。

来源:Hugging Face Blog · hf-mirror.com