4. MSA在AlphaFold中的作用

讲MSA多样性之前,得先把MSA在AlphaFold里到底干了些啥说清楚。我接触过不少同学,一上来就调MSA参数,结果模型怎么崩的都不知道。说白了,没搞懂MSA在模型里的角色,后面所有优化都是瞎忙活。

一句话总结:MSA是AlphaFold从进化历史中“偷师”的工具。它告诉模型——哪些位置必须保守,哪些位置可以随意变。

4.1 MSA到底承载了什么信息?

蛋白质序列不是随机写出来的。同源序列在进化中保留的痕迹,其实就是结构约束的铁证。你想想看,如果某个位点在所有同源蛋白里都是甘氨酸,那这个位置大概率在局部折叠里扮演特殊角色——可能是转角,可能空间太小容不下侧链。

MSA提供的核心信息,我归纳为三类:

  1. 共进化信号——两个位点同时发生突变的模式。A变B也跟着变,说明它们可能在空间上挨着。
  2. 保守性模式——哪些位置雷打不动,哪些位置随便换。保守位置通常是功能或结构核心。
  3. 插入/缺失模式——哪些区域允许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条,进化距离拉得开,共进化信号就清晰得多。

避坑提醒:别以为MSA深度越大越好。我遇到过一种情况——把阈值设太低,搜回来一堆低质量序列。结果MSA是深了,但噪声淹没了信号,预测的pLDDT反而跌了。

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轮,每轮加宽搜索。但实际项目中我建议:先看第一条序列属于什么蛋白家族。如果是激酶这类大家族,保守序列多,多样性好;如果是孤儿蛋白,得主动去扩张搜索范围。

实操技巧:在AlphaFold配置里修改max_hit参数。默认值可能只返回5000条序列,但如果你用Jackhmmer的--incE参数设到0.001以下,有些远缘同源能挖出来。当然,得结合计算资源权衡。

我曾经遇到过一个案例——预测一个细菌效应蛋白。标准UniRef90搜回来不到30条序列,多样性很差。后来扩展到MGnify和JGI的宏基因组数据库,序列数到了3000多条,其中包含一些土壤宏基因组里非常远的同源。结果从pLDDT 65直接拉到82。这就是多样性的威力。

4.5 一张图看懂MSA在AlphaFold中的角色

MSA在AlphaFold中的信息流 输入序列 同源序列搜索(Jackhmmer等) MSA堆叠 MSA Representation Pair Representation Evoformer 信息交换 结构模块(IPA) 预测结构 MSA多样性关键点 • 进化距离越远越好 • 覆盖不同物种分支 • 避免近缘序列过度采样

4.6 实际项目中怎么判断MSA够不够好?

说了这么多理论,来点实在的。我自己在项目里有一套快速评估流程:

  1. 看深度——有效序列(去gap后覆盖>70%)有没有至少100条。不够就扩库。
  2. 看多样性——计算我说的那个diversity score。低于0.3就得警惕,低于0.1基本是废的。
  3. 看覆盖度——MSA的列覆盖是不是均匀。如果有些区域全是gap,说明那块同源性极低,模型容易出错。
  4. 跑一次试预测——pLDDT如果区域之间有断崖式变化,多半是MSA在那个区域没提供约束。
我的经验:有不少时候,你觉得模型出了错,其实不是AlphaFold的问题,是MSA没喂好。先回去检查MSA,再调模型参数。这个顺序别搞反。

好了,关于MSA在AlphaFold中的作用就聊到这儿。把这些搞明白,你再看后面的MSA多样性优化策略时,就知道每一步是在改什么了。