Feature Extraction
Transformers
Safetensors
fast_esmfold
protein
structure-prediction
esmfold
test-time-training
custom_code
Instructions to use Synthyra/FastESMFold with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Synthyra/FastESMFold with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="Synthyra/FastESMFold", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("Synthyra/FastESMFold", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
Upload README.md with huggingface_hub
Browse files
README.md
CHANGED
|
@@ -12,7 +12,7 @@ The GitHub with the implementation and requirements.txt can be found [here](http
|
|
| 12 |
|
| 13 |
# FastESMFold
|
| 14 |
|
| 15 |
-
FastESMFold is a self-contained, HuggingFace-compatible reimplementation of ESMFold with optional **Test-Time Training (TTT)** and multi-backend attention (SDPA, Flash, Flex).
|
| 16 |
|
| 17 |
No dependency on `fair-esm`, `proteinttt`, or `openfold`. Just `transformers`, `torch`, and `einops`.
|
| 18 |
|
|
@@ -22,7 +22,16 @@ Protein language models like ESM2 are trained on millions of sequences, but at i
|
|
| 22 |
|
| 23 |
**Test-Time Training (TTT)** adapts the model to each individual protein before predicting its structure. The idea is simple: before folding, we briefly train the ESM2 backbone on the input sequence using masked language modeling (the same objective it was pretrained with). This forces the model to "study" the specific sequence, strengthening its internal representation of that protein's structural features.
|
| 24 |
|
| 25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
**When is TTT most useful?**
|
| 28 |
- Sequences with low baseline pLDDT (< 0.5): TTT can improve pLDDT by 10-30+ points
|
|
@@ -36,7 +45,7 @@ The adaptation uses **LoRA** (Low-Rank Adaptation) for efficiency: only small ad
|
|
| 36 |
## Key Features
|
| 37 |
|
| 38 |
- **Standard ESMFold**: Full ESMFold v1 structure prediction, loadable via `AutoModel`
|
| 39 |
-
- **Optional TTT**: Enable test-time training for
|
| 40 |
- **Best structure selection**: When TTT is enabled, folds after each step and returns the structure with the highest pLDDT
|
| 41 |
- **FastESM2 attention**: SDPA/Flash/Flex backends for the 3B ESM2 backbone
|
| 42 |
- **Self-contained LoRA**: lora_diffusion-compatible implementation (no peft dependency)
|
|
@@ -64,9 +73,12 @@ plddt = output["plddt"].mean().item()
|
|
| 64 |
print(f"pLDDT: {plddt:.3f}")
|
| 65 |
```
|
| 66 |
|
| 67 |
-
### Structure prediction with TTT
|
| 68 |
|
| 69 |
-
TTT adapts the ESM2 backbone to a specific input sequence via masked language
|
|
|
|
|
|
|
|
|
|
| 70 |
|
| 71 |
```python
|
| 72 |
# Configure TTT
|
|
@@ -74,8 +86,10 @@ model._ttt_cfg.steps = 10 # 10 optimizer steps (default)
|
|
| 74 |
model._ttt_cfg.lora_rank = 8 # LoRA rank (default)
|
| 75 |
model._ttt_cfg.lora_alpha = 32 # LoRA scale (default)
|
| 76 |
|
| 77 |
-
#
|
| 78 |
-
result = model.fold_protein("MKTLLILAVVAAALA...")
|
|
|
|
|
|
|
| 79 |
print(f"pLDDT: {result['plddt']:.3f}")
|
| 80 |
print(f"Best step: {result['best_step']} (0=baseline, 1-10=TTT steps)")
|
| 81 |
print(f"Step pLDDTs: {[f'{p:.2f}' for p in result['step_plddts']]}")
|
|
@@ -87,34 +101,37 @@ with open("structure.pdb", "w") as f:
|
|
| 87 |
|
| 88 |
### Return values
|
| 89 |
|
| 90 |
-
`fold_protein(sequence)` returns a dict
|
|
|
|
| 91 |
|
| 92 |
| Key | Type | Description |
|
| 93 |
|-----|------|-------------|
|
| 94 |
-
| `plddt` | float |
|
| 95 |
-
| `ptm` | float | Predicted TM-score
|
| 96 |
-
| `pdb_string` | str | PDB format structure
|
| 97 |
-
| `step_plddts` | list[float] | pLDDT
|
| 98 |
-
| `best_step` | int | Which step produced the
|
| 99 |
|
| 100 |
-
###
|
| 101 |
|
| 102 |
-
|
|
|
|
| 103 |
|
| 104 |
```python
|
| 105 |
-
#
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
model = AutoModel.from_pretrained("Synthyra/FastESMFold", config=config, trust_remote_code=True)
|
| 109 |
-
result = model.fold_protein("MKTLLILAVVAAALA...") # No TTT, just baseline fold
|
| 110 |
|
| 111 |
-
#
|
| 112 |
with torch.no_grad():
|
| 113 |
output = model.infer("MKTLLILAVVAAALA...")
|
| 114 |
pdb_strings = model.output_to_pdb(output)
|
| 115 |
```
|
| 116 |
|
| 117 |
-
## TTT Benchmark
|
|
|
|
|
|
|
|
|
|
| 118 |
|
| 119 |
Tested on 10 difficult sequences on A10G GPU:
|
| 120 |
|
|
@@ -155,7 +172,7 @@ TTT parameters are set via `config.ttt_config` (a dict) or by modifying `model._
|
|
| 155 |
| Parameter | Default | Description |
|
| 156 |
|-----------|---------|-------------|
|
| 157 |
| `lr` | 4e-4 | Learning rate for SGD optimizer |
|
| 158 |
-
| `steps` | 10 | Number of optimizer steps
|
| 159 |
| `ags` | 4 | Gradient accumulation steps per optimizer step |
|
| 160 |
| `batch_size` | 4 | Batch size for masked language model training |
|
| 161 |
| `mask_ratio` | 0.15 | Fraction of tokens to mask |
|
|
|
|
| 12 |
|
| 13 |
# FastESMFold
|
| 14 |
|
| 15 |
+
FastESMFold is a self-contained, HuggingFace-compatible reimplementation of ESMFold with optional experimental **Test-Time Training (TTT)** and multi-backend attention (SDPA, Flash, Flex).
|
| 16 |
|
| 17 |
No dependency on `fair-esm`, `proteinttt`, or `openfold`. Just `transformers`, `torch`, and `einops`.
|
| 18 |
|
|
|
|
| 22 |
|
| 23 |
**Test-Time Training (TTT)** adapts the model to each individual protein before predicting its structure. The idea is simple: before folding, we briefly train the ESM2 backbone on the input sequence using masked language modeling (the same objective it was pretrained with). This forces the model to "study" the specific sequence, strengthening its internal representation of that protein's structural features.
|
| 24 |
|
| 25 |
+
TTT is disabled by default. Standard `fold_protein(...)`, `infer(...)`, and
|
| 26 |
+
`state_dict()` behavior are unchanged unless you explicitly pass `ttt=True` or
|
| 27 |
+
call `fold_protein_ttt(...)`.
|
| 28 |
+
|
| 29 |
+
The adaptation uses **LoRA** (Low-Rank Adaptation) for efficiency: only small
|
| 30 |
+
adapter weights are trained (~4.4M parameters out of 3.5B), and the base model
|
| 31 |
+
is restored after each prediction. This takes 20-45 seconds per sequence on an
|
| 32 |
+
A10G GPU. It can improve structure prediction quality on difficult targets
|
| 33 |
+
where standard ESMFold produces low-confidence predictions, but it is
|
| 34 |
+
experimental and can degrade predictions that already have high confidence.
|
| 35 |
|
| 36 |
**When is TTT most useful?**
|
| 37 |
- Sequences with low baseline pLDDT (< 0.5): TTT can improve pLDDT by 10-30+ points
|
|
|
|
| 45 |
## Key Features
|
| 46 |
|
| 47 |
- **Standard ESMFold**: Full ESMFold v1 structure prediction, loadable via `AutoModel`
|
| 48 |
+
- **Optional experimental TTT**: Enable test-time training for difficult sequences with explicit `ttt=True`
|
| 49 |
- **Best structure selection**: When TTT is enabled, folds after each step and returns the structure with the highest pLDDT
|
| 50 |
- **FastESM2 attention**: SDPA/Flash/Flex backends for the 3B ESM2 backbone
|
| 51 |
- **Self-contained LoRA**: lora_diffusion-compatible implementation (no peft dependency)
|
|
|
|
| 73 |
print(f"pLDDT: {plddt:.3f}")
|
| 74 |
```
|
| 75 |
|
| 76 |
+
### Structure prediction with experimental TTT
|
| 77 |
|
| 78 |
+
TTT adapts the ESM2 backbone to a specific input sequence via masked language
|
| 79 |
+
modeling before folding. It can improve pLDDT on difficult sequences, but it is
|
| 80 |
+
experimental, adds test-time compute, and should not be assumed to improve every
|
| 81 |
+
sequence.
|
| 82 |
|
| 83 |
```python
|
| 84 |
# Configure TTT
|
|
|
|
| 86 |
model._ttt_cfg.lora_rank = 8 # LoRA rank (default)
|
| 87 |
model._ttt_cfg.lora_alpha = 32 # LoRA scale (default)
|
| 88 |
|
| 89 |
+
# ttt=True runs TTT, folds after each step, returns best structure
|
| 90 |
+
result = model.fold_protein("MKTLLILAVVAAALA...", ttt=True)
|
| 91 |
+
# Equivalent:
|
| 92 |
+
# result = model.fold_protein_ttt("MKTLLILAVVAAALA...")
|
| 93 |
print(f"pLDDT: {result['plddt']:.3f}")
|
| 94 |
print(f"Best step: {result['best_step']} (0=baseline, 1-10=TTT steps)")
|
| 95 |
print(f"Step pLDDTs: {[f'{p:.2f}' for p in result['step_plddts']]}")
|
|
|
|
| 101 |
|
| 102 |
### Return values
|
| 103 |
|
| 104 |
+
`fold_protein(sequence)` returns a dict. Without `ttt=True`, `step_plddts`
|
| 105 |
+
contains only the baseline pLDDT and `best_step` is `0`.
|
| 106 |
|
| 107 |
| Key | Type | Description |
|
| 108 |
|-----|------|-------------|
|
| 109 |
+
| `plddt` | float | Mean pLDDT for the selected structure |
|
| 110 |
+
| `ptm` | float | Predicted TM-score for the selected structure |
|
| 111 |
+
| `pdb_string` | str | PDB format structure |
|
| 112 |
+
| `step_plddts` | list[float] | Baseline pLDDT, plus per-step pLDDT when TTT is enabled |
|
| 113 |
+
| `best_step` | int | Which step produced the selected structure (0=baseline) |
|
| 114 |
|
| 115 |
+
### TTT default behavior
|
| 116 |
|
| 117 |
+
TTT is disabled by default. Use FastESMFold as a standard ESMFold by calling
|
| 118 |
+
`fold_protein(...)` or `infer(...)` without `ttt=True`:
|
| 119 |
|
| 120 |
```python
|
| 121 |
+
# Baseline fold, no TTT
|
| 122 |
+
result = model.fold_protein("MKTLLILAVVAAALA...")
|
| 123 |
+
print(result["best_step"]) # 0
|
|
|
|
|
|
|
| 124 |
|
| 125 |
+
# Raw ESMFold output
|
| 126 |
with torch.no_grad():
|
| 127 |
output = model.infer("MKTLLILAVVAAALA...")
|
| 128 |
pdb_strings = model.output_to_pdb(output)
|
| 129 |
```
|
| 130 |
|
| 131 |
+
## Experimental TTT Benchmark
|
| 132 |
+
|
| 133 |
+
This benchmark is provided as an example of where TTT can help. It is not a
|
| 134 |
+
guarantee of improvement on every sequence.
|
| 135 |
|
| 136 |
Tested on 10 difficult sequences on A10G GPU:
|
| 137 |
|
|
|
|
| 172 |
| Parameter | Default | Description |
|
| 173 |
|-----------|---------|-------------|
|
| 174 |
| `lr` | 4e-4 | Learning rate for SGD optimizer |
|
| 175 |
+
| `steps` | 10 | Number of optimizer steps when TTT is explicitly enabled |
|
| 176 |
| `ags` | 4 | Gradient accumulation steps per optimizer step |
|
| 177 |
| `batch_size` | 4 | Batch size for masked language model training |
|
| 178 |
| `mask_ratio` | 0.15 | Fraction of tokens to mask |
|