Post

扩散模型与文生图

扩散模型(Diffusion Model)分两个过程:

模型原理 阅读 0 点赞 0 评论 0

1. 扩散模型原理

扩散模型(Diffusion Model)分两个过程:

  • 前向过程(加噪):对一张真实图像,按马尔可夫链逐步、多次(T 步,通常几百到上千步)添加高斯噪声,每一步噪声都很小,T 步之后图像变成一张接近纯高斯噪声的图。这个过程不需要学习,是固定的数学过程。
  • 反向过程(去噪/生成):训练一个神经网络(通常是 U-Net 结构),学会"给定第 t 步的带噪图像,预测这一步加入的噪声是什么"。生成时从纯噪声出发,用网络逐步预测并减去噪声,一步步还原出一张清晰图像。

训练目标:网络预测噪声 ε̂ 与真实加入的噪声 ε 之间的 MSE(均方误差)损失,即让网络学会"识别噪声",而不是直接学会"生成图像"。

❓ 常见追问 · 为什么要拆成 T 步小噪声,而不是一步到位?——一步预测"从纯噪声到清晰图"太难(分布跨度大、多峰),拆成多步小步长去噪,每一步只需预测局部微小变化,学习难度大幅降低,生成质量也更稳定。


2. Latent Diffusion / Stable Diffusion

原始 Diffusion(如 DDPM)直接在像素空间做加噪去噪,图像分辨率高时计算量极大。Latent Diffusion(LDM)先用 VAE 把图像压缩到一个更小的潜空间(latent space)(如 512×512×3 压缩到 64×64×4),扩散过程全部在潜空间进行,最后再用 VAE 解码回像素图像,计算量大幅下降。Stable Diffusion(SD)就是 LDM 的代表实现。

SD 三大组件
- VAE:编码器把图像压缩到潜空间,解码器把去噪后的潜向量还原成图像。
- U-Net:扩散去噪的主干网络,在潜空间上逐步预测噪声。
- 文本编码器(CLIP Text Encoder):把输入的文本 prompt 编码成语义向量,作为生成的条件。

# 关键调用示例(diffusers)
from diffusers import StableDiffusionPipeline
pipe = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
image = pipe(prompt="a cat wearing sunglasses", num_inference_steps=30, guidance_scale=7.5).images[0]

3. 文本如何控制生成

文本条件通过 cross-attention(交叉注意力) 注入到 U-Net 的各层:U-Net 的中间特征作为 Query,文本编码器输出的 embedding 作为 Key/Value,让图像特征在每一层都能"关注"到文本语义,从而引导去噪方向朝着符合 prompt 的内容走。

CFG(Classifier-Free Guidance,无分类器引导):训练时让模型同时学习"有条件"和"无条件(空文本)"两种去噪预测,推理时按 guidance_scale 把两者的差值放大,公式近似:
噪声预测 = 无条件预测 + guidance_scale × (有条件预测 − 无条件预测)
guidance scale 越大,生成结果越贴合 prompt 但多样性/自然度下降;越小则更自由但可能偏离描述。常用范围 7~12。


4. 可控生成扩展

在文本条件之外,还有更精细的空间/结构控制手段:

  • ControlNet:复制一份 U-Net 编码器权重作为可训练分支,额外输入边缘图(Canny)、深度图、人体姿态骨架(OpenPose)等条件图,精确控制生成图像的结构/构图,同时保留原 SD 的生成能力。
  • IP-Adapter:用一张参考图像(而不是文字)作为额外条件,实现"图像提示",保持参考图的风格/人物一致性。
  • inpainting(局部重绘):只对图像的某个 mask 区域重新生成,其余区域保持不变,常用于修图、换背景。
  • img2img(图生图):以一张已有图像加噪到某个中间步数,再走反向去噪,可在保留原图大致结构的前提下按 prompt 改变细节/风格。

5. 文生图微调

常见的 SD 定制化/微调方法:

  • DreamBooth:用少量(几张到几十张)特定主体的图像,对整个(或部分)模型做微调,让模型学会生成这个特定的人物/物体/风格,并绑定一个特殊标识符(如 sks dog)。
  • SD-LoRA:在 U-Net(有时也包括文本编码器)的权重旁插入低秩矩阵 W + ΔW = W + BA,冻结原始权重只训练 A、B 两个小矩阵。参数量小、训练快、可作为插件加载/卸载/叠加,是目前 SD 社区最主流的定制化方式。
  • Textual Inversion:不改动模型权重,而是学习一个新的"伪词"embedding,插入到文本编码器的词表空间中,用这个新 token 代表特定概念/风格,最轻量但表达能力有限。

SD-LoRA vs LLM-LoRA(见 09 微调篇):两者是同一套低秩思想(冻结原权重、旁路注入低秩矩阵 W+BA),差别在于载体和作用对象——LLM-LoRA 通常注入 Transformer 的注意力层(Q/K/V/O 投影矩阵),用于让语言模型适配新任务/新知识;SD-LoRA 注入扩散 U-Net 的卷积/注意力层(有时含文本编码器),用于让文生图模型学会新风格/新主体。两者都具备"参数少、可插拔、可与基座模型解耦"的共同优势。


6. 采样器与关键参数

采样器(Sampler / Scheduler)决定了从噪声到图像的具体数值求解方式:
- DDPM:最原始的采样方法,逐步随机采样,步数多(上千步),生成慢但理论最贴合训练过程。
- DDIM:把采样过程改写为确定性(非马尔可夫)路径,可以跳步采样,几十步就能出图,速度快很多。
- Euler / Euler a、DPM++ 等:把扩散过程看作求解一个常微分方程(ODE/SDE),用数值积分方法加速收敛,是目前实际使用中最常见的高效采样器。

关键生成参数
- steps(采样步数):去噪迭代次数,步数越多细节通常越精细,但边际收益递减,超过一定步数后提升很小。
- guidance scale(CFG scale):见 §3,控制"贴合 prompt 程度"与"多样性/自然度"的权衡。
- seed(随机种子):固定初始噪声,相同 seed + 相同参数可复现同一张图,常用于对比调参效果。
- negative prompt(反向提示词):告诉模型"不要生成什么"(如模糊、多余肢体、低质量),在 CFG 公式中作为"无条件"一侧的替代条件,帮助排除不想要的特征。


7. 高频追问

❓ 常见追问 · 扩散模型和 GAN 的区别?——GAN 是生成器和判别器对抗训练,一步生成,训练不稳定(模式坍塌、难收敛),但推理快;Diffusion 训练目标简单稳定(MSE 去噪),生成质量和多样性通常更好,但推理需要多步迭代,速度慢(可用 DDIM/蒸馏等加速)。

❓ 常见追问 · 为什么要在潜空间(latent space)而不是像素空间做扩散?——像素空间维度高(如 512×512×3),每一步去噪计算量巨大;VAE 把图像压缩到语义等价但维度小得多的潜空间(如 64×64×4),扩散在这个小空间进行,计算量和显存需求大幅降低,训练/推理都更快,这是 Stable Diffusion 能在消费级显卡上跑起来的关键原因。

❓ 常见追问 · Stable Diffusion 和 DALL·E 的区别?——SD 是开源的 Latent Diffusion 模型,可本地部署、可微调(LoRA/DreamBooth 等)、生态插件丰富(ControlNet 等);DALL·E(尤其 DALL·E 2/3)是 OpenAI 闭源模型,早期版本采用 CLIP 图像空间的扩散先验(unCLIP)架构,通过 API 调用,生成质量和 prompt 理解能力强但不可本地微调,可控性主要靠更精细的 prompt/图像输入。

❓ 常见追问 · 采样 steps 是不是越多越好?——不是。steps 增多会让去噪更充分、细节更精细,但边际收益递减,超过某个阈值(常见 SD 模型约 20~50 步,视采样器而定)后画质提升非常有限,反而线性增加推理耗时和成本;实际工程中应结合采样器类型(DDIM/Euler/DPM++ 等收敛更快)选择"够用就好"的步数,而不是一味堆高。


继续阅读

全部归档

评论