ramhemanth580's picture
Update app.py
5a94da6 verified
# -*- coding: utf-8 -*-
"""RAG Conversational Chat Application using lanchain, Mistral 7B , Pinecone vector DB
### Step-1: Upload Documents and Load with Langchain Document Loader
- Upload the documents to Google Colab.
- Use Langchain document loader to load the documents.
### Step-2: Perform Chunking
- Perform chunking on the loaded documents.
### Step-3: Initialize LLM and Use Huggingface Embedding Model
- Initialize a Large Language Model (LLM).
- Use the Huggingface Embedding Model to convert the chunks into embeddings.
### Step-4: Initialize Vector Database
- Initialize a Vector Database to store the resulting embeddings.
### Step-5: Upload Embeddings to Vector Database
- Upload the embeddings to the Vector Database.
### Step-6: Create Langchain Conversational Buffer Memory
- Create a Langchain conversational buffer memory.
### Step-7: Create Prompt Template
- Create a prompt template for generating responses.
### Step-8: Use Langchain RetreivalQA
- Use Langchain RetreivalQA for creating the conversational chat.
### Step-9: Create Front End with Streamlit
- Create a front end for the application using Gradio.
### Step-10: Upload Code to GitHub
- Upload the code to a GitHub repository.
### Step-11: Deploy App in Huggingface Spaces
- Deploy the application in Huggingface Spaces.
### Step-12: Create Documentation
- Create documentation for the entire process followed.
"""
# Installing the required libraries
# !pip install langchain
# !pip install pypdf
# !pip install sentence-transformers==2.2.2
# !pip install pinecone-client==2.2.4
# !pip install unstructured
# !pip install "unstructured[pdf]"
# initializing the Huggingface API to access Embeddig models
# from google.colab import userdata
# HUGGINGFACE_API_KEY = userdata.get('Hugging_Face_API_Key')
# HUGGINGFACE_API_KEY=HUGGINGFACE_API_KEY
# Creating a directory to store the data
# from langchain.document_loaders import PyPDFDirectoryLoader
# loader = PyPDFDirectoryLoader("data")
# importing all the required Libraries
from PyPDF2 import PdfReader
from langchain.chains.question_answering import load_qa_chain
from langchain.prompts import PromptTemplate
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
# from langchain.document_loaders import PyPDFDirectoryLoader
# loader = PyPDFDirectoryLoader("data")
# data = loader.load()
# len(data)
import streamlit as st
# Get the Huggingface API token from streamlit secrets
import os
huggingfacehub_api_token = st.secrets["HF_API_TOKEN"]
def get_pdf_text(pdf_docs):
text=""
for pdf in pdf_docs:
pdf_reader= PdfReader(pdf)
for page in pdf_reader.pages:
text+= page.extract_text()
return text
# creating chunking for the above data
def get_text_chunks(text):
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
chunks = text_splitter.split_text(text)
return chunks
# # creating chunking for the above data
# from langchain.text_splitter import RecursiveCharacterTextSplitter
# text_splitter=RecursiveCharacterTextSplitter(chunk_size=200,chunk_overlap=20)
# chunked_data=text_splitter.split_text(data)
# Create Embeddings using Huggingface Embeddings
import sentence_transformers
from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
# Initializing Pinecone
PINECONE_API_KEY=os.environ.get('PINECONE_API_KEY', 'f7384d73-ea97-45ca-abaa-9b14327fd50f')
PINECONE_API_ENV=os.environ.get('PINECONE_API_ENV', 'gcp-starter')
import pinecone
# initialize pinecone
pinecone.init(
api_key=PINECONE_API_KEY, # find at app.pinecone.io
environment=PINECONE_API_ENV # next to api key in console
)
index_name = "pinecone-demo" # put in the name of your pinecone index here
from langchain.vectorstores import Pinecone
# Load the data into pinecone database
def get_vector_store(text_chunks):
#docsearch = Pinecone.from_texts(chunked_data, embeddings, index_name=index_name)
docsearch = Pinecone.from_texts([t for t in text_chunks], embeddings, index_name=index_name)
return docsearch
# query = "How many topics are covered?"
# docs = docsearch.similarity_search(query, k=1)
# docs
from langchain import HuggingFaceHub
llm=HuggingFaceHub(huggingfacehub_api_token=huggingfacehub_api_token,repo_id="mistralai/Mixtral-8x7B-Instruct-v0.1")
# from langchain.chains import RetrievalQA
# # retriever = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=docsearch.as_retriever())
# retriever = docsearch.as_retriever(search_kwargs={"k": 2})
# qa_chain = RetrievalQA.from_chain_type(llm=llm,
# chain_type="stuff",
# retriever=retriever,
# return_source_documents=True)
#question = "What are the Technical Skills to learn for a Promising AI Career?"
#print(qa_chain(question))
## Adding Memory component
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True, max_history_length=5
)
# Chat History
#chat = llm.start_chat(history=[])
# intialize session state for chat history if it doesn't exist
if 'chat_history' not in st.session_state:
st.session_state['chat_history'] = []
def user_input(user_question):
# Load embeddings only once (assuming same model for both)
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
# Pinecone search using the loaded embeddings
docsearch = Pinecone.from_existing_index(index_name, embeddings)
docs = docsearch.similarity_search(user_question)
# Define prompt template
template = """Answer the question as detailed as possible from the provided context, make sure to provide all the details,
if the answer is not available in the provided context just say, "answer is not available in the context", don't provide the wrong answer\n\n
{context}
Donot provide the Context , Provide the Answer only , to the question in the following format
Question: {question}
Helpful Answer:"""
prompt = PromptTemplate(input_variables=["context", "question"], template=template)
#prompt = PromptTemplate(input_variables=["question"], template=template)
# Create retriever and chain using the loaded embeddings
retriever = docsearch.as_retriever()
qa_chain = ConversationalRetrievalChain.from_llm(
llm,
retriever=retriever,
memory=memory
)
# Extract context from retrieved documents (replace with your logic)
# Consider filtering or summarizing retrieved documents
#context = " ".join([doc.get("text", "") for doc in docs[:3]])
context = docs
# Inject prompt into query (alternative approach)
query = f"{template.format(context=context, question=user_question)}\nQuestion: {user_question}"
#query = f"{template.format( question=user_question)}\nQuestion: {user_question}"
response = qa_chain(
{"question": query},
return_only_outputs=True
)
# Display response
#st.write("Reply: ", response["answer"])
Ans = extract_helpful_answer(response)
st.write(Ans)
# Feature to load Chat history
if st.button("Load Chat History"):
# add user query and response to session chat history
st.session_state['chat_history'].append(("you",user_question))
# for chunk in Ans:
# #st.write(chunk.text)
# st.session_state['chat_history'].append(("AI Assistant",chunk))
st.session_state['chat_history'].append(("AI Assistant",Ans))
st.subheader("The chat history is ")
for role,text in st.session_state['chat_history']:
st.write(f"{role}: {text}")
# Feature to load Related Context from the uploaded Documents
if st.button("Load Related Context from Your Document"):
related_context = docs
st.subheader("Related Context from Your Document:")
for doc in related_context:
st.write(f"Document: {doc}")
st.write("\n")
else:
st.warning("Please enter a question before loading related context.")
def extract_helpful_answer(response):
# Split the response by the delimiter "Helpful Answer:"
parts = response["answer"].split("Helpful Answer:")
# If there are two parts (before and after "Helpful Answer:"), return the second part
return parts[2].strip()
def main():
#st.set_page_config("Chat PDF")
st.header("Chat with PDF using Mistral")
user_question = st.text_input("Ask a Question from the PDF Files")
if user_question:
user_input(user_question)
with st.sidebar:
st.title("Menu:")
pdf_docs = st.file_uploader("Upload your PDF Files and Click on the Submit & Process Button", accept_multiple_files=True)
if st.button("Submit & Process"):
with st.spinner("Processing..."):
raw_text = get_pdf_text(pdf_docs)
text_chunks = get_text_chunks(raw_text)
get_vector_store(text_chunks)
st.success("Done")
if __name__ == "__main__":
main()