vivekmehta27's picture
Download PDF from Hugging Face Dataset
c50eeb0
Raw
History Blame Contribute Delete
6.73 kB
import requests
import sys
import transformers
import sentence_transformers
import os
from dotenv import load_dotenv
load_dotenv()
# Suppress warnings
def warn(*args, **kwargs):
pass
import warnings
warnings.warn = warn
warnings.filterwarnings("ignore")
# Document loading
from langchain_community.document_loaders import PyMuPDFLoader
# Text splitting
from langchain_text_splitters import RecursiveCharacterTextSplitter
# Vector store
from langchain_community.vectorstores import Chroma
# Embeddings
from langchain_huggingface import HuggingFaceEmbeddings
#loader = PyMuPDFLoader("FAQ_NEW.pdf")
PDF_NAME = "FAQ_NEW.pdf"
PDF_URL = "https://huggingface.co/datasets/vivekmehta27/btech-rag-data/resolve/main/FAQ_NEW.pdf"
if not os.path.exists(PDF_NAME):
print("Downloading PDF...")
response = requests.get(PDF_URL)
response.raise_for_status()
with open(PDF_NAME, "wb") as f:
f.write(response.content)
print("Download completed.")
loader = PyMuPDFLoader(PDF_NAME)
documents = loader.load()
print(documents[0].page_content)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=100
)
texts = text_splitter.split_documents(documents)
print("Number of chunks:", len(texts))
#print("\nFirst chunk:\n")
#print(texts[0].page_content[:500])
for i, chunk in enumerate(texts[:5]):
print(f"\n{'='*50}")
print(f"CHUNK {i+1}")
print(f"{'='*50}")
print(chunk.page_content)
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
docsearch = Chroma.from_documents(
documents=texts,
embedding=embeddings
)
print("Document ingestion completed.")
print("Number of chunks stored:", len(texts))
"""## LLM model construction
"""
from langchain_nvidia_ai_endpoints import ChatNVIDIA
print("API Key:", os.getenv("NVIDIA_API_KEY"))
llm = ChatNVIDIA(
model="meta/llama-3.1-8b-instruct",
api_key=os.getenv("NVIDIA_API_KEY"),
temperature=0.2,
top_p=0.7,
max_tokens=1024,
)
# User's question
query = " if a student has backlog in one VAC course like design thinking here for example, then by choosing some other VAC course in this list will his /her requirement of 3 vac courses still be considered as in can one vac course replace the other then?"
# Retrieve the top 3 most relevant chunks from the vector database
docs = docsearch.similarity_search(query, k=3)
# Display the retrieved chunks
for i, doc in enumerate(docs):
# Print chunk number
print(f"\n{'='*60}")
print(f"RETRIEVED CHUNK {i+1}")
print(f"{'='*60}")
# Print chunk content
print(doc.page_content)
# Print metadata (source document information)
print("\nMetadata:", doc.metadata)
"""## The next step is Augmentation (constructing the prompt) and then Generation (sending it to the LLM).
## Build Context from Retrieved Chunks
"""
# Combine the retrieved chunks into a single context
context = "\n\n".join([doc.page_content for doc in docs])
print("Context Length:", len(context))
print("\nContext Sent to LLM:\n")
print(context)
"""# Create the Prompt"""
# Construct the RAG prompt
prompt = f"""
You are a helpful assistant.
Answer the question using only the provided context.
Context:
{context}
Question:
{query}
Answer:
"""
print(prompt)
"""# Invoke the LLM"""
# Generate answer using the LLM
response = llm.invoke(prompt)
print(response.content)
"""### RAG summary
### Stage 1: Retrieval
docs = docsearch.similarity_search(query, k=3)
### Stage 2: Augmentation
context = "\n\n".join([doc.page_content for doc in docs])
### Stage 3: Generation
prompt = f'''
Answer the question using only the context below.
Context:
{context}
Question:
{query}
Answer:
'''
response = llm.invoke(prompt)
print(response.content)
# chatbot with memory
"""
class RAGChatbot:
"""
A simple RAG chatbot with conversation memory.
"""
def __init__(self, llm, vector_db, k=3):
"""
Initialize the chatbot.
Parameters:
llm : Language model object
vector_db : Chroma vector database
k : Number of chunks to retrieve
"""
self.llm = llm
self.vector_db = vector_db
self.k = k
self.chat_history = []
def ask(self, query):
"""
Ask a question to the chatbot.
"""
# Retrieve relevant chunks
docs = self.vector_db.similarity_search(
query,
k=self.k
)
# Combine retrieved chunks into a context
context = "\n\n".join(
[doc.page_content for doc in docs]
)
# Convert chat history into text
history_text = "\n".join(
[
f"User: {q}\nAssistant: {a}"
for q, a in self.chat_history
]
)
# Create RAG prompt
prompt = f"""
You are a helpful assistant.
Previous Conversation:
{history_text}
Context:
{context}
Current Question:
{query}
Answer:
"""
# Generate response
response = self.llm.invoke(prompt)
answer = response.content
# Update memory
self.chat_history.append(
(query, answer)
)
return answer
def show_history(self):
"""
Display conversation history.
"""
for i, (q, a) in enumerate(self.chat_history, start=1):
print(f"\nConversation {i}")
print(f"User : {q}")
print(f"Assistant : {a}")
def clear_history(self):
"""
Clear chatbot memory.
"""
self.chat_history = []
print("Conversation history cleared.")
chatbot = RAGChatbot(
llm=llm,
vector_db=docsearch,
k=3
)
chatbot.ask(
" if that student has backlog in one VAC course like design thinking here for example, then by choosing some other VAC course in this list will his /her requirement of 3 vac courses still be considered as in can one vac course replace the other then?"
)
chatbot.ask(
"Can employees use personal devices?"
)
chatbot.ask(
"Summarize the policy in three points."
)
"""# Creating a GUI with gradio"""
# Commented out IPython magic to ensure Python compatibility.
# %%capture
# !{sys.executable} -m pip install -U gradio
import gradio as gr
# Function that Gradio will call
def chat_with_rag(message, history):
response = chatbot.ask(message)
return response
# Create interface
demo = gr.ChatInterface(
fn=chat_with_rag,
title="Btech Policy RAG Chatbot",
description="Ask questions about Btech regulations."
)
if __name__ == "__main__":
demo.launch()