Classifier-Free Guidance(CFG)全面解读:从 Classifier Guidance 到现代扩散模型的核心技术

一、背景:Classifier Guidance 利用外部分类器指导扩散模型

扩散模型的目标是在去噪过程中预测噪声:

如果希望模型生成某一个类别(例如"猫"),最直接的方法就是加入条件 y:

OpenAI 最早提出的方法:除训练扩散模型(UNet)之外,再额外训练一个分类器(Classifier)。

系统变成:

复制代码
           x_t
            │
      ┌─────┴─────┐
      │           │
      ▼           ▼
    UNet      Classifier
 ε(x,t,y)     p(y|x,t)
      │           │
      │     ∇logp(y|x)
      └─────┬─────┘
            │
       修正去噪方向
  • UNet负责预测噪声;
  • Classifier负责判断当前图片属于哪个类别;
  • 分类器不仅给出类别,还通过梯度告诉扩散模型:应该往哪个方向修改图像更符合目标类别。

最终采样方向变成:


二、Classifier Guidance 引发的质疑

虽然 Classifier Guidance 能明显提升生成质量,但论文作者提出了一个非常深刻的问题:

模型真的画得更好了,还是只是学会了迎合分类器?

扩散模型经典评估指标如:FID、IS(Inception Score),本质上都依赖 Inception-V3 分类网络

换句话说,生成图片最后也是交给分类器评分。而 Classifier Guidance 在采样过程中每一步都利用分类器梯度修改图片。

就像:学生考试 → 提前知道阅卷老师是谁 → 专门写老师喜欢的答案 → 最终得高分

因此产生质疑:Classifier Guidance 会不会其实是在做一种"对抗攻击"?

不断调整像素,让分类器越来越确信:"这一定是一只猫!" 即使人眼看起来未必更自然。

因此作者希望找到一种完全不依赖任何外部分类器的方法。


三、CFG 的数学思想

作者利用贝叶斯公式进行了一个非常漂亮的推导。

原来:

利用:

得到:

代回去:

整理得:

这就是著名的 CFG 公式。

通常写成:


四、CFG 的核心思想

CFG 的核心思想可以概括成一句话:

不用分类器,而是利用同一个 UNet 自己学习"有条件"和"无条件"之间的差异。

以前:UNet + Classifier

现在:只有UNet

把原来分类器提供的信息:

变成: 即:Prompt 对图像产生的影响


五、CFG 在网络中到底如何实现?

CFG 最大的改变发生在训练阶段。没有增加新的网络,只是改变了训练方式。

1. Condition Dropout

训练时:随机丢弃条件。

例如:

文本:

复制代码
"A cat"

训练过程:90%

复制代码
输入:x_t t "A cat"

10%

复制代码
输入: x_t t NULL

这里 NULL 可以是:空 Token、全零 Embedding、空 Prompt

论文称为:Condition Dropout

于是:

复制代码
                x_t
                 │
       ┌─────────┴─────────┐
       │                   │
       ▼                   ▼
 Prompt="cat"        Prompt=NULL
       │                   │
       └─────────┬─────────┘
                 ▼
             同一个UNet
                 ▼
          ε(x,t,condition)

始终只有:一个 UNet。


2. UNet 学到了什么?

由于训练过程中有时候有 Prompt,有时候没有 Prompt,

UNet 自然学会:

第一种情况

输入:cat,输出:猫图片对应噪声,即:

第二种情况

输入:NULL

输出:整个数据集平均噪声,即:

一个网络,同时学会了:条件预测、无条件预测


六、推理阶段:UNet 运行两次

CFG 推理流程如下:

复制代码
             x_t
              │
      ┌───────┴────────┐
      │                │
      ▼                ▼
 Prompt="cat"     Prompt=NULL
      │                │
      ▼                ▼
     UNet            UNet
      │                │
      ▼                ▼
 ε_cond          ε_uncond
      │                │
      └───────┬────────┘
              ▼
 ε_cfg = ε_uncond + w(ε_cond-ε_uncond)
              │
              ▼
        更新x_{t-1}

虽然没有 Classifier,但UNet 会运行两次。

相比 Classifier Guidance少了Classifier Forward、Classifier Backward,速度明显更快。


七、Stable Diffusion 中 CFG 的实现

CFG 中的UNet 基本没有变化,变化的是文本条件输入。

例如 Stable Diffusion:

复制代码
Prompt → CLIP Text Encoder → Text Embedding → Cross Attention → UNet → 预测噪声

如果 Prompt 是:"A cat",UNet 就得到:条件预测。

如果 Prompt 是:空,CLIP 输出 NULL Embedding,UNet 仍然可以正常工作,因此CFG 根本没有增加新的网络。只是同一个 UNet 接受不同的文本条件。


八、Guidance Scale 的物理意义

CFG 中:

w 为 CFG Scale

w=1,几乎没有强化 Prompt,生成更加自然,但可能Prompt 不够准确。

w≈7.5 Stable Diffusion 默认值。通常效果最好,Prompt 与自然度取得平衡。

w=15 Prompt 非常强。模型拼命满足文字描述。但容易出现过饱和、人脸崩坏、色彩失真、重复纹理、结构异常

Guidance Scale 本质就是:Prompt 对生成过程施加影响的强弱。


九、为什么 CFG 能替代 Classifier?

Classifier Guidance 中,分类器提供的是:

告诉模型:朝目标类别方向修改图片。

而 CFG 中:

表达的是:加入 Prompt 后,预测噪声发生了怎样的变化。

这个差值实际上就是:条件信息带来的引导方向。

因此:

Classifier Guidance Classifier-Free Guidance
引导方向来自分类器梯度 引导方向来自两次 UNet 预测差值
两个网络(UNet + Classifier) 一个网络(UNet)
每步需要前向和反向传播分类器 每步仅进行两次 UNet 前向推理
需要额外训练分类器 无需分类器,只需训练时进行 Condition Dropout
难以扩展到开放文本条件 天然支持自然语言 Prompt

可以看到,两者的目标完全一致:都是估计"条件引导方向",只是来源不同。CFG 将这一能力内化到 UNet 中,从而摆脱了对外部分类器的依赖。