Spaces:
Sleeping
Sleeping
File size: 6,059 Bytes
ec9e166 3579388 0fe1d37 ec9e166 142ca34 4ae7ab5 ec9e166 4ae7ab5 ec9e166 4ae7ab5 ec9e166 142ca34 ec9e166 4ae7ab5 142ca34 ec9e166 1dd7d51 ec9e166 17388c4 a5ca45a ec9e166 e370bd9 ec9e166 e370bd9 ec9e166 0fe1d37 ec9e166 9cdcee6 ec9e166 de0dbd9 ceb03e2 1c55637 ceb03e2 16a13e4 ceb03e2 de0dbd9 ec9e166 4ae7ab5 ec9e166 4ae7ab5 ec9e166 e5228b1 ec9e166 683ac4d ec9e166 |
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 |
"""
Question Answering with Retrieval QA and LangChain Language Models featuring FAISS vector stores.
This script uses the LangChain Language Model API to answer questions using Retrieval QA
and FAISS vector stores. It also uses the Mistral huggingface inference endpoint to
generate responses.
"""
import os
import streamlit as st
from dotenv import load_dotenv
from PyPDF2 import PdfReader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import UnstructuredPDFLoader
from langchain.embeddings import HuggingFaceBgeEmbeddings
from langchain.vectorstores import FAISS
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from htmlTemplates import css, bot_template, user_template
from langchain.llms import HuggingFaceHub
def get_pdf_text(pdf_docs):
"""
Extract text from a list of PDF documents.
Parameters
----------
pdf_docs : list
List of PDF documents to extract text from.
Returns
-------
str
Extracted text from all the PDF documents.
"""
text = ""
for pdf in pdf_docs:
pdf_loader = UnstructuredPDFLoader(pdf)
pdf_pages = pdf_loader.load_and_split()
for page in pdf_pages:
text += page.extract_text()
return text
def get_text_chunks(text):
"""
Split the input text into chunks.
Parameters
----------
text : str
The input text to be split.
Returns
-------
list
List of text chunks.
"""
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1024, chunk_overlap=64
)
texts = text_splitter.split_text(text)
return texts
def get_vectorstore(text_chunks):
"""
Generate a vector store from a list of text chunks using HuggingFace BgeEmbeddings.
Parameters
----------
text_chunks : list
List of text chunks to be embedded.
Returns
-------
FAISS
A FAISS vector store containing the embeddings of the text chunks.
"""
model = "sentence-transformers/all-mpnet-base-v2"
encode_kwargs = {
"normalize_embeddings": True
} # set True to compute cosine similarity
embeddings = HuggingFaceBgeEmbeddings(
model_name=model, encode_kwargs=encode_kwargs, model_kwargs={"device": "cpu"}
)
vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embeddings)
return vectorstore
def get_conversation_chain(vectorstore):
"""
Create a conversational retrieval chain using a vector store and a language model.
Parameters
----------
vectorstore : FAISS
A FAISS vector store containing the embeddings of the text chunks.
Returns
-------
ConversationalRetrievalChain
A conversational retrieval chain for generating responses.
"""
llm = HuggingFaceHub(
repo_id="mistralai/Mixtral-8x7B-Instruct-v0.1",
model_kwargs={"temperature": 0.5, "max_length": 1048},
)
# llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
conversation_chain = ConversationalRetrievalChain.from_llm(
llm=llm, retriever=vectorstore.as_retriever(), memory=memory
)
return conversation_chain
def handle_userinput(user_question):
"""
Handle user input and generate a response using the conversational retrieval chain.
Parameters
----------
user_question : str
The user's question.
"""
response = st.session_state.conversation({"question": user_question})
st.session_state.chat_history = response["chat_history"]
for i, message in enumerate(st.session_state.chat_history):
if i % 2 == 0:
st.write("//_^ User: " + message.content)
else:
st.write("🤖 ChatBot: " + message.content)
def main():
"""
Putting it all together.
"""
st.set_page_config(
page_title="Chat with a Bot that tries to answer questions about multiple PDFs",
page_icon=":books:",
)
st.markdown("# Chat with a Bot")
st.markdown("This bot tries to answer questions about multiple PDFs. Let the processing of the PDF finish before adding your question. 🙏🏾")
st.write(css, unsafe_allow_html=True)
# set huggingface hub token in st.text_input widget
# then hide the input
huggingface_token = st.text_input("Enter your HuggingFace Hub token", type="password", value="DNTClESFouRJbgsoxTzdLFzYfIlGSVsWvM")
#openai_api_key = st.text_input("Enter your OpenAI API key", type="password")
if not huggingface_token.startswith("hf_"):
huggingface_token = "hf_" + huggingface_token
# set this key as an environment variable
os.environ["HUGGINGFACEHUB_API_TOKEN"] = huggingface_token
#os.environ["OPENAI_API_KEY"] = openai_api_key
if "chat_history" not in st.session_state:
st.session_state.chat_history = None
with st.sidebar:
st.subheader("Your documents")
pdf_docs = st.file_uploader(
"Upload your PDFs here and click on 'Process'", accept_multiple_files=True
)
if st.button("Process"):
with st.spinner("Processing"):
# get the raw text
text = get_pdf_text(pdf_docs)
# get the text chunks
text_chunks = get_text_chunks(text)
# create vector store
vectorstore = get_vectorstore(text_chunks)
# create conversation chain
st.session_state.conversation = get_conversation_chain(vectorstore)
print(st.session_state.conversation)
st.header("Chat with a Bot 🤖🦾 that tries to answer questions about multiple PDFs :books:")
user_question = st.text_input("Ask a question about your documents:")
if user_question:
handle_userinput(user_question)
if __name__ == "__main__":
main()
|