From ea83ea6a3e0806f29781abca4503efc8fa494215 Mon Sep 17 00:00:00 2001 From: marioggil Date: Sun, 24 Sep 2023 00:37:33 -0500 Subject: [PATCH] add logo plus, filtred and refactoring --- FindinDB.py | 136 ++++++++++++++++++++++++++++++++-------------------- logo.jpg | Bin 0 -> 14394 bytes 2 files changed, 85 insertions(+), 51 deletions(-) create mode 100644 logo.jpg diff --git a/FindinDB.py b/FindinDB.py index 67eb0e6..9811710 100644 --- a/FindinDB.py +++ b/FindinDB.py @@ -17,80 +17,114 @@ from langchain.embeddings import GPT4AllEmbeddings from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler from langchain.callbacks.base import BaseCallbackManager from langchain.document_loaders import DataFrameLoader +from langchain.embeddings import HuggingFaceEmbeddings import pandas as pd import sqlite3 +from sentence_transformers import SentenceTransformer +#from cleantext import clean +import re +model_name = 'hiiamsid/sentence_similarity_spanish_es' +model_kwargs = {'device': 'cpu'} +encode_kwargs = {'normalize_embeddings': True} +hf = HuggingFaceEmbeddings( + model_name=model_name, + model_kwargs=model_kwargs, + encode_kwargs=encode_kwargs +) + + def loadModels(): #model = GPT4All("orca-mini-3b.ggmlv3.q4_0.bin") callback_manager = BaseCallbackManager([StreamingStdOutCallbackHandler()]) llm = GPT4All(model="orca-mini-3b.ggmlv3.q4_0.bin",temp=0.1,streaming=True)#callback_manager=callback_manager, verbose=True,repeat_last_n=0 embeddings = GPT4AllEmbeddings() return llm, embeddings + + +def loadCopysAndData(pathsqlite="motor.sqlite"): + con = sqlite3.connect(pathsqlite) + copies_df = pd.read_sql_query("SELECT * from copies", con) + copiesT = copies_df[copies_df.copy_start =="T"] + copiesT=copiesT[["copy_message","id","name"]] + data = copiesT + B=DataFrameLoader(data,page_content_column="copy_message") + B2=DataFrameLoader(data,page_content_column="name") + documents=B.load() + documents2=B2.load() + return documents,documents2 + +def makeFaissdb(documents,folder_path,embedding): + try: + db=FAISS.load_local(folder_path=folder_path,embeddings=embedding) + + except: + db = FAISS.from_documents(documents, embedding) + FAISS.save_local(db,folder_path=folder_path) + return db + llm,emb=loadModels() +documents,documents2=loadCopysAndData() +db=makeFaissdb(documents,"Copies",emb) +db2=makeFaissdb(documents2,"names",emb) +db3=makeFaissdb(documents2,"nameshf",hf) -con = sqlite3.connect("motor.sqlite") -copies_df = pd.read_sql_query("SELECT * from copies", con) -copiesT = copies_df[copies_df.copy_start =="T"] -copiesT=copiesT[["copy_message","id","name"]] -data = copiesT -B=DataFrameLoader(data,page_content_column="copy_message") -B2=DataFrameLoader(data,page_content_column="name") -documents=B.load() -documents2=B2.load() - -try: - db=FAISS.load_local(folder_path="Copies",embeddings=emb) - -except: - db = FAISS.from_documents(documents, emb) - FAISS.save_local(db,folder_path="Copies") - -try: - db2=FAISS.load_local(folder_path="names",embeddings=emb) - -except: - db2 = FAISS.from_documents(documents2, emb) - FAISS.save_local(db2,folder_path="names") - -def FinderDb(query,dbs): - Sal = dbs.similarity_search_with_score(query,3) - page_content=[] - id=[] - d=[] - for output in Sal: - page_content.append(output[0].page_content) - id.append(output[0].metadata["id"]) - d.append(output[1]) - espacio=""" - - -######################## +def FinderDbs(query,dbs,filtred=False,th=1.2): + AllData={} + for dbt in dbs: + Sal = dbt.similarity_search_with_score(query,4) + for output in Sal: + if output[0].metadata["id"] in AllData.keys(): + AllData[output[0].metadata["id"]]["d"]=min([AllData[output[0].metadata["id"]]["d"]-0.1,output[1]-0.1]) + else: + AllData[output[0].metadata["id"]]={"d":output[1],"page_content":output[0].page_content} + for item in AllData.items(): + print(item) + if filtred: + filtredData={} + for row in AllData.keys(): + if AllData[row]["d"]<1.2: + filtredData[row]=AllData[row] + filtredData=dict(sorted(filtredData.items(), key=lambda item: item[1]["d"])) + return filtredData,filtredData.keys() -""" - page_content=espacio.join(page_content) - return page_content,d,id + else: + AllData=dict(sorted(AllData.items(), key=lambda item: item[1]["d"])) + return AllData,AllData.keys() -def QARequest(Pregunta): +def QARequest(Pregunta,filtred=False): query = Pregunta - page_content,d,id=FinderDb(query,db) - page_content2,d2,id2=FinderDb(query,db2) - return page_content,d,id,page_content2,d2,id2 + AllData=FinderDbs(query,[db,db2],filtred) + return AllData with gr.Blocks() as demo: + gr.Image("logo.jpg",height=100) + gr.Markdown("Esta es la busqueda que hace el usuario") Pregunta = gr.Textbox(label="Pregunta") - #Respuesta = gr.Textbox(label="Respuesta") - #id = gr.Textbox(label="id") - #metrica=gr.Textbox(label="metrica") - Respuesta2 = gr.Textbox(label="Respuesta2") - id2 = gr.Textbox(label="id2") - metrica2=gr.Textbox(label="metrica2") + #Pregunta = re.sub(r"(@\[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)|^rt|http.+?", "", Pregunta) + #Pregunta=Pregunta.strip().lower() + + filtred=gr.Checkbox(label="filtrado") + + gr.Markdown("Respuestas para orca desde los copys") + Respuesta = gr.Textbox(label="Respuesta") + id = gr.Textbox(label="id") + # metrica=gr.Textbox(label="metrica") + # gr.Markdown("Respuestas para orca desde los names") + # Respuesta2 = gr.Textbox(label="Respuesta2") + # id2 = gr.Textbox(label="id2") + # metrica2=gr.Textbox(label="metrica2") + # gr.Markdown("Respuestas para hf desde los names") + # Respuesta3 = gr.Textbox(label="Respuesta3") + # id3 = gr.Textbox(label="id3") + # metrica3=gr.Textbox(label="metrica3") Enviar_btn = gr.Button("Responder") - Enviar_btn.click(fn=QARequest, inputs=Pregunta, outputs=[Respuesta2,metrica2,id2], api_name="Respuestas") # Respuesta,metrica,id, + Enviar_btn.click(fn=QARequest, inputs=[Pregunta,filtred], outputs=[Respuesta,id], api_name="Angela") # demo.launch() # diff --git a/logo.jpg b/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1043589c0686372369b433474ac09b1a7d8d06d0 GIT binary patch literal 14394 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 T0bJ+vWD4@l3n1(QxLEjKWJSim literal 0 HcmV?d00001