PSP - 蛋白质序列提取 Transformer 蛋白质语言模型 ESM2 特征

news2024/12/25 11:21:31

欢迎关注我的CSDN:https://spike.blog.csdn.net/
本文地址:https://spike.blog.csdn.net/article/details/132888139

Contracts

蛋白质语言模型 ESM (Evolutionary Scale Modeling) 是一种利用深度学习技术来预测蛋白质结构和功能的方法。ESM 通过在大规模的蛋白质序列数据库上,训练一个自回归的神经网络,学习蛋白质的进化规律和序列-结构-功能的关系。ESM 可以根据给定的蛋白质序列,生成其对应的隐向量,表示其结构和功能的特征,还可以利用隐向量进行多种下游任务,如结构预测、功能注释、相互作用分析等。ESM 是一种强大而通用的蛋白质语言模型,为蛋白质科学提供了新的视角和工具。

ESM (Evolutionary Scale Modeling),即进化尺度模型,包括 ESM-2、ESMFold、ESM-MSA-1b、ESM-1v、ESM-IF1(反向折叠),即

  • ESM-2,2022.8,SOTA 通用目的蛋白质语言模型 v2 版,其中 ESM-1v 是 v1 版本。
  • ESMFold,2022.11,端到端的单序列 3D 结构预测
  • ESM-MSA-1b,2021.6,MSA Transformer 语言模型
  • ESM-IF1,2022.4,反向折叠模型

具体参考:ESM GitHub

1. 配置 Docker 环境

配置 TORCH_HOMEBOS 环境,即:

vim ~/.bashrc

export TORCH_HOME=[your folder]/torch_home/
alias bos='bcecmd/bcecmd --conf-path bcecmd/bceconf/ bos'

建议配置 TORCH_HOME,固定 PyTorch 模型缓存地址,即 torch_home/hub/checkpoints 中。

在 Docker Image 中,导入 ESM 环境:

conda create -n esmfold --clone miniconda3/envs/esmfold

需要安装的 Torch 相关包:

pip install -q torch-scatter -f https://data.pyg.org/whl/torch-1.12.1+cu113.html
pip install -q torch-sparse -f https://data.pyg.org/whl/torch-1.12.1+cu113.html
pip install -q torch-cluster -f https://data.pyg.org/whl/torch-1.12.1+cu113.html
pip install -q torch-spline-conv -f https://data.pyg.org/whl/torch-1.12.1+cu113.html
pip install -q torch-geometric

导出 Docker 环境:

# 提交 Tag
docker ps -a
docker commit [container id] esmfold:v1.0

# 准备远程 Tag
docker tag esmfold:v1.0 [your ip]/esmfold:v1.0

# 推送至远程
docker push [your ip]/esmfold:v1.0
# 从远程拉取
# docker pull [your ip]/esmfold:v1.0

2. 批量推理 ESM2 模型

配置 ESM 推理脚本:

set -xe
PROJECT_DIR="$(cd "$(dirname $0)" && pwd)/.."

source activate esmfold
export PATH="/usr/local/cuda-11.6/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda-11.6/lib64:$LD_LIBRARY_PATH"
export TORCH_HOME=[your folder]/torch_home/

echo "${PROJECT_DIR}"

python "${PROJECT_DIR}/scripts/extract.py" esm2_t36_3B_UR50D \
  "${PROJECT_DIR}/mydata/all-1.fasta" \
  [your folder]/esm2_3B_feat/ \
  --toks_per_batch 1536 \
  --repr_layers -1 \
  --include per_tok contacts \
  --truncation_seq_length 1536 \
  --num_workers 8

测试 A100 显卡 80G,最大支持 1536 序列长度。

优化 scripts/extract.py 脚本,输出结果是序列 MD5 编码的特征,避免序列过长或名字重复:

  1. 增加 num_workers,提升推理速度。
  2. 替换 label 为蛋白质序列。
  3. 增加断点处理,避免重复搜索

# ...
data_loader = DataLoader(
    dataset, collate_fn=alphabet.get_batch_converter(args.truncation_seq_length),
    batch_sampler=batches, num_workers=args.num_workers,
)
# ...
# result = {"label": label}
result = {"label": strs[i]}  # label 修改成序列
# ...
for i, label in enumerate(labels):
    args.output_file = args.output_dir / f"{label}.pt"
    if os.path.isfile(args.output_file):
        warnings.warn(f"The feat has processed. {args.output_file}")
        continue
# ...

注意不能使用 num_workers 否则程序无法运行。

日志:

python workspace/esm-by-chenlong/run/../scripts/extract.py esm2_t36_3B_UR50D workspace/esm-by-chenlong/mydata/all-1.fasta pdb_dataset/esm2_6b_feat/ --toks_per_batch 1536 --repr_layers -1 --include per_tok contacts --truncation_seq_length 1536 --num_workers 32
Transferred model to GPU
Read /nfs_beijing_ai/chenlong/workspace/esm-by-chenlong/run/../mydata/all-1.fasta with 27115 sequences
Processing 1 of 6668 batches (66 sequences)
Processing 2 of 6668 batches (61 sequences)
Processing 3 of 6668 batches (56 sequences)
Processing 4 of 6668 batches (52 sequences)
Processing 5 of 6668 batches (51 sequences)

注意序列尺寸 2048 导致显存溢出。

3. 准备 ESM2 输入 FASTA 数据

将 FASTA 文件夹中的全部 FASTA 文件组成1个文件,并且序列描述,转换成 Hash 编码,避免相同序列的特征重复生成特征,即:

  • seq_encoder :Hash 编码函数,同时也用于查找。
  • load_feat:读取 feature 特征,支持显示数据和绘制图像。
  • merge_fasta_folder:合并 FASTA 文件夹。

即:

#!/usr/bin/env python
# -- coding: utf-8 --
"""
Copyright (c) 2022. All rights reserved.
Created by C. L. Wang on 2023/9/13
"""
import argparse
import os
import sys
import warnings
from pathlib import Path

from tqdm import tqdm

p = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if p not in sys.path:
    sys.path.append(p)

from myutils.project_utils import traverse_dir_files_for_large, read_file, write_list_to_file


class Esm2FastaGenerator(object):
    """
    ESM2 工具类
    """
    def __init__(self):
        pass

    @staticmethod
    def seq_encoder(sequence):
        """
        将 seq 使用 hash 编码,避免重复生成
        """
        import hashlib
        return hashlib.md5(sequence.encode(encoding="utf-8")).hexdigest()

    @staticmethod
    def load_feat(path, is_print=False):
        """
        加载 ESM 特征文件,以及打印特征
        """
        import torch
        from torch import Tensor
        rep = torch.load(path)
        if is_print:
            print(f"[Info] rep: {rep.keys()}")
            for key in rep.keys():
                val = rep[key]
                if isinstance(val, str):
                    print(f"[Info] {key}: {val}")
                elif isinstance(val, dict):
                    for sub_key in val.keys():
                        print(f"[Info] {key}: {sub_key}: {val[sub_key].shape}")
                elif isinstance(val, Tensor):
                    print(f"[Info] {key}: {val.shape}")
                else:
                    print(f"[Info] {key}: {val}")

            # 绘制接触矩阵
            import matplotlib.pyplot as plt
            contacts_map = rep["contacts"]
            plt.matshow(contacts_map)
            plt.title("contacts_map")
            save_name = "contacts_map.png"
            plt.savefig(save_name, bbox_inches='tight', format='png')
            plt.show()
        return rep

    @classmethod
    def merge_fasta_folder(cls, folder_path, output_path):
        """
        合并 fasta 文件,用于 esm 推理
        """
        print(f"[Info] folder_path: {folder_path}")
        print(f"[Info] output_path: {output_path}")
        assert os.path.isdir(folder_path)
        path_list = traverse_dir_files_for_large(folder_path, ext="fasta")
        print(f"[Info] fasta: {len(path_list)}")
        seq_set = set()
        for path in tqdm(path_list, "[Info] fasta"):
            data_lines = read_file(path)
            n = len(data_lines)
            for i in range(1, n, 2):
                seq = data_lines[i]
                if seq:
                    seq_set.add(seq)
        seq_list = list(seq_set)
        print(f"[Info] seq unique: {len(seq_list)}")
        # create_empty_file(output_path)
        seq_lines = []
        header_set = set()
        for seq in tqdm(seq_list, "[Info] seq"):
            header = cls.seq_encoder(seq)
            header_set.add(header)
            seq_lines.append(f">{header}")
            seq_lines.append(seq)
        assert len(seq_lines) // 2 == len(header_set)
        write_list_to_file(output_path, seq_lines)
        print(f"[Info] over! {output_path}")


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-f",
        "--folder-path",
        type=Path,
        required=True,
    )
    parser.add_argument(
        "-o",
        "--output-path",
        type=Path,
        required=True
    )
    args = parser.parse_args()

    folder_path = str(args.folder_path)
    output_path = str(args.output_path)
    if os.path.isfile(output_path):
        warnings.warn(f"The output file exists, append lines to it! {output_path}")
    # from root_dir import DATA_DIR
    # folder_path = os.path.join(DATA_DIR, "fasta")
    # output_path = os.path.join(DATA_DIR, "all.fasta")
    Esm2FastaGenerator.merge_fasta_folder(folder_path, output_path)


def main2():
    from root_dir import DATA_DIR
    feat_path = os.path.join(DATA_DIR, "fffd26f4307d76eec938ac9c2c93a698.pt")
    Esm2FastaGenerator.load_feat(feat_path, is_print=True)


if __name__ == '__main__':
    main()
    # main2()

输出的序列 ESM2 特征包括:

  • label 序列描述
  • representations 序列表征 LxH
  • mean_representations 均值化表征 H
  • bos_representations 起始 Token 表征 H
  • contacts 序列接触表征 LxL

例如 序列长度是 65,ESM2 650M 的 Embeddings 是 1280,ESM2 3B 是 2560,即:

[Info] rep: dict_keys(['label', 'representations', 'contacts'])
[Info] label: MAKDSKAPVVEIFDERDGCTSAGSTGKASDAGEKGLLVKVSMQKVGYNAIMAKSVAASYMNK
[Info] representations: 36: torch.Size([62, 2560])
[Info] contacts: torch.Size([62, 62])

其中 序列长度 235 的 ESM2 3B 特征,约是 2.6M,序列长度 65 的 ESM2 650M 特征,约是 361 KB。

4. 测试 ESM2 推理脚本

推理脚本:

#!/usr/bin/env python
# -- coding: utf-8 --
"""
Copyright (c) 2022. All rights reserved.
Created by C. L. Wang on 2023/9/11
"""
import math
import os
import sys
import time

import torch

import esm

p = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if p not in sys.path:
    sys.path.append(p)

from myutils.project_utils import time_elapsed


class Esm2Infer(object):
    """
    推理 ESM2 特征
    """
    def __init__(self):
        print("[Info] 加载模型开始! ")
        s_time = time.time()
        self.model, self.alphabet = esm.pretrained.esm2_t33_650M_UR50D()
        print(f"[Info] vocab: {self.alphabet.to_dict()}")
        self.batch_converter = self.alphabet.get_batch_converter()
        self.model.eval()  # disables dropout for deterministic results
        print(f"[Info] 加载模型完成! 耗时: {time_elapsed(s_time, time.time())}")

    def predict(self, data_list):
        """
        数据示例:
        data_list = [
            ("protein1", "MKTVRQERLKSIVRILERSKEPVSGAQLAEELSVSRQVIVQDIAYLRSLGYNIVATPRGYVLAGG"),
            ("protein2", "KALTARQQEVFDLIRDHISQTGMPPTRAEIAQRLGFRSPNAAEEHLKALARKGVIEIVSGASRGIRLLQEE"),
            ("protein2 with mask", "KALTARQQEVFDLIRD<mask>ISQTGMPPTRAEIAQRLGFRSPNAAEEHLKALARKGVIEIVSGASRGIRLLQEE"),
            ("protein3",  "K A <mask> I S Q"),
        ]
        """
        print(f"[Info] data_list: {len(data_list)}")
        batch_labels, batch_strs, batch_tokens = self.batch_converter(data_list)
        print(f"[Info] batch_labels: {batch_labels}")
        print(f"[Info] batch_tokens: {batch_tokens}")
        batch_lens = (batch_tokens != self.alphabet.padding_idx).sum(1)
        print(f"[Info] batch_lens: {batch_lens}")  # 有效维数

        # Extract per-residue representations (on CPU)
        with torch.no_grad():
            results = self.model(batch_tokens, repr_layers=[33], return_contacts=True)
        token_representations = results["representations"][33]

        # Generate per-sequence representations via averaging
        # NOTE: token 0 is always a beginning-of-sequence token, so the first residue is token 1.
        sequence_representations = []
        for i, tokens_len in enumerate(batch_lens):
            feat = token_representations[i, 1: tokens_len - 1]
            # embeddings = feat.mean(0)
            # print(f"[Info] idx: {i}, feat: {feat.shape}, embeddings: {embeddings.shape}")
            # sequence_representations.append(embeddings)
            sequence_representations.append(feat)
        return sequence_representations


def main():
    data_list = [
        ("protein1", "MKTVRQERLKSIVRILERSKEPVSGAQLAEELSVSRQVIVQDIAYLRSLGYNIVATPRGYVLAGG"),
        ("protein2", "KALTARQQEVFDLIRDHISQTGMPPTRAEIAQRLGFRSPNAAEEHLKALARKGVIEIVSGASRGIRLLQEE"),
        ("protein2 with mask", "KALTARQQEVFDLIRD<mask>ISQTGMPPTRAEIAQRLGFRSPNAAEEHLKALARKGVIEIVSGASRGIRLLQEE"),
        ("protein3", "K A <mask> I S Q"),
    ]
    ei = Esm2Infer()
    ei.predict(data_list)


if __name__ == '__main__':
    main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1009990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

激光雷达检测负障碍物(附大概 C++ 代码)

检测效果如图&#xff0c;红色是正负的障碍物点&#xff1a; 障碍物根据其相对于地面的高度可以分为两类&#xff1a;正向障碍物和负向障碍物。在室外环境中&#xff0c;负障碍物是沟渠、悬崖、洞口或具有陡峭负坡度的地形&#xff0c;可能会造成安全隐患。 不慎通过道路坑洼处…

【电子通识】案例:采用电阻分压式采样电压的设计注意事项

在一些应用中,我们往往采用电阻分压方式来采样外部电压。如文章【Arduino+ESP32专题】案例:简单的实现NTC热敏电阻检测板卡温度中我们就使用一个10K的电阻与NTC电阻形成分压,通过ADC读取到的电压换算成温度值来检测外部环境温度。 当然,比如手持机的电池电压,如果没有一些…

docker-compose 中 depends_on 的作用

文章目录 depends_on 介绍depends_on 有一个长定义模式condition 说明required 说明 参考文档 depends_on 介绍 在 Docker Compose 中&#xff0c;depends_on 是一个用于定义服务之间依赖关系的关键字。它允许您指定一个或多个服务依赖于其他服务&#xff0c;以确保在启动或重…

基于STM32F407ZET6的环境温湿度监控系统(粤嵌GEC-M4)

注意使用事项&#xff1a; 开发板如下 由于外部晶振是8M&#xff0c;需要修改setup和stm32f4头文件的晶振值。 操作如下&#xff1a; system_stm32f4xx.c的254行 #define PLL_M 8stm32f4xx.h的127行 #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the Ex…

实战SRC漏洞挖掘全过程,流程详细【网络安全】

前言 记录一次完整的某SRC漏洞挖掘实战&#xff0c;为期一个多星期。文章有点长&#xff0c;请耐心看完&#xff0c;记录了完整的SRC漏洞挖掘实战 渗透过程 因为选择的幸运儿没有对测试范围进行规划&#xff0c;所以此次范围就是没有范围。 先上主域名看一眼&#xff0c;看…

2023 Google 开发者大会 – AI 领域的技术更新

大会介绍 Google 开发者大会是 Google 面向开发者和科技爱好者展示最新产品和平台的年度盛会。2023 Google 开发者大会 (Google I/O Connect | China) 为开发者提供丰富的学习资源&#xff0c;实践操作和现场演示&#xff0c;提供与谷歌专家互动、与其他开发者交流的契机&…

贝锐蒲公英客户端6.0发布,异地组网更快、更简单

贝锐蒲公英客户端6.0全新升级&#xff0c;新版本融合了企业版、个人版和个人管理端&#xff0c;不同身份用户可以统一登录&#xff0c;快速部署&#xff0c;即装即用&#xff0c;为异地组网带来更加简单、高效的解决方案。 快速部署、即装即用&#xff0c;支持不同身份用户统一…

langchain主要模块(三):Chain

langchain2之Chain langchain1.概念2.主要模块模型输入/输出 (Model I/O)数据连接 (Data connection)链式组装 (Chains)代理 (Agents)内存 (Memory)回调 (Callbacks) 3.链• LLMChain&#xff1a;• SimpleSequentialChain• Sequential Chains:• RouterChain&#xff1a; lan…

社群团购平台方的选品,无外乎就几个方面:

社群团购平台方选品&#xff0c;无外乎几个方面&#xff1a; 1、是个主推广爆品&#xff0c;好产品&#xff08;好产品的标准&#xff1a;有卖点&#xff1a;比如&#xff1a;有 品牌力、市场需求力、诱人的性价比等&#xff09; 2、你是否跟社群团购平台方说清楚这个产品的优…

什么是云存储,从对象存储说起?

在《存储系统形态之争,从块存储到统一存储》一文中我们提到了对象存储的概念,知道目前很多企业级存储都是支持对象存储的,比如EMC、NetApp和华为等。以EMC的对象存储为例,其最早在1998年就已经具备成熟的产品了,到目前已经有二十多年的历史了。如图是关于对象存储主要产品…

科研诚信与学术规范MOOC-错题集

为了确保学术和科研诚信&#xff0c;很多大学制定了荣誉法则。大学建立荣誉制度的初衷旨在预防大学生考试作弊。“反相对论公司”是对科学的不当干预。&#xff08;√&#xff09;科学具有普遍性&#xff0c;与种族、国籍、宗教、阶级和个人品质等个人因素无关。&#xff08;不…

GpsModule 350+ 常用GPS坐标地图

背景 开源库 GpsAndMap 的 GpsModule 模块中整理集成了 350 国内常用地市的GPS坐标地址&#xff0c;对于日常使用&#xff0c;例如打些标记&#xff0c;做些PPT展示&#xff0c;是非常方便的。 引入模块 pip install GpsAndMap 打印常用地市GPS地名清单 以下代码打印了常用…

【业务功能109】微服务-springcloud-springboot-Skywalking-链路追踪-监控

Skywalking skywalking是一个apm系统&#xff0c;包含监控&#xff0c;追踪&#xff0c;并拥有故障诊断能力的 分布式系统 一、Skywalking介绍 1.什么是SkyWalking Skywalking是由国内开源爱好者吴晟开源并提交到Apache孵化器的产品&#xff0c;它同时吸收了Zipkin /Pinpoint …

力扣 -- 1218. 最长定差子序列

参考代码&#xff1a; class Solution { public:int longestSubsequence(vector<int>& arr, int difference) {int narr.size();unordered_map<int,int> hash;//nums[i]绑定dp[i]hash[arr[0]]1;int ret1;for(int i1;i<n;i){int aarr[i];int ba-difference;…

电力系统安全问题,金融行业需警惕!

在现代金融业务的快速发展中&#xff0c;电力供应的可靠性变得愈发重要。金融交易和数据处理依赖于持续的电力供应&#xff0c;任何电力中断都可能导致严重的业务中断和损失。 为了应对这一挑战&#xff0c;金融机构广泛采用了不间断电源&#xff08;UPS&#xff09;系统&#…

QT 连接SQLServer数据库

1、安装SQLServer数据库后 在SQL Server 配置管理器中 设置后&#xff0c;需要重新启动SQL Server服务 2、重点* 配置ODBC数据源 由于没有配置ODBC&#xff0c;一直无法连接 开始——ODBC数据源管理程序(64位) 之后选择&#xff1a;使用用户输入登录ID和密码的SQL Server验…

Improving 3D Imaging with Pre-Trained Perpendicular 2D Diffusion Models

使用预先训练的垂直 2D 扩散模型改进 3D 成像 论文链接&#xff1a;https://arxiv.org/abs/2303.08440 项目链接&#xff1a;https://github.com/hyn2028/tpdm Abstract 扩散模型由于其众多的优点已经成为一种流行的图像生成和重建方法。然而&#xff0c;大多数基于扩散的逆…

只有68g的电竞鼠标,软硬件都能自定义,雷柏VT9Pro上手

最近雷柏的轻量化无线鼠标又出了一款新品VT9PRO&#xff0c;这款鼠标相比于之前的VT9升级不少&#xff0c;不仅机身更轻盈&#xff0c;而且配置更高&#xff0c;采用了原相定制3398光学引擎&#xff08;3395高定版&#xff09;&#xff0c;外加欧姆龙5000万次轻脆微动等专业级配…

Jmeter安装与测试

目录 一&#xff1a;JMeter简介&#xff1a; 二&#xff1a;JMeter安装与配置 三&#xff1a;JMeter主要原件 一&#xff1a;JMeter简介&#xff1a; JMeter&#xff0c;一个100&#xff05;的纯Java桌面应用&#xff0c;由Apache组织的开放源代码项目&#xff0c;它是功能 …

链式法则:概率论描述语言模型

目录 1.事件相互独立 2.链式法则 3.示例 4.语言模型中的链式法则 1.事件相互独立 事件相互独立就是&#xff1a;一个事件的发生与否&#xff0c;不会影响另外一个事件的发生。 当a和b两个事件互相独立时&#xff0c;有&#xff1a; P(a | b) P(a) 推广到3个事件就有下面…