joey1101 commited on
Commit
6a85efc
·
verified ·
1 Parent(s): 4938977

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -180
app.py CHANGED
@@ -1,201 +1,128 @@
1
  ##########################################
2
- # Step 0: 导入必需的库
3
  ##########################################
4
- import streamlit as st
5
- from transformers import pipeline, SpeechT5Processor, SpeechT5ForTextToSpeech, SpeechT5HifiGan, AutoModelForCausalLM, AutoTokenizer, pipeline
6
- from datasets import load_dataset
7
- from IPython.display import Audio, display
8
- import torch
9
- import soundfile as sf
10
-
11
- from google.colab import drive
12
-
13
- from huggingface_hub import login
14
-
15
- # Streamlit application title
16
- st.title("Comment reply for you")
17
- st.write("automative reply")
18
-
19
- # Text input for user to enter the comment
20
- text = st.text_area("Enter your comment", "")
21
 
22
  ##########################################
23
- # Step 1:情感分析 - 分析用户评论的情感倾向
24
  ##########################################
 
 
 
25
 
26
-
 
 
27
  def analyze_dominant_emotion(user_review):
28
- # Initialize the emotion classifier pipeline
 
 
29
  emotion_classifier = pipeline(
30
- "text-classification",
31
- model="Thea231/jhartmann_emotion_finetuning",
32
  return_all_scores=True
33
- )
34
-
35
- # Get emotion predictions for the input review
36
- emotion_results = emotion_classifier(user_review)[0] # Get first result (single input case)
37
-
38
- # Extract the emotion with highest confidence score
39
- dominant_emotion = max(emotion_results, key=lambda x: x['score'])
40
-
41
  return dominant_emotion
42
 
43
- # 提取置信度最高的情感标签(可选)
44
- # dominant_emotion = analyze_dominant_emotion(user_review)
45
- # print("\n主导情感:", dominant_emotion['label'], f"(置信度: {dominant_emotion['score']:.2f})")
46
-
47
-
48
-
49
  ##########################################
50
- # Step 2:回复生成 - 根据情感生成自动回复
51
  ##########################################
52
-
53
-
54
- def prompt_gen(user_review):
55
- dominant_emotion = analyze_dominant_emotion(user_review)
56
- emotion_strategies = {
57
- "anger": {
58
- "prompt": (
59
- "Customer complaint: '{review}'\n\n"
60
- "As a customer service representative, craft a professional response that:\n"
61
- "- Begins with sincere apology and acknowledgment\n"
62
- "- Clearly explains solution process with concrete steps\n"
63
- "- Offers appropriate compensation/redemption\n"
64
- "- Keeps tone humble and solution-focused (3-4 sentences)\n\n"
65
- "Response:"
66
- )
67
- },
68
- "disgust": {
69
- "prompt": (
70
- "Customer quality concern: '{review}'\n\n"
71
- "As a customer service representative, craft a response that:\n"
72
- "- Immediately acknowledges the product issue\n"
73
- "- Explains quality control measures being taken\n"
74
- "- Provides clear return/replacement instructions\n"
75
- "- Offers goodwill gesture (3-4 sentences)\n\n"
76
- "Response:"
77
- )
78
- },
79
- "fear": {
80
- "prompt": (
81
- "Customer safety concern: '{review}'\n\n"
82
- "As a customer service representative, craft a reassuring response that:\n"
83
- "- Directly addresses the safety worries\n"
84
- "- References relevant certifications/standards\n"
85
- "- Offers dedicated support contact\n"
86
- "- Provides satisfaction guarantee (3-4 sentences)\n\n"
87
- "Response:"
88
- )
89
- },
90
- "joy": {
91
- "prompt": (
92
- "Customer review: '{review}'\n\n"
93
- "As a customer service representative, craft a concise response that:\n"
94
- "- Specifically acknowledges both positive and constructive feedback\n"
95
- "- Briefly mentions loyalty/referral programs\n"
96
- "- Ends with shopping invitation (3-4 sentences)\n\n"
97
- "Response:"
98
- )
99
- },
100
- "neutral": {
101
- "prompt": (
102
- "Customer feedback: '{review}'\n\n"
103
- "As a customer service representative, craft a balanced response that:\n"
104
- "- Provides additional relevant product information\n"
105
- "- Highlights key service features\n"
106
- "- Politely requests more detailed feedback\n"
107
- "- Maintains professional tone (3-4 sentences)\n\n"
108
- "Response:"
109
- )
110
- },
111
- "sadness": {
112
- "prompt": (
113
- "Customer disappointment: '{review}'\n\n"
114
- "As a customer service representative, craft an empathetic response that:\n"
115
- "- Shows genuine understanding of the issue\n"
116
- "- Proposes personalized recovery solution\n"
117
- "- Offers extended support options\n"
118
- "- Maintains positive outlook (3-4 sentences)\n\n"
119
- "Response:"
120
- )
121
- },
122
- "surprise": {
123
- "prompt": (
124
- "Customer enthusiastic feedback: '{review}'\n\n"
125
- "As a customer service representative, craft a response that:\n"
126
- "- Matches customer's positive energy appropriately\n"
127
- "- Highlights unexpected product benefits\n"
128
- "- Invites to user community/events\n"
129
- "- Maintains brand voice (3-4 sentences)\n\n"
130
- "Response:"
131
- )
132
- }
133
- }
134
- # 生成回复Prompt
135
- template = emotion_strategies[dominant_emotion['label'].lower()]["prompt"]
136
- prompt = template.format(review=user_review)
137
- print(prompt)
138
- return prompt
139
-
140
-
141
-
142
  def response_gen(user_review):
143
- prompt = prompt_gen(user_review)
144
- # 加载Llama-3作为text generation模型
145
- tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.2-1B")
146
- model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
147
- inputs = tokenizer(prompt, return_tensors="pt")
148
- outputs = model.generate(**inputs, max_new_tokens=100)
149
-
150
- input_length = inputs.input_ids.shape[1]
151
- response = tokenizer.decode(outputs[0][input_length:], skip_special_tokens=True)
152
- # print(response)
153
- return response
154
-
155
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
  ##########################################
158
- # Step 3:语音生成 - 根据回复合成语音
159
  ##########################################
160
  def sound_gen(response):
161
- # 加载模型和处理器
162
- #processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")
163
- #speech_model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")
164
- #vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
165
-
166
- processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")
167
- model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")
168
- vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
169
-
170
- # 创建默认的说话人嵌入
171
- embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")
172
- speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0) # 女性中性语音
173
-
174
- # 文本预处理和语音合成
175
- inputs = processor(text=response, return_tensors="pt")
176
- spectrogram = model.generate_speech(inputs["input_ids"], speaker_embeddings)
177
-
178
- # 使用声码器生成波形音频
179
- with torch.no_grad():
180
- speech = vocoder(spectrogram)
181
-
182
- # 保存为WAV文件(16kHz采样率)
183
- sf.write("customer_service_response.wav", speech.numpy(), samplerate=16000)
184
-
185
- print("语音生成完成,已保存为 customer_service_response.wav")
186
- return
187
-
188
-
189
- st.write("customer_service_response.wav", speech.numpy(), samplerate=16000)
190
- st.text("I wanna tell you that")
191
- st.audio("customer_service_response.wav")
192
 
 
 
 
193
  def main():
194
- user_review = "I love the fast delivery, but the product quality could be better."
195
- response = response_gen(user_review)
196
- print(response)
197
- sound_gen(response)
198
- return
199
-
 
 
 
200
  if __name__ == "__main__":
201
- main()
 
1
  ##########################################
2
+ # Step 0: Import required libraries
3
  ##########################################
4
+ import streamlit as st # For building the web application
5
+ from transformers import (
6
+ pipeline,
7
+ SpeechT5Processor,
8
+ SpeechT5ForTextToSpeech,
9
+ SpeechT5HifiGan,
10
+ AutoModelForCausalLM,
11
+ AutoTokenizer
12
+ ) # For emotion analysis, text-to-speech, and text generation
13
+ from datasets import load_dataset # For loading datasets (e.g., speaker embeddings)
14
+ import torch # For tensor operations
15
+ import soundfile as sf # For saving audio as .wav files
 
 
 
 
 
16
 
17
  ##########################################
18
+ # Streamlit application title and input
19
  ##########################################
20
+ st.title("Comment Reply for You") # Application title
21
+ st.write("Generate automatic replies for user comments") # Application description
22
+ text = st.text_area("Enter your comment", "") # Text input for user to enter comments
23
 
24
+ ##########################################
25
+ # Step 1: Sentiment Analysis Function
26
+ ##########################################
27
  def analyze_dominant_emotion(user_review):
28
+ """
29
+ Analyze the dominant emotion in the user's review using a text classification model.
30
+ """
31
  emotion_classifier = pipeline(
32
+ "text-classification",
33
+ model="Thea231/jhartmann_emotion_finetuning",
34
  return_all_scores=True
35
+ ) # Load pre-trained emotion classification model
36
+
37
+ emotion_results = emotion_classifier(user_review)[0] # Get emotion scores for the review
38
+ dominant_emotion = max(emotion_results, key=lambda x: x['score']) # Find the emotion with the highest confidence
 
 
 
 
39
  return dominant_emotion
40
 
 
 
 
 
 
 
41
  ##########################################
42
+ # Step 2: Response Generation Function
43
  ##########################################
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  def response_gen(user_review):
45
+ """
46
+ Generate a response based on the sentiment of the user's review.
47
+ """
48
+ # Use Llama-based model to create a response based on a generated prompt
49
+ dominant_emotion = analyze_dominant_emotion(user_review) # Get the dominant emotion
50
+ emotion_label = dominant_emotion['label'].lower() # Extract emotion label
51
+
52
+ # Define response templates for each emotion
53
+ emotion_prompts = {
54
+ "anger": (
55
+ "Customer complaint: '{review}'\n\n"
56
+ "As a customer service representative, write a response that:\n"
57
+ "- Sincerely apologizes for the issue\n"
58
+ "- Explains how the issue will be resolved\n"
59
+ "- Offers compensation where appropriate\n\n"
60
+ "Response:"
61
+ ),
62
+ "joy": (
63
+ "Customer review: '{review}'\n\n"
64
+ "As a customer service representative, write a positive response that:\n"
65
+ "- Thanks the customer for their feedback\n"
66
+ "- Acknowledges both positive and constructive comments\n"
67
+ "- Invites them to explore loyalty programs\n\n"
68
+ "Response:"
69
+ ),
70
+ # Add other emotions as needed...
71
+ }
72
+
73
+ # Format the prompt with the user's review
74
+ prompt = emotion_prompts.get(emotion_label, "Neutral").format(review=user_review)
75
+
76
+ # Load a pre-trained text generation model (replace 'meta-llama/Llama-3.2-1B' with an available model)
77
+ tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.2-1B")
78
+ model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
79
+ inputs = tokenizer(prompt, return_tensors="pt") # Tokenize the prompt
80
+ outputs = model.generate(**inputs, max_new_tokens=100) # Generate a response
81
+
82
+ input_length = inputs.input_ids.shape[1] # Length of the input text
83
+ response = tokenizer.decode(outputs[0][input_length:], skip_special_tokens=True) # Decode the generated text
84
+ return response
85
 
86
  ##########################################
87
+ # Step 3: Text-to-Speech Conversion Function
88
  ##########################################
89
  def sound_gen(response):
90
+ """
91
+ Convert the generated response to speech and save as a .wav file.
92
+ """
93
+ # Load the pre-trained TTS models
94
+ processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")
95
+ model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")
96
+ vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
97
+
98
+ # Load speaker embeddings (e.g., neutral female voice)
99
+ embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")
100
+ speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0)
101
+
102
+ # Process the input text and generate a spectrogram
103
+ inputs = processor(text=response, return_tensors="pt")
104
+ spectrogram = model.generate_speech(inputs["input_ids"], speaker_embeddings)
105
+
106
+ # Use the vocoder to generate a waveform
107
+ with torch.no_grad():
108
+ speech = vocoder(spectrogram)
109
+
110
+ # Save the generated speech as a .wav file
111
+ sf.write("customer_service_response.wav", speech.numpy(), samplerate=16000)
112
+ st.audio("customer_service_response.wav") # Play the audio in Streamlit
 
 
 
 
 
 
 
 
113
 
114
+ ##########################################
115
+ # Main Function
116
+ ##########################################
117
  def main():
118
+ """
119
+ Main function to orchestrate the workflow of sentiment analysis, response generation, and text-to-speech.
120
+ """
121
+ if text: # Check if the user entered a comment
122
+ response = response_gen(text) # Generate a response
123
+ st.write(f"Generated response: {response}") # Display the generated response
124
+ sound_gen(response) # Convert the response to speech and play it
125
+
126
+ # Run the main function
127
  if __name__ == "__main__":
128
+ main()