> 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-fr/science-et-recherche/esmfold.md).

# Structure protéique ESMFold

**Prédiction de structure protéique ultra-rapide par Meta AI** — prédire des structures protéiques 3D à partir de séquences d'acides aminés en quelques secondes, sans alignements de séquences multiples.

> 🧬 Développé par **Meta AI Research** | Licence MIT | 10x–60x plus rapide qu'AlphaFold2

***

## Qu'est-ce qu'ESMFold ?

ESMFold est le système de prédiction de structure protéique de Meta AI qui exploite **Evolutionary Scale Modeling (ESM-2)** — le plus grand modèle de langage protéique au monde (15 milliards de paramètres) — pour prédire des structures protéiques 3D directement à partir de séquences d'acides aminés.

### Avantages clés par rapport à AlphaFold2

| Fonctionnalité             | ESMFold          | AlphaFold2          |
| -------------------------- | ---------------- | ------------------- |
| MSA requis                 | ❌ Non            | ✅ Oui               |
| Vitesse (protéine typique) | **\~2 secondes** | \~10 minutes–heures |
| Précision (score TM)       | \~0.87           | \~0.92              |
| VRAM GPU (650 aa)          | \~8GB            | \~8GB               |
| Entrée séquence unique     | ✅ Oui            | Limité              |
| Protéines orphelines       | ✅ Excellent      | A des difficultés   |

### Pourquoi pas de MSA ?

AlphaFold2 nécessite **Alignement de séquences multiples (MSA)** — collecter et aligner les parents évolutifs de la protéine requête. Cela est coûteux en calcul et impossible pour des protéines nouvelles ou conçues sans parents évolutifs.

ESMFold stocke l'information évolutive **dans les poids de son modèle de langage** (entraîné sur 250 millions de séquences protéiques), éliminant entièrement le MSA. Cela le rend :

* **Plus rapide :** Pas de recherche MSA (minutes économisées par prédiction)
* **Plus évolutif :** Traiter efficacement des protéomes entiers
* **Mieux pour les protéines nouvelles :** Les séquences conçues n'ont pas de parents évolutifs

***

## Démarrage rapide sur Clore.ai

### Étape 1 : Choisir un serveur

Sur [clore.ai](https://clore.ai) place de marché :

* **Minimum :** GPU NVIDIA avec **16 Go de VRAM** (le modèle de langage ESM-2 est volumineux)
* **Recommandé :** A100 40GB, RTX 3090, RTX 4090 pour le modèle complet
* **Option plus petite :** Utilisez `esm2_t33_650M_UR50D` pour 8GB de VRAM

Guide VRAM GPU :

| Longueur de la protéine | Variante du modèle | VRAM requise |
| ----------------------- | ------------------ | ------------ |
| Jusqu'à 300 aa          | ESMFold (3B)       | \~16GB       |
| Jusqu'à 500 aa          | ESMFold (3B)       | \~20GB       |
| Jusqu'à 1000 aa         | ESMFold (3B)       | \~40GB       |
| Jusqu'à 600 aa          | ESMFold (chunk)    | \~8GB        |

### Étape 2 : Construire une image Docker personnalisée

```dockerfile
FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-devel

# Dépendances système
RUN apt-get update && apt-get install -y \
    git \
    wget \
    curl \
    openssh-server \
    libhdf5-dev \
    pkg-config \
    && rm -rf /var/lib/apt/lists/*

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

# Installer ESMFold et dépendances
RUN pip install --no-cache-dir \
    fair-esm[esmfold] \
    torch \
    biopython \
    biotite \
    fastapi \
    uvicorn \
    pydantic \
    openmm==8.0.0 \
    pdbfixer

# Installer OpenFold (requis pour ESMFold)
RUN pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

EXPOSE 22

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

### Étape 3 : Déployer sur Clore.ai

* **Image Docker :** `yourname/esmfold:latest`
* **Ports :** `22` (SSH)
* **Environnement :** `NVIDIA_VISIBLE_DEVICES=all`

***

## Installation et configuration

### Méthode 1 : pip install

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

# Installer OpenFold (dépendance requise)
pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

# Optionnel mais recommandé
pip install biotite biopython
```

### Méthode 2 : Depuis les sources

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

### Vérifier l'installation

```python
import esm
print("Version d'ESM :", esm.__version__)

# Test rapide de chargement du modèle
model = esm.pretrained.esmfold_v1()
print("ESMFold chargé avec succès !")
```

***

## Utilisation basique

### Prédire la structure d'une seule protéine

```python
import torch
import esm

# Charger le modèle ESMFold
model = esm.pretrained.esmfold_v1()
model = model.eval().cuda()

# Optionnel : Activer la taille de chunk pour économiser de la VRAM
# Augmente le temps de calcul mais réduit l'utilisation de la VRAM
model.set_chunk_size(64)  # Réduire pour moins de VRAM

# Séquence protéique (exemple : Lysozyme C)
sequence = "KVFGRCELAAAMKRHGLDNYRGYSLGNWVCAAKFESNFNTQATNRNTDGSTDYGILQINSRWWCNDGRTPGSRNLCNIPCSALLSSDITASVNCAKKIVSDGNGMNAWVAWRNRCKGTDVQAWIRGCRL"

# Prédire la structure
with torch.no_grad():
    output = model.infer_pdb(sequence)

# Sauvegarder le fichier PDB
with open("lysozyme.pdb", "w") as f:
    f.write(output)

print(f"Structure prédite ! Enregistrée dans lysozyme.pdb")
print(f"Longueur de la séquence : {len(sequence)} acides aminés")
```

### Prédire plusieurs séquences (lot)

```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"Prédit {name} : {len(seq)} aa")

print("Toutes les prédictions terminées !")
```

### Obtenir la confiance par résidu (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)

# Extraire les scores pLDDT (confiance par résidu)
plddt = output["plddt"].cpu().numpy()  # Forme : [1, seq_len]
plddt_par_residu = plddt[0]

print(f"pLDDT moyen : {plddt_par_residu.mean():.2f}")
print(f"Résidus à haute confiance (>90) : {(plddt_par_residu > 90).sum()}")
print(f"Résidus à faible confiance (<50) : {(plddt_par_residu < 50).sum()}")

# Classer les régions de confiance
for i, score in enumerate(plddt_par_residu):
    if score >= 90:
        confidence = "Très élevée (bleu)"
    elif score >= 70:
        confidence = "Confiant (bleu clair)"
    elif score >= 50:
        confidence = "Faible (jaune)"
    else:
        confidence = "Très faible (orange)"
    # print(f"Résidu {i+1} : {score:.1f} - {confidence}")  # Décommentez pour sortie complète
```

***

## Serveur API REST

Construire une API de production pour 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 de prédiction de structure protéique ESMFold",
    description="Prédire des structures protéiques 3D à partir de séquences d'acides aminés",
    version="1.0.0"
)

# Charger le modèle au démarrage
print("Chargement du modèle ESMFold (cela prend ~30 secondes)...")
model = esm.pretrained.esmfold_v1()
model = model.eval().cuda()
model.set_chunk_size(64)  # Optimisation mémoire
print("ESMFold prêt !")

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):
    """Prédire la structure protéique 3D à partir d'une séquence d'acides aminés."""
    
    # Valider la séquence
    valid_aa = set("ACDEFGHIKLMNPQRSTVWY")
    sequence = request.sequence.upper().strip()
    
    invalid = set(sequence) - valid_aa
    if invalid:
        raise HTTPException(
            status_code=400,
            detail=f"Acides aminés invalides dans la séquence : {invalid}. Utilisez les 20 acides aminés standards."
        )
    
    if len(sequence) > 2000:
        raise HTTPException(
            status_code=400,
            detail="Séquence trop longue (max 2000 acides aminés). Pour des séquences plus longues, utilisez la prédiction par morceaux."
        )
    
    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 hors mémoire. Essayez une séquence plus courte ou réduisez la taille des morceaux."
        )
    
    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": "API ESMFold — /predict pour prédire des structures, /docs pour l'interface Swagger"}
```

```bash
# Lancer l'API
pip install fastapi uvicorn
uvicorn api_server:app --host 0.0.0.0 --port 8080 --workers 1
```

***

## Exemples d'utilisation de l'API

```bash
# Prédire la structure via l'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\"pLDDT moyen : {data['mean_plddt']:.1f}\")
print(f\"Temps : {data['inference_time_seconds']}s\")
# Sauvegarder le PDB
open('ubiquitin.pdb', 'w').write(data['pdb_content'])
print('PDB enregistré !')
"
```

***

## Script de traitement par lot

```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):
    """Prédire les structures pour toutes les séquences d'un fichier FASTA."""
    
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    
    # Charger le modèle
    model = esm.pretrained.esmfold_v1()
    model = model.eval().cuda()
    model.set_chunk_size(chunk_size)
    
    # Lire le FASTA
    sequences = list(SeqIO.parse(fasta_file, "fasta"))
    print(f"Prédiction des structures pour {len(sequences)} protéines...")
    
    results = []
    for i, record in enumerate(sequences):
        seq = str(record.seq).upper()
        name = record.id
        
        print(f"[{i+1}/{len(sequences)}] Prédiction de {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()
            
            # Sauvegarder le 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"  Erreur : {e}")
            results.append({"name": name, "status": f"error: {e}"})
    
    # Écrire le récapitulatif
    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"\nTerminé ! {success}/{len(sequences)} structures prédites avec succès")
    print(f"Résultats enregistrés dans {output_dir}/")

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

***

## Visualisation des structures

### Utilisation de 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()
```

### Utilisation de PyMOL

```bash
# Installer PyMOL
apt-get install pymol

# Ouvrir la structure
pymol lysozyme.pdb
```

### Visualisation programmatique avec Biotite

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

# Charger la structure prédite
pdb_file = pdb.PDBFile.read("lysozyme.pdb")
structure = pdb.get_structure(pdb_file, model=1)

# Analyser la structure secondaire
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"Composition de la structure secondaire :")
print(f"  Hélice alpha :  {helix_frac:.1f}%")
print(f"  Feuillet bêta :   {sheet_frac:.1f}%")
print(f"  Boucle/Autre :   {coil_frac:.1f}%")
```

***

## Optimisation de la mémoire

### Guide de taille de chunk

```python
# Chunk_size plus faible = moins de VRAM, prédiction plus lente
# Chunk_size plus élevé = plus de VRAM, prédiction plus rapide

# Pour 8GB de VRAM (permet jusqu'à ~400 aa)
model.set_chunk_size(32)

# Pour 16GB de VRAM (jusqu'à ~700 aa)
model.set_chunk_size(64)

# Pour 40GB de VRAM (jusqu'à ~2000 aa, pas de chunking)
model.set_chunk_size(None)  # Désactiver le chunking
```

### Déchargement CPU pour des séquences très longues

```python
# Charger le modèle sur le CPU, le déplacer sur le GPU par inférence
model = esm.pretrained.esmfold_v1()
model = model.eval()

# Déplacer sur GPU pour l'inférence, revenir sur CPU après
model = model.cuda()
with torch.no_grad():
    output = model.infer(sequence)
model = model.cpu()  # Libérer la mémoire GPU
torch.cuda.empty_cache()
```

***

## Dépannage

### CUDA : mémoire insuffisante

```bash
# Réduire la taille des chunks
model.set_chunk_size(32)  # ou même 16

# Vérifier la VRAM libre
nvidia-smi --query-gpu=memory.free --format=csv,noheader

# Pour les protéines très longues, diviser en domaines
# Il est généralement sûr de diviser les protéines > 1000 aa en domaines de 300-500 aa
```

### ImportError pour openfold

```bash
# Réinstaller avec un commit spécifique
pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

# Vérifier l'installation
python -c "import openfold; print('OpenFold OK')"
```

### Chargement lent du modèle

```bash
# Le premier chargement télécharge des poids de modèle de 2,7 Go — c'est normal
# Les chargements suivants utilisent les poids en cache (~30s de temps de chargement)

# Vérifier l'emplacement du cache
python -c "import torch; print(torch.hub.get_dir())"
ls ~/.cache/torch/hub/
```

{% hint style="warning" %}
**Remarque mémoire :** Le modèle de langage d'ESMFold (ESM-2 15B paramètres) requiert une VRAM significative. Pour des serveurs GPU avec moins de 16GB de VRAM, utilisez la `esm2_t33_650M_UR50D` variante backbone ou activez un chunking agressif.
{% endhint %}

{% hint style="info" %}
**Interprétation du pLDDT :**

* **>90** = Confiance très élevée (bleu dans le coloriage AlphaFold)
* **70–90** = Confiant (cyan/bleu clair)
* **50–70** = Faible confiance (jaune) — traiter avec prudence
* **<50** = Très faible confiance (orange/rouge) — région probablement désordonnée
  {% endhint %}

***

## Recommandations GPU Clore.ai

La demande en VRAM d'ESMFold est dominée par le modèle de langage ESM-2 à 15 milliards de paramètres. La longueur de la séquence ajoute un surcoût mémoire.

| GPU       | VRAM  | Prix Clore.ai | Longueur maximale de séquence | Temps de prédiction (300 aa) |
| --------- | ----- | ------------- | ----------------------------- | ---------------------------- |
| RTX 3090  | 24 Go | \~0,12 $/h    | \~400 aa (avec chunking)      | \~8 secondes                 |
| RTX 4090  | 24 Go | \~0,70 $/h    | \~400 aa (avec chunking)      | \~5 secondes                 |
| A100 40GB | 40 Go | \~1,20 $/h    | \~800 aa confortablement      | \~3 secondes                 |
| A100 80GB | 80 Go | \~2,00 $/h    | \~1500+ aa, grosses protéines | \~4 secondes                 |

{% hint style="warning" %}
**VRAM minimale : 16GB.** ESMFold ne peut pas fonctionner sur des GPUs de 8GB avec le backbone ESM-2 complet. Le RTX 3090/4090 (24GB) peut gérer des protéines jusqu'à \~400 acides aminés sans chunking — activez `chunk_size=64` dans l'API pour des séquences plus longues.
{% endhint %}

**Meilleur rapport qualité/prix pour la recherche :** Le RTX 3090 à \~0,12 $/h gère la grande majorité des tâches de prédiction de structure protéique (protéine humaine moyenne : \~300–400 aa). À \~8 secondes par prédiction, vous pouvez traiter \~450 structures par heure pour \~0,12 $ au total — comparé à AlphaFold2 qui nécessite un calcul MSA prenant des minutes par structure.

**Protéomique à haut débit :** Pour le criblage de milliers de séquences, un A100 40GB (\~1,20 $/h) avec inférence en lot traite \~1 200+ prédictions par heure — viable pour des études à l'échelle des protéomes.

***

## Ressources

* 🐙 **GitHub :** [github.com/facebookresearch/esm](https://github.com/facebookresearch/esm)
* 🤗 **Modèles :** [huggingface.co/facebook/esmfold\_v1](https://huggingface.co/facebook/esmfold_v1)
* 📄 **Article :** [Prediction à l'échelle évolutive de la structure protéique au niveau atomique avec un modèle de langage (Science, 2023)](https://www.science.org/doi/10.1126/science.ade2574)
* 🌐 **Atlas métagénomique ESM :** [esmatlas.com](https://esmatlas.com) — 772M de structures prédites avec ESMFold
* 💻 **Blog Meta AI :** [ai.meta.com/blog/protein-folding-esmfold-metagenomics](https://ai.meta.com/blog/protein-folding-esmfold-metagenomics/)
* 🔬 **Journal des modifications 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:

```
GET https://docs.clore.ai/guides/guides_v2-fr/science-et-recherche/esmfold.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
