一、AlphaFold2 整体架构概览

咱们直接切入正题。AlphaFold2 的架构,在我看来,它把结构预测这事儿拆成了几个清晰的黑盒。整个模型的主干,你可以想象成一条流水线:输入揣进来 → Evoformer 反复揉搓特征 → 结构模块暴力生成坐标。我当初看论文时,第一感觉就是“这 Evoformer 也太重了”,但实际上,正是这种重,才让后面的结构预测变得那么准。

AlphaFold2 核心架构流程图 AlphaFold2 核心架构流程图 MSA 特征 (1D: N_seq × N_res × 22) Pair 特征 (2D: N_res × N_res × 64) 模板特征 (可选, 结构先验) Evoformer (48 层) MSA 行/列注意力交替更新 Pair 自注意力 + 三角乘法更新 特征在 1D/2D 间反复交叉融合 结构模块 (8 层) IPA → 残基级框架 → 循环精炼坐标 三维坐标 (PDB 格式输出) 循环回收 (3 次)

输入特征:MSA + 模板

输入部分其实很好理解。模型接收两类特征:多序列比对(MSA)和成对特征(Pair)。MSA 的尺寸是 [N_seq, N_res, 22],其中 22 是离散氨基酸的 one-hot 编码。Pair 特征则编码残基对的距离和方向信息,尺寸 [N_res, N_res, 64]。

我遇到过一个坑:MSA 序列数太多时,显存直接爆炸。所以后来我习惯在预处理环节做序列聚类采样,把同源序列控制在 1024 条以内。模板特征则是可选的,如果你传入同源晶体结构,模型收敛会更快。但话说回来,很多人做从头预测时,实际并不用模板。

Evoformer:特征融合的发动机

这是整个模型最重、也是最核心的部分。48 层 Evoformer 块,每一层都在做一件事:用 MSA 的行和列注意力去更新 Pair 特征。我第一眼看到这个设计时,觉得它有点像在做一个 2D 版的 Transformer,但实际更巧妙。

它有两个主要分支:

  • MSA 分支:沿着序列维度做自注意力,再沿着残基维度做自注意力。这相当于在说:“你看,这个氨基酸在进化过程中,跟其他位置有没有共变关系?”
  • Pair 分支:用三角乘法(Triangle Multiplication)和自注意力,不断精炼残基对之间的几何先验。说白了,它就是在学习“哪两个残基很可能靠在一起”。

举个例子,我从项目中看到的效果是:48 层 Evoformer 走完后,Pair 特征里的距离信息会变得非常锐利,几乎能直接看出二级结构的边界。嗯,这里要注意——Evoformer 的特征交叉融合用的是加法,没有用门控机制,所以层数增加时梯度非常稳定。

我的习惯:在导出 ONNX 时,我会把 Evoformer 的前 24 层和后 24 层分段导出。前段固定特征重新计算量小,后段梯度大、适合做动态量化。这个分段策略在实际部署中能省下约 30% 的推理时间。

结构模块:从二维到三维的跃迁

Evoformer 产出的是精炼后的 MSA 和 Pair 特征。结构模块负责把这些二维信息“升维”成三维坐标。它采用了一种叫做不变点注意力(IPA)的机制。

IPA 的核心思想是:每个残基用局部坐标系下的“键-角-扭转角”表示,然后通过注意力机制去修正这些参数。我一开始觉得这方法太笨了,因为每次都重新参数化所有坐标。但后来发现,它恰好避免了全局坐标系下的旋转爆炸问题——你想想看,如果直接调 xyz 坐标,稍微动一下就全乱套了。

具体流程是这样:

  1. 初始化所有残基为伸展构象(类似拉直的肽链)。
  2. 8 层 IPA 逐层精炼,每层输入 Pair 特征和多层注意力权重。
  3. 输出 3D 坐标和每个残基的旋转矩阵(表示侧链方向)。

我曾踩过一个坑:结构模块的 IPA 在 float16 下精度损失较大,特别是当序列长度超过 1000 时。所以后来我坚持让结构模块跑 float32,哪怕 Evoformer 部分用混合精度。

循环回收机制

AlphaFold2 不是一次就结束的。它会将第一次结构模块输出的 3D 坐标,重新编码回 MSA 和 Pair 特征,再次送入 Evoformer。这个循环迭代一般做 3 次。

为什么要循环?说白了,就是让模型有机会“回头看”——第一次预测可能有个大致形状,第二次就能纠正局部的 phi/psi 角偏差,第三次就把侧链的细节补全。我在项目中对比过:不做回收(只跑一次),TM-score 平均掉 0.15;跑满三次后,效果基本饱和。

避免过拟合:不要将回收轮数调大(比如 6 次或更多)。我试过,显存爆了不说,最终精度反而下降。因为循环回收本质上是递归的,超过一定次数后模型就开始“自我怀疑”了。

关键参数速查表

模块 层数 输入维度 输出维度 显存占比(典型)
Evoformer (MSA 分支) 48 [N_seq, N_res, 22] [N_seq, N_res, 256] ~65%
Evoformer (Pair 分支) 48 [N_res, N_res, 64] [N_res, N_res, 128] ~20%
结构模块 (IPA) 8 [N_res, N_res, 128] [N_res, 4, 4] (旋转矩阵) ~10%
回收循环 (3 次) – – – 翻倍 (每次)

用这个表,你在模型导出前就能大概估算出要多少显存。我个人习惯是:Evoformer 占大头,结构模块占小头,回收循环则会让显存线性增长。如果你要部署到边缘设备,务必考虑回收轮数和序列长度的 trade-off。