Skip to content

跨模态生成

跨模态生成以另一种模态的输入为条件,产生一种模态的输出;从文本到图像,从图像到文本,从文本到音频,等等。本文涵盖 DALL-E、Stable Diffusion、无分类器引导、ControlNet、图像描述、文本到视频(Sora)以及文本到音频生成。

  • 在本章的前几部分(文件 01-03),你学习了如何表示、对齐和标记不同模态。现在进入创造性行为:从一种模态生成另一种模态。跨模态生成是文本到图像工具、视频合成系统、音乐创作模型和图像描述背后的引擎。可以把它想象成教机器成为多媒体艺术家——你用文字描述你想要的,它就会绘画、制作动画或作曲。

  • 核心思想是条件生成:给定来自模态 \(A\)(例如文本)的输入,生成模态 \(B\)(例如图像)的输出。形式化地说,你学习一个模型 \(p_\theta(y \mid x)\),其中 \(x\) 是条件信号,\(y\) 是生成的输出。挑战在于这个条件分布极其复杂且高维——一张 512x512 的图像位于 \(\mathbb{R}^{786432}\) 中,而单个文本提示对应许多有效的图像。

跨模态生成概览:文本、图像、音频和视频模态通过方向箭头连接,显示生成路径,如文本到图像、图像到文本、文本到音频和文本到视频

文本到图像生成

  • 想象一下你向法庭素描艺术家描述一个场景。艺术家必须诠释你的话语,回忆物体的样子,在空间上组合它们,并渲染出最终图片。文本到图像模型正是做这件事,但它们必须从数据中学习所有这些技能,而不是经过多年的艺术学校学习。

DALL-E:自回归图像生成

  • DALL-E(Ramesh 等人,2021)将图像生成视为一个序列预测问题——与驱动语言模型(第 07 章)相同的范式。关键见解是,如果你能将图像表示为离散词元(回想一下第 03 章中的 VQ-VAE),那么生成图像就是逐个生成词元序列。

  • 管道分为两个阶段。首先,一个离散 VAE(dVAE) 将 256x256 的图像压缩成一个 32x32 的离散词元网格,词元来自一个包含 8192 个条目的码本,将图像简化为 1024 个词元的序列。其次,一个Transformer 解码器被训练来建模 256 个文本词元(BPE 编码)与 1024 个图像词元拼接后的联合分布,总共 1280 个词元:

\[p(x_{\text{text}}, x_{\text{img}}) = \prod_{i=1}^{1280} p(x_i \mid x_1, \ldots, x_{i-1})\]
  • 在生成时,你输入文本词元,模型自回归地逐个采样图像词元。这很优雅,因为它将语言建模的精确机制(注意力、因果掩码、top-k 采样)重用于图像合成。

  • 缺点是自回归生成本质上是顺序的:一次生成 1024 个词元很慢,并且序列早期的任何错误都会累积。DALL-E 通过生成许多候选图像并使用 CLIP(来自第 01 章)对它们重新排序来缓解这一点,以找到与文本提示最匹配的图像。

DALL-E 流程:文本词元和图像词元拼接成一个序列,由 Transformer 解码器处理,该解码器以文本词元为条件自回归地预测图像词元

Stable Diffusion:带文本条件的潜在扩散

  • Stable Diffusion(Rombach 等人,2022)采用了一种根本不同的方法。它不是逐个预测词元,而是从纯噪声开始,在文本提示的引导下逐步去噪为图像。回想第 08 章的扩散模型——Stable Diffusion 在压缩的潜在空间中操作,而不是像素空间,从而大大提高了效率。

  • 该架构有三个组件协同工作。一个VAE 编码器将图像从像素空间(\(512 \times 512 \times 3\))压缩到潜在表示(\(64 \times 64 \times 4\)),将维度降低了 48 倍。一个文本编码器(通常是 CLIP 或 OpenCLIP)将文本提示转换为嵌入向量序列。一个U-Net 去噪器接收带噪潜在表示、时间步和文本嵌入,并预测每一步要减去的噪声。文本条件通过交叉注意力层进入 U-Net:

\[\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d}}\right)V\]
  • 其中 \(Q\) 来自带噪图像特征,\(K, V\) 来自文本嵌入。这让模型能够在每个空间位置关注相关的单词——当对“红球”应该出现的区域进行去噪时,模型会关注“红色”和“球”这几个词元。

  • 在推理时,你在潜在空间中采样 \(z_T \sim \mathcal{N}(0, I)\),使用 U-Net 迭代去噪 \(T\) 步(通常使用 DDIM 调度为 20-50 步),然后用 VAE 解码器将干净的潜在表示 \(z_0\) 解码回像素空间。整个前向传播在消费级 GPU 上几秒钟内生成一张 512x512 的图像。

Stable Diffusion 架构:文本提示由 CLIP 编码,潜在空间中的随机噪声由 U-Net 迭代去噪,U-Net 通过交叉注意力与文本嵌入交互,然后由 VAE 解码生成最终图像

实践中的无分类器引导

  • 无分类器引导(CFG) 是使文本到图像模型生成真正匹配其提示的图像的秘密成分。回想第 08 章,CFG 在条件和无条件下训练模型,然后在采样时放大条件信号:
\[\hat{\epsilon} = \epsilon_\theta(x_t, \varnothing) + s \cdot (\epsilon_\theta(x_t, c) - \epsilon_\theta(x_t, \varnothing))\]
  • 其中 \(s\) 是引导尺度。可以把 \((\epsilon_\theta(x_t, c) - \epsilon_\theta(x_t, \varnothing))\) 项看作是“朝向提示的方向”——它捕捉了有条件和无条件预测之间的差异。乘以 \(s > 1\) 会夸大这个方向,以牺牲多样性为代价将图像推向更接近文本描述。

  • 在实践中,对于 Stable Diffusion,\(s = 7.5\) 是常见的默认值。在 \(s = 1.0\) 时,你得到原始模型输出(多样但大致匹配提示)。在 \(s = 20+\) 时,图像变得过饱和和重复,但与文本非常一致。最佳的 \(s\) 取决于应用:创意探索倾向于较低的引导,而精确的提示遵循需要较高的引导。

Imagen:具有语言理解能力的级联扩散

  • Imagen(Saharia 等人,2022)证明了强大的文本编码器比更大的图像模型更重要。Imagen 没有使用 CLIP,而是使用一个冻结的 T5-XXL 语言模型(来自第 07 章)作为文本编码器,它对语言语义、组合性和空间关系(“一个蓝色立方体在一个红色球体上面”)有更丰富的理解。

  • Imagen 使用级联扩散方法:一个基础扩散模型生成 64x64 的图像,第一个超分辨率模型将其放大到 256x256,第二个超分辨率模型达到 1024x1024。每个阶段都是一个以文本(对于超分辨率模型,还有低分辨率图像)为条件的独立扩散模型。这种级联避免了在基础分辨率上建模精细细节,使基础模型能够专注于构图和语义,而超分辨率模型处理纹理和清晰度。

  • Imagen 还引入了动态阈值:在每个去噪步骤中,预测的像素值被裁剪到一个基于百分位数的范围,而不是固定范围 \([-1, 1]\)。这防止了高引导尺度下的饱和伪影,这是扩散模型中的一个常见问题。

Parti:大规模自回归

  • Parti(Pathways Autoregressive Text-to-Image,Yu 等人,2022)以大规模复兴了自回归方法。与 DALL-E 类似,它将图像转换为离散词元(使用 ViT-VQGAN),并使用 Transformer 顺序生成它们。但 Parti 使用了 200 亿参数的编码器-解码器 Transformer(基于 Pathways 架构),并表明自回归模型在充分扩展时可以匹配扩散模型的质量。

  • Parti 的编码器-解码器架构是与 DALL-E 仅解码器设计的关键区别。文本通过编码器;解码器在生成图像词元时交叉关注编码后的文本。这类似于机器翻译(第 07 章)——从“文本语言”翻译到“图像语言”。

DiT 与基于流的生成

  • 扩散 Transformer(DiT)(Peebles 和 Xie,2023)用普通的 Transformer 取代了扩散模型中的 U-Net 骨干。每个带噪潜在图像块被当作一个词元(类似于第 08 章的 ViT),Transformer 使用自注意力和与文本条件的交叉注意力处理这些词元。DiT 表明,对于扩散模型,Transformer 比 U-Net 具有更可预测的扩展性——计算量加倍,FID 分数可靠地减半。

  • 流匹配(回顾第 08 章)已成为扩散噪声预测范式的替代方案。模型不是预测要减去的噪声 \(\epsilon\),而是预测一个速度场 \(v_\theta(x_t, t)\),将样本沿着从噪声到数据的直线路径传输。Stable Diffusion 3Flux 采用流匹配和多模态 DiT(MM-DiT) 架构,其中文本和图像词元由 Transformer 块联合处理,具有双向注意力——两种模态相互关注,而不是仅通过交叉注意力以文本条件约束图像特征。

DiT 架构:带噪潜在图像块像 ViT 一样被标记化,由带有自适应层归一化(用于时间步和类别条件)的 Transformer 块处理,然后解码回空间潜在表示

文本到视频生成

  • 文本到视频是文本到图像加上一个无情的额外约束:时间一致性。每一帧本身必须是内部一致的(有效的图像),但连续帧之间也必须平滑连接——物体应该自然移动,光照应该连续变化,“摄像机”应该遵循物理上合理的轨迹。想象一下绘制单幅风景画和导演一部电影之间的区别。

时间挑战

  • 视频在图像生成之外引入了三个挑战。时间一致性要求物体在帧间保持其身份——第 1 帧中的狗在第 100 帧中应该是同一只狗。运动建模需要学习物理动态:物体如何移动,重力如何工作,流体如何流动。计算成本是巨大的:一个 10 秒的视频,24 fps,512x512 分辨率,包含 \(10 \times 24 \times 512 \times 512 \times 3 \approx 1.88\) 亿个值,大约是单张图像数据量的 240 倍。

Make-A-Video 和扩展到视频的方法

  • Make-A-Video(Singer 等人,2022)采取了一种务实的方法:从一个预训练的文本到图像模型开始,并添加时间层。关键见解是,你已经有了在数十亿图像-文本对上训练的强大文本-图像模型,你只需要从(无标签的)视频数据中学习运动。

  • Make-A-Video 在预训练的空间 U-Net 中插入了时间注意力时间卷积层。空间层(在图像上预训练)处理外观,而新的时间层(在视频上训练)处理运动。空间自注意力在每帧内操作;时间注意力在每个空间位置上跨帧操作。这种分解是高效的,因为时间和空间模式在很大程度上是可分离的。

  • 生成流程镜像了 Imagen 的级联:一个基础模型生成 16 帧 64x64 的图像,然后空间和时间超分辨率模型将其放大到最终分辨率和帧率。一个帧插值网络提高了时间平滑度。

VideoPoet 和基于词元的视频模型

  • VideoPoet(Kondratyuk 等人,2024)在语言建模范式下统一了视频生成。所有模态——文本、图像、视频、音频——都被标记为离散序列,一个大型语言模型(LLM)被训练来自回归地预测所有模态的词元。这实现了零样本能力:文本到视频、图像到视频、视频到音频、视频编辑和修复都从同一个模型中涌现出来。

  • VideoPoet 使用 MAGVIT-v2 编码器(一个 3D VQ-VAE,来自第 03 章)对视频进行标记化,该编码器联合压缩空间和时间维度。音频使用 SoundStream 进行标记化。LLM 骨干在文本上预训练,并在多模态词元序列上进行微调,学习跨模态的联合分布。

Sora 风格的时间扩散

  • Sora(OpenAI,2024)凭借其生成长时长、连贯、物理上合理的视频的能力,将时间扩散带入了主流关注。虽然完整的架构细节尚未公布,但其关键思想涉及将 DiT 扩展到时空:视频帧被分解为时空图像块(跨越高度、宽度和时间的 3D 块),这些块被当作大型 Transformer 的词元。

  • 时空图像块方法意味着模型将视频视为原生 3D 信号,而不是 2D 帧序列。这使得它能够捕获长程时间依赖——模型可以“预先规划”整个视频时长,而不是逐帧生成。

  • Sora 可以通过调整时空图像块的数量来处理不同的时长、分辨率和宽高比。在数据的原始分辨率上训练(而不是将所有内容裁剪成正方形)提高了构图和取景质量。

Wan:开源视频生成

  • Wan(Wan 等人,2025)是一系列开源视频生成模型(1.3B 和 14B 参数),基于 DiT 骨干和 3D VAE 时间压缩构建。Wan 使用流匹配而不是传统的 DDPM 风格扩散,学习从噪声到视频潜在表示的直线传输路径。3D VAE 在空间和时间上压缩视频(4 倍时间压缩),DiT 使用全 3D 注意力处理所得的时空潜在词元。

  • Wan 支持文本到视频、图像到视频(使静态图像动起来)和视频编辑。14B 模型能够生成长达 5 秒、720p 分辨率的连贯视频,表明当架构和训练方案选择得当时,开源模型可以接近专有系统的质量。

文本到视频流程:文本由语言模型编码,时空噪声由时间扩散 Transformer 去噪,同时关注文本嵌入,然后由 3D VAE 解码为视频帧

文本到音频生成

  • 想象一下电影作曲家阅读剧本并为配乐谱曲。文本到音频模型做着类似的事情:给定一个文本描述(“伴有大雨和远处雷声的雷暴”),它们生成相应的音频波形。挑战在于弥合文本的离散、符号性质与声音的连续、时间性质之间的差距。

AudioLM:音频的语言建模

  • AudioLM(Borsos 等人,2023)通过自回归地预测离散音频词元来生成音频,借鉴了 DALL-E 用于图像的语言建模范式。它使用一个分层的词元结构:语义词元(来自自监督模型,如 w2v-BERT,回顾第 09 章)捕获高层内容(正在说什么或演奏什么),而声学词元(来自 SoundStream,一种神经音频编解码器)捕获细粒度的声学细节(声音如何——音色、录音质量)。

  • 生成分两个阶段进行。首先,一个 Transformer 在给定可选音频提示的情况下预测语义词元,建立高层内容计划。其次,另一个 Transformer 以语义词元为条件预测声学词元,填充声学细节。这种层次结构镜像了文本到语音流程(第 09 章)——语义词元扮演音素的角色,声学词元扮演梅尔频谱图帧的角色。

  • AudioLM 可以生成语音延续(给定 3 秒语音,生成接下来的 10 秒)、音乐延续和音效,所有这些都来自一个仅在音频数据上训练的单一模型(预训练不需要文本标签)。

MusicLM:文本条件的音乐

  • MusicLM(Agostinelli 等人,2023)将 AudioLM 扩展到文本条件的音乐生成。它添加了一个文本-音频联合嵌入(来自 MuLan,一个在音乐-文本对上训练的类似 CLIP 的模型)来条件化生成。MuLan 嵌入捕获文本描述(“带有萨克斯独奏的欢快爵士乐”)的语义含义,并指导分层的词元生成。

  • MusicLM 以 24 kHz 生成任意时长的音乐,在几分钟的乐曲中保持旋律和节奏的连贯性。它还可以以哼唱的旋律(使用音高跟踪器提取的旋律词元)加上文本描述为条件,生成一个完整的编曲,遵循哼唱的曲调并符合文本描述的风格。

MusicGen:高效的单阶段生成

  • MusicGen(Copet 等人,2023)简化了多阶段方法。MusicGen 没有使用单独的语义和声学模型,而是使用一个单一的自回归 Transformer,直接生成来自音频编解码器的多个码本级别。关键的创新是交错的码本模式:MusicGen 不是先为一个时间步生成所有码本级别再进入下一个时间步,而是以某种模式在码本和时间步之间交错词元,允许并行解码某些码本级别。

  • 条件化很简单:文本由 T5 编码器编码,文本嵌入被添加到音频词元序列之前(就像语言模型中的前缀提示)或通过交叉注意力注入。MusicGen 还支持旋律条件化:参考旋律的色度图(来自第 09 章讨论的频谱图特征)被编码并与文本条件一起使用。

\[p(a_1, \ldots, a_T) = \prod_{t=1}^{T} \prod_{k=1}^{K} p(a_{t,k} \mid a_{<t}, c_{\text{text}})\]
  • 其中 \(a_{t,k}\) 是时间步 \(t\) 和码本级别 \(k\) 的音频词元,\(c_{\text{text}}\) 是文本条件。对 \(k\) 的乘积根据码本模式进行分解——某些级别是并行预测的。

文本到音频流程:文本由语言模型编码,Transformer 解码器以交错的模式生成跨多个码本级别的离散音频词元,音频编解码器解码器重建波形

图像到文本生成

  • 现在翻转方向:给定一张图像,生成自然语言描述。这就是图像描述,它是一种条件文本生成形式,其中图像是条件。想象一下博物馆向导描述一幅画——他们必须感知视觉内容,理解物体之间的关系,并用流利的语言表达他们的观察。

作为条件生成的图像描述

  • 经典方法使用编码器-解码器架构(第 07 章)。一个预训练的 CNN 或 ViT(第 08 章)将图像编码为一组特征向量。一个语言模型解码器逐词生成描述,在每一步关注图像特征:
\[p(w_1, \ldots, w_L \mid I) = \prod_{l=1}^{L} p(w_l \mid w_1, \ldots, w_{l-1}, I)\]
  • 其中 \(w_l\) 是描述中的单词,\(I\) 是图像表示。交叉注意力将文本解码器连接到图像特征,允许模型在生成不同单词时“查看”图像的不同区域——在生成“狗”时关注狗的区域,在生成“公园”时关注公园的区域。

  • CoCa(Contrastive Captioners,Yu 等人,2022)将对比学习(第 01 章的 CLIP 风格目标)与图像描述统一在单个模型中。图像编码器产生的特征既用于与文本的对比对齐,也用于图像描述解码器中的交叉注意力。这种多任务训练使 CoCa 具有强大的零样本识别能力(来自对比学习)和强大的生成能力(来自图像描述)。

现代视觉语言描述

  • 现代方法通常使用大型多模态模型(第 02 章)进行图像描述。像 LLaVA、Qwen-VL 和 GPT-4V 这样的模型将图像描述视为视觉问答的一个特例——“问题”隐式地是“描述这张图像”。视觉编码器(CLIP ViT 或 SigLIP)产生图像块词元,这些词元被投影到 LLM 的嵌入空间中,LLM 生成自由形式的描述。

  • 基于 LLM 的图像描述相对于专用编码器-解码器模型的优势在于指令跟随:你可以要求不同层次的细节(“用一句话描述” vs “提供一段详细的描述”),关注特定方面(“描述颜色”),或生成结构化输出(“列出所有物体及其位置”)。这种灵活性来自于 LLM 的指令微调(第 07 章)。

视频-音频协同生成

  • 想象一下关掉声音看电影——体验是空洞的。视觉内容和音频是深度耦合的:弹跳的球有节奏的砰砰声,雨产生滴答声,人群发出欢呼声。视频-音频协同生成旨在同时产生两种模态,保持所见与所听之间的时间对齐。

联合时间建模

  • 核心挑战是时间同步:鼓击的音频必须与显示鼓槌敲击鼓的视觉帧精确重合。这需要一个两种模态都可以引用的共享时间表示。

  • 一种方法是基于共享的潜在时间线生成视频和音频。像 CoDi(Composable Diffusion,Tang 等人,2023)这样的模型为每种模态使用独立的扩散模型,但通过共享的潜在空间对齐它们。在训练期间,跨模态注意力层学习在每个时间步同步视觉和音频特征。在生成期间,两个扩散过程同时运行,通过共享的对齐相互条件化。

  • VideoPoet(上文讨论过)采取了更统一的方法:由于所有模态都被标记化为单个序列,LLM 自然会学习视频和音频词元之间的时间对应关系。一个狗叫的视频片段后跟相应的音频词元教会模型将视觉的吠叫动作与吠叫声关联起来。

  • 时间对齐损失函数显式地强制同步。一种形式在帧级别使用对比学习:时间 \(t\) 的音频片段应该比其它时间的帧更相似于时间 \(t\) 的视频帧:

\[\mathcal{L}_{\text{sync}} = -\mathbb{E}_t \left[\log \frac{\exp(\text{sim}(v_t, a_t) / \tau)}{\sum_{t'} \exp(\text{sim}(v_t, a_{t'}) / \tau)}\right]\]
  • 其中 \(v_t\)\(a_t\) 是时间 \(t\) 的视频和音频表示,\(\tau\) 是温度参数。这在结构上与第 01 章的 InfoNCE 损失相同,但应用于时间帧级别而不是片段级别。

指令跟随生成

  • 想象一下告诉艺术家“让天空更戏剧化”或“把帽子换成王冠”。指令跟随生成让你使用自然语言命令而不是精确的空间遮罩或笔触来编辑图像。

InstructPix2Pix:通过描述进行编辑

  • InstructPix2Pix(Brooks 等人,2023)训练了一个条件扩散模型,该模型接受输入图像和文本指令,然后生成编辑后的图像。巧妙之处在于训练数据的创建方式:GPT-3 生成编辑指令(“把它变成冬天”,“把猫变成狗”)配对的输入-输出文本描述,然后一个文本到图像模型(Stable Diffusion)生成相应的图像对。

  • 该模型是一个修改过的 Stable Diffusion U-Net,它接收文本指令(通过交叉注意力)和输入图像的潜在表示(与带噪潜在表示在通道维度上拼接)。它使用双无分类器引导,有两个引导尺度——一个用于文本指令(\(s_T\)),一个用于输入图像(\(s_I\)):

\[\hat{\epsilon} = \epsilon_\theta(x_t, \varnothing, \varnothing) + s_I \cdot (\epsilon_\theta(x_t, c_I, \varnothing) - \epsilon_\theta(x_t, \varnothing, \varnothing)) + s_T \cdot (\epsilon_\theta(x_t, c_I, c_T) - \epsilon_\theta(x_t, c_I, \varnothing))\]
  • 其中 \(c_I\) 是输入图像条件,\(c_T\) 是文本指令。第一个引导项控制保留输入图像的程度;第二个控制遵循指令的强度。这为用户提供了一个二维旋钮:高 \(s_I\) 紧密保留原始图像,而高 \(s_T\) 进行更戏剧性的编辑。

InstructPix2Pix:输入图像和文本指令输入到修改过的扩散模型,生成遵循指令同时保留未编辑区域的编辑图像

SDEdit 和基于噪声的编辑

  • SDEdit(Meng 等人,2022)提供了一种更简单的编辑方法,不需要特殊训练。你获取输入图像,向其添加噪声(将正向扩散过程运行到中间时间步 \(t_0\)),然后使用描述所需输出的文本提示进行去噪。噪声量控制编辑强度:低噪声保留结构(颜色变化、风格迁移),而高噪声允许重大重组(物体替换、布局更改)。

  • 权衡是精确的:在时间步 \(t_0\),带噪图像保留了 \(\bar{\alpha}_{t_0}\) 比例的原始信号。去噪过程根据新的文本提示填充被破坏的细节。这在数学上是有依据的:扩散模型从后验 \(p(x_0 \mid x_{t_0}, c)\) 中采样,其中 \(x_{t_0}\) 约束生成“接近”原始图像。

ControlNet:空间条件

  • ControlNet(Zhang 等人,2023)为文本到图像扩散添加了细粒度的空间控制。一个预训练 U-Net 编码器的副本被训练来接受额外的输入条件——边缘图(Canny 边缘)、深度图、姿态骨架、分割图——而原始的 U-Net 权重被冻结。ControlNet 编码器的输出通过零卷积(初始化为零的 1x1 卷积)添加到冻结 U-Net 的跳跃连接中,确保训练从预训练模型的行为开始,并逐渐学习新的条件。

  • 这种架构让你提供草图、深度图或人体姿态作为结构指南,文本提示则填充外观。预训练权重处理照片真实感和文本理解;ControlNet 层处理对条件的空间保真度。

一致性与对齐度量

  • 你如何衡量生成的图像是否好?“好”至少有两个维度:质量(它看起来像真实的图像吗?)和对齐(它与文本提示匹配吗?)。已经开发了几种度量标准来量化这些。

Frechet 初始距离(FID)

  • Frechet 初始距离(FID)(Heusel 等人,2017)在预训练 Inception 网络的特征空间中测量生成图像分布与真实图像分布之间的距离。可以理解为比较两个图像集合的“指纹”,而不是比较单个图像。

  • 真实和生成的图像集都通过 Inception-v3,并收集倒数第二层的激活。这些激活被建模为多元高斯分布 \(\mathcal{N}(\mu_r, \Sigma_r)\)\(\mathcal{N}(\mu_g, \Sigma_g)\)。FID 是这些高斯之间的 Frechet 距离(Wasserstein-2 距离):

\[\text{FID} = \|\mu_r - \mu_g\|^2 + \text{Tr}\left(\Sigma_r + \Sigma_g - 2(\Sigma_r \Sigma_g)^{1/2}\right)\]
  • 较低的 FID 更好。FID = 0 意味着分布相同。FID 捕捉了质量(如果生成的图像模糊,它们的特征将与真实图像不同)和多样性(如果模型遭受模式坍塌,\(\Sigma_g\) 将比 \(\Sigma_r\) 小)。在 ImageNet 256x256 上,典型的最先进值 FID < 2.0。

  • FID 有已知的局限性:它假设高斯特征分布(是近似的),它需要数千个样本才能获得稳定的估计,并且它使用 Inception 特征(可能无法捕获所有感知相关的差异)。

Inception 分数(IS)

  • Inception 分数(IS)(Salimans 等人,2016)衡量两个属性:每个生成的图像应该可以被自信地分类(条件类分布 \(p(y \mid x)\) 应该是尖锐的),并且生成的图像集应该覆盖许多类别(边缘分布 \(p(y) = \mathbb{E}_x[p(y \mid x)]\) 应该是均匀的)。IS 通过 KL 散度结合了这些:
\[\text{IS} = \exp\left(\mathbb{E}_x \left[D_{\text{KL}}(p(y \mid x) \| p(y))\right]\right)\]
  • 较高的 IS 更好。最大 IS 等于类别数(ImageNet 为 1000)。IS 奖励质量(清晰、可识别的图像)和多样性(类别覆盖),但它有显著的局限性:它完全忽略了真实数据分布,它无法检测类内的模式丢失,并且由于它使用 Inception 的类别预测,它偏向于类似 ImageNet 的图像。

CLIPScore:测量文本-图像对齐

  • CLIPScore(Hessel 等人,2021)使用预训练的 CLIP 模型(第 01 章)直接测量生成的图像与其文本提示的匹配程度。该分数就是 CLIP 图像嵌入和 CLIP 文本嵌入之间的余弦相似度:
\[\text{CLIPScore}(I, T) = \max(0, \cos(E_I(I), E_T(T)))\]
  • 其中 \(E_I\)\(E_T\) 是 CLIP 图像和文本编码器。CLIPScore 是无参考的——它不需要真实图像,只需要文本提示。它与人类对文本-图像对齐的判断具有良好的相关性,并已成为评估文本到图像模型中提示保真度的标准度量。

  • 为了与参考描述进行比较,RefCLIPScore 加入了一个参考图像:

\[\text{RefCLIPScore} = \text{HarmonicMean}(\text{CLIPScore}(I, T), \max(0, \cos(E_I(I), E_I(I_{\text{ref}}))))\]
  • 这平衡了文本对齐与对参考图像的视觉相似性。

评估度量:FID 比较真实和生成图像集的特征分布,IS 仅测量生成图像的质量和多样性,CLIPScore 测量图像和文本嵌入之间的余弦相似度

人类评估

  • 自动度量是代理;人类判断仍然是黄金标准。常见的协议包括成对比较(两张图像哪张更好地匹配提示?)、李克特量表(从 1-5 对质量和对齐进行评分)和 Elo 评分(模型间的锦标赛式排名)。DrawBench 和 PartiPrompts 基准为系统化的人类评估提供了标准化的提示集。

伦理考量

  • 跨模态生成是人工智能中伦理影响最重大的领域之一。从文本描述创建逼真图像、视频和音频的能力引发了从业者必须认真对待的深刻担忧。

深度伪造与虚假信息

  • 深度伪造是被生成或操纵的媒体,旨在描绘从未发生的事件。文本到图像和文本到视频模型可以创建令人信服的公众人物伪造照片、捏造的证据和误导性的新闻图像。危险不仅在于伪造品的存在,还在于它们的存在破坏了人们对所有媒体的信任——如果任何图像都可能是伪造的,那么没有图像是完全可信的。

  • 检测方法包括训练分类器区分真实和生成的图像、分析统计伪影(GAN 生成的图像有微妙的频谱特征),以及嵌入不可见水印(Stable Diffusion 的不可见水印,Google 的 SynthID)。然而,检测是一场军备竞赛:随着生成器的改进,检测器必须不断更新。

生成中的偏见

  • 在互联网规模数据上训练的模型继承并放大了社会偏见。文本到图像模型不成比例地生成肤色较浅的面孔,将某些职业与特定性别关联起来,并对未充分指定的提示默认采用西方文化规范。这些偏见根植于训练数据分布以及 CLIP/T5 文本编码器中,后者编码了来自自身训练语料库的偏见。

  • 缓解策略包括策划更具代表性的训练数据、对文本编码器应用去偏技术、使用安全分类器过滤有问题的输出,以及使用户能够控制人口统计属性。这些都不是完整的解决方案,持续审计至关重要。

内容过滤与安全

  • 负责任的部署需要多层保护。输入过滤在生成之前阻止有害提示。输出过滤对生成的内容进行分类并拒绝有害材料。NSFW 分类器检测露骨的色情、暴力或其他有害内容。例如,Stable Diffusion 的安全检查器计算生成图像的 CLIP 嵌入与一组预定义的有害概念嵌入之间的余弦相似度,标记超过阈值的图像。

  • 许多生成模型(Stable Diffusion、Wan)的开源性质在民主化访问和防止滥用之间造成了紧张关系。一旦模型权重被发布,内容过滤就可能被绕过。这引发了关于适当开放程度以及模型开发者责任的辩论。

知识产权与同意

  • 在互联网数据上训练的生成模型可能会在未经同意的情况下复制受版权保护的风格、商标或真实人物的肖像。法律和伦理框架仍在发展中,但负责任的实践包括尊重退出机制、承认训练数据中嵌入的创造性贡献,以及开发针对记忆和复述训练示例的技术保障措施。

编程任务(使用 CoLab 或 notebook)

  1. 为一个玩具 2D 扩散模型实现无分类器引导。在一个 2D 数据集(例如带标签的聚类)上训练一个条件扩散模型,然后使用不同的引导尺度进行采样,以观察质量-多样性的权衡。

    import jax
    import jax.numpy as jnp
    import matplotlib.pyplot as plt
    
    # 具有无分类器引导的玩具 2D 条件扩散
    def noise_schedule(T):
        betas = jnp.linspace(1e-4, 0.02, T)
        alphas = 1.0 - betas
        return jnp.cumprod(alphas)
    
    def forward_diffuse(x0, t, alpha_bars, key):
        noise = jax.random.normal(key, x0.shape)
        return jnp.sqrt(alpha_bars[t]) * x0 + jnp.sqrt(1 - alpha_bars[t]) * noise, noise
    
    # 生成带标签的 2D 数据:类别 0 = 环形,类别 1 = 聚类
    key = jax.random.PRNGKey(42)
    k1, k2, k3 = jax.random.split(key, 3)
    theta = jax.random.uniform(k1, (200,)) * 2 * jnp.pi
    ring = jnp.stack([jnp.cos(theta), jnp.sin(theta)], axis=1) * 2
    ring += jax.random.normal(k2, ring.shape) * 0.1
    cluster = jax.random.normal(k3, (200, 2)) * 0.3
    
    data = jnp.concatenate([ring, cluster])
    labels = jnp.concatenate([jnp.zeros(200), jnp.ones(200)])
    
    # 模拟 CFG:展示引导如何将样本推向类别条件模式
    # 尝试改变 guidance_scale 从 0.0 到 5.0 并观察结果
    guidance_scales = [0.0, 1.0, 3.0, 7.0]
    fig, axes = plt.subplots(1, 4, figsize=(16, 4))
    for ax, s in zip(axes, guidance_scales):
        ax.scatter(ring[:, 0], ring[:, 1], s=8, alpha=0.4, label='环形 (c=0)')
        ax.scatter(cluster[:, 0], cluster[:, 1], s=8, alpha=0.4, label='聚类 (c=1)')
        ax.set_title(f'引导尺度 s={s}')
        ax.set_xlim(-4, 4); ax.set_ylim(-4, 4)
        ax.set_aspect('equal'); ax.legend(fontsize=7)
    plt.suptitle('实验:改变引导尺度,观察质量与多样性')
    plt.tight_layout(); plt.show()
    # 练习:训练一个带类别条件的小型 MLP 去噪器,
    # 然后实现 CFG 公式,用不同的 s 值进行采样。
    

  2. 使用完整的 Frechet 距离公式计算两组 2D 样本之间的 FID。改变生成的分布,观察 FID 如何变化。

    import jax
    import jax.numpy as jnp
    import matplotlib.pyplot as plt
    
    def compute_fid(real, generated):
        """计算两组 2D 样本集之间的 Frechet 距离。"""
        mu_r, mu_g = jnp.mean(real, axis=0), jnp.mean(generated, axis=0)
        sigma_r = jnp.cov(real.T)
        sigma_g = jnp.cov(generated.T)
        diff = mu_r - mu_g
        # 通过特征分解计算矩阵平方根
        product = sigma_r @ sigma_g
        eigvals, eigvecs = jnp.linalg.eigh(product)
        sqrt_product = eigvecs @ jnp.diag(jnp.sqrt(jnp.maximum(eigvals, 0))) @ eigvecs.T
        fid = jnp.sum(diff ** 2) + jnp.trace(sigma_r + sigma_g - 2 * sqrt_product)
        return fid
    
    key = jax.random.PRNGKey(0)
    k1, k2, k3, k4 = jax.random.split(key, 4)
    
    # 真实分布:标准 2D 高斯
    real = jax.random.normal(k1, (1000, 2))
    
    # 生成的分布,发散度逐渐增加
    shifts = [0.0, 0.5, 1.0, 2.0, 4.0]
    fig, axes = plt.subplots(1, len(shifts), figsize=(18, 3.5))
    for ax, shift in zip(axes, shifts):
        gen = jax.random.normal(k2, (1000, 2)) * (1 + shift * 0.2) + shift
        fid = compute_fid(real, gen)
        ax.scatter(real[:, 0], real[:, 1], s=3, alpha=0.3, label='真实')
        ax.scatter(gen[:, 0], gen[:, 1], s=3, alpha=0.3, label='生成')
        ax.set_title(f'偏移={shift}\nFID={fid:.2f}')
        ax.set_xlim(-5, 8); ax.set_ylim(-5, 8)
        ax.set_aspect('equal'); ax.legend(fontsize=7)
    plt.suptitle('随着生成分布偏离真实分布,FID 增加')
    plt.tight_layout(); plt.show()
    # 尝试:改变生成样本的方差而不移动均值。
    # FID 对多样性不匹配与位置不匹配的反应有何不同?
    

  3. 使用随机投影作为 CLIP 的替代,实现文本和图像嵌入之间的 CLIPScore。观察当你改变模态之间的“对齐”时,余弦相似度如何行为。

    import jax
    import jax.numpy as jnp
    import matplotlib.pyplot as plt
    
    def cosine_similarity(a, b):
        return jnp.dot(a, b) / (jnp.linalg.norm(a) * jnp.linalg.norm(b))
    
    def clip_score(img_emb, txt_emb):
        """CLIPScore:限制范围的余弦相似度。"""
        return jnp.maximum(0.0, cosine_similarity(img_emb, txt_emb))
    
    key = jax.random.PRNGKey(42)
    dim = 512  # CLIP 嵌入维度
    
    # 模拟对齐和未对齐的配对
    # 对齐:图像和文本嵌入共享一个分量
    k1, k2, k3 = jax.random.split(key, 3)
    shared = jax.random.normal(k1, (dim,))
    shared = shared / jnp.linalg.norm(shared)
    
    noise_levels = jnp.linspace(0, 5, 20)
    scores = []
    for noise in noise_levels:
        noise_vec = jax.random.normal(k2, (dim,)) * noise
        img_emb = shared + noise_vec * 0.3
        txt_emb = shared + jax.random.normal(k3, (dim,)) * noise * 0.3
        scores.append(float(clip_score(img_emb, txt_emb)))
    
    plt.figure(figsize=(8, 4))
    plt.plot(noise_levels, scores, 'o-', color='#2c3e50')
    plt.xlabel('噪声水平(未对齐程度)')
    plt.ylabel('CLIPScore')
    plt.title('随着文本-图像对齐度下降,CLIPScore 降低')
    plt.grid(True, alpha=0.3)
    plt.tight_layout(); plt.show()
    # 实验:如果在添加噪声之前对嵌入进行归一化,会发生什么?
    # 维度如何影响分数分布?