可随意转载 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,具体算法如下:

M代表的是cross-Attention map。通过迭代编辑原始的M和M*重新扩散得到最终结果。

它有三种操作Cross-Attention的方法:

  • 更换prompt词:在某个时间步T之前用Edited Map,之后用原始Attention Map
  • prompt中加词:在没有overlap的方叠加上新词的Attention Map
  • 修改prompt中词的权重:Attention Map乘以一个常量

官方代码实现-支持SD(外链)

第三方基于SD的实现(外链)

三、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

具体步骤

  1. 做DDIM inversion(图片–>噪声),获得原图片的latent数组
  2. 做null_optimization(DDIM latent 数组 —> 噪声),输入DDIM latent,通过迭代计算得到多个时间步的噪声预测值(uncond_embeddings)。
  3. 执行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》,还未公布源代码。

分类: 未分类