在生物信息学与 AI for Science 的交叉领域,蛋白突变效应预测一直是个“看起来简单、做起来头疼”的方向。过去几年,大量基于深度学习的方法被提出来,从传统的进化保守性打分到后来的蛋白语言模型,大家都声称自己在公开数据集上取得了不错的效果。但真正落到实际使用时,问题立刻浮现:不同论文用的数据集不统一,评测指标的选取多种多样,有的用 Spearman 相关系数,有的用 AUC,基准版本也各不相同,导致横向对比几乎无法进行。
最近,哈佛大学团队提出的 PG-LLM 评测基准,正是冲着这个痛点来的。它号称是“首个面向 LLM 的蛋白突变排序标准化评测基准”,一次性测评了 13 款主流大语言模型和 95 种专业蛋白模型。这个工作对做蛋白设计、变异致病性分析、酶工程改造的开发者来说,意义很大。本文将围绕 PG-LLM 的设计思路、评测任务、模型表现与可复现实验展开,帮助你把这套评测思维迁移到自己的项目中。
1. 为什么需要蛋白突变排序基准
1.1 先理解蛋白突变排序是什么
蛋白质由氨基酸序列组成,每个位点的氨基酸一旦发生改变,就可能影响蛋白质的结构、稳定性、相互作用甚至生物学功能。蛋白突变排序(Variant Effect Prediction)要解决的问题是:给定一个蛋白的野生型序列,再给定一个或多个突变体,如何预测这些突变对蛋白功能的影响,并按影响程度从高到低排序。
这个任务在现实中有非常直接的应用场景:
- 罕见遗传病的致病性分析:某个基因上的单核苷酸变异是否导致疾病。
- 酶工程改造:在工业酶中引入若干突变,哪些组合能提升催化活性或热稳定性。
- 抗体人源化与亲和力成熟:筛选更优的突变体。
- 病毒进化监测:评估新出现的突变株是否可能逃逸中和抗体。
如果排序结果准确,能极大减少湿实验的筛选成本;如果排序结果不可靠,后续实验就是浪费时间和经费。
1.2 为什么排序质量难以衡量
你可能会觉得,预测突变影响不就是训练一个分类模型吗?实际上远没有这么简单。
第一,深度突变扫描(Deep Mutational Scanning, DMS)数据虽然比以前多了,但覆盖的蛋白数量仍然有限,数据分布很不均匀。有的蛋白覆盖了数千个突变,有的蛋白只有几十个突变。
第二,不同研究团队构建数据集时使用的参考序列版本、突变格式、功能标签阈值都不一样,直接把多个数据集拼在一起很容易引入偏差。
第三,评估指标的选择会直接影响结论。如果只看“预测值与实验值的斯皮尔曼相关系数”,模型会偏好校准较好的打分;如果看“Top-K 突变体召回率”,模型又会倾向另一种分布。没有统一指标,模型之间的比较就像“盲人摸象”。
1.3 LLM 凭什么参与蛋白突变排序
大语言模型(LLM)在自然语言处理任务中展示了极强的序列建模能力。蛋白序列本身由 20 种氨基酸字母组成,恰好可以被视为一种“生物语言”。因此,研究者自然想到:能不能把蛋白序列当作文本,用类似训练 GPT 或 BERT 的方式做预训练,再用这些模型来预测突变效应?
这类模型通常被称为蛋白语言模型(Protein Language Model, pLM),典型代表如 ESM、ProtTrans、ProGen 等。它们通过在数百万条天然蛋白序列上进行掩码语言建模或自回归建模,学习到了蛋白质序列的进化规律与结构约束。
通用 LLM(如 GPT-4、Claude、Llama 等)则更进一步,不仅能理解序列,还能结合文献知识、功能注释等文本信息进行推理。于是问题来了:通用 LLM 与专业蛋白模型放到同一个评测框架下,究竟谁更擅长排序蛋白突变?
在 PG-LLM 出现之前,没有一个标准化基准能回答这个问题。这也是该工作的核心价值所在。
2. PG-LLM 评测基准的核心设计
2.1 评测对象:13 款主流模型 + 95 种专业模型
PG-LLM 的设计思路非常直接:把所有候选模型放到同一批任务、同一套指标、同一种数据划分方式下进行评测。
评测对象分为两大阵营:
| 阵营 | 代表模型 | 特点 |
|---|---|---|
| 通用大语言模型 | GPT-4、Claude、Llama 系列等 | 参数量大,训练数据包含文本与代码,拥有推理能力 |
| 蛋白专业模型 | ESM 系列、ProtTrans、ProGen 等 | 在蛋白序列上预训练,任务专一,适合序列打分 |
严格来说,95 种专业模型里面,除了基于 Transformer 的蛋白语言模型,还包括大量传统方法,比如基于进化保守性打分的方法、基于结构能量函数的工具等。PG-LLM 把它们全部统一到同一套评测标准下,相当于给整个领域做了一次“期末考试”。
2.2 数据与任务设计
这里需要特别注意一点:PG-LLM 不是简单地把已知的 DMS 数据集合并起来然后跑一遍模型。
它的数据设计有几个明显的诉求:
- 覆盖足够多的蛋白家族与突变类型,避免模型在某一类蛋白上“偏科”。
- 使用严格的数据划分,确保训练集、验证集、测试集之间没有序列泄露。
- 突变排序任务不仅包括单点突变,还包括部分多点组合突变。
从中可以看到,PG-LLM 把“标准化评测”落实到了数据层面,而不是仅仅在评测指标层面做统一。
2.3 标准化指标
评测指标方面,PG-LLM 使用了多个互补的指标:
- 斯皮尔曼相关系数(Spearman's ρ):衡量预测排序与实验排序的单调一致性。
- 肯德尔 tau 系数(Kendall's τ):另一种排序相关性指标,对局部顺序变化更敏感。
- 归一化折损累计增益(NDCG@K):评估前 K 个高风险或高功能突变是否被正确排在前面。
- 部分场景下的 AUC:用于二分类问题,如“致病/不致病”。
这类多指标设计比较合理,因为单一指标容易被模型在某个维度上的强势表现所掩盖。排序任务尤其要关注 NDCG@K,因为实际实验中科学家往往只关心排名最靠前的一小批突变。
2.4 评测协议与可复现性
一个评测基准要真正被社区接受,除了指标合理,还需要把评测流程开源出来。PG-LLM 相关的核心在于评测协议的可复现性:
- 所有模型的输入输出格式统一。
- 所有数据集的预处理脚本统一。
- 所有评测脚本的随机种子固定。
- 每次评测记录详细的模型版本与超参数。
这套协议对后续同类工作很有参考价值。很多团队在做自己的模型评测时,往往忽略统一输入格式这个问题,导致不同模型之间对比时很难说清楚差异究竟是来自模型能力还是数据预处理。
3. 13 款主流大模型与 95 种专业模型的横向对比
3.1 通用大语言模型:表现有惊喜也有瓶颈
评测结果显示,通用大语言模型在零样本或少样本场景下,已经具备一定的蛋白突变排序能力。这是因为它们通过大规模文本训练,掌握了大量生物学知识,能够理解“某个突变发生在保守位点”这类隐含信息。
但通用 LLM 在排序任务上也有明显瓶颈:
- 输出不稳定。同一个 prompt 重复运行多次,结果可能存在波动。
- 打分尺度不统一。不同模型对不同蛋白的分数分布差异较大。
- 对长序列的上下文理解有限。蛋白序列通常有几百甚至上千个氨基酸,直接塞进 LLM 的 token 上下文会有截断问题。
- 计算成本高。对比专业蛋白模型,通用 LLM 的推理开销大得多。
3.2 专业蛋白模型:依然是排序任务的主力
在 PG-LLM 的整体评测中,专业蛋白模型仍然表现出较强的竞争力。这类模型直接在蛋白序列上预训练,输出的对数似然或掩码预测置信度天然适合做突变打分。
不过,专业模型之间也存在明显差异:
- 基于单序列的模型推理速度快,适合全蛋白组扫描,但精度可能受限于序列上下文。
- 基于多序列比对(MSA)的模型效果好,但依赖同源序列数据库,计算代价更高,而且对新蛋白或孤儿蛋白不友好。
- 结构感知模型引入结构模块后,对部分构象敏感的突变预测更准,但需要结构信息,适用范围受限。
3.3 关键观察:标准化评测引发的行业反思
PG-LLM 最重要的贡献不一定是给出“谁第一”的排行榜,而是通过标准化评测揭示了一些此前被忽略的事实:
第一,通用 LLM 的“知识型”推理与传统蛋白模型的“序列型”打分具有很强的互补性。在部分数据集中,将两者组合使用比单独使用任何一个都更好。
第二,不同模型擅长的蛋白类型不同。某个模型在酶蛋白上表现优秀,未必在转录因子上同样优秀。只看整体平均分很容易错过这种差异。
第三,数据泄露问题比预想中严重。部分模型在训练阶段可能已经见过评测相关的蛋白序列或 DMS 数据,导致评测分数虚高。PG-LLM 的数据划分策略对这类问题做了针对性规避。
对于任何想用 LLM 做蛋白相关任务的开发者来说,这个结论都值得注意:不要盲目相信某个模型在论文里报告的分数,最好先在目标蛋白上做小规模验证。
4. 一份可复用的评测小实验
PG-LLM 是一个偏研究性质的评测基准,但它的评测思路完全可以迁移到我们自己的实验中。下面我以一个简化版的突变排序评测实验为例,演示如何用自己的数据评测蛋白语言模型。
注意:以下代码是演示思路,不是 PG-LLM 官方仓库的完整复现。实际接口请根据你选择的模型和官方工具包调整。
4.1 环境准备
建议使用 Python 3.9 以上版本,并安装必要的依赖:
pip install torch scipy scikit-learn pandas fair-esm如果你计划使用 ESM 系列模型,fair-esm是常用的加载方式。其他蛋白模型可以按官方文档安装。
4.2 准备突变数据集
我们使用一个简化的 CSV 格式数据集,包含四个字段:
wt_sequence:野生型蛋白序列。mutant:突变描述,如A12V表示第 12 位由 A 变为 V。experimental_score:实验测得的效应分数,数值越高表示影响越大。
import pandas as pd # 只有演示用途,实际请替换为你自己的数据 data = pd.DataFrame({ "wt_sequence": [ "MEEPQSDPSVEPPLSQETFSDLWKLLPENNVLSPLPSQAMDDLMLSPDDIEQWFTED", "MEEPQSDPSVEPPLSQETFSDLWKLLPENNVLSPLPSQAMDDLMLSPDDIEQWFTED", "MEEPQSDPSVEPPLSQETFSDLWKLLPENNVLSPLPSQAMDDLMLSPDDIEQWFTED", ], "mutant": ["A12V", "L22R", "S46F"], "experimental_score": [0.8, 1.2, 0.3], }) print(data.head())4.3 使用 ESM 模型计算突变打分
这里采用一种比较常见的打分思路:分别计算突变序列与野生型序列在模型输出空间中的概率差异,将差异作为突变效应分数。
import torch import esm # 加载 ESM 模型(按需选择,这里以 esm2_t12_35M_UR50D 为例) model, alphabet = esm.pretrained.esm2_t12_35M_UR50D() model.eval() batch_converter = alphabet.get_batch_converter() def score_sequence(seq: str) -> float: """返回序列在模型下的对数似然分数(简化版)""" data = [("protein", seq)] batch_labels, batch_strs, batch_tokens = batch_converter(data) with torch.no_grad(): results = model(batch_tokens, repr_layers=[12], return_contacts=False) logits = results["logits"] # 计算每个位置正确 token 的 logits 均值,作为序列分数 tokens = batch_tokens[0] scores = [] for i in range(1, len(tokens) - 1): if tokens[i] == alphabet.padding_idx: continue logit = logits[0, i, tokens[i]] scores.append(logit.item()) return sum(scores) / len(scores) def get_mutant_sequence(wt_seq: str, mutant: str) -> str: """把 A12V 形式的突变描述转换为突变序列""" ref = mutant[0] pos = int(mutant[1:-1]) - 1 alt = mutant[-1] assert wt_seq[pos] == ref, f"参考序列第 {pos + 1} 位不是 {ref}" seq_list = list(wt_seq) seq_list[pos] = alt return "".join(seq_list) # 为每个突变计算分数差 for _, row in data.iterrows(): wt_score = score_sequence(row["wt_sequence"]) mut_seq = get_mutant_sequence(row["wt_sequence"], row["mutant"]) mut_score = score_sequence(mut_seq) print(f"{row['mutant']} diff_score = {mut_score - wt_score:.4f}")这个示例的核心逻辑是:用蛋白语言模型对野生型和突变型序列分别打分,然后取差值。差值越大,说明突变对蛋白序列的“合理性”破坏越大,即效应越强。
4.4 计算排序相关性指标
拿到所有突变的预测分数后,下一步就是计算它和实验分数的排序相关性。
from scipy.stats import spearmanr, kendalltau import numpy as np # 假设已经得到预测分数 predicted_scores = np.array([0.9, 1.5, 0.2]) experimental_scores = data["experimental_score"].values # 计算 Spearman 和 Kendall tau rho, p_value_rho = spearmanr(predicted_scores, experimental_scores) tau, p_value_tau = kendalltau(predicted_scores, experimental_scores) print(f"Spearman rho = {rho:.4f}, p = {p_value_rho:.4f}") print(f"Kendall tau = {tau:.4f}, p = {p_value_tau:.4f}")4.5 评估脚本整体设计
在实践中,建议把数据加载、模型打分、指标计算拆成独立函数或独立文件,方便以后替换模型和数据集。项目结构可以参考:
variant_eval/ ├── data/ │ └── mutations.csv ├── models/ │ ├── esm_scorer.py │ └── llm_scorer.py ├── metrics/ │ └── ranking_metrics.py ├── configs/ │ └── eval_config.yaml └── run_evaluation.py这样做的好处是,换模型时只需要修改模型封装层,不需要改动指标计算和数据分析代码。
5. 常见问题与排查思路
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 模型加载时报 CUDA out of memory | 模型过大或 batch size 过大 | 减小 batch size,使用半精度,或切换到 CPU 推理 |
| 突变序列生成时报错 “reference sequence mismatch” | 突变位点描述与参考序列不一致 | 检查序列索引是 0-based 还是 1-based,核对参考序列版本 |
| 不同模型分数分布差异大,难以比较 | 模型输出概率尺度不同 | 先对每个模型的预测分数做秩变换(rank),再计算相关性 |
| 评测结果波动明显 | 模型推理存在随机性 | 固定随机种子,多次运行取平均 |
| 某个蛋白上所有模型表现都差 | 该蛋白 DMS 数据量过少或噪声较大 | 单独检查数据质量,必要时剔除异常值 |
| 通用 LLM 输出格式解析失败 | Prompt 模板与模型输出格式不匹配 | 增加输出解析容错,加入 few-shot 示例约束格式 |
在实际评测中,最容易踩的坑是“数据泄露”。建议认真检查训练数据与测试数据之间是否存在同一蛋白的不同突变位点重叠。如果评测数据集来自 DMS 数据库,务必确认模型预训练语料没有包含该数据集对应蛋白的大规模突变扫描结果。
6. 最佳实践与工程建议
6.1 评测基准要可复现
无论你是使用 PG-LLM 还是自建评测集,都要把可复现放在首位。具体可以做到:
- 固定依赖版本,最好使用虚拟环境或容器镜像。
- 记录模型权重文件的版本号或 commit hash。
- 将数据划分逻辑写入代码,不依赖随机抽样。
- 评测脚本增加
--seed参数,默认固定一个种子值。
6.2 排序任务优先关注 Top-K 指标
蛋白突变排序的最终应用场景中,实验验证通常只覆盖排名最靠前的几十个突变。因此,不要只盯着整体相关性指标。建议额外关注 NDCG@K、Precision@K 等指标。一个整体相关性一般但 Top-K 召回率高的模型,可能比整体相关性高但 Top 位置有大量误报的模型更实用。
6.3 多模型集成是稳定的提升路径
PG-LLM 的评测结果从侧面说明:不同模型的错误模式有差异,集成往往比单模型更鲁棒。
# 示例:对多个模型的打分结果进行 rank 融合 import numpy as np from scipy.stats import rankdata # 假设三个模型的预测分数 model1_scores = np.array([0.8, 1.2, 0.4, 1.5]) model2_scores = np.array([0.7, 1.0, 0.6, 1.8]) model3_scores = np.array([0.9, 1.1, 0.5, 1.3]) # 转换为秩,再取平均 rank_sum = ( rankdata(model1_scores) + rankdata(model2_scores) + rankdata(model3_scores) ) ensemble_rank = rankdata(rank_sum) print("集成后的排序(秩):", ensemble_rank)这个思路在工程中很有价值。你可以分别用 ESM、ProtTrans 和一个通用 LLM 打分,然后对三个分数做秩平均,往往比单一模型更稳定。
6.4 模型选择要考虑场景
- 全蛋白组扫描:优先选择推理速度快的单序列 pLM,例如 ESM-2 的小参数量版本。
- 高精度少量突变验证:可以结合 MSA 模型或结构模型。
- 需要可解释性:当模型输出置信度低时,引入 LLM 的文本推理链路,输出突变影响的文字解释。
6.5 警惕过度拟合评测基准
当一个评测基准逐渐流行后,后续模型会针对它做调优,导致分数虚高。使用时要注意:
- 对于新的模型,优先看它在“未参与预训练的数据子集”上的表现。
- 不要只看平均值,要看模型在不同蛋白功能类别上的表现差异。
- 如果可能,保留一个自己内部的留出数据集做最终验证。
7. 总结与下一步学习路线
本文围绕 PG-LLM 这一首个面向 LLM 的蛋白突变排序标准化评测基准,梳理了蛋白突变排序任务的背景、评测基准的设计逻辑、大批量模型对比带来的行业启示,以及一套可迁移到自有项目的评测实现思路。
复盘下来,值得记住的关键点有三个:
- 蛋白突变排序评测必须标准化。没有统一的数据划分、评测指标和输入输出格式,模型之间的对比是不可信的。
- 专业蛋白模型与通用 LLM 各有优劣,不能简单说谁取代谁。实际落地时,优先用专业模型做基础打分,再用通用 LLM 做知识补充或解释。
- 评测结果要放在应用场景里解读。排序任务中,Top-K 质量往往比整体相关性更值得关注。
如果你想深入这个方向,下一步可以去查阅 PG-LLM 的论文原文与官方评测工具,跑通它的评估流程。然后可以尝试做两件事:一是用你自己的蛋白突变数据在 ESM、ProtTrans 等开源模型上建立一个小规模基线;二是把一个通用 LLM 接入同一套评估管线,看看知识型推理究竟能给排序任务带来多少提升。
动手跑一次完整的评测流程,比读十篇论文都能更快地理解这个领域的真实状态。希望这篇文章对你准备自己的蛋白突变排序实验有帮助。