Spaces:
Runtime error
Runtime error
Commit
·
6777e11
1
Parent(s):
9186e4f
Fix: Resolve runtime errors by enabling GPU, refactoring auth and updating gradio
Browse filesThe Space was previously failing to run due to gradio issues and incorrect hardware requests. This commit resolves these runtime errors, making the application fully functional.
Authentication Fix: The user-facing token input, which was causing errors, has been removed. The application now correctly authenticates by reading the HF_TOKEN from the Space's secrets.
GPU Enablement: Added the @spaces.GPU() decorator to the main processing functions. This ensures the Space requests and utilizes the necessary GPU hardware, fixing a key execution failure.
Dependency Update: Corrected the Gradio SDK version in README.md to 5.38.2.
UI Update: The description text in the UI has been updated to reflect the new, functional authentication method.
README.md
CHANGED
@@ -4,7 +4,7 @@ emoji: 🧬
|
|
4 |
colorFrom: gray
|
5 |
colorTo: green
|
6 |
sdk: gradio
|
7 |
-
sdk_version:
|
8 |
app_file: app.py
|
9 |
pinned: true
|
10 |
short_description: A frontier generative model for biology by EvolutionaryScale
|
|
|
4 |
colorFrom: gray
|
5 |
colorTo: green
|
6 |
sdk: gradio
|
7 |
+
sdk_version: 5.38.2
|
8 |
app_file: app.py
|
9 |
pinned: true
|
10 |
short_description: A frontier generative model for biology by EvolutionaryScale
|
app.py
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
|
2 |
import gradio as gr
|
3 |
import numpy as np
|
4 |
import os, tempfile
|
5 |
import torch
|
6 |
import py3Dmol
|
7 |
from huggingface_hub import login
|
8 |
-
|
9 |
|
10 |
from esm.utils.structure.protein_chain import ProteinChain
|
11 |
from esm.models.esm3 import ESM3
|
@@ -16,20 +16,24 @@ from esm.sdk.api import (
|
|
16 |
|
17 |
from gradio_molecule3d import Molecule3D
|
18 |
|
|
|
|
|
|
|
19 |
|
20 |
theme = gr.themes.Monochrome(
|
21 |
primary_hue="gray",
|
22 |
)
|
23 |
|
24 |
## Function to get model from Hugging Face using token
|
25 |
-
# @spaces.GPU()
|
26 |
def get_model(model_name, token):
|
27 |
-
login(token=token)
|
28 |
|
29 |
-
if
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
33 |
|
34 |
# model = ESM3.from_pretrained(model_name, device=torch.device("cpu"))
|
35 |
return model
|
@@ -45,28 +49,28 @@ def make_reps(res_start=None, res_end=None, main_color="whiteCarbon", highlight_
|
|
45 |
residue_range = f"{res_start}-{res_end}" if res_start != res_end else ""
|
46 |
|
47 |
return [
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
|
71 |
## Function to render 3D structure
|
72 |
def render_pdb(pdb_id, chain_id, res_start, res_end, pdb_string=None):
|
@@ -78,8 +82,11 @@ def render_pdb(pdb_id, chain_id, res_start, res_end, pdb_string=None):
|
|
78 |
|
79 |
return Molecule3D(tmp_pdb.name, reps=make_reps(res_start=res_start, res_end=res_end))
|
80 |
|
|
|
|
|
81 |
## Function for Scaffolding
|
82 |
-
|
|
|
83 |
pdb = get_pdb(pdb_id, chain_id)
|
84 |
|
85 |
## Get motif sequence and atom37 positions
|
@@ -102,7 +109,7 @@ def scaffold(model_name, token, pdb_id, chain_id, motif_start, motif_end, prompt
|
|
102 |
num_steps=sequence_prompt.count("_") // 2,
|
103 |
temperature=0.5)
|
104 |
## Generate sequence
|
105 |
-
model = get_model(model_name,
|
106 |
sequence_generation = model.generate(protein_prompt, sequence_generation_config)
|
107 |
generated_sequence = sequence_generation.sequence
|
108 |
|
@@ -110,7 +117,7 @@ def scaffold(model_name, token, pdb_id, chain_id, motif_start, motif_end, prompt
|
|
110 |
structure_prediction_config = GenerationConfig(
|
111 |
track="structure", # We want ESM3 to generate tokens for the structure track
|
112 |
num_steps=len(sequence_generation) // 8,
|
113 |
-
temperature=0.7,
|
114 |
)
|
115 |
structure_prediction_prompt = ESMProtein(sequence=sequence_generation.sequence)
|
116 |
structure_prediction = model.generate(structure_prediction_prompt, structure_prediction_config)
|
@@ -121,14 +128,14 @@ def scaffold(model_name, token, pdb_id, chain_id, motif_start, motif_end, prompt
|
|
121 |
# crmsd = structure_prediction_chain.rmsd(renal_dipep_chain, mobile_inds=motif_inds_in_generation, target_inds=motif_inds)
|
122 |
|
123 |
structure_orig_highlight = render_pdb(pdb_id, chain_id, res_start=motif_start, res_end=motif_end)
|
124 |
-
structure_new_highlight = render_pdb(pdb_id, chain_id, res_start=insert_size, res_end=insert_size+len(motif_sequence),
|
125 |
pdb_string=structure_prediction_chain.to_pdb_string())
|
126 |
|
127 |
return [
|
128 |
pdb.sequence,
|
129 |
motif_sequence,
|
130 |
structure_orig_highlight,
|
131 |
-
#
|
132 |
sequence_prompt,
|
133 |
# structure_prompt,
|
134 |
# protein_prompt
|
@@ -139,7 +146,8 @@ def scaffold(model_name, token, pdb_id, chain_id, motif_start, motif_end, prompt
|
|
139 |
]
|
140 |
|
141 |
## Function for Secondary Structure Editing
|
142 |
-
|
|
|
143 |
pdb = get_pdb(pdb_id, chain_id)
|
144 |
edit_region = np.arange(region_start, region_end)
|
145 |
|
@@ -148,21 +156,21 @@ def ss_edit(model_name, token, pdb_id, chain_id, region_start, region_end, short
|
|
148 |
|
149 |
## Construct a secondary structure prompt that retains the secondary structure of the flanking regions, and shortens the lengths of helices in the helix-coil-helix region
|
150 |
ss8_prompt = shortening_ss8[:edit_region[0]] + (((shortened_region_length - 3) // 2) * "H" + "C"*3 + ((shortened_region_length - 3) // 2) * "H") + shortening_ss8[edit_region[-1] + 1:]
|
151 |
-
|
152 |
## Save original sequence and secondary structure
|
153 |
original_sequence = pdb.sequence
|
154 |
original_ss8 = shortening_ss8
|
155 |
original_ss8_region = " "*edit_region[0] + shortening_ss8[edit_region[0]:edit_region[-1]+1]
|
156 |
-
|
157 |
proposed_ss8_region = " "*edit_region[0] + ss8_prompt[edit_region[0]:edit_region[0]+shortened_region_length]
|
158 |
|
159 |
## Create protein prompt
|
160 |
protein_prompt = ESMProtein(sequence=sequence_prompt, secondary_structure=ss8_prompt)
|
161 |
|
162 |
## Generatre sequence
|
163 |
-
model = get_model(model_name,
|
164 |
sequence_generation = model.generate(protein_prompt, GenerationConfig(track="sequence", num_steps=protein_prompt.sequence.count("_") // 2, temperature=0.5))
|
165 |
-
|
166 |
## Generate structure
|
167 |
structure_prediction = model.generate(ESMProtein(sequence=sequence_generation.sequence), GenerationConfig(track="structure", num_steps=len(protein_prompt) // 4, temperature=0))
|
168 |
structure_prediction_chain = structure_prediction.to_protein_chain()
|
@@ -185,18 +193,19 @@ def ss_edit(model_name, token, pdb_id, chain_id, region_start, region_end, short
|
|
185 |
]
|
186 |
|
187 |
## Function for SASA Editing
|
188 |
-
|
|
|
189 |
pdb = get_pdb(pdb_id, chain_id)
|
190 |
|
191 |
structure_prompt = torch.full((len(pdb), 37, 3), torch.nan)
|
192 |
-
structure_prompt[span_start:span_end] = torch.tensor(pdb[span_start:span_end].atom37_positions, dtype=torch.float32)
|
193 |
|
194 |
sasa_prompt = [None]*len(pdb)
|
195 |
sasa_prompt[span_start:span_end] = [40.0]*(span_end - span_start)
|
196 |
|
197 |
protein_prompt = ESMProtein(sequence="_"*len(pdb), coordinates=structure_prompt, sasa=sasa_prompt)
|
198 |
|
199 |
-
model = get_model(model_name,
|
200 |
|
201 |
generated_proteins = []
|
202 |
for i in range(n_samples):
|
@@ -227,7 +236,7 @@ scaffold_app = gr.Interface(
|
|
227 |
fn=scaffold,
|
228 |
inputs=[
|
229 |
gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
|
230 |
-
gr.Textbox(value = "
|
231 |
gr.Textbox(value="1ITU", label = "PDB Code"),
|
232 |
gr.Textbox(value="A", label = "Chain"),
|
233 |
gr.Number(value=123, label="Motif Start"),
|
@@ -253,7 +262,7 @@ ss_app = gr.Interface(
|
|
253 |
fn=ss_edit,
|
254 |
inputs=[
|
255 |
gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
|
256 |
-
gr.Textbox(value = "
|
257 |
gr.Textbox(value = "7XBQ", label="PDB ID"),
|
258 |
gr.Textbox(value = "A", label="Chain ID"),
|
259 |
gr.Number(value=38, label="Edit Region Start"),
|
@@ -280,12 +289,12 @@ sasa_app = gr.Interface(
|
|
280 |
fn=sasa_edit,
|
281 |
inputs=[
|
282 |
gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
|
283 |
-
gr.Textbox(value = "
|
284 |
gr.Textbox(value = "1LBS", label="PDB ID"),
|
285 |
gr.Textbox(value = "A", label="Chain ID"),
|
286 |
gr.Number(value=105, label="Span Start"),
|
287 |
gr.Number(value=116, label="Span End"),
|
288 |
-
# gr.Textbox(value="
|
289 |
gr.Number(value=1, label="Number of Samples")
|
290 |
],
|
291 |
outputs = [
|
@@ -325,7 +334,7 @@ with gr.Blocks(theme=theme) as esm_app:
|
|
325 |
|
326 |
Spaces App By: [[Colby T. Ford](https://colbyford.com)] from [Tuple, The Cloud Genomics Company](https://tuple.xyz)
|
327 |
|
328 |
-
NOTE: You will need to agree to EvolutionaryScale's [license agreement](https://huggingface.co/EvolutionaryScale/esm3-sm-open-v1) to use the model.
|
329 |
"""
|
330 |
)
|
331 |
with gr.Row():
|
@@ -343,4 +352,4 @@ with gr.Blocks(theme=theme) as esm_app:
|
|
343 |
])
|
344 |
|
345 |
if __name__ == "__main__":
|
346 |
-
esm_app.launch()
|
|
|
1 |
+
import spaces
|
2 |
import gradio as gr
|
3 |
import numpy as np
|
4 |
import os, tempfile
|
5 |
import torch
|
6 |
import py3Dmol
|
7 |
from huggingface_hub import login
|
8 |
+
|
9 |
|
10 |
from esm.utils.structure.protein_chain import ProteinChain
|
11 |
from esm.models.esm3 import ESM3
|
|
|
16 |
|
17 |
from gradio_molecule3d import Molecule3D
|
18 |
|
19 |
+
# --- Retrieve the HF token from the Space's secrets ---
|
20 |
+
HF_TOKEN = os.getenv("HF_TOKEN")
|
21 |
+
|
22 |
|
23 |
theme = gr.themes.Monochrome(
|
24 |
primary_hue="gray",
|
25 |
)
|
26 |
|
27 |
## Function to get model from Hugging Face using token
|
|
|
28 |
def get_model(model_name, token):
|
|
|
29 |
|
30 |
+
if token:
|
31 |
+
login(token=token)
|
32 |
+
|
33 |
+
# if torch.cuda.is_available():
|
34 |
+
model = ESM3.from_pretrained(model_name, device=torch.device("cuda"))
|
35 |
+
# else:
|
36 |
+
# model = ESM3.from_pretrained(model_name, device=torch.device("cpu"))
|
37 |
|
38 |
# model = ESM3.from_pretrained(model_name, device=torch.device("cpu"))
|
39 |
return model
|
|
|
49 |
residue_range = f"{res_start}-{res_end}" if res_start != res_end else ""
|
50 |
|
51 |
return [
|
52 |
+
{
|
53 |
+
"model": 0,
|
54 |
+
"chain": "",
|
55 |
+
"resname": "",
|
56 |
+
"style": main_style,
|
57 |
+
"color": main_color,
|
58 |
+
"residue_range": "",
|
59 |
+
"around": 0,
|
60 |
+
"byres": False,
|
61 |
+
"visible": True
|
62 |
+
},
|
63 |
+
{
|
64 |
+
"model": 0,
|
65 |
+
"chain": "",
|
66 |
+
"resname": "",
|
67 |
+
"style": highlight_style,
|
68 |
+
"color": highlight_color,
|
69 |
+
"residue_range": residue_range,
|
70 |
+
"around": 0,
|
71 |
+
"byres": False,
|
72 |
+
"visible": True
|
73 |
+
}]
|
74 |
|
75 |
## Function to render 3D structure
|
76 |
def render_pdb(pdb_id, chain_id, res_start, res_end, pdb_string=None):
|
|
|
82 |
|
83 |
return Molecule3D(tmp_pdb.name, reps=make_reps(res_start=res_start, res_end=res_end))
|
84 |
|
85 |
+
|
86 |
+
|
87 |
## Function for Scaffolding
|
88 |
+
@spaces.GPU()
|
89 |
+
def scaffold(model_name, pdb_id, chain_id, motif_start, motif_end, prompt_length, insert_size):
|
90 |
pdb = get_pdb(pdb_id, chain_id)
|
91 |
|
92 |
## Get motif sequence and atom37 positions
|
|
|
109 |
num_steps=sequence_prompt.count("_") // 2,
|
110 |
temperature=0.5)
|
111 |
## Generate sequence
|
112 |
+
model = get_model(model_name, HF_TOKEN)
|
113 |
sequence_generation = model.generate(protein_prompt, sequence_generation_config)
|
114 |
generated_sequence = sequence_generation.sequence
|
115 |
|
|
|
117 |
structure_prediction_config = GenerationConfig(
|
118 |
track="structure", # We want ESM3 to generate tokens for the structure track
|
119 |
num_steps=len(sequence_generation) // 8,
|
120 |
+
temperature=0.7,
|
121 |
)
|
122 |
structure_prediction_prompt = ESMProtein(sequence=sequence_generation.sequence)
|
123 |
structure_prediction = model.generate(structure_prediction_prompt, structure_prediction_config)
|
|
|
128 |
# crmsd = structure_prediction_chain.rmsd(renal_dipep_chain, mobile_inds=motif_inds_in_generation, target_inds=motif_inds)
|
129 |
|
130 |
structure_orig_highlight = render_pdb(pdb_id, chain_id, res_start=motif_start, res_end=motif_end)
|
131 |
+
structure_new_highlight = render_pdb(pdb_id, chain_id, res_start=insert_size, res_end=insert_size+len(motif_sequence),
|
132 |
pdb_string=structure_prediction_chain.to_pdb_string())
|
133 |
|
134 |
return [
|
135 |
pdb.sequence,
|
136 |
motif_sequence,
|
137 |
structure_orig_highlight,
|
138 |
+
# gr.Textbox(label="Motif Positions")
|
139 |
sequence_prompt,
|
140 |
# structure_prompt,
|
141 |
# protein_prompt
|
|
|
146 |
]
|
147 |
|
148 |
## Function for Secondary Structure Editing
|
149 |
+
@spaces.GPU()
|
150 |
+
def ss_edit(model_name, pdb_id, chain_id, region_start, region_end, shortened_region_length, shortening_ss8):
|
151 |
pdb = get_pdb(pdb_id, chain_id)
|
152 |
edit_region = np.arange(region_start, region_end)
|
153 |
|
|
|
156 |
|
157 |
## Construct a secondary structure prompt that retains the secondary structure of the flanking regions, and shortens the lengths of helices in the helix-coil-helix region
|
158 |
ss8_prompt = shortening_ss8[:edit_region[0]] + (((shortened_region_length - 3) // 2) * "H" + "C"*3 + ((shortened_region_length - 3) // 2) * "H") + shortening_ss8[edit_region[-1] + 1:]
|
159 |
+
|
160 |
## Save original sequence and secondary structure
|
161 |
original_sequence = pdb.sequence
|
162 |
original_ss8 = shortening_ss8
|
163 |
original_ss8_region = " "*edit_region[0] + shortening_ss8[edit_region[0]:edit_region[-1]+1]
|
164 |
+
|
165 |
proposed_ss8_region = " "*edit_region[0] + ss8_prompt[edit_region[0]:edit_region[0]+shortened_region_length]
|
166 |
|
167 |
## Create protein prompt
|
168 |
protein_prompt = ESMProtein(sequence=sequence_prompt, secondary_structure=ss8_prompt)
|
169 |
|
170 |
## Generatre sequence
|
171 |
+
model = get_model(model_name, HF_TOKEN)
|
172 |
sequence_generation = model.generate(protein_prompt, GenerationConfig(track="sequence", num_steps=protein_prompt.sequence.count("_") // 2, temperature=0.5))
|
173 |
+
|
174 |
## Generate structure
|
175 |
structure_prediction = model.generate(ESMProtein(sequence=sequence_generation.sequence), GenerationConfig(track="structure", num_steps=len(protein_prompt) // 4, temperature=0))
|
176 |
structure_prediction_chain = structure_prediction.to_protein_chain()
|
|
|
193 |
]
|
194 |
|
195 |
## Function for SASA Editing
|
196 |
+
@spaces.GPU()
|
197 |
+
def sasa_edit(model_name, pdb_id, chain_id, span_start, span_end, n_samples):
|
198 |
pdb = get_pdb(pdb_id, chain_id)
|
199 |
|
200 |
structure_prompt = torch.full((len(pdb), 37, 3), torch.nan)
|
201 |
+
structure_prompt[span_start:span_end] = torch.tensor(pdb[span_start:span_end].atom37_positions, dtype=torch.float32)
|
202 |
|
203 |
sasa_prompt = [None]*len(pdb)
|
204 |
sasa_prompt[span_start:span_end] = [40.0]*(span_end - span_start)
|
205 |
|
206 |
protein_prompt = ESMProtein(sequence="_"*len(pdb), coordinates=structure_prompt, sasa=sasa_prompt)
|
207 |
|
208 |
+
model = get_model(model_name, HF_TOKEN)
|
209 |
|
210 |
generated_proteins = []
|
211 |
for i in range(n_samples):
|
|
|
236 |
fn=scaffold,
|
237 |
inputs=[
|
238 |
gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
|
239 |
+
# gr.Textbox(value = "hf_...", label="Hugging Face Token", type="password"),
|
240 |
gr.Textbox(value="1ITU", label = "PDB Code"),
|
241 |
gr.Textbox(value="A", label = "Chain"),
|
242 |
gr.Number(value=123, label="Motif Start"),
|
|
|
262 |
fn=ss_edit,
|
263 |
inputs=[
|
264 |
gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
|
265 |
+
# gr.Textbox(value = "hf_...", label="Hugging Face Token", type="password"),
|
266 |
gr.Textbox(value = "7XBQ", label="PDB ID"),
|
267 |
gr.Textbox(value = "A", label="Chain ID"),
|
268 |
gr.Number(value=38, label="Edit Region Start"),
|
|
|
289 |
fn=sasa_edit,
|
290 |
inputs=[
|
291 |
gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
|
292 |
+
# gr.Textbox(value = "hf_...", label="Hugging Face Token", type="password"),
|
293 |
gr.Textbox(value = "1LBS", label="PDB ID"),
|
294 |
gr.Textbox(value = "A", label="Chain ID"),
|
295 |
gr.Number(value=105, label="Span Start"),
|
296 |
gr.Number(value=116, label="Span End"),
|
297 |
+
# gr.Textbox(value="...", label="SS8 String")
|
298 |
gr.Number(value=1, label="Number of Samples")
|
299 |
],
|
300 |
outputs = [
|
|
|
334 |
|
335 |
Spaces App By: [[Colby T. Ford](https://colbyford.com)] from [Tuple, The Cloud Genomics Company](https://tuple.xyz)
|
336 |
|
337 |
+
NOTE: You will need to agree to EvolutionaryScale's [license agreement](https://huggingface.co/EvolutionaryScale/esm3-sm-open-v1) to use the model. This space uses a stored token for API access.
|
338 |
"""
|
339 |
)
|
340 |
with gr.Row():
|
|
|
352 |
])
|
353 |
|
354 |
if __name__ == "__main__":
|
355 |
+
esm_app.launch()
|