lukiod commited on
Commit
e1fb3b2
Β·
verified Β·
1 Parent(s): 026e077

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +175 -173
app.py CHANGED
@@ -1,175 +1,189 @@
1
  import gradio as gr
2
  import pandas as pd
3
  from datetime import datetime
4
- from huggingface_hub import InferenceClient
 
 
 
5
  import os
6
- from typing import Optional, Dict, List, Any
7
- import json
8
 
9
- # ====================== MODEL CONFIGURATION ======================
10
- FALCON_MODEL = "tiiuae/falcon-7b-instruct"
11
- BACKUP_MODEL = "google/flan-t5-base" # Smaller model as backup
12
-
13
- class LLMHandler:
14
  def __init__(self):
15
- self.client = self._init_client()
16
- self.has_llm = self.client is not None
17
-
18
- def _init_client(self) -> Optional[InferenceClient]:
 
 
 
19
  try:
20
- return InferenceClient(
21
- model=FALCON_MODEL,
22
- token=os.getenv("HF_TOKEN")
 
 
23
  )
 
 
24
  except Exception as e:
25
- print(f"Primary LLM initialization failed: {str(e)}")
26
- try:
27
- return InferenceClient(model=BACKUP_MODEL)
28
- except:
29
- return None
30
 
31
- def get_response(self, prompt: str, temperature: float = 0.7) -> str:
32
- if not self.has_llm:
33
- return "Service is running in basic mode. Using template responses."
34
-
35
  try:
36
- response = self.client.text_generation(
 
 
 
 
 
 
37
  prompt,
38
- max_new_tokens=512,
39
- temperature=temperature,
40
- repetition_penalty=1.1,
41
- do_sample=True,
42
- top_k=10,
43
- top_p=0.95
44
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  return response
46
  except Exception as e:
47
- return f"Error: {str(e)}"
 
 
 
 
 
48
 
49
- # ====================== DATA MANAGEMENT ======================
50
- class HealthDataManager:
51
  def __init__(self):
52
- self.metrics: List[Dict[str, Any]] = []
53
- self.medications: List[Dict[str, Any]] = []
54
 
55
- def add_metrics(self, metrics: Dict[str, Any]) -> bool:
56
  try:
57
  self.metrics.append({
58
  'Date': datetime.now().strftime('%Y-%m-%d'),
59
  **metrics
60
  })
61
  return True
62
- except Exception:
63
  return False
64
 
65
- def add_medication(self, medication: Dict[str, Any]) -> bool:
66
  try:
67
  self.medications.append(medication)
68
  return True
69
- except Exception:
70
  return False
71
 
72
- def get_metrics_df(self) -> pd.DataFrame:
73
- return pd.DataFrame(self.metrics)
74
-
75
- def get_medications_df(self) -> pd.DataFrame:
76
- return pd.DataFrame(self.medications)
77
-
78
- def get_latest_metrics(self) -> Optional[Dict[str, Any]]:
79
- return self.metrics[-1] if self.metrics else None
80
-
81
- def format_health_context(self) -> str:
82
- context = []
83
 
84
- # Add metrics context
85
  if self.metrics:
86
- latest = self.get_latest_metrics()
87
- context.append(f"""Recent Health Metrics:
88
- - Date: {latest['Date']}
89
- - Weight: {latest['Weight']} kg
90
- - Steps: {latest['Steps']}
91
- - Sleep: {latest['Sleep']} hours""")
92
 
93
- # Add trends
94
- if len(self.metrics) > 1:
95
- df = self.get_metrics_df()
96
- context.append("\nTrends:")
97
- for column in ['Weight', 'Steps', 'Sleep']:
98
- trend = df[column].diff().iloc[-1]
99
- if not pd.isna(trend):
100
- direction = "increased" if trend > 0 else "decreased"
101
- context.append(f"- {column} has {direction} by {abs(trend):.1f}")
102
-
103
- # Add medications context
104
  if self.medications:
105
- context.append("\nCurrent Medications:")
106
  for med in self.medications:
107
- context.append(f"- {med['Medication']} ({med['Dosage']}) at {med['Time']}")
108
  if med['Notes']:
109
- context.append(f" Note: {med['Notes']}")
 
110
 
111
- return "\n".join(context) if context else ""
112
 
113
- # ====================== HEALTH ASSISTANT ======================
114
  class HealthAssistant:
115
  def __init__(self):
116
- self.llm = LLMHandler()
117
- self.data_manager = HealthDataManager()
118
-
119
- def analyze_symptoms(self, symptoms: str) -> str:
120
- if not symptoms:
121
- return "Please describe your symptoms."
122
-
123
- prompt = f"""Analyze these symptoms carefully:
124
- {symptoms}
 
125
 
126
- Provide a structured analysis with:
127
- 1. Risk Level (Low/Medium/High)
128
- 2. Key Symptoms Identified
129
- 3. Possible Causes
130
- 4. Recommended Actions
131
- 5. Urgency Level
132
 
133
- Remember to emphasize if immediate medical attention is needed."""
134
-
135
- return self.llm.get_response(prompt, temperature=0.3)
136
 
137
- def chat_response(self, message: str, history: List[Dict[str, str]]) -> str:
138
- if not message:
139
- return ""
140
 
141
  # Get health context
142
- health_context = self.data_manager.format_health_context()
143
 
144
- # Format conversation history
145
- conv_context = "\n".join([
146
- f"Human: {h['content']}" if h['role'] == 'user' else f"Assistant: {h['content']}"
147
- for h in history[-4:] if h['content']
148
- ])
149
 
150
- prompt = f"""System: You are a helpful healthcare assistant. Consider the user's health information when providing advice.
151
-
152
- {f'User Health Information:\n{health_context}\n' if health_context else ''}
153
-
154
- Previous conversation:
155
- {conv_context}
156
-
157
- Current question: {message}
158
-
159
- Provide a helpful response, referencing their health data if relevant. Include appropriate medical disclaimers."""
160
 
161
- return self.llm.get_response(prompt, temperature=0.7)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
- # ====================== GRADIO INTERFACE ======================
164
  class HealthAssistantUI:
165
  def __init__(self):
166
  self.assistant = HealthAssistant()
167
 
168
- def user_chat(self, message: str, history: List[Dict[str, str]]) -> tuple:
169
  if message.strip() == "":
170
  return "", history
171
 
172
- bot_message = self.assistant.chat_response(message, history)
173
  history.append({"role": "user", "content": message})
174
  history.append({"role": "assistant", "content": bot_message})
175
  return "", history
@@ -179,8 +193,9 @@ class HealthAssistantUI:
179
  return "⚠️ Please fill in all metrics.", None
180
 
181
  metrics = {'Weight': weight, 'Steps': steps, 'Sleep': sleep}
182
- if self.assistant.data_manager.add_metrics(metrics):
183
- return "βœ… Metrics saved successfully!", self.assistant.data_manager.get_metrics_df()
 
184
  return "❌ Error saving metrics", None
185
 
186
  def save_medication(self, name: str, dosage: str, time: str, notes: str) -> tuple:
@@ -193,18 +208,14 @@ class HealthAssistantUI:
193
  'Time': time,
194
  'Notes': notes or ''
195
  }
196
- if self.assistant.data_manager.add_medication(medication):
197
- return "βœ… Medication added successfully!", self.assistant.data_manager.get_medications_df()
 
198
  return "❌ Error adding medication", None
199
 
200
  def create_interface(self):
201
  with gr.Blocks(title="Virtual Health Assistant", theme=gr.themes.Soft()) as demo:
202
- gr.Markdown(
203
- """
204
- # πŸ₯ Virtual Health Assistant
205
- Your AI-powered health companion. Get personalized health guidance based on your data.
206
- """
207
- )
208
 
209
  with gr.Tabs():
210
  # Chat Interface
@@ -212,36 +223,29 @@ class HealthAssistantUI:
212
  with gr.Row():
213
  with gr.Column(scale=3):
214
  chatbot = gr.Chatbot(
215
- type='messages',
216
  show_label=False,
217
  height=450,
218
  container=True,
219
- bubble_full_width=False
220
  )
221
  with gr.Column(scale=1):
 
222
  context_display = gr.Markdown(
223
- value=self.assistant.data_manager.format_health_context() or
224
- "*No health data available yet.*"
225
  )
226
 
227
  with gr.Row():
228
  msg = gr.Textbox(
229
- placeholder="Type your health question... (Press Enter to send)",
230
  lines=2,
231
  max_lines=2,
232
  show_label=False,
233
  container=False,
234
  scale=9
235
  )
236
- send_btn = gr.Button("Send", scale=1, variant="primary")
237
 
238
  clear_btn = gr.Button("Clear Chat")
239
-
240
- # Event handlers
241
- msg.submit(self.user_chat, [msg, chatbot], [msg, chatbot])
242
- send_btn.click(self.user_chat, [msg, chatbot], [msg, chatbot])
243
- clear_btn.click(lambda: None, None, chatbot, queue=False)
244
-
245
  # Symptom Checker
246
  with gr.Tab("πŸ” Symptom Checker"):
247
  symptoms_input = gr.Textbox(
@@ -251,71 +255,69 @@ class HealthAssistantUI:
251
  )
252
  analyze_btn = gr.Button("Analyze Symptoms", variant="primary")
253
  symptoms_output = gr.Markdown()
254
-
255
- analyze_btn.click(
256
- self.assistant.analyze_symptoms,
257
- inputs=[symptoms_input],
258
- outputs=[symptoms_output]
259
- )
260
-
261
  # Health Metrics
262
  with gr.Tab("πŸ“Š Health Metrics"):
263
  with gr.Row():
264
  with gr.Column():
265
- weight_input = gr.Number(label="Weight (kg)", minimum=0)
266
- steps_input = gr.Number(label="Steps", minimum=0)
267
- sleep_input = gr.Number(label="Hours Slept", minimum=0)
268
  metrics_btn = gr.Button("Save Metrics", variant="primary")
269
  metrics_status = gr.Markdown()
270
 
271
  with gr.Column():
272
  metrics_display = gr.Dataframe(
273
- headers=["Date", "Weight", "Steps", "Sleep"],
274
- label="Your Health Metrics",
275
- wrap=True
276
  )
277
-
278
- metrics_btn.click(
279
- self.save_metrics,
280
- inputs=[weight_input, steps_input, sleep_input],
281
- outputs=[metrics_status, metrics_display]
282
- )
283
-
284
  # Medication Manager
285
  with gr.Tab("πŸ’Š Medication Manager"):
286
  with gr.Row():
287
  with gr.Column():
288
  med_name = gr.Textbox(label="Medication Name")
289
  med_dosage = gr.Textbox(label="Dosage")
290
- med_time = gr.Textbox(label="Time (e.g., 9:00 AM)")
291
  med_notes = gr.Textbox(label="Notes (optional)")
292
  med_btn = gr.Button("Add Medication", variant="primary")
293
  med_status = gr.Markdown()
294
 
295
  with gr.Column():
296
  meds_display = gr.Dataframe(
297
- headers=["Medication", "Dosage", "Time", "Notes"],
298
- label="Your Medications",
299
- wrap=True
300
  )
301
-
302
- med_btn.click(
303
- self.save_medication,
304
- inputs=[med_name, med_dosage, med_time, med_notes],
305
- outputs=[med_status, meds_display]
306
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
 
308
  gr.Markdown(
309
- """
310
- ### ⚠️ Medical Disclaimer
311
  This AI assistant provides general health information only.
312
- Always consult healthcare professionals for medical advice.
313
- """
314
  )
315
 
316
  return demo
317
 
318
- # ====================== MAIN APPLICATION ======================
319
  def main():
320
  ui = HealthAssistantUI()
321
  demo = ui.create_interface()
 
1
  import gradio as gr
2
  import pandas as pd
3
  from datetime import datetime
4
+ import torch
5
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
6
+ import gc
7
+ from typing import List, Dict, Optional
8
  import os
 
 
9
 
10
+ # ================== Model Configuration ==================
11
+ class ModelHandler:
 
 
 
12
  def __init__(self):
13
+ self.model_name = "google/flan-t5-large"
14
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
15
+ self.tokenizer = None
16
+ self.model = None
17
+ self.initialize_model()
18
+
19
+ def initialize_model(self):
20
  try:
21
+ self.tokenizer = AutoTokenizer.from_pretrained(self.model_name)
22
+ self.model = AutoModelForSeq2SeqLM.from_pretrained(
23
+ self.model_name,
24
+ torch_dtype=torch.float32,
25
+ low_cpu_mem_usage=True
26
  )
27
+ self.model.to(self.device)
28
+ return True
29
  except Exception as e:
30
+ print(f"Error initializing model: {str(e)}")
31
+ return False
 
 
 
32
 
33
+ def generate_response(self, prompt: str, max_length: int = 512) -> str:
 
 
 
34
  try:
35
+ # Clear memory
36
+ gc.collect()
37
+ if torch.cuda.is_available():
38
+ torch.cuda.empty_cache()
39
+
40
+ # Prepare input
41
+ inputs = self.tokenizer(
42
  prompt,
43
+ return_tensors="pt",
44
+ truncation=True,
45
+ max_length=512
46
+ ).to(self.device)
47
+
48
+ # Generate response
49
+ with torch.no_grad():
50
+ outputs = self.model.generate(
51
+ inputs.input_ids,
52
+ max_length=max_length,
53
+ num_beams=2,
54
+ temperature=0.7,
55
+ no_repeat_ngram_size=3,
56
+ length_penalty=1.0
57
+ )
58
+
59
+ response = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
60
+
61
+ # Clear memory
62
+ del outputs, inputs
63
+ gc.collect()
64
+ if torch.cuda.is_available():
65
+ torch.cuda.empty_cache()
66
+
67
  return response
68
  except Exception as e:
69
+ return f"Error generating response: {str(e)}"
70
+
71
+ def clear_memory(self):
72
+ gc.collect()
73
+ if torch.cuda.is_available():
74
+ torch.cuda.empty_cache()
75
 
76
+ # ================== Data Management ==================
77
+ class HealthData:
78
  def __init__(self):
79
+ self.metrics = []
80
+ self.medications = []
81
 
82
+ def add_metrics(self, metrics: Dict) -> bool:
83
  try:
84
  self.metrics.append({
85
  'Date': datetime.now().strftime('%Y-%m-%d'),
86
  **metrics
87
  })
88
  return True
89
+ except:
90
  return False
91
 
92
+ def add_medication(self, medication: Dict) -> bool:
93
  try:
94
  self.medications.append(medication)
95
  return True
96
+ except:
97
  return False
98
 
99
+ def get_health_context(self) -> str:
100
+ context_parts = []
 
 
 
 
 
 
 
 
 
101
 
 
102
  if self.metrics:
103
+ latest = self.metrics[-1]
104
+ context_parts.append(f"Recent Health Metrics (Date: {latest['Date']}):")
105
+ context_parts.append(f"- Weight: {latest['Weight']} kg")
106
+ context_parts.append(f"- Steps: {latest['Steps']}")
107
+ context_parts.append(f"- Sleep: {latest['Sleep']} hours")
 
108
 
 
 
 
 
 
 
 
 
 
 
 
109
  if self.medications:
110
+ context_parts.append("\nCurrent Medications:")
111
  for med in self.medications:
112
+ med_info = f"- {med['Medication']} ({med['Dosage']}) at {med['Time']}"
113
  if med['Notes']:
114
+ med_info += f" | Note: {med['Notes']}"
115
+ context_parts.append(med_info)
116
 
117
+ return "\n".join(context_parts) if context_parts else "No health data available."
118
 
119
+ # ================== Health Assistant ==================
120
  class HealthAssistant:
121
  def __init__(self):
122
+ self.model = ModelHandler()
123
+ self.data = HealthData()
124
+ self.request_count = 0
125
+
126
+ def _create_prompt(self, message: str, context: str = "", history: List = None) -> str:
127
+ prompt_parts = [
128
+ "You are a helpful healthcare assistant. Provide accurate and helpful information.",
129
+ f"User Health Information:\n{context}" if context else "",
130
+ "Previous conversation:",
131
+ ]
132
 
133
+ if history:
134
+ for h in history[-3:]: # Last 3 messages for context
135
+ prompt_parts.append(f"User: {h['content']}" if h['role'] == 'user'
136
+ else f"Assistant: {h['content']}")
 
 
137
 
138
+ prompt_parts.append(f"Current question: {message}")
139
+ return "\n\n".join(filter(None, prompt_parts))
 
140
 
141
+ def get_response(self, message: str, history: List = None) -> str:
142
+ # Increment request counter
143
+ self.request_count += 1
144
 
145
  # Get health context
146
+ context = self.data.get_health_context()
147
 
148
+ # Create prompt
149
+ prompt = self._create_prompt(message, context, history)
 
 
 
150
 
151
+ # Get response
152
+ response = self.model.generate_response(prompt)
153
+
154
+ # Periodic memory cleanup
155
+ if self.request_count % 5 == 0:
156
+ self.model.clear_memory()
157
+
158
+ return response
 
 
159
 
160
+ def analyze_symptoms(self, symptoms: str) -> str:
161
+ if not symptoms:
162
+ return "Please describe your symptoms."
163
+
164
+ prompt = (
165
+ "Analyze these symptoms as a medical professional:\n"
166
+ f"{symptoms}\n\n"
167
+ "Provide analysis with:\n"
168
+ "1. Risk Level\n"
169
+ "2. Key Symptoms\n"
170
+ "3. Possible Causes\n"
171
+ "4. Recommended Actions\n"
172
+ "5. When to Seek Medical Care"
173
+ )
174
+
175
+ return self.model.generate_response(prompt)
176
 
177
+ # ================== Gradio Interface ==================
178
  class HealthAssistantUI:
179
  def __init__(self):
180
  self.assistant = HealthAssistant()
181
 
182
+ def user_chat(self, message: str, history: List) -> tuple:
183
  if message.strip() == "":
184
  return "", history
185
 
186
+ bot_message = self.assistant.get_response(message, history)
187
  history.append({"role": "user", "content": message})
188
  history.append({"role": "assistant", "content": bot_message})
189
  return "", history
 
193
  return "⚠️ Please fill in all metrics.", None
194
 
195
  metrics = {'Weight': weight, 'Steps': steps, 'Sleep': sleep}
196
+ if self.assistant.data.add_metrics(metrics):
197
+ df = pd.DataFrame(self.assistant.data.metrics)
198
+ return "βœ… Metrics saved successfully!", df
199
  return "❌ Error saving metrics", None
200
 
201
  def save_medication(self, name: str, dosage: str, time: str, notes: str) -> tuple:
 
208
  'Time': time,
209
  'Notes': notes or ''
210
  }
211
+ if self.assistant.data.add_medication(medication):
212
+ df = pd.DataFrame(self.assistant.data.medications)
213
+ return "βœ… Medication added successfully!", df
214
  return "❌ Error adding medication", None
215
 
216
  def create_interface(self):
217
  with gr.Blocks(title="Virtual Health Assistant", theme=gr.themes.Soft()) as demo:
218
+ gr.Markdown("# πŸ₯ Virtual Health Assistant")
 
 
 
 
 
219
 
220
  with gr.Tabs():
221
  # Chat Interface
 
223
  with gr.Row():
224
  with gr.Column(scale=3):
225
  chatbot = gr.Chatbot(
 
226
  show_label=False,
227
  height=450,
228
  container=True,
 
229
  )
230
  with gr.Column(scale=1):
231
+ gr.Markdown("### Your Health Info")
232
  context_display = gr.Markdown(
233
+ value=self.assistant.data.get_health_context()
 
234
  )
235
 
236
  with gr.Row():
237
  msg = gr.Textbox(
238
+ placeholder="Type your health question... (Press Enter)",
239
  lines=2,
240
  max_lines=2,
241
  show_label=False,
242
  container=False,
243
  scale=9
244
  )
245
+ send_btn = gr.Button("Send", scale=1)
246
 
247
  clear_btn = gr.Button("Clear Chat")
248
+
 
 
 
 
 
249
  # Symptom Checker
250
  with gr.Tab("πŸ” Symptom Checker"):
251
  symptoms_input = gr.Textbox(
 
255
  )
256
  analyze_btn = gr.Button("Analyze Symptoms", variant="primary")
257
  symptoms_output = gr.Markdown()
258
+
 
 
 
 
 
 
259
  # Health Metrics
260
  with gr.Tab("πŸ“Š Health Metrics"):
261
  with gr.Row():
262
  with gr.Column():
263
+ weight_input = gr.Number(label="Weight (kg)")
264
+ steps_input = gr.Number(label="Steps")
265
+ sleep_input = gr.Number(label="Hours Slept")
266
  metrics_btn = gr.Button("Save Metrics", variant="primary")
267
  metrics_status = gr.Markdown()
268
 
269
  with gr.Column():
270
  metrics_display = gr.Dataframe(
271
+ headers=["Date", "Weight", "Steps", "Sleep"]
 
 
272
  )
273
+
 
 
 
 
 
 
274
  # Medication Manager
275
  with gr.Tab("πŸ’Š Medication Manager"):
276
  with gr.Row():
277
  with gr.Column():
278
  med_name = gr.Textbox(label="Medication Name")
279
  med_dosage = gr.Textbox(label="Dosage")
280
+ med_time = gr.Textbox(label="Time")
281
  med_notes = gr.Textbox(label="Notes (optional)")
282
  med_btn = gr.Button("Add Medication", variant="primary")
283
  med_status = gr.Markdown()
284
 
285
  with gr.Column():
286
  meds_display = gr.Dataframe(
287
+ headers=["Medication", "Dosage", "Time", "Notes"]
 
 
288
  )
289
+
290
+ # Event handlers
291
+ msg.submit(self.user_chat, [msg, chatbot], [msg, chatbot])
292
+ send_btn.click(self.user_chat, [msg, chatbot], [msg, chatbot])
293
+ clear_btn.click(lambda: None, None, chatbot)
294
+
295
+ analyze_btn.click(
296
+ self.assistant.analyze_symptoms,
297
+ inputs=[symptoms_input],
298
+ outputs=[symptoms_output]
299
+ )
300
+
301
+ metrics_btn.click(
302
+ self.save_metrics,
303
+ inputs=[weight_input, steps_input, sleep_input],
304
+ outputs=[metrics_status, metrics_display]
305
+ )
306
+
307
+ med_btn.click(
308
+ self.save_medication,
309
+ inputs=[med_name, med_dosage, med_time, med_notes],
310
+ outputs=[med_status, meds_display]
311
+ )
312
 
313
  gr.Markdown(
314
+ """### ⚠️ Medical Disclaimer
 
315
  This AI assistant provides general health information only.
316
+ Always consult healthcare professionals for medical advice."""
 
317
  )
318
 
319
  return demo
320
 
 
321
  def main():
322
  ui = HealthAssistantUI()
323
  demo = ui.create_interface()