> 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-es/ciencia-e-investigacion/esmfold.md).

# Estructura de proteínas ESMFold

**Predicción ultrarrápida de estructuras proteicas por Meta AI** — predice estructuras proteicas 3D a partir de secuencias de aminoácidos en segundos, sin alineamientos múltiples de secuencias.

> 🧬 Desarrollado por **Investigación de Meta AI** | Licencia MIT | 10x–60x más rápido que AlphaFold2

***

## ¿Qué es ESMFold?

ESMFold es el sistema de predicción de estructuras proteicas de Meta AI que aprovecha **Modelado de Escala Evolutiva (ESM-2)** — el modelo de lenguaje para proteínas más grande del mundo (15 mil millones de parámetros) — para predecir estructuras proteicas 3D directamente a partir de secuencias de aminoácidos.

### Ventajas clave sobre AlphaFold2

| Función                       | ESMFold          | AlphaFold2         |
| ----------------------------- | ---------------- | ------------------ |
| MSA requerido                 | ❌ No             | ✅ Sí               |
| Velocidad (proteína típica)   | **\~2 segundos** | \~10 min–horas     |
| Precisión (TM-score)          | \~0.87           | \~0.92             |
| VRAM de la GPU (650 aa)       | \~8 GB           | \~8 GB             |
| Entrada de una sola secuencia | ✅ Sí             | Limitado           |
| Proteínas huérfanas           | ✅ Excelente      | Tiene dificultades |

### ¿Por qué no MSA?

AlphaFold2 requiere **Alineamiento múltiple de secuencias (MSA)** — recopilar y alinear los parientes evolutivos de la proteína consultada. Esto es computacionalmente costoso e imposible para proteínas nuevas o diseñadas sin parientes evolutivos.

ESMFold almacena la información evolutiva **en los pesos de su modelo de lenguaje** (entrenado con 250 millones de secuencias de proteínas), eliminando por completo el MSA. Esto lo hace:

* **Más rápido:** Sin búsqueda de MSA (minutos ahorrados por predicción)
* **Más escalable:** Procesa proteomas completos de forma eficiente
* **Mejor para proteínas nuevas:** Las secuencias diseñadas no tienen parientes evolutivos

***

## Inicio rápido en Clore.ai

### Paso 1: Selecciona un servidor

En [clore.ai](https://clore.ai) marketplace:

* **Mínimo:** GPU NVIDIA con **16 GB de VRAM** (el modelo de lenguaje ESM-2 es grande)
* **Recomendado:** A100 40GB, RTX 3090, RTX 4090 para el modelo completo
* **Opción más pequeña:** Usa `esm2_t33_650M_UR50D` para 8GB de VRAM

Guía de VRAM de la GPU:

| Longitud de la proteína | Variante del modelo | VRAM requerida |
| ----------------------- | ------------------- | -------------- |
| Hasta 300 aa            | ESMFold (3B)        | \~16GB         |
| Hasta 500 aa            | ESMFold (3B)        | \~20GB         |
| Hasta 1000 aa           | ESMFold (3B)        | \~40GB         |
| Hasta 600 aa            | ESMFold (chunk)     | \~8 GB         |

### Paso 2: Construir imagen Docker personalizada

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

# Dependencias del sistema
RUN apt-get update && apt-get install -y \\
    git \\
    wget \\
    curl \\
    openssh-server \\
    libhdf5-dev \\
    pkg-config \\
    && rm -rf /var/lib/apt/lists/*

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

# Instalar ESMFold y dependencias
RUN pip install --no-cache-dir \\
    fair-esm[esmfold] \\
    torch \\
    biopython \\
    biotite \\
    fastapi \\
    uvicorn \\
    pydantic \\
    openmm==8.0.0 \\
    pdbfixer

# Instalar OpenFold (requerido para ESMFold)
RUN pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

EXPOSE 22

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

### Paso 3: Despliega en Clore.ai

* **Imagen Docker:** `yourname/esmfold:latest`
* **Puertos:** `22` (SSH)
* **Entorno:** `NVIDIA_VISIBLE_DEVICES=all`

***

## Instalación y configuración

### Método 1: pip install

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

# Instalar OpenFold (dependencia requerida)
pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

# Opcional pero recomendado
pip install biotite biopython
```

### Método 2: Desde el código fuente

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

### Verificar la instalación

```python
import esm
print("Versión de ESM:", esm.__version__)

# Prueba rápida de carga del modelo
model = esm.pretrained.esmfold_v1()
print("¡ESMFold cargado correctamente!")
```

***

## Uso básico

### Predecir una sola estructura proteica

```python
import torch
import esm

# Cargar el modelo ESMFold
model = esm.pretrained.esmfold_v1()
model = model.eval().cuda()

# Opcional: habilitar chunk-size para ahorrar VRAM
# Aumenta el tiempo de cálculo pero reduce el uso de VRAM
model.set_chunk_size(64)  # Reducir para usar menos VRAM

# Secuencia proteica (ejemplo: lisozima C)
sequence = "KVFGRCELAAAMKRHGLDNYRGYSLGNWVCAAKFESNFNTQATNRNTDGSTDYGILQINSRWWCNDGRTPGSRNLCNIPCSALLSSDITASVNCAKKIVSDGNGMNAWVAWRNRCKGTDVQAWIRGCRL"

# Predecir estructura
with torch.no_grad():
    output = model.infer_pdb(sequence)

# Guardar archivo PDB
with open("lysozyme.pdb", "w") as f:
    f.write(output)

print(f"¡Estructura predicha! Guardada en lysozyme.pdb")
print(f"Longitud de la secuencia: {len(sequence)} aminoácidos")
```

### Predecir múltiples secuencias (lote)

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

print("¡Todas las predicciones completadas!")
```

### Obtener confianza por residuo (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)

# Extraer puntuaciones pLDDT (confianza por residuo)
plddt = output["plddt"].cpu().numpy()  # Forma: [1, seq_len]
plddt_per_residue = plddt[0]

print(f"pLDDT medio: {plddt_per_residue.mean():.2f}")
print(f"Residuos con alta confianza (>90): {(plddt_per_residue > 90).sum()}")
print(f"Residuos con baja confianza (<50): {(plddt_per_residue < 50).sum()}")

# Clasificar regiones de confianza
for i, score in enumerate(plddt_per_residue):
    if score >= 90:
        confidence = "Muy alta (azul)"
    elif score >= 70:
        confidence = "Confiable (azul claro)"
    elif score >= 50:
        confidence = "Baja (amarillo)"
    else:
        confidence = "Muy baja (naranja)"
    # print(f"Residuo {i+1}: {score:.1f} - {confidence}")  # Descomentar para salida completa
```

***

## Servidor de API REST

Construir una API de producción para 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 predicción de estructuras proteicas ESMFold",
    description="Predice estructuras proteicas 3D a partir de secuencias de aminoácidos",
    version="1.0.0"
)

# Cargar el modelo al inicio
print("Cargando el modelo ESMFold (esto tarda ~30 segundos)...")
model = esm.pretrained.esmfold_v1()
model = model.eval().cuda()
model.set_chunk_size(64)  # Optimización de memoria
print("¡ESMFold listo!")

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):
    """Predecir la estructura 3D de una proteína a partir de su secuencia de aminoácidos."""
    
    # Validar secuencia
    valid_aa = set("ACDEFGHIKLMNPQRSTVWY")
    sequence = request.sequence.upper().strip()
    
    invalid = set(sequence) - valid_aa
    if invalid:
        raise HTTPException(
            status_code=400,
            detail=f"Aminoácidos no válidos en la secuencia: {invalid}. Usa los 20 aminoácidos estándar."
        )
    
    if len(sequence) > 2000:
        raise HTTPException(
            status_code=400,
            detail="La secuencia es demasiado larga (máximo 2000 aminoácidos). Para secuencias más largas, usa predicción por chunks."
        )
    
    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="La GPU se quedó sin memoria. Prueba con una secuencia más corta o reduce el tamaño de chunk."
        )
    
    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 de ESMFold — /predict para predecir estructuras, /docs para Swagger UI"}
```

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

***

## Ejemplos de uso de la API

```bash
# Predecir estructura mediante la 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\"Nombre: {data['name']}\")
print(f\"Longitud: {data['sequence_length']} aa\")
print(f\"pLDDT medio: {data['mean_plddt']:.1f}\")
print(f\"Tiempo: {data['inference_time_seconds']}s\")
# Guardar PDB
open('ubiquitin.pdb', 'w').write(data['pdb_content'])
print('¡PDB guardado!')
"
```

***

## Script de procesamiento por lotes

```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):
    """Predecir estructuras para todas las secuencias de un archivo FASTA."""
    
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    
    # Cargar modelo
    model = esm.pretrained.esmfold_v1()
    model = model.eval().cuda()
    model.set_chunk_size(chunk_size)
    
    # Leer FASTA
    sequences = list(SeqIO.parse(fasta_file, "fasta"))
    print(f"Prediciendo estructuras para {len(sequences)} proteínas...")
    
    results = []
    for i, record in enumerate(sequences):
        seq = str(record.seq).upper()
        name = record.id
        
        print(f"[{i+1}/{len(sequences)}] Prediciendo {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()
            
            # Guardar 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"  Error: {e}")
            results.append({"name": name, "status": f"error: {e}"})
    
    # Escribir resumen
    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¡Listo! {success}/{len(sequences)} estructuras predichas con éxito")
    print(f"Resultados guardados en {output_dir}/")

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

***

## Visualización de estructuras

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

### Usando PyMOL

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

# Abrir estructura
pymol lysozyme.pdb
```

### Visualización programática con Biotite

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

# Cargar la estructura predicha
pdb_file = pdb.PDBFile.read("lysozyme.pdb")
structure = pdb.get_structure(pdb_file, model=1)

# Analizar la estructura secundaria
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"Composición de la estructura secundaria:")
print(f"  Hélice alfa:  {helix_frac:.1f}%")
print(f"  Lámina beta:   {sheet_frac:.1f}%")
print(f"  Coil/Otro:     {coil_frac:.1f}%")
```

***

## Optimización de memoria

### Guía de tamaño de chunk

```python
# Menor chunk_size = menos VRAM, predicción más lenta
# Mayor chunk_size = más VRAM, predicción más rápida

# Para 8GB de VRAM (permite hasta ~400 aa)
model.set_chunk_size(32)

# Para 16GB de VRAM (hasta ~700 aa)
model.set_chunk_size(64)

# Para 40GB de VRAM (hasta ~2000 aa, sin chunking)
model.set_chunk_size(None)  # Desactivar chunking
```

### Descarga a CPU para secuencias muy largas

```python
# Cargar el modelo en CPU, moverlo a GPU por inferencia
model = esm.pretrained.esmfold_v1()
model = model.eval()

# Mover a GPU para inferencia, volver a CPU después
model = model.cuda()
with torch.no_grad():
    output = model.infer(sequence)
model = model.cpu()  # Liberar memoria de la GPU
torch.cuda.empty_cache()
```

***

## Solución de problemas

### Memoria insuficiente en CUDA

```bash
# Reducir el tamaño de chunk
model.set_chunk_size(32)  # o incluso 16

# Comprobar VRAM libre
nvidia-smi --query-gpu=memory.free --format=csv,noheader

# Para proteínas muy largas, dividir en dominios
# Normalmente es seguro dividir proteínas de > 1000 aa en dominios de 300-500 aa
```

### ImportError para openfold

```bash
# Reinstalar con un commit específico
pip install "git+https://github.com/aqlaboratory/openfold.git@4b41059694619831a7db195b7e0988fc4ff3a307"

# Comprobar la instalación
python -c "import openfold; print('OpenFold OK')"
```

### Carga lenta del modelo

```bash
# La primera carga descarga 2,7 GB de pesos del modelo — esto es normal
# Las cargas posteriores usan pesos almacenados en caché (~30 s de tiempo de carga)

# Verificar la ubicación de la caché
python -c "import torch; print(torch.hub.get_dir())"
ls ~/.cache/torch/hub/
```

{% hint style="warning" %}
**Nota de memoria:** El modelo de lenguaje de ESMFold (ESM-2, 15 mil millones de parámetros) requiere una VRAM significativa. Para servidores GPU con menos de 16 GB de VRAM, usa la `esm2_t33_650M_UR50D` variante backbone o habilita un troceado agresivo.
{% endhint %}

{% hint style="info" %}
**Interpretación de pLDDT:**

* **>90** = Confianza muy alta (azul en la coloración de AlphaFold)
* **70–90** = Confidente (cian/azul claro)
* **50–70** = Baja confianza (amarillo) — tratar con precaución
* **<50** = Confianza muy baja (naranja/rojo) — probablemente región desordenada
  {% endhint %}

***

## Recomendaciones de GPU para Clore.ai

El requisito de VRAM de ESMFold está dominado por el modelo de lenguaje ESM-2 de 15 mil millones de parámetros. La longitud de la secuencia añade una carga adicional de memoria.

| GPU       | VRAM  | Precio de Clore.ai                        | Longitud máxima de secuencia  | Tiempo de predicción (300 aa) |
| --------- | ----- | ----------------------------------------- | ----------------------------- | ----------------------------- |
| RTX 3090  | 24 GB | $0.07–0.21/h                              | \~400 aa (con troceado)       | \~8 segundos                  |
| RTX 4090  | 24 GB | $0.14–0.42/h                              | \~400 aa (con troceado)       | \~5 segundos                  |
| A100 40GB | 40 GB | [bare metal](https://clore.ai/bare-metal) | \~800 aa sin problema         | \~3 segundos                  |
| A100 80GB | 80 GB | [bare metal](https://clore.ai/bare-metal) | \~1500+ aa, proteínas grandes | \~4 segundos                  |

{% hint style="warning" %}
**VRAM mínima: 16 GB.** ESMFold no puede ejecutarse en GPUs de 8 GB con el backbone completo de ESM-2. La RTX 3090/4090 (24 GB) puede manejar proteínas de hasta \~400 aminoácidos sin troceado — habilita `chunk_size=64` en la API para secuencias más largas.
{% endhint %}

**Mejor relación calidad-precio para investigación:** La RTX 3090 a $0,07–0,21/h maneja la gran mayoría de las tareas de predicción de estructuras proteicas (proteína humana promedio: \~300–400 aa). A \~8 segundos por predicción, puedes procesar \~450 estructuras por hora por \~$0,12 en total — en comparación con AlphaFold2, que requiere el cálculo de MSA y tarda minutos por estructura.

**Proteómica de alto rendimiento:** Para cribar miles de secuencias, la A100 de 40 GB ([bare metal](https://clore.ai/bare-metal)) con inferencia por lotes procesa \~1.200+ predicciones por hora — viable para estudios a escala de proteoma.

***

## Recursos

* 🐙 **GitHub:** [github.com/facebookresearch/esm](https://github.com/facebookresearch/esm)
* 🤗 **Modelos:** [huggingface.co/facebook/esmfold\_v1](https://huggingface.co/facebook/esmfold_v1)
* 📄 **Artículo:** [Predicción a escala evolutiva de la estructura proteica a nivel atómico con un modelo de lenguaje (Science, 2023)](https://www.science.org/doi/10.1126/science.ade2574)
* 🌐 **Atlas metagenómico ESM:** [esmatlas.com](https://esmatlas.com) — 772 millones de estructuras predichas con ESMFold
* 💻 **Blog de Meta AI:** [ai.meta.com/blog/protein-folding-esmfold-metagenomics](https://ai.meta.com/blog/protein-folding-esmfold-metagenomics/)
* 🔬 **Registro de cambios de 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-es/ciencia-e-investigacion/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.
