想象一间画室。一位画家面对一张沾满随机墨迹的草稿纸,他从不一挥而就,而是先把纸揉皱、泼墨,再一步步把混乱的墨迹“救”成一幅画——这个过程就是扩散模型的去噪。问题在于:画家自由发挥时,画出的可能是猫、是狗或是一团云,客户明明要“戴帽子的猫”,他却交来一只打盹的橘猫。怎么让他“听指挥”?团队先想了个笨办法:请一位评审专家在旁边喊方向,可专家又贵又总看走眼。后来艺术总监发现了一个妙招:让画家每次同时交两版草稿——一版自由画,一版照着需求画——两版之间的差别,正是“需求的方向”。把这差别放大后再加回去,画家就会画出客户想要的东西。这个办法,就是无分类引导(Classifier-Free Guidance,CFG)。它如何推导、如何训练、那个“放大音量”的旋钮怎么调,以及它如何撑起 Stable Diffusion 这类爆款产品,正是本文要讲完的完整故事。
对 AI 从业者而言,CFG 是理解 Stable Diffusion 等文生图产品“为何听指挥”的核心钥匙,也是从事图像生成、提示词工程与推理优化的必备基本功。
可视化演示
展示Classifier-Free Guidance公式推导、条件丢弃训练策略与引导尺度权衡,切换模式理解扩散模型核心引导技术的数学原理与工程实践。
本节配有交互动效(进入视口后自动加载,约 3KB)。
CFG推理引导公式 条件分数ε_cond和无条件分数ε_uncond线性组合,w控制条件引导强度 w=0为纯无条件生成,w越大越贴合条件但多样性降低 ε = (1+w)·ε_cond - w·ε_uncond CFG无需额外分类器即可实现条件引导,是Stable Diffusion的核心技术
背景与动机
画家把第一幅自由创作挂上墙,客户只看了一眼:“我要的是戴帽子的猫。” 画家很委屈:“我画的确实是猫啊。” 他没错,但也没用——作品和客户需求之间没有任何保证,全凭运气。自由发挥时,画家脑子里装着所有猫的样子,随机挑一个画,这就是无条件生成的本质:模型学到了整个数据分布,却不知道此刻该把画笔落在哪个点上。
扩散模型与此完全同构。它的生成过程是从一团纯噪声出发,逐步去噪成一张图;而无条件模型只掌握数据的整体分布——所有图像的“平均气质”。你给它任何提示词,它都在分布里随便挑一个区域落笔,画面与文本的对齐全靠巧合。训练时虽然会把文本条件注入网络,但条件信号在每步去噪中只是“轻微耳语”,模型经常听岔:明明输入“猫”,却画出狗。
于是工业界与学术界都在思考同一个问题:如何把条件信号“推”得更用力,让模型坚定地朝用户想要的方向走。这个“推一把”的动作,就是引导(guidance)的本质,也是 CFG 要解决的核心矛盾。
艺术总监的结论也很直接:光会画不够,还要能“按需求坚定地画”。那么问题来了——用什么方式推,才推得准、推得起?
分类器引导
第一版方案很朴素:请一位“评审专家”站在画架旁。画家每擦一笔,评审就喊:“再往左一点,那里更像猫的轮廓。” 画家的画笔因此被硬生生拽向需求。这位评审,就是分类器(classifier)。在数学上,这个拽法来自贝叶斯分解:把“在满足条件 c 的前提下看到带噪画面”的后验得分,拆成“无条件得分”加上“分类器给出的条件得分”。
1. 条件后验得分:我们要在“画面 z_t 满足客户条件 c”的后验分布上采样,取对数后对 z_t 求梯度,就能得到把画面推向需求的最优方向。
2. 贝叶斯分解:贝叶斯公式把条件后验拆成先验乘以似然,取对数后乘法变加法,与 z_t 无关的常数项在求导时会消失。
3. 无条件得分:第一项是模型中本来就存在的无条件得分,相当于画家自由发挥时的直觉笔触。
4. 分类器梯度:第二项来自额外训练的分类器,它像评审专家的手指,指出“往哪个方向擦,画面更像客户要的东西”。
但这位评审的毛病太多:它得先在一个“充满噪声的画面上”学会分辨内容,而噪声越大它越看不清,给的方向经常是错的,甚至退化成对抗性的乱指。训练它还要额外花一份算力,维护成本极高。艺术总监算了笔账,觉得不划算,决心换一种“不用评审”的办法。
核心公式推导
艺术总监的灵感来自一个被忽略的细节:画家自己其实知道需求是什么——只要他盯着需求单,他就能画出对照版。为什么非要请外人来评判?干脆让画家同时交两版草稿:一版完全不看需求、凭直觉画(自由版),一版紧盯需求、拼命对齐(对照版)。两版草稿之间的差异,就是需求“推”着画笔的方向。
这个洞察对应到数学上,就是“隐式替代”:条件模型在训练中已经学会了条件分布的信息,它本身就编码了 p(c|z_t),不需要再用一个显式分类器去逼近。于是 CFG 用同一个模型在两种输入下的输出之差,替换了分类器梯度。推理时的引导公式如下:
1. 条件预测:模型同时看到带噪画面与条件文本,预测当前噪声,相当于画家盯着需求单画的“对照版”。
2. 无条件预测:模型只看带噪画面、不看任何条件,预测当前噪声,相当于画家被收走需求单的“自由版”。
3. 需求方向:两版预测之差正是“客户需求”给画面带来的方向增量,等价于一种隐式的条件得分,CFG 的核心创新就在这一步。
4. 放大并叠加:引导尺度 w 把需求方向放大 w 倍,再叠加回自由版基线上,得到最终更强的引导预测。
1. 噪声与得分的关系:扩散模型中噪声预测与得分函数只差一个与时间有关的已知系数,因此两者可以互相换算,方向完全一致。
2. 对称形式:把两个噪声预测都换成得分函数,就得到同样结构的 CFG 得分表达式,便于理论分析与后续推导。
画家从此不再需要评审:自己画两版、自己对比、自己用力。CFG 的名字里带着“免分类器”,正是因为它把这个外部依赖整个删掉了。
训练策略
但新问题出现了:画家“自由画”和“照需求画”是两种技能。如果训练时永远只给他需求单,他从来不知道“不看需求”时手该怎么动;可推理时我们又真的需要那版自由草稿。艺术总监的安排很巧妙:训练时随机收走需求单——有些回合给需求,有些回合把需求擦掉,让他凭直觉画。
对应到实现上,就是在训练中以一定概率 p 把条件 c 替换成空条件 ∅(空字符串、空白 token 或零向量),其余时候正常输入条件。这样同一个模型、同一套权重,同时学会了两种能力:看到条件就对齐,看不到条件就回到数据分布本身。目标函数写成:
1. 训练期望:对随机时刻 t、真实噪声 ε、干净图像与条件 c 取平均,把海量练习回合全部纳入损失。
2. 标准答案:训练时我们已经知道加进画面的真实噪声 ε,它是去噪任务的“标准答案”。
3. 预测误差:模型预测噪声与真实噪声的平方距离越小,说明画家对画面当前状态的理解越准。
4. 随机条件开关:以概率 p 将条件替换成空条件 ∅,以概率 1−p 保留真实条件——这就是“随机收走需求单”的数学写法。
实践中,丢弃率 p 的经验值是 10%~20%:太低则模型对空条件不敏感,太高则条件生成能力退化。训练时只需在 batch 内随机选一部分样本做无条件处理,几乎不增加额外成本。训练完成,画家闭上眼也能画,睁着眼也能画——所谓“无条件模型”从来不是另一个模型,而是同一个画家被收走需求单时的状态。
引导尺度权衡
艺术总监手里有个扩音器,旋钮上写着 w。开太小声,画家听不清需求,画得自由散漫;开太大声,画家被吼到只会机械复读需求模板,画面僵硬、颜色刺眼。找到那个“刚好能听清又不被吓到”的音量,就是引导尺度选择的艺术。
从分布视角看,CFG 的放大行为等价于把“条件似然”取 w 次方:w 越大,只有足够像需求的画面位置才保留下来,其他位置被急剧压制。这相当于把客户需求从“建议”提升为“命令”:
1. 自由发挥基线:p(z_t) 代表画面本身在自然数据分布中的概率,对应不看需求的自由版草稿。
2. 条件似然放大:把“像不像客户需求”的似然取 w 次方,w 越大,只有足够符合需求的画面位置才保留权重。
3. 比例符号:∝ 表示只关心相对大小,归一化常数由分母自动吸收,不影响采样时“往哪走”的方向。
实际效果可以总结为一对矛盾:w 越大,提示词匹配度越高(画面更“贴题”),但样本多样性越低(所有图长得越来越像,分布缩成一个尖峰);w 超过某个上限后还会出现过曝、伪影、纹理僵化。Stable Diffusion 的默认值是 7.5,通用推荐区间在 5~8,具体甜点取决于模型与采样器。好的艺术总监,永远在“听指挥”与“留灵气”之间找平衡。
实际应用
画室里最抢手的画家,是那个“每单都能稳定交付客户需求”的人。CFG 正是让 AIGC 产品稳定交付的定海神针——现在的文生图模型,几乎都靠它让画面“听人话”。
Stable Diffusion 系列(SD 1.x、SD 2.x、SDXL)在采样器内部默认执行 CFG:每一步同时做一次条件前向和一次无条件前向,再用引导公式合成最终方向。Imagen 等模型同样采用 CFG 控制提示词对齐。用户界面里的"CFG Scale"滑杆,调的就是公式中的 w。
CFG 还催生了一个非常实用的衍生技巧:负面提示词(negative prompt)。想要“没有水印、没有模糊”,就把这些不想要的内容当作一个负向条件,在公式里朝它的反方向推——相当于再交一版“反向需求”草稿,把画面从坏方向推开。采样器(DDIM、DPMSolver++、Euler)则负责在引导后的得分场上走得更快更稳,两者配合,才得到既清晰又听话的画面。
从产品到开源生态,CFG 已经成为“条件生成”的标准基础设施。艺术家和工程师调的不是玄学,而是那个“两版草稿之差”的放大倍数——理解这一点,就理解了整个扩散模型可控生成的地基。
局限与进阶
再好的方法也有代价。画家每画一步都要交两版草稿,工作量翻倍——CFG 推理时每步需要两次前向传播,计算成本大约翻倍,这在低延迟在线服务里是一笔扎眼的开销;w 调得过大还会“过冲”,出现伪影。
于是研究界开始思考:能不能让画家“闭着眼也画出两版结合的效果”?答案是知识蒸馏。训练一个学生网络,直接以老师(CFG)的引导输出为目标,让学生用一次前向就复现“两版草稿对比”后的成品:
1. 学生模型:ε_φ 是一个单次前向的学生网络,目标是学会老师的引导行为,而不是重新学一遍两版对比。
2. 老师输出:带波浪号的 ε_θ 是 CFG 老师做两次前向得到的引导预测,作为教学范本。
3. 模仿差距:最小化学生与老师在带噪画面上的预测差距,蒸馏完成后学生一步就“自带引导”,推理成本直接减半。
由此诞生了 guidance distillation、SD-Turbo、LCM 等一系列加速方案,让高质量文生图跑进实时交互。研究界还在探索自适应引导尺度——不同内容、不同去噪阶段使用不同的 w。也许未来的画家闭着眼也能画出客户要的画,但理解“两版草稿之差”这个原理,依然是这一切的地基。
AI 应用场景
文生图产品的提示词控制
阶段:推理与生成控制
解决的问题:没有 CFG 时,用户输入的提示词对画面影响微弱,产品“不听指挥”,生成结果随机漂移。CFG 通过放大两版预测之差,把条件信号变成硬约束,是文生图产品可用性的底线。
具体案例:Stable Diffusion WebUI 界面上的 CFG Scale 滑杆默认 7.5——用户调高获得贴近提示词的画面,调低获得发散创意稿;ComfyUI 的自定义节点同样暴露 CFG 参数,供工作流按需调整。
生成质量与多样性的评测调参
阶段:模型评测与调参
解决的问题:固定 w 无法同时兼顾提示词对齐与生成多样性。传统做法靠肉眼调参,主观且不可复现;AI 评测用批量生成加指标量化,把 w 的选择从“玄学”变成“数据”。
具体案例:评测团队在 1K 条提示词集合上按 w=3/5/7/9/12 分组批量生成,用 CLIP score 评估对齐程度、用 FID 与多样性指标评估分布覆盖,从而为上线版本选定最优配置区间。
低延迟部署中的引导蒸馏
阶段:模型优化与推理部署
解决的问题:CFG 每步两次前向,在线服务算力成本接近翻倍、延迟超标。通过引导蒸馏把 CFG 效果压缩进一次前向,兼顾质量与速度。
具体案例:团队在 Stable Diffusion 基础上微调 SD-Turbo/LCM 风格的学生模型:以老师 CFG 输出为回归目标,端到端蒸馏,部署后延迟下降约一半,同时保持提示词对齐水平。
Python 演示
import numpy as np rng = np.random.default_rng(42)MU = {0: np.array([-2.0, 2.0]), 1: np.array([2.0, -2.0])}DATA = {c: rng.normal(MU[c], 0.8, size=(400, 2)) for c in (0, 1)} def fit(data): m = data.mean(axis=0) cov = (data - m).T @ (data - m) / len(data) return m, cov M_ALL, C_ALL = fit(np.vstack([DATA[0], DATA[1]]))M_TAR, C_TAR = fit(DATA[1]) # 目标条件:类别1 def alpha_bar(t): return np.cos(t * np.pi / 2) ** 2 def score(x, t, m, cov): ab = alpha_bar(t) target_cov = ab * cov + (1 - ab) * np.eye(2) return -np.linalg.solve(target_cov, x - np.sqrt(ab) * m) def sample_cfg(w, steps=60, seed=0): rng = np.random.default_rng(seed) x = rng.normal(size=2) for i in range(steps): t = 1.0 - (i + 0.5) / steps s_all = score(x, t, M_ALL, C_ALL) s_tar = score(x, t, M_TAR, C_TAR) s_cfg = s_all + w * (s_tar - s_all) x = x + s_cfg * 0.15 + rng.normal(size=2) * (0.35 * (1 - t) + 0.03) return x if __name__ == "__main__": for w in (0.0, 1.0, 4.0): out = np.array([sample_cfg(w, seed=s) for s in range(80)]) aligned = (np.linalg.norm(out - M_TAR, axis=1) < np.linalg.norm(out - MU[0], axis=1)).mean() dist = np.linalg.norm(out - M_TAR, axis=1).mean() spread = out.std(axis=0).mean() print(f"w={w:<4} 目标簇占比={aligned:.2f} 距目标中心={dist:.2f} 离散度={spread:.2f}")
DATA = {c: rng.normal(MU[c], 0.8, size=(400, 2)) for c in (0, 1)}生成两个类别簇:类别 0 与类别 1,类别 1 充当“客户需求”。def fit(data):用最大似然拟合每个类的高斯均值与协方差,作为得分函数的基础。def alpha_bar(t):余弦噪声调度,控制“当前时刻画面还剩多少原始信息”。def score(x, t, m, cov):返回某时刻边缘分布的得分,即“朝数据高密度区走”的方向。s_cfg = s_all + w * (s_tar - s_all)CFG 核心一行:无条件得分加上放大后的条件方向差。x = x + s_cfg * 0.15 + rng.normal(size=2) * (0.35 * (1 - t) + 0.03)沿得分迈一步并注入退火噪声,模拟随机采样过程。aligned = (np.linalg.norm(out - M_TAR, axis=1) < np.linalg.norm(out - MU[0], axis=1)).mean()统计落在目标簇附近的样本占比,衡量“听指挥”程度。spread = out.std(axis=0).mean()用标准差衡量样本多样性,引导越强通常离散度越小。
常见误区
误区我以为是给扩散模型接一个分类器,在生成时用它的梯度推一推,跟分类器引导差不多,只是改进了一下。
正解CFG 恰恰是“免分类器”:它完全不需要额外分类器,只用同一个条件扩散模型在“给条件”和“不给条件”两种输入下的两次前向之差完成引导。分类器引导需要另训分类器,还要依赖分类器在噪声图上的表现;CFG 让模型自己当自己的评审——相当于不再请外行评审,而是让画家自己对比两版草稿。
为何常见:名字里有 Guidance,训练时又偶尔听人提到“引导”,容易和分类器引导混淆;两者公式形式上确实相似(都是加一个梯度项),但来源完全不同。
误区w 调大一点,画面肯定更贴提示词,质量也应该更好,那我直接拉到 20。
正解w 只放大“需求方向”,并不增加任何信息。过大的 w 会让样本过度集中到条件模式的尖峰附近,出现颜色过饱和、边缘伪影、纹理僵化,甚至内容失真。正确做法是在 5~8 区间按模型与采样器微调,并配合多样性指标(如 FID)一起评估。
为何常见:因为 w 提高确实让单张图更“贴题”,用户立刻感受到相关性提升,容易忽略分布层面的多样性崩塌和伪影,形成“越大越好”的错觉。
误区CFG 要同时用有条件模型和无条件模型,那我得训练两个模型,参数量直接翻倍。
正解不需要。推理时的无条件输出来自同一个模型:把条件输入置空(空文本、空白 token、零向量)即可得到“自由版”预测。训练时随机丢弃条件,正是为了让这个共享模型学会处理空条件,训练成本几乎没有增加。
为何常见:看到公式里同时出现 ε(z,∅) 和 ε(z,c),想当然以为是两个网络——忽略了“同一个模型、两种输入”的参数共享设计。
误区既然要学无条件生成,那把条件丢弃率提到 80%,模型肯定更全能,引导效果也更好。
正解丢弃率过高会让模型很少见到真实条件,条件生成能力退化,整体图像质量反而下降。Ho & Salimans 的原始工作与后续实践都表明 10%~20% 的丢弃率足够:模型既熟练掌握条件,又保留无条件能力。丢弃率是训练超参数,不是越大越好。
为何常见:从“丢弃条件让模型学无条件”推出“丢得越多学得越好”,忽略了条件生成才是主任务,训练分布必须保持绝大多数样本带条件。
面试题
Q1. CFG 引导尺度 w 设为 0 时,生成行为相当于?
- A.进行纯无条件生成← 正确答案
- B.进行纯条件生成
- C.等价于分类器引导
- D.直接输出随机噪声
答案:A。w=0 时公式变成“自由版草稿 + 0×需求方向”,即只剩下无条件预测。就像把扩音器音量关到零,画家完全听不到需求,只会自由发挥。w=1 才是普通条件生成,所以 B、C、D 都不对。
Q2. CFG 生成过程每步需要几次模型前向?
- A.仅需要一次前向
- B.恰好两次前向← 正确答案
- C.需要三次前向
- D.步数决定次数
答案:B。CFG 每一去噪步都要同时得到无条件预测与条件预测,再对两者做差并放大,所以恰好是两次前向。step 表示去噪轮数而非前向次数,D 混淆了概念。这也是 CFG 计算成本翻倍的原因。
Q3. 训练时随机丢弃条件的主要目的是?
- A.增强条件生成能力
- B.增加模型参数量
- C.降低采样生成速度
- D.掌握条件与无条件生成← 正确答案
答案:D。丢弃条件(置空)让同一模型在训练中同时见到“给条件”和“不给条件”两种输入,从而掌握两种能力,推理时才能提供 CFG 公式需要的两个预测。A 只讲了一半,B、C 与事实相反。
Q4. 引导尺度 w 设置过大时,最常见的现象是?
- A.画面过度饱和并出现伪影← 正确答案
- B.画面变得非常模糊不清
- C.生成过程明显变慢
- D.模型直接输出黑图
答案:A。w 过大相当于艺术总监吼得太凶,画家只会机械复制需求模板,常见后果是颜色过饱和、边缘伪影、纹理僵化。模糊通常是欠拟合或采样步数不足,生成速度与 w 无关,直接黑图也不是 w 过大的典型表现。
Q5. 与分类器引导相比,CFG 的优势包括?
- A.无需额外训练分类器← 正确答案
- B.可处理任意文本条件← 正确答案
- C.无需任何条件输入
- D.每步前向次数更少
答案:AB。CFG 用条件模型与无条件模型的输出之差隐式替代分类器梯度,因此免训练分类器,也能自然支持任意文本条件。C 错误,CFG 必须有条件输入才有引导意义;D 错误,CFG 与分类器引导同为两次前向,前向次数并不更少。
Q6. 推理时获得“无条件预测”的正确做法是?
- A.将条件 token 置为空← 正确答案
- B.将模型权重全部置零
- C.将噪声图像全部设零
- D.将引导尺度降到零点
答案:A。无条件预测来自同一个模型的空条件输入:把文本条件替换为空字符串、空白 token 或零向量即可。置零权重、置零噪声图都会破坏生成,而引导尺度是推理公式里的放大系数,不会改变条件输入本身。
Q7. 关于 CFG 的说法正确的是?
- A.属于免分类器引导方法← 正确答案
- B.提升条件相关性对齐← 正确答案
- C.会降低生成样本多样性← 正确答案
- D.需要额外增加一个模型
答案:ABC。CFG 无需分类器,通过放大条件方向显著提升生成结果与条件的对齐度,但代价是样本分布更集中在条件模式附近、多样性下降。D 错误:无条件输出由同一模型置空条件得到,不需要额外模型。
Q8. Stable Diffusion 中 CFG 尺度常用的推荐区间是?
- A.趋近于零附近
- B.略大于一附近
- C.五到八附近← 正确答案
- D.百位数以上
答案:C。Stable Diffusion 默认 CFG scale 为 7.5,通用推荐区间是 5~8:太小则画面不贴提示词,太大则过曝伪影。w≈0 等于无条件生成,w≈1 等于普通条件生成,百位以上几乎必然出现严重伪影。
Q9. 引导尺度 w 增大带来的影响包括?
- A.提示词匹配度上升← 正确答案
- B.样本多样性下降← 正确答案
- C.采样速度必然加快
- D.可能出现过曝伪影← 正确答案
答案:ABD。w 放大“需求方向”,所以画面更贴提示词、匹配度上升;但分布被压向条件尖峰,多样性下降;超出合理范围时出现过曝伪影。w 只改变得分方向与强度,不改变去噪步数,因此与采样速度无关。
Q10. 引导蒸馏(guidance distillation)的核心目标是?
- A.一次前向复现两步引导← 正确答案
- B.用分类器替换引导网络
- C.彻底移除条件输入
- D.将引导尺度无限调高
答案:A。蒸馏让学生网络以老师 CFG 的引导输出为回归目标,训练完成后用一次前向复现原本需要两次前向的引导效果,推理成本几乎减半。B 是倒退到分类器引导,C 会失去条件控制,D 是制造伪影而非优化方向。