|
import gradio as gr |
|
import torch |
|
from transformers import AutoTokenizer, AutoModel |
|
import time |
|
from functools import wraps |
|
import sys |
|
import spaces |
|
|
|
|
|
def medir_tiempo(func): |
|
@wraps(func) |
|
def wrapper(*args, **kwargs): |
|
inicio = time.time() |
|
resultado = func(*args, **kwargs) |
|
fin = time.time() |
|
tiempo_transcurrido = fin - inicio |
|
print(f"Tiempo de ejecución de '{func.__name__}': {tiempo_transcurrido:.2f} segundos") |
|
return resultado |
|
return wrapper |
|
|
|
|
|
device = "cuda" if torch.cuda.is_available() else "cpu" |
|
if device == "cpu": |
|
print("Advertencia: CUDA no está disponible. Se usará la CPU, lo que puede ser lento.") |
|
|
|
|
|
model_name = "yangheng/OmniGenome" |
|
|
|
try: |
|
print("Cargando el tokenizador...") |
|
tokenizer = AutoTokenizer.from_pretrained(model_name) |
|
except ValueError as e: |
|
print(f"Error al cargar el tokenizador: {e}") |
|
sys.exit(1) |
|
|
|
try: |
|
print("Cargando el modelo...") |
|
model = AutoModel.from_pretrained(model_name) |
|
model.to(device) |
|
except Exception as e: |
|
print(f"Error al cargar el modelo: {e}") |
|
sys.exit(1) |
|
|
|
@spaces.GPU(duration=120) |
|
@medir_tiempo |
|
def predecir_estructura_rna(secuencias): |
|
""" |
|
Función que predice estructuras secundarias de ARN a partir de secuencias de ARN proporcionadas. |
|
""" |
|
try: |
|
if not secuencias.strip(): |
|
return "Por favor, ingresa una o más secuencias de ARN válidas." |
|
|
|
|
|
secuencias_lista = [seq.strip().upper() for seq in secuencias.strip().split('\n') if seq.strip()] |
|
resultados = [] |
|
|
|
for seq in secuencias_lista: |
|
|
|
if not all(residue in 'AUCG' for residue in seq): |
|
resultados.append(f"Secuencia inválida: {seq}. Solo se permiten los nucleótidos A, U, C y G.") |
|
continue |
|
|
|
|
|
inputs = tokenizer(seq, return_tensors="pt") |
|
input_ids = inputs["input_ids"].to(device) |
|
attention_mask = inputs["attention_mask"].to(device) |
|
|
|
|
|
with torch.no_grad(): |
|
outputs = model(input_ids=input_ids, attention_mask=attention_mask) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
predictions = torch.argmax(outputs.logits, dim=-1).squeeze().tolist() |
|
|
|
|
|
|
|
|
|
structure_mapping = { |
|
0: 'Helix', |
|
1: 'Loop', |
|
2: 'Bulge', |
|
3: 'Internal Loop', |
|
|
|
} |
|
|
|
|
|
predicted_structures = [structure_mapping.get(pred, "Unknown") for pred in predictions] |
|
|
|
|
|
nucleotide_to_structure = list(zip(list(seq), predicted_structures)) |
|
|
|
|
|
secuencia_resultado = [] |
|
for i, (nucleotide, structure) in enumerate(nucleotide_to_structure): |
|
secuencia_resultado.append(f"Posición {i+1} - {nucleotide}: {structure}") |
|
|
|
|
|
resultados.append("\n".join(secuencia_resultado)) |
|
|
|
|
|
return "\n\n".join(resultados) |
|
|
|
except Exception as e: |
|
print(f"Error durante la predicción: {e}") |
|
return f"Error al predecir las estructuras de ARN: {e}" |
|
|
|
|
|
titulo = "OmniGenome: Predicción de Estructuras Secundarias de ARN" |
|
descripcion = ( |
|
"Ingresa una o más secuencias de ARN (una por línea) y obtén predicciones de estructuras secundarias para cada nucleótido." |
|
" El modelo utilizado es OmniGenome, un modelo de fundamentos basado en transformadores para alineación secuencia-estructura en tareas genómicas." |
|
) |
|
|
|
iface = gr.Interface( |
|
fn=predecir_estructura_rna, |
|
inputs=gr.Textbox( |
|
lines=10, |
|
placeholder="Escribe tus secuencias de ARN aquí, una por línea (solo A, U, C, G)...", |
|
label="Secuencias de ARN" |
|
), |
|
outputs=gr.Textbox(label="Predicciones de Estructuras Secundarias de ARN"), |
|
title=titulo, |
|
description=descripcion, |
|
examples=[ |
|
[ |
|
"AUGGCUACUUUCG", |
|
"GCGCGAUCGACGUAGCUAGC" |
|
], |
|
[ |
|
"AUAUGCGGUAUCGUACGUA", |
|
"GGAUACGUGAUCGUAGCAGU" |
|
] |
|
], |
|
cache_examples=False, |
|
allow_flagging="never" |
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
iface.launch() |
|
|