Pant0x commited on
Commit
cbe35e2
·
verified ·
1 Parent(s): c732be2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -117
app.py CHANGED
@@ -1,24 +1,17 @@
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
3
- from transformers import pipeline
4
  import random
5
  import re
6
  import torch
7
- import tempfile
8
- import soundfile as sf
 
9
  import numpy as np
10
- import pyttsx3
11
-
12
- # ==============================
13
- # CONFIG
14
- # ==============================
15
-
16
- # Voice emotion model
17
- emotion_model = pipeline("audio-classification", model="Hatman/audio-emotion-detection")
18
-
19
- # Text model setup
20
- MENTAL_MODEL = "tanusrich/Mental_Health_Chatbot"
21
 
 
 
22
  MENTAL_KEYWORDS = [
23
  "depression", "depressed", "anxiety", "anxious", "panic", "stress", "sad", "lonely",
24
  "trauma", "mental", "therapy", "therapist", "counselor", "mood", "overwhelmed", "anger",
@@ -26,12 +19,13 @@ MENTAL_KEYWORDS = [
26
  "relax", "calm", "sleep", "emotion", "feeling", "feel", "thoughts", "help", "life", "advice",
27
  "unmotivated", "lost", "hopeless", "tired", "burnout", "cry", "hurt", "love", "breakup",
28
  "friend", "family", "alone", "heartbroken", "scared", "fearful",
29
- "ana", "zahqan", "daye2", "ha2t", "mota3ab", "za3lan", "malo", "khalni", "mash3or", "bakhaf",
30
- "w7ed", "msh 3aref", "mash fahem", "malish", "3ayez", "ayez", "7azeen", "mdaye2",
31
  "حزين", "تعبان", "قلق", "خايف", "وحدة", "ضيق", "توتر", "زعلان", "اكتئاب", "علاج",
32
  "مشاعر", "مضغوط", "قلقان", "وحدي", "مش مبسوط", "زهقان", "ضايق", "تعب", "مش مرتاح",
33
  ]
34
 
 
35
  OFF_TOPIC = [
36
  "recipe", "song", "music", "lyrics", "joke", "funny", "laugh", "code", "python", "program",
37
  "game", "food", "cook", "movie", "film", "series", "sport", "football", "instagram",
@@ -40,17 +34,17 @@ OFF_TOPIC = [
40
  "بيزنس", "فلوس", "العاب", "لعبة", "كود", "برمجة", "ذكاء اصطناعي"
41
  ]
42
 
 
43
  OFF_TOPIC_RESPONSES = [
44
- "I'm here to help with emotional and mental well-being. Let's focus on how you're feeling, coping, or managing your emotions today.",
45
- "I specialize in mental and emotional health conversations. Tell me what’s been on your mind lately.",
46
- "Let’s bring it back to how you’ve been feeling — I’m here to help you talk through emotions, stress, or challenges.",
47
- "My goal is to support your mental health. How have things been emotionally for you lately?",
 
48
  ]
49
 
50
- # ==============================
51
- # HELPERS
52
- # ==============================
53
-
54
  def contains_arabic(text: str) -> bool:
55
  return bool(re.search(r"[\u0600-\u06FF]", text))
56
 
@@ -64,83 +58,69 @@ def is_mental_health_related(text: str) -> bool:
64
  return True
65
  return False
66
 
67
- # Text-to-speech helper
68
- def speak_text(text):
69
- engine = pyttsx3.init()
70
- engine.setProperty("rate", 175)
71
- engine.say(text)
72
- engine.runAndWait()
73
-
74
- # ==============================
75
- # MAIN CHAT RESPONSE
76
- # ==============================
77
-
78
- def respond(
79
- message,
80
- history,
81
- system_message,
82
- max_tokens,
83
- temperature,
84
- top_p,
85
- hf_token: gr.OAuthToken,
86
- ):
 
 
 
 
 
 
87
  if not is_mental_health_related(message):
88
- yield random.choice(OFF_TOPIC_RESPONSES)
89
- return
90
-
91
- locked_system_message = (
92
- "You are a licensed mental health therapy assistant. "
93
- "You respond with empathy, emotional intelligence, and a therapeutic tone. "
94
- "Never answer questions unrelated to emotional or mental wellness."
95
- )
96
-
97
- client = InferenceClient(token=hf_token.token, model=MENTAL_MODEL)
98
-
99
- messages = [{"role": "system", "content": locked_system_message}]
100
- messages.extend(history)
101
- messages.append({"role": "user", "content": message})
102
-
103
- response = ""
104
-
105
- for msg in client.chat_completion(
106
- messages,
107
- max_tokens=max_tokens,
108
- stream=True,
109
- temperature=temperature,
110
- top_p=top_p,
111
- ):
112
- token = msg.choices[0].delta.content if len(msg.choices) and msg.choices[0].delta else ""
113
- response += token
114
- yield response
115
-
116
- # Auto speak last reply
117
- speak_text(response)
118
-
119
-
120
- # ==============================
121
- # VOICE EMOTION DETECTION
122
- # ==============================
123
-
124
- def detect_mood(audio_file):
125
- if audio_file is None:
126
- return "No audio detected."
127
- result = emotion_model(audio_file)
128
- mood = max(result, key=lambda x: x["score"])["label"]
129
- return f"Detected mood: {mood}"
130
-
131
-
132
- # ==============================
133
- # UI
134
- # ==============================
135
-
136
- with gr.Blocks(theme=gr.themes.Soft(), title="Mental Health Therapy Chatbot") as app:
137
- gr.Markdown(
138
- "<h1 style='text-align:center; color:#3B82F6;'>🧠 Mental Health Therapy Chatbot</h1>"
139
- "<p style='text-align:center;'>Text or talk about how you feel — your emotional support companion.</p>"
140
- )
141
-
142
  with gr.Row():
143
- with gr.Column(scale=2):
144
  chatbot = gr.ChatInterface(
145
  respond,
146
  type="messages",
@@ -148,23 +128,9 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Mental Health Therapy Chatbot") as
148
  gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
149
  gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
150
  gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
151
- gr.Slider(
152
- minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)"
153
- ),
154
  ],
155
  )
156
- with gr.Column(scale=1):
157
- gr.Markdown("### 🎤 Voice Mood Detection")
158
- audio_input = gr.Audio(sources=["microphone"], type="filepath", label="Record or Upload Voice")
159
- mood_output = gr.Textbox(label="Detected Mood", interactive=False)
160
- audio_btn = gr.Button("Analyze Mood")
161
- audio_btn.click(detect_mood, inputs=audio_input, outputs=mood_output)
162
-
163
- with gr.Row():
164
- gr.Markdown("<hr>")
165
- gr.Markdown(
166
- "<p style='text-align:center;'>Made with ❤️ to support emotional wellness. — Panto</p>"
167
- )
168
-
169
- if __name__ == "__main__":
170
- app.launch()
 
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
 
3
  import random
4
  import re
5
  import torch
6
+ from transformers import Wav2Vec2ForSequenceClassification, Wav2Vec2Processor
7
+ import librosa
8
+ from gtts import gTTS
9
  import numpy as np
10
+ import tempfile
11
+ import os
 
 
 
 
 
 
 
 
 
12
 
13
+ # ------------------------------
14
+ # Allowed mental health keywords
15
  MENTAL_KEYWORDS = [
16
  "depression", "depressed", "anxiety", "anxious", "panic", "stress", "sad", "lonely",
17
  "trauma", "mental", "therapy", "therapist", "counselor", "mood", "overwhelmed", "anger",
 
19
  "relax", "calm", "sleep", "emotion", "feeling", "feel", "thoughts", "help", "life", "advice",
20
  "unmotivated", "lost", "hopeless", "tired", "burnout", "cry", "hurt", "love", "breakup",
21
  "friend", "family", "alone", "heartbroken", "scared", "fearful",
22
+ "ana", "zahqan", "daye2", "ha2t", "mota3ab", "mota3eb", "za3lan", "malo", "khalni", "mash3or",
23
+ "bakhaf", "w7ed", "msh 3aref", "mash fahem", "malish", "3ayez", "ayez", "7azeen", "mdaye2",
24
  "حزين", "تعبان", "قلق", "خايف", "وحدة", "ضيق", "توتر", "زعلان", "اكتئاب", "علاج",
25
  "مشاعر", "مضغوط", "قلقان", "وحدي", "مش مبسوط", "زهقان", "ضايق", "تعب", "مش مرتاح",
26
  ]
27
 
28
+ # Off-topic keywords
29
  OFF_TOPIC = [
30
  "recipe", "song", "music", "lyrics", "joke", "funny", "laugh", "code", "python", "program",
31
  "game", "food", "cook", "movie", "film", "series", "sport", "football", "instagram",
 
34
  "بيزنس", "فلوس", "العاب", "لعبة", "كود", "برمجة", "ذكاء اصطناعي"
35
  ]
36
 
37
+ # Random off-topic responses
38
  OFF_TOPIC_RESPONSES = [
39
+ "I'm here to help with emotional and mental well-being. Let's focus on how you're feeling today.",
40
+ "I specialize in mental and emotional health conversations. Tell me what’s on your mind.",
41
+ "Let’s bring it back to your feelings — I’m here to help you talk through emotions or stress.",
42
+ "My goal is to support your mental health. How have things been emotionally lately?",
43
+ "I’m here for emotional support only. What’s been bothering you recently?",
44
  ]
45
 
46
+ # ------------------------------
47
+ # Arabic detection
 
 
48
  def contains_arabic(text: str) -> bool:
49
  return bool(re.search(r"[\u0600-\u06FF]", text))
50
 
 
58
  return True
59
  return False
60
 
61
+ # ------------------------------
62
+ # Load voice emotion model
63
+ voice_model_name = "Hatman/audio-emotion-detection"
64
+ voice_model = Wav2Vec2ForSequenceClassification.from_pretrained(voice_model_name)
65
+ voice_processor = Wav2Vec2Processor.from_pretrained(voice_model_name)
66
+
67
+ def detect_voice_emotion(audio_file):
68
+ audio, sr = librosa.load(audio_file, sr=16000)
69
+ inputs = voice_processor(audio, sampling_rate=16000, return_tensors="pt", padding=True)
70
+ with torch.no_grad():
71
+ logits = voice_model(**inputs).logits
72
+ predicted_id = torch.argmax(logits, dim=-1).item()
73
+ return voice_model.config.id2label[predicted_id]
74
+
75
+ # ------------------------------
76
+ # Chat + voice response with TTS
77
+ def respond(message, history: list[dict[str, str]], system_message, max_tokens, temperature, top_p, hf_token: gr.OAuthToken, audio=None):
78
+ transcript = {"user": "", "bot": "", "tts": None}
79
+ response_text = ""
80
+
81
+ # Detect audio emotion
82
+ if audio:
83
+ emotion = detect_voice_emotion(audio)
84
+ response_text += f"[Detected mood: {emotion}] "
85
+
86
+ transcript["user"] = message
87
  if not is_mental_health_related(message):
88
+ response_text += random.choice(OFF_TOPIC_RESPONSES)
89
+ transcript["bot"] = response_text
90
+ else:
91
+ locked_system_message = (
92
+ "You are a licensed mental health therapy assistant. "
93
+ "You respond with empathy, emotional intelligence, and a therapeutic tone. "
94
+ "Never answer questions unrelated to emotional or mental wellness, even if they are in another language."
95
+ )
96
+
97
+ client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
98
+ messages = [{"role": "system", "content": locked_system_message}]
99
+ messages.extend(history)
100
+ messages.append({"role": "user", "content": message})
101
+
102
+ # Stream response
103
+ for msg in client.chat_completion(messages, max_tokens=max_tokens, stream=True, temperature=temperature, top_p=top_p):
104
+ choices = msg.choices
105
+ token = ""
106
+ if len(choices) and choices[0].delta.content:
107
+ token = choices[0].delta.content
108
+ response_text += token
109
+ transcript["bot"] = response_text
110
+
111
+ # Convert response to speech (TTS)
112
+ tts = gTTS(text=transcript["bot"], lang='ar' if contains_arabic(transcript["bot"]) else 'en')
113
+ tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
114
+ tts.save(tmp_file.name)
115
+ transcript["tts"] = tmp_file.name
116
+
117
+ return transcript
118
+
119
+ # ------------------------------
120
+ # Gradio UI
121
+ with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  with gr.Row():
123
+ with gr.Column():
124
  chatbot = gr.ChatInterface(
125
  respond,
126
  type="messages",
 
128
  gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
129
  gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
130
  gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
131
+ gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)"),
132
+ gr.Audio(source="microphone", type="filepath", label="Record your voice (optional)"),
133
+ gr.OAuthToken(label="Hugging Face Token"),
134
  ],
135
  )
136
+ demo.launch()