4. MSA在AlphaFold中的作用
讲MSA多样性之前,得先把MSA在AlphaFold里到底干了些啥说清楚。我接触过不少同学,一上来就调MSA参数,结果模型怎么崩的都不知道。说白了,没搞懂MSA在模型里的角色,后面所有优化都是瞎忙活。
4.1 MSA到底承载了什么信息?
蛋白质序列不是随机写出来的。同源序列在进化中保留的痕迹,其实就是结构约束的铁证。你想想看,如果某个位点在所有同源蛋白里都是甘氨酸,那这个位置大概率在局部折叠里扮演特殊角色——可能是转角,可能空间太小容不下侧链。
MSA提供的核心信息,我归纳为三类:
- 共进化信号——两个位点同时发生突变的模式。A变B也跟着变,说明它们可能在空间上挨着。
- 保守性模式——哪些位置雷打不动,哪些位置随便换。保守位置通常是功能或结构核心。
- 插入/缺失模式——哪些区域允许gap,哪些区域必须连续。这直接暗示loop区域和核心二级结构的分界。
说实话,以前做传统蛋白质结构预测时,这些信号要手动提取,费时费力。AlphaFold用attention机制自己学,省了大事。
4.2 AlphaFold是怎么“消化”MSA的?
模型里有两个核心模块在吃MSA:Evoformer和结构模块。Evoformer里又分两条道——MSA representation和Pair representation。
- MSA representation:直接存每条序列的每个位置的信息。维度是 [N_seq, N_res, c_m]。
- Pair representation:存每对残基之间的关系。维度是 [N_res, N_res, c_z]。
这两条道之间不停做信息交换。MSA道的attention可以捕捉不同序列间的共进化模式,Pair道的attention可以捕捉残基对间的空间约束。具体来说:
# MSA到Pair的通信(简化伪代码)
# 从MSA的行attention里提取"残基对"的关系
for each pair (i, j):
pair_ij += outer_product(msa_row_i, msa_row_j)
# 反过来,Pair也影响MSA的更新
# 用pair信息做bias,引导MSA的attention聚焦
这么做的好处是——进化信息和空间信息互相强化。我早年做传统接触图预测时,只用了MSA的共进化信号,效果远不如AlphaFold这种端到端的交互方式。
| 信息流方向 | 作用 | 实际效果 |
|---|---|---|
| MSA → Pair | 用共进化信号更新残基对特征 | 让Pair representation带上进化约束 |
| Pair → MSA | 用空间约束bias MSA的attention | 防止MSA attention被噪声带偏 |
| MSA内部 | 行/列attention捕捉序列和残基关系 | 直接学习共进化模式和保守性 |
4.3 为什么MSA多样性这么关键?
好,到了重点。MSA多样性指的是——你输入的同源序列覆盖了多少进化分支,以及序列之间差异有多大。
我个人习惯把MSA多样性想成一个“采样问题”。你采样了100条同源序列,但如果它们全是同一物种的最近旁系同源,那进化信息量很小。反之,如果你从细菌、古菌、真核生物各拿了30条,进化距离拉得开,共进化信号就清晰得多。
AlphaFold的Evoformer对MSA多样性非常敏感。实验里可以看到:
- 高多样性MSA:attention map里共进化模式清晰,残基对之间的约束明确。
- 低多样性MSA(全是近缘序列):attention几乎平均分布,模型得不到有效约束,预测结果接近“暴力模板匹配”。
- 极低多样性(甚至单序列):模型退化到靠物理势和语言模型硬撑,精度断崖式下跌。
# 实际项目中评估MSA多样性的代码片段(Python)
import numpy as np
def msa_diversity_score(msa_seqs, ref_seq_idx=0):
"""
评估MSA的序列多样性。
越接近1说明多样性越高,越接近0说明都是近缘序列。
"""
seqs = [s for i, s in enumerate(msa_seqs) if i != ref_seq_idx]
if len(seqs) == 0:
return 0.0
ref = msa_seqs[ref_seq_idx]
identities = []
for s in seqs:
matches = sum(1 for a, b in zip(ref, s) if a == b and a != '-')
aligned = sum(1 for a, b in zip(ref, s) if a != '-' or b != '-')
identities.append(matches / max(aligned, 1))
# 多样性和平均序列一致性成反比
mean_id = np.mean(identities)
return 1.0 - mean_id
4.4 不同MSA构建策略带来的差异
这里有个很实际的对比。我在测试不同数据库构建的MSA时,发现结果差距非常大。
| MSA构建方式 | 多样性 | 对AlphaFold影响 | 典型场景 |
|---|---|---|---|
| 仅用Jackhmmer搜索UniRef90 | 中等 | 够用,但遇到孤儿蛋白就崩 | 常规结构预测 |
| UniRef90 + MGnify + 环境宏基因组 | 高 | 覆盖深,孤儿蛋白也能找到微弱同源 | 困难目标 |
| 自定义加权MSA(去冗余+多样性重采样) | 可控 | 性能最稳定,避免噪声 | 工程化部署 |
| 单序列(无MSA) | 无 | 仅靠ESM/TrippeNet,精度下降10%+ | 快速扫描 |
嗯,这里要注意——AlphaFold官方推荐的做法是先用Jackhmmer跑5轮,每轮加宽搜索。但实际项目中我建议:先看第一条序列属于什么蛋白家族。如果是激酶这类大家族,保守序列多,多样性好;如果是孤儿蛋白,得主动去扩张搜索范围。
我曾经遇到过一个案例——预测一个细菌效应蛋白。标准UniRef90搜回来不到30条序列,多样性很差。后来扩展到MGnify和JGI的宏基因组数据库,序列数到了3000多条,其中包含一些土壤宏基因组里非常远的同源。结果从pLDDT 65直接拉到82。这就是多样性的威力。
4.5 一张图看懂MSA在AlphaFold中的角色
4.6 实际项目中怎么判断MSA够不够好?
说了这么多理论,来点实在的。我自己在项目里有一套快速评估流程:
- 看深度——有效序列(去gap后覆盖>70%)有没有至少100条。不够就扩库。
- 看多样性——计算我说的那个diversity score。低于0.3就得警惕,低于0.1基本是废的。
- 看覆盖度——MSA的列覆盖是不是均匀。如果有些区域全是gap,说明那块同源性极低,模型容易出错。
- 跑一次试预测——pLDDT如果区域之间有断崖式变化,多半是MSA在那个区域没提供约束。
好了,关于MSA在AlphaFold中的作用就聊到这儿。把这些搞明白,你再看后面的MSA多样性优化策略时,就知道每一步是在改什么了。