Sasmitah commited on
Commit
1be62ad
1 Parent(s): d9ca3c2

Update chatbot.py

Browse files
Files changed (1) hide show
  1. chatbot.py +235 -235
chatbot.py CHANGED
@@ -1,236 +1,236 @@
1
- import streamlit as st
2
- from langchain_core.prompts import PromptTemplate
3
- from langchain_core.output_parsers import StrOutputParser
4
- from transformers import pipeline
5
- from langchain_huggingface import HuggingFaceEndpoint
6
- import numpy as np
7
- from pydub import AudioSegment
8
- import os
9
- from langchain.memory import ConversationBufferWindowMemory
10
- from transformers import AutoModelForAudioClassification, Wav2Vec2FeatureExtractor
11
-
12
- # Set the page configuration first
13
- st.set_page_config(page_title="HuggingFace ChatBot", page_icon="🤗")
14
-
15
- # Fixed conversational memory length
16
- memory_length = 5
17
- memory = ConversationBufferWindowMemory(k=memory_length, memory_key="chat_history", return_messages=True)
18
-
19
- # Model IDs
20
- model_id = "Sasmitah/llama_16bit_2"
21
- model2_id = "meta-llama/Llama-3.2-3B-Instruct"
22
- whisper_model = "openai/whisper-small" # Using Whisper model for audio transcription
23
- model1 = AutoModelForAudioClassification.from_pretrained("ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition")
24
- feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained("ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition")
25
-
26
- def predict_emotion(audio_file):
27
- if not audio_file:
28
- return "No audio file provided!"
29
-
30
- sound = AudioSegment.from_file(audio_file)
31
- sound = sound.set_frame_rate(16000)
32
- sound_array = np.array(sound.get_array_of_samples())
33
-
34
- input = feature_extractor(
35
- raw_speech=sound_array,
36
- sampling_rate=16000,
37
- padding=True,
38
- return_tensors="pt")
39
-
40
- result = model1.forward(input.input_values.float())
41
-
42
- id2label = {
43
- "0": "angry",
44
- "1": "calm",
45
- "2": "disgust",
46
- "3": "fearful",
47
- "4": "happy",
48
- "5": "neutral",
49
- "6": "sad",
50
- "7": "surprised"
51
- }
52
-
53
- # Map result to emotion labels with probabilities
54
- emotion_scores = dict(zip(id2label.values(), list(round(float(i),4) for i in result[0][0])))
55
- return emotion_scores
56
-
57
- def get_llm_hf_inference(model_id, max_new_tokens=128, temperature=0.5):
58
- """Returns a language model for HuggingFace inference."""
59
- try:
60
- llm = HuggingFaceEndpoint(
61
- repo_id=model_id,
62
- max_new_tokens=max_new_tokens,
63
- temperature=temperature,
64
- token=os.getenv("HF_TOKEN")
65
- )
66
- return llm
67
- except Exception as e:
68
- st.error(f"Error initializing model: {e}")
69
- return None
70
-
71
- def load_transcription_model():
72
- try:
73
- transcriber = pipeline("automatic-speech-recognition", model=whisper_model)
74
- return transcriber
75
- except Exception as e:
76
- st.error(f"Error loading Whisper model: {e}")
77
- return None
78
-
79
- def preprocess_audio(file):
80
- audio = AudioSegment.from_file(file).set_frame_rate(16000).set_channels(1)
81
- audio_samples = np.array(audio.get_array_of_samples()).astype(np.float32) / (2**15)
82
- return audio_samples
83
-
84
- def transcribe_audio(file, transcriber):
85
- audio = preprocess_audio(file)
86
- transcription = transcriber(audio)["text"]
87
- return transcription
88
-
89
- def display_chatbot():
90
-
91
- st.title("Personal Therapist Chatbot")
92
- st.markdown(
93
- """
94
- 🔒 *Disclaimer:* Please do not share any personal, sensitive, or confidential information during your interaction with this chatbot. This tool is for informational and supportive purposes only, and any data shared is not stored or monitored to protect your privacy.
95
- """
96
- )
97
-
98
- with st.sidebar:
99
- reset_history = st.button("Reset Chat History")
100
- go_home = st.button("Back to Home")
101
- if go_home:
102
- st.session_state.page = "home"
103
-
104
- if reset_history:
105
- st.session_state.chat_history = [{"role": "assistant", "content": st.session_state.starter_message}]
106
- st.session_state.user_text = None
107
- st.session_state.avatars = {'user': None, 'assistant': None}
108
- st.session_state.max_response_length = 1000
109
-
110
- def get_response(system_message, chat_history, user_text, model_id, max_new_tokens=256):
111
- """Generates a response from the chatbot model."""
112
- hf = get_llm_hf_inference(model_id=model_id, max_new_tokens=max_new_tokens)
113
- if hf is None:
114
- return "Error: Model not initialized.", chat_history
115
-
116
- prompt = PromptTemplate.from_template(
117
- (
118
- "[INST] {system_message}"
119
- "\nCurrent Conversation:\n{chat_history}\n\n"
120
-
121
- "\nPatient: {user_text}.\n [/INST]"
122
- "\ntherapist:"
123
- )
124
- )
125
- chat = prompt | hf.bind(skip_prompt=True) | StrOutputParser(output_key='content')
126
-
127
- response = chat.invoke(input=dict(system_message=system_message, user_text=user_text, chat_history=chat_history))
128
- response = response.split("AI:")[-1].strip()
129
-
130
- low_engagement_threshold = 3
131
- end_keywords = ["thank you", "thanks", "goodbye", "bye", "that's all"]
132
-
133
- short_responses = len(user_text.split()) <= low_engagement_threshold
134
- end_pattern_match = any(keyword in user_text.lower() for keyword in end_keywords)
135
-
136
- recent_short_responses = all(len(msg["content"].split()) <= low_engagement_threshold for msg in chat_history[-2:])
137
- response_is_acknowledgment = user_text.lower() in ["yes", "okay", "alright"]
138
-
139
- if (end_pattern_match or (short_responses and recent_short_responses)) and not response_is_acknowledgment:
140
- follow_up_question = "Would you like to have a report of your current health? Yes/No"
141
- response = f"I’m glad to hear that. Let’s keep checking in on this, and you can tell me how it goes next time."
142
- response += f"\n\n{follow_up_question}"
143
-
144
- chat_history.append({'role': 'user', 'content': user_text})
145
- chat_history.append({'role': 'assistant', 'content': response})
146
- return response, chat_history
147
-
148
- def get_summary_of_chat_history(chat_history, model2_id):
149
- """Generates a comprehensive summary of the chat history and a health report."""
150
- hf = get_llm_hf_inference(model_id=model2_id, max_new_tokens=256)
151
- if hf is None:
152
- return "Error: Model not initialized."
153
-
154
- chat_content = "\n".join([f"{message['role']}: {message['content']}" for message in chat_history])
155
-
156
- prompt = PromptTemplate.from_template(
157
- f"""
158
- Generate a detailed report based on the following conversation between a therapist and patient.
159
- Conversation:\n{chat_content}
160
-
161
- The report should include:
162
- 1. *Patient Information:*
163
- - Include placeholders for Name, Age, Gender, Date of Session.
164
-
165
- 2. *Conversation Summary:*
166
- - Summarize the main points of the conversation, focusing on the patient’s primary concerns and emotional state.
167
- - Note any specific causes of stress or distress, how these issues affect the patient's personal life, and their expressed desires or goals.
168
-
169
- 3. *Preliminary Diagnosis:*
170
- - Identify the main symptoms observed in the conversation, such as mood, energy levels, motivation, etc.
171
- - Suggest a potential preliminary diagnosis based on the symptoms described, e.g., stress-induced burnout or other relevant concerns. Mention the need for further assessment if applicable.
172
-
173
- 4. *Recommendations & Strategies:*
174
- - Provide practical, achievable strategies tailored to the patient’s needs.
175
-
176
- Format the report neatly with headings and subheadings as shown in the example. Aim to keep the language supportive and professional.
177
- """
178
- )
179
-
180
- summary = prompt | hf.bind(skip_prompt=True) | StrOutputParser(output_key='content')
181
- summary_response = summary.invoke(input={"chat_content": chat_content})
182
-
183
- return summary_response
184
-
185
- transcriber = load_transcription_model()
186
-
187
- input_type = st.radio("Select your input type", ("Text", "Audio"))
188
-
189
- if input_type == "Text":
190
- st.session_state.user_text = st.text_input("Enter your text here:")
191
- elif input_type == "Audio":
192
- audio_file = st.file_uploader("Upload an audio file for transcription", type=["mp3", "wav", "m4a"])
193
-
194
- if audio_file is not None and transcriber:
195
- with st.spinner("Transcribing audio..."):
196
- try:
197
- st.session_state.user_text = transcribe_audio(audio_file, transcriber)
198
- st.success("Audio transcribed successfully!")
199
- st.audio(audio_file, format='audio/mp3')
200
- emotion_result = predict_emotion(audio_file)
201
- predicted_emotion = max(emotion_result, key=emotion_result.get)
202
- st.write(f"Most likely emotion: {predicted_emotion.capitalize()}")
203
- except Exception as e:
204
- st.error(f"Error transcribing audio: {e}")
205
-
206
-
207
-
208
- output_container = st.container()
209
-
210
- with output_container:
211
- for message in st.session_state.chat_history:
212
- if message['role'] == 'system':
213
- continue
214
- with st.chat_message(message['role'], avatar=st.session_state['avatars'][message['role']]):
215
- st.markdown(message['content'])
216
-
217
- if st.session_state.user_text:
218
- with st.chat_message("user", avatar=st.session_state.avatars['user']):
219
- st.markdown(st.session_state.user_text)
220
-
221
- with st.chat_message("assistant", avatar=st.session_state.avatars['assistant']):
222
- response = st.session_state.chat_history[-1]['content'] if len(st.session_state.chat_history) > 2 else st.session_state.starter_message
223
-
224
- if "yes" in st.session_state.user_text.lower() and "Would you like to have a report of your current health? Yes/No" in response:
225
- with st.spinner("Generating your health report..."):
226
- report = get_summary_of_chat_history(st.session_state.chat_history, model2_id)
227
- st.markdown(report)
228
- with st.spinner("Addressing your concerns..."):
229
- response, st.session_state.chat_history = get_response(
230
- system_message=st.session_state.system_message,
231
- user_text=st.session_state.user_text,
232
- chat_history=st.session_state.chat_history,
233
- model_id=model_id,
234
- max_new_tokens=st.session_state.max_response_length,
235
- )
236
  st.markdown(response)
 
1
+ import streamlit as st
2
+ from langchain_core.prompts import PromptTemplate
3
+ from langchain_core.output_parsers import StrOutputParser
4
+ from transformers import pipeline
5
+ from langchain_huggingface import HuggingFaceEndpoint
6
+ import numpy as np
7
+ from pydub import AudioSegment
8
+ import os
9
+ from langchain.memory import ConversationBufferWindowMemory
10
+ from transformers import AutoModelForAudioClassification, Wav2Vec2FeatureExtractor
11
+
12
+ # Set the page configuration first
13
+ st.set_page_config(page_title="HuggingFace ChatBot", page_icon="🤗")
14
+
15
+ # Fixed conversational memory length
16
+ memory_length = 5
17
+ memory = ConversationBufferWindowMemory(k=memory_length, memory_key="chat_history", return_messages=True)
18
+
19
+ # Model IDs
20
+ model_id = "Sasmitah/llama_16bit_2"
21
+ model2_id = "unsloth/Llama-3.2-1B-Instruct"
22
+ whisper_model = "openai/whisper-small" # Using Whisper model for audio transcription
23
+ model1 = AutoModelForAudioClassification.from_pretrained("ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition")
24
+ feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained("ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition")
25
+
26
+ def predict_emotion(audio_file):
27
+ if not audio_file:
28
+ return "No audio file provided!"
29
+
30
+ sound = AudioSegment.from_file(audio_file)
31
+ sound = sound.set_frame_rate(16000)
32
+ sound_array = np.array(sound.get_array_of_samples())
33
+
34
+ input = feature_extractor(
35
+ raw_speech=sound_array,
36
+ sampling_rate=16000,
37
+ padding=True,
38
+ return_tensors="pt")
39
+
40
+ result = model1.forward(input.input_values.float())
41
+
42
+ id2label = {
43
+ "0": "angry",
44
+ "1": "calm",
45
+ "2": "disgust",
46
+ "3": "fearful",
47
+ "4": "happy",
48
+ "5": "neutral",
49
+ "6": "sad",
50
+ "7": "surprised"
51
+ }
52
+
53
+ # Map result to emotion labels with probabilities
54
+ emotion_scores = dict(zip(id2label.values(), list(round(float(i),4) for i in result[0][0])))
55
+ return emotion_scores
56
+
57
+ def get_llm_hf_inference(model_id, max_new_tokens=128, temperature=0.5):
58
+ """Returns a language model for HuggingFace inference."""
59
+ try:
60
+ llm = HuggingFaceEndpoint(
61
+ repo_id=model_id,
62
+ max_new_tokens=max_new_tokens,
63
+ temperature=temperature,
64
+ token=os.getenv("HF_TOKEN")
65
+ )
66
+ return llm
67
+ except Exception as e:
68
+ st.error(f"Error initializing model: {e}")
69
+ return None
70
+
71
+ def load_transcription_model():
72
+ try:
73
+ transcriber = pipeline("automatic-speech-recognition", model=whisper_model)
74
+ return transcriber
75
+ except Exception as e:
76
+ st.error(f"Error loading Whisper model: {e}")
77
+ return None
78
+
79
+ def preprocess_audio(file):
80
+ audio = AudioSegment.from_file(file).set_frame_rate(16000).set_channels(1)
81
+ audio_samples = np.array(audio.get_array_of_samples()).astype(np.float32) / (2**15)
82
+ return audio_samples
83
+
84
+ def transcribe_audio(file, transcriber):
85
+ audio = preprocess_audio(file)
86
+ transcription = transcriber(audio)["text"]
87
+ return transcription
88
+
89
+ def display_chatbot():
90
+
91
+ st.title("Personal Therapist Chatbot")
92
+ st.markdown(
93
+ """
94
+ 🔒 *Disclaimer:* Please do not share any personal, sensitive, or confidential information during your interaction with this chatbot. This tool is for informational and supportive purposes only, and any data shared is not stored or monitored to protect your privacy.
95
+ """
96
+ )
97
+
98
+ with st.sidebar:
99
+ reset_history = st.button("Reset Chat History")
100
+ go_home = st.button("Back to Home")
101
+ if go_home:
102
+ st.session_state.page = "home"
103
+
104
+ if reset_history:
105
+ st.session_state.chat_history = [{"role": "assistant", "content": st.session_state.starter_message}]
106
+ st.session_state.user_text = None
107
+ st.session_state.avatars = {'user': None, 'assistant': None}
108
+ st.session_state.max_response_length = 1000
109
+
110
+ def get_response(system_message, chat_history, user_text, model_id, max_new_tokens=256):
111
+ """Generates a response from the chatbot model."""
112
+ hf = get_llm_hf_inference(model_id=model_id, max_new_tokens=max_new_tokens)
113
+ if hf is None:
114
+ return "Error: Model not initialized.", chat_history
115
+
116
+ prompt = PromptTemplate.from_template(
117
+ (
118
+ "[INST] {system_message}"
119
+ "\nCurrent Conversation:\n{chat_history}\n\n"
120
+
121
+ "\nPatient: {user_text}.\n [/INST]"
122
+ "\ntherapist:"
123
+ )
124
+ )
125
+ chat = prompt | hf.bind(skip_prompt=True) | StrOutputParser(output_key='content')
126
+
127
+ response = chat.invoke(input=dict(system_message=system_message, user_text=user_text, chat_history=chat_history))
128
+ response = response.split("AI:")[-1].strip()
129
+
130
+ low_engagement_threshold = 3
131
+ end_keywords = ["thank you", "thanks", "goodbye", "bye", "that's all"]
132
+
133
+ short_responses = len(user_text.split()) <= low_engagement_threshold
134
+ end_pattern_match = any(keyword in user_text.lower() for keyword in end_keywords)
135
+
136
+ recent_short_responses = all(len(msg["content"].split()) <= low_engagement_threshold for msg in chat_history[-2:])
137
+ response_is_acknowledgment = user_text.lower() in ["yes", "okay", "alright"]
138
+
139
+ if (end_pattern_match or (short_responses and recent_short_responses)) and not response_is_acknowledgment:
140
+ follow_up_question = "Would you like to have a report of your current health? Yes/No"
141
+ response = f"I’m glad to hear that. Let’s keep checking in on this, and you can tell me how it goes next time."
142
+ response += f"\n\n{follow_up_question}"
143
+
144
+ chat_history.append({'role': 'user', 'content': user_text})
145
+ chat_history.append({'role': 'assistant', 'content': response})
146
+ return response, chat_history
147
+
148
+ def get_summary_of_chat_history(chat_history, model2_id):
149
+ """Generates a comprehensive summary of the chat history and a health report."""
150
+ hf = get_llm_hf_inference(model_id=model2_id, max_new_tokens=256)
151
+ if hf is None:
152
+ return "Error: Model not initialized."
153
+
154
+ chat_content = "\n".join([f"{message['role']}: {message['content']}" for message in chat_history])
155
+
156
+ prompt = PromptTemplate.from_template(
157
+ f"""
158
+ Generate a detailed report based on the following conversation between a therapist and patient.
159
+ Conversation:\n{chat_content}
160
+
161
+ The report should include:
162
+ 1. *Patient Information:*
163
+ - Include placeholders for Name, Age, Gender, Date of Session.
164
+
165
+ 2. *Conversation Summary:*
166
+ - Summarize the main points of the conversation, focusing on the patient’s primary concerns and emotional state.
167
+ - Note any specific causes of stress or distress, how these issues affect the patient's personal life, and their expressed desires or goals.
168
+
169
+ 3. *Preliminary Diagnosis:*
170
+ - Identify the main symptoms observed in the conversation, such as mood, energy levels, motivation, etc.
171
+ - Suggest a potential preliminary diagnosis based on the symptoms described, e.g., stress-induced burnout or other relevant concerns. Mention the need for further assessment if applicable.
172
+
173
+ 4. *Recommendations & Strategies:*
174
+ - Provide practical, achievable strategies tailored to the patient’s needs.
175
+
176
+ Format the report neatly with headings and subheadings as shown in the example. Aim to keep the language supportive and professional.
177
+ """
178
+ )
179
+
180
+ summary = prompt | hf.bind(skip_prompt=True) | StrOutputParser(output_key='content')
181
+ summary_response = summary.invoke(input={"chat_content": chat_content})
182
+
183
+ return summary_response
184
+
185
+ transcriber = load_transcription_model()
186
+
187
+ input_type = st.radio("Select your input type", ("Text", "Audio"))
188
+
189
+ if input_type == "Text":
190
+ st.session_state.user_text = st.text_input("Enter your text here:")
191
+ elif input_type == "Audio":
192
+ audio_file = st.file_uploader("Upload an audio file for transcription", type=["mp3", "wav", "m4a"])
193
+
194
+ if audio_file is not None and transcriber:
195
+ with st.spinner("Transcribing audio..."):
196
+ try:
197
+ st.session_state.user_text = transcribe_audio(audio_file, transcriber)
198
+ st.success("Audio transcribed successfully!")
199
+ st.audio(audio_file, format='audio/mp3')
200
+ emotion_result = predict_emotion(audio_file)
201
+ predicted_emotion = max(emotion_result, key=emotion_result.get)
202
+ st.write(f"Most likely emotion: {predicted_emotion.capitalize()}")
203
+ except Exception as e:
204
+ st.error(f"Error transcribing audio: {e}")
205
+
206
+
207
+
208
+ output_container = st.container()
209
+
210
+ with output_container:
211
+ for message in st.session_state.chat_history:
212
+ if message['role'] == 'system':
213
+ continue
214
+ with st.chat_message(message['role'], avatar=st.session_state['avatars'][message['role']]):
215
+ st.markdown(message['content'])
216
+
217
+ if st.session_state.user_text:
218
+ with st.chat_message("user", avatar=st.session_state.avatars['user']):
219
+ st.markdown(st.session_state.user_text)
220
+
221
+ with st.chat_message("assistant", avatar=st.session_state.avatars['assistant']):
222
+ response = st.session_state.chat_history[-1]['content'] if len(st.session_state.chat_history) > 2 else st.session_state.starter_message
223
+
224
+ if "yes" in st.session_state.user_text.lower() and "Would you like to have a report of your current health? Yes/No" in response:
225
+ with st.spinner("Generating your health report..."):
226
+ report = get_summary_of_chat_history(st.session_state.chat_history, model2_id)
227
+ st.markdown(report)
228
+ with st.spinner("Addressing your concerns..."):
229
+ response, st.session_state.chat_history = get_response(
230
+ system_message=st.session_state.system_message,
231
+ user_text=st.session_state.user_text,
232
+ chat_history=st.session_state.chat_history,
233
+ model_id=model_id,
234
+ max_new_tokens=st.session_state.max_response_length,
235
+ )
236
  st.markdown(response)