
做生成式 AI 开发的同学大概率都遇到过类似的情况同一个扩散模型换了一个随机种子生成结果的质量忽高忽低。有人把这归结为“运气”有人把它称为“抽卡”。但从实际的生产视角看这种不确定性的根源并不是模型本身而是生成过程中被消耗掉的伪随机流。这个观点不是一句经验之谈。它背后有一个值得深挖的技术判断伪随机流并不是一个无关紧要的“随机数来源”它在扩散模型里更像是一种可学习的输入。具体怎么说它对生成质量的影响发生在哪些环节工程师能不能主动控制它而不是被动接受“抽卡”结果这篇文章会把这些问题讲清楚。文章会从扩散模型中的随机性位置开始逐步拆解伪随机流的生成机制、它与可学习参数的关系、影响生成质量的具体路径最后给出可落地的代码示例和工程建议。无论你是在做文生图、视频生成还是图像编辑这套理解方式都会对你定位问题有帮助。1. 这篇文章真正要解决的问题先给一个明确的判断扩散模型的生成质量不只取决于模型权重、提示词和采样步数还取决于一组随机噪声张量的具体取值。很多人关注前三个因素却忽略最后一个。而忽略随机流的结果就是复现困难、效果不稳定、上线后难排查。这篇文章要解决的核心问题有三个。第一理解扩散模型内部伪随机流到底在哪里出现它如何被消耗。只有知道随机性发生在流程的哪一个环节才能判断它对结果影响力的边界。第二理解“伪随机流是一种可学习输入”这个论断。这意味着随机流有结构、有语义、有优化的可能不再是一个呼之即来挥之即去的临时变量。第三掌握控制随机流的方法。包括固定随机流保证可复现把随机流当作可学习参数参与优化以及在工程上对随机流做搜索和筛选从而稳定提升生成质量。适合读这篇文章的读者也很明确正在调文生图模型的算法工程师处理生成结果不稳定问题的后端开发以及对扩散模型原理感兴趣的学生。如果你只是跑过一次 Demo那这篇文章能帮你理解各种 Repeatable 工具背后的原理。2. 扩散模型里的随机性到底在哪要理解伪随机流先要回到扩散模型本身的运行机制。扩散模型的通常做法是前向阶段对真实图像不断加噪声直到变成纯噪声反向阶段让模型学习逐步去噪从纯噪声一步步恢复图像。在生成时我们并不给模型一张图像而是给它一张从标准正态分布中采样得到的纯噪声张量。这个噪声张量就是生成过程的起点。但随机性并不只出现在起点。在反向去噪的每一个采样步骤中大部分采样器例如 DDIM 之外的一些随机采样器还会在每次去噪后加入新的随机噪声。也就是说整个采样轨迹是由一组按顺序消耗的随机数决定的而不是一个孤立的随机数。前向过程真实图像 x0 → x1 → ... → xT逐步加噪 反向过程噪声 xT → ... → x1 → x0逐步去噪在这条链路里随机噪声出现在两个地方初始噪声张量 xT以及反向过程中每一步重噪声项。它们共同构成了一条伪随机流。把前向和反向的随机性放在一张表里看会更清楚阶段随机性来源生成时是否启用对结果的影响前向加噪每次加噪使用随机噪声一般不直接使用决定训练数据的构造反向采样的初始噪声 xT标准正态分布采样是第一个关键输入决定生成内容的全局结构反向采样的每步重噪声采样器中按公式加入取决于采样器类型决定采样轨迹和细节变化可以看到前向过程的随机性主要影响训练生成阶段的随机性才直接影响输出。我们常说的“固定种子”本质上是固定了生成阶段这条伪随机流的取值序列。这里容易产生一个误解大多数人认为“种子只是保证可复现”所以在同一个种子下换提示词觉得效果变化是提示词引起的。但实际上同一个种子在不同提示词、不同模型版本下产生的是一个不同的随机流消费路径。种子本身并不携带语义它只是伪随机数生成器的入口。真正参与计算的是从入口展开的一组具体数值。这就带来了一个关键问题既然每次生成都要消费一组具体的数值而这些数值又直接影响生成路径那么这组数值就不应该被简单当成“天生随机”它完全可以像输入特征一样被设计、被优化。3. 伪随机流扩散模型中被低估的输入先给一个准确定义。伪随机流Pseudorandom Streams在这里指一类看起来随机、但由确定性算法生成的有序数值序列。扩散模型通常用它来构造初始噪声张量和每步重噪声张量。常见的伪随机数生成器PRNG包括 PCG、MT19937、Philox 等PyTorch 默认使用 Philox 算法生成 GPU 上的随机数序列。为什么扩散模型需要这种伪随机流而不是真随机数原因有两个。第一可复现。伪随机流由种子决定同样的算法、同样的种子、同样的消费顺序就能得到同样的噪声序列。这对调试、对比实验和生产灰度非常重要。第二方便控制。由于伪随机流是确定性的工程师可以选择不同的种子来覆盖不同的生成效果也可以对同一个种子做局部扰动来研究生成结果对随机性的敏感程度。3.1 从随机流到噪声张量的映射过程在 PyTorch 等深度学习框架中伪随机流通常不是一次性生成完整噪声的张量而是通过一个随机数生成器对象按需输出。每次调用torch.randn时都会从生成器中消耗一部分随机数。import torch # 创建一个独立的随机数生成器 g_cpu torch.Generator() g_cpu.manual_seed(42) # 从这个生成器中采样一个形状为 (1, 4, 64, 64) 的噪声张量 initial_noise torch.randn((1, 4, 64, 64), generatorg_cpu)这个initial_noise就相当于扩散模型反向生成时的第一个输入。如果采样的顺序、形状、数据类型发生变化即使种子相同实际拿到的噪声张量也不同。这是一个非常重要的细节后面排错时还会提到。从随机流到噪声张量的过程可以理解为PRNG 输出一串均匀分布或正态分布的数值框架再根据需求 reshape 成给定形状的张量。这个 reshape 本身不增加信息量但它决定了一条随机流会被如何切分。3.2 一个直观类比可以把伪随机流理解成生成过程的“底稿”。模型权重相当于“画师的技法”提示词相当于“客户的需求描述”而伪随机流相当于“画纸上的潜在底稿”。底稿不同即使技法相同、需求相同最终呈现的画面结构也会不同。如果底稿是凭空随机出来的那每次出图都有运气的成分。但如果底稿可以被设计那么画师就有机会在同样技法下找到更能发挥水平的底稿。这就是“伪随机流作为可学习输入”的核心含义底稿不是天然的偶然事件它是可以被优化的对象。这个类比并不完美但它能解释为什么两个相同种子之间的结果差异往往不是模型出了问题而是底稿本身的差异被模型放大成了结构上的差异。3.3 为什么说伪随机流是“输入”在工程角度看模型的输入通常包括 prompt embedding、图像条件、ControlNet 条件等。伪随机流虽然承担了“初始化随机性”的角色但它在计算图中的位置和输入张量并不完全相同在普通前向推理中随机流不经过梯度反向传播也不会被优化器更新。但从另一个角度看它具备了输入的几个核心特征影响输出的因果路径明确。没有这组噪声就无法生成结果。可被外部替换。换一组噪声输出就会变化。可参与优化。只要把它声明为可学习参数损失函数的梯度就能回溯到它。一旦它具备这些性质把它理解为“输入”就顺理成章。一个输入是否可学习取决于我们是否允许对它求梯度、更新它。伪随机流完全可以做到这一点。这也是学术界讨论“伪随机流是可学习输入”的主要原因。它把随机性从“不可控的先验”转化成“可控的潜变量”为生成质量优化打开了一个新方向。4. 为什么伪随机流可以作为可学习输入严格来说扩散模型中的伪随机流并不是模型学出来的但在实践中它可以被当作参数来优化。这个“当作”来自三个层面的机制。4.1 初始噪声带有多尺度结构语义扩散模型在生成时初始噪声张量通常具有(batch, channels, height, weight)的形状。对于潜在扩散模型Latent Diffusion Models这个噪声张量进入的是潜空间通道数远小于原图像空间。比如 Stable Diffusion 的潜空间形状是(4, 64, 64)对应 512x512 的图像。这意味着每一个噪声点都不是独立像素它代表的是潜空间某个位置多个通道的取值。这些取值经过扩散模型的解码器后会被映射到图像的不同高层语义。因此初始噪声的某些局部结构可能对应最终图像中的构图、色调或空间布局。这不是玄学。扩散模型的 UNet 在去噪时会根据噪声特征估计“应该去除的噪声”而这个估计过程会保留低频结构信息。所以初始噪声中的低频成分往往决定了最终图像的大致轮廓高频成分则影响纹理和细节。如果把初始噪声看作一段潜空间编码那它自然就有了可学习性你可以搜索一组更好地匹配给定提示词的噪声编码。4.2 每步随机噪声会改变采样轨迹反向扩散过程通常被视为一个从先验分布到数据分布的变换。许多采样器在每一步会加入高斯噪声使得采样轨迹带随机性。引入每步噪声的采样器如 SDE 采样器、某些离散采样器在数学上等价于随机微分方程的离散化。每步噪声的方差和取值会直接影响最终采样点落在数据流形上的位置。也就是说一条伪随机流实际上决定了采样器在流形上“漂移”的具体路线。如果你固定模型参数只调整这条路线得到的结果可能完全不同。这解释了为什么有些文章会展示“同一个 prompt不同 seed 效果差异巨大”不是因为模型不稳而是因为随机流引导了不同的采样轨迹。4.3 梯度可以回溯到噪声要让随机流变成可学习输入最关键的一环是梯度能传递到它。在 PyTorch 中只要我们创建一个带梯度的噪声张量并把它传入 UNet损失就能反向传播回来。noise_latent torch.randn((1, 4, 64, 64), requires_gradTrue)在训练或优化阶段诸如 Stable Diffusion 中预测噪声的损失函数可以直接计算对noise_latent的梯度。这意味着我们可以把它当作优化变量用梯度下降或更专业的优化策略来更新它。已有很多研究在践行这一思路在采样时优化初始潜变量、搜索符合条件的噪声、做 latent 级联筛选。从实际效果看这类方法可以在不调整模型权重的情况下提升生成结果的美学得分、对齐度或实现对特定概念的控制。4.4 一个必要澄清强调一下上面说的不是“模型自动学会了生成随机流”也不是“随机流变成了模型权重”。更准确的说法是在生成流程中伪随机流是可被替换、可被优化、具备输入性质的变量。具体到某个模型是否在训练时隐式适应了随机流分布这取决于训练策略。所以在讨论“伪随机流是可学习输入”时合理的理解是它在推理阶段具有可学习变量的属性并且在实践中确实能被优化。这个论断的价值在于它让我们把生成质量的一部分变化归因于随机流本身而不是把所有问题都推给模型。5. 伪随机流如何影响生成质量理解了随机流的结构性下一步是看它具体影响哪些质量指标。这里从最常见的场景出发。5.1 构图与全局布局初始噪声张量中包含低频信息直接影响图像的整体布局。一个物体在画面左侧还是右侧人物是居中还是偏离天空占比多高这些往往在初始噪声的低频成分里就已经有了雏形。如果发现某次生成结果构图失衡换一个种子就可能解决。这背后是随机流提供了不同的低频结构。在工程实践中很多“构图不好”的问题用 seed 搜索往往比调 prompt 更高效。5.2 细节纹理与风格倾向高频噪声成分会影响纹理、颗粒感、边缘锐度等细节特征。不同随机流带来的细节差异可能在特定风格下被放大。例如在油画风格、动漫风格或写实风格下同一模型和 prompt 使用不同随机流会呈现不同的“笔触感”或“质感”。这也是为什么在使用同样的模型权重时不同 seed 的 CLIP score 和人工美学评分会出现明显波动因为评分模型对纹理和细节敏感。5.3 视频生成中的时间一致性在视频生成或条件生成场景中通常需要多个帧使用同一个种子或经过设计的噪声偏移来保证时间一致性。如果把每个帧的随机流独立采样视频会出现闪烁。这里随机流影响的可不只是单帧质量而是整体时空一致性。所以业界常见的做法是使用共享噪声或噪声偏移noise offset让相邻帧的随机流保持关联从而在不显著损失单帧质量的情况下减少闪烁。5.4 多样性如果固定伪随机流模型生成结果会收敛到同一区域。如果随机流变化生成样本的多样性会提高。也就是说伪随机流的分布范围决定了模型的探索空间。生成质量不只看单图好坏还看整体多样性。过于集中或过于离散的随机流都会影响用户体验和生产可用性。正确做法是让伪随机流保持合理的统计特性同时对尾部异常样本做过滤。5.5 从现象到本质综合来看伪随机流对生成质量的影响不是“整体变好或变差”这种单维评价而是多维度的结构性影响。它同时影响构图、纹理、一致性、多样性。一个自然推论是如果我们能够在一个合理的搜索空间内挑选伪随机流就能针对不同目标构图更好、一致性更强、风格更稳分别做优化。这就是把随机流当作可学习输入的实际价值。6. 代码实践固定流、优化流、搜索流这一部分给出三个可复制的 PyTorch 示例分别对应工程上的三个需求固定随机流保证可复现、将随机流作为可学习参数优化、通过搜索筛选更优的随机流。6.1 固定伪随机流以保证可复现文件路径demo_fix_noise.pyimport torch def create_fixed_noise(seed: int, shape(1, 4, 64, 64), devicecuda): generator torch.Generator(devicedevice) generator.manual_seed(seed) return torch.randn(shape, generatorgenerator, devicedevice), generator # 用法示例 noise_1, gen_1 create_fixed_noise(42) noise_2, gen_2 create_fixed_noise(42) # 比较两个噪声是否一致 print(torch.equal(noise_1, noise_2)) # True这段代码的关键点有两个。一是torch.Generator必须手动设置 seed二是生成噪声的形状必须固定。只要这两个条件不变随时都能重建同一条伪随机流。注意如果你在两次运行时调用了其他随机操作比如 dropout、torch.randn未指定 generator全局状态可能会被干扰。生产环境建议用独立的 generator 实例避免全局 seed 污染。6.2 将初始噪声当作可学习参数在实际优化中我们一般不会直接用裸噪声作为可学习参数因为它的梯度信噪比低。更常见的做法是先定义优化器再在循环中更新噪声。下面演示一个最小框架说明如何让噪声参与梯度计算。文件路径demo_learnable_noise.pyimport torch def optimize_noise(pipe, prompt, steps50, lr0.01, seed0): # 声明可学习噪声 latent torch.randn( (1, 4, 64, 64), generatortorch.Generator().manual_seed(seed), devicepipe.unet.device, requires_gradTrue, ) optimizer torch.optim.Adam([latent], lrlr) for _ in range(steps): optimizer.zero_grad() # 这里以 Stable Diffusion 的 vae encode 和 unet 为例 # 假设我们有一个函数把 latent 和 prompt 编码后送入 unet # 并返回一个损失比如与目标的 L2 距离 loss compute_generation_loss(pipe, latent, prompt) loss.backward() optimizer.step() return latent.detach()这段代码只是框架示例compute_generation_loss需要根据具体任务实现。比如你想让生成的图像与某张参考图接近可以用 VAE 把参考图编码成 latent再计算生成 latent 与参考 latent 之间的距离。真正容易踩坑的地方是UNet 在去噪时会对 latent 做多次卷积与下采样梯度通过这些层传回 latent 时可能比较微弱。所以学习率通常要设置得足够小迭代次数也要足够多。另一个坑是如果不限定噪声的统计范围优化出来的噪声可能偏离初始分布导致采样器行为异常。一种常用的约束方式是在优化过程中加入噪声正则项让 latent 接近标准正态分布。# 在损失中加入正则项防止 latent 偏离标准正态分布 reg (latent ** 2).mean() loss task_loss 0.05 * reg6.3 伪随机流搜索与选择搜索是比梯度优化更轻量、更适合线上实时使用的方案。它的思路是用多个种子生成候选随机流然后用某个评分函数筛选出最优结果。文件路径demo_seed_search.pyimport torch def search_best_seed(pipe, prompt, scores, num_seeds8): best_seed None best_score -float(inf) for seed in range(num_seeds): generator torch.Generator().manual_seed(seed) latent torch.randn((1, 4, 64, 64), generatorgenerator, devicepipe.unet.device) image generate_with_latent(pipe, prompt, latent) score scores(image) if score best_score: best_score score best_seed seed return best_seed, best_score这个搜索过程在文生图产品里很常见。评分函数可以是 CLIP score、美学评分模型、人脸质量模型也可以是人挑。实际线上策略通常先筛出 top-k 候选再交给用户选择。这里的工程难点在于生成延迟和算力成本。如果一次采样需要几秒搜索 8 个种子就会放大延迟。常用优化思路是并行采样或者把种子搜索放到队列中异步完成。7. 运行结果与效果验证上面代码的运行结果主要体现在两个层面可复现与质量变化。7.1 可复现验证运行demo_fix_noise.py预期输出True这说明固定 generator 和 shape 后两次创建的噪声张量完全相同。把它接入扩散模型的采样流程理论上两次生成的图像也应完全相同。如果两次生成图像不同优先检查三处UNet 或采样器内部是否还有自己的随机操作。是否在生成中途对全局随机状态做了修改。不同 GPU 上的算子实现是否存在差异。7.2 质量优化验证对于可学习噪声或种子搜索验证方式不是看单张图而是看指标分布。推荐验证流程选取一个验证集包含多种 prompt 和风格。对每个 prompt用固定 seed 生成一批结果作为基线。用噪声优化或 seed 搜索生成同等数量结果。对比两者的 FID、CLIP Score 或人工评分分布。需要注意的是FID 和 CLIP Score 对随机流不是完全同向的。有的随机流可能让图像更符合 prompt但细节质量下降有的随机流可能美学分高但语义不对齐。因此质量验证要同时关注多个维度。从实践角度最容易在 seed 搜索中看到明显收益的任务是美学构图要求高的场景营销海报、封面。prompt 较长、语义复杂的场景。对同一主题需要生成多张候选图供人工筛选的场景。训练类任务中的噪声优化则更适合需要精确控制的编辑场景如图像修复、基于示例的生成。7.3 如何判断是否成功一个实用的判断标准是优化后的噪声流在保持采样器正常工作的同时让评分指标的均值提升并且不出现明显的分布偏移。如果优化后的 latent 导致输出图像色彩失衡或结构塌缩说明你可能过度优化了噪声偏离了训练时见过的分布。此时应加大正则项强度或改用更保守的种子搜索。8. 常见问题与排查思路问题现象可能原因排查方式解决方案同样种子两次生成结果不同生成过程中使用了全局随机状态或采样器内部随机操作检查所有torch.randn/torch.rand是否指定 generator统一使用独立 generator并将采样器设置为确定性模式换一张卡或换一个框架版本结果变化GPU 算子实现或随机数生成逻辑差异对比 PyTorch 版本和 CUDA 版本固定 Python/PyTorch/CUDA 版本并在文档中记录优化后的噪声导致图像异常噪声偏离标准正态分布打印 latent 的均值、方差分布增加正则项或限制搜索空间在初始噪声附近种子搜索成本太高单次生成延迟大、搜索数过多查看 profiling 结果并行采样、减少搜索数、或改用轻量评分模型初始噪声可复现但中间采样步骤不一致采样器引入了新的随机噪声检查采样器实现确认是否每一步都使用独立 generator在采样循环中显式传入 generator不同 batch 结果差异大同一条随机流被切分成不同形状或顺序检查消费随机流的代码是否与训练时一致固定噪声形状并确保 batch 内的噪声组织方式稳定这些问题的共性是随机流与张量形状、采样顺序、生成器状态绑定。任何一环发生变化都会造成结果漂移。建议在项目的笔记中记录种子、形状、框架版本、采样步数和采样器名称。9. 最佳实践与工程建议9.1 把随机流当配置而不是意外在生成类服务的配置中随机种子应该是一个显式配置项而不是散落在代码里的临时变量。generation: sampler: dpmpp_2m steps: 30 cfg_scale: 7.5 seed: 42 noise_shape: [1, 4, 64, 64]记录这些字段的好处是当线上出现一张效果异常的图时可以快速定位到“随机流是否可控”这一层。9.2 生产环境优先用种子搜索而不是梯度优化梯度优化噪声通常需要额外的前向反向循环在线推理场景下延迟不可接受。种子搜索只要并行生成少量候选再用轻量评分模型过滤就足够提升用户体验。建议线上策略默认固定种子作为可复现的基准。当用户点击“重新生成”时随机或遍历种子生成多张候选。后台对候选做黑名单和低质量过滤再返回给用户。9.3 验证时要覆盖多个随机流无论你是在调采样器、调 prompt还是调模型权重都应该在多个种子下测试而不是只看一个 seed 的效果。一个 seed 上效果提升并不能说明方法有效。更稳妥的做法是统计多个随机流上的指标均值和方差。推荐至少使用 16 个种子做小规模验证。如果资源允许32 个种子更可靠。9.4 区分模型问题与随机流问题遇到一张效果不好的图不要急着调模型或 prompt。先看同 seed 是否稳定复现再用同一 prompt 换几个 seed 对比。如果多个 seed 结果都不好大概率是模型或 prompt 问题。如果只有个别 seed 异常那就是随机流问题。这套判断逻辑虽然简单但能节省很多调参时间。很多团队在排查生成质量时总是先怀疑模型结果换了好几种权重也没解决最后才发现是随机流选择策略太随机。9.5 记录可复现信息工程上建议把生成参数直接打进图片的 EXIF 或返回 JSON 中方便后续 audit{ prompt: a cat sitting on the windowsill, seed: 42, sampler: dpmpp_2m, steps: 30, model_version: sd-xl-base-1.0, noise_shape: [1, 4, 128, 128] }这样即使线下复盘也能快速还原生成条件。9.6 小心安全边界对噪声做优化或搜索时需要关注两类风险一是生成内容可能绕过内容审核二是恶意用户可能通过搜索特定噪声生成违反平台规则的图像。生产环境应在生成后接入内容审核模型并保留随机流信息作为日志依据。未经授权不要对服务做爬取式 seed 搜索也不要通过噪声操纵绕过模型安全限制。10. 总结与后续学习方向这篇文章的核心观点可以浓缩成一句话扩散模型中的伪随机流不是随机噪声那么简单它是有结构、可控制、可优化的输入变量直接影响构图、纹理、时间一致性和多样性。围绕这个观点我们拆了三层内容第一层是扩散模型中随机性的位置第二层是伪随机流为什么具备可学习输入的属性第三层是工程上如何通过固定流、优化流和搜索流来提升生成质量。如果你正在做生成式 AI 应用建议先把“固定种子 多 seed 验证”这套基础能力搭好再考虑引入噪声优化或 seed 搜索。如果只是研究算法可以进一步深挖 latent 空间的几何结构、随机流对 CLIP Score 的影响原理以及多卡环境下并行采样的随机流切分策略。有一个事情值得再提醒一遍不要在一个 seed 上评价一个模型也不要在多个 seed 上抱怨模型。先确认是不是随机流的问题再决定下一步优化方向。这会让你的排查效率明显提升。下一步可以继续研究的是在同一个模型内怎样的伪随机流分布能最大化多样性而不牺牲质量以及如何让噪声优化保持采样器和图像质量的双重稳定。这两个方向既有理论深度也有实际落地价值。