跟李沐学AI:DALL·E 2 论文精读

原视频:DALL·E 2(内含扩散模型介绍)【论文精读】_哔哩哔哩_bilibili

原论文:[2204.06125] Hierarchical Text-Conditional Image Generation with CLIP Latents

背景知识

GAN (Generative Adversarial Networks)

生成对抗网络 (GAN) 是一种生成式模型,它由两个核心组件构成:一个生成器 (Generator, G) 和一个判别器 (Discriminator, D)

  • 生成器 (G) 的目标是学习真实数据分布,并生成与真实数据高度相似的合成数据样本。 它通常以一个从预定义的先验分布(例如,高斯分布或均匀分布)中随机采样的噪声向量 (latent vector, z) 作为输入。生成器通过一系列复杂的变换(通常由深度神经网络实现),将这个低维的噪声向量映射到高维的数据空间,例如生成图像的像素矩阵。理想情况下,生成器希望其生成的“假”数据能够以假乱真,使得判别器难以区分真伪。

  • 判别器 (D) 的目标是一个二分类任务:判断给定的数据样本是来自真实数据分布的“真”样本,还是由生成器产生的“假”样本。 判别器接收一个数据样本作为输入(这个样本可能是真实的训练数据,也可能是生成器生成的伪造数据),并输出一个概率值(通常在 0 到 1 之间),表示该样本是真实数据的可能性。判别器的训练目标是准确地区分真实数据和生成器产生的假数据

AE (Auto Encoder)

自编码器AE主要由两部分组成:

  • Encoder编码器:接受输入数据x,经过一系列非线性变化,将其映射为一个低维度的潜在表示z,z=E(x)。这个过程可以看作是对输入数据的压缩或特征提取。
  • Decoder解码器:接受潜在表示z,经过非线性变换,将z还原为符合原始数据分布的\hat{x}\hat{x}=D(z)。解码器的目标是尽可能地从潜在表示中恢复出原始输入数据。

AE的训练目标是最小化真实数据x和重构数据\hat{x}之间的误差。

DAE (Denosing Auto Encoder)

DAE与AE相比最主要的区别为:DAE 的目标不是直接学习输入x的恒等映射(即 x \approx \hat{x}),而是学习一个从被污染的输入\widetilde{x}映射到原始的、干净的输入x的函数。

具体来说,DAE训练包括如下流程:

  1. 对原始数据x添加噪声得到\widetilde{x} = C(x)。其中 C 是一个随机 corruption 过程。常见的噪声类型包括高斯噪声、遮挡部分像素(对于图像)、随机交换词语(对于文本)等。
  2. 将噪声数据\widetilde{x}输入编码器得到低维潜在特征z
  3. 解码器将z重构为\hat{x}=D(z)
  4. DAE 的训练目标是最小化重构\hat{x}与原始的、未被污染的输入x之间的差异,即最小化 L(x, \hat{x})

VAE (Variation Auto Encoder)

AE和DAE主要都是为了学习原始输入X经过Encoder后得到的潜在特征z,而不是学习一个概率分布,主要用于分类、分割任务等。z不能进行随机采样,不能用于生成任务。为了将Encoder-Decoder的架构用于生成类任务,VAE主要学习一个概率分布(假设为高斯分布),而不是z特征。

具体来说,VAE在得到Encoder的输出后,将输出特征通过全连接层预测概率分布的均值和方差。得到均值方差后,根据特定的公式:z=\mu +\sigma \xi来采样一个z交给解码器。这样VAE就可以用于生成任务了,模型解码时无需Encoder,只需要从学习到的分布进行随机采样即可。

VAE 假设数据 x 是由一个隐藏的、连续的潜在变量 z 生成的。VAE 的目标是学习这个潜在变量的分布 p(z) 以及给定潜在变量生成数据的条件分布 p_\theta (x | z)。由于真实的后验分布 p (z | x) 通常难以直接计算,VAE 通过引入一个近似的后验分布 q_{\phi }(z | x) 来进行学习。

在图像生成任务中VAE相比GAN具有更好的多样性。

VQVAE (Vector Quantized Variational Autoencoder)

VQVAE相对于VAE的核心改进为:将学习一个潜在分布的目标改变为,学习K个d维度的特征向量来简化学习目标。

标准VAE中,学习一个连续的分布存在如下挑战:

- 需要模型能表示这个分布在连续空间的形状

- 需要保障潜在空间是连续且有意义的

- 从连续分布中随机采样生成高质量的样本有时比较困难

VQ-VAE 的关键创新在于引入了码本,这是一个包含 K 个 d 维向量(码字)的集合。编码器仍然输出一个连续的特征映射,但是这个特征映射随后被量化到码本中最接近的码字。这个量化过程本质上是将连续的潜在空间离散化为 K 个“类别”或“原型”。

VQVAE的组成为:

Encoder:将输入 x 映射到连续的潜在空间,输出一个特征映射e(x)

Codebook:创建Codebook,包含K个Codewords,每个Codeword是d维的向量。

量化:将Encoder中输出的每个e(x),从Codebook中找到与之最相近的Codeword(通常通过欧氏距离),将每个e(x)替换为codeword

Decoder:将量化后的的离散潜在表示作为输出,尝试重构\hat{x}

VQVAE无法直接用于生成任务,需要额外的Prior网络才能进行生成。

即将一个预训练好的VQVAE对原始数据进行编码得到特征映射,随后我们可以将这个特征映射中的每个离散的潜在编码看作序列中的一个元素。

然后,我们可以使用像 PixelCNNTransformer 或 RNN 这样的自回归模型来学习这些离散潜在编码的条件概率分布。 

1. VQ-VAE 的局限性

VQ-VAE 本身只是一个压缩模型,它的功能是:

  • 编码器:将输入数据(如图像)映射到离散的潜在编码(即 codebook 中的向量索引)。
  • 解码器:根据离散编码重建数据。
    但问题在于
    VQ-VAE 没有学习数据的概率分布,因此无法直接生成新的离散编码(即无法“创造”新数据)。

2. 解决方案:引入 Prior 网络

为了生成新数据,需要额外训练一个 Prior 网络(即自回归模型),学习离散潜在编码的分布。具体步骤如下:

步骤 1:用 VQ-VAE 压缩数据

  • 输入图像 → VQ-VAE 编码器 → 得到离散潜在编码序列 z(例如,一张图像被编码为 32×32 的整数矩阵,每个整数对应 codebook 中的一个向量)。
# 伪代码示例
z = vqvae_encoder(image)  # 输出形状 [32, 32],每个元素是codebook的索引

步骤 2:将离散编码视为序列

  • 将 z 展平为序列(如按光栅顺序排列成 1024 长度的序列),每个位置的值是离散的(类似文本中的单词索引)。
z_sequence = flatten(z)  # 例如 [12, 5, 9, ..., 42](共1024个token)

步骤 3:训练 Prior 网络学习序列分布

用自回归模型(如 Transformer、PixelCNN)学习这些离散编码的联合概率分布

  • 训练目标:给定前 i−1 个 token,预测第 i个 token(类似语言模型)。
  • 生成时:Prior 网络逐步采样 z1,z2,...,zn 生成全新的离散编码序列。

步骤 4:用 VQ-VAE 解码生成数据

将 Prior 网络生成的离散序列 z 输入 VQ-VAE 解码器,得到最终生成的数据。

generated_image = vqvae_decoder(z_sequence)

DALLE 1 

基于VQVAE的思想,OpenAI 训练了DALLE 1。

首先,OpenAI团队训练了一个VQVAE,用于维护纬度为K(8192)的codebook。

VQVAE的输入是256x256x3的图片,经过CNN Encoders,将高分辨率的图像映射到低纬的连续空间(通常为32x32的feature map)。

对于32x32中每个连续的潜向量,通过欧氏距离,选择codebook中与之最接近的code vectors。

随后VQVAE的Decoder则通过codebook中的code vectors通过反卷积尝试重构输入图片。

VQVAE具体通过重建损失同时优化Encoder、Decoder和Codebook中的vectors。

VQVAE训练好后,需要通过Prior网络(一个自回归网络)进行图像生成。

OpenAI团队基于GPT架构训练了一个Prior网络。Prior网络训练时,首先对文本prompt进行tokenize,得到输入序列token,对训练图像经过VQVAE中的Encoder,得到32x32的潜向量,随后通过欧氏距离,为每个潜向了找到codebook中与之最相近的code vectors,并用该code vectors在codebook中的ids,代替原本的潜向量。因此,32x32的潜向量将被转化为1024个整数索引序列。

Prior网络的训练目标就变为了,给定文本 tokens 和之前所有已生成的图像 token indices,预测下一个图像 token index。它是一个条件概率模型 P(下一个图像 index | 文本 tokens, 之前的图像 indices)。

Codebook中的code vectors就类似于文本token的Vocab,每个vector有对应的image_token_id,模型只需要预测id即可,预测出的image_id将被重新映射回codebooks中的code vectors,随后由VQVAE中的Decoder进行解码,得到最终生成的图像。

推理阶段,根据用户输入prompt的text_token_ids序列,预测image_token_ids,随后将预测的image_token_ids与codebook中的code vectors进行映射,由VQVAE的Decoder对图像token进行解码生成图像。

Codebook有点类似于NLP中的embedding层,实现了token与embedding的映射。Codebook Size类似于Vocab Size,通过ID即可访问到具体的Embedding。NLP 中的 Embedding 层通常是模型参数的一部分,会在下游任务中(有时)进行微调。VQ-VAE 的 Codebook 在 DALL-E 1 中是预训练且固定的,Prior 网络只学习预测其索引,而不改变 Codebook 本身。

总的来说:

DALL-E 1 的核心思想是将图像生成问题转化为一个基于文本条件的、自回归的序列生成任务。它巧妙地结合了 VQ-VAE 和 Transformer (Prior) 网络。

阶段一:视觉编码基础 - VQ-VAE 预训练

  1. 目标: 学习一种将连续图像压缩为离散“视觉词汇”表示的方法。

  2. 组件:

    • Encoder (CNN): 接收原始图像(如 256x256x3),输出一个低维的连续特征图(如 32x32)。

    • Codebook (码本): 维护一个包含 K 个(例如 8192 个)离散码向量 (code vectors) 的“字典”。每个码向量代表一种学习到的基础视觉模式。 这类似于 NLP 中的词汇表 (Vocab),其中每个词有一个 ID。

    • Quantization (量化): 对于 Encoder 输出的 32x32 特征图中的每一个连续向量,通过查找最近邻(如欧氏距离),在 Codebook 中找到最接近的那个 code vector

    • Decoder (反卷积): 接收由选定的 code vectors 组成的 32x32 网格,并尝试重建原始输入图像。

  3. 训练: 通过组合重建损失(让解码图像接近原始图像)、Codebook Loss 和 Commitment Loss 来联合优化 Encoder、Decoder 和 Codebook 中的 vectors。

  4. 关键产物:

    • 一个训练好的 Encoder,可以将图像映射到特征图。

    • 一个训练好的 Decoder,可以从 code vectors 重建图像。

    • 一个包含 K 个 code vectors 的固定 Codebook。

    • 核心机制:能够将任意输入图像转化为一个 32x32=1024 个 Codebook 索引 (indices) 的序列(通过记录量化步骤中选择了哪个 code vector)。

阶段二:序列建模 - Prior (自回归 Transformer) 训练

  1. 目标: 学习文本描述与对应图像的离散表示 (token indices) 之间的映射关系,以及图像内部的空间结构。

  2. 模型: 一个大型的自回归 Transformer 模型(类似 GPT 架构)。

  3. 数据准备:

    • 文本处理: 将文本提示 (prompt) 通过 Tokenizer (如 BPE) 转换为文本 token indices 序列。

    • 图像处理: 将训练图像输入预训练好的 VQ-VAE Encoder,得到 32x32 特征图。对每个特征向量进行量化,记录下对应的 Codebook indices,形成一个 1024 长度的图像 token indices 序列。

    • 序列拼接: 将文本 token indices 和图像 token indices 拼接成一个长序列 [text_indices, image_indices]。

  4. 训练:

    • Transformer 以自回归方式处理拼接后的序列。

    • 训练目标: 对于序列中的每一个位置 t(尤其是在图像 token 部分),根据位置 1 到 t 的所有 token indices,预测位置 t+1 的正确 token index。模型通过最大化预测正确 index 的概率(使用交叉熵损失)进行学习。

    • 核心:模型学习的是预测下一个离散的 index,而不是连续的 vector。

阶段三:图像生成 - 推理

  1. 输入: 用户提供一个新的文本提示 (prompt)。

  2. 文本编码: 将文本提示转换为文本 token indices 序列。

  3. 自回归采样:

    • 将文本 token indices 输入训练好的 Prior Transformer。

    • 模型预测第一个图像 token index 的概率分布,并从中采样一个 index。

    • 将采样到的 index 添加到输入序列末尾,再次输入模型,预测并采样第二个图像 token index。

    • 重复此过程 1024 次,生成完整的 1024 个图像 token indices 序列。

  4. 图像解码:

    • 索引到向量映射: 根据生成的 1024 个 indices,从 VQ-VAE 的 Codebook 中查找对应的 code vectors这里完美体现了你关于 Codebook 类似 Vocab/Embedding 层,通过 ID 访问具体内容的理解。

    • 重构图像: 将查找到的 1024 个 code vectors 排列成 32x32 网格,输入预训练好的 VQ-VAE Decoder

    • Decoder 将这些离散的视觉基元组合,生成最终的像素图像。

Diffusion Models(DDPM)

Diffusion Model涉及加噪,去噪两个环节。

  • 正向扩散过程(forward process):从真实数据 x0​,逐渐加噪,直到变成纯噪声 xT。

  • 逆向去噪过程(reverse process):从噪声 xT出发,逐步去噪,重建出 x0​。

Diffusion Model涉及严谨的数学推理,经过数学推导后,可以得到一个简单的训练过程

- 随机采样一张真实的图像X0

- 随机选择一个时间步t∈[1,T]。

- 根据公式,得到t时刻的噪声图Xt

- 输入 xt 和 t 到神经网络,预测在生成 xt过程中加进去的噪声 ϵ。

- 使用MSE loss计算损失

- 用这个损失反向传播,更新神经网络参数。

简单的伪代码如下:

import torch
import torch.nn as nn
import torch.nn.functional as F

# ==== 1. 简单版 UNet骨架 ====
class SimpleUNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 64, 3, padding=1)
        self.conv2 = nn.Conv2d(64, 3, 3, padding=1)  # 输出3通道,直接预测噪声

    def forward(self, x, t):
        # 通常时间t会被嵌入,但这里忽略(简化版)
        x = F.relu(self.conv1(x))
        x = self.conv2(x)
        return x

# ==== 2. 前向扩散,加噪声 ====
def q_sample(x_start, t, noise):
    """
    给x_start加噪声,t是时间步,noise是标准高斯噪声
    """
    sqrt_alpha_bar = torch.sqrt(1 - 0.02 * t).view(-1, 1, 1, 1)  # 简化版,手动制造ᾱ_t
    sqrt_one_minus_alpha_bar = torch.sqrt(1 - sqrt_alpha_bar**2)
    return sqrt_alpha_bar * x_start + sqrt_one_minus_alpha_bar * noise

# ==== 3. 设置网络、优化器 ====
model = SimpleUNet()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)

# ==== 4. 训练循环核心 ====
for epoch in range(1000):
    x0 = torch.randn(8, 3, 64, 64)  # 假设8张batch,每张64x64图
    t = torch.randint(1, 1000, (8,))  # 随机挑选时间步,范围 [1, 1000)
    noise = torch.randn_like(x0)  # 生成随机噪声

    xt = q_sample(x0, t, noise)  # 加噪过程
    predicted_noise = model(xt, t)  # 预测噪声

    loss = F.mse_loss(predicted_noise, noise)  # MSE loss,直接预测噪声
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f"Epoch {epoch}: Loss = {loss.item():.4f}")

推理过程则是要不断还原出Xt-1时间步下的图像:

- 随机采样初始噪声

- 循环T次(从T到1)

        - 输入Xt和t进入模型(UNet)

        - 预测噪声 

        - 用公式反推Xt-1

- 最终得到X0

伪代码如下:

# 推理阶段
x = torch.randn(1, 3, 64, 64)  # 初始化纯噪声

for t in reversed(range(1, T+1)):
    predicted_noise = model(x, t)
    beta_t = ...   # beta表
    alpha_bar_t = ...   # alphā表

    x = (1/torch.sqrt(1-beta_t)) * (x - beta_t/torch.sqrt(1-alpha_bar_t) * predicted_noise)
    if t > 1:
        x += torch.randn_like(x) * noise_scale(t)

Improved DDPM

原始 DDPM 已经展示了扩散模型生成高质量图像的潜力,但 Improved DDPM 在此基础上进行了几项关键改进,显著提升了模型的性能(尤其是在对数似然指标上)和采样效率。

相较于原始 DDPM,Improved DDPM 的主要创新在于:

  • 从固定方差到学习方差 (σ_θ): 提升了模型的灵活性和对数似然。

  • 从线性噪声调度到余弦噪声调度 (β_t): 改善了训练动态,显著提升了样本质量 (FID)。

  • 从单一简化损失到混合损失 (L_hybrid): 使得能够有效训练学习方差,并在样本质量和对数似然之间取得更好的平衡。

这些改进共同作用,使得 Improved DDPM 在生成质量(FID 分数)和模型拟合度(对数似然)方面都取得了当时 SOTA (State-of-the-Art) 的结果,并且为后续扩散模型的发展奠定了重要基础。

Diffusion Beats GAN

相较于 Improved DDPM,"Diffusion Models Beat GANs" (ADM) 的主要发展和创新在于:

  • 架构升级: 通过采用更深、更宽、并加入多尺度注意力机制的 U-Net 架构,大幅提升了模型的基础表达能力。

  • 引入分类器指导(Classifier Guidance): 这是突破性的贡献。通过在采样阶段利用一个独立的、预训练的分类器来引导生成过程,极大地提高了条件图像生成的保真度,使其在 ImageNet 等任务上首次超越了顶尖 GAN 模型。

什么是Classifier Guidance?

Classifier Guidance 是一种在推理阶段引导预训练好的扩散模型生成特定类别图像的技术。它的核心思想是:

引入一个“专家”(分类器),在扩散模型每一步去噪时,给它一点“建议”,确保最终生成的图像符合我们想要的目标类别。

所以提出了Classifier Guidance在推理过程中,用一个分类器来引导扩散方向,使采样向目标类别收敛。

工作过程:

  1. 基础过程: 扩散模型在推理时,需要从当前的噪声图像 xt 预测并采样出稍微干净一点的图像 xt-1。这本质上是从概率分布 pθ(xt-1|xt) 中采样。

  2. 引入“专家”: 我们需要一个分类器 pϕ(y|xt)。这个分类器很特别,它不仅能识别干净的图像,还能判断带有不同程度噪声的图像 xt 属于目标类别 y (例如,“猫”) 的概率。

  3. 获取“建议”: 在每个去噪步骤 t,我们问分类器:“对于当前的噪声图像 xt,我应该如何调整它,才能让它看起来更像目标类别 y?” 分类器的答案就藏在它预测概率对输入图像 xt 的梯度 ∇_{xt} log pϕ(y|xt) 中。这个梯度指向了能最大化“像类别 y”概率的方向。

  4. 融合“建议”: Classifier Guidance 做的事情就是,在扩散模型原本要走的采样方向(由 pθ(xt-1|xt) 决定)基础上,加上这个由分类器梯度提供的“引导项”。

    • 直观理解: 扩散模型自己想走一步,分类器说“往这边偏一点,更像猫!”,于是模型就稍微调整了它的步伐。

  5. 结果: 通过在每一步都施加这种“引导”,整个去噪过程的轨迹被巧妙地“推向”了目标类别 y,最终生成的图像 x0 就会有很大概率是我们想要的类别。

Classifier Guidance 的精髓在于:

  • 利用外部知识: 借助一个预训练的分类器(如 CNN 或强大的 CLIP 模型)的能力。

  • 作用于推理阶段: 无需改变原始扩散模型的训练(虽然分类器本身需要训练)。

  • 梯度引导: 使用分类器预测概率对噪声图像的梯度,作为引导信号。

  • 目标明确: 使得生成的图像在内容上更符合指定的目标类别 y。

但是Classifier也带来如下问题:

  • 额外成本: 需要训练一个能在噪声图像上工作的分类器,这本身就是一个挑战,增加了额外的训练和计算开销。

  • 保真度 vs. 多样性: Classifier Guidance 可以显著提高生成图像与目标类别的符合度(保真度),但过度引导可能会牺牲生成结果的多样性(生成的图像可能都比较“典型”,缺乏创意)。这个平衡通常通过一个“指导强度”超参数来控制。

Classifier-Free Guidance

Classifier Free Guidance帮住Diffusion模型摆脱了Classifier的外部依赖。与CG(Classifier Guidance)不同,CFG(Classifier Free Guidance)无需依赖外部模型,而是通过扩散模型本身进行两次forward来产生guidance信号。

具体而言,CFG 的实现分为训练和推理两个阶段:

训练阶段:

我们希望模型即能在有条件的情况下进行噪声预测 ε_θ(xt, t, c),我们也希望他能在无条件的情况下进行噪声预测ε_θ(xt, t, ∅) (其中 ∅ 代表无条件状态)。

条件一般为图像-文本对数据集中的captions。

因此,在训练时,我们按照概率(10%-20%)为模型提供无条件状态。通过这种方式,同一个模型 ε_θ 被训练得能够根据输入的条件是 c 还是 ∅ 来切换其预测模式

  • 当输入包含真实的条件 c 时,模型学习预测 ε_θ(xt, t, c)。

  • 当输入包含空的条件 ∅ 时,模型学习预测 ε_θ(xt, t, ∅),这等价于学习无条件生成。空条件可能为特殊的token,也可能为全0 Embedding。

推理阶段:

在每个去噪步骤t,进行两次推理

第一次根据用户的输入提示词,进行有条件预测:ε_cond = ε_θ(xt, t, c)

第二次则将条件置空,进行无条件预测:ε_uncond = ε_θ(xt, t, ∅)

结合两次预测结果,进行预测:

通过一个引导强度 (guidance scale) 参数 w (通常 w > 1) 来组合这两个预测:

        ε_final = ε_uncond + w * (ε_cond - ε_uncond)

或者等价地写为:

        ε_final = (1 - w) * ε_uncond + w * ε_cond

使用最终预测: 使用这个结合后的 ε_final 来执行该步骤的去噪操作(即计算 xt-1)。

CGF优势:

  • 无需额外模型: 避免了训练和维护一个独立的、能在噪声图上工作的分类器,简化了流程。

  • 实现更简单: 相较于计算分类器梯度,进行两次前向传播并线性组合通常更容易实现。

  • 适用性广: 可以非常自然地应用于各种类型的条件信息 c(类别、文本、图像等),只要能将条件信息编码成嵌入向量并送入扩散模型即可。这使得它在文本到图像生成(如 Stable Diffusion, Imagen)中非常成功。

  • 性能优异: 在许多任务上,CFG 能够达到甚至超过 Classifier Guidance 的性能。

Latent Diffusion Models(LDM)

DDPMs基于原尺寸图像进行加噪去噪,计算量较大。LDMs希望将高分辨率图像压缩为一个低纬度的潜向量,对潜向量进行扩散以提升计算效率。

因此,我们首先要训练一个VAE用于压缩图像,同时能还原图像。

随后,我们将原来在像素空间X进行的扩散过程,迁移至潜向量上进行:

  • 训练阶段总结:

    1. 取一个图像-文本对 (x, y)。

    2. 用 VAE Encoder 将 x 编码为 z_0 = E(x)。

    3. 随机选择时间步 t,采样噪声 ε,计算加噪后的潜码 z_t。

    4. 用文本编码器将 y 编码为条件嵌入 c。

    5. 将 z_t, t, c 输入到潜空间的 U-Net ε_θ,得到预测噪声 ε_pred = ε_θ(z_t, t, c)。

    6. 计算损失 ||ε - ε_pred||^2,更新 U-Net ε_θ 的权重。(通常 VAE 和文本编码器是预训练好并冻结的)。

  • 推理(生成图像)阶段总结:

    1. 输入文本提示 y。

    2. 用文本编码器将其编码为条件嵌入 c。

    3. 潜空间中生成一个与 z 维度相同的随机高斯噪声向量 z_T。

    4. 从 t = T 开始,逐步进行反向去噪过程:

      • 使用 U-Net ε_θ(z_t, t, c) 预测噪声 ε_pred。(通常这里会应用 Classifier-Free Guidance,即计算有条件和无条件的预测并结合)。

      • 根据预测的噪声 ε_pred 和扩散公式,从 z_t 计算出更“干净”的 z_{t-1}。

    5. 重复步骤 4 直到 t = 0,得到最终的去噪潜码 z_0。

    6. 关键最后一步: 将这个最终的潜码 z_0 输入到 VAE 的解码器 D 中,得到最终的高分辨率像素图像 x_generated = D(z_0)。

总结 LDM 的核心优势:

  • 高效率: 扩散过程在低维潜空间进行,极大地降低了计算复杂度和内存需求。

  • 高质量: 通过强大的 VAE 和在潜空间保留的语义信息,以及跨注意力条件机制,可以生成高保真度且符合条件的图像。

Stable Diffusion

Stable Diffusion 本质上就是 LDM 思想的一个非常成功和著名的实现。

我们来看看 Stable Diffusion 是如何运用 LDM 的各个组件的:

  1. 图像压缩/解压器 (VAE):

    • Stable Diffusion 使用一个预训练好的 VAE。这个 VAE 负责将输入的图像(例如 512x512x3)高效地压缩到低维潜空间(例如 64x64x4),以及在生成过程结束后将潜空间的表示解码回高分辨率图像。这个 VAE 对于最终图像的清晰度和细节至关重要。

  2. 潜空间去噪网络 (Latent U-Net):

    • 这是 Stable Diffusion 的核心引擎。它是一个在低维潜空间上操作的 U-Net 网络。

    • 它的任务是在每个时间步 t,接收加噪的潜码 z_t、时间步信息 t 以及条件信息 c,然后预测出应该移除的噪声 ε_pred。

    • 这个 U-Net 的设计(层数、通道数、注意力机制的位置等)直接影响了生成图像的质量和对条件的理解能力。

  3. 条件注入 (Conditioning - Primarily Text):

    • Stable Diffusion 的主要目标是文本到图像 (Text-to-Image) 生成。

    • 文本编码器 (Text Encoder): 它使用一个预训练好的、强大的文本编码器,通常是 CLIP 的文本编码器 (CLIP Text Encoder)(例如 OpenCLIP ViT-L/14)。这个编码器负责将用户输入的文本提示 (prompt) y 转换成一系列嵌入向量 c。

    • 跨注意力 (Cross-Attention): 这些文本嵌入向量 c 通过跨注意力机制被注入到 U-Net 的不同层中。这使得 U-Net 在去噪时能够“关注”文本提示的不同部分,从而根据文本内容引导图像的生成。

  4. 引导 (Guidance - Classifier-Free Guidance):

    • 为了让生成的图像更贴合文本提示并且质量更高,Stable Diffusion 广泛使用 Classifier-Free Guidance (CFG)

    • 实现: 在训练 U-Net 时,会以一定概率(例如 10%)丢弃文本条件 c,让模型学会无条件生成。在推理时,模型会同时计算有条件预测 ε_cond = ε_θ(z_t, t, c) 和无条件预测 ε_uncond = ε_θ(z_t, t, ∅),然后通过一个引导强度 (guidance scale / CFG scale) w 将它们结合:ε_final = ε_uncond + w * (ε_cond - ε_uncond)。这个 ε_final 被用来执行去噪步骤。

Stable Diffusion 的图像生成流程:

  1. 输入: 用户提供文本提示 y (例如 "a photograph of an astronaut riding a horse in space")。

  2. 文本编码: 使用 CLIP Text Encoder 将 y 转换为嵌入向量 c。

  3. 初始化噪声: 在潜空间生成一个随机高斯噪声 z_T(维度如 64x64x4)。

  4. 迭代去噪 (反向扩散): 从 t=T 到 t=1:

    • 将 z_t、时间步 t 和条件 c(以及用于 CFG 的空条件 ∅)输入到 U-Net。

    • 利用 CFG 计算出最终的噪声预测 ε_final。

    • 根据 ε_final 从 z_t 计算出 z_{t-1}。

  5. 解码: 得到最终的去噪潜码 z_0 后,将其输入到 VAE 的解码器 D 中。

  6. 输出: VAE 解码器输出最终的高分辨率像素图像 x = D(z_0)。

标题解读

使用CLIP训练好的特征,进行层级式的,基于文本的图片生成。

层级式:DALLE2先生成一个64*64分辨率的小图片,再上采样到256*256,最后再上采样到1024*1024

CLIP特征:DALLE2先训练好一个CLIP模型,利用与训练好的CLIP文本编码器得到文本特征,然后使用训练好的Prior模型,根据文本特征得到图像特征,然后将图像特征输入给解码器得到完整的图像。

摘要

如CLIP等基于对比学习的模型,已经学会了如何捕捉一个稳健的、包含语意和风格的图像特征。为了将这种特征利用与图像生成任务,作者团队提出了一个两阶段的模型:1. 一个Prior模型根据给定的文本描述,生成CLIP图像Embedding;2. 一个根据图像Embedding生成图片的Decoder。

具体流程为:

文本 -> CLIP生成文本特征 -> 根据文本特征生成图像特征(Prior) -> 解码器根据图像特征生成图像

作者团队发现。显式地加入文本特征可以在最小损害图像真实性和文本相似性的情况下,提升图像的多样性。即图片生成的结果又逼真又多样。

在CLIP模型的文本-图像联合语义空间下,用户可以使用自然语言直接对生成的图像进行操控。

作者团队使用扩散模型作为decoder,然后对Autoregressive模型和Diffusion模型都进行实验后,发现Diffusion模型更适合作为模型架构中的Prior模型。

引言

1. CLIP模型

在大规模的从网络收集的图-文对数据集框架中,CLIP模型展现出了强大的图像特征学习能力。CLIP Embeddings在图像特征偏移的问题上展现了强大的健壮性、拥有强大的zero-shot能力和很好的图像文本任务微调迁移能力。

2. Diffusion模型

扩散模型展现出强大的图像、视频生成能力。为了实现更逼真的生产结果,扩散模型利用“guidance technique”,以牺牲采样的多样性,来提升结果的真实性。

方法

图像上半部分:预训练好的CLIP模型。将文本Emedding和图片Embedding使用对比学习的方式进行对齐。

图像下半部分:在锁住已经预训练好的CLIP模型的基础上,训练Prior模型,训练目标如下:根据CLIP文本Embedding,Prior模型能生成一个图像Embedding。具体而言,训练时,Prior模型的输入式CLIP模型的文本Embedding,随后将CLIP图像编码器生成的Embedding作为Ground Truth进行训练。训练完成后,Prior模型能直接从文本特征得到后续用于解码的图像特征。

DALLE2数据集由图像-文本对组成。图像和文本数据分别用CLIP模型中的图像编码器和文本编码器编码为Zi, Zt。随后设计了一个两阶段的生成策略:

  • 通过一个Prior模型,根据Captions Embedding Zt,生成CLIP空间的 Image Embeddings Zi
  • 通过一个Decoder,将Prior模型生成的Image Embeddings Zi解码为最终图片。

Prior

论文探讨了两种Prior模型的实现方式,AR或Diffusion

  • AR Prior模型的实现方式与DALLE1类似,输入文本token,让模型预测图像token
  • Diffusion Prior模型直接在连续的 CLIP 图像嵌入向量 zi 上使用扩散模型。模型学习如何从一个标准高斯噪声向量出发,在标题 y 的引导下,逐步去噪,最终得到目标图像嵌入 zi。

Classifier-Free Guidance (CFG): 为了提高生成 zi 的质量以及与 y (和 zt) 的匹配度,两种 Prior 都支持 CFG。这是通过在训练时,有 10% 的概率随机丢弃文本条件信息来实现的。这使得模型能在推理时结合有条件和无条件的预测。

文章最终选取了基于Transformer的Diffusion Model作为Prior模型。

  • 模型架构: 使用一个仅解码器 (Decoder-only) 的 Transformer,带有因果注意力掩码。这与常见的用于图像扩散的 U-Net 不同,而是采用 Transformer 来处理序列化的输入并进行预测。

  • 输入序列结构: Transformer 处理的序列包含以下部分(按顺序):

    1. 编码后的文本标题 y。

    2. CLIP 文本嵌入 zt。

    3. 扩散时间步 t 的嵌入。

    4. 加噪后的 CLIP 图像嵌入 zi^(t)

    5. 一个最终的特殊嵌入 (final embedding)

  • 预测目标: Transformer 的输出中,对应于那个最终特殊嵌入位置的向量被用来直接预测去噪后的(unnoised)CLIP 图像嵌入 zi

  • 重要区别: 这不同于原始 DDPM [25] 中预测噪声 ε 的 ε-prediction 方式。作者发现,对于这个任务,直接预测 zi 本身效果更好

Decoder

Decoder模型的核心任务是接收 Prior 模型生成的 CLIP 图像嵌入 zi(以及可选的文本标题 y),并将其“解码”成一张逼真的像素图像 x。DALLE2的Decoder为一个精心设计的Diffusion Model。

Decoder模型训练时同样运用Classifier Free Guidance的技巧:

  • 针对 zi: 在训练期间,有 10% 的概率将输入的 CLIP 图像嵌入 zi 随机设置为零向量(或者一个可学习的特殊嵌入向量)。
  • 针对 y: 在训练期间,有 50% 的概率随机丢弃 (drop) 文本标题 y。这使得模型能够学习在没有文本条件下的预测(即 P(x|zi, ∅)),为基于文本的 CFG(尽管他们发现文本帮助不大,但机制上支持了)或完全无条件的预测 (P(x|∅, ∅)) 提供可能。

同时,Decoder使用了集联式的生成,先生成64x64的分辨率的图像,再将图像上采样至256x256,最后再将256x256的图像提升至1024x1024。

Upsampler 训练细节:

  • 鲁棒性提升: 为了让 Upsampler 对输入的低分辨率图像不那么敏感(更鲁棒),训练时会对输入的低分辨率图像进行轻微的损坏 (corruption)

    • 第一个 Upsampler (->256): 使用高斯模糊 (Gaussian blur)

    • 第二个 Upsampler (->1024): 使用更多样化的 BSR 退化 (BSR degradation)(BSR 通常包含模糊、噪声、压缩伪影等)。

Decoder是基于CNN实现的,非Transformer。

总结DALL-E 2 的核心架构:一个两阶段模型,先用 Prior 从文本标题 y 生成核心的 CLIP 图像嵌入 zi,再用 Decoder 将 zi (和 y) 渲染成最终图像 x

局限性和结语

因为DALLE2基于CLIP模型实现,所以属性绑定或者属性理解能力较弱。CLIP模型只负责将图片与语意信息的相似度提升至最高,而忽略了具体的属性信息。比如:

当提示要求生成“一个红色的立方体和一个蓝色的球体”时,DALL-E 2 可能更容易混淆,生成“一个蓝色的立方体和一个红色的球体”,或者颜色“溢出”到错误的对象上。

作者推测这是因为 CLIP 图像嵌入 zi 本身可能没有显式地编码对象和属性之间的绑定关系。CLIP 更关注整体语义匹配,而不是精确的空间或属性关联。Decoder 在从 zi 重建图像时,有时会混淆这些属性。

DALLE2不擅长生成文本,生成的文字往往是扭曲的、无意义的或拼写错误的。

可能原因:

这可能与属性绑定问题相关,即 CLIP 嵌入 zi 可能没有精确地编码渲染文本的拼写信息

使用的 BPE (Byte Pair Encoding) 文本编码方式会模糊 (obscure) 标题中单词的实际拼写,使得模型很难直接从标题中学习拼写。BPE编码是根据词根词缀进行编码的,而不是完整的赐予。模型需要独立地在训练图像中看到每个 token 被“写出来”的样子才能学会渲染它。

同时,DALLE2在复杂场景中的细节不足。

可能原因: 作者推测这可能是因为其 Decoder 结构的限制。基础 Decoder 只生成 64x64 分辨率的图像,然后通过两个 Upsampler 逐步放大。在这个过程中,一些精细的细节可能在低分辨率阶段就丢失了,或者 Upsampler 无法完美地恢复或创造这些细节。

潜在解决方案: 提高 Decoder 的基础生成分辨率(例如直接生成 128x128 或更高),但这会显著增加训练和推理的计算成本。

DALLE2生成的图像越来越逼真,难以与真实照片区分,这增加了被用于制造虚假信息、欺诈或恶意宣传的风险。随着技术进步,AI 生成的痕迹越来越少。模型可能被用来生成不当、冒犯性或有害的内容。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值