Muhammadidrees commited on
Commit
438bc72
·
verified ·
1 Parent(s): 0071032

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +98 -288
app.py CHANGED
@@ -1,142 +1,19 @@
1
  import gradio as gr
2
- from transformers import AutoTokenizer, AutoModelForCausalLM
3
- import torch
4
- import re
5
 
6
- # Load model
 
 
7
  MODEL_ID = "Muhammadidrees/my-gpt-oss"
8
 
9
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
10
-
11
- # Load model with proper dtype handling
12
- try:
13
- # First try auto dtype (preserves original model dtype)
14
- model = AutoModelForCausalLM.from_pretrained(
15
- MODEL_ID,
16
- device_map="auto",
17
- torch_dtype="auto",
18
- low_cpu_mem_usage=True
19
- )
20
- except Exception as e:
21
- print(f"Auto dtype failed: {e}")
22
- try:
23
- # Try BFloat16 specifically
24
- model = AutoModelForCausalLM.from_pretrained(
25
- MODEL_ID,
26
- device_map="auto",
27
- torch_dtype=torch.bfloat16,
28
- low_cpu_mem_usage=True
29
- )
30
- except Exception as e2:
31
- print(f"BFloat16 failed: {e2}")
32
- # Final fallback: float32 (works everywhere but slower)
33
- model = AutoModelForCausalLM.from_pretrained(
34
- MODEL_ID,
35
- device_map="auto",
36
- torch_dtype=torch.float32,
37
- low_cpu_mem_usage=True
38
- )
39
-
40
- if tokenizer.pad_token is None:
41
- tokenizer.pad_token = tokenizer.eos_token
42
- model.config.pad_token_id = tokenizer.eos_token_id
43
-
44
-
45
- def clean_output(text):
46
- """Remove reasoning artifacts and clean formatting"""
47
-
48
- # Remove common reasoning patterns
49
- patterns_to_remove = [
50
- r"Let's produce.*?(?=\*\*|$)",
51
- r"We need to.*?(?=\*\*|$)",
52
- r"We must.*?(?=\*\*|$)",
53
- r"assistantfinal\*\*",
54
- r"Note that.*?(?=\*\*|$)",
55
- r"Use concise statements.*?(?=\*\*|$)",
56
- r"Provide bullet points.*?(?=\*\*|$)",
57
- r"✅ Medical Insights(?!\*\*)",
58
- ]
59
-
60
- for pattern in patterns_to_remove:
61
- text = re.sub(pattern, "", text, flags=re.DOTALL | re.IGNORECASE)
62
-
63
- # Find where actual report starts
64
- start_markers = [
65
- "**1. Executive Summary**",
66
- "**Executive Summary**",
67
- "1. Executive Summary",
68
- "## 1. Executive Summary"
69
- ]
70
-
71
- for marker in start_markers:
72
- if marker in text:
73
- idx = text.find(marker)
74
- text = text[idx:]
75
- break
76
-
77
- # Fix common formatting issues from the model
78
- replacements = {
79
- # Fix typos
80
- 'Albumen': 'Albumin',
81
- 'Creatinin': 'Creatinine',
82
- 'Nomal': 'Normal',
83
- 'Lympho': 'Lymphocytes',
84
- 'Strea‑ngths': 'Strengths',
85
- 'Priori­ties': 'Priorities',
86
- 'Hea​th': 'Health',
87
- 'Kid­nee': 'Kidney',
88
- 'Meta‑bolic': 'Metabolic',
89
- 'Heal­th*': 'Health**',
90
- 'Per­sone­lized': 'Personalized',
91
- 'Ac­tion': 'Action',
92
- 'Pla­n': 'Plan',
93
- 'Interac­tion': 'Interaction',
94
- 'Ta­bular': 'Tabular',
95
- 'Ma­pping': 'Mapping',
96
- 'Bioma­rker': 'Biomarker',
97
- 'Val­ue': 'Value',
98
- 'Sta­tus': 'Status',
99
- 'Clin­i­cal': 'Clinical',
100
- 'In­si­ght': 'Insight',
101
- 'Recom­men­ta­tion': 'Recommendation',
102
- 'Lon­ge‑ti­mal': 'Longitudinal',
103
- 'Lon­ge-Term': 'Long-Term',
104
- 'Insigh ts': 'Insights',
105
- 'A.I.': 'AI',
106
- 'Immu­ne': 'Immune',
107
-
108
- # Fix units
109
- 'gdL': 'g/dL',
110
- 'mgl/dL': 'mg/dL',
111
- 'mg/mL': 'mg/L',
112
- 'ui/l': 'U/L',
113
- 'kc/ml': 'K/uL',
114
- 'fl': 'fL',
115
-
116
- # Clean up weird unicode characters
117
- '­': '',
118
- '​': '',
119
- '‑': '-',
120
- '–': '-',
121
- '—': '-',
122
- '│': '|',
123
- '├─': '|',
124
- '•': '-',
125
- '‐': '-',
126
- }
127
-
128
- for old, new in replacements.items():
129
- text = text.replace(old, new)
130
-
131
- # Clean up extra whitespace and duplicate asterisks
132
- text = re.sub(r'\*{3,}', '**', text)
133
- text = re.sub(r'\n{3,}', '\n\n', text)
134
- text = re.sub(r' {2,}', ' ', text)
135
- text = text.strip()
136
-
137
- return text
138
 
139
 
 
 
 
140
  def analyze(
141
  albumin, creatinine, glucose, crp, mcv, rdw, alp,
142
  wbc, lymph, age, gender, height, weight
@@ -145,186 +22,116 @@ def analyze(
145
  try:
146
  height_m = height / 100
147
  bmi = round(weight / (height_m ** 2), 2)
148
- except:
149
  bmi = "N/A"
150
 
151
- # Determine status for each biomarker
152
- def get_status(value, normal_range):
153
- low, high = normal_range
154
- if value < low:
155
- return "Low"
156
- elif value > high:
157
- return "High"
158
- return "Normal"
159
-
160
- albumin_status = get_status(albumin, (3.5, 5.5))
161
- creatinine_status = get_status(creatinine, (0.7, 1.3))
162
- glucose_status = get_status(glucose, (70, 100))
163
- crp_status = get_status(crp, (0, 3))
164
- mcv_status = get_status(mcv, (80, 100))
165
- rdw_status = get_status(rdw, (11.5, 14.5))
166
- alp_status = get_status(alp, (44, 147))
167
- wbc_status = get_status(wbc, (4, 11))
168
- lymph_status = get_status(lymph, (20, 40))
169
-
170
- # Ultra-direct prompt with explicit instruction to skip reasoning
171
- prompt = f"""You are a medical AI. Generate ONLY the final report. Do NOT include any reasoning, planning, or meta-commentary.
172
-
173
- OUTPUT ONLY THIS STRUCTURE:
174
-
175
- **1. Executive Summary**
176
- - **Top Priority Issues**: List 2-3 main concerns based on abnormal values
177
- - **Key Strengths**: List 2-3 positive findings
178
-
179
- **2. System-Specific Analysis**
180
- - **Blood Health** (MCV {mcv} fL, RDW {rdw}%, Lymph {lymph}%, WBC {wbc} K/uL): Brief clinical interpretation
181
- - **Protein & Liver Health** (Albumin {albumin} g/dL, ALP {alp} U/L): Brief clinical interpretation
182
- - **Kidney Health** (Creatinine {creatinine} mg/dL): Brief clinical interpretation
183
- - **Metabolic Health** (Glucose {glucose} mg/dL, CRP {crp} mg/L): Brief clinical interpretation
184
-
185
- **3. Personalized Action Plan**
186
- - **Medical**: Specific tests or consultations needed
187
- - **Nutrition**: Dietary recommendations and supplements
188
- - **Lifestyle**: Exercise, hydration, sleep recommendations
189
- - **Testing**: Follow-up labs (ferritin, Vitamin D, GGT, etc.)
190
-
191
- **4. Interaction Alerts**
192
- Explain how abnormal biomarkers may interact or compound risks.
193
-
194
- **5. Tabular Mapping**
195
- | Biomarker | Value | Status | Clinical Insight | Recommendation |
196
- |-----------|-------|--------|------------------|----------------|
197
- | Albumin | {albumin} g/dL | {albumin_status} | [insight] | [action] |
198
- | Creatinine | {creatinine} mg/dL | {creatinine_status} | [insight] | [action] |
199
- | Glucose | {glucose} mg/dL | {glucose_status} | [insight] | [action] |
200
- | CRP | {crp} mg/L | {crp_status} | [insight] | [action] |
201
- | MCV | {mcv} fL | {mcv_status} | [insight] | [action] |
202
- | RDW | {rdw}% | {rdw_status} | [insight] | [action] |
203
- | ALP | {alp} U/L | {alp_status} | [insight] | [action] |
204
- | WBC | {wbc} K/uL | {wbc_status} | [insight] | [action] |
205
- | Lymphocytes | {lymph}% | {lymph_status} | [insight] | [action] |
206
-
207
- **6. Enhanced AI Insights & Longitudinal Risk**
208
- - **Subclinical Nutrients**: Predicted Iron, B12, Folate, Copper status
209
- - **ALP Source**: Likely bone vs liver origin
210
- - **Immune Trends**: WBC and lymphocyte assessment
211
- - **Long-term Risk**: Predictive health considerations
212
-
213
- Patient: {gender}, Age {age}, BMI {bmi}
214
-
215
- START REPORT NOW (no reasoning or commentary):
216
-
217
- **1. Executive Summary**"""
218
 
219
- try:
220
- inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=2048)
221
- inputs = {k: v.to(model.device) for k, v in inputs.items()}
222
-
223
- with torch.no_grad():
224
- outputs = model.generate(
225
- **inputs,
226
- max_new_tokens=2800,
227
- min_new_tokens=1000,
228
- temperature=0.75,
229
- top_p=0.92,
230
- top_k=40,
231
- repetition_penalty=1.2,
232
- do_sample=True,
233
- early_stopping=False,
234
- pad_token_id=tokenizer.pad_token_id,
235
- eos_token_id=tokenizer.eos_token_id,
236
- no_repeat_ngram_size=4
237
- )
238
-
239
- generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
240
-
241
- # Extract the actual report part
242
- if "START REPORT NOW" in generated_text:
243
- output_text = generated_text.split("START REPORT NOW")[-1]
244
- elif "**1. Executive Summary**" in generated_text:
245
- parts = generated_text.split("**1. Executive Summary**")
246
- # Take the LAST occurrence (the actual output, not from prompt)
247
- if len(parts) > 1:
248
- output_text = "**1. Executive Summary**" + parts[-1]
249
- else:
250
- output_text = generated_text
251
- else:
252
- output_text = generated_text
253
-
254
- # Clean up the output
255
- output_text = clean_output(output_text)
256
-
257
- # Improved validation with flexible matching
258
- required_sections = {
259
- "Executive Summary": ["Executive Summary", "Execut­ive Sum", "Executive Sum"],
260
- "System-Specific Analysis": ["System-Specific Analysis", "System‑Specific", "Sys‐tem‑Specific"],
261
- "Personalized Action Plan": ["Personalized Action Plan", "Per­sone­lized Ac­tion", "Action Plan"],
262
- "Interaction Alerts": ["Interaction Alerts", "Interac­tion Alerts"],
263
- "Tabular Mapping": ["Tabular Mapping", "Ta­bular Ma­pping", "| Bioma"],
264
- "Enhanced AI Insights": ["Enhanced AI Insights", "Enhanced A.I. Insigh", "Lon­ge‑ti"]
265
- }
266
-
267
- missing_sections = []
268
- for section, variants in required_sections.items():
269
- if not any(variant in output_text for variant in variants):
270
- missing_sections.append(section)
271
-
272
- # Only warn if truly incomplete (very short OR missing most sections)
273
- if len(output_text) < 500 or len(missing_sections) >= 4:
274
- warning = "\n\n⚠️ **Warning: Incomplete Output**\n\n"
275
- warning += f"Generated: {len(output_text)} characters | Missing: {', '.join(missing_sections) if missing_sections else 'None'}\n\n"
276
- warning += "**Suggestions:**\n"
277
- warning += "- Try regenerating with different parameter values\n"
278
- warning += "- Consider using a larger model (Llama-3-8B, Mistral-7B)\n"
279
- warning += "- Or use API-based models for guaranteed quality\n"
280
- output_text += warning
281
-
282
- return output_text
283
-
284
- except Exception as e:
285
- return f"❌ **Error**: {str(e)}\n\nPlease verify all inputs and model availability."
286
 
287
 
 
288
  # Gradio Interface
 
289
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
290
 
291
  gr.Markdown("""
292
- # 🏥 AI Medical Biomarker Analysis
293
  ### Comprehensive wellness insights from lab values
294
  """)
295
 
296
  with gr.Row():
297
  with gr.Column(scale=1):
298
  gr.Markdown("### 👤 Demographics")
299
- age = gr.Number(label="Age", value=35)
300
  gender = gr.Dropdown(["Male", "Female"], label="Gender", value="Male")
301
- height = gr.Number(label="Height (cm)", value=175)
302
  weight = gr.Number(label="Weight (kg)", value=75)
303
 
304
  gr.Markdown("### 🩸 Blood Panel")
305
- wbc = gr.Number(label="WBC (K/uL)", value=7.0)
306
- lymph = gr.Number(label="Lymphocytes (%)", value=30)
307
- mcv = gr.Number(label="MCV (fL)", value=90)
308
  rdw = gr.Number(label="RDW (%)", value=13)
309
 
310
  with gr.Column(scale=1):
311
  gr.Markdown("### 🧬 Chemistry Panel")
312
- albumin = gr.Number(label="Albumin (g/dL)", value=4.2)
313
- creatinine = gr.Number(label="Creatinine (mg/dL)", value=1.0)
314
- glucose = gr.Number(label="Glucose (mg/dL)", value=95)
315
- crp = gr.Number(label="CRP (mg/L)", value=1.5)
316
- alp = gr.Number(label="ALP (U/L)", value=75)
317
 
318
- analyze_btn = gr.Button("🔬 Generate Report", variant="primary", size="lg")
319
 
320
  gr.Markdown("### 📊 Analysis Output")
321
- output = gr.Textbox(
322
- label="Medical Report",
323
- lines=30,
324
- max_lines=50,
325
- show_copy_button=True,
326
- placeholder="Results will appear here..."
327
- )
328
 
329
  analyze_btn.click(
330
  fn=analyze,
@@ -333,6 +140,9 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
333
  outputs=output
334
  )
335
 
336
- gr.Markdown("*Disclaimer: For educational purposes only. Consult healthcare professionals.*")
 
 
337
 
338
- demo.launch()
 
 
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, device_map="auto")
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
 
22
  try:
23
  height_m = height / 100
24
  bmi = round(weight / (height_m ** 2), 2)
25
+ except Exception:
26
  bmi = "N/A"
27
 
28
+ # Fixed Instruction (no estimation, structured format only)
29
+ system_prompt = """
30
+ You are a professional AI Medical Assistant.
31
+ You are analyzing patient demographics and Levine biomarker panel values.
32
+ Output MUST strictly follow this structured format:
33
+
34
+ 1. Executive Summary
35
+ - Top Priority Issues
36
+ - Key Strengths
37
+
38
+ 2. System-Specific Analysis
39
+ - Blood Health (MCV, RDW, Lymphocytes, WBC)
40
+ - Protein & Liver Health (Albumin, ALP)
41
+ - Kidney Health (Creatinine µmol/L)
42
+ - Metabolic Health (Glucose mmol/L, CRP)
43
+ - Other relevant systems
44
+
45
+ 3. Personalized Action Plan
46
+ - Medical (tests/consults)
47
+ - Nutrition (diet & supplements)
48
+ - Lifestyle (hydration, exercise, sleep)
49
+ - Testing (follow-up labs: ferritin, Vitamin D, GGT)
50
+
51
+ 4. Interaction Alerts
52
+ - How biomarkers interact (e.g., anemia ↔ infection cycle, ALP with bone/liver origin)
53
+
54
+ 5. Tabular Mapping (Biomarker → Value → Status → AI-Inferred Insight → Client-Friendly Message)
55
+
56
+ 6. Enhanced AI Insights & Longitudinal Risk
57
+ - Subclinical nutrient predictions (Iron, B12, Folate, Copper)
58
+ - Elevated ALP interpretation (bone vs liver origin)
59
+ - WBC & lymphocyte trends for immunity
60
+ - Predictive longevity risk profile
61
+ """
62
+
63
+ # Patient Data
64
+ patient_input = f"""
65
+ Patient Profile:
66
+ - Age: {age}
67
+ - Gender: {gender}
68
+ - Height: {height} cm
69
+ - Weight: {weight} kg
70
+ - BMI: {bmi}
71
+
72
+ Lab Values:
73
+ - Albumin: {albumin} g/dL
74
+ - Creatinine: {creatinine} mg/dL
75
+ - Glucose: {glucose} mg/dL
76
+ - CRP: {crp} mg/L
77
+ - MCV: {mcv} fL
78
+ - RDW: {rdw} %
79
+ - ALP: {alp} U/L
80
+ - WBC: {wbc} K/uL
81
+ - Lymphocytes: {lymph} %
82
+ """
83
+
84
+ prompt = system_prompt + "\n" + patient_input
85
+
86
+ # Call LLM
87
+ result = pipe(
88
+ prompt,
89
+ max_new_tokens=1500,
90
+ do_sample=True,
91
+ temperature=0.3,
92
+ top_p=0.9,
93
+ return_full_text=False
94
+ )
95
 
96
+ return result[0]["generated_text"].strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
 
99
+ # -----------------------
100
  # Gradio Interface
101
+ # -----------------------
102
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
103
 
104
  gr.Markdown("""
105
+ # 🏥 AI Medical Biomarker Analysis
106
  ### Comprehensive wellness insights from lab values
107
  """)
108
 
109
  with gr.Row():
110
  with gr.Column(scale=1):
111
  gr.Markdown("### 👤 Demographics")
112
+ age = gr.Number(label="Age", value=30)
113
  gender = gr.Dropdown(["Male", "Female"], label="Gender", value="Male")
114
+ height = gr.Number(label="Height (cm)", value=174)
115
  weight = gr.Number(label="Weight (kg)", value=75)
116
 
117
  gr.Markdown("### 🩸 Blood Panel")
118
+ wbc = gr.Number(label="WBC (K/uL)", value=1.0)
119
+ lymph = gr.Number(label="Lymphocytes (%)", value=2)
120
+ mcv = gr.Number(label="MCV (fL)", value=88)
121
  rdw = gr.Number(label="RDW (%)", value=13)
122
 
123
  with gr.Column(scale=1):
124
  gr.Markdown("### 🧬 Chemistry Panel")
125
+ albumin = gr.Number(label="Albumin (g/dL)", value=3.0)
126
+ creatinine = gr.Number(label="Creatinine (mg/dL)", value=0.9)
127
+ glucose = gr.Number(label="Glucose (mg/dL)", value=90)
128
+ crp = gr.Number(label="CRP (mg/L)", value=0.5)
129
+ alp = gr.Number(label="ALP (U/L)", value=70)
130
 
131
+ analyze_btn = gr.Button("🔬 Generate Report", variant="primary")
132
 
133
  gr.Markdown("### 📊 Analysis Output")
134
+ output = gr.Markdown(label="Medical Report")
 
 
 
 
 
 
135
 
136
  analyze_btn.click(
137
  fn=analyze,
 
140
  outputs=output
141
  )
142
 
143
+ gr.Markdown(
144
+ "*⚠️ Disclaimer: This AI output is for educational purposes only and not a substitute for professional medical advice.*"
145
+ )
146
 
147
+ # Launch app
148
+ demo.launch()