PG-LLM:标准化评测大语言模型在蛋白突变排序中的表现 蛋白突变排序是蛋白质工程里最常被问到的任务之一给一个蛋白序列再给一批单点突变如何判断哪些突变更可能保持功能、哪些更可能破坏功能。过去这类任务主要交给进化序列模型或蛋白质语言模型大语言模型能不能胜任一直没有统一答案。哈佛大学团队提出的 PG-LLM正是面向 LLM 的蛋白突变排序标准化评测基准它用同一套数据组织方式、同一套提示词协议和同一套排序指标评估了 13 款主流 LLM 和 95 种专业模型。对于做突变效应预测、蛋白质设计筛选、模型评测和 LLM 应用的人来说理解 PG-LLM 的设计思路比单纯记住某个模型的分数更有价值。这篇文章把 PG-LLM 解决什么问题、怎么评测、怎么复现、有哪些坑一次讲清楚。1. 为什么蛋白突变排序需要 PG-LLM 这样的标准化基准1.1 突变效应预测不等于分类很多数据库把突变标注成“致病”和“良性”这是二分类问题。但蛋白质工程实验里更常见的是 deep mutational scanningDMS这类高通量数据实验输出通常是一个连续值例如细胞存活率、酶活性、蛋白丰度或热稳定性。连续值带来的问题不是简单标成“有害”或“无害”而是排序在同一蛋白背景下突变 A 是否比突变 B 影响更大。排序任务和分类任务虽然相关但评估方式不同。分类任务看重 AUC、F1、准确率。排序任务看重 Spearman、Kendall、Top-K 召回。模型可能分类很好但中间排名一团糟。也可能绝对分数偏差很大但相对顺序很好。LLM 在突变效应预测里的价值恰恰可能不是给出准确的绝对效应值而是对一组突变给出合理的相对顺序。PG-LLM 把“排序”作为核心任务是因为排序更贴近蛋白质筛选真实使用场景实验验证成本高先让模型把候选突变排好队再取 Top 一批去做湿实验。1.2 通用模型和专业模型的评估信号并不对齐蛋白质突变效应预测的模型来源非常杂。传统专业模型包括进化序列模型、蛋白质语言模型、结构模型、混合模型。它们的输入形式完全不同有的吃多序列比对有的吃单条序列有的吃 PDB 结构有的吃序列和结构混合特征。输出也不是统一格式可能是能量分数、log-likelihood、masked logits、结构损失甚至分类概率。通用 LLM 更特殊。它吃的输入是文本输出是文本。要让 GPT 这类模型预测突变效应必须先构造提示词把蛋白序列和突变写进去再让模型输出一个数值或判断。同一个模型换一种提示词结果可能完全不一样。PG-LLM 面对的核心矛盾就在这里模型类型差异太大如果不用统一接口、统一指标结果毫无可比性。它选择把问题标准化成一个对 LLM 友好的文本任务再对所有模型统一输出排序分数。1.3 PG-LLM 标准化的四个维度PG-LLM 称为“标准化评测基准”重点在于它把评测链路里最容易失控的四个环节都固定下来。第一是数据格式。蛋白编号、突变表示、实验分数方向必须统一。例如A123V和p.Ala123Val如果不做归一化模型解析和指标计算都会出错。第二是模型接入方式。通用 LLM 使用文本提示词专业模型使用各自原生接口但最终都必须输出一个“可排序分数”。第三是指标计算。统一使用排序类指标而不是直接比较不同模型的绝对误差。第四是评测协议。包括训练集和测试集如何划分、是否控制同源序列、是否允许多次采样、随机种子如何设置。这四个维度看似简单实际任何一处不一致都会让两篇论文的结果无法对照。这也是 PG-LLM 这类基准对社区最大的贡献。2. PG-LLM 评测什么对象、数据与指标2.1 13 款主流 LLM 如何归类标题里提到了 13 款主流模型具体名单应该以论文附表为准。从评测角度来看这 13 款模型不是简单堆数量而是覆盖了不同接入方式。LLM 类型常见接入方式评测前需要确认的事情闭源对话模型Chat Completion API输出长度限制、随机性、token 计费开源指令模型Transformers / vLLM本地显存、上下文长度、量化效果长上下文模型多序列输入到 prompt长序列是否真的有效还是只处理了局部推理增强模型输出分析再打分输出中夹杂原因解析规则是否稳定不要把“13 款主流模型”理解成 13 个一模一样的 LLM。它们之间的差异不仅影响最终分数还影响评测脚本是否要针对性地处理输出格式。2.2 95 种专业模型覆盖哪些技术路线95 种专业模型的名单同样以论文为准但理解评测结果不需要逐个记忆。可以把它们按技术路线归类。专业模型类型典型输入信号打分形式在排序评测中的注意点进化序列模型多序列比对保守性/能量分数对同源序列数量非常敏感蛋白质语言模型单条序列log-likelihood 或 embedding 分数需要统一坐标和突变 tokenization结构模型PDB 结构或预测结构结构稳定性分数结构缺失时表现会退化混合模型序列 结构 注释综合分数特征对齐和缺失值处理复杂监督学习模型人工特征或已有标签分类概率训练集泄漏风险更高这些模型和 LLM 放在一起评测真正的意义是回答一个问题通用大语言模型在蛋白突变排序上到底有没有赶上专门为蛋白质设计的模型。2.3 输入数据长什么样在 PG-LLM 的评测框架里最底层的数据是一张表格。每一行表示“某个蛋白的某个突变实验测出来的效应值”。一个简化后的数据格式如下protein,variant,experimental_score BRCA1,A123V,-1.25 BRCA1,D456N,0.68 BRCA1,E789K,-0.42 TP53,R175H,-2.10 TP53,Y220C,-1.85字段含义protein蛋白标识可以是基因名或 UniProt ID。variant单点氨基酸突变使用标准的A123V表示。experimental_score实验测得的连续效应分数。这里要特别注意experimental_score的方向。有的实验分数越高代表功能越强有的越高代表破坏越大。如果不统一方向Spearman 的正负号会反评测结果会完全错误。2.4 排序指标怎么选PG-LLM 这类基准不会只看一个指标。常用的排序指标包括以下这些指标计算对象适合场景注意点Spearman 相关系数全部突变判断整体单调关系对离群点不敏感适合通用排序Kendall tau全部突变更关注逐对一致性计算量略高AUROC二值化标签判断正负分离能力需要提前设定阈值AUPRC二值化标签正样本很少时更准确阈值选取影响结论NDCGKTop K 排序关注头部排序质量需要设定 K 和真实分数权重Top-K 召回Top K 排序湿实验筛选场景需要定义“真实阳性”对蛋白筛选来说Top-K 召回往往比全局 Spearman 更实际因为实验只会验证排名最靠前的几十个突变。PG-LLM 强调“排序”意味着评测时应当优先看模型能不能把真正强的突变放到前面而不是只看回归误差。3. 本地搭建可复现的排序评测流程3.1 环境准备在本地复现 PG-LLM 的评估思路不需要一次性搭建完整的大平台。先跑通一个小规模评测脚本再逐步扩大。推荐使用 conda 管理环境conda create -n pgllm-eval python3.10 -y conda activate pgllm-eval pip install pandas numpy scipy scikit-learn matplotlib openpyxl如果后面要调用 LLM API还需要安装对应 SDK。以 OpenAI 兼容接口为例pip install openai需要注意这里安装的不是某一个固定工具而是一套通用评测链路。实际项目中的依赖版本最好写入requirements.txt避免换机器后结果无法复现。3.2 数据字段统一评测前必须先把突变表示统一成一种格式。常见写法有三种A123VAla123Valp.Ala123Val推荐统一成一位氨基酸编码import re amino_acid_map { Ala: A, Arg: R, Asn: N, Asp: D, Cys: C, Gln: Q, Glu: E, Gly: G, His: H, Ile: I, Leu: L, Lys: K, Met: M, Phe: F, Pro: P, Ser: S, Thr: T, Trp: W, Tyr: Y, Val: V, } def normalize_variant(variant: str) - str: variant variant.replace(p., ) m re.match(r^([A-Z][a-z]{2})(\d)([A-Z][a-z]{2})$, variant) if m: wt amino_acid_map.get(m.group(1)) mut amino_acid_map.get(m.group(3)) if wt and mut: return f{wt}{m.group(2)}{mut} return variant.upper()这段代码把p.Ala123Val转成A123V。如果输入本来就是A123V则原样返回。注意突变坐标在绝大多数生物学数据库里是 1-based也就是第一位氨基酸是 1。脚本中不要混用 0-based 和 1-based否则会出现看似格式正确、实际位置错一位的隐蔽错误。3.3 核心评测脚本有了统一数据下一步是按蛋白分组计算排序指标。下面这段脚本是 PG-LLM 评估流程的最小实现。import pandas as pd from scipy.stats import spearmanr, kendalltau df pd.read_csv(dms_data.csv) pred pd.read_csv(model_predictions.csv) # 关键按 protein 和 variant 合并 merged pd.merge(df, pred, on[protein, variant], howinner) results [] for protein, g in merged.groupby(protein): # 样本太少或分数没有变化时相关系数没有意义 if len(g) 5: continue if g[experimental_score].nunique() 2: continue if g[model_score].nunique() 2: continue rho, _ spearmanr(g[experimental_score], g[model_score]) tau, _ kendalltau(g[experimental_score], g[model_score]) results.append({ protein: protein, n: len(g), spearman: rho, kendall: tau, }) summary pd.DataFrame(results) print(summary) print(平均 Spearman:, summary[spearman].mean())这里有一个容易忽略的点pd.merge使用的键是protein和variant。如果模型预测文件里的蛋白名和实验数据里的蛋白名大小写不一致就会丢失大量匹配行。合并完成后应当先检查行数有没有明显减少。3.4 接入 LLM 并解析输出通用 LLM 的输出不是结构化 JSON必须先定义提示词再写解析器。一段最小提示词模板如下PROMPT_TEMPLATE You are evaluating single amino acid mutations in a protein. Protein: {sequence} Protein name: {protein} Mutation: {variant} Return a single numeric score. Higher score means the mutation is more functionally tolerant, lower score means more deleterious. Output only the numeric score. 输出解析建议先提取最后出现的数字而不是随便取第一个数字import re import math def extract_numeric_score(text: str) - float: text text.replace(,, ) numbers re.findall(r-?\d\.?\d*, text) if not numbers: return float(nan) return float(numbers[-1]) def score_mutation(client, model_name, protein, sequence, variant): prompt PROMPT_TEMPLATE.format( sequencesequence, proteinprotein, variantvariant, ) resp client.chat.completions.create( modelmodel_name, messages[{role: user, content: prompt}], temperature0, max_tokens16, ) content resp.choices[0].message.content return extract_numeric_score(content)temperature0是为了降低随机性但并不能保证绝对稳定。如果模型仍然输出解释性文本比如“This mutation is likely harmful, score: -0.8”上面的解析器会取-0.8。如果输出里出现多个数字规则要提前固定避免评测脚本在真实数据上“碰运气”。3.5 用 vLLM 部署本地推理服务如果评测的 LLM 是开源模型推荐用 vLLM 部署成 OpenAI 兼容服务。这样上层评测脚本只需要改base_url不需要为每个模型重写推理代码。vllm serve meta-llama/Llama-3.1-8B-Instruct \ --port 8000 \ --max-model-len 8192 \ --gpu-memory-utilization 0.9启动后脚本里这样连接from openai import OpenAI client OpenAI( base_urlhttp://localhost:8000/v1, api_keyEMPTY, )本地 vLLM 服务的api_key只是占位符不需要真实密钥。模型名在调用时要换成启动时实际加载的模型名。4. 决定结果可信度的关键设计4.1 零样本还是微调PG-LLM 这类基准首先要明确模型是否允许先在训练集上微调。如果允许微调那么专业模型和 LLM 之间的对比会混入训练数据因素很难判断提升来自模型能力还是数据拟合。更稳妥的做法是先做零样本评估再看少样本提示、微调、适配器带来的增量。实际复现时建议把评测流程设计成支持“零样本 少样本”两种模式。零样本用来衡量模型原有能力少样本用来衡量模型在少量示例下的适应能力。两者分开报告不要混合成一个分数。4.2 序列同源性和数据泄漏蛋白突变预测最容易出现的问题不是模型写错而是数据泄漏。如果训练模型时见过同源蛋白的突变数据测试时再放一个相似蛋白进来分数会虚高。标准做法是使用序列聚类控制同源性常见的相似度阈值是 30% 或 50% 序列同一性。复现评测时至少要做两件事按蛋白序列聚类保证训练蛋白和测试蛋白不落在同一个聚类里。检查 LLM 是否在预训练阶段见过对应蛋白序列。这个问题无法完全规避只能通过在低同源性测试集上的表现来近似判断。不控制同源性评测结论很容易变成“模型记住了训练数据”而不是“模型学会了突变排序”。4.3 提示词模板和模型先验同一个模型在不同提示词下的表现可能差很多。PG-LLM 的价值之一就是固定提示词协议让不同模型面对相同任务。提示词设计有几个细节会影响结果是否给出蛋白名称。给出名字会让模型调用已有知识但不一定是对实验数据有用的知识。是否给出参考序列。序列太长可能超出上下文窗口太短又丢失上下文。是否给出正负方向。如果不说明“高分代表功能保持”模型可能按照自己的理解输出相反方向。是否允许解释。解释会提高输出解析难度也会增加 token 成本。最佳做法是把提示词作为变量做一次消融实验而不是直接认定某一种模板最优。4.4 排序指标的统计边界排序指标也有统计噪声尤其是蛋白内突变数量少的时候。一个只有 20 个突变的小蛋白Spearman 的波动范围很大。某一轮测试可能因为一个离群点就从 0.3 变成 0.6。因此不要只看所有蛋白的平均 Spearman还要看蛋白数量。每个蛋白的突变数量。指标标准差。置信区间。标准做法是在报告里同时给出 weighted Spearman也就是按每个蛋白的突变数量加权。这样样本量大的蛋白对结果影响更大更接近真实筛选场景。4.5 多突变和实验标签异质性PG-LLM 如果只做单点突变评测相对干净。但真实蛋白质工程经常涉及组合突变、插入缺失和截短体。组合突变的难点是上位效应两个单点突变单独看都可能无害同时出现却可能破坏蛋白。通用 LLM 在单点突变上的排序能力不能直接推广到组合突变。另一个问题是实验标签异质性。有的实验测的是稳定性有的是活性有的是表达量。不同实验分数不能直接合并比较。跨蛋白比较时必须对每个蛋白单独计算排序指标再聚合而不是把所有行放进同一个回归模型。5. 复现 PG-LLM 流程时最常见的五个坑5.1 突变命名不规范现象模型预测结果和实验数据合并后匹配率为 0。原因一边使用A123V另一边使用p.Ala123Val甚至出现小写a123v。检查方式查看两个文件里的 unique 突变格式。处理建议统一用normalize_variant做标准化合并前先统计两种格式的重复表。5.2 参考序列坐标不匹配现象样本量看起来很多但 Spearman 普遍接近 0。原因参考序列来自不同版本突变坐标对应不同氨基酸。检查方式对每个蛋白检查wt_seq[position - 1]是否等于突变中的原始氨基酸。处理建议建立自己的参考序列索引所有突变坐标以统一参考序列为基准并在脚本中增加断言。5.3 排序指标出现 NaN现象某些蛋白的 Spearman 显示为nan。原因模型对所有突变输出同一个分数或者实验分数本身完全相同。检查方式增加唯一值数量检查。处理建议样本量少于 5 或唯一值少于 2 时跳过该蛋白并在日志里记录跳过原因。5.4 LLM 输出随机性没有控制现象同一个模型跑两次结果排序变化很大。原因模型调用没有固定 temperature或者使用流式输出时解析到不完整文本。检查方式固定temperature0对同一个 prompt 重复三次对比分数。处理建议评测结果取多次运行的平均排名而不是单次输出。5.5 把绝对分数高当成排序好现象某个模型输出的分数区间很大看起来很有区分度但 Spearman 很低。原因模型分数偏离实验分数或者方向不一致。检查方式画散点图看是否单调。处理建议坚持用排序指标评估不使用 MSE 作为唯一标准。问题现象常见原因检查方式处理建议合并后匹配行很少突变格式不一致统计 unique variant 格式统一归一化后再合并Spearman 普遍为负实验分数方向未统一检查正负相关方向按实验定义翻转分数指标出现 NaN常数预测或样本太少打印每个蛋白唯一值数量加过滤条件并记录日志结果不稳定随机采样未控制同一模型跑 3 次固定 temperature 并用平均排名Top-K 结果和 Spearman 矛盾全局排序和头部排序不一致分别计算 Spearman 和 NDCGK两个指标都报告6. 从 PG-LLM 基准到蛋白质筛选落地6.1 研究复现与工程落地的差异在论文里跑通 PG-LLM 评测和在生产级蛋白质筛选流程里落地是两个不同问题。研究复现阶段要保证的是公平、可复现、控制变量。工程落地阶段要考虑的是吞吐量、成本、失败率、模型更新、缓存和监控。环节研究复现工程落地数据集公开 DMS 数据自有湿实验数据需要质量控制LLM 推理单机 GPU 或 API 小量调用高并发服务缓存和限流指标Spearman / AUROCTop-K 推荐命中率、实验回报输出解析少量手工检查大规模异常检测和自动重试模型更新固定版本版本管理和回归评测如果只是用 LLM 从大量突变里初筛出 Top 100再做湿实验那么关注的重点应该是 Top-K 召回率和稳定复现而不是全局 Spearman 的一点点提升。6.2 落地前检查清单在把 PG-LLM 评估流程接入自己的项目前可以按下面清单逐项确认。是否统一了突变表示和参考序列坐标。是否确认了实验分数方向高分代表功能强还是破坏强。是否做了同源序列去重避免数据泄漏。是否固定了提示词模板并做了至少一次模板消融。是否固定了模型版本和采样参数。是否同时计算 Spearman、Kendall、NDCGK。是否记录了每个蛋白的样本量和跳过原因。是否预留了缓存机制避免同一突变重复调用 LLM。是否保存了每一次评测的原始输出方便回溯。是否为模型升级保留了旧版本评测结果方便对比回归。这个清单不是摆设。任何一个环节缺失评测分数都可能不可信。6.3 下一步可以尝试的方向理解 PG-LLM 之后下一步可以围绕三个方向深入。第一是少样本和上下文学习。尝试在提示词里放入几个已知实验分数让 LLM 参考这些示例重新排序观察是否比零样本更稳定。第二是模型融合和集成排序。不同模型的错误模式不同可以通过 rank-based 融合把多个模型排名合并再用 PG-LLM 的统一指标评估融合后的效果。注意融合的目标是改善排序而不是追求绝对分数更接近实验值。第三是异常检测和输出约束。LLM 输出经常不是纯数字可以探索用函数调用或者 constrained decoding 强制输出 JSON再接入排序管道。这样能大幅降低解析失败率也更容易在生产环境长期运行。蛋白突变排序评测不会止步于一个基准。PG-LLM 真正有用的地方是让模型对比从“谁在某个数据集上分更高”变成“谁对突变相对效应排序更稳定”。如果你想把 LLM 放进蛋白筛选流程建议先按文中的最小流程跑通一个蛋白再扩展到全量数据。评测脚本稳定后每一次提示词改动和模型升级都能被客观衡量这才是基准对工程实践最大的价值。