在一座繁忙的乐高建筑事务所里,老师傅们世代相传一门手艺:从一堆杂乱无章的乐高颗粒(噪声)中,一层层搭出精致的建筑(图片)。他们每搭一层,都要对照图纸反复修正——这就是扩散模型“逐渐去噪、化乱为整”的生成过程。老工坊(基于CNN的U-Net)虽然手艺精湛,但师傅们都只盯着自己眼前的一小块积木,难以体会整片屋顶与远山的呼应。 DiT(Diffusion Transformer)像是一位横空出世的“全局总设计师”。他把巨大的图纸划成整齐的小方块(Patch化),让每位助手(Transformer模块)都能同时俯瞰所有方块之间的关系;他还会把客户的期望清单(类别、文本等条件)转译成每一步搭建的微调指令(条件注入)。于是,从静态图片到流动的Sora视频世界,这位总设计师正在改变整个行业的施工方式。
理解DiT,你就拿到了解读Stable Diffusion 3、Sora等新一代AIGC模型的钥匙。对于AI从业者,这是从“会调API”迈向“设计生成架构”的关键一步,也是应对AIGC前沿研究的基础能力。
目录
可视化演示
动态演示DiT扩散Transform的核心机制,通过采集/分析/决策/反馈四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
DiT扩散Transform:DiT的 DiT的核心设计思想:从U-N Patch化序列建模机制 核心机制可视化 DiT扩散Transform整体架构与关键组件
背景与动因——旧工坊的困境
在城市的某个角落,有一座祖传的乐高建筑工坊。老师傅的技法炉火纯青:他能从一堆杂乱的乐高颗粒(噪声)中,一砖一瓦地把建筑(图像)搭出来。这个过程不轻松,要经历几十上百轮“敲打与修正”——这正是扩散模型的核心:先从纯噪声出发,依靠逐步去噪,最终形成清晰的画面。扩散模型确实厉害,但老师傅有个先天短板:他的眼睛永远只看得到眼前十厘米的地方。
传统主干网络U-Net基于卷积神经网络(CNN),每个卷积核所覆盖的视野(感受野)有限,虽然可以通过堆叠层数间接扩大视野,但本质上仍偏向局部。面对“一整片星空下连绵的山脉”这类需要全局协调的画面,CNN就容易顾此失彼。2022年,William Peebles等人发表DiT论文,核心思路非常直接:既然Transformer在语言、视觉任务上都展现出强大的全局建模与扩展能力,那能不能把它直接作为扩散模型的主干?
训练目标保持不变,仍然是最小化预测噪声与真实噪声之间的均方误差:
DiT的诞生,就像老师傅终于请来了一位能俯瞰全局的总设计师。训练目标不变、手艺不变,但“看问题的方式”彻底改变了。旧工坊的困境,从此被一位全局视野的新人打破。
- 噪声目标 $\epsilon$训练时人为加到图像上的高斯噪声。可以理解为“故意撒进乐高堆里的杂质颗粒”。
- 模型预测 $\epsilon_\theta(x_t, t)$给定已被污染的图片 $x_t$ 和时间步 $t$,模型输出对噪声的估计。就像老师傅看一眼被弄乱的建筑,判断“哪些颗粒是被后撒进去的”。
- 均方误差把预测噪声和真实噪声逐点相减、平方、求均值。数值越小,说明师傅的眼光越准。
- 期望 $\mathbb{E}_{t, \epsilon}$对随机取样的时间步 $t$ 和噪声 $\epsilon$ 求期望,相当于训练时反复练习各种程度的“混乱局面”,让模型在所有情况下都稳定发挥。
Patch化处理——给底板刻格子
新来的总设计师虽然视野过人,但他有个习惯:先把巨大的建筑底板划成整齐的小方格,再逐一编号。这样他才能高效地指派任务——这恰好对应DiT的第一步:Patch化。DiT把一张图像看作“底板上密密麻麻的像素点”。如果让Transformer直接处理每一个像素,序列长度会爆炸,计算量难以承受。
因此DiT借鉴ViT的做法,把图像切成固定大小的方块(patch)。例如一张 $32 \times 32$ 的灰度图,按 $4 \times 4$ 切分,可以得到 $8 \times 8 = 64$ 个patch,每个patch是一个“小零件”。每个patch需要被嵌入成一个向量(token),这个步骤叫PatchEmbed。虽然名字里带"Embed",实践中通常用卷积层实现——卷积核大小等于patch大小、步长也等于patch大小。
同时,还要加上位置编码(Positional Embedding),告诉Transformer“这个patch原本位于左上角还是右下角”。否则所有token打乱顺序,对模型来说都一样。这一过程用公式表示为:
有了方格和编号,总设计师才能指挥千军万马:每个token都是图纸上的一块小积木,清清楚楚、各归其位。
- PatchEmbed(x)负责把 $p \times p$ 的像素块压成一个向量。它像个“零件压缩器”,把一小块积木压缩成一张标签卡。
- PosEmbed(p)根据patch的位置坐标生成位置向量,像给图纸上的每个格子里写上坐标编号。
- 向量相加内容信息和位置信息加在一起,组成一个携带“内容+坐标”的token,正式进入Transformer流程。
DiT核心架构——总设计师的工作台
总设计师的办公桌上铺满了零件盒。他每隔一阵子就会把所有盒子整体看一遍,判断“哪些盒子之间的颗粒需要呼应”——比如房顶的颜色要与墙体统一。这种同时观察所有盒子的能力,正是Transformer的注意力机制。DiT的基本构成单元是DiTBlock,它由层归一化、多头自注意力和前馈网络组成。
与常见Transformer略有不同,DiT采用pre-norm结构(先归一化再送入注意力),目的是让深层网络训练更稳定。序列中的每个token生成三份角色:查询(Q)、键(K)、值(V),通过注意力计算完成信息聚合:
每一层DiTBlock就是一次“全盘审阅+精修”:先全局对比,再局部加工(前馈网络),让整座建筑在一次次的巡检中越来越协调。
- 注意力分数矩阵通过 $Q$ 与 $K$ 的内积,计算任意两个token之间的关联强度。就像设计师同时对比每两个零件盒的匹配度。
- 缩放因子除以 $\sqrt{d_k}$ 防止数值过大,保障softmax后的梯度稳定。相当于把打分表归一化到合理量程。
- softmax归一化把每一行的分数转换成“权重”,让同一行权重之和为1。类似在所有零件盒中分配注意力预算。
- 加权聚合值向量按权重把每个token的 $V$ 融合,得到当前token更新后的表示。好比参考所有盒子后,重新调整当前盒子的内容。
条件注入——客户的期望清单
总设计师不能自作主张。客户递来一张期望清单:“我要一栋北欧风格的木屋,颜色素雅。”这份清单如何影响每一块积木的摆放,正是条件注入要解决的问题。在扩散模型里,条件可以是类别标签(如“猫”)、文本描述,也可以是时间步 $t$。
DiT论文比较了四种注入方式:In-context(把条件拼进输入序列)、Cross-Attention(让注意力“参考”条件向量)、AdaLN(自适应归一化)、AdaLN-Zero(AdaLN的改进版)。AdaLN的做法是:把条件 $c$ 通过一个MLP映射为缩放参数 $\alpha$ 和偏移参数 $\beta$,对归一化后的特征进行调制:
AdaLN-Zero更进一步:在AdaLN之后增加一个由条件控制的残差门控,初始化时门控为零,让每个块从“恒等映射”开始逐步学习条件影响:
好的条件注入像给设计师戴上一副“需求眼镜”——看每块积木时都带着客户的要求,而不是把清单摔在桌上让他手忙脚乱。
- 层归一化 LN(h)先对隐状态做标准化,相当于先把每个零件盒里的颗粒摆正、对齐。
- MLP生成调制参数条件 $c$ 先经过MLP,输出缩放系数 $\alpha$ 和偏移系数 $\beta$。好比把客户需求翻译成“调色参数”。
- 自适应调制$\alpha$ 逐元素乘上归一化结果,再加上 $\beta$。每个token被条件“拧紧”或“放松”。
- 门控 $\gamma_c$AdaLN-Zero额外学一个门控,初始值为零。让条件在每个块中的作用从“零干预”逐步加大。
模型缩放——工坊规模的意义
客户问:“是不是工坊越大、人手越多,成品就越精致?”DiT团队用严谨的实验回答了这个问题:是,但要以正确的方式扩大。论文设计了四个规模的模型:DiT-S、DiT-B、DiT-L、DiT-XL,参数量从3300万到6.75亿,并在相同的计算预算下对比生成质量(以FID为指标,越小越好)。
实验结果有两个重要发现:第一,在相同计算量下,Transformer的FID明显优于U-Net;第二,随着模型规模和总计算量增大,FID持续下降,呈现幂律关系:
DiT的缩放规律告诉业界:与其在手艺细节上反复抠,不如把工坊规模做大——只要架构选对Transformer,加大投入就能看到实打实的质量提升。
- 计算量 $C$训练总FLOPs,可以理解为工坊投入的总工时。
- 幂律项 $a \cdot C^{-\alpha}$FID随工时按指数 $\alpha$ 下降。$\alpha$ 越大,扩大规模带来的收益越明显。
- 质量下限 $b$即使投入无限多,质量也有天花板。好比人手再多,也受制于设计图纸和材料极限。
- 整体函数 FID(C)生成质量随规模变化的规律,是架构设计的重要参考。
Sora应用——从静态建筑到流动城市
总设计师的野心不止于静态建筑。他要让城市活起来:汽车在路上跑,行人在街角穿行。这就是从“生成图片”到“生成视频”的跃迁。2024年,OpenAI发布的Sora展示了令人惊叹的视频生成能力,底层正是DiT的延伸。
视频比图片多了一个时间维度,因此Sora把视频看作一个三维时空体,将其切成“时空patch”(spacetime patches)。具体做法是:先用视觉编码器把视频压缩成低维潜空间表示,然后再在潜空间上切patch、送入DiT。一个视频 $V$ 可表示为 $T \times H \times W \times C$ 的四维张量,时空patch化后变成token序列:
对总设计师来说,从“一张图纸”升级到“一套动画分镜”,只是把方格改成“有厚度的方格”——全局视野的魔法依然有效。
- 视频张量 $V$四维数组:帧数 $T$、高 $H$、宽 $W$、通道数 $C$。
- Patchify操作沿时间、高、宽三个轴切块,把三维小块压缩成token。
- Token序列 $Z$得到形状 $N \times D$ 的序列,交给DiT处理。
架构转变与前景——新一代工坊的诞生
旧工坊中老师傅的技艺虽值得尊敬,但越来越多的客户发现:新工坊(DiT)的作品细节丰富、全局和谐。行业开始思考:是时候全面换血了。DiT的意义不只是一个新模型,而是证明了Transformer可以完全替代U-Net成为扩散模型的主干,并带来更好的扩展性和生成质量。
整个DiT前向流程可以概括为:输入图像先被Patch化并加上位置编码,然后经过 $L$ 个DiT块(每块都注入条件 $c$),最后通过一个输出头预测噪声:
现在,越来越多的“工坊”开始采用总设计师模式:从Stable Diffusion 3到Sora,从图像到视频,DiT正在成为新一代生成模型的事实标准。旧工坊并未消失,但新工坊已经改变了行业的模样。
- PatchEmbed + PosEmbed图像切成小块并嵌入,加上位置信息。
- L层DiTBlock堆叠每个块内部是注意力+前馈+条件调制,共堆叠 $L$ 层。
- 输出头 Head最后的线性层或解码头,输出预测噪声。
- 整体流程从像素到token,再到噪声预测,简洁而统一。
AI 应用场景
文生图模型研发
阶段:模型架构设计
解决的问题:传统U-Net在复杂构图和长文本描述下容易顾此失彼,对全局语义和细节纹理的协调能力不足。DiT的全局注意力机制能更好地建模“画面整体关系”,让文字描述与画面内容精准对应。
具体案例:Stable Diffusion 3采用基于DiT的多模态架构(MMDiT),生成带有丰富文字信息的图片时,文字渲染准确率大幅提升,构图也更加和谐统一。
视频生成系统构建
阶段:视频模型选型
解决的问题:视频数据维度高,传统模型难以建模长时间跨度的动态变化。DiT通过“时空patch”将视频压缩成统一token序列,让时间与空间信息同时被注意力机制建模。
具体案例:Sora将视频切分为时空patch,用DiT统一处理画面内容与运动变化,支持生成10秒以上、场景一致且动作连贯的高质量视频。
医学影像生成与数据增强
阶段:数据增强
解决的问题:医疗数据稀缺且隐私敏感,需要生成逼真的合成影像来扩充训练集。DiT的全局建模能力让生成影像在解剖结构和病灶细节上更真实。
具体案例:基于DiT的扩散模型生成高分辨率CT切片,帮助下游分割模型在罕见病灶上显著提升检测召回率。
Python 演示
"""最小 DiT-Block 前向演示"""import torchimport torch.nn as nn class PatchEmbed(nn.Module): def __init__(self, patch_size=2, in_chans=1, dim=32): super().__init__() self.proj = nn.Conv2d(in_chans, dim, kernel_size=patch_size, stride=patch_size) def forward(self, x): x = self.proj(x) x = x.flatten(2).transpose(1, 2) return x class DiTBlock(nn.Module): def __init__(self, dim, num_heads=4): super().__init__() self.norm1 = nn.LayerNorm(dim) self.attn = nn.MultiheadAttention(dim, num_heads, batch_first=True) self.norm2 = nn.LayerNorm(dim) self.mlp = nn.Sequential( nn.Linear(dim, dim * 4), nn.GELU(), nn.Linear(dim * 4, dim), ) def forward(self, x): x = x + self.attn(self.norm1(x), self.norm1(x), self.norm1(x))[0] x = x + self.mlp(self.norm2(x)) return x def main(): torch.manual_seed(0) x = torch.randn(2, 1, 8, 8) pe = PatchEmbed(patch_size=2, in_chans=1, dim=32) z = pe(x) pos = torch.randn(1, 16, 32) * 0.02 z = z + pos block = DiTBlock(dim=32, num_heads=4) out = block(z) print("输入 token 序列:", list(z.shape)) print("输出 token 序列:", list(out.shape)) assert out.shape == z.shape if __name__ == "__main__": main()
self.proj = nn.Conv2d(in_chans, dim, kernel_size=patch_size, stride=patch_size)用卷积实现Patch嵌入:卷积核尺寸和步长都等于patch大小,一次完成切块和向量化。x.flatten(2).transpose(1, 2)把 $B \times C \times H \times W$ 的特征展平成 $B \times N \times D$ 的token序列,符合Transformer的输入格式。nn.MultiheadAttention(dim, num_heads, batch_first=True)内置多头自注意力,让每个token都能看到序列中的其他所有token。x = x + self.attn(self.norm1(x), ...)[0]Pre-norm + 残差连接,这是DiT块中稳定训练的关键设计。z = z + pos加入随机位置编码,模拟DiT中的位置信息注入。
常见误区
误区很多人以为DiT只是把U-Net的卷积层换成Transformer块,其他都不用动。实际上我尝试直接替换后效果并不理想,训练还特别不稳定。
正解DiT在多个维度做了系统设计:图像要先切成patch而不是当成像素序列;条件注入要选AdaLN-Zero而不是简单拼接;位置编码、归一化方式、模型规模都要配套调整。就像给旧工坊请来总设计师,光换人不够,图纸、流程、零件盒都得重新设计。
为何常见:因为“替换主干”听起来简单,人们容易忽略架构匹配的复杂性,只有亲手复现过才发现细节决定成败。
误区我认为把patch设得大一些,token数量少、计算快,模型应该更好训练,生成的图像也会更干净。
正解patch越大,每个token承载的空间细节越粗糙,图像恢复时容易丢失高频信息。DiT论文在patch size为2、4、8之间做了系统对比,小patch虽然计算更贵,但质量上限更高。实际使用中要权衡计算成本和细节保真度,并不是越大越好。
为何常见:直觉上“压缩得更狠=更高效”,但生成任务是逆问题,输入信息的损失会直接反映在输出质量上。
误区既然都是把条件信息喂给模型,in-context、cross-attention、AdaLN应该差别不大,选个最简单的就行。
正解DiT论文用严格对照实验证明,AdaLN-Zero显著优于in-context和cross-attention,尤其是在大模型上差距更明显。in-context把条件混在序列里,容易被长序列稀释;cross-attention增加了额外计算;AdaLN-Zero则让条件以调制方式精准作用于每一层特征,且从零初始化的门控让训练更稳。
为何常见:没有做过消融实验时,很难直观感知不同注入方式对梯度流和特征分布的深远影响。
误区既然DiT是纯Transformer架构,卷积应该被彻底淘汰了,整个模型全是注意力。
正解DiT的PatchEmbed模块通常就是用卷积层实现的(卷积核=步长=patch size)。此外,空间上先切块再展平,本质上也是一种局部结构的归纳偏置。Transformer负责全局关系建模,卷积负责高效的局部特征提取,两者是合作关系而非替代关系。
为何常见:媒体宣传常强调“Transformer取代CNN”,读者容易理解成“卷积消失”,实际上架构创新往往是组合创新。
误区DiT的缩放规律说明FID随模型增大而下降,那我无脑堆参数量就能得到最好的模型。
正解缩放规律是在相同训练数据和足够计算预算下成立的。现实中数据量、训练时间、推理成本都是约束。DiT-XL比DiT-S效果好,但训练成本高出数十倍。而且从幂律曲线看,收益是递减的——投入翻倍,FID改善却越来越小。
为何常见:“越大越好”符合直觉,但忽略了缩放规律成立的前提条件,也忽略了工程成本的非线性增长。
面试题
Q1. DiT中的patch指的是什么?
- A.图像的单个像素
- B.图像的小块区域← 正确答案
- C.整张原始图像
- D.随机噪声向量
答案:B。patch是图像切分出的固定大小方块,通常包含 $p \times p$ 个像素,而不是单个像素或整张图。选项B准确描述了patch的“小块区域”本质;A只到像素粒度,C把范围扩大到全图,D则是噪声概念,均不符合。
Q2. DiT论文中哪种条件注入方式效果最优?
- A.上下文拼接法
- B.交叉注意力法
- C.自适应归一化
- D.自适应零起始法← 正确答案
答案:D。DiT论文通过消融实验证明AdaLN-Zero(自适应零起始法)最优。它让门控从零开始学习,训练更稳定且生成质量最高。上下文拼接和交叉注意力也有一定效果但不如AdaLN系列,因此选D。
Q3. AdaLN-Zero中新增门控因子的初值为?
- A.设置为数值零← 正确答案
- B.设置为随机值
- C.设置为固定一
- D.设置为负一值
答案:A。AdaLN-Zero的核心创新在于将γ初始化为0,使每个DiT块从恒等映射开始训练,先学习主流程再加入条件调制。若初始化为1或随机值,就退化为普通AdaLN,失去了稳定训练的优势。
Q4. DiT用哪种架构取代了U-Net?
- A.循环神经网络
- B.卷积神经网络
- C.视觉Transformer← 正确答案
- D.自编码网络
答案:C。DiT的全称是Diffusion Transformer,核心工作就是把扩散模型中的U-Net主干替换为视觉Transformer(ViT)。RNN适合序列数据,CNN是旧主干的代表,自编码网络与生成主干无关,因此选C。
Q5. DiT的Patch嵌入主要靠什么实现?
- A.全连接层
- B.卷积操作← 正确答案
- C.注意力层
- D.池化操作
答案:B。PatchEmbed在实践中通常用卷积层实现,卷积核大小和步长都设为patch size,一次性完成“切块+投影”。全连接层需要先手动切块再逐块映射,效率较低;注意力层和池化层都不是嵌入的标准实现。
Q6. 相比U-Net,DiT的优势包括哪些?
- A.全局依赖建模← 正确答案
- B.算力缩放友好← 正确答案
- C.局部纹理细节
- D.归纳偏置更强
答案:AB。DiT的注意力机制能直接建模任意两个token之间的关系,全局依赖能力强;实验证明其FID随计算量增加持续下降,缩放友好。局部纹理细节和强归纳偏置恰恰是CNN(U-Net)的传统优势,而非DiT的强项。
Q7. Sora用DiT生成视频的关键步骤是?
- A.时空Patch化← 正确答案
- B.视觉压缩← 正确答案
- C.长短时记忆
- D.大规模训练← 正确答案
答案:ABD。Sora先将视频压缩到潜空间,再沿时间和空间轴切出时空patch,最后用DiT在大规模数据上训练生成模型。长短时记忆(LSTM)是RNN时代的时序建模方法,并非Sora的关键步骤。
Q8. DiT缩放规律揭示FID随计算量如何变化?
- A.线性下降
- B.幂律下降← 正确答案
- C.周期波动
- D.持续上升
答案:B。DiT论文的缩放实验显示,FID随总计算量增加按幂律下降(FID = a·C^(-α) + b),即先快速改善后逐渐饱和。不是简单的线性下降,更不是波动或上升,因此选幂律下降。
Q9. 下面哪项不属于DiT的条件注入方式?
- A.上下文拼接
- B.交叉注意力
- C.自适应归一化
- D.权重初始化← 正确答案
答案:D。DiT论文研究的四种条件注入方式是In-context(上下文拼接)、Cross-Attention(交叉注意力)、AdaLN(自适应归一化)和AdaLN-Zero。权重初始化是训练策略,不是把条件信息注入模型的方式,因此选D。
Q10. 关于DiT架构,下列描述正确的有?
- A.包含注意力模块← 正确答案
- B.包含前馈网络← 正确答案
- C.包含层归一化← 正确答案
- D.必须含卷积编码
答案:ABC。DiTBlock由层归一化、多头自注意力和前馈网络组成,A、B、C都正确。虽然PatchEmbed常用卷积实现,但并非必须——用全连接层或未来更高效的算子也可以完成嵌入,所以D过于绝对。