pymite6941's picture
Upload models, ONNX exports and application code
e93bfbd verified
Raw
History Blame Contribute Delete
6.38 kB
"""
Browser-based UI for MedicalAI - Light Weight.
Auto-installs gradio if missing.
Auto-generates default models if none are trained.
"""
import importlib
import os
import subprocess
import sys
import tempfile
from PIL import Image
from optimize import (
clear_memory,
get_available_models,
get_device,
infer_blip,
infer_fusion,
infer_fusion_onnx,
set_cpu_threads,
)
CHECKPOINT_PATH = "./checkpoints/fusion_model.pth"
ONNX_FULL_DIR = "./checkpoints/onnx_full"
DEFAULT_MODEL_DIR = "./models/default"
def _ensure_gradio():
try:
return importlib.import_module("gradio")
except ImportError:
from rich.console import Console
console = Console()
console.print("[yellow]'gradio' is required for the web UI.[/yellow]")
import questionary
install = questionary.confirm("Install gradio now?", default=True).ask()
if not install:
console.print("[red]gradio is required. Exiting.[/red]")
sys.exit(1)
console.print("[cyan]Installing gradio...[/cyan]")
subprocess.check_call([sys.executable, "-m", "pip", "install", "gradio"])
return importlib.import_module("gradio")
def _ensure_default_models():
"""Generate default ONNX models if none exist at all."""
if os.path.exists(os.path.join(DEFAULT_MODEL_DIR, "fusion_classifier.onnx")):
return
if os.path.exists(CHECKPOINT_PATH):
return
print("No models found. Generating default models...")
subprocess.check_call(
[sys.executable, "setup_default.py"],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
)
print("Default models ready.")
def analyze_vision(image):
if image is None:
return "Please upload an X-ray image."
with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as f:
path = f.name
Image.fromarray(image).save(path)
try:
caption = infer_blip(path, use_onnx=False)
return caption
except Exception as e:
return f"Error: {e}"
finally:
os.unlink(path)
clear_memory()
def analyze_symptom(image, symptoms, use_onnx):
if image is None:
return "Please upload an X-ray image.", ""
if not symptoms:
symptoms = "No symptoms provided"
with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as f:
path = f.name
Image.fromarray(image).save(path)
try:
if use_onnx:
diagnosis, confidence = infer_fusion_onnx(path, symptoms)
else:
diagnosis, confidence = infer_fusion(path, symptoms)
if diagnosis is None:
return confidence, "No result"
return diagnosis, f"{confidence:.1%}"
except Exception as e:
return f"Error: {e}", ""
finally:
os.unlink(path)
clear_memory()
def main():
set_cpu_threads()
_ensure_default_models()
gr = _ensure_gradio()
models = get_available_models()
has_trained = models["trained_pytorch"]
has_default = models["default_classifier"]
has_onnx_full = models["onnx_full_pipeline"]
model_source = "ONNX (full pipeline)" if has_onnx_full else \
"Trained PyTorch" if has_trained else \
"Default (random weights)" if has_default else \
"NOT AVAILABLE"
print(f"Device: {get_device().upper()}")
print(f"Model: {model_source}")
print()
print("Launching web UI... open the URL below in your browser.")
with gr.Blocks(title="MedicalAI - Light Weight", theme=gr.themes.Soft()) as demo:
gr.Markdown(
"""
# MedicalAI - Light Weight
Upload a chest X-ray for AI-assisted analysis.
"""
)
with gr.Tab("Vision - Generate Report"):
gr.Markdown("Upload an X-ray and get an AI-generated radiology caption.")
with gr.Row():
img_in = gr.Image(label="X-ray Image", type="numpy")
with gr.Row():
btn_vision = gr.Button("Generate Report", variant="primary")
with gr.Row():
caption_out = gr.Textbox(label="Radiology Caption", lines=6)
btn_vision.click(fn=analyze_vision, inputs=img_in, outputs=caption_out)
with gr.Tab("Symptom Check - Diagnosis"):
gr.Markdown("Upload an X-ray, enter symptoms, and get a diagnosis.")
with gr.Row():
img_in2 = gr.Image(label="X-ray Image", type="numpy")
with gr.Row():
symptoms_in = gr.Textbox(
label="Patient Symptoms / Clinical Indication",
placeholder="e.g., shortness of breath, cough, fever...",
lines=3,
)
with gr.Row():
onnx_checkbox = gr.Checkbox(
label="Use ONNX (no PyTorch backend)",
value=has_onnx_full,
interactive=has_onnx_full,
)
with gr.Row():
btn_diag = gr.Button("Diagnose", variant="primary")
with gr.Row():
with gr.Column():
diag_out = gr.Textbox(label="Diagnosis", lines=4)
conf_out = gr.Textbox(label="Confidence")
btn_diag.click(
fn=analyze_symptom,
inputs=[img_in2, symptoms_in, onnx_checkbox],
outputs=[diag_out, conf_out],
)
with gr.Tab("System Info"):
gr.Markdown(f"""
**Device:** `{get_device().upper()}`
**Model:** `{model_source}`
**Trained checkpoint:** {'Yes' if has_trained else 'No'}
**ONNX full pipeline:** {'Yes' if has_onnx_full else 'No'}
**Default model:** {'Yes' if has_default else 'No'}
**Dataset:** `{os.path.abspath('./data/dataset.csv')}`
### 3 ways to improve accuracy
1. **Train** — `python training.py --mode prepare-data && python training.py --mode train`
2. **Update** — `python update.py --models` (downloads pre-trained model from Hugging Face)
3. **Export to ONNX** — `python quantization.py --mode export-full`
""")
demo.launch(server_name="127.0.0.1", server_port=7860, share=False)
if __name__ == "__main__":
main()