import streamlit as st from langchain.embeddings import HuggingFaceInstructEmbeddings from langchain.vectorstores import FAISS from langchain.text_splitter import CharacterTextSplitter from langchain.document_loaders import DirectoryLoader, PyPDFLoader import os from PyPDF2 import PdfReader from langchain.chains import RetrievalQAWithSourcesChain from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationalRetrievalChain #from htmlTemplates import css, bot_template, user_template from langchain.llms import HuggingFaceHub from dotenv import load_dotenv from transformers import pipeline from sentence_transformers import SentenceTransformer, util ########### #pip install faiss-cpu #pip install langchain #pip install pypdf #pip tiktoken #pip install InstructorEmbedding ############### def check_question(user_question): if len(user_question) < 10: # Beispielkriterium für minimale Länge return False return True # PDF in String umwandeln def get_pdf_text(folder_path): text = "" # Durchsuche alle Dateien im angegebenen Verzeichnis for filename in os.listdir(folder_path): filepath = os.path.join(folder_path, filename) # Überprüfe, ob die Datei die Erweiterung ".pdf" hat if os.path.isfile(filepath) and filename.lower().endswith(".pdf"): pdf_reader = PdfReader(filepath) for page in pdf_reader.pages: text += page.extract_text() #text += '\n' return text #Chunks erstellen def get_text_chunks(text): #Arbeitsweise Textsplitter definieren text_splitter = CharacterTextSplitter( separator="\n", chunk_size=1000, chunk_overlap=200, length_function=len ) chunks = text_splitter.split_text(text) return chunks # nur zum Anlegen des lokalen Verzeichnisses "Store" und speichern der Vektor-Datenbank def create_vectorstore_and_store(text_chunks): embeddings = HuggingFaceInstructEmbeddings(model_name="hkunlp/instructor-base") # Initiate Faiss DB vectorstoreDB = FAISS.from_texts(texts=text_chunks,embedding=embeddings)#texts=text_chunks, ### ### --> danach soll das PDF-Verzeichnis gelöscht werden, bzw. Datein verschieben, weil beim nächsten Upload ### # Verzeichnis in dem die VektorDB gespeichert werden soll save_directory = "Store" #VektorDB lokal speichern vectorstoreDB.save_local(save_directory) print(vectorstoreDB) return None ######## def get_vectorstore(): embeddings = HuggingFaceInstructEmbeddings(model_name="hkunlp/instructor-base") #Abruf lokaler Vektordatenbank save_directory = "Store" vectorstoreDB = FAISS.load_local(save_directory, embeddings) return vectorstoreDB def calculate_similarity(user_question, pdf_text): model = SentenceTransformer('paraphrase-distilroberta-base-v1') # Verwende ein vortrainiertes Modell encoded_pdf = model.encode(pdf_text, convert_to_tensor=True) encoded_question = model.encode(user_question, convert_to_tensor=True) # Berechne die Ähnlichkeit zwischen der Frage und den PDF-Inhalten similarity_scores = util.pytorch_cos_sim(encoded_question, encoded_pdf) max_similarity = max(similarity_scores[0]) return max_similarity.item() def main(): load_dotenv() user_question = st.text_area("Eingabe:") if not check_question(user_question): st.error("Die Frage ist zu ungenau. Bitte präzisiere deine Frage.") return folder_path = './PDFs' pdf_text = get_pdf_text(folder_path) text_chunks = get_text_chunks(pdf_text) create_vectorstore_and_store(text_chunks) similarity_score = calculate_similarity(user_question, pdf_text) # Nutze similarity_score zur Bewertung der Relevanz der Frage für die PDF-Inhalte relevance_threshold = 0.3 # Beispielwert, anpassen nach Bedarf st.write("Ähnlichkeit der Frage mit den PDF-Inhalten:", similarity_score) if similarity_score >= relevance_threshold: st.success("Die Frage ist relevant für die PDF-Inhalte.") # Führe die weitere Verarbeitung durch retriever = get_vectorstore().as_retriever() retrieved_docs = retriever.invoke(user_question) if user_question: st.text(retrieved_docs[0].page_content) # bei eingehendem PDF else: st.error("Die Frage ist nicht ausreichend relevant für die PDF-Inhalte. Bitte eine präzisere Frage stellen.") if __name__ == '__main__': main()