Stable diffusion流程
上述是单纯的图片得到原图,现在需要加入文本描述得到文本引导下的一致性原图,怎么加尼?
Classifier Free Guidance(无分类器引导,简称 CFG)并非特定的网络模型,而是一种用于文生图(Text-to-Image)模型的引导技术,它能显著提升生成图像与文本提示的一致性,CFG 技术通过同时计算有文本提示和无文本提示(即空提示)两种情况下的模型输出,然后利用两者之间的差异来引导图像生成过程
从公式中可以得知,cfg 参数越大说明生成的图片和文本关联性越大,
在实际工具中的体现
在诸如 Stable Diffusion Web UI、ComfyUI 等文生图工具中,用户可以分别输入正向提示词和负向提示词,并通过调整 CFG Scale 和 Neg Scale 等参数来控制图像生成的效果,实现对生成图像特征的精细控制。
vae
VAE(Variational Autoencoder,变分自编码器),VAE 可以将高维的图像数据压缩到低维的潜在空间中,提取出图像的本质特征。在文生图模型(如 Stable Diffusion)中,VAE 用于将图像从像素空间转换到潜在空间,这样可以减少计算量,提高模型的训练和推理效率。解码器通过一系列的神经网络层(如反卷积层)将编码向量 解码成与原始输入图像大小相同的图像。在一些简单的实验或者资源受限的场景中,latent_dim
可能设置为 32、64 或 128 ;而在复杂的大规模图像生成任务里,为了能够捕获更多的图像特征信息,latent_dim
可能会设置为 256、512 甚至更高。
许多文生图模型(如 Stable Diffusion)会使用预训练好的 VAE。这些 VAE 已经在大规模的图像数据集上进行了充分的训练,具有较好的图像编码和解码能力。在使用这些模型时,可以直接使用预训练的 VAE,而不需要重新训练。这样可以节省训练时间和计算资源,同时也能保证一定的图像生成质量。
图像4*3*512*512 =》 经过vae编码器处理潜空间VAE编码器会将图像压缩为原尺寸的1/8,512/8=64 ,[4, 4, 64, 64] =》 文本条件通过交叉注意力机制注入UNet,而非直接拼接通道。 CLIP文本编码输出为[4,77,768](batch=4,77个token), 需通过投影层与UNet的注意力层交互,不是拼接 =》 unet处理输出 [4, 4, 64, 64],添加噪声是通常,在扩散过程中,噪声是逐渐添加到潜空间, 扩散模型需多步迭代去噪(如50~100步),逐步预测并去除噪声,而非单次处理 for t in timesteps: 带噪潜空间 = 添加噪声(潜空间, t) 预测噪声 = UNet(带噪潜空间, t, 文本特征) 潜空间 = 去噪步骤(带噪潜空间, 预测噪声, t) =》 解码器输出 [4,3,512,512]
修正后的完整流程
-
输入图像:
[4,3,512,512]
(batch=4, RGB 512x512) -
VAE编码:压缩为潜空间
[4,4,64,64]
-
扩散过程迭代:
-
添加噪声:根据时间步
t
逐步添加噪声至潜空间。 -
UNet去噪:输入带噪潜空间
[4,4,64,64]
、时间步t
和文本特征[4,77,768]
,输出噪声预测[4,4,64,64]
。 -
更新潜空间:根据噪声预测更新潜空间。
-
-
VAE解码:最终潜空间
[4,4,64,64]
解码为图像[4,3,512,512]
。
CLIP(Contrastive Language - Image Pretraining)
模型是 OpenAI 开发的一种多模态模型,它能够学习图像和文本之间的关联,通过在大规模的图像 - 文本对数据集上进行对比学习,CLIP 能够将图像和文本映射到同一个特征空间中,输出文本特征向量,图像向量,相似度越高两者越来越匹配,相似度低不匹配
-
文生图任务:为图像生成模型提供文本的语义信息,引导模型生成符合文本描述的图像。
-
图像检索:根据文本查询从图像数据库中检索出相关的图像。相似度搜索
-
零样本分类:在没有对特定类别进行训练的情况下,根据文本描述对图像进行分类。相似度得分进行搜索
最后训练和使用文生图流程
其他微调模型
Dreambooth unet 整个微调,所以保存模型的时候都保存比较大
Lora 是加入一些层,改变unet 的一些层的输出,所以元模型保留后,只是保存很小的lora添加层,使用是lora 层加原模型
Controlnet, 也是新增加一个额外的网络结构 调整unet
扩散过程的核心逻辑
扩散模型通过逐步去噪生成图像,整个过程类似"从随机噪声中雕刻出图像"。具体分为3个阶段:
-
初始化:从纯噪声开始(
[4,4,64,64]
) -
迭代去噪:UNet逐步预测并去除噪声(循环50~100次)
-
最终解码:去噪后的潜空间通过VAE解码为图像
具体迭代步骤分解(以batch=4为例)
阶段1:初始化潜空间
python
复制
latents = torch.randn([4,4,64,64]) # 纯噪声初始潜空间
阶段2:扩散循环(关键步骤)
for t in timesteps: # 如从t=999到t=0逐步降噪 # 步骤1:将当前时间步编码为向量 t_batch = torch.tensor([t], device=device).repeat(4) # [4] # 步骤2:将潜空间输入UNet,同时传入时间步和文本条件 noise_pred = unet( latents, # 当前带噪潜空间 [4,4,64,64] timestep=t_batch, # 时间步向量 [4] encoder_hidden_states=text_embeddings # 文本特征 [4,77,768] ).sample # 输出噪声预测 [4,4,64,64] # 步骤3:根据噪声预测更新潜空间 latents = scheduler.step( noise_pred, # 预测的噪声 t, # 当前时间步 latents # 当前潜空间 ).prev_sample # 更新后的潜空间 [4,4,64,64]
关键技术细节
1. 时间步(Timestep)的作用
-
数值范围:通常为1000步(t=999到t=0)
-
物理意义:控制噪声添加的强度,t越大噪声越多
-
编码方式:通过正弦位置编码转换为向量输入UNet
2. 文本条件的注入机制
-
文本特征形状:
[4,77,768]
(batch=4,77个token) -
注入方式:通过UNet的交叉注意力层:
-
python
-
复制
# UNet内部伪代码 class CrossAttention(nn.Module): def forward(self, x, text_emb): # x: 潜空间特征 [4,320,64,64] # text_emb: 文本特征 [4,77,768] # 将x转换为query q = self.to_q(x) # [4,320,4096] # 将文本转换为key/value k = self.to_k(text_emb) # [4,77,320] v = self.to_v(text_emb) # [4,77,320] # 注意力计算:query与文本key的点积 attn = torch.matmul(q, k.transpose(1,2)) * self.scale attn = attn.softmax(dim=-1) # 输出与文本value的加权和 out = torch.matmul(attn, v) # [4,320,4096] return self.to_out(out) # 融合回潜空间特征
3. 噪声调度器(Scheduler)
-
常见类型:DDPM、DDIM、PLMS等
-
核心功能:根据预测噪声计算潜空间更新量
-
典型更新公式(DDPM):就是预测噪声的一个公式计算方法
# 简化的更新规则 latents = (latents - (noise_pred * (1 - alpha_t)) / sqrt(alpha_t) + sqrt(1 - alpha_t) * noise_pred)
可视化流程
初始噪声 [4,4,64,64] ↓ ┌───────────────┐ │ UNet预测噪声 │ ← 文本条件[4,77,768] └───────────────┘ ↓ 调度器更新潜空间 ↓ 重复50~100次 → 最终潜空间 ↓ VAE解码 → 输出图像[4,3,512,512]
常见参数配置
参数 | 典型值 | 作用 |
num_inference_steps | 50 | 扩散迭代总次数 |
guidance_scale | 7.5 | 文本条件强度(CFG参数) |
eta | 0 | 控制随机性的参数(DDIM专用) |
参考视频
[零基础] Stable Diffusion 原理详解
https://www.bilibili.com/video/BV1Yu411x7mg/?spm_id_from=333.337.search-card.all.click&vd_source=40cdba46cd0fe1ed5b7f9c50d95ee879