Muhammadidrees commited on
Commit
2c23c25
·
verified ·
1 Parent(s): 46dfb4d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +160 -105
app.py CHANGED
@@ -1,120 +1,178 @@
 
1
  import gradio as gr
2
  from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
 
 
 
3
 
4
- # -----------------------
5
- # Load Hugging Face Model
6
- # -----------------------
7
  MODEL_ID = "Muhammadidrees/my-gpt-oss"
8
 
 
 
 
9
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
10
- model = AutoModelForCausalLM.from_pretrained(MODEL_ID) # works on CPU & GPU
11
- pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  # -----------------------
15
- # Analysis Function
16
  # -----------------------
17
  def analyze(
18
  albumin, creatinine, glucose, crp, mcv, rdw, alp,
19
  wbc, lymph, age, gender, height, weight
20
  ):
21
- # Calculate BMI
 
 
 
 
22
  try:
23
- height_m = height / 100
24
- bmi = round(weight / (height_m ** 2), 2)
 
25
  except Exception:
26
  bmi = "N/A"
27
 
28
- system_prompt = """
29
- You are a professional AI Medical Assistant.
30
- You are analyzing patient demographics and Levine biomarker panel values.
31
- Output MUST strictly follow this structured format:
32
-
33
- 1. Executive Summary
34
- - Top Priority Issues
35
- - Key Strengths
36
-
37
- 2. System-Specific Analysis
38
- - Blood Health (MCV, RDW, Lymphocytes, WBC)
39
- - Protein & Liver Health (Albumin, ALP)
40
- - Kidney Health (Creatinine µmol/L)
41
- - Metabolic Health (Glucose mmol/L, CRP)
42
- - Other relevant systems
43
-
44
- 3. Personalized Action Plan
45
- - Medical (tests/consults)
46
- - Nutrition (diet & supplements)
47
- - Lifestyle (hydration, exercise, sleep)
48
- - Testing (follow-up labs: ferritin, Vitamin D, GGT)
49
-
50
- 4. Interaction Alerts
51
- - How biomarkers interact (e.g., anemia ↔ infection cycle, ALP with bone/liver origin)
52
-
53
- 5. Tabular Mapping (Biomarker Value → Status → AI-Inferred Insight → Client-Friendly Message)
54
-
55
- 6. Enhanced AI Insights & Longitudinal Risk
56
- - Subclinical nutrient predictions (Iron, B12, Folate, Copper)
57
- - Elevated ALP interpretation (bone vs liver origin)
58
- - WBC & lymphocyte trends for immunity
59
- - Predictive longevity risk profile
60
- """
61
-
62
- patient_input = f"""
63
- Patient Profile:
64
- - Age: {age}
65
- - Gender: {gender}
66
- - Height: {height} cm
67
- - Weight: {weight} kg
68
- - BMI: {bmi}
69
-
70
- Lab Values:
71
- - Albumin: {albumin} g/dL
72
- - Creatinine: {creatinine} mg/dL
73
- - Glucose: {glucose} mg/dL
74
- - CRP: {crp} mg/L
75
- - MCV: {mcv} fL
76
- - RDW: {rdw} %
77
- - ALP: {alp} U/L
78
- - WBC: {wbc} K/uL
79
- - Lymphocytes: {lymph} %
80
- """
81
-
82
- prompt = system_prompt + "\n" + patient_input
83
-
84
- result = pipe(
85
- prompt,
86
- max_new_tokens=1000,
87
- do_sample=True,
88
- temperature=0.3,
89
- top_p=0.9
90
  )
91
 
92
- text = result[0]["generated_text"].strip()
93
-
94
- # Robust split into left (1–4) and right (5–6)
95
- left_sections, right_sections = [], []
96
- capture_left = True
97
- for line in text.splitlines():
98
- if "Tabular Mapping" in line:
99
- capture_left = False
100
- if capture_left:
101
- left_sections.append(line)
102
- else:
103
- right_sections.append(line)
 
 
 
 
 
 
104
 
105
- return "\n".join(left_sections), "\n".join(right_sections)
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
  # -----------------------
109
- # Gradio Interface
110
  # -----------------------
111
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
112
-
113
- gr.Markdown("""
114
- # 🏥 AI Medical Biomarker Analysis
115
- ### Comprehensive wellness insights from lab values
116
- """)
117
-
118
  with gr.Row():
119
  with gr.Column(scale=1):
120
  gr.Markdown("### 👤 Demographics")
@@ -122,13 +180,13 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
122
  gender = gr.Dropdown(["Male", "Female"], label="Gender", value="Male")
123
  height = gr.Number(label="Height (cm)", value=174)
124
  weight = gr.Number(label="Weight (kg)", value=75)
125
-
126
  gr.Markdown("### 🩸 Blood Panel")
127
  wbc = gr.Number(label="WBC (K/uL)", value=6.5)
128
  lymph = gr.Number(label="Lymphocytes (%)", value=30)
129
  mcv = gr.Number(label="MCV (fL)", value=88)
130
  rdw = gr.Number(label="RDW (%)", value=13)
131
-
132
  with gr.Column(scale=1):
133
  gr.Markdown("### 🧬 Chemistry Panel")
134
  albumin = gr.Number(label="Albumin (g/dL)", value=4.2)
@@ -136,28 +194,25 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
136
  glucose = gr.Number(label="Glucose (mg/dL)", value=92)
137
  crp = gr.Number(label="CRP (mg/L)", value=1.0)
138
  alp = gr.Number(label="ALP (U/L)", value=70)
139
-
140
  analyze_btn = gr.Button("🔬 Generate Report", variant="primary")
141
-
142
  with gr.Row():
143
  with gr.Column(scale=1):
144
  gr.Markdown("### 📝 Summary & Action Plan")
145
- left_output = gr.Markdown()
146
  with gr.Column(scale=1):
147
  gr.Markdown("### 📊 Tabular & AI Insights")
148
- right_output = gr.Markdown()
149
-
150
  analyze_btn.click(
151
  fn=analyze,
152
- inputs=[albumin, creatinine, glucose, crp, mcv, rdw, alp,
153
- wbc, lymph, age, gender, height, weight],
154
  outputs=[left_output, right_output]
155
  )
156
-
157
- gr.Markdown(
158
- "*⚠️ Disclaimer: This AI output is for educational purposes only and not a substitute for professional medical advice.*"
159
- )
160
 
 
161
 
 
162
  if __name__ == "__main__":
163
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
+ # app.py
2
  import gradio as gr
3
  from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
4
+ import os
5
+ import torch
6
+ import re
7
 
 
 
 
8
  MODEL_ID = "Muhammadidrees/my-gpt-oss"
9
 
10
+ # -----------------------
11
+ # Load tokenizer + model safely (GPU or CPU)
12
+ # -----------------------
13
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
 
 
14
 
15
+ # Try a few loading strategies so this works on GPU or CPU Spaces
16
+ try:
17
+ # Preferred: let HF decide device placement (works for GPU-enabled Spaces)
18
+ model = AutoModelForCausalLM.from_pretrained(MODEL_ID)
19
+ except Exception:
20
+ # Fallback: force CPU (slower but safe)
21
+ model = AutoModelForCausalLM.from_pretrained(MODEL_ID, torch_dtype=torch.float32, low_cpu_mem_usage=True)
22
+
23
+ # Create pipeline
24
+ pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, device=0 if torch.cuda.is_available() else -1)
25
+
26
+ # -----------------------
27
+ # Helper: robust section splitter
28
+ # -----------------------
29
+ def split_report(text):
30
+ """
31
+ Split model output into left (sections 1-4) and right (sections 5-6).
32
+ Accepts various markers for robustness.
33
+ """
34
+ # Normalize whitespace
35
+ text = text.strip()
36
+ # Common markers that indicate tabular/insights section
37
+ markers = [
38
+ "5. Tabular Mapping",
39
+ "5. Tabular",
40
+ "Tabular Mapping",
41
+ "Tabular & AI Insights",
42
+ "📊 Tabular",
43
+ "## 5",
44
+ ]
45
+ # Find earliest marker occurrence
46
+ idx = None
47
+ for m in markers:
48
+ pos = text.find(m)
49
+ if pos != -1:
50
+ if idx is None or pos < idx:
51
+ idx = pos
52
+ if idx is None:
53
+ # fallback: try splitting at "Enhanced AI Insights" or "Enhanced AI"
54
+ fallback = text.find("Enhanced AI Insights")
55
+ if fallback == -1:
56
+ fallback = text.find("Enhanced AI")
57
+ idx = fallback if fallback != -1 else None
58
+
59
+ if idx is None:
60
+ # couldn't find a split marker -> put everything in left
61
+ return text, ""
62
+ left = text[:idx].strip()
63
+ right = text[idx:].strip()
64
+ return left, right
65
 
66
  # -----------------------
67
+ # The analyze function
68
  # -----------------------
69
  def analyze(
70
  albumin, creatinine, glucose, crp, mcv, rdw, alp,
71
  wbc, lymph, age, gender, height, weight
72
  ):
73
+ # Validate/constrain inputs
74
+ try:
75
+ age = int(age)
76
+ except Exception:
77
+ age = age
78
  try:
79
+ height = float(height)
80
+ weight = float(weight)
81
+ bmi = round(weight / ((height / 100) ** 2), 2) if height > 0 else "N/A"
82
  except Exception:
83
  bmi = "N/A"
84
 
85
+ # Structured system prompt (no estimates; follow sections exactly)
86
+ system_prompt = (
87
+ "You are a professional AI Medical Assistant.\n"
88
+ "You are analyzing patient demographics and Levine biomarker panel values.\n"
89
+ "Output MUST strictly follow this structured format (no extra commentary):\n\n"
90
+ "1. Executive Summary\n"
91
+ " - Top Priority Issues\n"
92
+ " - Key Strengths\n\n"
93
+ "2. System-Specific Analysis\n"
94
+ " - Blood Health (MCV, RDW, Lymphocytes, WBC)\n"
95
+ " - Protein & Liver Health (Albumin, ALP)\n"
96
+ " - Kidney Health (Creatinine µmol/L)\n"
97
+ " - Metabolic Health (Glucose mmol/L, CRP)\n"
98
+ " - Other relevant systems\n\n"
99
+ "3. Personalized Action Plan\n"
100
+ " - Medical (tests/consults)\n"
101
+ " - Nutrition (diet & supplements)\n"
102
+ " - Lifestyle (hydration, exercise, sleep)\n"
103
+ " - Testing (follow-up labs: ferritin, Vitamin D, GGT)\n\n"
104
+ "4. Interaction Alerts\n"
105
+ " - How biomarkers interact (e.g., anemia infection cycle, ALP with bone/liver origin)\n\n"
106
+ "5. Tabular Mapping (Biomarker → Value → Status → AI-Inferred Insight → Client-Friendly Message)\n\n"
107
+ "6. Enhanced AI Insights & Longitudinal Risk\n"
108
+ " - Subclinical nutrient predictions (Iron, B12, Folate, Copper)\n"
109
+ " - Elevated ALP interpretation (bone vs liver origin)\n"
110
+ " - WBC & lymphocyte trends for immunity\n"
111
+ " - Predictive longevity risk profile\n\n"
112
+ "Now analyze the patient below and produce the report strictly in the format above using bullet points, headings and a Markdown table for section 5.\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  )
114
 
115
+ patient_input = (
116
+ f"Patient Profile:\n"
117
+ f"- Age: {age}\n"
118
+ f"- Gender: {gender}\n"
119
+ f"- Height: {height} cm\n"
120
+ f"- Weight: {weight} kg\n"
121
+ f"- BMI: {bmi}\n\n"
122
+ "Lab Values:\n"
123
+ f"- Albumin: {albumin} g/dL\n"
124
+ f"- Creatinine: {creatinine} mg/dL\n"
125
+ f"- Glucose: {glucose} mg/dL\n"
126
+ f"- CRP: {crp} mg/L\n"
127
+ f"- MCV: {mcv} fL\n"
128
+ f"- RDW: {rdw} %\n"
129
+ f"- ALP: {alp} U/L\n"
130
+ f"- WBC: {wbc} K/uL\n"
131
+ f"- Lymphocytes: {lymph} %\n"
132
+ )
133
 
134
+ prompt = system_prompt + "\n" + patient_input
135
 
136
+ # Generate
137
+ # Keep generation parameters conservative for Spaces
138
+ gen = pipe(prompt,
139
+ max_new_tokens=900,
140
+ do_sample=True,
141
+ temperature=0.25,
142
+ top_p=0.9,
143
+ return_full_text=False)
144
+
145
+ # Extract generated text
146
+ generated = gen[0].get("generated_text") or gen[0].get("text") or str(gen[0])
147
+ generated = generated.strip()
148
+
149
+ # Clean: some models repeat prompt — attempt to strip prompt if present
150
+ # Remove leading prompt echo if it appears
151
+ if patient_input.strip() in generated:
152
+ generated = generated.split(patient_input.strip())[-1].strip()
153
+ # Also remove repeated instructions
154
+ if system_prompt.strip() in generated:
155
+ generated = generated.split(system_prompt.strip())[-1].strip()
156
+
157
+ # Split into left/right panels
158
+ left_md, right_md = split_report(generated)
159
+
160
+ # If the model output is empty or too short, return a helpful fallback
161
+ if len(left_md) < 50 and len(right_md) < 50:
162
+ fallback = (
163
+ "⚠️ The model returned an unexpectedly short response. Try re-running the report.\n\n"
164
+ "**Patient Profile:**\n" + patient_input
165
+ )
166
+ return fallback, ""
167
+ return left_md, right_md
168
 
169
  # -----------------------
170
+ # Build Gradio app
171
  # -----------------------
172
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
173
+ gr.Markdown("# 🏥 AI Medical Biomarker Dashboard")
174
+ gr.Markdown("Enter lab values and demographics — Report is generated in two panels (Summary & Table/Insights).")
175
+
 
 
 
176
  with gr.Row():
177
  with gr.Column(scale=1):
178
  gr.Markdown("### 👤 Demographics")
 
180
  gender = gr.Dropdown(["Male", "Female"], label="Gender", value="Male")
181
  height = gr.Number(label="Height (cm)", value=174)
182
  weight = gr.Number(label="Weight (kg)", value=75)
183
+
184
  gr.Markdown("### 🩸 Blood Panel")
185
  wbc = gr.Number(label="WBC (K/uL)", value=6.5)
186
  lymph = gr.Number(label="Lymphocytes (%)", value=30)
187
  mcv = gr.Number(label="MCV (fL)", value=88)
188
  rdw = gr.Number(label="RDW (%)", value=13)
189
+
190
  with gr.Column(scale=1):
191
  gr.Markdown("### 🧬 Chemistry Panel")
192
  albumin = gr.Number(label="Albumin (g/dL)", value=4.2)
 
194
  glucose = gr.Number(label="Glucose (mg/dL)", value=92)
195
  crp = gr.Number(label="CRP (mg/L)", value=1.0)
196
  alp = gr.Number(label="ALP (U/L)", value=70)
197
+
198
  analyze_btn = gr.Button("🔬 Generate Report", variant="primary")
199
+
200
  with gr.Row():
201
  with gr.Column(scale=1):
202
  gr.Markdown("### 📝 Summary & Action Plan")
203
+ left_output = gr.Markdown(value="Press *Generate Report* to create the analysis.")
204
  with gr.Column(scale=1):
205
  gr.Markdown("### 📊 Tabular & AI Insights")
206
+ right_output = gr.Markdown(value="Tabular mapping and enhanced insights will appear here.")
207
+
208
  analyze_btn.click(
209
  fn=analyze,
210
+ inputs=[albumin, creatinine, glucose, crp, mcv, rdw, alp, wbc, lymph, age, gender, height, weight],
 
211
  outputs=[left_output, right_output]
212
  )
 
 
 
 
213
 
214
+ gr.Markdown("*⚠️ Disclaimer: This AI output is for educational purposes only and not a substitute for professional medical advice.*")
215
 
216
+ # Launch (HF Spaces expects this pattern)
217
  if __name__ == "__main__":
218
+ demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)))