> 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-ru/nauka-i-issledovaniya/esmfold.md).

# Структура белка ESMFold

**Ультрабыстрое предсказание структуры белков от Meta AI** — предсказывайте 3D-структуры белков по последовательностям аминокислот за считанные секунды, без выравниваний множественных последовательностей.

> 🧬 Разработано **Исследования Meta AI** | Лицензия MIT | в 10–60 раз быстрее, чем AlphaFold2

***

## Что такое ESMFold?

ESMFold — это система предсказания структуры белков от Meta AI, которая использует **Evolutionary Scale Modeling (ESM-2)** — крупнейшая в мире языковая модель для белков (15 миллиардов параметров) — для прямого предсказания 3D-структур белков по последовательностям аминокислот.

### Ключевые преимущества перед AlphaFold2

| Функция                       | ESMFold         | AlphaFold2           |
| ----------------------------- | --------------- | -------------------- |
| Требуется MSA                 | ❌ Нет           | ✅ Да                 |
| Скорость (типичный белок)     | **\~2 секунды** | \~10 минут–часов     |
| Точность (TM-score)           | \~0.87          | \~0.92               |
| GPU VRAM (650 аминокислот)    | \~8 ГБ          | \~8 ГБ               |
| Ввод одной последовательности | ✅ Да            | Ограничено           |
| Одиночные (orphan) белки      | ✅ Отлично       | Испытывает трудности |

### Почему без MSA?

AlphaFold2 требует **выравнивание множественных последовательностей (MSA)** — сбор и выравнивание эволюционных родственников запрашиваемого белка. Это вычислительно дорого и невозможно для новых или спроектированных белков, у которых нет эволюционных родственников.

ESMFold хранит эволюционную информацию **в весах своей языковой модели** (обученной на 250 миллионах белковых последовательностей), полностью исключая MSA. Это делает его:

* **Быстрее:** Нет поиска MSA (минуты экономятся на каждом предсказании)
* **Более масштабируемым:** Эффективно обрабатывать целые протеомы
* **Лучше для новых белков:** Сконструированные последовательности не имеют эволюционных родственников

***

## Быстрый старт на Clore.ai

### Шаг 1: Выбор сервера

На [clore.ai](https://clore.ai) рынок:

* **Минимум:** NVIDIA GPU с **16 ГБ VRAM** (языковая модель ESM-2 большая)
* **Рекомендуется:** A100 40GB, RTX 3090, RTX 4090 для полного моделирования
* **Более компактный вариант:** Используйте `esm2_t33_650M_UR50D` для 8GB VRAM

Руководство по GPU VRAM:

| Длина белка         | Вариант модели  | Требуемая VRAM |
| ------------------- | --------------- | -------------- |
| До 300 аминокислот  | ESMFold (3B)    | \~16GB         |
| До 500 аминокислот  | ESMFold (3B)    | \~20GB         |
| До 1000 аминокислот | ESMFold (3B)    | \~40GB         |
| До 600 аминокислот  | ESMFold (chunk) | \~8 ГБ         |

### Шаг 2: Создание пользовательского Docker-образа

```dockerfile
FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-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()

# Необязательно: включить размер чанка, чтобы сэкономить 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)} аминокислот")

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, длина_последовательности]
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 сервер

Создайте production API для ESMFold:

```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="API предсказания структуры белков ESMFold",
    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 закончилась память. Попробуйте более короткую последовательность или уменьшите размер чанка."
        )
    
    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\"Name: {data['name']}\")
print(f\"Length: {data['sequence_length']} aa\")
print(f\"Mean pLDDT: {data['mean_plddt']:.1f}\")
print(f\"Time: {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)} аминокислот)...")
        
        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}%")
```

***

## Оптимизация памяти

### Руководство по размеру чанка

```python
# Меньший chunk_size = меньше VRAM, медленнее предсказание
# Больший chunk_size = больше VRAM, быстрее предсказание

# Для 8GB VRAM (позволяет до ~400 аминокислот)
model.set_chunk_size(32)

# Для 16GB VRAM (до ~700 аминокислот)
model.set_chunk_size(64)

# Для 40GB VRAM (до ~2000 аминокислот, без чанкинга)
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
# Уменьшить размер чанка
model.set_chunk_size(32)  # или даже 16

# Проверить свободную VRAM
nvidia-smi --query-gpu=memory.free --format=csv,noheader

# Для очень длинных белков разделяйте на домены
# Обычно безопасно разделять белки > 1000 аминокислот на домены по 300–500 аминокислот
```

### ImportError для openfold

```bash
# Переустановить с конкретным коммитом
pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

# Проверить установку
python -c "import openfold; print('OpenFold OK')"
```

### Медленная загрузка модели

```bash
# При первой загрузке скачиваются веса модели 2.7GB — это нормально
# Последующие загрузки используют кэшированные веса (~30s для загрузки)

# Проверить расположение кэша
python -c "import torch; print(torch.hub.get_dir())"
ls ~/.cache/torch/hub/
```

{% hint style="warning" %}
**Примечание о памяти:** Языковая модель ESMFold (ESM-2 15B параметров) требует значительного объёма VRAM. Для GPU-серверов с менее чем 16GB VRAM используйте `esm2_t33_650M_UR50D` вариант backbone или включите агрессивный чанкинг.
{% endhint %}

{% hint style="info" %}
**Интерпретация pLDDT:**

* **>90** = Очень высокое доверие (синий в раскраске AlphaFold)
* **70–90** = Уверенно (голубой/светло-голубой)
* **50–70** = Низкое доверие (жёлтый) — относиться с осторожностью
* **<50** = Очень низкое доверие (оранжевый/красный) — вероятно, неупорядоченный регион
  {% endhint %}

***

## Рекомендации Clore.ai по GPU

Требование VRAM ESMFold определяется в основном языковой моделью ESM-2 с 15 миллиардами параметров. Длина последовательности добавляет дополнительную нагрузку на память.

| GPU       | VRAM  | Цена Clore.ai | Максимальная длина последовательности | Время предсказания (300 аминокислот) |
| --------- | ----- | ------------- | ------------------------------------- | ------------------------------------ |
| RTX 3090  | 24 ГБ | \~$0.12/ч     | \~400 аминокислот (с чанкингом)       | \~8 секунд                           |
| RTX 4090  | 24 ГБ | \~$0.70/ч     | \~400 аминокислот (с чанкингом)       | \~5 секунд                           |
| A100 40GB | 40 ГБ | \~$1.20/ч     | \~800 аминокислот комфортно           | \~3 секунды                          |
| A100 80GB | 80 ГБ | \~$2.00/ч     | \~1500+ аминокислот, большие белки    | \~4 секунды                          |

{% hint style="warning" %}
**Минимальная VRAM: 16GB.** ESMFold не может работать на 8GB GPU с полным бэкендом ESM-2. RTX 3090/4090 (24GB) могут обрабатывать белки до \~400 аминокислот без чанкинга — включите `chunk_size=64` в API для более длинных последовательностей.
{% endhint %}

**Лучшее соотношение цены/качества для исследований:** RTX 3090 при \~$0.12/ч покрывает подавляющее большинство задач предсказания структуры белков (средний человеческий белок: \~300–400 аминокислот). При \~8 секундах на предсказание вы можете обработать \~450 структур в час примерно за \~$0.12 — по сравнению с AlphaFold2, который требует вычислений MSA, занимающих минуты на структуру.

**Высокопроизводительная протеомика:** Для скрининга тысяч последовательностей A100 40GB (\~$1.20/ч) с батчевой инференцией обрабатывает \~1200+ предсказаний в час — жизнеспособно для исследований в масштабе протеома.

***

## Ресурсы

* 🐙 **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) — предсказано 772M структур с помощью ESMFold
* 💻 **Блог Meta AI:** [ai.meta.com/blog/protein-folding-esmfold-metagenomics](https://ai.meta.com/blog/protein-folding-esmfold-metagenomics/)
* 🔬 **Changelog 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-ru/nauka-i-issledovaniya/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.
