采样器下拉框里那串名字大部分人是从上往下试一遍哪个顺眼用哪个。Euler a 稳、DPM 2M 快、LCM 两步出图这些用久了都有肌肉记忆。等到某天列表里冒出一个带 EDM 的选项点下去发现出图气质明显变了——线条更硬、暗部更实、二十步就基本收敛于是问题就来了Stable Diffusion EDM Sampler 到底改了什么它是单纯换了个求解公式还是换了一整套看待扩散过程的视角这篇东西就是想把这件事讲透。我会从 EDM 这套设计的底层逻辑讲起说清楚 sigma 参数化、噪声调度、二阶求解器和随机性注入分别在干什么再落到 Stable Diffusion 这个具体场景里——毕竟 SD 模型不是按 EDM 那套训练的直接照搬论文参数会踩一堆坑。中间会给可复现的参数计算、采样器横评记录和排查表也会写我自己调这块时踩过的坑。适合已经会用 SD 出图、但对着采样器列表不知道怎么选的人也适合想改采样器代码、自己加调度的人。基础概念我会顺手补不需要你先去啃论文。1. EDM 采样器到底是什么先把概念掰正1.1 采样器在 SD 里到底承担什么工作很多人把采样器理解成画图的算法这个说法不算错但太模糊导致后面选参数全靠玄学。把扩散模型的生成过程拆开看其实只有两件事一件是神经网络干的给定一张带噪图和一个噪声强度预测这张图原本长什么样另一件是采样器干的决定从纯噪声走到干净图这条路径怎么走、每步走多远、要不要在中间加点扰动。神经网络是训练出来的你改不了采样器是纯数学你可以随便换。同一张种子、同一个提示词、同一个模型换采样器出图不一样原因就在这条路径的形状不同。有的路径走得直二十步就到有的路径带随机抖动每步都拐一下出来的纹理就更活有的路径步长分配不合理高噪声区一步跨太大结构就崩。所以采样器的本质是一个数值积分器加一套步长安排。积分器负责用当前点的斜率推算下一点步长安排负责在噪声轴上哪里密、哪里疏。EDM 这套东西就是把这两件事同时重新设计了一遍而且设计得相当讲究。1.2 EDM 不是某个公式而是一整套设计空间这里要先破除一个常见误解EDM 不是一个像 Euler 那样的单一求解公式。它源自一篇讨论扩散模型设计空间的论文核心贡献是把整个生成流程拆成几个可以独立选择的部分——训练时怎么采噪声、网络输入输出怎么缩放、推理时噪声强度怎么排布、用什么求解器走这条路径——然后告诉你每个部分怎么选才合理。换句话说EDM 更像一份配置方案而不是一个算法。你在前端里看到的那个 EDM 采样器实际上是这份方案里推理侧的那一半一套按幂律排布的噪声强度序列配一个二阶求解器可选再加一点随机扰动。训练侧的那套预处理系数对已经训练好的 SD 模型来说用不上因为 SD 的网络里已经内含了它自己的缩放逻辑。这一点特别重要因为它解释了为什么你在 SD 里用 EDM 采样器效果和论文里报的数字对不上——论文是在按 EDM 方案从零训练的模型上测的你手上的是按另一套离散 beta 调度训练的 SD 模型。采样器只是借了 EDM 的走法模型本身没变。理解了这个前提后面所有的参数调整才有依据。1.3 它和 DDIM、DPM-Solver 的根本差别DDIM 的思路是把随机过程变成确定过程用一个非马尔可夫的逆向链让同样的起点走到同样的终点。它的步长是按训练时的离散时间步来的你选 20 步它就从前 1000 个时间步里等间隔抽 20 个。问题在于等间隔抽点在高噪声区太密、在低噪声区又不够细而人眼对低频结构的容错远高于高频细节这个分配其实不太符合视觉需求。DPM-Solver 系列换了个角度把扩散 ODE 写成半线性形式用指数积分器求解析解再把非线性部分用泰勒展开近似所以能用很少的步数达到不错的效果。它的步长安排仍然依赖原来的时间步体系只是求解精度更高。EDM 则把整个坐标系换掉了。它不用 0 到 1000 的离散时间步改用连续的噪声标准差 sigma 作为自变量然后把 sigma 的排布做成一条幂律曲线。高噪声端步长拉得很宽低噪声端收得很紧正好对应先定大结构、再磨小细节的生成顺序。求解器上它默认用二阶的 Heun 方法每步做一次预测加一次校正误差比一阶的 Euler 小一个量级。三者放在一起对比DDIM 是按原时间表等间隔走DPM-Solver 是用更聪明的积分方法走原时间表EDM 是换一条时间表再配一个好积分方法。差别不在精度高低而在路径形状本身。2. 四个核心设计拆解sigma、预处理、调度、求解器2.1 把时间轴换成噪声强度轴扩散模型里有两个容易混淆的量时间步 t 和噪声强度 sigma。训练时用的是离散的 t从 0 到 999每个 t 对应一个固定的噪声水平但噪声水平本身是连续的t 只是一个索引。EDM 干的第一件事就是扔掉索引直接用噪声标准差 sigma 当自变量。具体写法是把带噪图表示成干净图加上 sigma 倍的标准正态噪声x x_0 sigma · n。当 sigma 接近 0图几乎是干净的当 sigma 很大图基本是纯噪声。生成过程就是从一个大 sigma 出发一步步把 sigma 降下来每步让网络估计一次当前的干净图然后往那个方向挪一点。这个换轴的好处很直接不同模型、不同分辨率、不同训练配置下t 的含义可能完全不一样但 sigma 的物理意义是统一的——它就是噪声的强度。你换了个模型只要噪声强度对应得上采样器的行为就可预期。这也是为什么 EDM 这套东西能跨模型复用而按 t 索引的采样器换个模型就得重新调步数。2.2 预处理与后处理的三个系数EDM 论文里给网络设计了一组输入输出缩放系数用来让不同噪声强度下的输入输出量级保持稳定。三个系数分别管输入缩放、跳连缩放和输出缩放还额外给了一个噪声强度的对数变换作为条件输入。这套系数在训练时是必需的因为它们决定了网络学到的映射关系。但在 SD 推理时这组系数基本不会显式出现原因在于 SD 的网络已经用自己的方式处理了同样的问题它通过时间步嵌入感知当前噪声水平通过固定的缩放因子把 latent 拉到合适量级。你如果硬把论文里的系数套上去反而会破坏 SD 网络已经适应的输入分布。不过理解这组系数的直觉还是有用的。以噪声强度为 1、数据标准差为 0.5 为例输入缩放约 0.894跳连缩放 0.2输出缩放 0.447——意思是网络输出只占最终结果的一小部分大部分靠输入直接传过去。噪声强度升到 10输入缩放降到 0.1跳连缩放降到 0.0025输出缩放升到 0.499——这时候输入几乎没信息结果基本全靠网络预测。噪声强度降到 0.01跳连缩放升到 0.9996输入几乎原样透传网络只需要做微小修正。这组数字说明的是一个朴素道理高噪声时信网络低噪声时信输入。EDM 的采样器在低噪声段步长收得那么紧就是在配合这个逻辑——越到后面每一步的修正量越小越不能跨大步。2.3 ρ7 的幂律调度怎么排EDM 的噪声序列用一条幂律曲线生成公式是把 sigma 的最大值和最小值各开 1/ρ 次方在这两个值之间等间隔取点再把每个点 ρ 次方回去。ρ 取 7 是论文里调出来的经验值值越大低噪声端越密。我把 20 步、最大噪声 80、最小噪声 0.002 的序列算出来给你看步索引sigma 值说明080.0起点纯噪声159.6高噪声区步长很大243.9仍在定大结构516.0开始出现轮廓101.98中噪声主体成形150.099低噪声磨细节190.002终点前五步就把 sigma 从 80 降到 16跨度极大后五步从 0.099 降到 0.002跨度极小。这个分配不是拍脑袋而是对应扩散过程的信息分布高噪声区网络只能决定构图和色调跨大步不会丢太多信息低噪声区每一步都在处理纹理和边缘跨大步就会糊。我在实际调的时候发现一个规律把步数从 20 加到 30新增的步几乎全落在低噪声段。也就是说加步数主要是在磨细节不是在改构图。这也解释了为什么有些人加到 50 步感觉没变化——构图早在第 10 步就定了后面加的全是微调。2.4 Heun 二阶校正与随机性注入EDM 默认用二阶 Heun 方法走这条路径。一阶 Euler 的做法是在当前点算一个斜率沿着斜率走一步到位。Heun 的做法是先按 Euler 走一步得到一个预测点在预测点上再算一个斜率然后取两个斜率的平均值作为最终方向重新从起点走这一步。代价是每步要评估两次网络。20 步的 Heun 实际是 39 次网络评估最后一步只需一阶耗时差不多等于 40 步的 Euler。收益是误差从一阶降到二阶同样步数下结构更稳、噪点更少。这个取舍很关键很多人抱怨 EDM 慢其实是没意识到它的步数要按一半折算。除了确定性版本EDM 还提供了随机版本思路是在每步开始前往当前图里注入一点噪声把 sigma 短暂抬高再走 ODE。注入量由一个 churn 参数控制只在中间某段噪声区间生效——太高或太低都不加。这个设计的意图是让采样过程带一点随机性避免确定性 ODE 在低步数下陷入过度平滑的解同时又不至于像完全随机采样那样把结构打乱。实际用下来churn 调大纹理更丰富但容易脏调小更干净但可能发闷。多数 SD 前端把这个参数藏在高级选项里默认值偏保守这也是为什么默认的 EDM 出图看起来比随机类采样器稳但平。3. 落到 Stable Diffusion适配才是难点3.1 SD 模型不接受 sigma只接受 timestep这是 EDM 采样器在 SD 上最核心的适配问题。EDM 的求解器要在 sigma 轴上走但 SD 的 UNet 只认 0 到 999 的整数时间步它内部的时间嵌入表就是按这个范围训练的。你没法直接喂一个 3.7 进去。所以任何在 SD 上实现的 EDM 采样器内部都必须做一次 sigma 到 timestep 的映射。映射的依据是噪声强度与累积乘积的关系SD 的前向过程写成 x_t sqrt(alpha_bar) · x_0 sqrt(1 - alpha_bar) · n把噪声强度定义成 sigma sqrt((1 - alpha_bar) / alpha_bar)反解出来 alpha_bar 1 / (1 sigma²)。拿到 alpha_bar 之后再去模型的调度表里查最接近的那个 t或者直接用解析式反算。这个映射的精度直接影响出图质量。如果映射做得粗sigma 序列在低噪声端会挤到同一个 t 上等于好几步在做同一件事浪费算力还可能导致过度去噪如果映射做得偏t 和实际噪声强度对不上网络就会在错误的前提下预测出图发灰或者结构崩。我见过有人自己改采样器代码直接把 sigma 乘个系数当 t 用结果出图全是灰雾。排查了半天才发现是映射错了不是模型问题。这个坑值得单独记一笔。3.2 sigma 最大值不能照抄论文的 80论文里最大噪声取 80是因为它训练的模型能处理那么高的噪声。SD 不行。SD 的 beta 调度决定了它在 t999 时的噪声强度是有限的按常见的线性 beta 配置算下来末端 sigma 大概在十几到二十几之间具体数值取决于 beta 的起止值和步数。如果你把 sigma 起点设成 80映射到 t 的时候会超过 999只能截断到 999结果是前好几步全在同一个 t 上打转白白浪费步数。更糟的是某些实现不截断而是外推网络收到超出训练分布的输入预测直接失真。正确的做法是让起点的 sigma 对齐模型调度表在 t999 处的实际噪声强度终点对齐 t0 附近。有些前端会自动做这件事你选 EDM 采样器它内部就按模型的调度取了端点有些前端需要你手动选调度器档位选错了端点就不对。判断方法很简单如果前几步出图几乎没变化多半是端点设高了。3.3 不同预测类型的换算SD 家族里有两种主流预测目标预测噪声和预测速度。SD 1.5 和 SDXL 用前者SD 2.x 用后者。EDM 的求解器需要的是当前噪声强度下的干净图估计所以两种预测都得先换算成干净图。预测噪声的情况下干净图等于带噪图减去噪声项乘预测噪声再除以缩放系数。预测速度的情况下干净图等于缩放系数乘带噪图减去噪声项乘预测速度。这两个换算是采样器的基本功写错一个符号出图就是全黑或者全白。蒸馏模型是另一个特殊情况。LCM、Turbo、Lightning 这类模型是在极少数步数上专门训练过的它们的去噪器在低噪声区的行为和大模型完全不同。你拿 EDM 的二阶校正去跑它们校正步会产生过冲四步的模型跑到八步反而更差。我的建议很直接蒸馏模型就用它配套的采样器和步数别混搭。4. 实操参数怎么配、实验怎么做4.1 时间步序列手算与验证自己算一遍序列比看十篇说明都管用。下面这段代码就是幂律调度的标准实现改几个参数就能生成任意步数的序列def edm_sigmas(n, s_max, s_min, rho7.0): inv_max s_max ** (1.0 / rho) inv_min s_min ** (1.0 / rho) return [(inv_max i / (n - 1) * (inv_min - inv_max)) ** rho for i in range(n)] for i, s in enumerate(edm_sigmas(20, 20.0, 0.002)): print(i, round(s, 4))把 s_max 从 80 改成 20你会发现前几步的跨度立刻变得合理了。这就是上一节说的端点对齐问题用代码验证一遍比凭感觉调靠谱。映射到 timestep 的验证方法也不复杂拿算出来的 sigma 反解 alpha_bar再和模型调度表里的 alpha_bar 逐个比对看误差有多大。如果某几个 sigma 映射到了同一个 t就说明步数给多了或者端点设窄了需要调整。def sigma_to_alpha(sigma): return 1.0 / (1.0 sigma ** 2) sigmas edm_sigmas(20, 20.0, 0.002) alphas [sigma_to_alpha(s) for s in sigmas] print([round(a, 5) for a in alphas])这段跑出来的 alpha 序列是从接近 0 单调升到接近 1 的中间不该有平台期。有平台期就说明映射有问题。4.2 步数、CFG 与分辨率的联动步数这块我的经验是 20 到 28 步是甜点区。低于 16 步二阶校正的预测点误差太大容易出现结构错位高于 32 步新增的步全在低噪声端收益极小还可能因为累积的数值误差让画面变糊。如果用的是二阶求解器记得实际耗时按两倍算。CFG 这块EDM 比 Euler 类采样器更敏感。原因是二阶校正会放大 CFG 带来的方向偏移CFG 拉到 9 以上高对比区域的边缘会出现硬边或者色块。我一般把 CFG 压在 6 到 7.5 之间需要更强提示词约束时优先加提示词权重而不是拉 CFG。分辨率的影响常被忽略。EDM 的 sigma 序列是在 latent 空间算的而 SD 的 latent 分辨率和像素分辨率是固定比例。你出 512 的图和出 1024 的图同样的 sigma 序列对应的实际噪声结构尺度不一样。高分辨率下低噪声段的步长相对更粗细节容易不足。所以出大图时我会把步数往上提四到六步或者分两段做先低分辨率定构图再高分辨率重绘。4.3 采样器横评记录表下面这张表是我在同一模型、同一提示词、同一 seed 下横向试出来的主观记录步数统一按 20 步给耗时按单张 512 图粗估只作参考采样器网络评估次数收敛步数画面特征适合场景Euler2025 到 30锐利边缘清晰通用结构要求高Euler a2020 到 25纹理活随机性强插画、氛围图Heun3918 到 22平滑噪点少写实、产品图DPM 2M2018 到 22平衡速度快批量出图DPM SDE22 左右20 到 25细节多略脏材质、毛发EDM Heun3918 到 24对比高暗部实强光影、建筑UniPC2016 到 20干净略平快速预览从这张表能看出两件事。第一EDM 的收敛步数确实靠前20 步左右就能到别人 25 步的水平但它每步的代价高总耗时并不占优。第二它的画面特征偏向高对比和实暗部这个特征在不同模型上表现不一致SDXL 上更明显SD1.5 上有时会显得过曝。我个人的用法是需要强光影和清晰结构的图用 EDM需要柔和氛围和丰富纹理的图用随机类采样器批量草图用 DPM 2M。没有哪个采样器全能别指望一个选项吃遍所有场景。5. 常见问题与排查实录5.1 出图发灰、发黑、全噪点发灰是最常见的症状八成是 sigma 到 timestep 的映射偏了。表现是画面像蒙了一层雾对比度上不去细节糊在一起。排查顺序是先确认端点 sigma 是否和模型调度对齐再看步数是不是给少了导致低噪声段没走完最后检查预测类型的换算符号有没有写反。发黑或者全白通常是换算公式的符号错误尤其是预测速度的模型减号写成加号就是这个结果。这种错误很干脆不会时好时坏一测就能定位。全噪点的情况少见但很典型一般是 sigma 终点的值没有真正降到接近零采样提前结束了。有些实现会在最后一步跳过校正直接归零有些不会后者在低步数下容易留下残余噪声。遇到这种情况把步数加两步或者换一个终点处理更干净的前端版本基本能解决。5.2 步数加上去没变化甚至更差这个问题的根源在幂律调度的分布特性。前面算过20 步的序列里后五步都在 0.1 以下你加到 40 步新增的 20 步大部分挤在这个区间映射到 timestep 时可能反复落在相邻的几个 t 上等于同一件事做了好几遍。重复去噪不会让细节更好只会让画面越来越死。我的处理办法是步数超过 30 之后不再单纯加步而是换一阶求解器配更多步或者把省下来的算力用在分阶段重绘上。二阶求解器的优势在低步数区间步数高了以后它的校正收益递减反而不如一阶来得直接。还有一种情况是更差表现为细节变糊。这通常不是步数的问题而是 CFG 太高加上二阶校正的过冲在高对比边缘反复修正导致振铃。把 CFG 降一档或者换随机性更低的求解器能明显改善。5.3 和其他组件混用时的坑LoRA 本身不影响采样器行为但 LoRA 会改变模型对噪声强度的响应。有些 LoRA 在低噪声区训练得比较猛配 EDM 这种低噪声段步长很密的采样器效果会被放大出现风格过载。遇到这种情况把 LoRA 权重降 0.1 到 0.2比换采样器有效。ControlNet 在 EDM 下的控制力会比 Euler 弱一些原因是控制信号在每一步都会被注入而 EDM 的低噪声段步长太密注入次数多但每次修正量小累积效果反而被稀释。需要强控制时把控制权重往上提或者换成步长分布更均匀的采样器。局部重绘是另一个容易翻车的地方。重绘区域和原图的接缝处噪声强度在边界上不连续EDM 的二阶校正在这种不连续处容易产生色差。我的做法是把重绘边缘留宽一点或者重绘完成后再整体过一遍低强度的图生图把接缝磨掉。高清修复的第二阶段也要注意。第二阶段是从第一阶段的图加噪再重绘降噪强度决定加多少噪声。EDM 在低降噪强度下0.3 以下几乎不改动画面因为它的低噪声段步长太细走不了几步就到终点了。想要明显变化降噪强度至少给到 0.45或者干脆在第二阶段换回一阶采样器。最后分享一个我调这块时总结的小习惯每次换采样器先固定 seed 和提示词只出 512 的小图对比看构图和色调确认方向对了再放大图看细节。EDM 的差异主要体现在中低噪声段小图上看得更清楚大图上反而容易被分辨率带来的细节掩盖。这个顺序能省下不少试错时间。