用 Latent Consistency LoRA 让 SDXL 4 步出图
SDXL in 4 steps with Latent Consistency LoRAs
Hugging Face 发布 LCM LoRA,把 SDXL 的推理步数从 25 到 50 步降到 4 到 8 步,方法是不蒸馏整个模型,只训练少量 LoRA 适配器,再配合 LCMScheduler 使用。
原文给出了 LCM LoRA 的原理、代码和跨硬件基准,读者可据此评估在现有 SDXL 流程中提速的可行性。
潜在一致性模型(LCM)是一种通过蒸馏原始模型来减少使用稳定扩散(或 SDXL)生成图像所需步骤的方法,蒸馏后的模型需要更少的步骤(4 到 8 步,而不是原来的 25 到 50 步)。蒸馏是一种训练过程,试图使用新模型复制源模型的输出。蒸馏后的模型可能被设计得更小,如 DistilBERT 或最近发布的 Distil-Whisper;或者在本例中,需要更少的运行步骤。这通常是一个漫长且昂贵的过程,需要大量数据、耐心和几块 GPU。
好吧,那是今天之前的情况!
我们很高兴地宣布一种新方法,它基本上可以让稳定扩散和 SDXL 变得更快,就像它们使用 LCM 过程进行了蒸馏一样!在 3090 上运行任何 SDXL 模型只需约 1 秒而不是 7 秒,或在 Mac 上快 10 倍,听起来怎么样?请继续阅读了解详情!
内容
- 方法概述
- 为什么这很重要
- Fast Inference with SDXL LCM LoRAs
- 基准测试
- 今日发布的 LCM LoRA 和模型
- 附加:将 LCM LoRA 与常规 SDXL LoRA 结合使用
- 如何训练 LCM LoRA
- 资源
- 致谢
方法概述
那么,诀窍是什么? 对于潜在一致性蒸馏,每个模型需要单独蒸馏。LCM LoRA 的核心思想是仅训练少量适配器,即 LoRA 层,而不是整个模型。这样得到的 LoRA 可以应用于任何微调版本的模型,而无需单独蒸馏。如果您迫不及待想看到实际效果,请直接跳到下一节来运行推理代码。如果您想训练自己的 LoRA,可以使用以下流程:
- 从 Hub 选择一个可用的教师模型。例如,您可以使用 SDXL(基础版),或任何您喜欢的微调或 dreambooth 版本。
- 在该模型上训练一个 LCM LoRA。LoRA 是一种性能高效的微调方法,即 PEFT,比完整模型微调便宜得多。有关 PEFT 的更多详细信息,请查看这篇博客文章或diffusers LoRA 文档。
- 将 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,这是潜在一致性模型中使用的调度器。
- 就是这么简单!
这将产生以下全分辨率图像:

使用 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 张图像:

使用 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 管道结果(相同的提示和随机种子),分别使用 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

使用 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 和模型
-
latent-consistency/lcm-lora-sdxl。用于 SDXL 1.0 base 的 LCM LoRA,如上文示例所示。latent-consistency/lcm-lora-sdv1-5。用于 Stable Diffusion 1.5 的 LCM LoRA。latent-consistency/lcm-lora-ssd-1b。用于segmind/SSD-1B的 LCM LoRA,这是一个蒸馏版 SDXL 模型,比原版 SDXL 小 50%,快 60%。
latent-consistency/lcm-sdxl。基于 SDXL 1.0 base 派生的完全微调一致性模型。latent-consistency/lcm-ssd-1b。基于segmind/SSD-1B派生的完全微调一致性模型。
额外内容:将 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

标准 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