Spaces:
Sleeping
Sleeping
File size: 5,813 Bytes
32802b5 dd5582f 32802b5 dd5582f 32802b5 dd5582f dd93648 32802b5 dd93648 32802b5 344ca58 32802b5 e3487ab 32802b5 09461d3 32802b5 344ca58 e3487ab 344ca58 09461d3 32802b5 e3487ab 32802b5 09461d3 32802b5 dd93648 32802b5 09461d3 344ca58 09461d3 e3487ab 344ca58 09461d3 89d98f5 e3487ab 344ca58 e3487ab 89d98f5 09461d3 344ca58 e3487ab 344ca58 09461d3 32802b5 09461d3 dd5582f 32802b5 344ca58 32802b5 dd5582f 32802b5 dd5582f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
import gradio as gr
from Bio import Entrez
import requests
from functools import lru_cache
import logging
# Configurar logging
logging.basicConfig(level=logging.INFO)
# Cargar un modelo de lenguaje médico más pequeño (optimizado para CPU)
model_name = "microsoft/BioGPT"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name).to("cpu") # Usar CPU
# Configurar PubMed
Entrez.email = "[email protected]" # Proporciona un correo válido
# Función para buscar en PubMed con caché
@lru_cache(maxsize=100)
def buscar_en_pubmed(pregunta):
try:
# Agregar palabras clave médicas a la pregunta
termino = f"{pregunta} AND (medical OR health OR disease)"
handle = Entrez.esearch(db="pubmed", term=termino, retmax=1) # Buscar solo 1 artículo
record = Entrez.read(handle)
handle.close()
if record["IdList"]:
referencias = []
for id_articulo in record["IdList"]:
handle = Entrez.efetch(db="pubmed", id=id_articulo, rettype="abstract", retmode="text")
resumen = handle.read()
referencias.append(f"Artículo {id_articulo}:\n{resumen[:500]}...\n") # Aumentar el límite a 500 caracteres
handle.close()
return "\n".join(referencias)
else:
return "No encontré artículos relevantes en PubMed."
except Exception as e:
logging.error(f"Error al buscar en PubMed: {e}")
return "Error al buscar en PubMed. Inténtalo de nuevo."
# Función para buscar en Internet con tiempo de espera
def buscar_en_internet(pregunta):
try:
# Agregar palabras clave médicas a la pregunta
termino = f"{pregunta} medical OR healthcare OR treatment"
url = f"https://api.duckduckgo.com/?q={termino}&format=json"
respuesta = requests.get(url, timeout=10) # Incrementa el tiempo de espera a 10 segundos
datos = respuesta.json()
if "Abstract" in datos and datos["Abstract"]:
return datos["Abstract"][:300] # Aumentar el límite a 300 caracteres
else:
return "No encontré información en Internet."
except Exception as e:
logging.error(f"Error al buscar en Internet: {e}")
return "Error al buscar en Internet. Inténtalo de nuevo."
# Función para generar respuestas del modelo (optimizada para CPU)
def generar_respuesta(pregunta):
try:
# Truncar la pregunta si es demasiado larga
pregunta = pregunta[:500] # Limitar a 500 caracteres
inputs = tokenizer(
f"Explica {pregunta} de forma clara y detallada. Incluye causas, síntomas, diagnóstico y tratamiento si corresponde.",
return_tensors="pt",
max_length=512, # Limitar la longitud máxima de entrada
truncation=True
).to("cpu")
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=400, # Aumentar el límite para respuestas más largas
do_sample=True, # Usar muestreo para respuestas más naturales
temperature=0.5, # Reducir la creatividad para respuestas más precisas
num_beams=6 # Mejorar la coherencia
)
respuesta = tokenizer.decode(outputs[0], skip_special_tokens=True)
# Eliminar el prompt de la respuesta
respuesta = respuesta.replace(f"Explica {pregunta} de forma clara y detallada. Incluye causas, síntomas, diagnóstico y tratamiento si corresponde.", "").strip()
return respuesta
except Exception as e:
logging.error(f"Error al generar respuesta del modelo: {e}")
return "No pude generar una respuesta. Inténtalo de nuevo."
# Función principal para hacer preguntas al bot
def pregunta_medica_con_carga(pregunta):
try:
# Validar la entrada
if not isinstance(pregunta, str) or not pregunta.strip():
yield "Por favor, ingresa una pregunta válida."
return
yield "Procesando tu pregunta..." # Mensaje de carga
# Respuesta del modelo médico
respuesta_modelo = generar_respuesta(pregunta)
# Buscar en PubMed
referencias_pubmed = buscar_en_pubmed(pregunta)
# Buscar en Internet
respuesta_internet = buscar_en_internet(pregunta)
# Combinar respuestas
respuesta_final = (
f"Respuesta del Profesor Médico:\n{respuesta_modelo}\n\n"
f"Referencias de PubMed:\n{referencias_pubmed}\n\n"
f"Información de Internet:\n{respuesta_internet}"
)
yield respuesta_final
except Exception as e:
logging.error(f"Error inesperado: {e}")
yield "Lo siento, ocurrió un error al procesar tu pregunta. Por favor, inténtalo de nuevo más tarde."
# Crear la interfaz web con Gradio
css = """
.gradio-container {
background-color: #f9f9f9;
font-family: Arial, sans-serif;
}
.gr-button {
background-color: #007bff;
color: white;
border-radius: 5px;
}
"""
interfaz = gr.Interface(
fn=pregunta_medica_con_carga,
inputs=gr.Textbox(label="Pregunta"),
outputs=gr.Textbox(label="Respuesta"),
title="Profesor Médico Bot",
description="Pregúntale al Profesor Médico sobre medicina. Te explicará de manera clara y didáctica.",
css=css
)
# Lanzar la interfaz
interfaz.launch() |