> 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 des protéines ESMFold

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

> 🧬 Développé par **Meta AI Research** | Licence MIT | 10 à 60 fois 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 pour protéines au monde (15 milliards de paramètres) — pour prédire directement des structures protéiques 3D à partir de séquences d’acides aminés.

### Principaux avantages par rapport à AlphaFold2

| Fonctionnalité             | ESMFold          | AlphaFold2                 |
| -------------------------- | ---------------- | -------------------------- |
| MSA requis                 | ❌ Non            | ✅ Oui                      |
| Vitesse (protéine typique) | **\~2 secondes** | \~10 min à quelques heures |
| Précision (TM-score)       | \~0.87           | \~0.92                     |
| VRAM GPU (650 aa)          | \~8 Go           | \~8 Go                     |
| Entrée à séquence unique   | ✅ Oui            | Limité                     |
| Protéines orphelines       | ✅ Excellente     | Éprouve des difficultés    |

### Pourquoi pas de MSA ?

AlphaFold2 nécessite **un alignement multiple de séquences (MSA)** — la collecte et l'alignement des proches évolutifs de la protéine requête. Cela est coûteux en calcul et impossible pour des protéines nouvelles ou conçues sans proches é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 complètement la MSA. Cela le rend :

* **Plus rapide :** Aucune recherche de MSA (minutes économisées par prédiction)
* **Plus évolutif :** Traite efficacement des protéomes entiers
* **Mieux adapté aux protéines nouvelles :** Les séquences conçues n'ont aucun proche évolutif

***

## Démarrage rapide sur Clore.ai

### Étape 1 : Sélectionnez 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 40 Go, RTX 3090, RTX 4090 pour le modèle complet
* **Option plus légère :** Utilisez `esm2_t33_650M_UR50D` pour 8 Go de VRAM

Guide de VRAM GPU :

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

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

```dockerfile
FROM pytorch/pytorch:2.11.0-cuda12.8-cudnn9-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 les 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éployez sur Clore.ai

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

***

## Installation et configuration

### Méthode 1 : installation via pip

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

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

# Facultatif 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 ESM :", esm.__version__)

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

***

## Utilisation de base

### 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()

# Facultatif : activer la taille de morceaux pour économiser 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)

# Enregistrer 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 sont 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_per_residue = plddt[0]

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

# Classer les régions de confiance
for i, score in enumerate(plddt_per_residue):
    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 l'affichage complet
```

***

## Serveur d'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 environ 30 secondes)...")
model = esm.pretrained.esmfold_v1()
model = model.eval().cuda()
model.set_chunk_size(64)  # Optimisation de la 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 3D d'une protéine à partir de sa 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 standard."
        )
    
    if len(sequence) > 2000:
        raise HTTPException(
            status_code=400,
            detail="Séquence trop longue (2000 acides aminés max). Pour les séquences plus longues, utilisez une 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="Mémoire GPU insuffisante. 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 les structures, /docs pour l'interface Swagger"}
```

```bash
# Exécuter 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\"Nom : {data['name']}\")
print(f\"Longueur : {data['sequence_length']} aa\")
print(f\"pLDDT moyen : {data['mean_plddt']:.1f}\")
print(f\"Temps : {data['inference_time_seconds']}s\")
# Enregistrer 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 des 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()
            
            # Enregistrer 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"erreur : {e}"})
    
    # Écrire le résumé
    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édictes 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

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

### Utiliser 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 morceaux

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

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

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

# Pour 40 Go de VRAM (jusqu'à environ 2000 aa, sans découpage)
model.set_chunk_size(None)  # Désactiver le découpage
```

### Déchargement sur CPU pour les séquences très longues

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

# Déplacer sur le GPU pour l'inférence, puis revenir sur le CPU
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

### Mémoire CUDA insuffisante

```bash
# Réduire la taille des morceaux
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, les découper en domaines
# Il est généralement sûr de découper les protéines de plus de 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 2,7 Go de poids du modèle — c’est normal
# Les chargements suivants utilisent des poids en cache (~30 s 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 sur la mémoire :** Le modèle de langage d’ESMFold (ESM-2, 15 milliards de paramètres) nécessite une quantité importante de VRAM. Pour les serveurs GPU disposant de moins de 16 Go de VRAM, utilisez la `esm2_t33_650M_UR50D` variante backbone ou activez un découpage agressif.
{% endhint %}

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

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

***

## Recommandations GPU Clore.ai

La mémoire VRAM requise par ESMFold est principalement déterminée par le modèle de langage ESM-2 à 15 milliards de paramètres. La longueur de la séquence ajoute une surcharge mémoire supplémentaire.

| GPU        | VRAM  | Prix Clore.ai                             | Longueur maximale de séquence  | Temps de prédiction (300 aa) |
| ---------- | ----- | ----------------------------------------- | ------------------------------ | ---------------------------- |
| RTX 3090   | 24 Go | 0,07–0,21 $/h                             | \~400 aa (avec découpage)      | \~8 secondes                 |
| RTX 4090   | 24 Go | 0,14–0,42 $/h                             | \~400 aa (avec découpage)      | \~5 secondes                 |
| A100 40 Go | 40 Go | [bare metal](https://clore.ai/bare-metal) | \~800 aa sans difficulté       | \~3 secondes                 |
| A100 80 Go | 80 Go | [bare metal](https://clore.ai/bare-metal) | \~1 500+ aa, grandes protéines | \~4 secondes                 |

{% hint style="warning" %}
**VRAM minimale : 16 Go.** ESMFold ne peut pas fonctionner sur des GPU de 8 Go avec le backbone ESM-2 complet. Les RTX 3090/4090 (24 Go) peuvent traiter des protéines allant jusqu’à \~400 acides aminés sans découpage — activez `chunk_size=64` dans l’API pour les séquences plus longues.
{% endhint %}

**Meilleur rapport qualité-prix pour la recherche :** La RTX 3090 à 0,07–0,21 $/h prend en charge 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 un total d’environ 0,12 $ — contre AlphaFold2, qui nécessite un calcul MSA prenant des minutes par structure.

**Protéomique à haut débit :** Pour cribler des milliers de séquences, l’A100 40 Go ([bare metal](https://clore.ai/bare-metal))

***

## 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 :** [Prédiction à 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) — 772 millions 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, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-fr/science-et-recherche/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.
