Diffusers DEISMultistepScheduler 详解:基于指数积分器的高阶 ODE 快速采样器
2026/9/10 16:16:56 网站建设 项目流程

Diffusers DEISMultistepScheduler 详解:基于指数积分器的高阶 ODE 快速采样器

【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers

导读

DEISMultistepScheduler(Diffusion Exponential Integrator Sampler)是 🤗 Diffusers 中实现的一类快速高阶扩散常微分方程(ODE)求解器,它利用扩散过程学习到的半线性结构来显著降低离散化误差,从而在仅 10 步左右即可生成高质量样本。本文以 docs/source/en/api/schedulers/deis.md 为骨架,深入结合 调度器源码 与 单元测试,系统讲解 DEIS 的数学动机、全部构造参数、采样流程、动态阈值化以及如何在实际 pipeline 中替换使用。读完本文,你将掌握如何在 Stable Diffusion 等 pipeline 中配置并调优DEISMultistepScheduler,在减少采样步数的同时保住生成质量。

一、背景:扩散模型为什么需要快速采样器

扩散模型(Diffusion Models, DMs)能生成高保真样本,但一个主要痛点是采样过程极其缓慢:通常需要成百上千个时间离散化步骤才能达到期望精度。DEIS 论文《Fast Sampling of Diffusion Models with Exponential Integrator》系统地分析了 DM 的采样过程,指出影响样本质量的关键因素中离散化方法最为关键

DEIS 的核心思路是:

  • 基于**指数积分器(Exponential Integrator)**来离散化扩散过程的常微分方程(ODE);
  • 利用扩散过程学习到的半线性(semilinear)结构降低离散化误差;
  • 可以应用到任意扩散模型,在10 步内即可生成高保真样本;
  • 在有限的 score function evaluation(NFE)下达到当时的 SOTA 采样性能。

原文摘要给出的参考数据(论文中报告):CIFAR10 上 10 个 NFE 时 FID 4.17,15 个 NFE 时 FID 3.37、IS 9.74;单张 A6000 GPU 约 3 分钟生成 50k 张 CIFAR10 图像。这些数据来自论文本身,可作为理解其加速效果的背景参考。

本仓库实现的两个关键改动

DEISMultistepScheduler的实现(见 调度器源码)相比原论文做了两点重要修改:

  1. 多项式拟合从原始线性t空间改到 log-rho 空间。原论文在时间t上做多项式拟合,本实现改为在rho = sigma / alpha的对数空间中进行,从而获得指数多步更新的闭式系数(closed-form coefficients),不再依赖数值求解器;
  2. 支持多种预测类型与噪声调度,包括epsilonsamplev_predictionflow_prediction,以及 Karras、exponential、beta、flow 四种 sigma 调度,使其能适配从经典 Stable Diffusion 到 flow-matching 类模型的不同场景。

从源码注释看,该实现基于DPMSolverMultistepScheduler修改而来(见 调度器源码第 16 行),因此其 API 风格、step流程与 DPM-Solver 系列高度一致。

二、快速上手:在 Stable Diffusion pipeline 中替换调度器

DEISMultistepScheduler与 Stable Diffusion 系列 pipeline 完全兼容。以经典的StableDiffusionPipeline为例:

import torch from diffusers import StableDiffusionPipeline, DEISMultistepScheduler pipe = StableDiffusionPipeline.from_pretrained( "runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16 ) pipe = pipe.to("cuda") # 用 DEIS 替换默认调度器 pipe.scheduler = DEISMultistepScheduler.from_config(pipe.scheduler.config) # 仅用 10~25 步即可获得良好结果 image = pipe( "a photo of an astronaut riding a horse on mars", num_inference_steps=10, guidance_scale=7.5, ).images[0]

要点:

  • from_config(pipe.scheduler.config)会继承原调度器的num_train_timestepsbeta_startbeta_endbeta_scheduleprediction_type等关键配置,避免手动重复指定;
  • 官方文档建议solver_order取 2 或 3(见 deis.md),其中solver_order=1等价于DDIMScheduler
  • 对于 CFG 引导采样推荐solver_order=2,无条件采样推荐solver_order=3(见 源码参数文档)。

三、构造参数全解析

DEISMultistepScheduler继承自SchedulerMixinConfigMixin,因此天然支持save_configfrom_pretrainedfrom_config等通用能力(详见 配置基类)。所有参数均通过@register_to_config注册到config中,构造后可通过scheduler.config.xxx访问。

3.1 噪声计划(beta 计划)

参数默认值说明
num_train_timesteps1000训练时的扩散步数,决定 beta 序列长度
beta_start0.0001beta 序列起始值
beta_end0.02beta 序列终止值
beta_schedule"linear"可选linearscaled_linearsquaredcos_cap_v2
trained_betasNone直接传入训练好的 beta 数组,以绕过beta_start/beta_end

在 源码第 192-211 行 中可以看到三种 beta schedule 的具体实现:

  • lineartorch.linspace(beta_start, beta_end, num_train_timesteps),等距线性插值;
  • scaled_linear:先对 beta 开方后线性插值再平方,**专门针对潜在扩散模型(latent diffusion)**设计,Stable Diffusion 系列默认使用;
  • squaredcos_cap_v2:GLIDE 风格余弦计划,调用betas_for_alpha_bar生成,该辅助函数还支持cosineexplaplace三种alpha_transform_type(见 源码第 33-83 行)。

__init__中,调度器还会由 beta 派生出一系列量:alphasalphas_cumprodalpha_tsigma_tlambda_tlog(alpha) - log(sigma))以及sigmas = ((1 - alphas_cumprod) / alphas_cumprod) ** 0.5(见 源码第 213-219 行)。注意注释明确说明当前仅支持 VP 型噪声计划("Currently we only support VP-type noise schedule")。

3.2 求解器阶数与预测类型

参数默认值说明
solver_order2DEIS 阶数,取1231等价于 DDIM
prediction_type"epsilon"可选epsilonsamplev_predictionflow_prediction
algorithm_type"deis"求解器算法类型,当前仅支持deis
solver_type"logrho"求解器类型,当前仅支持logrho
lower_order_finalTrue最后几步是否降阶使用低阶求解器,仅对 <15 步推理有效

阶数选择建议(官方文档 Tips 与源码 docstring 双重确认):

  • solver_order=1:等价于DDIMScheduler
  • solver_order=2:推荐用于引导采样(guided sampling,如 CFG);
  • solver_order=3:推荐用于无条件采样(unconditional sampling)。

lower_order_final=True时,当推理步数少于 15 步,最后两步会分别降为二阶、一阶更新以稳定数值(见 step 方法中的判断逻辑)。

预测类型convert_model_output中对应四种不同的反推x0公式(见 源码第 618-631 行):

  • epsilonx0_pred = (sample - sigma_t * model_output) / alpha_t(预测噪声);
  • samplex0_pred = model_output(直接预测干净样本);
  • v_predictionx0_pred = alpha_t * sample - sigma_t * model_output(Imagen Video 论文中的 v 预测,见 Imagen Video);
  • flow_predictionx0_pred = sample - sigma_t * model_output(flow-matching 类模型)。

3.3 动态阈值化(Dynamic Thresholding)

参数默认值说明
thresholdingFalse是否启用 Imagen 提出的动态阈值化
dynamic_thresholding_ratio0.995分位数比例,仅thresholding=True时生效
sample_max_value1.0阈值上限,仅thresholding=True时生效

重要限制:动态阈值化不适合潜在空间扩散模型(如 Stable Diffusion),只适用于像素空间扩散模型(官方文档 Tips 明确指出)。其原理(来自 Imagen 论文,见 _threshold_sample 源码注释):在每个采样步,取x_t0(t 时刻对x_0的预测)绝对像素值的某个分位数作为s;若s > 1,则将x_t0裁剪到[-s, s]再除以s。这会把接近饱和(接近 -1 和 1)的像素向内推,防止每步饱和,从而显著提升照片真实感与图文对齐,尤其在使用很大引导权重时。

实现细节:_threshold_sample会将样本展平后沿 batch 维度计算torch.quantile(abs_sample, ratio, dim=1),再clamp(min=1, max=sample_max_value)——当 clamp 到最小值 1 时等价于标准的[-1, 1]裁剪(见 源码第 386-393 行)。fp16 样本会先上转为 float32 做分位数计算,再转回原 dtype,相关正确性由 test_fp16_support 测试 覆盖。

3.4 噪声调度(sigma schedule)与时间步

参数默认值说明
use_karras_sigmasFalse使用 Karras 噪声调度(EDM 论文)
use_exponential_sigmasFalse使用指数 sigma 调度
use_beta_sigmasFalse使用 Beta 分布采样调度(Beta Sampling is All You Need)
use_flow_sigmasFalse使用 flow sigma 调度(适配 flow-matching 模型)
flow_shift1.0flow 模型的 shift 参数
timestep_spacing"linspace"可选linspaceleadingtrailing
steps_offset0推理步的偏移量,部分模型家族需要
use_dynamic_shiftingFalse是否使用动态 shifting
time_shift_type"exponential"时间偏移类型,当前仅支持exponential

互斥约束use_karras_sigmasuse_exponential_sigmasuse_beta_sigmas三者同时只能开启一个,否则构造时抛出ValueError;且use_beta_sigmas=True要求安装scipy(见 源码第 177-191 行)。beta 调度的实现使用scipy.stats.beta.ppf生成 sigma 序列,参数alpha=0.6, beta=0.6(见 _convert_to_beta)。

时间步三种间距(对应论文《Common Diffusion Noise Schedules and Sample Steps are Flawed》Table 2):

  • linspace(默认):在[0, num_train_timesteps-1]上等距取整;
  • leading:按step_ratio取整生成,会叠加steps_offset
  • trailing:从num_train_timesteps倒推step_ratio步长取整并减 1。

具体实现见 set_timesteps 方法第 288-311 行。

四、采样流程与核心方法

4.1 采样前的准备:set_timesteps

推理前必须调用set_timesteps(num_inference_steps),否则step会抛出 "Number of inference steps is 'None'" 异常(见 step 方法第 943-946 行)。该方法完成:

  1. 根据timestep_spacing生成离散时间步序列;
  2. 按配置选择 Karras / exponential / beta / flow sigma 或默认插值 sigma;
  3. 重置内部状态model_outputs(长度为solver_order的历史输出缓存)与lower_order_nums计数器;
  4. 初始化_step_index/_begin_index索引计数器。

若开启use_dynamic_shifting,还可传入mu参数:flow_shift = exp(mu)(见 set_timesteps 第 285-287 行)。

4.2 单步推进:step

step(model_output, timestep, sample, return_dict=True)是采样循环的核心,流程如下(见 step 方法):

  1. step_index未初始化,通过_init_step_index依据当前 timestep 定位索引;
  2. 判断最后一步(len(timesteps) < 15lower_order_final=True时)是否降阶;
  3. 调用convert_model_output将模型输出统一转换为 DEIS 所需的“噪声型”输出;
  4. 将新输出压入model_outputs历史缓存(长度固定为solver_order,滚动覆盖);
  5. 按阶数选择更新公式:
    • solver_order == 1或历史不足/最后一步 →deis_first_order_update等价于 DDIM);
    • solver_order == 2或历史不足两步/倒数第二步 →multistep_deis_second_order_update
    • 否则 →multistep_deis_third_order_update
  6. lower_order_nums递增(不超过solver_order),step_index加一;
  7. 返回SchedulerOutput(prev_sample=...)(prev_sample,)元组。

4.3 一阶更新:与 DDIM 的等价关系

一阶 DEIS 更新公式为(见 deis_first_order_update):

h = lambda_t - lambda_s x_t = (alpha_t / alpha_s) * sample - sigma_t * (exp(h) - 1.0) * model_output

其中lambda_t = log(alpha_t) - log(sigma_t)。这正是 DDIM 的闭式解形式,也是文档中"solver_order=1等价于DDIMScheduler"的数学来源。

4.4 二/三阶多步更新:log-rho 空间的闭式系数

高阶更新在 log-rho 空间(rho = sigma / alpha)对模型输出做多项式插值后精确积分。二阶更新(见 multistep_deis_second_order_update):

# 辅助积分函数 ind_fn(t, b, c) = Integrate[(log(t) - log(c)) / (log(b) - log(c)), {t}] def ind_fn(t, b, c): return t * (-np.log(c) + np.log(t) - 1) / (np.log(b) - np.log(c)) coef1 = ind_fn(rho_t, rho_s0, rho_s1) - ind_fn(rho_s0, rho_s0, rho_s1) coef2 = ind_fn(rho_t, rho_s1, rho_s0) - ind_fn(rho_s0, rho_s1, rho_s0) x_t = alpha_t * (sample / alpha_s0 + coef1 * m0 + coef2 * m1)

三阶更新(见 multistep_deis_third_order_update)对二次插值多项式做解析积分,得到三个闭式系数coef1/coef2/coef3

x_t = alpha_t * (sample / alpha_s0 + coef1 * m0 + coef2 * m1 + coef3 * m2)

正是因为在 log-rho 空间做多项式拟合,这些系数才能以闭式表达,避免了论文原版中对数值求解器的依赖——这是本仓库实现区别于原论文的核心技术点(见 deis.md 第 17 行)。

4.5 其余关键方法

方法作用
convert_model_output将模型输出按prediction_type转换为 DEIS 所需的统一形式,并可选执行动态阈值化
scale_model_input恒等返回输入,保证与需要缩放输入的调度器接口互换(见 源码第 981-994 行)
add_noise依据 sigma 调度向原始样本添加噪声,用于 img2img / inpainting 等中途启动场景(见 源码第 996-1044 行)
set_begin_index设置起始索引,pipeline 在推理前调用(拷贝自 DPM-Solver)
index_for_timestep在调度表中定位 timestep 的索引,支持重复 timestep 场景
__len__返回num_train_timesteps

五、兼容性与降级逻辑

DEISMultistepScheduler被列入KarrasDiffusionSchedulers枚举族(见 源码第 148 行),在 schedulers/init.py 与 diffusers/init.py 中公开导出。

值得注意的向后兼容降级逻辑(见 源码第 224-235 行):

  • 若传入algorithm_type="dpmsolver""dpmsolver++",会被静默改写为"deis"(兼容旧配置);
  • 若传入solver_type="midpoint""heun""bh1""bh2",会被静默改写为"logrho"
  • 其他未支持的取值则抛出NotImplementedError

也就是说,从 DPM-Solver 或旧版 DEIS 配置迁移时,无需修改配置即可直接加载,调度器会自动落到唯一受支持的deis+logrho组合。

另外,DEISMultistepScheduler也被 StableDiffusionSAGPipeline(Self-Attention Guidance) 列为受支持的调度器之一,说明其与 Stable Diffusion 生态的兼容性良好。

六、测试验证与数值稳定性

仓库在 tests/schedulers/test_scheduler_deis.py 中提供了完整的测试覆盖,可作为使用与验证的参考:

  • test_switch/test_full_loop_no_noise:用固定 dummy 模型跑 10 步完整循环,断言mean(|sample|)等于0.23916 ± 1e-3,且与DPMSolverSinglestepDPMSolverMultistepUniPCMultistep往返转换(from_config)后结果一致——这说明DEIS 与同族多步求解器配置互通、输出可复现
  • test_full_loop_with_v_prediction:验证v_prediction模式下期望均值为0.091 ± 1e-3
  • test_full_loop_with_noise:验证中途加入噪声(img2img 场景)后sum ≈ 315.3016mean ≈ 0.41054
  • test_solver_order_and_type:遍历solver_order ∈ {1,2,3}×prediction_type ∈ {epsilon, sample},断言无 NaN;
  • test_thresholding:遍历阶数与sample_max_value ∈ {0.5, 1.0, 2.0}验证动态阈值化;
  • test_inference_steps:覆盖[1, 2, 3, 5, 10, 50, 100, 999, 1000]各种推理步数;
  • test_timesteps:覆盖num_train_timesteps ∈ {25, 50, 100, 999, 1000}
  • test_fp16_support:验证半精度推理全程保持float16
  • test_beta_sigmas/test_exponential_sigmas:验证两种 sigma 调度的可用性。

测试默认配置(见 get_scheduler_config)为num_train_timesteps=1000beta_start=0.0001beta_end=0.02beta_schedule="linear"solver_order=2,这也是实践中最常用的起步配置。

七、实践调优建议

  1. 起步配置:沿用solver_order=2prediction_type="epsilon"(与 Stable Diffusion 权重匹配),先用 25 步对比 DDIM 效果,再逐步降至 10 步观察质量衰减;
  2. 引导 vs 无条件:CFG 引导场景保持solver_order=2;无条件/低引导场景可尝试solver_order=3获得更高精度;
  3. 小步数稳定性:推理步数少于 15 时保持lower_order_final=True(默认),让末尾两步自动降阶,避免高阶插值在终点附近振荡;
  4. 像素空间模型:如果模型在像素空间(非 latent),可开启thresholding=True并配合dynamic_thresholding_ratio=0.995sample_max_value=1.0改善高引导权重下的饱和度问题;latent 模型(如 Stable Diffusion)请勿开启
  5. 噪声调度实验use_karras_sigmas常能改善低步数质量;use_beta_sigmas需先安装 scipy,且三者互斥;
  6. 配置继承:通过from_config(pipe.scheduler.config)替换调度器,可自动继承权重对应的 beta 计划与预测类型,避免手动配置不一致。

相关文档与源码索引

  • 官方 API 文档:docs/source/en/api/schedulers/deis.md
  • 调度器实现:src/diffusers/schedulers/scheduling_deis_multistep.py
  • 单元测试:tests/schedulers/test_scheduler_deis.py
  • 公共输出结构:SchedulerOutput定义于 src/diffusers/schedulers/scheduling_utils.py
  • 调度器注册与导出:src/diffusers/schedulers/init.py、src/diffusers/init.py

【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询