File size: 13,625 Bytes
c02b4bf 2dd4394 91bfd0f 2dd4394 3dba665 2dd4394 3dba665 2dd4394 c02b4bf 2dd4394 a6019c9 c02b4bf d3ae86a c02b4bf a6019c9 c02b4bf 83a946a c02b4bf a6019c9 583fa98 12594b9 48c2bf9 a6019c9 ef9bc0a 5d754fa a6019c9 7eefba8 a6019c9 c02b4bf a6019c9 7eefba8 a6019c9 2dd4394 3e9f047 2dd4394 c02b4bf 2214362 a6019c9 3e9f047 c02b4bf 6bd4693 2214362 6bd4693 d9f8d20 6bd4693 853f2d0 6bd4693 437a85d 6bd4693 3e9f047 6bd4693 3e9f047 1ceac94 2813ac3 1ceac94 a6019c9 3dba665 a6019c9 0aec7e8 a6019c9 a32622e 37011e9 1ceac94 8d4f7be 2dd4394 a6019c9 2dd4394 437a85d a6019c9 2dd4394 437a85d a6019c9 2dd4394 a6019c9 2dd4394 bf53022 a6019c9 c02b4bf a6019c9 2dd4394 a6019c9 853f2d0 a6019c9 2dd4394 a6019c9 3e8c5ce c02b4bf |
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 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
import chromadb
import os
import gradio as gr
import json
from huggingface_hub import InferenceClient
import gspread
from google.oauth2 import service_account
from datetime import datetime
import chromadb
# Google Sheets setup
scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
key1 = os.getenv("key1")
key2 = os.getenv("key2")
key3 = os.getenv("key3")
key4 = os.getenv("key4")
key5 = os.getenv("key5")
key6 = os.getenv("key6")
key7 = os.getenv("key7")
key8 = os.getenv("key8")
key9 = os.getenv("key9")
key10 = os.getenv("key10")
key11 = os.getenv("key11")
key12 = os.getenv("key12")
key13 = os.getenv("key13")
key14 = os.getenv("key14")
key15 = os.getenv("key15")
key16 = os.getenv("key16")
key17 = os.getenv("key17")
key18 = os.getenv("key18")
key19 = os.getenv("key19")
key20 = os.getenv("key20")
key21 = os.getenv("key21")
key22 = os.getenv("key22")
key23 = os.getenv("key23")
key24 = os.getenv("key24")
key25 = os.getenv("key25")
key26 = os.getenv("key26")
key27 = os.getenv("key27")
key28 = os.getenv("key28")
key29 = os.getenv("key29")
key30 = os.getenv("key30")
key31 = os.getenv("key31")
pkey="-----BEGIN PRIVATE KEY-----\n"+key2+"\n"+key3+"\n"+ key4+"\n"+key5+"\n"+ key6+"\n"+key7+"\n"+key8+"\n"+key9+"\n"+key10+"\n"+key11+"\n"+key12+"\n"+key13+"\n"+key14+"\n"+key15+"\n"+key16+"\n"+key17+"\n"+key18+"\n"+key19+"\n"+key20+"\n"+key21+"\n"+key22+"\n"+key24+"\n"+key25+"\n"+key26+"\n"+key27+"\n"+key28+"\n-----END PRIVATE KEY-----\n"
json_data={
"type": "service_account",
"project_id": "nestolechatbot",
"private_key_id": key1,
"private_key": pkey,
"client_email": key29,
"client_id": key30,
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": key31,
"universe_domain": "googleapis.com"
}
creds = service_account.Credentials.from_service_account_info(json_data, scopes=scope)
client = gspread.authorize(creds)
sheet = client.open("nestolechatbot").sheet1 # Open the sheet
def save_to_sheet(date, name, message, IP, dev, header):
# Write user input to the Google Sheet
sheet.append_row([date, name, message, IP, dev, header])
return f"Thanks {name}, your message has been saved!"
path='/Users/thiloid/Desktop/LSKI/ole_nest/Chatbot/LLM/chroma'
if(os.path.exists(path)==False): path="/home/user/app/chroma"
print(path)
client = chromadb.PersistentClient(path=path)
print(client.heartbeat())
print(client.get_version())
print(client.list_collections())
from chromadb.utils import embedding_functions
default_ef = embedding_functions.DefaultEmbeddingFunction()
sentence_transformer_ef = embedding_functions.SentenceTransformerEmbeddingFunction(model_name="T-Systems-onsite/cross-en-de-roberta-sentence-transformer")#"VAGOsolutions/SauerkrautLM-Mixtral-8x7B-Instruct")
collection = client.get_collection(name="chromatsc", embedding_function=sentence_transformer_ef)
client = InferenceClient("mistralai/Mixtral-8x7B-Instruct-v0.1")
from nltk.tokenize import word_tokenize
import nltk
nltk.download('punkt')
nltk.download('punkt_tab')
import pandas as pd
import string
import re
osa= pd.read_excel("/home/user/app/OSA.xlsx", nrows=136)
osa.loc[osa["Hochschule"] == "Übergreifend", "Hochschule"] = " "
osa.loc[osa["OSA: Fach (original)"] == "Allgemein", "OSA: Fach (original)"] = " "
# text that will be added to chatbot answer
osa.loc[osa["Link_Studium_Allgemein"].notna(), "Link_Studium_Allgemein"] = "Basierend auf deiner Frage empfehele ich dir diesen Interessenstest: "+ osa["Link_Studium_Allgemein"]
osa.loc[osa["Link_Uni_Allgemein"].notna(), "Link_Uni_Allgemein"] = "Basierend auf deinem Interesse an der "+osa["Hochschule"]+" empfehele ich dir diesen Interessenstest: "+ osa["Link_Uni_Allgemein"]
osa.loc[osa["Link_Fach"].notna(), "Link_Fach"] = "Basierend auf deinem Interesse an der " +osa["Hochschule"]+ " "+osa["OSA: Fach (original)"]+" zu studieren, empfehle ich dir diesen Interessenstest: "+ osa["Link_Fach"]
osa["chattext"]= osa["Link_Studium_Allgemein"].fillna('')+ osa["Link_Uni_Allgemein"].fillna('')+osa["Link_Fach"].fillna('')
# Text to compare with user prompt
osa["combi"]= osa["Hochschule"]+ " "+ osa["OSA: Fach (original)"]
osalist= osa["combi"].tolist()
osalist
def simosa(prompt, osalist, osa):
lcos = []
prompt = prompt.lower()
p_list = word_tokenize(prompt)
# Form a set containing keywords of the prompt
sw = [",", "?"]
p_set = {w for w in p_list if not w in sw}
for val in osalist:
val = val.lower()
v_list = word_tokenize(val)
# Form a set containing keywords of the current value
v_set = {w for w in v_list if not w in sw}
# Union of both sets
rvector = p_set.union(v_set)
# Create vectors
l1 = [1 if w in p_set else 0 for w in rvector]
l2 = [1 if w in v_set else 0 for w in rvector]
# Compute cosine similarity
dot_product = sum(l1[i] * l2[i] for i in range(len(rvector)))
magnitude1 = sum(l1)
magnitude2 = sum(l2)
if magnitude1 == 0 or magnitude2 == 0:
cosine = 0.0
else:
cosine = dot_product / float((magnitude1 * magnitude2) ** 0.5)
lcos.append(cosine)
osa["testsim"]=lcos
match=osa.loc[osa['testsim'].idxmax()]["testsim"]
#print(match)
if match >0.29:
answer = str(osa.loc[osa['testsim'].idxmax()]["chattext"])
else:
answer= "Wenn du dir unsicher bist, was du studieren könntest oder ob deine Fähigkeiten ausreichen, dann mach doch diesen Test (https://www.was-studiere-ich.de/) oder schau dir mal diese Seminare an (https://www.bw-best.de)."
print("Done simosa")
return answer
def parse_for_nc(text):
'''
Parses text for words relating to NC and Abiturnote
:param text: a string
:return: an automatic response in form of a string
'''
nc_words = [" nc ", "abischnitt", "abiturschnitt", "abinote", "abiturnote", "ncschnitt", "abschlussnote", "abschlussdurchschnitt", "abschlussnote", "zulassungsbeschränkung", "numerus clausus", "noten"]
response = "Wenn du dir unsicher bist, ob du die Zulassungsvoraussetzungen zu einem Studiengang erfüllst, schau am besten einmal auf der Website der Universität nach, was gefordert ist.\n Häufig entscheidet nicht allein die Abiturnote die Zulassung, sondern auch Faktoren wie praktische Erfahrung oder ein FSJ.\n Lass dich außerdem nicht von den NCs vergangener Jahre verunsichern.\n Der NC gibt nur an, was im vergangenen Jahr die schlechteste Note des regulären Prozesses war, mit der man noch zugelassen wurde.\n Der NC kann sich also von Jahr zu Jahr verändern und oft werden auch Leute zugelassen, die einen schlechteren Schnitt ab (bspw. durch Wartesemester).\n Wenn du dir hingegen unsicher bist, ob deine Fähigkeiten mit denen des Fachs übereinstimmen,\n dann mach doch vielleicht mal einen Test. Außerdem gibt es Aufbau- und Vorbereitungskurse mittels derer du Wissen und Fähigkeiten aufbauen kannst."
# if the string is not empty
if text:
text = text.strip() # strip
text = text.lower() # lower all letters
text = text.translate(str.maketrans('', '', string.punctuation)) # remove punctuation
text = " "+text+" " # add whitespaces so that nc can be found correctly
for nc_word in nc_words:
if nc_word in text:
return response
print("Done NC")
return "No"
def extract_ip_and_device(headers_obj):
ip_address = None
device_info = None
# Access the raw headers list
headers = headers_obj.raw
for header in headers:
if len(header) != 2:
print(f"Unexpected header format: {header}")
continue
key, value = header
if key == b'x-forwarded-for':
ip_address = value.decode('utf-8')
elif key == b'user-agent':
device_info = value.decode('utf-8')
return ip_address, device_info
def format_prompt(message, history):
prompt = ""
if history:
user_prompt, bot_response = history[-1]
prompt += f"[INST] {user_prompt} [/INST] {bot_response}</s> "
prompt += f"[INST] {message} [/INST]"
return prompt
def format_promptc(message):
prompt = "" #"<s>"
prompt += f"[INST] {message} [/INST]"
return prompt
def responsecritical(
prompt, temperature=0.9, max_new_tokens=10, top_p=0.95, repetition_penalty=1.0,
):
temperature = float(temperature)
if temperature < 1e-2: temperature = 1e-2
top_p = float(top_p)
generate_kwargs = dict(
temperature=temperature,
max_new_tokens=max_new_tokens,
top_p=top_p,
repetition_penalty=repetition_penalty,
do_sample=True,
seed=42,
)
systemc="Bitte evaluiere ob die Frage soziokulturell oder allgemein problematisch oder auch sensibel oder politisch ist. Antworte ausschließlich mit Ja wenn sie soziokulturell oder allgemein problematisch ist, ansonsten nur mit Nein. Erkläre deine Entscheidung nicht.\n\nUser-Anliegen:"
formatted_promptc = format_promptc(systemc+"\n"+prompt)
streamc = client.text_generation(formatted_promptc, **generate_kwargs, stream=True, details=True, return_full_text=False)
outputc = ""
print(streamc)
for responsec in streamc:
outputc += responsec.token.text
print("CRITICAL")
print(outputc)
sentence_lower = outputc.lower()
print("Done critcial")
# Check if the word 'nein' is in the sentence
if 'ja' in sentence_lower:
return False
else:
return True
def get_value_after_question_mark(url):
url=str(url)
# Find the position of the question mark
question_mark_index = url.find('?')
# Extract the part after the question mark
if question_mark_index != -1:
value_after_question_mark = url[question_mark_index + 1:].split('=')[0]
else:
value_after_question_mark = ""
return value_after_question_mark
def response(
request: gr.Request, prompt,history, temperature=0.9, max_new_tokens=500, top_p=0.95, repetition_penalty=1.0,
):
temperature = float(0.9)
if temperature < 1e-2: temperature = 1e-2
top_p = float(top_p)
generate_kwargs = dict(
temperature=temperature,
max_new_tokens=max_new_tokens,
top_p=top_p,
repetition_penalty=repetition_penalty,
do_sample=True,
seed=42,
)
#get ID
full_url = request.url
IDval= get_value_after_question_mark(full_url)
print(full_url)
headers = request.headers
IP, dev = extract_ip_and_device(headers)
if responsecritical(prompt)==False:
now = str(datetime.now())
save_to_sheet(now, prompt, "Es scheint so, als sei dies keine Frage, die sich auf die Studienorientierung bezieht", IP, dev, str(headers))
yield "Es scheint so, als sei dies keine Frage, die sich auf die Studienorientierung bezieht"
else:
answernc=parse_for_nc(prompt)
if answernc!="No":
now = str(datetime.now())
save_to_sheet(now, prompt, answernc, IP, dev, str(headers))
yield answernc
else:
prompt = re.sub(r'\buni\b', 'Universität', prompt, flags=re.IGNORECASE)
addon=""
search_prompt = format_prompt(prompt, history)
results=collection.query(
query_texts=[search_prompt],
n_results=40
)
dists=["<br><small>(relevance: "+str(round((1-d)*100)/100)+";" for d in results['distances'][0]]
results=results['documents'][0]
combination = zip(results,dists)
combination = [' '.join(triplets) for triplets in combination]
if(len(results)>1):
addon=" Bitte berücksichtige bei deiner Antwort ausschießlich folgende Auszüge aus unserer Datenbank, sofern sie für die Antwort erforderlich sind. Beantworte die Frage knapp und präzise. Ignoriere unpassende Datenbank-Auszüge OHNE sie zu kommentieren, zu erwähnen oder aufzulisten:\n"+"\n".join(results)
system="Du bist ein deutschsprachiges KI-basiertes Studienberater Assistenzsystem, das zu jedem Anliegen möglichst geeignete Studieninformationen empfiehlt."+addon+"\n\nUser-Anliegen:"
formatted_prompt = format_prompt(system+"\n"+prompt, history)
stream = client.text_generation(formatted_prompt, **generate_kwargs, stream=True, details=True, return_full_text=False)
output = ""
for response in stream:
output += response.token.text
print(output)
osaanswer=simosa(prompt, osalist, osa)
output=output[:-4]+"\n"+osaanswer
now = str(datetime.now())
save_to_sheet(now, prompt, output, IP, dev, str(headers))
yield output
gr.ChatInterface(response, chatbot=gr.Chatbot(value=[[None,"Herzlich willkommen! Ich bin Chätti ein KI-basiertes Studienassistenzsystem, das für jede Anfrage die besten Studieninformationen empfiehlt.<br>Erzähle mir was dich interessiert! Allgemein kann ich dir diesen Test (https://www.was-studiere-ich.de/) oder diese Seminare (https://www.bw-best.de) zur Studienfindung empfehlen."]],render_markdown=True),title="German Studyhelper Chätti").queue().launch(share=True) #False, server_name="0.0.0.0", server_port=7864)
print("Interface up and running!")
|