Se corrigio el problema que mantenia el archivo entre sesiones implementando la session_state de streamlit y un mejor manejo de la cache

This commit is contained in:
mongar 2024-05-04 11:35:04 -05:00
parent 0b593e29d4
commit a691ebd109
30 changed files with 8635 additions and 68 deletions

18
app.py
View File

@ -64,10 +64,14 @@ if pdf_name:
# Creamos la cadena que integra Vectorstroe, el LLM para hacer consultas.
# Para este caso la cadena tene el parametro de memoria.
qa = langChainTools.define_retrieval_qa_memory(
llm, docstorage, pdf_name, embedding_model
if "qa" not in st.session_state.keys():
st.session_state.qa = langChainTools.define_retrieval_qa_memory(
llm, pdf_name, embedding_model
)
# qa = langChainTools.define_retrieval_qa_memory(llm, pdf_name, embedding_model)
# Store conversation history
if "messages" not in st.session_state.keys():
st.session_state.messages = [
@ -110,13 +114,15 @@ if pdf_name:
with st.spinner("Thinking..."):
# Creamos la cadena que integra Vectorstroe, el LLM para hacer consultas.
# Para este caso la cadena tene el parametro de memoria.
qa = langChainTools.define_retrieval_qa_memory(
llm, docstorage, pdf_name, embedding_model
)
# qa = langChainTools.define_retrieval_qa_memory(
# llm, docstorage, pdf_name, embedding_model
# )
input = "\n".join([msg["content"] for msg in st.session_state.messages])
query = qa.invoke({"question": f"{prompt}"}, return_only_outputs=True)
query = st.session_state.qa.invoke(
{"question": f"{prompt}"}, return_only_outputs=True
)
response_text = query["answer"]
documents_source = query["source_documents"]

View File

@ -7,7 +7,7 @@ from streamlit_extras.add_vertical_space import add_vertical_space
from langchain_tools.pdf_tools import PdfLangChain
from langchain_tools.lc_tools import LangChainTools
from chats.chat_tools import MessageManager
from langchain_community.llms import HuggingFaceEndpoint
from langchain_community.llms import Ollama
# App title
@ -52,13 +52,22 @@ if pdf_name:
# Cargamos el modelo de embeddings
embedding_model = langChainTools.load_embedding_opnai()
# Cargamos el modelo de embeddings
# embedding_model = langChainTools.load_embedding_hf()
# Creamos el vector store
docstorage = langChainTools.create_vector_strore(
docs_split, pdf_name, embedding_model
)
# Cargamos el modelo LLM desde LangChain
llm = langChainTools.load_llm_open_source()
# llm = langChainTools.load_llm_open_source()
# Cargamos el modelo LLM desde LangChain
llm = langChainTools.load_llm_openai()
# Cargamos el modelo desde Ollama
# llm = Ollama(model="gemma")
# Creamos la cadena que integra Vectorstroe, el LLM para hacer consultas.
# Para este caso la cadena tene el parametro de memoria.
@ -116,7 +125,7 @@ if pdf_name:
query = qa.invoke({"question": f"{prompt}"}, return_only_outputs=True)
response_text_en = query["answer"]
response_text = query["answer"]
documents_source = query["source_documents"]
messageManager = MessageManager()
@ -125,10 +134,10 @@ if pdf_name:
# st.markdown(citation)
with st.chat_message("assistant"):
st.write(response_text_en)
# st.write(translation)
st.write(response_text)
st.session_state.messages.append(
{"role": "assistant", "content": response_text_en}
{"role": "assistant", "content": response_text}
)
expander = st.expander("Fuentes")
expander.markdown(citation)

View File

@ -1,33 +1,48 @@
import streamlit as st
import os
# @st.cache_data
def import_file() -> str:
List_of_files: list = []
# Cargar el archivo pdf
archivo = st.file_uploader(
'Arrastra o ingresa tu archivo .pdf', type=['.pdf'])
nombre_archivo: str = ''
archivo = st.file_uploader("Arrastra o ingresa tu archivo .pdf", type=[".pdf"])
nombre_archivo: str = ""
# Verificar si se ha cargado un archivo
if archivo is not None:
nombre_archivo = archivo.name
# Abrir un archivo en modo escritura binaria ('wb') para guardar el archivo de audio
with open(f'documents/pdfs/{nombre_archivo}', 'wb') as new_file:
# Agregamos el nombre a la lista de archvios para luego podr verificarlos
List_of_files.append(nombre_archivo)
st.success(
f"El numero de archivos en la lista de archivos es de: {len(List_of_files)}"
)
# Abrir un archivo en modo escritura binaria ('wb') para guardar el archivo de audio
with open(f"documents/pdfs/{nombre_archivo}", "wb") as new_file:
# Leer los datos del archivo cargado y escribirlos en el nuevo archivo
new_file.write(archivo.read())
st.success(f"Se carga el archivo con nombre: {nombre_archivo}")
# Verificamos que en la lista solo haya un archivo, de lo contrario, limpiamos la session_state
if (
"archivo_anterior" in st.session_state
and st.session_state.archivo_anterior != nombre_archivo
):
st.session_state.clear()
st.session_state.archivo_anterior = nombre_archivo
return nombre_archivo
# Define la función para borrar el caché
def clear_cache():
cache_path = os.path.join(st.__path__[0], 'static', 'cache')
cache_path = os.path.join(st.__path__[0], "static", "cache")
for root, dirs, files in os.walk(cache_path):
for file in files:
os.remove(os.path.join(root, file))
st.success('Cache limpio exitosamente.')
st.success("Cache limpio exitosamente.")

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,6 @@ from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_community.llms import OpenAI
from langchain_community.chat_models import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain.memory.buffer import ConversationBufferMemory
import os
import streamlit as st
@ -10,6 +9,7 @@ from dotenv import load_dotenv
from langchain.chains import RetrievalQAWithSourcesChain, ConversationalRetrievalChain
from langchain_community.llms import HuggingFaceEndpoint
from langchain_community.embeddings import HuggingFaceEmbeddings
from streamlit.runtime.state import session_state
class LangChainTools:
@ -55,7 +55,7 @@ class LangChainTools:
return self.embedding_model
@st.cache_resource
# @st.cache_resource
def create_vector_strore(
_self, _docs_split: list, _file_name: str, _embedding_model
):
@ -66,21 +66,33 @@ class LangChainTools:
_file_name (str): Nombre del documento
"""
db_name = _file_name.replace(".pdf", "").replace(" ", "_").lower()
# db_name = _file_name.replace(".pdf", "").replace(" ", "_").lower()
st.success(_file_name)
if "db_name" not in st.session_state.keys():
st.session_state.db_name = (
_file_name.replace(".pdf", "").replace(" ", "_").lower()
)
# Cargamos el modelo de embeddings
# _embedding_model = self._embedding_model
# Verificamos si existe la vector strore
persist_directory = f"embeddings/{db_name}"
# persist_directory = f"embeddings/{db_name}"
if os.path.exists(persist_directory):
if "persist_director" not in st.session_state.keys():
st.session_state.persist_directory = (
f"embeddings/{st.session_state.db_name}"
)
if os.path.exists(st.session_state.persist_directory):
vectordb = Chroma(
persist_directory=persist_directory, embedding_function=_embedding_model
persist_directory=st.session_state.persist_directory,
embedding_function=_embedding_model,
)
else:
vectordb = Chroma.from_documents(
persist_directory=persist_directory,
persist_directory=st.session_state.persist_directory,
documents=_docs_split,
embedding=_embedding_model,
)
@ -110,7 +122,8 @@ class LangChainTools:
return llm_openai
def load_llm_open_source(self):
@st.cache_resource
def load_llm_open_source(_self):
"""Esta funcion carga un modelo de LLM OpenSource desde HuggingFace
Returns:
@ -137,24 +150,6 @@ class LangChainTools:
return llm
def load_prompt_template(self):
"""Esta funcion construye un prompt template de lanfchain.
Returns:
_type_: Retorno a un prompt template de LangChain.
"""
template = """Responde en español la siguiente pregunta utilizando los documentos proporcionados y citando las fuentes relevantes entre corchetes []:
Pregunta: {question}
Respuesta:"""
prompt_template = PromptTemplate(
template=template, input_variables=["question"]
)
return prompt_template
def define_retrieval_qa(self, _llm, _vectordb, _file_name, _embedding_model):
"""Esta función integra un LLM y una base de datos vectorial en una
chain de LangChain para hacer requerimientos. Este modelo no integra memoria.
@ -193,10 +188,8 @@ class LangChainTools:
return qa
@st.cache_resource
def define_retrieval_qa_memory(
_self, _llm, _vectordb, _file_name, _embedding_model
):
# @st.cache_resource
def define_retrieval_qa_memory(_self, _llm, _file_name, _embedding_model):
"""Esta función integra un LLM y una base de datos vectorial en una
chain de LangChain para hacer requerimientos. Este modelo integra memoria.
@ -213,13 +206,14 @@ class LangChainTools:
y la BDV.
"""
db_name = _file_name.replace(".pdf", "").replace(" ", "_").lower()
# db_name = _file_name.replace(".pdf", "").replace(" ", "_").lower()
# Verificamos si existe la vector strore
persist_directory = f"embeddings/{db_name}"
# persist_directory = f"embeddings/{db_name}"
_vectordb = Chroma(
persist_directory=persist_directory, embedding_function=_embedding_model
persist_directory=st.session_state.persist_directory,
embedding_function=_embedding_model,
)
# Configura la memoria

View File

@ -22,7 +22,7 @@ class PdfLangChain:
"""
self.file_name = file_name
self.file_path = os.path.join('documents', 'pdfs', self.file_name)
self.file_path = os.path.join("documents", "pdfs", self.file_name)
# Verificar si el directorio exist, sino, crearlo
if not os.path.exists(self.file_path):
@ -38,6 +38,8 @@ class PdfLangChain:
loader = PyPDFLoader(_self.file_path)
_self.docs = loader.load()
st.success(f"Se carga el pdf : {_self.file_path}")
return _self.docs
def split_docs(self, data: list) -> list:
@ -54,8 +56,10 @@ class PdfLangChain:
chunk_overlap = 300
splitter = RecursiveCharacterTextSplitter(
chunk_size=chunk_size,
chunk_overlap=chunk_overlap)
chunk_size=chunk_size, chunk_overlap=chunk_overlap
)
self.docs_split = splitter.split_documents(data)
st.success(f"{self.file_path[3][:200]}")
return self.docs_split

8
pruebas.py Normal file
View File

@ -0,0 +1,8 @@
from langchain_community.llms import Ollama
llm = Ollama(model="gemma")
print(llm.invoke("Cual es tu nombre?"))
query = "Cual es el sentido de la vida?"