Spaces:
Running on Zero
Running on Zero
Delete inference.py
Browse files- inference.py +0 -74
inference.py
DELETED
|
@@ -1,74 +0,0 @@
|
|
| 1 |
-
"""
|
| 2 |
-
Loads the SERAPH model once at import time and exposes the prediction
|
| 3 |
-
and preset-change handlers used by the Gradio UI.
|
| 4 |
-
"""
|
| 5 |
-
import spaces
|
| 6 |
-
import torch
|
| 7 |
-
|
| 8 |
-
from config import IDX_TO_LABEL
|
| 9 |
-
from dataset import PROTEIN_MAP
|
| 10 |
-
from html_builder import build_result_html
|
| 11 |
-
from model import load_model
|
| 12 |
-
|
| 13 |
-
model, tokenizer = load_model()
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
@spaces.GPU
|
| 17 |
-
def predict_structure(sequence_input: str, selected_protein_name: str) -> tuple:
|
| 18 |
-
"""Runs ESM-2 + BiLSTM inference and builds the HTML visualization."""
|
| 19 |
-
sequence = sequence_input.upper().strip()
|
| 20 |
-
# Sanitize inputs to amino acid alphabet
|
| 21 |
-
valid_aas = set("ACDEFGHIKLMNPQRSTVWY")
|
| 22 |
-
sequence = "".join([c for c in sequence if c in valid_aas])
|
| 23 |
-
|
| 24 |
-
if not sequence:
|
| 25 |
-
empty_html = """
|
| 26 |
-
<div style='padding: 24px; text-align: center; background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.08); border-radius: 16px;'>
|
| 27 |
-
<p style='color: #8e8e93; font-family: "JetBrains Mono", monospace;'>Please enter a valid amino acid sequence (e.g., M K W V T F I S L L L L F S S A)...</p>
|
| 28 |
-
</div>
|
| 29 |
-
"""
|
| 30 |
-
return empty_html, "", ""
|
| 31 |
-
|
| 32 |
-
# Model inference
|
| 33 |
-
tokens = tokenizer(sequence, return_tensors="pt", truncation=True, max_length=512)
|
| 34 |
-
with torch.no_grad():
|
| 35 |
-
output = model(input_ids=tokens["input_ids"], attention_mask=tokens["attention_mask"])
|
| 36 |
-
preds = output.argmax(dim=-1)[0]
|
| 37 |
-
|
| 38 |
-
# Extract predicted structure labels
|
| 39 |
-
pred_labels = [IDX_TO_LABEL[p.item()] for p in preds[1:-1]]
|
| 40 |
-
# Handle truncation alignment safely
|
| 41 |
-
pred_str = "".join(pred_labels[:len(sequence)])
|
| 42 |
-
if len(pred_str) < len(sequence):
|
| 43 |
-
pred_str += "C" * (len(sequence) - len(pred_str))
|
| 44 |
-
|
| 45 |
-
# Match with dataset ground truth if selected
|
| 46 |
-
meta = PROTEIN_MAP.get(selected_protein_name, None)
|
| 47 |
-
has_truth = False
|
| 48 |
-
true_ss = ""
|
| 49 |
-
description = ""
|
| 50 |
-
fun_fact = ""
|
| 51 |
-
|
| 52 |
-
if meta and meta["sequence"].upper() == sequence:
|
| 53 |
-
has_truth = True
|
| 54 |
-
true_ss = meta["true_ss"]
|
| 55 |
-
description = meta["description"]
|
| 56 |
-
fun_fact = meta["fun_fact"]
|
| 57 |
-
|
| 58 |
-
# Calculate Q3 Metric if Ground Truth matches
|
| 59 |
-
q3_score = None
|
| 60 |
-
if has_truth and len(true_ss) == len(sequence):
|
| 61 |
-
matches = sum(1 for i in range(len(sequence)) if pred_str[i] == true_ss[i])
|
| 62 |
-
q3_score = (matches / len(sequence)) * 100.0
|
| 63 |
-
|
| 64 |
-
html_output = build_result_html(sequence, pred_str, true_ss if has_truth else None, q3_score, description, fun_fact)
|
| 65 |
-
|
| 66 |
-
return html_output, sequence, pred_str
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
def on_preset_change(selected_name):
|
| 70 |
-
"""Populates the sequence textbox when a preset dropdown item is chosen."""
|
| 71 |
-
if selected_name in PROTEIN_MAP:
|
| 72 |
-
item = PROTEIN_MAP[selected_name]
|
| 73 |
-
return item["sequence"]
|
| 74 |
-
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|