Spaces:
Runtime error
Runtime error
File size: 9,044 Bytes
6bc94ac b55470f 6bc94ac abca9bf 2fc6e46 6bc94ac db5ef00 6bc94ac abca9bf 6bc94ac 5beab45 6bc94ac b55470f 6bc94ac 5beab45 6bc94ac 5beab45 db5ef00 5beab45 6bc94ac abca9bf 6bc94ac 5beab45 6bc94ac db5ef00 5beab45 db5ef00 5beab45 8bc0535 db5ef00 5beab45 db5ef00 8bc0535 5beab45 8bc0535 db5ef00 8bc0535 5beab45 db5ef00 5beab45 db5ef00 7fedcd4 5beab45 db5ef00 5beab45 8bc0535 5beab45 8bc0535 db5ef00 8bc0535 5beab45 db5ef00 5beab45 db5ef00 5beab45 db5ef00 8bc0535 5beab45 6bc94ac 8bc0535 5beab45 8bc0535 5beab45 427e102 abca9bf 370e3bc 2a846a9 6bc94ac 5beab45 6bc94ac |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
import datetime
import numpy as np
import torch
import torch.nn.functional as F
import speech_recognition as sr
import re
import time
import pickle
from sklearn.metrics.pairwise import cosine_similarity
# Build the AI
class CelebBot():
def __init__(self, name, gender, QA_tokenizer, QA_model, sentTr_tokenizer, sentTr_model, spacy_model, knowledge_sents, top_k = 8):
self.name = name
self.gender = gender
print("--- starting up", self.name, self.gender, "---")
self.text = ""
self.QA_tokenizer = QA_tokenizer
self.QA_model = QA_model
self.sentTr_tokenizer = sentTr_tokenizer
self.sentTr_model = sentTr_model
self.spacy_model = spacy_model
self.all_knowledge = knowledge_sents
self.top_k = top_k
def speech_to_text(self):
recognizer = sr.Recognizer()
with sr.Microphone() as mic:
recognizer.adjust_for_ambient_noise(mic, duration=1)
# flag = input("Are you ready to record?\nProceed (Y/n)")
# try:
# assert flag=='Y'
# except:
# self.text = ""
# print(f"me --> Permission denied")
time.sleep(1)
print("listening")
audio = recognizer.listen(mic)
try:
self.text = recognizer.recognize_google(audio)
except:
self.text = ""
print(f"me --> No audio recognized")
def text_to_speech(self, autoplay=True):
import run_tts
return run_tts.tts(self.text, "_".join(self.name.split(" ")), self.spacy_model, autoplay)
def sentence_embeds_inference(self, texts: list):
def _mean_pooling(model_output, attention_mask):
token_embeddings = model_output[0] #First element of model_output contains all token embeddings
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
# Tokenize sentences
encoded_input = self.sentTr_tokenizer(texts, padding=True, truncation=True, return_tensors='pt')
encoded_input["input_ids"] = encoded_input["input_ids"].to(self.sentTr_model.device)
encoded_input["attention_mask"] = encoded_input["attention_mask"].to(self.sentTr_model.device)
# Compute token embeddings
with torch.no_grad():
model_output = self.sentTr_model(**encoded_input)
# Perform pooling
sentence_embeddings = _mean_pooling(model_output, encoded_input['attention_mask'])
# Normalize embeddings
sentence_embeddings = F.normalize(sentence_embeddings, p=2, dim=1)
return sentence_embeddings
def retrieve_knowledge_assertions(self, change_person=True):
question_embeddings = self.sentence_embeds_inference([self.text])
all_knowledge_embeddings = self.sentence_embeds_inference(self.all_knowledge)
similarity = cosine_similarity(all_knowledge_embeddings.cpu(), question_embeddings.cpu())
similarity = np.reshape(similarity, (1, -1))[0]
K = min(self.top_k, len(self.all_knowledge))
top_K = np.sort(np.argpartition(similarity, -K)[-K: ])
all_knowledge_assertions = np.array(self.all_knowledge)[top_K]
# similarities = np.array(similarity)[top_K]
# print(*all_knowledge_assertions, sep='\n')
if change_person:
all_knowledge_assertions = [self.third_to_first_person(sent) for sent in all_knowledge_assertions]
return " ".join(all_knowledge_assertions)
def third_to_first_person(self, text):
text = text.replace(" ", " ")
possible_names = [name.lower() for name in self.name.split(" ")]
if "bundchen" in self.name.lower():
possible_names.append("bündchen")
if "beyonce" in self.name.lower():
possible_names.append("beyoncé")
if "adele" in self.name.lower():
possible_names.append("adkins")
if "katy perry" in self.name.lower():
possible_names.append("hudson")
if "lady gaga" in self.name.lower():
possible_names.append("germanotta")
if "michelle obama" in self.name.lower():
possible_names.append("robinson")
if "natalie portman" in self.name.lower():
possible_names.append("hershlag")
if "rihanna" in self.name.lower():
possible_names.append("fenty")
if "victoria beckham" in self.name.lower():
possible_names.append("adams")
doc = self.spacy_model(text)
transformed_text = []
for i, token in enumerate(doc):
if self.gender == "M":
if token.text.lower() == "he":
transformed_text.append("I")
elif token.text.lower() == "him":
transformed_text.append("me")
elif token.text.lower() == "his":
transformed_text.append("my")
elif token.text.lower() == "himself":
transformed_text.append("myself")
elif token.text.lower() in possible_names and token.dep_ in ["nsubj", "nsubjpass"]:
transformed_text.append("I")
elif token.text in ["'s", "’s"] and doc[i-1].text.lower() in possible_names:
transformed_text[-1] = "my"
elif token.text.lower() in possible_names and token.dep_ in ["dobj", "dative"]:
transformed_text.append("me")
elif token.text.lower() == "their":
transformed_text.append("our")
elif token.text.lower() == "they":
transformed_text.append("we")
else:
transformed_text.append(token.text)
elif self.gender == "F":
if token.text.lower() == "she":
transformed_text.append("I")
elif token.text.lower() == "her":
if i < len(doc)-2 and doc[i+2].dep_ in ["nsubj", "nsubjpass", "dobj", "appos", "dative", "attr", "amod", "nummod", "compound", "pobj", "pcomp"]:
transformed_text.append("my")
else:
transformed_text.append("me")
elif token.text.lower() == "herself":
transformed_text.append("myself")
elif token.text.lower() in possible_names and token.dep_ in ["nsubj", "nsubjpass"]:
transformed_text.append("I")
elif token.text in ["'s", "’s"] and doc[i-1].text.lower() in possible_names:
transformed_text[-1] = "my"
elif token.text.lower() in possible_names and token.dep_ in ["dobj", "dative"]:
transformed_text.append("me")
elif token.text.lower() == "their":
transformed_text.append("our")
elif token.text.lower() == "they":
transformed_text.append("we")
else:
transformed_text.append(token.text)
return "".join(transformed_text)
def question_answer(self, instruction='', knowledge='', chat_his=''):
instruction = f"Your name is {self.name}. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature. If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information."
if self.text != "":
if re.search(re.compile(rf'\b({self.name})\b', flags=re.IGNORECASE), self.text) != None:
knowledge = self.retrieve_knowledge_assertions(change_person=False)
else:
knowledge = self.retrieve_knowledge_assertions()
query = f"Context: {instruction} {knowledge}\n\nQuestion: {self.text}\n\nAnswer:"
input_ids = self.QA_tokenizer(f"{query}", truncation=False, return_tensors="pt").input_ids.to(self.QA_model.device)
outputs = self.QA_model.generate(input_ids, max_length=1024, min_length=8, repetition_penalty=2.5)
self.text = self.QA_tokenizer.decode(outputs[0], skip_special_tokens=True)
return self.text
@staticmethod
def action_time():
return f"it's {datetime.datetime.now().time().strftime('%H:%M')}"
@staticmethod
def save_kb(kb, filename):
with open(filename, "wb") as f:
pickle.dump(kb, f)
@staticmethod
def load_kb(filename):
res = None
with open(filename, "rb") as f:
res = pickle.load(f)
return res |