目录
可随意转载 Update 2024.03.03
前言
2020年,大神Jonathan Ho发表论文《Denoising Diffusion Probabilistic Models》(DDPM),带火了Diffusion Model。
2022年,大神Jonathan Ho入职谷歌后又发表论文《Classifier-Free Diffusion Guidance》(CFG), 走出了分类(classify)的束缚,引入了conditional 和unconditional方法,并定义了引导参数w,奠定了Google的Imagen,OpenAI的GLIDE模型,开源的Stable Diffusion三个重量级产品的理论基础。
研究者从数学公理出发,推导了DDPM的一般化的表示,提出了DDIM。
但研究者并不满足,为了实现图片编辑需求,Prompt-to-Prompt给prompt的迭代过程动手脚,修改了CrosssAttentionMap,实现了免训练的图片编辑功能。 同作者NTI中使用pivotal Inversion方法解决这个问题。但是它需要对每张图片做迭代更新,速度慢。
NPI论文提出了一个解析解(closed-form)条件∅t = C,并论证只要解析解成立,仅仅做source prompt embedding可以达到NTI同样的效果,无需迭代更新速度更快。
同时,腾讯的论文《Masactrl: Tuning-free mutual self-attention control for consistent image synthesis and editing》提出了修改Self-Attention来控制编辑的方法。
论文《ProxEdit: Improving Tuning-Free Real Image Editing with Proximal Guidance》结合上述两类方法并用proximal方法进一步做了研究,提升了文字引导图片生成的效果。
注意:免训练是一条单独的技术路线,学术界主流的技术路线是通过微调扩散模型来实现,虽然主流技术路线非常费算力,但是它有一些免训练路线不可能做到的科研成果,容后再续。
算法综述
一、 CFG算法
《Classifier-Free Diffusion Guidance》(CFG) 算法实现conditional和unconditional混合训练只需要在DDPM训练代码中增加随机dropout概率,在sampling代码中合理混合 conditional和unconditional 张量就行了。
简单的代码实现(第三方,外链) 注意:guide_w >1 而且drop_prob=0.1
另一个代码实现更清晰展示了CFG在sampling阶段混合conditional和unconditional的具体实现:
# diffusion.py
def p_mean_variance(self, x_t:torch.Tensor, t:torch.Tensor, **model_kwargs) -> tuple[torch.Tensor, torch.Tensor]:
"""
calculate the parameters of p_{theta}(x_{t-1}|x_t)
"""
if model_kwargs == None:
model_kwargs = {}
B, C = x_t.shape[:2]
assert t.shape == (B,)
cemb_shape = model_kwargs['cemb'].shape
pred_eps_cond = self.model(x_t, t, **model_kwargs)
model_kwargs['cemb'] = torch.zeros(cemb_shape, device = self.device)
pred_eps_uncond = self.model(x_t, t, **model_kwargs)
# 这里
pred_eps = (1 + self.w) * pred_eps_cond - self.w * pred_eps_uncond
assert torch.isnan(x_t).int().sum() == 0, f"nan in tensor x_t when t = {t[0]}"
assert torch.isnan(t).int().sum() == 0, f"nan in tensor t when t = {t[0]}"
assert torch.isnan(pred_eps).int().sum() == 0, f"nan in tensor pred_eps when t = {t[0]}"
p_mean = self._predict_xt_prev_mean_from_eps(x_t, t.type(dtype=torch.long), pred_eps)
p_var = self._extract(self.vars, t.type(dtype=torch.long), x_t.shape)
return p_mean, p_var
同理,这个实现也适用于DDIM sampling阶段。
二、Prompt-to-Prompt算法
假如用diffusion生成了图片(bike),我想修改它的颜色、材质甚至换成别的东西,保持seed不变,修改prompt是否可以做到?
从道理上说可以做。但是在任何diffusion算法中,结果都是No。保持seed不变,修改提示词会导致整幅图片大幅变化。这也是为什么一些基于Diffusion的图片编辑方法要用遮罩(Mask)的原因。
谷歌这篇论文发现算法中的Cross-Attention模块才是此问题的关键所在,要达到目标就要用源图的Attention Map去控制目标图的Attention Map,通过修改后的Attention Map去生成修改后的图片,而不是通过修改prompt,具体算法如下:
它有三种操作Cross-Attention的方法:
- 更换prompt词:在某个时间步T之前用Edited Map,之后用原始Attention Map
- prompt中加词:在没有overlap的方叠加上新词的Attention Map
- 修改prompt中词的权重:Attention Map乘以一个常量
三、NTI算法
来自谷歌的《Null-text Inversion for Editing Real Images using Guided Diffusion Models》
假如原图不是SD生成的图,而是普通图片,上面的 prompt-to-prompt 算法就不行了(因为算法没有CrossAttention Map可以去编辑)。所以要引入图片反转去生成MEdit( prompt-to-prompt中的CrossAttention Map )。
虽然DDIM Inversion可以很好重建原始sample,但是仅仅在w=1的时候,如果需要编辑图片(w>1),DDIM效果就很差。
Null-text Inversion官方代码实现和prompt-to-prompt代码在同一个库里,并支持SD
具体步骤
- 做DDIM inversion(图片–>噪声),获得原图片的latent数组
- 做null_optimization(DDIM latent 数组 —> 噪声),输入DDIM latent,通过迭代计算得到多个时间步的噪声预测值(uncond_embeddings)。
- 执行CFG生成图片,用uncond_embeddings和文字引导embeddings做CFG生成图片
# NTI
...
# 带条件的embeding不做训练
with torch.no_grad():
noise_pred_cond = self.get_noise_pred_single(latent_cur, t, cond_embeddings)
# 只训练无条件的embeding
for j in range(num_inner_steps):
noise_pred_uncond = self.get_noise_pred_single(latent_cur, t, uncond_embeddings)
noise_pred = noise_pred_uncond + w * (noise_pred_cond - noise_pred_uncond)
latents_prev_rec = self.prev_step(noise_pred, t, latent_cur)
# 用MSE最小化DDIM Inversion的预测值与无条件的预测值latents_prev_rec
loss = nnf.mse_loss(latents_prev_rec, latent_prev)
optimizer.zero_grad()
loss.backward()
...
论文中首次实现了DDIM Inversion算法;并且发明了null_optimization;缺点是这个算法的速度很慢。
四、NPI算法
《Negative-prompt Inversion: Fast Image Inversion for Editing with Text-guided Diffusion Models》
通过简单的数学推导证明:迭代优化NTI约等于条件C的预测值,所以无需任何迭代计算,只需要一次forward即可,论文的推论是:
- 对于图片重建,让∅t = C相当于根本不使用CFG
- 对于图片编辑,NTI中迭代优化∅t的过程可以被简单的替换∅t = C所取代,无需迭代计算
这个理论推导就很牛逼了,但没有源码
五、ProxEdit
《Improving Tuning-Free Real Image Editing via Proximal Guidance》 , 对NPI算法进行了进一步优化,提供了NPI源码复现(非官方)
源码地址。
六、MasaCtrl算法
self-attention结构改成mutual self-attention,自动生成Mask, 主要创新点是保持原图中的物体的identity。
七、DI算法
2023年7月,又提出了一个新的Inversion算法,号称效果最好,论文是:《Direct Inversion: Boosting Diffusion-based Editing with 3 Lines of Code》,DI Code (github.com)
八、Consitory算法
2024年2月,英伟达提出免训练的T2I算法《Training-Free Consistent Text-to-Image Generation》,还未公布源代码。