ESM:从零开始掌握蛋白质结构分析及预测
一、基本信息扎克伯格旗下 Biohub团队发布了一个蛋白质生物学的世界级模型一个用于预测、设计和发现的科学引擎。该系统基于最新一代的进化尺度建模ESM技术从进化产生的蛋白质序列中学习并利用这些知识来表示、映射、预测和设计跨尺度的蛋白质——从原子相互作用到跨越数十亿年的进化关系。该系统包含三个组件ESMC、ESMFold2 和 ESM Atlas。ESMC是一种先进的蛋白质语言模型它通过对数十亿条蛋白质序列的训练学习了蛋白质生物学的规则。可用于分析、分类、比较和解释蛋白质。目标描述使用ESMC嵌入序列嵌入蛋白质序列探索不同的Transformer层如何编码结构和功能信息。零样本熵和突变分析计算每个位置的熵和对数似然比以识别受限位点与突变容忍位点。用于酶功能分类的层扫描学习如何扫描所有层以酶分类为任务找出最佳层。微调ESMC使用参数高效微调 (PEFT) 在 ESMC 之上针对您的数据集微调分类或回归头。ESMFold2基于 ESMC 6B 模型构建是一款先进的结构预测模型 可根据序列预测 3D 蛋白质结构包括 DNA/RNA 和小分子。在 Foldbench 蛋白质-蛋白质和抗体-抗原复合物的 DockQ 通过率方面ESMFold2 优于其他模型并且可以在单序列模式下使用从而将折叠速度提高一个数量级。ESMFold2 已在实验室中针对五个治疗靶点进行了验证。ESMFold2 的反转能够生成具有高命中率、纳摩尔级亲和力、靶点特异性和功能活性的全新微型结合剂和抗体衍生的 scFv。目标描述使用 ESMFold2 进行折叠将蛋白质与 DNA、RNA 和小分子配体结合进行折叠。Binder 设计设计高命中率的抗体和微型结合剂。实施我们论文中介绍的方案该方案制备的结合剂在实验室检测中表现出纳摩尔级亲和力、靶向特异性和功能活性。ESMAltas是一张包含 68 亿个蛋白质的图谱涵盖了生命多样性的全部范围。ESMFold2 的折叠吞吐量使其能够预测超过 10 亿个结构。该图谱根据 ESMC 的内部世界模型进行组织。我们通过训练稀疏自编码器 (SAE) 使该世界模型可解释。SAE 是无监督神经网络经过训练可将 ESMC 的内部表征分解为约 16,000 个可解释的稀疏特征集这些特征揭示了 ESMC 学习到的蛋白质之间的功能关系。每个特征都通过一个智能体流程以自然语言进行概括该流程将特征映射到来自蛋白质数据库的已知生物学信息。Biohub发布了一系列在不同模型尺度、层级和不同粒度级别上训练的 SAE。了解更多关于如何在Biohub平台上使用 ESM Atlas 的信息。二、快速上手运行ESM模型主要有两种方式通过Biohub平台或在本地使用Hugging Face。Biohub平台使用户能够以最少的设置轻松运行ESM模型推理。有兴趣自定义或微调ESM模型的用户可以使用Hugging Face提供的模型。2.1 环境配置安装2.1.1 通过 Hugging Face 运行 ESMFold2通过Pip安装esmpip install esm然后使用以下代码在本地运行 ESMFold2并使用来自 Hugging Face 的权重from esm.models.esmfold2 import ( DNAInput, ESMFold2InputBuilder, EsmFold2Model, LigandInput, Modification, ProteinInput, StructurePredictionInput, ) HHAI_SEQ ( MIEIKDKQLTGLRFIDLFAGLGGFRLALESCGAECVYSNEWDKYAQEVYEMNFGEKPEGDITQVNEKTIPDH DILCAGFPCQAFSISGKQKGFEDSRGTLFFDIARIVREKKPKVVFMENVKNFASHDNGNTLEVVKNTMNELD YSFHAKVLNALDYGIPQKRERIYMICFRNDLNIQNFQFPKPFELNTFVKDLLLPDSEVEHLVIDRKDLVMTN QEIEQTTPKTVRLGIVGKGGQGERIYSTRGIAITLSAYGGGIFAKTGGYLVNGKTRKLHPRECARVMGYPDS YKVHPSTSQAYKQFGNSVVINVLQYIAYNIGSSLNFKPY ) model EsmFold2Model.from_pretrained(biohub/ESMFold2, devicecuda).eval() spi StructurePredictionInput( sequences[ ProteinInput(idA, sequenceHHAI_SEQ), DNAInput( idB, sequenceGATAGCGCTATC, modifications[Modification(position5, ccdC36)], ), DNAInput( idC, sequenceTGATAGCGCTATC, modifications[Modification(position6, ccdC36)], ), LigandInput(idL, ccd[SAH]), ] ) result ESMFold2InputBuilder().fold( model, spi, num_loops20, num_sampling_steps100, num_diffusion_samples1, seed0 ) print(fpLDDT mean: {float(result.plddt.mean()):.3f}, pTM: {float(result.ptm):.3f}, ipTM: {float(result.iptm):.3f}) with open(1mht_pred.cif, w) as f: f.write(result.complex.to_mmcif())如果遇到CUDA兼容性问题建议使用conda创建独立环境conda create -n esmfold python3.9 conda activate esmfold conda install pytorch cudatoolkit11.3 -c pytorch pip install esm2.1.2 通过 Biohub 平台运行 ESMFold2首先安装esmPython 包pip install esm导入必要的库from esm.sdk.forge import SequenceStructureForgeInferenceClient from esm.sdk.api import FoldingConfig from esm.utils.structure.input_builder import ProteinInput, StructurePredictionInput使用选定的模型调用推理客户端并将替换为您的标记名称client SequenceStructureForgeInferenceClient(modelesmfold2-fast-2026-05, urlhttps://biohub.ai, tokenyour API token) # Human carbonic anhydrase II (PDB 2CBA) ca2_sequence ( MSHHWGYGKHNGPEHWHKDFPIAKGERQSPVDIDTHTAKYDPSLKPLSVSYDQATSLRILNNGHAFNVEFDD SQDKAVLKGGPLDGTYRLIQFHFHWGSLDGQGSEHTVDKKKYAAELHLVHWNTKYGDFGKAVQQPDGLAVL GIFLKVGSAKPGLQKVVDVLDSIKTKGKSADFTNFDPRGLLPESLDYWTYPGSLTTPPLLECVTWIVLKEP ISVSSEQVLKFRKLNFNGEGEPEELMVDNWRPAQPLKNRQIKASFK ) ca2_input StructurePredictionInput( sequences[ProteinInput(idA, sequenceca2_sequence)] ) config FoldingConfig( num_loops20, num_sampling_steps100 ) result client.fold_all_atom(ca2_input, configconfig) with open(result.cif, w) as f: f.write(result.complex.to_mmcif())2.1.3 并行作业执行对于需要处理多个输入的作业并行执行器会发送并行请求在遵守速率限制并适应请求延迟的前提下高效地并发执行这些请求。以下示例展示了在嵌入序列时如何使用 parallel_executor 上下文管理器2.2 用例展示2.2.1 RNase H1–RNA/DNA hybrid complex来自PDB编号4H8K的该复合物包含四条链承担三种生物学功能LC11-RNase H1链A和B来源于宏基因组样本的耐热RNase H1直系同源物以同源二聚体形式表达并结晶。我们将其作为一个包含两个链ID的单个ProteinInput提供。底物RNA链C与DNA模板配对并被酶切割的RNA链。底物DNA链D杂交双链中互补的DNA链。我们将把全部四条链一起折叠以复现PDB 4H8K中所示的结构构型# Define all components from PDB 4H8K (LC11-RNase H1 RNA/DNA hybrid) # LC11-RNase H1 protein sequence (140 amino acids, chains A and B share this sequence) rnaseh_sequence ( MNKIIIYTDGGARGNPGPAGIGVVITDEKGNTLHESSAYIGETTNNVAEYEALIRALEDLQ MFGDKLVDMEVEVRMNSELIVRQMQGVYKVKEPTLKEKFAKIAHIKMERVPNLVFVHIPRE KNARADELVNEAIDKALS ) # Substrate RNA sequence (14 nucleotides) rna_sequence CGACACCUGAUUCC # Substrate DNA sequence (14 nucleotides, complementary to the RNA) dna_sequence GGAATCAGGTGTCG # Express the homodimer as a single ProteinInput with two chain IDs rnaseh_protein input_builder.ProteinInput(id[A, B], sequencernaseh_sequence) substrate_rna input_builder.RNAInput(idC, sequencerna_sequence) substrate_dna input_builder.DNAInput(idD, sequencedna_sequence) # Create the complex input rnaseh_complex_input input_builder.StructurePredictionInput( sequences[rnaseh_protein, substrate_rna, substrate_dna] ) rnaseh_structure client.fold_all_atom(rnaseh_complex_input, configconfig) # Save the structure with open(rnaseh_complex_4h8k.cif, w) as f: f.write(rnaseh_structure.complex.to_mmcif())下面将通过两种方式对上面生成的复合物进行可视化每条链用不同颜色显示两个RNase H1亚基、RNA链和DNA链分别着色按每个残基的置信度得分pLDDT对残基进行颜色标记该分数反映模型对每个残基位置的置信程度。提示pLDDT分数代表每个残基的置信度极高90深蓝色、高70–90浅蓝色、低50–70黄色、极低50橙色。RNA/DNA的末端及柔性环区通常得分较低这属于正常现象。rnaseh_cif open(rnaseh_complex_4h8k.cif).read() rnaseh_plddt normalize_plddt(rnaseh_structure.plddt.cpu().numpy()) v1 py3Dmol.view(width500, height400) v1.addModel(rnaseh_cif, mmcif) v1.setStyle({chain: A}, {cartoon: {color: #4A90E2}}) v1.setStyle({chain: B}, {cartoon: {color: #7FB3E8}}) v1.setStyle({chain: C}, {cartoon: {color: #F5A623}}) v1.setStyle({chain: D}, {cartoon: {color: #50E3C2}}) v1.zoomTo() v2 py3Dmol.view(width500, height400) v2.addModel(rnaseh_cif, mmcif) apply_plddt_style(v2, rnaseh_plddt) rnaseh_legend ( span stylecolor:#4A90E2;#9632;/span RNase H1 (A) nbsp; span stylecolor:#7FB3E8;#9632;/span RNase H1 (B) nbsp; span stylecolor:#F5A623;#9632;/span RNA nbsp; span stylecolor:#50E3C2;#9632;/span DNA ) show_dual_viewer( v1, RNase H1–RNA/DNA Hybrid Complex, rnaseh_legend, v2, Confidence (pLDDT), PLDDT_LEGEND, )可视化结果如下图所示2.2.2司美格鲁肽 GLP-1受体定义GLP-1受体# Human GLP1R sequence (UniProt P43220) # This construct includes N-terminal FLAG tag, TEV cleavage site, and C-terminal His-tag receptor_sequence ( MKTIIALSYIFCLVFADYKDDDDLEVLFQGPARPQGATVSLWETVQKWREYRRQCQRSLTEDPPPATDLFCNRTFDEYAC WPDGEPGSFVNVSCPWYLPWASSVPQGHVYRFCTAEGLWLQKDNSSLPWRDLSECEESKRGERSSPEEQLLFLYIIYTVG YALSFSALVIASAILLGFRHLHCTRNYIHLNLFASFILRALSVFIKDAALKWMYSTAAQQHQWDGLLSYQDSLSCRLVFL LMQYCVAANYYWLLVEGVYLYTLLAFSVFSEQWIFRLYVSIGWGVPLLFVVPWGIVKYLYEDEGCWTRNSNMNYWLIIRL PILFAIGVNFLIFVRVICIVVSKLKANLMCKTDIKCRLAKSTLTLIPLLGTHEVIFAFVMDEHARGTLRFIKLFTELSFT SFQGLMVAILYCFVNNEVQLEFRKSWERWRLEHLHIQRDSSMKPLKCPTSSLSSGATAGSSMYTATCQASCSPAGLEVLF QGPHHHHHHH ) receptor input_builder.ProteinInput(idA, sequencereceptor_sequence)定义司美格鲁肽肽链第2位的AIB取代AIB即α-氨基异丁酸是一种非天然氨基酸通过限制主链柔性和降低蛋白水解降解来增强肽的稳定性。这种修饰常用于治疗性肽中以改善其药代动力学特性。赖氨酸作为连接位点指定那个将与脂质连接子形成共价键的赖氨酸残# Semaglutide peptide sequence peptide_sequence HAEGTFTSDVSSYLEGQAAKEFIAWLVRGRG # AIB substitution (0-indexed) aib_position 1 peptide input_builder.ProteinInput( idB, sequencepeptide_sequence, modifications[input_builder.Modification(positionaib_position, ccdAIB)], ) lys_idx peptide_sequence.index(K) # residue index in peptide (0-based) print(Lys at residue index:, lys_idx)定义脂质连接子SMILES使用SMILES表示法来定义一个类脂质连接子。该SMILES的编写方式使得连接处的羰基碳作为第一个原子从而简化原子索引。def get_protractor_smiles() - str: # Protractor refers to Novo Nordisks fatty acid linker technology used in semaglutide. # This SMILES is a representative structure inspired by semaglutides linker design, # not the exact compound. For the precise semaglutide structure, see PDB 7KI0 or the FDA label. # First atom (index 0) is the carbonyl carbon used for attachment to the peptide. return C(O)(CCOCCOCC(O)NCCOCCOCCNCC(O)N[CH](CCC(O)NCCCCCCCCCCCCCCCCCC(O)O)C(O)O) ligand input_builder.LigandInput(idC, ccdNone, smilesget_protractor_smiles())现在我们将人GLP1R、司美格鲁肽肽链和脂质连接子一起折叠bond input_builder.CovalentBond( chain_id1B, res_idx1lys_idx, atom_idx18, chain_id2C, res_idx20, atom_idx20 ) complex_inputs input_builder.StructurePredictionInput( sequences[receptor, peptide, ligand], covalent_bonds[bond] ) complex_structure client.fold_all_atom(complex_inputs, configconfig) with open(glp1r_semaglutide.cif, w) as f: f.write(complex_structure.complex.to_mmcif())可视化生成的复合物cif_data open(glp1r_semaglutide.cif).read() plddt normalize_plddt(complex_structure.plddt.cpu().numpy()) v1 py3Dmol.view(width500, height400) v1.addModel(cif_data, mmcif) v1.setStyle({chain: A}, {cartoon: {color: #2166ac}}) v1.setStyle({chain: B}, {cartoon: {color: #f4a9c4}}) v1.addStyle({hetflag: True}, {stick: {color: #e6550d}}) # Highlight the lysine on semaglutide that anchors the protractor linker v1.addStyle({chain: B, resn: LYS}, {stick: {}}) v1.zoomTo() v2 py3Dmol.view(width500, height400) v2.addModel(cif_data, mmcif) apply_plddt_style(v2, plddt, add_hetflagTrue) v2.addStyle({chain: B, resn: LYS}, {stick: {}}) chain_legend ( span stylecolor:#2166ac;#9632;/span Receptor nbsp; span stylecolor:#f4a9c4;#9632;/span Peptide nbsp; span stylecolor:#e6550d;#9632;/span Protractor ) show_dual_viewer( v1, Chain identity, chain_legend, v2, Confidence (pLDDT), PLDDT_LEGEND )复合物如下图所示Predicted Aligned Error (pAE)pae complex_structure.pae.cpu().numpy() len_receptor len(receptor_sequence) len_peptide len(peptide_sequence) plot_pae( pae, chains[ (0, len_receptor, GLP1R, #2166ac), (len_receptor, len_receptor len_peptide, Peptide, #f4a9c4), (len_receptor len_peptide, pae.shape[0], Protractor, #e6550d), ], )2.2.3 利用MSA引导的泛素折叠到目前为止我们一直依赖单序列折叠这种方法以牺牲准确性换取速度。ESMFold2也可以通过多序列比对MSA来调用MSA提供的进化背景能够显著提高折叠准确性。MSA揭示了序列在相关物种和蛋白质之间的演化历程帮助模型识别结构上重要的残基以及共进化约束。在本示例中我们将折叠泛素——一种存在于几乎所有真核生物中的小分子调控蛋白全长76个残基。我们将使用来自ColabFold MMseqs2搜索的真实MSA。MSA在以下情况下尤其有用具有大量同源物的蛋白质识别保守的结构特征提高不确定区域的准确性解决模糊构象# download the MSA !wget -q https://drive.google.com/uc?exportdownloadid1la9UUK_FnFQFR9VB35DIB797d87Zwm0b -O ubiquitin.a3mfrom esm.utils.msa import MSA from esm.utils.structure.input_builder import ProteinInput, StructurePredictionInput ubiquitin_sequence ( MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTLHLVLRLRGG ) msa MSA.from_a3m(pathubiquitin.a3m, remove_insertionsTrue, max_sequences1000) print(fMSA depth: {msa.depth} sequences, length: {msa.seqlen} residues) # Sanity check — first MSA seq should match the query print(First MSA seq matches query:, msa.sequences[0] ubiquitin_sequence) print(First MSA seq:, repr(msa.sequences[0][:80])) print(Query: , repr(ubiquitin_sequence)) fold_result client.fold_all_atom( StructurePredictionInput( sequences[ProteinInput(idA, sequenceubiquitin_sequence, msamsa)] ) ) print(f\npTM: {fold_result.ptm:.3f}) print(fAverage pLDDT: {fold_result.plddt.mean().item():.1f}) with open(ubiquitin_with_msa.cif, w) as f: f.write(fold_result.complex.to_mmcif())结果可视化cif_data open(ubiquitin_with_msa.cif).read() plddt normalize_plddt(fold_result.plddt.cpu().numpy()) v1 py3Dmol.view(width500, height400) v1.addModel(cif_data, mmcif) v1.setStyle({}, {cartoon: {color: #4A90E2}}) v1.zoomTo() v2 py3Dmol.view(width500, height400) v2.addModel(cif_data, mmcif) apply_plddt_style(v2, plddt) v2.zoomTo() show_dual_viewer( v1, Ubiquitin (cartoon), None, v2, Confidence (pLDDT), PLDDT_LEGEND )2.2.4 使用MSA折叠蛋白质-蛋白质复合物对于多链复合物MSA可能是区分错误界面与正确界面的关键。您需要为每条链提供一份MSA并将每条链作为独立的ProteinInput传入复用与示例3相同的msa参数。跨链配对可选。MSA头部可携带keyid标记不同链中共享相同key的行将被置于MSA的同一行中从而使模型能够读取链间的共进化信息key通常编码来源物种。不带key的行则作为普通单链行使用——此处的大部分改进来自单链的序列深度配对作为附加信号。您只需标注头部而无需自行构建布局query GPYYPTNKLQAAVM... UniRef100_A0A... key10245 # 同一物种 → 与另一条链中 key10245 的行配对 ...自行构建MSA的方法运行配对搜索例如ColabFold/MMseqs2然后将每个命中条目的OXorganism_id标签重写为keyorganism_id。某条链的命中条目若没有携带key仍会被折叠——其各行仅仅是未配对的。# Download the MSAs for chain A and B directly from GitHub !wget -q -O g3l5_chainA.a3m https://raw.githubusercontent.com/Biohub/esm/main/cookbook/tutorials/g3l5_chainA.a3m !wget -q -O g3l5_chainB.a3m https://raw.githubusercontent.com/Biohub/esm/main/cookbook/tutorials/g3l5_chainB.a3m from esm.utils.msa import MSA from esm.utils.structure.input_builder import ProteinInput, StructurePredictionInput # Vaccinia virus G3/L5 entry sub-complex (PDB 7YTU), two chains. chainA_seq GPYYPTNKLQAAVMETDRENAIIRQRNDEIPTRTLDTAIFTDASTVASAQIHLYYNSNIGKIIMSLNGKKHTFNLYDDNDIRTLLPILLLSK chainB_seq ( GPNMFFMPKRKIPDPIDRLRRANLACEDDKLMIYGLPWMTTQTSALSINSKPIVYKDCAKLLRSINGSQPVSLNDVLRR ) # One MSA per chain (headers carry key for optional cross-chain pairing). chainA_msa MSA.from_a3m(pathg3l5_chainA.a3m, remove_insertionsTrue) chainB_msa MSA.from_a3m(pathg3l5_chainB.a3m, remove_insertionsTrue) fold_result client.fold_all_atom( StructurePredictionInput( sequences[ ProteinInput(idA, sequencechainA_seq, msachainA_msa), ProteinInput(idB, sequencechainB_seq, msachainB_msa), ] ), configconfig, ) print(fpTM: {fold_result.ptm:.3f}, ipTM: {fold_result.iptm:.3f}) print(fAverage pLDDT: {fold_result.plddt.mean().item():.1f}) with open(g3l5_complex.cif, w) as f: f.write(fold_result.complex.to_mmcif())