前言:本文没有太多公式推理,只有一些简单的公式,以及公式和代码的对应关系。本文仅做个人学习笔记,如有理解错误的地方,请指出。
本文包含stable diffusion入门文献和不同版本的代码。
文献资源
- 本文学习的代码;
- 相关文献:
- Denoising Diffusion Probabilistic Models : DDPM,这个是必看的,推推公式
- Denoising Diffusion Implicit Models :DDIM,对 DDPM 的改进
- Pseudo Numerical Methods for Diffusion Models on Manifolds :PNMD/PLMS,对 DDPM 的改进
- High-Resolution Image Synthesis with Latent Diffusion Models :Latent-Diffusion,必看
- Neural Discrete Representation Learning : VQVAE,简单翻了翻,示意图非常形象,很容易了解其做法
代码资源
- stable diffusion v1.1-v1.4, https://github.com/CompVis/stable-diffusion
- stable diffusion v1.5,https://github.com/runwayml/stable-diffusion
- stable diffusion v2,https://github.com/Stability-AI/stablediffusion
- stable diffusion XL,https://github.com/Stability-AI/generative-models
前向过程(训练)
- 输入一张图片+随机噪声,训练unet,网络预测图片加上的噪声
反向过程(推理)
- 给个随机噪声,不断迭代去噪,输出一张图片
一些系数
scale:提示词的重要程度;
strength:在图生图中,毁掉原图信息的强度;0不毁坏(不在latent feature中加噪声),1完全毁坏(在latent feature中加很多噪声);
总体流程
- 输入的prompt经过clip encoder编码成(3+3,77,768)特征,正负prompt各3个,默认negative prompt为空‘’,解码时正的和负的latent图片用公式计算一下才是最终结果;time step通过linear层得到(3+3,1280)特征;把prompt和time ebedding和随机生成的图片放入unet,得到的就是我们要的图片。(n,4,64,64)输入UNet中去燥,网络的中间层特征图是(8,8)的,然后上采样到(n,4,64,64)得到噪声。再用公式去燥得到特征(n,4,64,64),把这个特征放到VAE的解码器中解码,上采样4倍得出输出图片。
采样流程 text2img
- 该函数在PLMSSampler中,输入x(噪声,(3,4,64,64))-----c(输入的prompt,(3,77,768)----t (输入的time step,第几次去噪(3,)。把这三个东西输入unet,得到预测的噪声e_t。先x先加上噪声然后再和prompt条件进行交叉注意力;
def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=False, quantize_denoised=False,
temperature=1., noise_dropout=0., score_corrector=None, corrector_kwargs=None,
unconditional_guidance_scale=1., unconditional_conditioning=None, old_eps=None, t_next=None):
b, *_, device = *x.shape, x.device
def get_model_output(x, t):
if unconditional_conditioning is None or unconditional_guidance_scale == 1.:
e_t = self.model.apply_model(x, t, c)
else:
x_in = torch.cat