ADM扩散模型如何以FID 3.85击败GAN:分类器引导与架构消融详解
2021 年之前你要是跟做生成模型的人说“扩散模型能干掉 GAN”十个人里有九个会觉得你疯了。那会儿 ImageNet 场景下 BigGAN 就是绝对霸主FID 指标被它按在地上摩擦几乎所有高分辨率生成任务都是 GAN 的天下。直到 OpenAI 那篇《Diffusion Models Beat GANs on Image Synthesis》出来直接在 ImageNet 512×512 上刷出 3.85 的 FID把当时的 SOTA GAN 拉下马这个叫 ADMAblated Diffusion Model的家伙也就是大家常说的 Guided Diffusion才正式进入大众视野。今天这篇文章就围绕 ADM 展开聊聊它为什么能赢、分类器引导到底怎么工作、实操时要怎么调参以及它对后来 Stable Diffusion 那一串方案的辐射影响。适合正在研究扩散模型、想搞清楚 FID 怎么优化、或者准备复现经典工作的同学读。1. 项目概览ADM 到底是什么它动摇了谁1.1 2019 年的“GAN 不败”氛围先把时间线拉回去。2019 年那会儿BigGAN 在 ImageNet 上可以说是横着走的128×128、256×256 甚至 512×512 的生成效果都漂亮得不像话。做生成任务的人默认一套组合拳用 GAN、堆 Batch Size、调谱归一化、改铰链损失顶多加一些渐进式训练或者自注意力模块。大家心里其实都清楚 GAN 有毛病——训练不稳定、模式坍缩、判别器太强或太弱都难受但在图像质量这个硬指标上还真没人能撼动它的位置。扩散模型那时候在干嘛呢还在玩玩具数据集。DDPM 在 CIFAR-10 上虽然能生成不错的图但拿到 ImageNet 这种千分类、高分辨率的数据集上计算量直接爆炸效果也没法跟 BigGAN 比。我记得当时大家普遍觉得扩散模型就是“理论上有意思、实用上跑不动”的玩意直到 ADM 这篇论文出来直接把 FID 3.85 拍在桌上跟 BigGAN 在 512×512 上正面对决并胜出整个圈子的风向才变了。1.2 FID 到底是什么指标聊 ADM 之前必须把 FID 说透。FIDFréchet Inception Distance是把生成图和真实图都塞进 Inception V3取倒数第二层特征然后假设这些特征服从高斯分布计算两个分布之间的 Frechet 距离。FID 越低说明生成分布和真实分布越接近它比 Inception Score 更靠谱的地方在于IS 只关注“生成的图是否像某个类别”FID 同时关注“生成的图是否覆盖真实分布的所有模式”。所以 FID 对模式坍缩很敏感一个只会生成猫的模型IS 可能很高但 FID 会很差。ADM 拿 3.85 的 FID 说事意味着它的生成结果不仅在“像不像”上达标在多样性上也扛住了。1.3 ADM 的三大核心卖点ADM 这个项目表面上是“一个更强的扩散模型”实际上它做了三件非常具体的事情第一把扩散模型的 UNet 架构做了一轮彻底的消融实验找到了几个真正有效的改进点这些改进合并起来就叫 ADM 架构。第二提出了分类器引导Classifier Guidance机制用一个小分类器在采样时实时把生成过程往指定类别方向推实现了保真度和多样性之间的人工调控。第三在 ImageNet 512×512 上用完整的 pipeline 验证了效果FID 3.85历史第一次在 ImageNet 这种高难度基准上击败 SOTA GAN。它适合谁来读如果你只做应用层用 Stable Diffusion 比较多那理解 ADM 的分类器引导能帮你搞懂为什么现在大家都用无分类器引导Classifier-Free Guidance因为后者就是站在前者的肩膀上改出来的。如果你正在复现扩散模型或者自己训练一个生成模型那 ADM 的架构消融结果就是一本现成的避坑手册。2. 核心思路拆解为什么扩散模型能翻身2.1 扩散模型的生成逻辑扩散模型的思路用一个形象的类比来说就是“先毁掉一幅画再学着把它画回来”。前向过程对一张真实图片逐步加高斯噪声一直加到图片彻底变成纯噪声。这个过程不需要训练就是一个固定的马尔可夫链每一步加噪的强度由 schedule 控制。反向过程训练一个神经网络输入噪声图和时间步 t让它预测“刚才加进去的噪声是什么”或者等价地预测“干净图像是什么”然后一步步去噪从纯噪声里恢复出图片。ADM 在数学上用的还是 DDPM 那套变分下界目标训练时随机采样一个时间步 t对原图加噪得到 x_t让模型预测噪声 ε。这里的“时间步嵌入”类似于 Transformer 里的位置编码把 t 编码成向量之后注入到网络中。整个框架说白了不复杂但训练起来非常吃算力这也是早期扩散模型打不过 GAN 的直接原因之一——同等参数量下扩散模型的训练成本高一个量级。2.2 架构消融哪几刀真正有用ADM 论文里最扎实的部分就是那一堆消融实验。OpenAI 那群人很老实地把 UNet 架构拆开一个一个地试看哪些改动对 FID 真正有正收益。我挑几个对后来影响最大的说。第一加宽比加深划算。他们发现增加通道数比增加 ResBlock 层数更有效。用大白话说同样的计算预算下把网络做得“又胖又矮”比“又瘦又高”在 FID 上表现更好。这一点后来被 LDM 等很多工作继承它背后的原因是扩散模型需要对不同尺度的特征做精细建模宽度大意味着每个尺度上能表达的信息更多。第二注意力机制的布点。原版 DDPM 只在 16×16 分辨率位置加了注意力ADM 发现把多头注意力加到 32×32、16×16、8×8 甚至 4×4 的更小分辨率上对高分辨率生成有很大帮助。这个也好理解低分辨率特征图的通道数多、空间尺寸小注意力可以捕捉全局依赖让模型在生成大结构时更协调。第三自适应归一化Adaptive Group NormalizationAdaGN。这是一个非常有代表性的细节。普通的 GroupNorm 是固定做归一化AdaGN 把时间步嵌入和类别嵌入经过一个全连接投影变成 per-channel 的 scale 和 shift在 GroupNorm 归一化之后做一次仿射变换。这样模型可以根据当前噪声级别动态调整特征的分布效果非常显著。第四残差块的上采样/下采样策略。ADM 借鉴了 BigGAN 的做法在上下采样路径上不是简单粗暴地 resize而是用带有跳跃连接的残差块来过渡保持梯度顺畅。这个细节看起来不起眼但对训练稳定性和最终效果都有实际影响。2.3 分类器引导的控制原理如果说架构改进是“体力活”那分类器引导就是 ADM 最有“头脑”的贡献。它的数学本质是贝叶斯分解。生成过程本身学的是 p(x_t)要想生成属于类别 y 的图像我们需要的是 p(x_t|y)。贝叶斯公式给出∇log p(x_t|y) ∇log p(x_t) ∇log p(y|x_t)。也就是说条件生成的打分函数等于无条件生成的打分函数加上一个分类器的对数梯度。扩散模型的采样过程恰好就是在用神经网络近似打分函数所以实现起来非常优雅先用一个无条件或类别条件)的扩散模型估计 p(x_t) 的梯度方向再混入一个额外训练好的噪声分类器 p(y|x_t, t) 的梯度。用一个系数 s 控制这个梯度的强度就得到最终的采样梯度。s 越大模型越倾向于生成分类器“认可”的图像保真度上升、多样性下降s 越小越接近原始扩散模型的自然分布。这个可调节的 s 是 GAN 不具备的。GAN 的生成器一旦训好保真度和多样性的平衡就焊死了想调只能重新训练。而 ADM-G 在采样阶段加一个系数就能实时控制这个“可操控性”直接打开了工程上的想象空间。3. 实操细节从训练到采样3.1 训练配置与 UNet 结构如果你要复现 ADM官方代码OpenAI 的 guided-diffusion 仓库是绕不开的。它的 UNet 结构大致是初始卷积后接四组下采样 stage中间层加多头注意力再通过上采样 stage 回到原分辨率。关键超参数如下表这是我在复现时常用的基线配置参数典型值说明基础通道数64 或 128第一层卷积的输出通道翻倍到 512通道乘数[1, 2, 4, 8]每个 stage 的通道翻倍ResBlock 数/层2~3每个分辨率阶段放 2 个残差块注意力分辨率32, 16, 8, 4多头注意力所在的分辨率注意力头数4~8多头注意力的头数时间嵌入维度512 或 1024正弦位置编码注入 AdaGNClass Embedding 维度512 或 1024类别条件嵌入同样注入 AdaGN训练超参方面我记得官方常用的配置是AdamW 优化器学习率 1e-4 到 2e-4 之间Batch Size 在 256 左右512×512 上可能降低到 128EMA 衰减系数 0.9999。混合精度一定要开否则显存直接爆掉。这里有个容易踩的坑时间步嵌入用的是 Transformer 风格的三角函数编码而不是简单的一维向量。这个编码会被投影两次再注入到每个 ResBlock 的 AdaGN 里如果你漏了 AdaGN 的投影层模型对噪声级别的感知会变差生成结果会明显发糊。3.2 分类器的训练方式分类器引导里的分类器不是随便拿一个 ImageNet 预训练分类器就能用的。原因很简单采样过程中分类器要在不同噪声级别 t 的图像上做预测而普通分类器只见过干净图片。所以 ADM 的做法是训练一个专门的噪声感知分类器输入加噪后的图像 x_t 和时间步 t同样做嵌入输出类别 logits。这个分类器结构不需要很大一个小型 ResNet 或者 UNet 的下采样部分就行。训练时同样随机采样 t把干净图加噪到对应级别再喂给分类器用标准的交叉熵损失。值得注意的是训练分类器和训练扩散模型要公用同一个加噪 schedule否则采样时梯度方向会出现偏差。从实操角度如果你不想自己训分类器直接在 ImageNet 预训练模型上微调几个 epoch 在低噪声级别也能凑合用但高噪声级别t 接近 T上会非常不准确导致引导梯度“瞎指挥”生成结果出现伪影。所以“噪声感知”这四个字是真金白银别省。3.3 采样过程与引导强度的选择采样时的流程可以简化成下面这样初始化一个纯高斯噪声图 x_T。从 t T 循环到 t 1。在每一步用扩散模型预测噪声 ε_θ(x_t, y)再计算分类器梯度 ∇_x_t log pφ(y|x_t, t)。两者按公式 ε ε_θ - s·√(1-ᾱ_t)·∇_x_t log pφ 合并作为新的噪声估计。用 DDPM 或者 DDIM 的更新公式从 x_t 推出 x_{t-1}。循环结束输出 x_0。引导强度 s 是最重要的超参数。s 太小引导效果不明显类别保真度不够s 太大生成图像会出现过度锐利甚至产生伪影多样性暴跌。在 ImageNet 512×512 上论文里用到的 s 大概在 1.0 到 2.0 之间再往上走 FID 反而可能恶化。实操里我习惯先跑一组小规模消融在 256×256 分辨率下分别用 s 0.5、1.0、1.5、2.0 生成 5000 张图对比 FID 和人工肉眼观察选定 s 之后再上完整实验。这个方法虽然朴素但非常有效能省下大量高价分辨率下的试错成本。4. 常见问题与调试心得4.1 FID 忽高忽低怎么排查FID 这个东西有个让人头疼的特点受采样数量、生成种子、随机噪声分布影响很大。你要是每轮只采样 200 张算 FID那结果方差大到没法看。ADM 论文和后续工作基本都用 5000 张以上才算数。我自己的经验是至少 10000 张把随机种子固定好计算时跟测试集特征分布对齐。如果 FID 忽高忽低先别怀疑模型坏了把样本量加上去、种子固定住再比较。4.2 引导强度的“甜蜜点”问题我前面说的 s 范围只是参考不同数据集、不同分辨率、不同分类器强度都会改变最优 s。理论上 s 越大生成结果越贴近分类器的偏好但也越容易导致模式坍缩——分类器觉得好的样本集中在一小块分布上真实分布的其他部分全丢了。这就是为什么 FID 曲线会随着 s 增大先降后升而 IS 则一直涨到某个点后缓慢下降。调试时一定要同时看 FID 和 IS不要只看一个。FID 降 IS 升那说明引导在起作用如果 FID 开始回弹但 IS 还在涨说明多样性已经受伤了这时候就该调小 s。4.3 训练过程中模型崩掉扩散模型训练最常见的崩法有两种loss 突然变成 NaN或者模型输出出现明显条带伪影。NaN 大概率是学习率太高、混合精度溢出或者某个残差块的梯度爆炸。解决办法是降学习率、换 AdamW 并加梯度裁剪。条带伪影则经常和 attention 在低分辨率上的权重失衡有关我遇到过把注意力层去掉之后反而更稳的情况代价是 FID 轻微变差。4.4 显存不够怎么办ADM 在 512×512 上的完整训练不是个人玩家能轻易复现的官方也是多卡并行。如果你只是想在单卡上实验我的建议是直接砍分辨率到 256×256或者用梯度累积模拟大 Batch Size。采样阶段可以用 DDIM 把步数从 1000 降到 250既保持质量又提速。另一个技巧是采样时开 fp16扩散模型对数值误差的容忍度比 GAN 高不少实测对最终 FID 影响很小。5. 对后续生成式 AI 的辐射影响5.1 无分类器引导是它的直系后代ADM 的分类器引导有个明显短板需要在采样时额外跑一个分类器而且分类器质量直接影响生成结果。后续的扩散模型研究很快发现不需要显式分类器也能实现引导——这就是无分类器引导Classifier-Free Guidance。核心思想是训练时随机丢弃类别条件让模型同时学会条件和无条件预测采样时把两者外推。它更简洁、更稳定所以现在 Stable Diffusion、Imagen 等主流方案全部默认用 CFG。但 CFG 的数学动机就是从 ADM 那个“贝叶斯分解 梯度合并”的思路延伸出来的。理解分类器引导再看 CFG 会特别顺畅。5.2 潜在扩散模型继承了它的骨架Stable Diffusion 的底层骨架——UNet 注意力 时间步条件注入基本就是 ADM 的架构在潜空间的重演。LDM 把扩散过程从像素空间搬到 VAE 潜空间大幅降低了计算量但 U-Net 的残差块布局、Attention 布点、条件注入方式都能看到 ADM 的影子。所以学 ADM 架构永远不会过时它是理解后面一大堆工作的地基。5.3 对个人研究者的启示ADM 的另一个价值是研究范式上的。它没有提出全新的数学框架而是把已有组件DDPM、UNet、Self-Attention、BigGAN 的残差块挑出来重新组合用极其扎实的消融实验证明了每个部件的必要性。这对想做生成模型研究的人是很好的启发与其追新架构不如把自己手里的模型每个螺丝都拧明白很多时候性能差距就是这些细节累积出来的。在我个人的实际体验里真正把 ADM 的消融结论吃透之后再去调后来的扩散模型思路会清晰很多。比如看到某个新模型 FID 有提升我能大概判断出它是靠哪一部分的改动换来的而不是盲猜。最后再提醒一句复现经典工作时记得把官方代码里的 EMA、混合精度、学习率 warmup 这些“隐形组件”一并实现这些被论文正文一笔带过的细节往往决定了你复现出来的 FID 是 3.9 还是 5.5。