使用 LCM LoRA 4 步完成 SDXL 推理
LCM 模型 通过将原始模型蒸馏为另一个需要更少步数 (4 到 8 步,而不是原来的 25 到 50 步) 的版本以减少用 Stable Diffusion (或 SDXL) 生成图像所需的步数。蒸馏是一种训练过程,其主要思想是尝试用一个新模型来复制源模型的输出。蒸馏后的模型要么尺寸更小 (如 DistilBERT 或最近发布的 Distil-Whisper),要么需要运行的步数更少 (本文即是这种情况)。一般来讲,蒸馏是一个漫长且成本高昂的过程,需要大量数据、耐心以及一些 GPU 运算。
但以上所述皆为过往,今天我们翻新篇了!
今天,我们很高兴地公开一种新方法,其可以从本质上加速 Stable Diffusion 和 SDXL,效果跟用 LCM 蒸馏过一样!有了它,我们在 3090 上运行 任何 SDXL 模型,不需要 70 秒,也不需要 7 秒,仅需要约 1 秒就行了!在 Mac 上,我们也有 10 倍的加速!听起来是不是很带劲?那继续往下读吧!
目录
- 方法概述
- 快有啥用?
- 快速推理 SDXL LCM LoRA 模型
- 测试基准
- 已公开发布的 LCM LoRA 及 LCM 模型
- 加分项:将 LCM LoRA 与常规 SDXL LoRA 结合起来
- 如何训练 LCM 模型及 LCM LoRA
- 资源
- 致谢
方法概述
到底用了啥技巧?
在使用原始 LCM 蒸馏时,每个模型都需要单独蒸馏。而 LCM LoRA 的核心思想是只对少量适配器 (即 LoRA 层) 进行训练,而不用对完整模型进行训练。推理时,可将生成的 LoRA 用于同一模型的任何微调版本,而无需对每个版本都进行蒸馏。如果你已经迫不及待地想试试这种方法的实际效果了,可以直接跳到 下一节 试一下推理代码。如果你想训练自己的 LoRA,流程如下:
- 从 Hub 中选择一个教师模型。如: 你可以使用 SDXL (base),或其任何微调版或 dreambooth 微调版,随你喜欢。
- 在该模型上 训练 LCM LoRA 模型。LoRA 是一种参数高效的微调 (PEFT),其实现成本比全模型微调要便宜得多。有关 PEFT 的更详细信息,请参阅 此博文 或 diffusers 库的 LoRA 文档。
- 将 LoRA 与任何 SDXL 模型和 LCM 调度器一起组成一个流水线,进行推理。就这样!用这个流水线,你只需几步推理即可生成高质量的图像。
欲知更多详情,请 下载我们的论文。
快有啥用?
Stable Diffusion 和 SDXL 的快速推理为新应用和新工作流打开了大门,仅举几例:
- 更易得: 变快后,生成工具可以被更多人使用,即使他们没有最新的硬件。
- 迭代更快: 无论从个人还是商业角度来看,在短时间内生成更多图像或进行更多尝试对于艺术家和研究人员来说都非常有用。
- 可以在各种不同的加速器上进行生产化部署,包括 CPU。
- 图像生成服务会更便宜。
为了衡量我们所说的速度差异,在 M1 Mac 上用 SDXL (base) 生成一张 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 base 模型去实例化一个标准的 diffusion 流水线。
- 应用 LCM LoRA。
- 将调度器改为 LCMScheduler,这是 LCM 模型使用的调度器。
- 结束!
生成的全分辨率图像如下所示:

LCM LORA 微调后的 SDXL 模型用 4 步生成的图像
生成质量
我们看下步数对生成质量的影响。以下代码将分别用 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 1 至 8 步生成的图像
不出所料,仅使用 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 上运行推理,该模型是用 Dreambooth 算法对 Stable Diffusion v1.5 微调而得。
代码与我们在前面示例中看到的代码类似。我们先加载微调后的模型,然后加载适合 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 工具箱中的许多特性和工作流,如:
- 对采用 Apple 芯片的 Mac 提供开箱即用的
mps支持。 - 内存和性能优化,例如 flash 注意力或
torch.compile()。 - 针对低 RAM 场景的其他内存节省策略,包括模型卸载。
- ControlNet 或图生图等工作流。
- 训练和微调脚本。
测试基准
本节列出了 SDXL LCM LoRA 在各种硬件上的生成速度,给大家一个印象。忍不住再提一句,能如此轻松地探索图像生成真是太爽了!
| 硬件 | 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 Free Tier) | 8.4s | 26.5s |
| A100 (80 GB) | 1.2s | 3.8s |
| Intel i9-10980XE CPU (共 36 核,仅用 1 核) | 29s | 219s |
上述所有测试的 batch size 均为 1,使用是 Sayak Paul 开发的 这个脚本。
对于显存容量比较大的卡 (例如 A100),一次生成多张图像,性能会有显著提高,一般来讲生产部署时会采取增加 batch size 的方法来增加吞吐。
已公开发布的 LCM LoRA 及 LCM 模型
-
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 步推理的超能力。
这里,我们将 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 版本) 空间,在这里你可以把玩社区的惊人创作并从中获取灵感!
如何训练 LCM 模型及 LCM LoRA
最新的 diffusers 中,我们提供了与 LCM 团队作者合作开发的训练和微调脚本。有了它们,用户可以:
- 在 Laion 等大型数据集上执行 Stable Diffusion 或 SDXL 模型的全模型蒸馏。
- 训练 LCM LoRA,它比全模型蒸馏更简单。正如我们在这篇文章中所示,训练后,可以用它对 Stable Diffusion 实现快速推理,而无需进行蒸馏训练。
更多详细信息,请查阅代码库中的 SDXL 或 Stable Diffusion 说明文档。
我们希望这些脚本能够激励社区探索实现自己的微调。如果你将它们用于自己的项目,请告诉我们!
资源
演示应用
训练脚本
致谢
LCM 团队 完成了 LCM 模型的出色工作,请务必查阅他们的代码、报告和论文。该项目是 diffusers 团队、LCM 团队以及社区贡献者 Daniel Gu 合作的结果。我们相信,这证明了开源人工智能的强大力量,它是研究人员、从业者和探客 (tinkerer) 们探索新想法和协作的基石。我们还要感谢 @madebyollin 对社区的持续贡献,其中包括我们在训练脚本中使用的 float16 自编码器。
英文原文: https://hf.co/blog/lcm_lora
原文作者: Pedro Cuenca,Suraj Patil,Simian Luo,Daniel Gu,Yiqin Tan,Sayak Paul,Apolinário
译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为 transformer-family 模型在各模态数据上的应用及大规模模型的训练推理。
审校/排版: zhongdongy (阿东)
使用 LCM LoRA 4 步完成 SDXL 推理的更多相关文章
- 使用 LoRA 和 Hugging Face 高效训练大语言模型
在本文中,我们将展示如何使用 大语言模型低秩适配 (Low-Rank Adaptation of Large Language Models,LoRA) 技术在单 GPU 上微调 110 亿参数的 F ...
- hdu 5584 LCM Walk(数学推导公式,规律)
Problem Description A frog has just learned some number theory, and can't wait to show his ability t ...
- 解密Prompt系列6. lora指令微调扣细节-请冷静,1个小时真不够~
上一章介绍了如何基于APE+SELF自动化构建指令微调样本.这一章咱就把微调跑起来,主要介绍以Lora为首的低参数微调原理,环境配置,微调代码,以及大模型训练中显存和耗时优化的相关技术细节 标题这样写 ...
- NOI前的考试日志
4.14 网络流专项测试 先看T1,不会,看T2,仙人掌???wtf??弃疗.看T3,貌似最可做了,然后开始刚,刚了30min无果,打了50分暴力,然后接着去看T1,把序列差分了一下,推了会式子,发现 ...
- Windows Phone App的dump文件实例分析-Stack Overflow
前言 这篇文章我们一起来分析一个从Windows Phone Dev Center上下载下来的dump file.首先按照我上一篇的步骤设置好我们的Windbg,并按住Ctrl +D打开dumpfil ...
- 概率图模型(PGM):贝叶斯网(Bayesian network)初探
1. 从贝叶斯方法(思想)说起 - 我对世界的看法随世界变化而随时变化 用一句话概括贝叶斯方法创始人Thomas Bayes的观点就是:任何时候,我对世界总有一个主观的先验判断,但是这个判断会随着世界 ...
- 用 Java 做个“你画手机猜”的小游戏
本文适合有 Java 基础的人群 作者:DJL-Lanking HelloGitHub 推出的<讲解开源项目>系列.有幸邀请到了亚马逊 + Apache 的工程师:Lanking( htt ...
- 寒武纪加速平台(MLU200系列) 摸鱼指南(四)--- 边缘端实例程序分析
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- 洛谷 P4708 - 画画(Burnside 引理+组合数学)
洛谷题面传送门 神仙题 %%%%%%%%%%%%%%%%%%%% 题解搬运人来了 首先看到本质不同(无标号)的图计数咱们可以想到 Burnside 引理,具体来说,我们枚举一个排列 \(p\),并统计 ...
- Minimum Sum LCM(uva10791+和最小的LCM+推理)
L - Minimum Sum LCM Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submi ...
随机推荐
- GoRedisLock:Golang保障数据一致性的分布式锁解决方案
在现代分布式系统中,多个节点之间共享资源是常见的需求.然而,并发访问共享资源可能导致数据不一致性和竞争条件.为了解决这些问题,我们需要引入分布式锁.GoRedisLock是一个出色的分布式锁库,它结合 ...
- Cilium系列-8-绕过 IPTables 连接跟踪
系列文章 Cilium 系列文章 前言 将 Kubernetes 的 CNI 从其他组件切换为 Cilium, 已经可以有效地提升网络的性能. 但是通过对 Cilium 不同模式的切换/功能的启用, ...
- 绕过PHP执行命令的函数执行系统cmd命令
<?php $evil=`set`; echo '<pre>'.$evil.'</pre>'; ?> 成功执行set命令,你懂的! 顺手写了个php执行cmd命令的 ...
- 牛客小白月赛65 E题 题解
原题链接 题意描述 构造一个\(1\)到\(n\)的排列,使得其中正好有\(k\)个二元组\((i, j)\)满足,\(1\le i\lt j\le n\) && \(a_i - a_ ...
- Redhat 8.2 系统语言切换(英文转中文)
前提条件 确保已连上网,并且配好 yum 源 若未配好 yum 源 可参考我上一篇文章 部分 Linux 换国内源 操作步骤 安装中文语言包 dnf install glibc-langpack-zh ...
- 只要学会这些AI工具,一个人就是一家营销咨询公司
随着AI工具的不断涌现,您只需掌握市面上热门的AI工具,便可独自开展营销咨询公司.通过一系列AI工具,您可以为企业提供全案服务,收获丰厚回报. 例如,在协助一家美妆初创公司出海时,我们运用一系列AI工 ...
- 04.使用 github actions+docker 自动部署前后端分离项目 zhontai (.net core+vue)
前言 Github Actions是什么?是 GitHub 提供的一种持续集成/持续部署(CI/CD)工作流程自动化服务,助力项目的自动化构建.测试和部署. 依托于平台,本文将分享使用 GitHub ...
- 二叉树(binary tree)
二叉树(binary tree) 二叉树(Binary Tree)是一种常见的树状数据结构,它由一组节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点.二叉树具有以下特点: 每个节点最多有 ...
- Note -「网络流 flows」
基本没有严谨证明. Part. 1 概念 Part. 1-1 流网络 流网络是一个有向图(不考虑反向边),我们把这个图记为 \(G=(V,E)\). 其中有两个特殊的点 \(s,t\),分别成为源点和 ...
- 关于C++拷贝控制
通常来说,对于类内动态分配资源的类需要进行拷贝控制:要在拷贝构造函数.拷贝赋值运算符.析构函数中实现安全高效的操作来管理内存.但是资源管理并不是一个类需要定义自己的拷贝控制成员的唯一原因.C++ Pr ...