Spaces:
Sleeping
Sleeping
| # app.py | |
| import os | |
| import gradio as gr | |
| import torch | |
| import requests | |
| from transformers import pipeline, AutoModelForTokenClassification, AutoTokenizer | |
| from monai.networks.nets import DenseNet121 | |
| import torchxrayvision as xrv | |
| # Configuration | |
| DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions" | |
| DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY") # Set in Hugging Face secrets | |
| DISCLAIMER = """ | |
| <div style="color: red; border: 2px solid red; padding: 15px; margin: 10px;"> | |
| ⚠️ WARNING: This is a prototype demonstration only. NOT ACTUAL MEDICAL ADVICE. | |
| DO NOT USE FOR REAL HEALTH DECISIONS. CONSULT LICENSED PROFESSIONALS. | |
| </div> | |
| """ | |
| class MedicalAssistant: | |
| def __init__(self): | |
| # Medical imaging models | |
| self.medical_models = self._init_imaging_models() | |
| # Clinical text processing | |
| self.prescription_parser = pipeline( | |
| "token-classification", | |
| model="obi/deid_bert_i2b2", | |
| tokenizer="obi/deid_bert_i2b2" | |
| ) | |
| # Safety systems | |
| self.safety_filter = pipeline( | |
| "text-classification", | |
| model="Hate-speech-CNERG/dehatebert-mono-english" | |
| ) | |
| def _init_imaging_models(self): | |
| """Initialize medical imaging models""" | |
| return { | |
| "xray": xrv.models.DenseNet(weights="densenet121-res224-all"), | |
| "ct": DenseNet121(spatial_dims=3, in_channels=1, out_channels=14), | |
| "histo": torch.hub.load('pytorch/vision', 'resnet50', pretrained=True) | |
| } | |
| def query_deepseek(self, prompt: str): | |
| """Query DeepSeek medical research API""" | |
| headers = { | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {DEEPSEEK_API_KEY}" | |
| } | |
| payload = { | |
| "model": "deepseek-medical-1.0", | |
| "messages": [{ | |
| "role": "user", | |
| "content": f"MEDICAL PROMPT: {prompt}\nRespond with latest research-supported information. Cite sources." | |
| }], | |
| "temperature": 0.2, | |
| "max_tokens": 500 | |
| } | |
| try: | |
| response = requests.post(DEEPSEEK_API_URL, json=payload, headers=headers) | |
| response.raise_for_status() | |
| return response.json()['choices'][0]['message']['content'] | |
| except Exception as e: | |
| return f"API Error: {str(e)}" | |
| def analyze_image(self, image_path: str, modality: str): | |
| """Medical image analysis""" | |
| try: | |
| img = self._preprocess_image(image_path, modality) | |
| if modality == "xray": | |
| output = self.medical_models["xray"](img) | |
| return xrv.datasets.default_pathologies[torch.argmax(output)] | |
| elif modality == "ct": | |
| output = self.medical_models["ct"](img) | |
| return "CT analysis placeholder" | |
| elif modality == "histo": | |
| output = self.medical_models["histo"](img) | |
| return "Histopathology analysis placeholder" | |
| except Exception as e: | |
| return f"Image analysis error: {str(e)}" | |
| def parse_prescription(self, text: str): | |
| """Clinical text parsing""" | |
| entities = self.prescription_parser(text) | |
| return { | |
| "medications": [ent for ent in entities if ent['entity'] == 'MEDICATION'], | |
| "dosage": [ent for ent in entities if ent['entity'] == 'DOSAGE'] | |
| } | |
| def generate_response(self, query: str, context: dict): | |
| """Generate safe, research-backed response""" | |
| # Construct enhanced prompt | |
| research_prompt = f""" | |
| Medical Query: {query} | |
| Context: | |
| - Image Findings: {context.get('image_analysis', 'N/A')} | |
| - Prescription Data: {context.get('prescription', 'N/A')} | |
| Requirements: | |
| 1. Provide evidence-based medical information | |
| 2. Cite recent research (post-2020 when possible) | |
| 3. Include safety considerations | |
| 4. Note confidence level | |
| """ | |
| # Get DeepSeek research response | |
| raw_response = self.query_deepseek(research_prompt) | |
| # Apply safety filters | |
| if self._is_unsafe(raw_response): | |
| return "I cannot provide advice on this matter. Please consult a healthcare professional." | |
| return self._add_disclaimer(raw_response) | |
| def _is_unsafe(self, text: str): | |
| """Content safety check""" | |
| return self.safety_filter(text)[0]['label'] == 'HATE' | |
| def _add_disclaimer(self, text: str): | |
| """Add legal disclaimer to response""" | |
| return f"{text}\n\n---\n⚠️ This information is for research purposes only. Not medical advice." | |
| def _preprocess_image(self, image_path: str, modality: str): | |
| """Image preprocessing placeholder""" | |
| return torch.rand((1, 224, 224)) | |
| # Initialize system | |
| assistant = MedicalAssistant() | |
| def process_input(query, image, prescription): | |
| context = {} | |
| if image is not None: | |
| context["image_analysis"] = assistant.analyze_image(image, "xray") | |
| if prescription: | |
| context["prescription"] = assistant.parse_prescription(prescription) | |
| return assistant.generate_response(query, context) | |
| # Gradio interface | |
| interface = gr.Interface( | |
| fn=process_input, | |
| inputs=[ | |
| gr.Textbox(label="Medical Query", placeholder="Enter your medical question..."), | |
| gr.Image(label="Medical Imaging", type="filepath"), | |
| gr.Textbox(label="Prescription Text") | |
| ], | |
| outputs=gr.Textbox(label="Research-Backed Response"), | |
| title="AI Medical Research Assistant", | |
| description=DISCLAIMER, | |
| allow_flagging="never" | |
| ) | |
| interface.launch() |