MattStammers commited on
Commit
38df248
·
verified ·
1 Parent(s): d4e11a5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -35
app.py CHANGED
@@ -1,47 +1,97 @@
 
 
 
 
1
  import gradio as gr
2
- from sentence_transformers import SentenceTransformer, util
3
- from transformers import pipeline
4
 
5
- # --- MODELS ---
6
- embedder = SentenceTransformer("all-MiniLM-L6-v2")
7
- llm = pipeline("text-generation", model="gpt2", max_new_tokens=60)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- # --- RULE-BASED FUNCTION ---
10
- def rule_based(text):
11
- if "anaemia" in text.lower() or "anemia" in text.lower():
12
- return "✅ Anaemia detected (keyword match)"
13
- else:
14
- return "❌ Anaemia not detected (no keyword match)"
15
 
16
- # --- MACHINE LEARNING FUNCTION ---
17
- reference_text = "Patient diagnosed with anaemia and low haemoglobin."
18
- ref_emb = embedder.encode(reference_text, convert_to_tensor=True)
 
 
19
 
20
- def ml_based(text):
 
 
 
 
21
  emb = embedder.encode(text, convert_to_tensor=True)
22
- score = util.cos_sim(emb, ref_emb).item()
23
- return f"Similarity to anaemia reference: {score:.2f}\n" + \
24
- ("✅ Anaemia likely" if score > 0.45 else "❌ Anaemia unlikely")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- # --- AI / FOUNDATION MODEL FUNCTION ---
27
- def ai_based(text):
28
- prompt = f"Determine if the following note suggests anaemia:\n\n{text}\n\nAnswer clearly with reasoning."
29
- result = llm(prompt)[0]["generated_text"]
30
- return result
31
 
32
- # --- GRADIO UI ---
33
- with gr.Blocks(title="Rule-Based vs Machine Learning vs AI") as demo:
34
- gr.Markdown("# 🔍 Clinical Text Understanding Demo\nCompare rule-based, ML, and AI approaches for detecting **anaemia**.")
35
- text_input = gr.Textbox(label="Enter clinical note", lines=4)
36
- rb_output = gr.Textbox(label="Rule-Based Result")
37
- ml_output = gr.Textbox(label="Machine Learning Result")
38
- ai_output = gr.Textbox(label="AI (LLM) Result")
39
 
40
- def process(text):
41
- return rule_based(text), ml_based(text), ai_based(text)
 
 
42
 
43
- btn = gr.Button("Run All")
44
- btn.click(process, inputs=text_input, outputs=[rb_output, ml_output, ai_output])
 
 
45
 
46
- demo.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False, show_error=True)
47
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ from functools import lru_cache
4
+
5
  import gradio as gr
 
 
6
 
7
+ # --- Space-friendly settings ---
8
+ # Keep caches persistent if you enabled Space storage
9
+ os.environ.setdefault("HF_HOME", "/data/huggingface")
10
+ os.environ.setdefault("GRADIO_ANALYTICS_ENABLED", "false")
11
+
12
+ # ---------- Lazy model loaders (no heavy work at import time) ----------
13
+ @lru_cache(maxsize=1)
14
+ def get_embedder():
15
+ # lazy import to avoid blocking the frontend
16
+ from sentence_transformers import SentenceTransformer
17
+ return SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
18
+
19
+ @lru_cache(maxsize=1)
20
+ def get_ref_emb():
21
+ from sentence_transformers import util # imported where needed
22
+ embedder = get_embedder()
23
+ reference_text = "Patient diagnosed with anaemia and low haemoglobin."
24
+ return embedder.encode(reference_text, convert_to_tensor=True)
25
 
26
+ @lru_cache(maxsize=1)
27
+ def get_llm():
28
+ from transformers import pipeline
29
+ # keep it light; GPT-2 works on CPU
30
+ return pipeline("text-generation", model="gpt2", max_new_tokens=80)
 
31
 
32
+ # ------------------------ Functions per approach ------------------------
33
+ def rule_based(text: str) -> str:
34
+ if re.search(r"\banae?mia\b", text, flags=re.IGNORECASE):
35
+ return "Anaemia detected (keyword match)"
36
+ return "Anaemia not detected (no keyword match)"
37
 
38
+ def ml_based(text: str) -> str:
39
+ # load lazily (first call)
40
+ from sentence_transformers import util
41
+ embedder = get_embedder()
42
+ ref_emb = get_ref_emb()
43
  emb = embedder.encode(text, convert_to_tensor=True)
44
+ score = float(util.cos_sim(emb, ref_emb).item())
45
+ verdict = "Anaemia likely" if score > 0.45 else "Anaemia unlikely"
46
+ return f"Similarity: {score:.2f}\n{verdict}"
47
+
48
+ def ai_based(text: str) -> str:
49
+ llm = get_llm()
50
+ prompt = (
51
+ "Determine if the following clinical note suggests anaemia. "
52
+ "Answer clearly in one short paragraph with reasoning.\n\n"
53
+ f"{text}\n"
54
+ )
55
+ out = llm(prompt)[0]["generated_text"]
56
+ return out
57
+
58
+ # ----------------------------- UI -----------------------------
59
+ def build_ui():
60
+ with gr.Blocks(title="RB vs ML vs AI — Anaemia Demo", theme=gr.themes.Soft()) as demo:
61
+ gr.Markdown("## Clinical Text Understanding — Three Approaches")
62
+ with gr.Row():
63
+ default_note = "The patient presents with fatigue and very low haemoglobin."
64
+ input_box = gr.Textbox(value=default_note, label="Clinical note", lines=4)
65
 
66
+ with gr.Tabs():
67
+ with gr.Tab("Rule-Based"):
68
+ rb_btn = gr.Button("Run Rule-Based")
69
+ rb_out = gr.Textbox(label="Result", lines=3)
70
+ rb_btn.click(fn=rule_based, inputs=input_box, outputs=rb_out)
71
 
72
+ with gr.Tab("Machine Learning (Embeddings)"):
73
+ ml_btn = gr.Button("Run ML")
74
+ ml_out = gr.Textbox(label="Result", lines=4)
75
+ ml_btn.click(fn=ml_based, inputs=input_box, outputs=ml_out)
 
 
 
76
 
77
+ with gr.Tab("AI / Foundation Model"):
78
+ ai_btn = gr.Button("Run AI")
79
+ ai_out = gr.Textbox(label="Result", lines=8)
80
+ ai_btn.click(fn=ai_based, inputs=input_box, outputs=ai_out)
81
 
82
+ gr.Markdown(
83
+ "Notes: models are loaded lazily on first run to keep the UI responsive in Spaces."
84
+ )
85
+ return demo
86
 
87
+ demo = build_ui()
88
 
89
+ # Queue + launch: SSR off is important for Spaces that show a blank/broken view.
90
+ demo.queue(concurrency_count=1, max_size=10).launch(
91
+ server_name="0.0.0.0",
92
+ server_port=7860,
93
+ ssr_mode=False,
94
+ show_error=True,
95
+ inbrowser=False,
96
+ share=False,
97
+ )