# ESMFold प्रोटीन संरचना

**Meta AI द्वारा अल्ट्रा-तेज़ प्रोटीन संरचना भविष्यवाणी** — अमीनो अम्ल अनुक्रमों से सेकंडों में 3D प्रोटीन संरचनाओं की भविष्यवाणी करें, बिना मल्टीपल सिक्वेंस अलाइन्मेंट्स के।

> 🧬 द्वारा विकसित **Meta AI Research** | MIT लाइसेंस | AlphaFold2 से 10x–60x तेज

***

## ESMFold क्या है?

ESMFold Meta AI का प्रोटीन संरचना भविष्यवाणी प्रणाली है जो उपयोग करता है **Evolutionary Scale Modeling (ESM-2)** — दुनिया का सबसे बड़ा प्रोटीन भाषा मॉडल (15 अरब पैरामीटर) — ताकि अमीनो अम्ल अनुक्रमों से सीधे 3D प्रोटीन संरचनाओं की भविष्यवाणी की जा सके।

### AlphaFold2 पर मुख्य लाभ

| फ़ीचर                          | AlphaFold2    | — 3 गाइड्स:    |
| ------------------------------ | ------------- | -------------- |
| MSA आवश्यक                     | ❌ नहीं        | ✅ हाँ          |
| गति (सामान्य प्रोटीन)          | **\~2 सेकंड** | \~10 मिनट–घंटे |
| सटीकता (TM-score)              | \~0.87        | \~0.92         |
| GPU VRAM (650aa)               | \~8GB         | \~8GB          |
| एकल अनुक्रम इनपुट              | ✅ हाँ         | सीमित          |
| अनाथ प्रोटीन (Orphan proteins) | ✅ उत्कृष्ट    | संघर्ष करता है |

### क्यों बिना MSA?

AlphaFold2 की आवश्यकता होती है **Multiple Sequence Alignment (MSA)** — प्रश्न प्रोटीन के विकासात्मक रिश्तेदारों को इकट्ठा और संरेखित करना। यह कम्प्यूटेशनली महंगा है और उन नवीन या इंजीनियर किए गए प्रोटीनों के लिए असंभव है जिनके कोई विकासात्मक रिश्तेदार नहीं हैं।

ESMFold विकासात्मक सूचना संग्रहीत करता है **अपने भाषा मॉडल वज़न्स में** (250 मिलियन प्रोटीन अनुक्रमों पर प्रशिक्षित), पूरी तरह से 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 मार्गदर्शिका:

| प्रोटीन की लंबाई | मॉडल संस्करण    | आवश्यक VRAM |
| ---------------- | --------------- | ----------- |
| 300 aa तक        | ESMFold (3B)    | \~16GB      |
| 500 aa तक        | ESMFold (3B)    | \~20GB      |
| 1000 aa तक       | ESMFold (3B)    | \~40GB      |
| 600 aa तक        | ESMFold (chunk) | \~8GB       |

### चरण 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 बचाने के लिए chunk-size सक्षम करें
# गणना समय बढ़ता है लेकिन 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"Residue {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 अमीनो अम्ल)। लंबे अनुक्रमों के लिए, chunked prediction का उपयोग करें."
        )
    
    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, Swagger UI के लिए /docs"}
```

```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)} 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 तक, बिना chunking)
model.set_chunk_size(None)  # Chunking निष्क्रिय करें
```

### बहुत लंबे अनुक्रमों के लिए CPU Offloading

```python
# मॉडल को CPU पर लोड करें, प्रत्येक inference के लिए GPU पर ले जाएँ
model = esm.pretrained.esmfold_v1()
model = model.eval()

# inference के लिए GPU पर ले जाएँ, बाद में फिर से CPU पर लौटाएँ
model = model.cuda()
with torch.no_grad():
    output = model.infer(sequence)
model = model.cpu()  # GPU मेमोरी मुक्त करें
torch.cuda.empty_cache()
```

***

## समस्या निवारण

### CUDA मेमोरी खत्म (Out of Memory)

```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 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 मांगता है। 16GB से कम VRAM वाले GPU सर्वरों के लिए, backbone संस्करण या आक्रामक chunking सक्षम करें। `esm2_t33_650M_UR50D` backbone variant या आक्रामक chunking सक्षम करें।
{% endhint %}

{% hint style="info" %}
**pLDDT की व्याख्या:**

* **>90** = बहुत उच्च आत्मविश्वास (AlphaFold रंग में नीला)
* **70–90** = आत्मविश्वासी (स्यान/हल्का नीला)
* **50–70** = कम आत्मविश्वास (पीला) — सावधानी से व्यवहार करें
* **<50** = बहुत कम आत्मविश्वास (नारंगी/लाल) — संभावना है कि यह अव्यवस्थित क्षेत्र है
  {% endhint %}

***

## Clore.ai GPU सिफारिशें

ESMFold की VRAM आवश्यकता ESM-2 15B पैरामीटर भाषा मॉडल द्वारा नियंत्रित होती है। अनुक्रम की लंबाई अतिरिक्त मेमोरी ओवरहेड जोड़ती है।

| GPU       | VRAM  | Clore.ai कीमत | अधिकतम अनुक्रम लंबाई       | भविष्यवाणी समय (300 aa) |
| --------- | ----- | ------------- | -------------------------- | ----------------------- |
| RTX 3090  | 24 GB | \~$0.12/घंटा  | \~400 aa (chunking के साथ) | \~8 सेकंड               |
| RTX 4090  | 24 GB | \~$0.70/घंटा  | \~400 aa (chunking के साथ) | \~5 सेकंड               |
| A100 40GB | 40 GB | \~$1.20/घंटा  | \~800 aa आराम से           | \~3 सेकंड               |
| A100 80GB | 80 GB | \~$2.00/घंटा  | \~1500+ aa, बड़े प्रोटीन   | \~4 सेकंड               |

{% hint style="warning" %}
**न्यूनतम VRAM: 16GB।** ESMFold पूर्ण ESM-2 backbone के साथ 8GB GPU पर नहीं चल सकता। RTX 3090/4090 (24GB) लगभग \~400 अमीनो अम्ल तक के प्रोटीन बिना chunking के हैंडल कर सकता है — लंबे अनुक्रमों के लिए API में सक्षम करें। `chunk_size=64` API में लंबे अनुक्रमों के लिए chunking सक्षम करें।
{% endhint %}

**अनुसंधान के लिए सर्वश्रेष्ठ मूल्य:** RTX 3090 लगभग \~$0.12/घंटा पर अधिकांश प्रोटीन संरचना भविष्यवाणी कार्यों को संभालता है (औसत मानव प्रोटीन: \~300–400 aa)। \~8 सेकंड प्रति भविष्यवाणी पर, आप \~450 संरचनाएँ प्रति घंटा लगभग \~$0.12 में प्रोसेस कर सकते हैं — तुलना करें AlphaFold2 से जिसकी MSA गणना प्रति संरचना मिनट लेती है।

**उच्च-थ्रूपुट प्रोटीओमिक्स:** हजारों अनुक्रमों की स्क्रीनिंग के लिए, A100 40GB (\~$1.20/घंटा) बैच्ड inference के साथ \~1,200+ भविष्यवाणियाँ प्रति घंटा प्रोसेस करता है — प्रोटीओम-स्केल अध्ययनों के लिए व्यावहारिक।

***

## संसाधन

* 🐙 **GitHub:** [github.com/facebookresearch/esm](https://github.com/facebookresearch/esm)
* 🤗 **मॉडल:** [huggingface.co/facebook/esmfold\_v1](https://huggingface.co/facebook/esmfold_v1)
* 📄 **पेपर:** [Evolutionary-scale prediction of atomic-level protein structure with a language model (Science, 2023)](https://www.science.org/doi/10.1126/science.ade2574)
* 🌐 **ESM मेटाजेनोमिक एटलस:** [esmatlas.com](https://esmatlas.com) — ESMFold के साथ 772M संरचनाएँ भविष्यवाणी की गईं
* Blender, Kandinsky, OpenClaw **Meta AI ब्लॉग:** [ai.meta.com/blog/protein-folding-esmfold-metagenomics](https://ai.meta.com/blog/protein-folding-esmfold-metagenomics/)
* TensorRT-LLM, ONNX Runtime **ESM चेंजलॉग:** [github.com/facebookresearch/esm/blob/main/CHANGELOG.md](https://github.com/facebookresearch/esm/blob/main/CHANGELOG.md)
