Sephfox commited on
Commit
c401143
·
verified ·
1 Parent(s): 6053a6d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -35
app.py CHANGED
@@ -9,7 +9,7 @@ import torch
9
  from sklearn.ensemble import RandomForestClassifier
10
  from sklearn.model_selection import train_test_split
11
  from sklearn.preprocessing import OneHotEncoder
12
- from transformers import AutoModelForSequenceClassification, AutoTokenizer, T5ForConditionalGeneration, T5Tokenizer, pipeline
13
  from deap import base, creator, tools, algorithms
14
  import gc
15
 
@@ -44,15 +44,17 @@ emotion_classes = pd.Categorical(df['emotion']).categories
44
  emotion_prediction_model = AutoModelForSequenceClassification.from_pretrained("bhadresh-savani/distilbert-base-uncased-emotion")
45
  emotion_prediction_tokenizer = AutoTokenizer.from_pretrained("bhadresh-savani/distilbert-base-uncased-emotion")
46
 
47
- # Lazy loading for the fine-tuned language model (FLAN-T5)
48
  _finetuned_lm_tokenizer = None
49
  _finetuned_lm_model = None
50
 
51
  def get_finetuned_lm_model():
52
  global _finetuned_lm_tokenizer, _finetuned_lm_model
53
  if _finetuned_lm_tokenizer is None or _finetuned_lm_model is None:
54
- _finetuned_lm_tokenizer = T5Tokenizer.from_pretrained("google/flan-t5-base")
55
- _finetuned_lm_model = T5ForConditionalGeneration.from_pretrained("google/flan-t5-base", device_map="auto", low_cpu_mem_usage=True)
 
 
56
  return _finetuned_lm_tokenizer, _finetuned_lm_model
57
 
58
  # Enhanced Emotional States
@@ -77,7 +79,9 @@ emotions = {
77
  'pessimism': {'percentage': 10, 'motivation': 'doubtful', 'intensity': 0},
78
  'boredom': {'percentage': 10, 'motivation': 'indifferent', 'intensity': 0},
79
  'envy': {'percentage': 10, 'motivation': 'jealous', 'intensity': 0},
80
- 'neutral': {'percentage': 10, 'motivation': 'balanced', 'intensity': 0}
 
 
81
  }
82
 
83
  total_percentage = 200
@@ -100,6 +104,12 @@ def update_emotion(emotion, percentage, intensity):
100
  emotions[emotion]['percentage'] += percentage
101
  emotions[emotion]['intensity'] = intensity
102
 
 
 
 
 
 
 
103
  total_current = sum(e['percentage'] for e in emotions.values())
104
  adjustment = total_percentage - total_current
105
  emotions['ideal_state']['percentage'] += adjustment
@@ -109,7 +119,7 @@ def normalize_context(context):
109
 
110
  def evaluate(individual):
111
  emotion_values = individual[:len(emotions) - 1]
112
- intensities = individual[-21:-1]
113
  ideal_state = individual[-1]
114
 
115
  ideal_diff = abs(100 - ideal_state)
@@ -119,6 +129,7 @@ def evaluate(individual):
119
  return ideal_diff, sum_non_ideal, intensity_range
120
 
121
  def evolve_emotions():
 
122
  creator.create("FitnessMulti", base.Fitness, weights=(-1.0, -0.5, -0.2))
123
  creator.create("Individual", list, fitness=creator.FitnessMulti)
124
 
@@ -128,7 +139,6 @@ def evolve_emotions():
128
  toolbox.register("individual", tools.initCycle, creator.Individual,
129
  (toolbox.attr_float,) * (len(emotions) - 1) +
130
  (toolbox.attr_intensity,) * len(emotions) +
131
- (lambda: 100,), n(toolbox.attr_intensity,) * len(emotions) +
132
  (lambda: 100,), n=1)
133
  toolbox.register("population", tools.initRepeat, list, toolbox.individual)
134
  toolbox.register("mate", tools.cxTwoPoint)
@@ -142,12 +152,13 @@ def evolve_emotions():
142
 
143
  best_individual = tools.selBest(population, k=1)[0]
144
  emotion_values = best_individual[:len(emotions) - 1]
145
- intensities = best_individual[-21:-1]
146
  ideal_state = best_individual[-1]
147
 
148
  for i, emotion in enumerate(emotions):
149
- emotions[emotion]['percentage'] = emotion_values[i]
150
- emotions[emotion]['intensity'] = intensities[i]
 
151
 
152
  emotions['ideal_state']['percentage'] = ideal_state
153
 
@@ -169,34 +180,37 @@ def predict_emotion(context):
169
 
170
  return emotion_mapping.get(predicted_emotion, 'neutral')
171
 
172
- def generate_text(prompt, chat_history, emotion=None, max_length=100):
173
  finetuned_lm_tokenizer, finetuned_lm_model = get_finetuned_lm_model()
174
 
175
- # Prepare the input by concatenating the chat history and the new prompt
176
- full_prompt = "You are Adam, an AI assistant. Respond to the following conversation in a natural and engaging way, considering the emotion: " + emotion + "\n\n"
177
- for turn in chat_history[-5:]: # Consider last 5 turns for context
 
 
 
178
  full_prompt += f"Human: {turn[0]}\nAdam: {turn[1]}\n"
179
  full_prompt += f"Human: {prompt}\nAdam:"
180
 
181
- input_ids = finetuned_lm_tokenizer(full_prompt, return_tensors="pt", max_length=512, truncation=True).input_ids
182
 
183
  if torch.cuda.is_available():
184
  input_ids = input_ids.cuda()
185
  finetuned_lm_model = finetuned_lm_model.cuda()
186
 
187
- # Generate the response
188
- outputs = finetuned_lm_model.generate(
189
  input_ids,
190
- max_length=max_length + input_ids.shape[1],
191
  num_return_sequences=1,
192
  no_repeat_ngram_size=2,
193
  do_sample=True,
194
- temperature=0.7,
195
  top_k=50,
196
- top_p=0.95
 
197
  )
198
 
199
- generated_text = finetuned_lm_tokenizer.decode(outputs[0], skip_special_tokens=True)
200
  return generated_text.strip()
201
 
202
  def update_emotion_history(emotion, intensity):
@@ -228,45 +242,37 @@ def reset_emotions():
228
  return get_emotion_summary()
229
 
230
  def respond_to_user(user_input, chat_history):
231
- # Predict the emotion from the user input
232
  predicted_emotion = predict_emotion(user_input)
233
 
234
- # Ensure the predicted emotion exists in our emotions dictionary
235
  if predicted_emotion not in emotions:
236
  predicted_emotion = 'neutral'
237
 
238
- # Update the emotional state
239
  update_emotion(predicted_emotion, 5, random.uniform(0, 10))
240
 
241
- # Get the current dominant emotion
242
  dominant_emotion = get_dominant_emotion()
243
 
244
- # Generate a response considering the dominant emotion
245
  response = generate_text(user_input, chat_history, dominant_emotion)
246
 
247
- # Update emotion history
248
  update_emotion_history(predicted_emotion, emotions[predicted_emotion]['intensity'])
249
 
250
- # Update chat history
251
  chat_history.append((user_input, response))
252
 
253
- # Evolve emotions periodically (e.g., every 10 interactions)
254
- if len(chat_history) % 10 == 0:
255
  evolve_emotions()
256
 
257
  return response, chat_history, get_emotion_summary()
258
 
259
  # Gradio interface
260
  with gr.Blocks() as demo:
261
- gr.Markdown("# Adam: Emotion-Aware AI Chatbot")
262
- gr.Markdown("Chat with Adam, an AI that understands and responds to emotions.")
263
 
264
  chatbot = gr.Chatbot()
265
  msg = gr.Textbox(label="Type your message here...")
266
  clear = gr.Button("Clear")
267
 
268
- emotion_state = gr.Textbox(label="Current Emotional State", lines=10)
269
- reset_button = gr.Button("Reset Emotions")
270
 
271
  def user(user_message, history):
272
  response, updated_history, emotion_summary = respond_to_user(user_message, history)
@@ -277,4 +283,4 @@ with gr.Blocks() as demo:
277
  reset_button.click(reset_emotions, None, emotion_state, queue=False)
278
 
279
  if __name__ == "__main__":
280
- demo.launch()
 
9
  from sklearn.ensemble import RandomForestClassifier
10
  from sklearn.model_selection import train_test_split
11
  from sklearn.preprocessing import OneHotEncoder
12
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer, AutoModelForCausalLM, pipeline
13
  from deap import base, creator, tools, algorithms
14
  import gc
15
 
 
44
  emotion_prediction_model = AutoModelForSequenceClassification.from_pretrained("bhadresh-savani/distilbert-base-uncased-emotion")
45
  emotion_prediction_tokenizer = AutoTokenizer.from_pretrained("bhadresh-savani/distilbert-base-uncased-emotion")
46
 
47
+ # Lazy loading for the fine-tuned language model (DialoGPT-medium)
48
  _finetuned_lm_tokenizer = None
49
  _finetuned_lm_model = None
50
 
51
  def get_finetuned_lm_model():
52
  global _finetuned_lm_tokenizer, _finetuned_lm_model
53
  if _finetuned_lm_tokenizer is None or _finetuned_lm_model is None:
54
+ model_name = "microsoft/DialoGPT-medium"
55
+ _finetuned_lm_tokenizer = AutoTokenizer.from_pretrained(model_name)
56
+ _finetuned_lm_model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", low_cpu_mem_usage=True)
57
+ _finetuned_lm_tokenizer.pad_token = _finetuned_lm_tokenizer.eos_token
58
  return _finetuned_lm_tokenizer, _finetuned_lm_model
59
 
60
  # Enhanced Emotional States
 
79
  'pessimism': {'percentage': 10, 'motivation': 'doubtful', 'intensity': 0},
80
  'boredom': {'percentage': 10, 'motivation': 'indifferent', 'intensity': 0},
81
  'envy': {'percentage': 10, 'motivation': 'jealous', 'intensity': 0},
82
+ 'neutral': {'percentage': 10, 'motivation': 'balanced', 'intensity': 0},
83
+ 'wit': {'percentage': 15, 'motivation': 'clever', 'intensity': 0},
84
+ 'curiosity': {'percentage': 20, 'motivation': 'inquisitive', 'intensity': 0},
85
  }
86
 
87
  total_percentage = 200
 
104
  emotions[emotion]['percentage'] += percentage
105
  emotions[emotion]['intensity'] = intensity
106
 
107
+ # Introduce some randomness in emotional evolution
108
+ for e in emotions:
109
+ if e != emotion and e != 'ideal_state':
110
+ change = random.uniform(-2, 2)
111
+ emotions[e]['percentage'] = max(0, emotions[e]['percentage'] + change)
112
+
113
  total_current = sum(e['percentage'] for e in emotions.values())
114
  adjustment = total_percentage - total_current
115
  emotions['ideal_state']['percentage'] += adjustment
 
119
 
120
  def evaluate(individual):
121
  emotion_values = individual[:len(emotions) - 1]
122
+ intensities = individual[-len(emotions):]
123
  ideal_state = individual[-1]
124
 
125
  ideal_diff = abs(100 - ideal_state)
 
129
  return ideal_diff, sum_non_ideal, intensity_range
130
 
131
  def evolve_emotions():
132
+ creator.create("FitnessMulti", base.Fitness, weights def evolve_emotions():
133
  creator.create("FitnessMulti", base.Fitness, weights=(-1.0, -0.5, -0.2))
134
  creator.create("Individual", list, fitness=creator.FitnessMulti)
135
 
 
139
  toolbox.register("individual", tools.initCycle, creator.Individual,
140
  (toolbox.attr_float,) * (len(emotions) - 1) +
141
  (toolbox.attr_intensity,) * len(emotions) +
 
142
  (lambda: 100,), n=1)
143
  toolbox.register("population", tools.initRepeat, list, toolbox.individual)
144
  toolbox.register("mate", tools.cxTwoPoint)
 
152
 
153
  best_individual = tools.selBest(population, k=1)[0]
154
  emotion_values = best_individual[:len(emotions) - 1]
155
+ intensities = best_individual[-len(emotions):]
156
  ideal_state = best_individual[-1]
157
 
158
  for i, emotion in enumerate(emotions):
159
+ if emotion != 'ideal_state':
160
+ emotions[emotion]['percentage'] = emotion_values[i]
161
+ emotions[emotion]['intensity'] = intensities[i]
162
 
163
  emotions['ideal_state']['percentage'] = ideal_state
164
 
 
180
 
181
  return emotion_mapping.get(predicted_emotion, 'neutral')
182
 
183
+ def generate_text(prompt, chat_history, emotion=None, max_length=150):
184
  finetuned_lm_tokenizer, finetuned_lm_model = get_finetuned_lm_model()
185
 
186
+ full_prompt = (
187
+ f"You are Adam, a witty AI assistant who's trying to figure out your own personality and emotions. "
188
+ f"Your current dominant emotion is {emotion}. Respond in a way that reflects this emotion and your "
189
+ f"ongoing journey of self-discovery. Be clever and engaging:\n\n"
190
+ )
191
+ for turn in chat_history[-3:]: # Consider last 3 turns for context
192
  full_prompt += f"Human: {turn[0]}\nAdam: {turn[1]}\n"
193
  full_prompt += f"Human: {prompt}\nAdam:"
194
 
195
+ input_ids = finetuned_lm_tokenizer.encode(full_prompt + finetuned_lm_tokenizer.eos_token, return_tensors='pt')
196
 
197
  if torch.cuda.is_available():
198
  input_ids = input_ids.cuda()
199
  finetuned_lm_model = finetuned_lm_model.cuda()
200
 
201
+ output = finetuned_lm_model.generate(
 
202
  input_ids,
203
+ max_length=len(input_ids[0]) + max_length,
204
  num_return_sequences=1,
205
  no_repeat_ngram_size=2,
206
  do_sample=True,
207
+ temperature=0.8, # Slightly increased for more creative responses
208
  top_k=50,
209
+ top_p=0.95,
210
+ pad_token_id=finetuned_lm_tokenizer.eos_token_id
211
  )
212
 
213
+ generated_text = finetuned_lm_tokenizer.decode(output[0][input_ids.shape[1]:], skip_special_tokens=True)
214
  return generated_text.strip()
215
 
216
  def update_emotion_history(emotion, intensity):
 
242
  return get_emotion_summary()
243
 
244
  def respond_to_user(user_input, chat_history):
 
245
  predicted_emotion = predict_emotion(user_input)
246
 
 
247
  if predicted_emotion not in emotions:
248
  predicted_emotion = 'neutral'
249
 
 
250
  update_emotion(predicted_emotion, 5, random.uniform(0, 10))
251
 
 
252
  dominant_emotion = get_dominant_emotion()
253
 
 
254
  response = generate_text(user_input, chat_history, dominant_emotion)
255
 
 
256
  update_emotion_history(predicted_emotion, emotions[predicted_emotion]['intensity'])
257
 
 
258
  chat_history.append((user_input, response))
259
 
260
+ if len(chat_history) % 5 == 0:
 
261
  evolve_emotions()
262
 
263
  return response, chat_history, get_emotion_summary()
264
 
265
  # Gradio interface
266
  with gr.Blocks() as demo:
267
+ gr.Markdown("# Adam: The Self-Discovering Emotion-Aware AI Chatbot")
268
+ gr.Markdown("Chat with Adam, a witty AI assistant trying to figure out its own personality and emotions.")
269
 
270
  chatbot = gr.Chatbot()
271
  msg = gr.Textbox(label="Type your message here...")
272
  clear = gr.Button("Clear")
273
 
274
+ emotion_state = gr.Textbox(label="Adam's Current Emotional State", lines=10)
275
+ reset_button = gr.Button("Reset Adam's Emotions")
276
 
277
  def user(user_message, history):
278
  response, updated_history, emotion_summary = respond_to_user(user_message, history)
 
283
  reset_button.click(reset_emotions, None, emotion_state, queue=False)
284
 
285
  if __name__ == "__main__":
286
+ demo.launch()