atalaydenknalbant commited on
Commit
6777e11
·
1 Parent(s): 9186e4f

Fix: Resolve runtime errors by enabling GPU, refactoring auth and updating gradio

Browse files

The 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.

Files changed (2) hide show
  1. README.md +1 -1
  2. app.py +58 -49
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 🧬
4
  colorFrom: gray
5
  colorTo: green
6
  sdk: gradio
7
- sdk_version: 4.37.1
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
- # import spaces
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 torch.cuda.is_available():
30
- model = ESM3.from_pretrained(model_name, device=torch.device("cuda"))
31
- else:
32
- model = ESM3.from_pretrained(model_name, device=torch.device("cpu"))
 
 
 
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
- "model": 0,
50
- "chain": "",
51
- "resname": "",
52
- "style": main_style,
53
- "color": main_color,
54
- "residue_range": "",
55
- "around": 0,
56
- "byres": False,
57
- "visible": True
58
- },
59
- {
60
- "model": 0,
61
- "chain": "",
62
- "resname": "",
63
- "style": highlight_style,
64
- "color": highlight_color,
65
- "residue_range": residue_range,
66
- "around": 0,
67
- "byres": False,
68
- "visible": True
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
- def scaffold(model_name, token, pdb_id, chain_id, motif_start, motif_end, prompt_length, insert_size):
 
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, token)
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
- # motif_atom37_positions,
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
- def ss_edit(model_name, token, pdb_id, chain_id, region_start, region_end, shortened_region_length, shortening_ss8):
 
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, token)
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
- def sasa_edit(model_name, token, pdb_id, chain_id, span_start, span_end, n_samples):
 
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, token)
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 = "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", label="Hugging Face Token", type="password"),
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 = "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", label="Hugging Face Token", type="password"),
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 = "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", label="Hugging Face Token", type="password"),
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="CCSSCCCCSSCHHHHHHTEEETTBBTTBCSSEEEEECCTTCCHHHHHTTTHHHHHHHTTCEEEEECCTTTTCSCHHHHHHHHHHHHHHHHHHTTSCCEEEEEETHHHHHHHHHHHHCGGGGGTEEEEEEESCCTTCBGGGHHHHHTTCBCHHHHHTBTTCHHHHHHHHTTTTBCSSCEEEEECTTCSSSCCCCSSSTTSTTCCBTSEEEEHHHHHCTTCCCCSHHHHHBHHHHHHHHHHHHCTTSSCCGGGCCSTTCCCSBCTTSCHHHHHHHHSTHHHHHHHHHHSCCBSSCCCCCGGGGGGSTTCEETTEECCC", label="SS8 String")
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. Then, create and paste your HuggingFace token in the appropriate field.
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()