跳转至

附录 A 从 ResNet 到 CLIP:你已经会的组件在 LLM 里的位置

这一篇的任务:把你在视觉领域已经掌握的模块,一个一个对应到本书正文的章节上。读完你会发现,第 2 到第 8 章里没有一个组件是凭空出现的——它们中的大多数你训练 ResNet 和 ViT 的时候就用过,只是换了名字和位置。

这一篇也负责一件同样重要的事:指出你的视觉训练直觉会在哪里失效(A.7)。那些地方比相似之处更值得花时间。

A.1 先说结论:架构的差异比你想的小,配方的差异比你想的大

把 ResNet-50 和一个 8B 语言模型并排放,你会以为它们毫无关系。但如果逐个拆零件:

零件 视觉里的形态 LLM 里的形态 本书章节
残差连接 ResNet 的 skip connection 残差流(residual stream) 第 2 章
归一化 BatchNorm RMSNorm 第 5 章
归一化位置 ResNet v2 的 pre-activation Pre-LN 第 5 章
升维再降维的非线性块 bottleneck 的 1×1 → 3×3 → 1×1 FFN 的 d → 4d → d 第 2 章
把图/文切成单元 ViT 的 patch embedding tokenizer + token embedding 第 1、2 章
位置信息 ViT 的可学习绝对位置嵌入 RoPE 第 6 章
局部感受野 Swin 的窗口注意力 滑动窗口注意力 第 11 章
全局交互 ViT 的全局自注意力 因果自注意力 第 2 章
跨模态交互 DETR / CLIP 的 cross-attention 与双塔 多模态连接器 附录 G

真正把两边区分开的不是这张表,而是训练配方:数据量与参数量的比例、epoch 数、正则化策略、精度、以及"只有一次机会"这个约束。A.7 专门讲这件事。

A.2 ResNet:残差流这个概念是它给的

ResNet(He et al., 2015, arXiv:1512.03385)解决的问题是:网络加深到一定程度后,训练误差反而上升——不是过拟合,是优化不动了。它的答案是让每个块学残差 y = x + F(x),而不是直接学 y = H(x)。

这个结构被 Transformer 原封不动地拿走了。现代 LLM 里的说法叫残差流:贯穿所有层的那条主干 x,每一层(注意力、FFN)把自己的输出加回主干。两点值得注意:

  • 主干的维度从头到尾不变(就是 d_model)。所有层都在往同一条流上读写,这是后来很多可解释性工作的出发点。
  • 加法而非替换,意味着任何一层都可以学成近似恒等。这是深层网络能训起来的物理原因,在 ResNet 和 Transformer 里是同一个原因。

bottleneck 结构也搬过来了。ResNet 的 1×1 降维 → 3×3 卷积 → 1×1 升维,和 Transformer FFN 的 d → 4d → d 是同一类设计:在一个与主干不同的维度里做非线性变换,再投影回来。区别只是 FFN 是先升后降、卷积是先降后升,以及 FFN 用 SwiGLU 把中间层拆成了门控与值两支(第 5 章)。

2026 年的一个转折:残差连接沿用了十年没变,但这一年两个前沿模型同时动了它——Kimi K3 的 Attention Residuals 和 DeepSeek-V4 的 Manifold-Constrained Hyper-Connections。详见附录 D.5。你在这里建立的"残差流"直觉,正好是理解那些改动的前提。

A.3 ResNet v2 与 Pre-LN:同一个发现,隔了两年在两个领域各发生一次

原始 ResNet 的块是 conv → BN → ReLU,残差加完之后再过激活。何恺明团队第二年做了一个看似很小的改动(arXiv:1603.05027):把 BN 和 ReLU 提到卷积前面(pre-activation),让残差路径变成一条纯粹的恒等通路。结果是 1000 层的网络可以训练了。

Transformer 那边发生了一模一样的事。原始 Transformer(2017)是 Post-LN:x + Sublayer(x) 然后再 LayerNorm。这个结构在深层时需要精心设计的学习率 warmup 才能不发散。GPT-2(2019)改成 Pre-LN:x + Sublayer(LN(x)),残差主干上不再有归一化,梯度可以一路直通。

这是同一个原理的两次独立发现:残差主干上不要放任何会缩放信号的操作。 如果你当年理解了 pre-activation ResNet 为什么更好训,第 5 章的 Pre-LN 你已经懂了。

现代模型在此之上还有一层变化:部分模型(Gemma 2、Qwen 系列的一些配置)在子层输出上再加一个归一化,形成 x + Norm(Sublayer(Norm(x))) 的"三明治"结构。目的是控制残差流的数值随深度累积增长。这同样在视觉里有对应物(各种 LayerScale / ReZero 的变体)。

A.4 BatchNorm 为什么进不了 LLM

这是视觉工程师最常问的问题之一,答案有四条,每一条单独都足以判死刑:

  1. 依赖 batch 统计量。推理时 batch 常常等于 1(decode 阶段逐 token 生成),BN 必须切换到滑动平均统计量,训练与推理行为不一致。语言模型对这种不一致更敏感。
  2. 序列长度可变。BN 要在 batch 和空间维度上求统计量;序列是变长的,加上因果掩码后每个位置可见的历史还不一样,"在哪个维度上归一化"这个问题没有好答案。
  3. 因果性会被破坏。在序列维度上求统计量意味着当前 token 能看到未来 token 的信息,直接违反自回归约束。
  4. 分布式训练要同步。BN 的统计量跨数据并行需要通信(SyncBN),在几千卡规模上这是不能接受的额外开销。

于是 LLM 走了 LayerNorm(Ba et al., 2016):只在特征维度上归一化,与 batch 和序列长度完全无关,每个 token 独立计算。再往后是 RMSNorm(Zhang & Sennrich, 2019):连均值中心化都去掉,只除以均方根,x / RMS(x) * g。省掉一次求均值和一次减法,效果基本不变,现在是事实标准(第 5.2 节)。

顺带回答另一个常见疑问:LLM 里为什么没有 BN 那种"自带正则化效果"的东西?因为预训练阶段基本不需要正则化——见 A.7。

A.5 ViT:你其实已经训过 Transformer 了

ViT(arXiv:2010.11929)的贡献是证明了一件事:把图像切成 16×16 的 patch,每个 patch 线性投影成一个向量,然后原封不动地喂进 NLP 那套 Transformer encoder,在足够数据下能打败 CNN。

这意味着你训 ViT 的时候,已经在训 Transformer 了。对照如下:

ViT LLM 差别在哪
patch embedding(线性投影) token embedding(查表) 图像是连续的所以用投影,文本是离散的所以用查表
固定 196 个 patch 变长 token 序列 LLM 必须处理变长,这带来 padding、packing、掩码一系列问题(第二册)
可学习绝对位置嵌入 RoPE 见下
双向自注意力 因果自注意力 ViT 每个 patch 看全图,LLM 每个 token 只能看左边(第 2.3 节)
CLS token 做分类 最后一个位置的 logits 做预测 任务头不同,主干相同
Post-LN → Pre-LN 的迁移 同样的迁移 见 A.3

最值得你花时间的差别是位置编码。 ViT 的可学习绝对位置嵌入有个硬伤:训练时是 196 个位置,推理时换分辨率就得插值。LLM 面对的是同一个问题的极端版本——训练时几千,部署时常要长得多。第 6 章讲的是 RoPE 怎样把相对距离写进注意力;超长时的显存和质量,在第 7、11 章。这也是为什么位置这套东西在视觉里没有同等分量。

另一个值得注意的对应是 Swin。 Swin Transformer(arXiv:2103.14030)为了把注意力的平方复杂度降下来,用了窗口内注意力 + 移位窗口。LLM 这边的滑动窗口注意力(Mistral、Gemma、gpt-oss)是同一个想法在一维上的版本,连"局部窗口必须配上某种全局通路"这个结论都一样——Swin 靠移位窗口跨窗传信息,LLM 靠在若干层里插入全注意力层(第 12、14 章)。

A.6 CLIP 与 SigLIP:它们今天的身份是"多模态大模型的眼睛"

CLIP(arXiv:2103.00020)本身是双塔对比学习:图像塔(ViT)和文本塔(一个小 Transformer)各自编码,在共享空间里拉近正样本、推远负样本,温度参数可学习。

对本书读者,CLIP 有三层意义:

  1. 它的文本塔就是一个标准的 Transformer 解码器结构(带因果掩码,取最后一个 token 的表示)。你读它的代码时看到的东西,第 2 章会逐行讲。
  2. 它的图像塔是今天几乎所有多模态大模型的视觉编码器的祖先。LLaVA 用 CLIP ViT,后来主流换成 SigLIP(arXiv:2303.15343,把 softmax 对比损失换成逐对 sigmoid,去掉了对全局负样本 all-gather 的依赖,因此更好扩展)。接法见附录 G。
  3. 它演示了"用海量弱标注数据做对比预训练"这个范式,和语言模型"用海量文本做 next-token 预训练"是同一个时代精神的两个分支。

A.7 你的视觉训练直觉会在这些地方失效

这一节比前面所有内容都重要。相似之处会自己浮现,不同之处不会,它们会以"我的实验结果很奇怪"的形式出现。

你的习惯 LLM 预训练的实际做法 为什么
训练 100–300 epoch 约 1 epoch,甚至不到 数据量远大于模型容量,重复看数据收益很低且会加剧记忆化
数据增强是标配 基本没有等价物 文本没有"不改变语义的扰动"这种廉价操作;对应的工作变成了数据配比、去重、质量过滤(第二、三册)
Dropout 0.1–0.5 预训练阶段通常关掉 单次遍历数据、模型远未过拟合,Dropout 只会拖慢收敛。后训练在小数据上微调时它才回来
BatchNorm RMSNorm 见 A.4
weight decay 给所有参数 只给矩阵参数,norm 的权重、bias、embedding 通常排除 对一维参数做衰减会直接改变归一化的尺度行为
看验证集早停 没有早停,按预算训完 验证 loss 单调下降,几乎不会转折;真正要看的是下游评测和训练稳定性
不行就重训 只有一次机会 一次预训练是千卡月级别的开销,所以超参必须靠小模型外推(附录 F 的 muP)
混合精度 = amp + fp32 权重 bf16 计算 + fp32 主权重,前沿模型已经在用 FP8 甚至 FP4 存专家 规模逼出来的,细节在第二册
过拟合是主要敌人 训练不稳定(loss 尖峰、发散)是主要敌人 第 5 章大半章在讲这个
模型大小由显存决定 模型大小由"训练预算 + 部署成本"共同决定 Chinchilla 与它后来的修正,见附录 B.5 和 C.1

如果只能记住一条:视觉里你在和过拟合搏斗,LLM 预训练里你在和不稳定与成本搏斗。 这条差异解释了本书为什么把整整一章(第 5 章)给了归一化和激活函数这些看起来很基础的东西。

A.8 ConvNeXt 给的一个方法论

ConvNeXt(arXiv:2201.03545)做的事是:拿一个标准 ResNet,按 Swin Transformer 的配方逐项改造——换宏观阶段比例、换大卷积核、换 GELU、换 LN、减少归一化层数量、用 AdamW 和更长的训练——最后纯卷积网络追平了 Transformer。

对读这本书的人,这个实验的价值在于它划清了一条界线:很多时候被归因于"新架构"的收益,其实来自随新架构一起引进的训练配方。所以后面三篇附录在拆解每个模型时,都会尽量分开写两件事:

  • 它改了计算图(新的注意力形式、新的路由、新的残差结构)——这是第一册的内容;
  • 它改了训练配方(数据量、优化器、精度、调度)——这是第二册的内容。

厂商的技术报告通常把两者混在一起报告收益。读报告时主动拆开,是判断一个新方法值不值得跟的基本功。


核心问答

Q1:我完全没做过 NLP,直接从第 2 章开始读会不会缺东西? 不会缺架构上的东西。真正需要补的只有 tokenizer(第 1 章讲)和"自回归生成"这个推理形态(第 1、4 章讲)。注意力、残差、归一化、FFN 你都熟。

Q2:既然 ViT 就是 Transformer,我能不能把视觉里的调参经验直接搬过来? 架构级的经验可以(比如 Pre-LN 更好训、加深比加宽更省参数)。训练配方级的经验基本不能搬,A.7 那张表就是清单。最容易出事的是 epoch 数、Dropout 和 weight decay 的作用范围。

Q3:为什么 LLM 不用 BatchNorm,而扩散模型里还能看到 GroupNorm? 因为扩散模型的输入是定长的特征图,没有因果约束,batch 内也不需要跨位置对齐。约束不同,选择就不同。判断标准始终是 A.4 那四条。

Q4:CLIP 这种双塔结构在语言模型里还有对应物吗? 有,在检索侧。RAG 的向量检索器就是双塔对比学习训出来的(第三册)。但生成主干是单塔解码器,这点没变。

Q5:我该按什么顺序读这四篇附录? A 读完就可以直接进正文。B、C、D 三篇建议在读完对应正文章节之后再读——比如读完第 9 章 MoE 再去看 C.2 的 Mixtral 和 C.6 的 DeepSeek-V3,那时候配置表上的每个数字才有意义。