Spaces:
Sleeping
Sleeping
File size: 7,065 Bytes
7b80f12 | 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 | import gradio as gr
import PyPDF2
import os
from langchain.text_splitter import RecursiveCharacterTextSplitter
from sentence_transformers import SentenceTransformer
from langchain.vectorstores import Chroma
from langchain_community.embeddings import SentenceTransformerEmbeddings
from langchain_groq import ChatGroq
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
# Initialize global variables for RAG components
rag_chain = None
vector_store = None
llm = None
embedding_model = None
embedding_function = None
# Set your Groq API key here - Read from environment variable
# os.environ["GROQ_API_KEY"] = "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" # Removed hardcoded key
groq_api_key = os.environ.get("GROQ_API_KEY")
def build_rag_from_pdf(pdf_path):
"""Builds the RAG chain from an uploaded PDF."""
global rag_chain, vector_store, llm, embedding_model, embedding_function
if not groq_api_key:
error_message = "Groq API key not set. Please set the GROQ_API_KEY environment variable."
print(error_message)
return False, error_message
pdf_text = ""
try:
with open(pdf_path, 'rb') as file:
reader = PyPDF2.PdfReader(file)
for page in reader.pages:
pdf_text += page.extract_text()
print("PDF text extracted successfully.")
except FileNotFoundError:
error_message = f"Error: The file '{pdf_path}' was not found."
print(error_message)
return False, error_message
except Exception as e:
error_message = f"An error occurred during PDF extraction: {e}"
print(error_message)
return False, error_message
if not pdf_text:
error_message = "Extracted text is empty."
print(error_message)
return False, error_message
# Split text into chunks
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
text_chunks = text_splitter.split_text(pdf_text)
print(f"Split PDF text into {len(text_chunks)} chunks.")
if not text_chunks:
error_message = "No text chunks created."
print(error_message)
return False, error_message
# Create embeddings
try:
embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
embeddings = embedding_model.encode(text_chunks)
print(f"Generated embeddings for {len(text_chunks)} text chunks.")
except Exception as e:
error_message = f"An error occurred during embedding generation: {e}"
print(error_message)
return False, error_message
# Set up vector store
try:
embedding_function = SentenceTransformerEmbeddings(model_name='all-MiniLM-L6-v2')
vector_store = Chroma.from_texts(texts=text_chunks, embedding=embedding_function)
print("Chroma vector store created successfully.")
except Exception as e:
error_message = f"An error occurred during vector store creation: {e}"
print(error_message)
return False, error_message
# Initialize LLM
try:
llm = ChatGroq(model_name="openai/gpt-oss-20b", groq_api_key=groq_api_key) # Pass API key
print("Groq language model set up successfully.")
except Exception as e:
error_message = f"An error occurred during LLM setup: {e}"
print(error_message)
return False, error_message
# Build RAG chain
try:
template = """Use the following pieces of context to answer queries about the provided document efficiently. If you don't know the answer, just say that you don't know, don't try to make up an answer.
{context}
Question: {question}
Helpful Answer:"""
QA_CHAIN_PROMPT = PromptTemplate.from_template(template)
rag_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vector_store.as_retriever(),
chain_type_kwargs={"prompt": QA_CHAIN_PROMPT}
)
print("RAG chain built successfully.")
return True, "Document processed. You can now ask questions."
except Exception as e:
error_message = f"An error occurred while building the RAG chain: {e}"
print(error_message)
rag_chain = None
return False, error_message
def chat_with_rag(message, history):
"""Handles chat interactions using the RAG chain."""
global rag_chain
print(f"chat_with_rag received history type: {type(history)}, content: {history}") # Debug print
if rag_chain is not None:
try:
response = rag_chain.invoke(message)
# Append message and response in the 'messages' format
history.append({"role": "user", "content": message})
history.append({"role": "assistant", "content": response['result']})
print(f"chat_with_rag returning history type: {type(history)}, content: {history}") # Debug print
return history
except Exception as e:
error_message = f"An error occurred while querying the RAG chain: {e}"
history.append({"role": "user", "content": message})
history.append({"role": "assistant", "content": error_message})
print(f"chat_with_rag returning history with error type: {type(history)}, content: {history}") # Debug print
return history
else:
error_message = "Please upload a document to start the chat."
history.append({"role": "user", "content": message})
history.append({"role": "assistant", "content": error_message})
print(f"chat_with_rag returning history with no RAG chain type: {type(history)}, content: {history}") # Debug print
return history
def process_file(file):
"""Processes the uploaded file and builds the RAG chain."""
if file is None:
print("process_file received None file.") # Debug print
return "Please upload a file.", None
print(f"Processing file: {file.name}") # Debug print
success, message = build_rag_from_pdf(file.name)
if success:
print("File processing successful, returning message and None for history.") # Debug print
# Return None for chatbot history to clear it on successful upload
return message, None
else:
print(f"File processing failed, returning message and empty list for history. Message: {message}") # Debug print
return message, []
# Define the Gradio interface
with gr.Blocks() as demo:
gr.Markdown("## RAG Chatbot with Document Upload")
file_upload = gr.File(label="Upload your document (PDF)")
output_message = gr.Textbox(label="Status")
chatbot = gr.Chatbot(type='messages') # Explicitly set type to 'messages'
msg = gr.Textbox(label="Your Question")
clear = gr.ClearButton([msg, chatbot])
file_upload.upload(process_file, inputs=[file_upload], outputs=[output_message, chatbot])
msg.submit(chat_with_rag, inputs=[msg, chatbot], outputs=[chatbot])
if __name__ == "__main__":
demo.launch(share=True)
|