Hub Part IX · Diffusion / DiT
Part IX · Diffusion / DiT 推理加速

从 1000 步到 1 步

DDPM 原版要 $T = 1000$ 步去噪。SDXL Turbo 一步出图, HunyuanVideo 一段视频从 100 步压到 8 步。 四条路同时压:更高阶 ODE 求解器把步数砍到 10; consistency / 蒸馏砍到 1-4; cache 让单步成本减半; 量化把每步从 fp16 压到 INT4。

§9.1ODE 求解器 · DDIM / DPM-Solver / UniPC

Diffusion 是按 $T$ 步逐步去噪:

$$ x_{t-1} = \mu_\theta(x_t, t) + \sigma_t \, \epsilon $$

原 DDPM 要 $T = 1000$;要部署,步数即一切。 Diffusion ODE 形式(DDIM 揭示):

$$ \frac{dx}{dt} = -\frac{1}{2} g^2(t) \nabla \log p_t(x) \approx -\frac{1}{2}g^2(t) \cdot \epsilon_\theta(x, t)/\sigma_t $$
方法关键想法典型步数
DDIM (2020)确定性 ODE,可降到 50 步50
DPM-Solver (2022)把 ODE 用半解析高阶展开10–20
DPM-Solver++ (2022)condition / cfg 数值稳定10–20
UniPC (2023)predictor-corrector 高阶5–10
Heun / Karras (EDM)更好的 noise schedule20–35

DDIM 单步代码

# DDIM: 给定 x_t, 预测 x_0, 然后用 ODE 跳到 x_{t-1}
def ddim_step(x_t, t, t_prev, model, alpha_bar):
    # 模型预测噪声
    eps = model(x_t, t)
    # 从 x_t 与 eps 反推 x_0
    x_0_pred = (x_t - (1 - alpha_bar[t]).sqrt() * eps) / alpha_bar[t].sqrt()
    # 用 alpha_bar[t_prev] 重构 x_{t-1} (确定性, sigma=0)
    x_prev = alpha_bar[t_prev].sqrt() * x_0_pred + (1 - alpha_bar[t_prev]).sqrt() * eps
    return x_prev
# 50 步: 用 50 个 t 等间距, 比 DDPM 快 20x

§9.2Consistency Models / LCM · 一步到位

Consistency Models / LCM — Latent Consistency Models for 1-/4-Step Generation
ICML 2023 / 2024 Song, Dhariwal · OpenAI · CM · LCM

Consistency Model:让模型在任意 $t$都能直接预测 $x_0$。 数学上:$f_\theta(x_t, t) \approx x_0$; 训练让 $f_\theta(x_{t}, t) = f_\theta(x_{t+1}, t+1)$。 部署只需 1 步(或 2–4 步迭代)→ 50× 加速。 LCM:把它套到 latent diffusion(SD 系列),用 LoRA 蒸出 8-step / 4-step 版。

# Consistency Model loss: 让相邻 step 的预测一致
def cm_loss(student, teacher_ema, x, t, t_next):
    # x_{t} ~ q(x_t | x_0)
    x_t = forward_diffuse(x, t)
    x_t_next = forward_diffuse(x, t_next)   # 同一 x_0 在两个 noise level
    pred_t      = student(x_t, t)            # 预测 x_0
    pred_t_next = teacher_ema(x_t_next, t_next)
    return (pred_t - pred_t_next.detach()).pow(2).mean()
# 训完: 一步推理 f(x_T, T) → 直接 x_0

§9.3DMD / DMD2 · 用 GAN 的方式蒸 diffusion

DMD / DMD2 — Distribution Matching Distillation
CVPR 2024 / NeurIPS 2024 Yin et al. · MIT / Adobe · DMD · DMD2

1 步生成器 $G$ + 两个 score 网络(pretrained "real" score + "fake" score) 互相博弈: 让 $G$ 输出的分布与 teacher 一致。 数学上等价于最小化反向 KL。 DMD2 加 GAN loss 让单步质量逼近 1000 步 teacher。 SDXL 单步出图 $\approx$ 多步 teacher 质量。

DMD 的训练循环

# DMD: 用两个 score model 估算梯度
def dmd_step(G, real_score, fake_score, z):
    # 1. 生成一张图
    x_gen = G(z)
    # 2. 加 noise 到一个 timestep t
    t = sample_t()
    x_noisy = forward_diffuse(x_gen, t)
    # 3. 两个 score 网络分别预测噪声
    s_real = real_score(x_noisy, t).detach()    # pretrained, frozen
    s_fake = fake_score(x_noisy, t).detach()
    # 4. G 的梯度 ∝ (s_fake - s_real)
    grad = (s_fake - s_real)
    loss = (x_gen * grad).sum()
    loss.backward()
    # 5. 另一边: fake_score 也要学 G 输出的分布 (online)
    fake_score_loss = (fake_score(x_noisy, t) - true_noise_for(x_gen)).pow(2).mean()

同家族派生:SDXL Turbo (ADD)SD3 TurboPCMHyper-SDSwiftBrushSiD

§9.4DeepCache / Δ-DiT / TGate · 不重算"深层"

DeepCache — Accelerating Diffusion Models for Free
CVPR 2024 Ma, Fang, Wang · NUS · arXiv:2312.00858

U-Net 中、深层特征在相邻 timestep 之间高度相关。 DeepCache:每 N 个 step 才重算一次 deep block, 其余 step 复用上次的中间结果, 浅层每步重算(控制变化方向)。 SD-1.5 上 ~2× 加速,几乎无损。

# DeepCache: 浅层 (downsample/upsample 入出) 每步算, 深层每 N 步算一次
class DeepCachedUNet:
    def __init__(self, unet, cache_interval=2):
        self.unet = unet
        self.cache_interval = cache_interval
        self.cached_deep = None

    def forward(self, x, t, step_idx):
        h_down = self.unet.down_blocks(x, t)
        if step_idx % self.cache_interval == 0 or self.cached_deep is None:
            self.cached_deep = self.unet.mid_block(h_down, t)
        # 复用上次 cached 的 deep feature
        h_up = self.unet.up_blocks(self.cached_deep, h_down, t)
        return self.unet.head(h_up)
Δ-DiT / FORA / TGate / TeaCache
2024 · DiT-aware caching

DiT(PixArt / Sora-class)没有 U-Net 的 hourglass 结构。 Δ-DiT 把 "deep block" 类比改成"高频/低频" block: 早 timestep 缓存全局结构、晚 timestep 缓存高频细节。 TGate / TeaCache 进一步 sample-aware 决定哪一 step 跳过哪些 block。 Flux.1、HunyuanVideo、CogVideoX 都用 caching 推到 2–5× 加速。

Demo 7 · Diffusion · 步数 vs 质量 vs DeepCache
左边是当前生成画面,右边是目标。 50-step DDIM 最稳但最慢;4-step LCM 快 12×、质量稍逊;1-step DMD 是"一锤定音" (这个 demo 是简化模型,不能完全复刻真实 quality)。 DeepCache 让单步成本变 0.75x,对短 schedule 提升相对小、对长 schedule 提升大。

§9.5ToMe-SD · 视觉 token 合并

ToMe-SD — Token Merging for Stable Diffusion / DiT
CVPR 2024 / 2023 · ToMe-SD

SD / DiT 的 latent token 之间常常很相似(背景、空旷天空)。 每个 attention block 入口处把相似 token 合并, attention 之后解合并。 自然剪到一半 token,~2× 加速,~1% 质量。 后续 ToMe-SDXL、CacheToMe 沿此线。

# ToMe: 把 token 分成 src 与 dst, src 中每个并到最相近的 dst, attention 后再解合并
def tome_merge(x, r):
    # x: [B, S, D], r = 要合并掉的 token 数
    src, dst = x[:, ::2], x[:, 1::2]                # 简单的 stride 划分
    sim = cosine_similarity(src, dst)               # [B, S/2, S/2]
    edges = sim.argmax(dim=-1)                       # 每个 src 最相近的 dst
    scores = sim.max(dim=-1).values
    keep = scores.topk(src.shape[1] - r, largest=False).indices  # 不合并的 src
    # 合并: 对 dst 中"被合并"的位置取平均
    return apply_merge(src, dst, edges, keep)

§9.6SVDQuant / Q-Diffusion / ViDiT-Q · 把 DiT 量到 4-bit

SVDQuant — Absorbing Outliers by Low-Rank Components for 4-Bit Diffusion
ICLR 2025 Li et al. · MIT · arXiv:2411.05007

DiT 量化的核心痛 = 激活有大 outlier。 SVDQuant:把权重 $W = LR + Q$ 分解为低秩部分 $LR$(吸 outlier)+ 量化 INT4 残差 $Q$。 低秩部分 fp16 跑、$Q$ 走 INT4 tensor core。 Flux.1-dev 量到 W4A4 仅掉 ~0.1 FID。

# SVDQuant: W ≈ L R + Q
def svdquant_decompose(W, rank=32, n_bits=4):
    # 1. SVD 分解
    U, s, V = torch.linalg.svd(W, full_matrices=False)
    L = U[:, :rank] * s[:rank].sqrt()
    R = (V[:rank, :].T * s[:rank].sqrt()).T
    LR = L @ R                                       # 低秩近似
    # 2. 残差量化到 INT4
    residual = W - LR
    Q = quantize_int4(residual)
    return L, R, Q
# Forward: y = x @ L @ R + x @ dequant(Q)
# 第一项 fp16, rank 小, 很快
# 第二项 INT4 tensor core, 主体运算
Q-Diffusion / ViDiT-Q
2023 / 2024 · Q-Diffusion · ViDiT-Q

Q-Diffusion:noise-schedule-aware PTQ, 在不同 timestep 用不同 calibration set 选 scale。 ViDiT-Q:把同样思路推到 video DiT,处理跨帧分布漂移。

速查 · diffusion 加速组合拳
  • 有 teacher 模型 + 训练资源 → LCM / DMD2,1-4 步出图。
  • 已部署 SD,只想免费提速 → DeepCache + ToMe-SD,2-3× 不掉分。
  • 边缘部署 → SVDQuant W4A4
  • 长视频 → Δ-DiT / TeaCache + LCM
  • 组合上限:SVDQuant + DMD2 + DeepCache, Flux 在 4090 上 1 步出图 0.4 s(vs baseline 8 s)。