> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-zh/ke-xue-yu-yan-jiu/esmfold.md).

# ESMFold 蛋白质结构

**Meta AI 的超快蛋白质结构预测** — 可在几秒钟内从氨基酸序列预测 3D 蛋白质结构，无需多序列比对。

> 🧬 开发者： **Meta AI Research** | MIT 许可证 | 比 AlphaFold2 快 10x–60x

***

## 什么是 ESMFold？

ESMFold 是 Meta AI 的蛋白质结构预测系统，利用 **进化尺度建模（ESM-2）** —— 世界上最大的蛋白质语言模型（150 亿参数）—— 直接从氨基酸序列预测 3D 蛋白质结构。

### 相较于 AlphaFold2 的主要优势

| 功能              | ESMFold   | AlphaFold2  |
| --------------- | --------- | ----------- |
| 需要 MSA          | ❌ 否       | ✅ 是         |
| 速度（典型蛋白质）       | **\~2 秒** | \~10 分钟–数小时 |
| 准确性（TM-score）   | \~0.87    | \~0.92      |
| GPU VRAM（650aa） | 约 8GB     | 约 8GB       |
| 单序列输入           | ✅ 是       | 有限          |
| 孤儿蛋白            | ✅ 非常好     | 有困难         |

### 为什么不需要 MSA？

AlphaFold2 需要 **多序列比对（MSA）** —— 收集并比对目标蛋白的进化同源序列。这在计算上开销很大，对于没有进化同源序列的新蛋白或工程化蛋白则完全不可行。

ESMFold 将进化信息存储 **在其语言模型权重中** （在 2.5 亿条蛋白质序列上训练），从而完全消除了 MSA 的需求。这使得它：

* **更快：** 无需 MSA 搜索（每次预测可节省数分钟）
* **更具可扩展性：** 高效处理整个蛋白质组
* **更适合新蛋白：** 工程化序列没有进化同源序列

***

## 在 Clore.ai 上快速开始

### 步骤 1：选择服务器

在 [clore.ai](https://clore.ai) 市场：

* **最低：** 带有 NVIDIA GPU 的 **16GB VRAM** （ESM-2 语言模型很大）
* **推荐：** A100 40GB、RTX 3090、RTX 4090 用于完整模型
* **更小的选项：** 使用 `esm2_t33_650M_UR50D` 适用于 8GB VRAM

GPU VRAM 指南：

| 蛋白质长度      | 模型变体        | 所需显存   |
| ---------- | ----------- | ------ |
| 最多 300 aa  | ESMFold（3B） | \~16GB |
| 最多 500 aa  | ESMFold（3B） | \~20GB |
| 最多 1000 aa | ESMFold（3B） | \~40GB |
| 最多 600 aa  | ESMFold（分块） | 约 8GB  |

### 步骤 2：构建自定义 Docker 镜像

```dockerfile
FROM pytorch/pytorch:2.11.0-cuda12.8-cudnn9-devel

# 系统依赖
RUN apt-get update && apt-get install -y \
    git \
    wget \
    curl \
    openssh-server \
    libhdf5-dev \
    pkg-config \
    && rm -rf /var/lib/apt/lists/*

# 配置 SSH
RUN mkdir /var/run/sshd && \
    echo 'root:esmfold' | chpasswd && \
    sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# 安装 ESMFold 和依赖项
RUN pip install --no-cache-dir \
    fair-esm[esmfold] \
    torch \
    biopython \
    biotite \
    fastapi \
    uvicorn \
    pydantic \
    openmm==8.0.0 \
    pdbfixer

# 安装 OpenFold（ESMFold 需要）
RUN pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

EXPOSE 22

CMD ["/usr/sbin/sshd", "-D"]
```

### 步骤 3：在 Clore.ai 上部署

* **Docker 镜像：** `yourname/esmfold:latest`
* **端口：** `22` （SSH）
* **环境变量：** `NVIDIA_VISIBLE_DEVICES=all`

***

## 安装与设置

### 方法 1：pip install

```bash
# 安装 ESMFold
pip install fair-esm[esmfold]

# 安装 OpenFold（必需依赖）
pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

# 可选但推荐
pip install biotite biopython
```

### 方法 2：从源代码安装

```bash
git clone https://github.com/facebookresearch/esm.git
cd esm
pip install -e ".[esmfold]"
```

### 验证安装

```python
import esm
print("ESM 版本：", esm.__version__)

# 快速模型加载测试
model = esm.pretrained.esmfold_v1()
print("ESMFold 加载成功！")
```

***

## 基础用法

### 预测单个蛋白质结构

```python
import torch
import esm

# 加载 ESMFold 模型
model = esm.pretrained.esmfold_v1()
model = model.eval().cuda()

# 可选：启用 chunk-size 以节省 VRAM
# 会增加计算时间，但减少 VRAM 使用
model.set_chunk_size(64)  # 降低可减少 VRAM 占用

# 蛋白质序列（示例：溶菌酶 C）
sequence = "KVFGRCELAAAMKRHGLDNYRGYSLGNWVCAAKFESNFNTQATNRNTDGSTDYGILQINSRWWCNDGRTPGSRNLCNIPCSALLSSDITASVNCAKKIVSDGNGMNAWVAWRNRCKGTDVQAWIRGCRL"

# 预测结构
with torch.no_grad():
    output = model.infer_pdb(sequence)

# 保存 PDB 文件
with open("lysozyme.pdb", "w") as f:
    f.write(output)

print(f"结构预测完成！已保存到 lysozyme.pdb")
print(f"序列长度：{len(sequence)} 个氨基酸")
```

### 预测多个序列（批处理）

```python
import torch
import esm

model = esm.pretrained.esmfold_v1()
model = model.eval().cuda()

sequences = {
    "protein_A": "MKTAYIAKQRQISFVKSHFSRQ...",
    "protein_B": "MGDVEKGKKIFVQKCAQCHTVEK...",
    "ubiquitin": "MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTLHLVLRLRGG",
}

for name, seq in sequences.items():
    with torch.no_grad():
        output = model.infer_pdb(seq)
    
    with open(f"{name}.pdb", "w") as f:
        f.write(output)
    
    print(f"已预测 {name}：{len(seq)} aa")

print("所有预测完成！")
```

### 获取每个残基的置信度（pLDDT）

```python
import torch
import esm
import numpy as np

model = esm.pretrained.esmfold_v1()
model = model.eval().cuda()

sequence = "MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTLHLVLRLRGG"

with torch.no_grad():
    output = model.infer(sequence)

# 提取 pLDDT 分数（每个残基的置信度）
plddt = output["plddt"].cpu().numpy()  # 形状：[1, seq_len]
plddt_per_residue = plddt[0]

print(f"平均 pLDDT：{plddt_per_residue.mean():.2f}")
print(f"高置信度残基（>90）：{(plddt_per_residue > 90).sum()}")
print(f"低置信度残基（<50）：{(plddt_per_residue < 50).sum()}")

# 对置信度区域分类
for i, score in enumerate(plddt_per_residue):
    if score >= 90:
        confidence = "非常高（蓝色）"
    elif score >= 70:
        confidence = "有信心（浅蓝色）"
    elif score >= 50:
        confidence = "低（黄色）"
    else:
        confidence = "非常低（橙色）"
    # print(f"残基 {i+1}：{score:.1f} - {confidence}")  # 取消注释可查看完整输出
```

***

## REST API 服务器

为 ESMFold 构建生产级 API：

```python
# api_server.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import torch
import esm
import time
from typing import Optional

app = FastAPI(
    title="ESMFold 蛋白质结构预测 API",
    description="从氨基酸序列预测蛋白质 3D 结构",
    version="1.0.0"
)

# 在启动时加载模型
print("正在加载 ESMFold 模型（这需要约 30 秒）...")
model = esm.pretrained.esmfold_v1()
model = model.eval().cuda()
model.set_chunk_size(64)  # 内存优化
print("ESMFold 已就绪！")

class PredictionRequest(BaseModel):
    sequence: str
    name: Optional[str] = "protein"

class PredictionResponse(BaseModel):
    name: str
    sequence_length: int
    pdb_content: str
    mean_plddt: float
    inference_time_seconds: float

@app.post("/predict", response_model=PredictionResponse)
async def predict_structure(request: PredictionRequest):
    """从氨基酸序列预测蛋白质 3D 结构。"""
    
    # 验证序列
    valid_aa = set("ACDEFGHIKLMNPQRSTVWY")
    sequence = request.sequence.upper().strip()
    
    invalid = set(sequence) - valid_aa
    if invalid:
        raise HTTPException(
            status_code=400,
            detail=f"序列中包含无效氨基酸：{invalid}。请使用标准 20 种氨基酸。"
        )
    
    if len(sequence) > 2000:
        raise HTTPException(
            status_code=400,
            detail="序列过长（最多 2000 个氨基酸）。对于更长序列，请使用分块预测。"
        )
    
    start_time = time.time()
    
    try:
        with torch.no_grad():
            output = model.infer(sequence)
            pdb_content = model.output_to_pdb(output)[0]
            
        plddt = output["plddt"].cpu().numpy()[0]
        mean_plddt = float(plddt.mean())
        
    except torch.cuda.OutOfMemoryError:
        torch.cuda.empty_cache()
        raise HTTPException(
            status_code=507,
            detail="GPU 显存不足。请尝试更短的序列或减小 chunk size。"
        )
    
    inference_time = time.time() - start_time
    
    return PredictionResponse(
        name=request.name,
        sequence_length=len(sequence),
        pdb_content=pdb_content,
        mean_plddt=mean_plddt,
        inference_time_seconds=round(inference_time, 2)
    )

@app.get("/health")
def health():
    gpu_mem = torch.cuda.memory_allocated() / 1024**3 if torch.cuda.is_available() else 0
    return {
        "status": "ok",
        "model": "ESMFold v1",
        "device": str(next(model.parameters()).device),
        "gpu_memory_gb": round(gpu_mem, 2)
    }

@app.get("/")
def root():
    return {"message": "ESMFold API — 使用 /predict 预测结构，使用 /docs 查看 Swagger UI"}
```

```bash
# 运行 API
pip install fastapi uvicorn
uvicorn api_server:app --host 0.0.0.0 --port 8080 --workers 1
```

***

## API 使用示例

```bash
# 通过 API 预测结构
curl -X POST http://localhost:8080/predict \
  -H "Content-Type: application/json" \\
  -d '{
    "name": "ubiquitin",
    "sequence": "MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTLHLVLRLRGG"
  }' | python3 -c "
import sys, json
data = json.load(sys.stdin)
print(f\"名称：{data['name']}\")
print(f\"长度：{data['sequence_length']} aa\")
print(f\"平均 pLDDT：{data['mean_plddt']:.1f}\")
print(f\"时间：{data['inference_time_seconds']}s\")
# 保存 PDB
open('ubiquitin.pdb', 'w').write(data['pdb_content'])
print('PDB 已保存！')
"
```

***

## 批处理脚本

```python
# batch_predict.py
import torch
import esm
import os
from pathlib import Path
from Bio import SeqIO  # pip install biopython

def predict_fasta(fasta_file: str, output_dir: str, chunk_size: int = 64):
    """预测 FASTA 文件中的所有序列结构。"""
    
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    
    # 加载模型
    model = esm.pretrained.esmfold_v1()
    model = model.eval().cuda()
    model.set_chunk_size(chunk_size)
    
    # 读取 FASTA
    sequences = list(SeqIO.parse(fasta_file, "fasta"))
    print(f"正在为 {len(sequences)} 个蛋白质预测结构...")
    
    results = []
    for i, record in enumerate(sequences):
        seq = str(record.seq).upper()
        name = record.id
        
        print(f"[{i+1}/{len(sequences)}] 正在预测 {name}（{len(seq)} aa）...")
        
        try:
            with torch.no_grad():
                output = model.infer(seq)
                pdb = model.output_to_pdb(output)[0]
            
            plddt = output["plddt"].cpu().numpy()[0].mean()
            
            # 保存 PDB
            output_path = os.path.join(output_dir, f"{name}.pdb")
            with open(output_path, "w") as f:
                f.write(pdb)
            
            results.append({
                "name": name,
                "length": len(seq),
                "mean_plddt": round(float(plddt), 2),
                "output": output_path,
                "status": "success"
            })
            
        except Exception as e:
            print(f"  错误：{e}")
            results.append({"name": name, "status": f"error: {e}"})
    
    # 写入摘要
    import csv
    with open(os.path.join(output_dir, "summary.csv"), "w") as f:
        writer = csv.DictWriter(f, fieldnames=["name", "length", "mean_plddt", "output", "status"])
        writer.writeheader()
        writer.writerows(results)
    
    success = sum(1 for r in results if r.get("status") == "success")
    print(f"\n完成！成功预测了 {success}/{len(sequences)} 个结构")
    print(f"结果已保存到 {output_dir}/")

if __name__ == "__main__":
    predict_fasta(
        fasta_file="./proteins.fasta",
        output_dir="./predicted_structures",
        chunk_size=64
    )
```

***

## 结构可视化

### 使用 Py3Dmol（Jupyter / Python）

```python
import py3Dmol  # pip install py3Dmol

with open("protein.pdb") as f:
    pdb_data = f.read()

view = py3Dmol.view(width=800, height=600)
view.addModel(pdb_data, "pdb")
view.setStyle({"cartoon": {"colorscheme": "ssJmol"}})
view.zoomTo()
view.show()
```

### 使用 PyMOL

```bash
# 安装 PyMOL
apt-get install pymol

# 打开结构
pymol lysozyme.pdb
```

### 使用 Biotite 进行程序化可视化

```python
import biotite.structure.io.pdb as pdb
import biotite.structure as struc
import numpy as np

# 加载预测结构
pdb_file = pdb.PDBFile.read("lysozyme.pdb")
structure = pdb.get_structure(pdb_file, model=1)

# 分析二级结构
sse = struc.annotate_sse(structure)

helix_frac = (sse == 'a').mean() * 100
sheet_frac = (sse == 'b').mean() * 100
coil_frac = (sse == 'c').mean() * 100

print(f"二级结构组成：")
print(f"  α 螺旋：  {helix_frac:.1f}%")
print(f"  β 折叠：   {sheet_frac:.1f}%")
print(f"  无规卷曲/其他：   {coil_frac:.1f}%")
```

***

## 内存优化

### chunk\_size 指南

```python
# chunk_size 越小 = VRAM 越少，预测越慢
# chunk_size 越大 = VRAM 越多，预测越快

# 适用于 8GB VRAM（可支持约 400 aa）
model.set_chunk_size(32)

# 适用于 16GB VRAM（可支持约 700 aa）
model.set_chunk_size(64)

# 适用于 40GB VRAM（可支持约 2000 aa，无需分块）
model.set_chunk_size(None)  # 禁用分块
```

### 超长序列的 CPU 卸载

```python
# 在 CPU 上加载模型，每次推理时再移到 GPU
model = esm.pretrained.esmfold_v1()
model = model.eval()

# 推理时移到 GPU，之后再回到 CPU
model = model.cuda()
with torch.no_grad():
    output = model.infer(sequence)
model = model.cpu()  # 释放 GPU 内存
torch.cuda.empty_cache()
```

***

## 故障排查

### CUDA 显存不足

```bash
# 减小 chunk size
model.set_chunk_size(32)  # 或甚至 16

# 检查可用 VRAM
nvidia-smi --query-gpu=memory.free --format=csv,noheader

# 对于非常长的蛋白质，将其拆分为多个结构域
# 通常可安全地将 > 1000 aa 的蛋白质拆分为 300-500 aa 的结构域
```

### openfold 的 ImportError

```bash
# 使用特定提交重新安装
pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

# 检查安装
python -c "import openfold; print('OpenFold 正常')"
```

### 模型加载缓慢

```bash
# 首次加载会下载 2.7GB 模型权重——这是正常的
# 后续加载使用缓存的权重（加载时间约 30 秒）

# 检查缓存位置
python -c "import torch; print(torch.hub.get_dir())"
ls ~/.cache/torch/hub/
```

{% hint style="warning" %}
**内存提示：** ESMFold 的语言模型（ESM-2，15B 参数）需要大量显存。对于显存低于 16GB 的 GPU 服务器，请使用 `esm2_t33_650M_UR50D` backbone 变体，或启用更激进的分块。
{% endhint %}

{% hint style="info" %}
**pLDDT 解释：**

* **>90** = 置信度非常高（在 AlphaFold 配色中为蓝色）
* **70–90** = 置信度较高（青色/浅蓝色）
* **50–70** = 置信度较低（黄色）——请谨慎对待
* **<50** = 置信度极低（橙色/红色）——很可能是无序区域
  {% endhint %}

***

## Clore.ai GPU 推荐

ESMFold 的显存需求主要由 ESM-2 15B 参数语言模型决定。序列长度会带来额外的内存开销。

| GPU       | 显存    | Clore.ai 价格                       | 最大序列长度           | 预测时间（300 aa） |
| --------- | ----- | --------------------------------- | ---------------- | ------------ |
| RTX 3090  | 24 GB | $0.07–0.21/小时                     | \~400 aa（启用分块）   | \~8 秒        |
| RTX 4090  | 24 GB | $0.14–0.42/小时                     | \~400 aa（启用分块）   | \~5 秒        |
| A100 40GB | 40 GB | [裸机](https://clore.ai/bare-metal) | \~800 aa 轻松支持    | \~3 秒        |
| A100 80GB | 80 GB | [裸机](https://clore.ai/bare-metal) | \~1500+ aa，大型蛋白质 | \~4 秒        |

{% hint style="warning" %}
**最低显存：16GB。** 使用完整的 ESM-2 backbone 时，ESMFold 无法在 8GB GPU 上运行。RTX 3090/4090（24GB）可以在不分块的情况下处理最多约 400 个氨基酸的蛋白质——请启用 `chunk_size=64` 在 API 中用于更长序列。
{% endhint %}

**研究用途的最佳性价比：** RTX 3090 每小时 $0.07–0.21 的价格即可处理绝大多数蛋白质结构预测任务（人类蛋白平均长度约 300–400 aa）。每次预测约 8 秒，每小时可处理约 450 个结构，总成本约 $0.12——相比之下，AlphaFold2 需要进行 MSA 计算，每个结构要花费数分钟。

**高通量蛋白质组学：** 对于筛选数千条序列，A100 40GB（[裸机](https://clore.ai/bare-metal)）配合批量推理，每小时可处理约 1,200+ 次预测——适用于蛋白质组规模研究。

***

## 资源

* 🐙 **GitHub：** [github.com/facebookresearch/esm](https://github.com/facebookresearch/esm)
* 🤗 **模型：** [huggingface.co/facebook/esmfold\_v1](https://huggingface.co/facebook/esmfold_v1)
* 📄 **论文：** [利用语言模型进行原子级蛋白质结构的进化尺度预测（Science，2023）](https://www.science.org/doi/10.1126/science.ade2574)
* 🌐 **ESM 宏基因组图谱：** [esmatlas.com](https://esmatlas.com) ——使用 ESMFold 预测了 7.72 亿个结构
* 💻 **Meta AI 博客：** [ai.meta.com/blog/protein-folding-esmfold-metagenomics](https://ai.meta.com/blog/protein-folding-esmfold-metagenomics/)
* 🔬 **ESM 更新日志：** [github.com/facebookresearch/esm/blob/main/CHANGELOG.md](https://github.com/facebookresearch/esm/blob/main/CHANGELOG.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-zh/ke-xue-yu-yan-jiu/esmfold.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
