alexkueck commited on
Commit
377d027
1 Parent(s): c45ac02

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +670 -0
app.py ADDED
@@ -0,0 +1,670 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import os, sys, json
3
+ import gradio as gr
4
+ import time
5
+ import re
6
+ import io
7
+ #from PIL import Image, ImageDraw, ImageOps, ImageFont
8
+ #import base64
9
+ import tempfile
10
+ import asyncio
11
+ from concurrent.futures import ThreadPoolExecutor
12
+
13
+ from PyPDF2 import PdfReader, PdfWriter
14
+
15
+
16
+ #from langchain.chains import LLMChain, RetrievalQA
17
+ from langchain_community.document_loaders import PyPDFLoader, UnstructuredWordDocumentLoader, DirectoryLoader
18
+ from langchain_community.document_loaders.blob_loaders.youtube_audio import YoutubeAudioLoader
19
+ #from langchain.document_loaders import GenericLoader
20
+ #from langchain.schema import AIMessage, HumanMessage
21
+ #from langchain_community.llms import HuggingFaceHub
22
+ from langchain_huggingface import HuggingFaceEndpoint
23
+ #from langchain_community.llms import HuggingFaceEndPoints
24
+ from langchain_huggingface import HuggingFaceEmbeddings
25
+ #from langchain_community.llms import HuggingFaceTextGenInference
26
+ #from langchain_community.embeddings import HuggingFaceInstructEmbeddings, HuggingFaceEmbeddings, HuggingFaceBgeEmbeddings, HuggingFaceInferenceAPIEmbeddings
27
+ #from langchain.prompts import PromptTemplate
28
+ #from langchain.chains import Runnable.................................
29
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
30
+ from langchain_community.vectorstores import Chroma
31
+ from chromadb.errors import InvalidDimensionException
32
+ from langchain_community.llms.huggingface_pipeline import HuggingFacePipeline
33
+ from transformers import pipeline
34
+ from huggingface_hub import InferenceApi
35
+ from utils import *
36
+ from beschreibungen import *
37
+
38
+
39
+
40
+ #Konstanten
41
+ #Validieren des PW
42
+ ANTI_BOT_PW = os.getenv("VALIDATE_PW")
43
+
44
+ ###############################
45
+ #HF Authentifizierung
46
+ HUGGINGFACEHUB_API_TOKEN = os.getenv("HF_READ")
47
+ os.environ["HUGGINGFACEHUB_API_TOKEN"] = HUGGINGFACEHUB_API_TOKEN
48
+ HEADERS = {"Authorization": f"Bearer {HUGGINGFACEHUB_API_TOKEN}"}
49
+ # Hugging Face Token direkt im Code setzen
50
+ hf_token = os.getenv("HF_READ")
51
+
52
+
53
+ #max Anzahl der zurückgelieferten Dokumente
54
+ ANZAHL_DOCS = 5
55
+ PATH_WORK = "."
56
+ CHROMA_DIR = "/chroma/kkg"
57
+ CHROMA_PDF = './chroma/kkg/pdf'
58
+ CHROMA_WORD = './chroma/kkg/word'
59
+ CHROMA_EXCEL = './chroma/kkg/excel'
60
+ DOCS_DIR = "chroma/kkg"
61
+
62
+ ###########################################
63
+ # Alternativen, um HF Modelle in der rAG Chain einzusetzen
64
+ ###########################################
65
+ #######################################
66
+ #1. Alternative: HuggingFace Model name--------------------------------
67
+ #MODEL_NAME_HF = "HuggingFaceH4/zephyr-7b-alpha" #"t5-small" #"meta-llama/Meta-Llama-3-8B-Instruct" #"mistralai/Mistral-7B-Instruct-v0.3" #"microsoft/Phi-3-mini-4k-instruct" #"HuggingFaceH4/zephyr-7b-alpha"
68
+
69
+ ############################################
70
+ #2. Alternative_ HuggingFace Reop ID--------------------------------
71
+ #repo_id = "meta-llama/Llama-2-13b-chat-hf"
72
+ #repo_id = "HuggingFaceH4/zephyr-7b-alpha" #das Modell ist echt gut!!! Vom MIT
73
+ #repo_id = "TheBloke/Yi-34B-Chat-GGUF"
74
+ #repo_id = "meta-llama/Llama-2-70b-chat-hf"
75
+ #repo_id = "tiiuae/falcon-40b"
76
+ #repo_id = "Vicuna-33b"
77
+ #repo_id = "alexkueck/ChatBotLI2Klein"
78
+ #repo_id = "mistralai/Mistral-7B-v0.1"
79
+ #repo_id = "internlm/internlm-chat-7b"
80
+ #repo_id = "Qwen/Qwen-7B"
81
+ #repo_id = "Salesforce/xgen-7b-8k-base"
82
+ #repo_id = "Writer/camel-5b-hf"
83
+ #repo_id = "databricks/dolly-v2-3b"
84
+ #repo_id = "google/flan-t5-xxl"
85
+ #repo_id = "mistralai/Mixtral-8x7B-Instruct-v0.1"
86
+ #repo_id = "abacusai/Smaug-72B-v0.1"
87
+
88
+ ###########################################
89
+ #3. Alternative: HF API - URL
90
+ #API_URL = "https://api-inference.huggingface.co/models/Falconsai/text_summarization"
91
+
92
+
93
+
94
+
95
+ ###############################################
96
+ #globale Variablen
97
+ ##############################################
98
+ #Filepath zu temp Folder (temp) mit File von ausgewähltem chatverlauf
99
+ file_path_download = ""
100
+
101
+ ################################################
102
+ # Erstellen des Vektorstores
103
+ ################################################
104
+ def create_vectorstore():
105
+ global vektordatenbank, SPLIT_TO_ORIGINAL_MAPPING, ORIGINAL_SPLITS, PREPROCESSED_SPLITS
106
+ # Splits zu allen Dokumenten in den Verzeichnissen erstellen
107
+ PREPROCESSED_SPLITS, SPLIT_TO_ORIGINAL_MAPPING, ORIGINAL_SPLITS = document_loading_splitting()
108
+ if PREPROCESSED_SPLITS:
109
+ print("Vektordatenbank neu .....................")
110
+ # Vektordatenbank zu den Splits erstellen
111
+ vektordatenbank = document_storage_chroma(PREPROCESSED_SPLITS)
112
+ # Speichern der Splits und Metadaten
113
+ save_splits(PREPROCESSED_SPLITS, ORIGINAL_SPLITS)
114
+ save_split_to_original_mapping(SPLIT_TO_ORIGINAL_MAPPING)
115
+
116
+ #falls Vektorstore vorhanden: neu laden!!!!!!!!!!!!!!!!!
117
+ def load_vectorstore_and_mapping():
118
+ global vektordatenbank, SPLIT_TO_ORIGINAL_MAPPING, ORIGINAL_SPLITS, PREPROCESSED_SPLITS
119
+ preprocessed_splits, original_splits = load_splits()
120
+ mapping = load_split_to_original_mapping()
121
+ if preprocessed_splits is not None and original_splits is not None and mapping is not None:
122
+ # Vektordatenbank zu den Splits erstellen
123
+ vektordatenbank = document_storage_chroma(preprocessed_splits)
124
+ SPLIT_TO_ORIGINAL_MAPPING = mapping
125
+ ORIGINAL_SPLITS = original_splits
126
+ PREPROCESSED_SPLITS = preprocessed_splits
127
+ else:
128
+ #fehler beim laden -> Vektorstore neu zusammensetzen
129
+ create_vectorstore()
130
+
131
+
132
+
133
+ ###########################################
134
+ # Beim Start der Anwendung - Vektorstore laden!!!!
135
+ ###########################################
136
+ print("Vektorstore laden.........................")
137
+ #die Variablen: vektordatenbank, PREPROCESSED_SPLITS, ORGINAL_SPLITS und das Mapping werden neu gesetzt global!!!!
138
+ load_vectorstore_and_mapping()
139
+
140
+
141
+ #################################################
142
+ #################################################
143
+ #Funktionen zur Verarbeitung
144
+ ################################################
145
+
146
+ ##############################################
147
+ #wenn löschen Button geklickt
148
+ def clear_all(history, uploaded_file_paths, chats):
149
+ dic_history = {schluessel: wert for schluessel, wert in history}
150
+ #später wird die summary auf 50 tokens verkürzt, um die Anfrage nicht so teuer werden zu lassen
151
+ #summary wird gebraucht für die Anfrage beim NN, um eine Überschrift des Eintrages zu generieren
152
+ summary = "\n\n".join(f'{schluessel}: \n {wert}' for schluessel, wert in dic_history.items())
153
+
154
+ #falls file mit summay für download existiert hat: das zunächst löschen
155
+ #cleanup(file_path_download)
156
+ #noch nicht im Einsatz, aber hier werden alle Chats einer Sitzung gespeichert
157
+ #den aktuellen Chatverlauf zum Download bereitstellen:
158
+ if chats != {} :
159
+ id_neu = len(chats)+1
160
+ chats[id_neu]= summary
161
+ else:
162
+ chats[0]= summary
163
+
164
+ #Eine Überschrift zu dem jeweiligen Chatverlauf finden - abhängig vom Inhalt
165
+ #file_path_download = save_and_download(summary)
166
+ #headers, payload = process_chatverlauf(summary, MODEL_NAME, OAI_API_KEY)
167
+ #response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)
168
+ #als json ausgeben
169
+ #data = response.json()
170
+ # Den "content" auswählen, da dort die Antwort der Ki enthalten ist
171
+ #result = data['choices'][0]['message']['content']
172
+ #worte = result.split()
173
+ #if len(worte) > 2:
174
+ #file_path_download = "data/" + str(len(chats)) + "_Chatverlauf.pdf"
175
+ #else:
176
+ #file_path_download = "data/" + str(len(chats)) + "_" + result + ".pdf"
177
+
178
+ #erstellePdf(file_path_download, result, dic_history)
179
+
180
+
181
+ #die session variable in gradio erweitern und alle fliepath neu in das gr.File hochladen
182
+ #uploaded_file_paths= uploaded_file_paths + [file_path_download]
183
+
184
+ return None, gr.Image(visible=False), uploaded_file_paths, [], gr.File(uploaded_file_paths, label="Download-Chatverläufe", visible=True, file_count="multiple", interactive = False), chats
185
+
186
+
187
+ #wenn löschen Button geklickt
188
+ def clear_all3(history):
189
+ #die session variable in gradio erweitern und alle fliepath neu in das gr.File hochladen
190
+ uploaded_file_paths= ""
191
+ return None, gr.Image(visible=False), [],
192
+
193
+
194
+
195
+ ##############################################
196
+ #History - die Frage oder das File eintragen...
197
+ #in history_file ist ein file gespeichert, falls voher im Verlauf schon ein File hochgeladen wurde.
198
+ #wird ein neuer File hochgeladen, so wird history_fiel dadurch ersetzt
199
+
200
+ def add_text(chatbot, history, prompt, file, file_history):
201
+ if (file == None):
202
+ chatbot = chatbot +[(prompt, None)]
203
+ else:
204
+ file_history = file
205
+ if (prompt == ""):
206
+ chatbot=chatbot + [((file.name,), "Prompt fehlt!")]
207
+ else:
208
+ chatbot = chatbot +[("Hochgeladenes Dokument: "+ get_filename(file) +"\n" + prompt, None)]
209
+
210
+ return chatbot, history, prompt, file, file_history, gr.Image(visible = False), ""
211
+
212
+
213
+ ############################################
214
+ #nach dem Upload soll das zusätzliche Fenster mit dem image drinnen angezeigt werden
215
+
216
+ def file_anzeigen(file):
217
+ ext = analyze_file(file)
218
+ if (ext == "png" or ext == "PNG" or ext == "jpg" or ext == "jpeg" or ext == "JPG" or ext == "JPEG"):
219
+ return gr.Image(width=47, visible=True, interactive = False, height=47, min_width=47, show_label=False, show_share_button=False, show_download_button=False, scale = 0.5), file, file
220
+ else:
221
+ return gr.Image(width=47, visible=True, interactive = False, height=47, min_width=47, show_label=False, show_share_button=False, show_download_button=False, scale = 0.5), "data/file.png", file
222
+
223
+ def file_loeschen():
224
+ return None, gr.Image(visible = False)
225
+
226
+
227
+ ############################################
228
+ #wenn 'Stop' Button geklickt, dann Message dazu und das Eingabe-Fenster leeren
229
+ def cancel_outputing():
230
+ reset_textbox()
231
+ return "Stop Done"
232
+
233
+ def reset_textbox():
234
+ return gr.update(value=""),""
235
+
236
+
237
+
238
+ ####################################################
239
+ #aus einem Text-Prompt die Antwort von KI bekommen
240
+ def generate_text (prompt, chatbot, history, retriever, top_p=0.6, temperature=0.2, max_new_tokens=4048, max_context_length_tokens=2048, repetition_penalty=1.3, top_k=35):
241
+ if (prompt == ""):
242
+ raise gr.Error("Prompt ist erforderlich.")
243
+
244
+ try:
245
+ #########################################
246
+ #Prompt mit History Daten zusammenstellen:
247
+ #Prompt an history anhängen und einen Text daraus machen
248
+ #history_text_und_prompt = generate_prompt_with_history(prompt, history)
249
+
250
+ #oder an Hugging Face --------------------------
251
+ print("HF Anfrage.......................")
252
+ #zusätzliche Dokumenten Splits aus DB zum Prompt hinzufügen (aus VektorDB - Chroma oder Mongo DB)
253
+
254
+ ##############################################
255
+ #Verschiedene Alternativen als llm übergeben an die rag-chain
256
+ #############################################
257
+ #0. Alternative - repo ID
258
+ # Verwenden Sie die Inference Api von huggingface_hub
259
+ #llm = InferenceApi(repo_id, token=hf_token)
260
+ #result = rag_chain(llm, history_text_und_prompt, retriever)
261
+
262
+ ##############################################
263
+ #1.Alternative mit Inference API ung HF EndPoint
264
+ # Erstelle eine HuggingFaceEndPoints-Instanz mit den entsprechenden Endpunkt-Parametern
265
+ """
266
+ llm = HuggingFaceEndpoint(
267
+ endpoint_url=f"https://api-inference.huggingface.co/models/{MODEL_NAME_HF}",
268
+ api_key=hf_token,
269
+ temperature=0.5,
270
+ max_length=1024,
271
+ top_k=top_k,
272
+ top_p=top_p,
273
+ repetition_penalty=repetition_penalty
274
+ )
275
+ result = rag_chain(llm, history_text_und_prompt, retriever)
276
+
277
+ #############################################
278
+ #2. Alternative: mit API_URL
279
+ #result = rag_chain(API_URL, history_text_und_prompt, retriever)
280
+ #############################################
281
+ #3.te Alternative für pipeline
282
+ # Erstelle eine Pipeline mit den gewünschten Parametern
283
+ #llm = pipeline("text-generation", model=MODEL_NAME_HF, config={"temperature": 0.5, "max_length": 1024, "num_return_sequences": 1, "top_k": top_k, "top_p": top_p, "repetition_penalty": repetition_penalty}, trust_remote_code=True)
284
+ #llm = pipeline("summarization", model=MODEL_NAME_HF, trust_remote_code=True)
285
+ #result = rag_chain(llm, history_text_und_prompt, retriever)
286
+ """
287
+
288
+ result = rag_chain_simpel(prompt, retriever)
289
+
290
+ except Exception as e:
291
+ raise gr.Error(e)
292
+ return result, False
293
+
294
+
295
+
296
+
297
+
298
+ ##############################################################
299
+ #Eingaben der GUI verarbeiten
300
+ def generate_auswahl(prompt_in, file, file_history, chatbot, history, anzahl_docs=4, top_p=0.6, temperature=0.5, max_new_tokens=4048, max_context_length_tokens=2048, repetition_penalty=1.3,top_k=5, validate=False):
301
+ global vektordatenbank, SPLIT_TO_ORIGINAL_MAPPING
302
+
303
+ #nur wenn man sich validiert hat, kann die Anwendung los legen
304
+ if (validate and not prompt_in == "" and not prompt_in == None):
305
+ # Vektorstore initialisieren
306
+ #falls schon ein File hochgeladen wurde, ist es in history_file gespeichert - falls ein neues File hochgeladen wurde, wird es anschließend neu gesetzt
307
+ neu_file = file_history
308
+
309
+ #prompt normalisieren bevor er an die KIs geht
310
+ prompt = preprocess_text(prompt_in)
311
+
312
+ if vektordatenbank is None:
313
+ print("db neu aufbauen!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1")
314
+ #Splits zu allen Dokumenten in den Verzeichnissen erstellen
315
+ #vektordatenbank, SPLIT_TO_ORIGINAL_MAPPING werden aktualisiert
316
+ create_vectorstore()
317
+
318
+ if vektordatenbank:
319
+ #Retriever erstellen, um die relevanten Slpits zu einem Prompt zu suchen.... (retrieven)
320
+ retriever = vektordatenbank.as_retriever(search_kwargs = {"k": ANZAHL_DOCS})
321
+
322
+ #kein Bild hochgeladen -> auf Text antworten...
323
+ status = "Antwort der Vektordatenbank"
324
+ results, status = generate_text(prompt, chatbot, history, retriever, top_p=0.6, temperature=0.5, max_new_tokens=4048, max_context_length_tokens=2048, repetition_penalty=1.3, top_k=3)
325
+
326
+ # Überprüfen, ob relevante Dokumente gefunden wurden
327
+ if results['relevant_docs']:
328
+ # in results sind die preprocessed Splits enthalten, dargestellt werden sollen die originalen:
329
+ relevant_docs_org = []
330
+ for result in results['relevant_docs']:
331
+ split_id = result.get("metadata", {}).get("split_id")
332
+ if split_id:
333
+ try:
334
+ original_split = SPLIT_TO_ORIGINAL_MAPPING[split_id]
335
+ relevant_docs_org.append(original_split)
336
+ except Exception as e:
337
+ print(f"Fehler beim Laden des Mappings...................: {str(e)}")
338
+
339
+ else:
340
+ # Keine relevanten Dokumente gefunden
341
+ status = "Keine relevanten Dokumente gefunden."
342
+ relevant_docs_org = []
343
+
344
+ relevant_docs = extract_document_info(relevant_docs_org)
345
+
346
+ #Ergebnisse für history und chatbot zusammenstellen
347
+ summary = str(results['answer']) + "\n\n"
348
+ summary += " ".join([
349
+ '<div><b>Dokument/Link: </b> <span style="color: #BB70FC;"><a href="' + str(doc['download_link']) + '" target="_blank">' + str(doc['titel']) + '</a></span>'
350
+ ' (<b>Seite:</span> <span style="color: red;">' + str(doc['seite']) + '</b></span>)<br>'
351
+ '<span><b>Auschnitt:</b> ' + str(doc["content"]) + '</span></div><br>'
352
+ #'<div><span><b>Link: </b><span style="color: #BB70FC;"><a href="' + str(doc['download_link']) + '" target="_blank">' + str(doc['titel']) + '</a></span></div><br>'
353
+ for doc in relevant_docs])
354
+
355
+ history = history + [[prompt_in, summary]]
356
+
357
+ chatbot[-1][1] = summary
358
+ return chatbot, history, None, file_history, ""
359
+ else:
360
+ chatbot[-1][1] = "keine Dokumente gefunden!"
361
+ return chatbot, history, None, file_history, ""
362
+
363
+
364
+ else: #noch nicht validiert, oder kein Prompt
365
+ return chatbot, history, None, file_history, "Erst validieren oder einen Prompt eingeben!"
366
+
367
+ ########################################
368
+ # Hochladen von Dateien und Vektorstore neu erstellen
369
+ # Beispiel-Upload-PDF-Funktion
370
+ def upload_pdf(files):
371
+ status_message = ""
372
+ if not files:
373
+ status_message = " Keine Dateien zum Hochladen! "
374
+ else:
375
+ for file in files:
376
+ try:
377
+ # Extrahieren des Dateinamens aus dem vollen Pfad
378
+ filename = os.path.basename(file.name)
379
+
380
+ # Extrahieren der Dateiendung
381
+ file_extension = os.path.splitext(filename)[1]
382
+ # Bestimmen des Upload-Pfads basierend auf der Dateiendung
383
+ if file_extension == ".pdf":
384
+ upload_path = f"chroma/kkg/pdf/{filename}"
385
+ elif file_extension == ".docx":
386
+ upload_path = f"chroma/kkg/word/{filename}"
387
+ else:
388
+ upload_path = f"chroma/kkg/{filename}"
389
+
390
+ # Entfernen der vorhandenen Datei, falls sie existiert
391
+ if os.path.exists(upload_path):
392
+ os.remove(upload_path)
393
+
394
+ # Datei zum Hugging Face Space hochladen
395
+ upload_file_to_huggingface(file.name, upload_path)
396
+
397
+ except Exception as e:
398
+ logging.error(f"Error uploading file {file.name}: {e}")
399
+ status_message = "Nicht alle Dateien konnten hochgeladen werden... "
400
+
401
+ status_message = "Hochladen der Dateien abgeschlossen! "
402
+
403
+ return gr.Textbox(label="Status", visible = True), display_files(), status_message
404
+
405
+ # Nachdem alle Dateien hochgeladen wurden, den Vektorstore neu laden
406
+ def update_vectorstore(status):
407
+ try:
408
+ ############################################
409
+ #Vektorstore neu....
410
+ ############################################
411
+ create_vectorstore()
412
+ message = status + "Vektorstore wurde erneuert!"
413
+ return message, message
414
+ except Exception as e:
415
+ message = status + "Fehler beim Erneuern des Vektorstores!"
416
+ return message, message
417
+
418
+ #File Input automatisch nach upload Prozess resetten
419
+ def reset_file_input():
420
+ # Zurücksetzen des file inputs
421
+ return gr.update(value=None)
422
+
423
+ # Für die Sttus Anzeige während und Nach File Upload und Vektordatenbank aktualisierung
424
+ def show_success():
425
+ return gr.Info( "System erfolgreich aktualisiert!")
426
+
427
+ def hide_status():
428
+ return gr.HTML(value="", label="Status", visible=False) #gr.Textbox( visible = False)
429
+
430
+ def show_status():
431
+ return gr.HTML(value="", label="Status", visible=True) ##gr.Textbox( label="Status", visible = True)
432
+
433
+ def show_text_status(status):
434
+ ausgabe = f"<div style='color: rgb(82, 255, 51) !important; text-align: center; font-size: 20px;'><b>{status}</b></div>" #style='color: red !important; text-align: center; font-size: 20px;'
435
+ return gr.HTML(value=ausgabe, label="Status", visible=True), ""
436
+
437
+
438
+ ########################################
439
+ # Bot- test gegen schädliche Bots die die Anwendung testen...
440
+ # Funktion zur Überprüfung der Benutzereingabe
441
+ # Funktion zur Überprüfung der Eingabe und Aktivierung der Hauptanwendung
442
+ def validate_input(user_input_validate, validate=False):
443
+ user_input_hashed = hash_input(user_input_validate)
444
+ if user_input_hashed == hash_input(ANTI_BOT_PW):
445
+ return "Richtig! Weiter gehts... ", True, gr.Textbox(visible=False), gr.Button(visible=False)
446
+ else:
447
+ return "Falsche Antwort!!!!!!!!!", False, gr.Textbox(label = "", placeholder="Bitte tippen Sie das oben im Moodle Kurs angegebene Wort ein, um zu beweisen, dass Sie kein Bot sind.", visible=True, scale= 5), gr.Button("Validieren", visible = True)
448
+ """
449
+ def custom_css():
450
+ return
451
+ #status_system_update {
452
+ color: red !important;
453
+ text-align: center;
454
+ font-size: 20px;
455
+ }
456
+ """
457
+
458
+ #############################################################################################
459
+ # Start Gui Vorabfrage
460
+ # Validierungs-Interface - Bots weghalten...
461
+ #################################################################################################
462
+ print ("Start GUI Hauptanwendung")
463
+ with open("custom.css", "r", encoding="utf-8") as f:
464
+ customCSS = f.read()
465
+
466
+ #Add Inputs für Tab 2
467
+ additional_inputs = [
468
+ gr.Slider(label="Temperature", value=0.65, minimum=0.0, maximum=1.0, step=0.05, interactive=True, info="Höhere Werte erzeugen diversere Antworten", visible=True),
469
+ gr.Slider(label="Max new tokens", value=1024, minimum=0, maximum=4096, step=64, interactive=True, info="Maximale Anzahl neuer Tokens", visible=True),
470
+ gr.Slider(label="Top-p (nucleus sampling)", value=0.6, minimum=0.0, maximum=1, step=0.05, interactive=True, info="Höhere Werte verwenden auch Tokens mit niedrigerer Wahrscheinlichkeit.", visible=True),
471
+ gr.Slider(label="Repetition penalty", value=1.2, minimum=1.0, maximum=2.0, step=0.05, interactive=True, info="Strafe für wiederholte Tokens", visible=True)
472
+ ]
473
+ with gr.Blocks(css=customCSS, theme=themeAlex) as demo:
474
+ #validiert speichern
475
+ validate = gr.State(True)
476
+ #Session Variablen, um Weete zu speichern, auch wenn die Felder in der GUI bereits wieder leer sind
477
+ # history parallel zu chatbot speichern - da in chatbot bei Bildern zum Anzeigen in der GUI die Bilder speziell formatiert werden,
478
+ # für die Übergabe an die ki aber der Pfad zum Bild behalten werden muss - was in der history der Fall ist!
479
+ history = gr.State([])
480
+ uploaded_file_paths= gr.State([])
481
+ history3 = gr.State([])
482
+ uploaded_file_paths3= gr.State([])
483
+ #alle chats einer Session sammeln
484
+ chats = gr.State({})
485
+ #damit der Prompt auch nach dem upload in die History noch für predicts_args verfügbar ist
486
+ user_question = gr.State("")
487
+ #für die anderen Tabs auch...
488
+ #damit der Prompt auch nach dem upload in die History noch für predicts_args verfügbar ist
489
+ user_question2 = gr.State("")
490
+ user_question3 = gr.State("")
491
+ attached_file = gr.State(None)
492
+ attached_file_history = gr.State(None)
493
+ attached_file3 = gr.State(None)
494
+ attached_file_history3 = gr.State(None)
495
+
496
+ status_display = gr.State("")
497
+ status_system_update= gr.State("")
498
+ #status_display2 = gr.State("")
499
+ #status_display3 = gr.State("")
500
+ ################################################
501
+ # Tab zum Chatbot mit Text oder Bildeingabe
502
+ ################################################
503
+ gr.Markdown(description_top)
504
+ """
505
+ with gr.Row():
506
+ user_input_validate =gr.Textbox(label= "Bitte das oben im Moodle Kurs angegebene Wort eingeben, um die Anwendung zu starten", visible=True, interactive=True, scale= 7)
507
+ validate_btn = gr.Button("Validieren", visible = True)
508
+ #validation_result = gr.Text(label="Validierungsergebnis")
509
+ """
510
+ with gr.Tab("KKG KI-Suche") as tab1:
511
+ with gr.Row():
512
+ #gr.HTML("LI Chatot")
513
+ status_display = gr.Markdown("Antwort der KI ...", visible = True) #, elem_id="status_display")
514
+ with gr.Row():
515
+ with gr.Column(scale=5):
516
+ with gr.Row():
517
+ chatbot = gr.Chatbot(elem_id="li-chat",show_copy_button=True)
518
+ with gr.Row():
519
+ with gr.Column(scale=12):
520
+ user_input = gr.Textbox(
521
+ show_label=False, placeholder="Gib hier deine Such-Frage ein...",
522
+ container=False
523
+ )
524
+ with gr.Column(min_width=70, scale=1):
525
+ submitBtn = gr.Button("Senden")
526
+ with gr.Column(min_width=70, scale=1):
527
+ cancelBtn = gr.Button("Stop")
528
+ with gr.Row():
529
+ image_display = gr.Image( visible=False)
530
+ upload = gr.UploadButton("📁", file_types=["pdf", "docx", "pptx", "xlsx"], scale = 10, visible = False)
531
+ emptyBtn = gr.ClearButton([user_input, chatbot, history, attached_file, attached_file_history, image_display], value="🧹 Neue Session", scale=10)
532
+
533
+ with gr.Column(visible = False):
534
+ with gr.Column(min_width=50, scale=1):
535
+ with gr.Tab(label="KKG-Suche ..."):
536
+ #Geht nicht, da für alle gleichzeitig sichtbar
537
+ #chat_selector = gr.CheckboxGroup(label="", choices=update_chat_options())
538
+ #download_button = gr.Button("Download ausgewählte Chats")
539
+ file_download = gr.File(label="Noch keine Chatsverläufe", visible=True, interactive = False, file_count="multiple",)
540
+
541
+ with gr.Tab(label="Parameter"):
542
+ #gr.Markdown("# Parameters")
543
+ #rag_option = gr.Radio(["Aus", "An"], label="KKG Erweiterungen (RAG)", value = "Aus")
544
+ model_option = gr.Radio(["HuggingFace"], label="Modellauswahl", value = "HuggingFace")
545
+ #websuche = gr.Radio(["Aus", "An"], label="Web-Suche", value = "Aus")
546
+
547
+
548
+ top_p = gr.Slider(
549
+ minimum=-0,
550
+ maximum=1.0,
551
+ value=0.95,
552
+ step=0.05,
553
+ interactive=True,
554
+ label="Top-p",
555
+ visible=False,
556
+ )
557
+ top_k = gr.Slider(
558
+ minimum=1,
559
+ maximum=100,
560
+ value=35,
561
+ step=1,
562
+ interactive=True,
563
+ label="Top-k",
564
+ visible=False,
565
+ )
566
+ temperature = gr.Slider(
567
+ minimum=0.1,
568
+ maximum=2.0,
569
+ value=0.2,
570
+ step=0.1,
571
+ interactive=True,
572
+ label="Temperature",
573
+ visible=False
574
+ )
575
+ max_length_tokens = gr.Slider(
576
+ minimum=0,
577
+ maximum=512,
578
+ value=512,
579
+ step=8,
580
+ interactive=True,
581
+ label="Max Generation Tokens",
582
+ visible=False,
583
+ )
584
+ max_context_length_tokens = gr.Slider(
585
+ minimum=0,
586
+ maximum=4096,
587
+ value=2048,
588
+ step=128,
589
+ interactive=True,
590
+ label="Max History Tokens",
591
+ visible=False,
592
+ )
593
+ repetition_penalty=gr.Slider(label="Repetition penalty", value=1.2, minimum=1.0, maximum=2.0, step=0.05, interactive=True, info="Strafe für wiederholte Tokens", visible=False)
594
+ anzahl_docs = gr.Slider(label="Anzahl Dokumente", value=3, minimum=1, maximum=10, step=1, interactive=True, info="wie viele Dokumententeile aus dem Vektorstore an den prompt gehängt werden", visible=False)
595
+ openai_key = gr.Textbox(label = "OpenAI API Key", value = "sk-", lines = 1, visible = False)
596
+
597
+
598
+ with gr.Tab("Datei hochladen") as tab2:
599
+ upload_pdf_files = gr.Files(label="PDF- oder Word-Dateien in Zwischenablage", file_count="multiple")
600
+ output_text = gr.HTML(value="", label="Status", elem_id="status") #gr.Textbox(label="Status", visible = False)
601
+ message = gr.Markdown(visible=False, elem_id="popup_message")
602
+ renew_button = gr.Button("Dateien hochladen und System aktualisieren", elem_id="renew_button")
603
+ file_list = gr.HTML(elem_id="file_list", show_label=False)
604
+
605
+
606
+ gr.Markdown(description)
607
+
608
+ ######################################
609
+ # Events und Übergabe Werte an Funktionen
610
+ #######################################
611
+ ######################################
612
+ # Für Tab 1: Chatbot
613
+ #Argumente für generate Funktion als Input
614
+ predict_args = dict(
615
+ fn=generate_auswahl,
616
+ inputs=[
617
+ user_question,
618
+ attached_file,
619
+ attached_file_history,
620
+ chatbot,
621
+ history,
622
+ anzahl_docs,
623
+ top_p,
624
+ temperature,
625
+ max_length_tokens,
626
+ max_context_length_tokens,
627
+ repetition_penalty,
628
+ top_k,
629
+ validate
630
+ ],
631
+ outputs=[chatbot, history, attached_file, attached_file_history, status_display],
632
+ show_progress=True,
633
+ )
634
+
635
+ reset_args = dict(
636
+ fn=reset_textbox, inputs=[], outputs=[user_input, status_display]
637
+ )
638
+
639
+ # Chatbot
640
+ transfer_input_args = dict(
641
+ fn=add_text, inputs=[chatbot, history, user_input, attached_file, attached_file_history], outputs=[chatbot, history, user_question, attached_file, attached_file_history, image_display , user_input], show_progress=True
642
+ )
643
+
644
+ ##############################################
645
+ # Button Events....
646
+ #Validation Button
647
+ # Event-Handler für die Validierung
648
+ #validate_btn.click(validate_input, inputs=[user_input_validate, validate], outputs=[status_display, validate, user_input_validate, validate_btn])
649
+ #user_input_validate.submit(validate_input, inputs=[user_input_validate, validate], outputs=[status_display, validate, user_input_validate, validate_btn])
650
+ #############################################
651
+ #1ter Tab
652
+ predict_event1 = user_input.submit(**transfer_input_args, queue=False,).then(**predict_args)
653
+ predict_event2 = submitBtn.click(**transfer_input_args, queue=False,).then(**predict_args)
654
+ predict_event3 = upload.upload(file_anzeigen, [upload], [image_display, image_display, attached_file] ) #.then(**predict_args)
655
+ emptyBtn.click(clear_all, [history, uploaded_file_paths, chats], [attached_file, image_display, uploaded_file_paths, history, file_download, chats])
656
+ #Bild Anzeige neben dem Button wieder entfernen oder austauschen..
657
+ image_display.select(file_loeschen, [], [attached_file, image_display])
658
+ #Berechnung oder Ausgabe anhalten (kann danach fortgesetzt werden)
659
+ cancelBtn.click(cancel_outputing, [], [status_display], cancels=[predict_event1,predict_event2, predict_event3])
660
+ ############################################
661
+ #2ter Tab
662
+ #renew_button.click(fn=upload_pdf, inputs=upload_pdf_files, outputs=[output_text, file_list])
663
+ # Hochladen der Dateien und dann Vektorstore aktualisieren
664
+ renew_button.click(fn=upload_pdf, inputs=[upload_pdf_files], outputs=[output_text, file_list, status_system_update]).then(
665
+ fn=update_vectorstore, inputs=status_system_update, outputs=[output_text, status_system_update]).then(
666
+ fn=reset_file_input, inputs=None, outputs=[upload_pdf_files]).then(fn=show_text_status, inputs=status_system_update, outputs=[output_text, status_system_update]) #.then(fn=hide_status, inputs=None, outputs=output_text, show_progress="hidden")
667
+ demo.load(display_files, outputs=file_list)
668
+
669
+ demo.title = "KKG-Suche"
670
+ demo.queue(default_concurrency_limit=15).launch(debug=True)