Classifier-Free Guidance条件扩散模型入门指南:从理论到PyTorch实战

1次阅读
没有评论

共计 1409 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

背景:从 Classifier Guidance 到 Classifier-Free

传统 classifier guidance 方法通过预训练分类器的梯度(gradient)来引导扩散过程,但存在两个致命缺陷:

Classifier-Free Guidance 条件扩散模型入门指南:从理论到 PyTorch 实战

  1. 梯度冲突 :分类器训练目标与生成质量目标不一致,导致梯度方向出现偏差
  2. 计算代价 :需要额外的前向 - 后向传播计算,显存占用增加 30% 以上

而 classifier-free guidance 通过联合训练条件 / 无条件扩散模型,直接学习条件嵌入(conditional embedding)的语义控制能力。其优势在于:

  • 统一的目标函数避免梯度冲突
  • 单次前向传播完成条件生成
  • 条件强度可通过 guidance scale 连续调节

核心实现

1. 联合训练策略

class ConditionalDiffusion(nn.Module):
    def __init__(self, unet_dim=512, cond_dim=128):
        super().__init__()
        # 共享主干网络
        self.unet = UNet(dim=unet_dim)  # [B,C,H,W]->[B,C,H,W] 
        # 条件嵌入层
        self.cond_proj = nn.Linear(cond_dim, unet_dim)  # [B,D_cond]->[B,D_model]

    def forward(self, x, t, cond=None):
        # 无条件分支
        if cond is None:
            return self.unet(x, t)  # [B,C,H,W]
        # 条件分支
        cond_emb = self.cond_proj(cond)  # [B,D_model]
        return self.unet(x, t, cond_emb)  # 需修改 UNet 支持条件输入 

训练时交替使用两种输入:

  • 50% 概率使用真实条件文本
  • 50% 概率将 cond 设为 None

2. Guidance Scale 公式推导

定义条件预测 ε_c 和无条件预测 ε_u,最终噪声预测为:

ε_θ = ε_u + w(ε_c - ε_u)

其中 w(guidance weight)控制条件强度:

  • w= 1 时退化为普通条件模型
  • w>1 时增强条件控制
  • w<1 时降低条件影响

3. 条件嵌入实现

# 文本编码器输出形状 [B, seq_len, D_text]
text_emb = clip_model.encode_text(prompts) 
# 均值池化获得全局条件向量 [B, D_text]
cond = text_emb.mean(dim=1)  
# 调节条件强度
noise_pred = (1 + guidance_scale) * cond_pred - guidance_scale * uncond_pred

性能分析

质量指标变化

guidance weight FID↓ CLIP↑
1.0 28.7 0.72
3.0 19.2 0.81
7.0 15.4 0.85
10.0 18.9 0.83

注:w>7 时出现质量下降,建议范围 3 -7

显存占用

batch_size 显存 (GB)
16 10.2
32 18.7
64 OOM

避坑指南

  1. 条件维度平衡 :
  2. cond_dim 建议取 model_dim 的 1 / 4 到 1 /2
  3. 过大会导致无条件生成质量下降

  4. 梯度爆炸预防 :

  5. 初始化 cond_proj 权重为小随机值
  6. 添加梯度裁剪(gradient clipping)
  7. 使用 AdamW 优化器(lr=3e-5)

开放问题

如何将 classifier-free guidance 扩展到视频生成?可能的思路:

  • 时间维度条件嵌入
  • 3D UNet 架构改造
  • 跨帧注意力机制

期待读者在实践中探索更多可能性。

正文完
 0
评论(没有评论)