File size: 3,572 Bytes
b5c68be
8a73d8b
b5c68be
 
 
 
 
 
 
 
 
 
8a73d8b
 
 
b5c68be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a73d8b
1317a05
b5c68be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a73d8b
 
 
b5c68be
 
 
8a73d8b
b5c68be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a73d8b
 
 
 
 
 
 
 
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
import streamlit as st
import os
from PyPDF2 import PdfReader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_groq import ChatGroq
from langchain_classic.chains import create_retrieval_chain
from langchain_classic.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
from transformers import AutoTokenizer

# Automatically fetch the key from Hugging Face Secrets
GROQ_API_KEY = os.getenv("RAGpdf")

# ==========================================
# Core Pipeline Functions
# ==========================================

def extract_text_from_pdf(pdf_file):
    pdf_reader = PdfReader(pdf_file)
    text = ""
    for page in pdf_reader.pages:
        if page.extract_text():
            text += page.extract_text()
    return text

def tokenize_and_chunk_text(text):
    model_name = "sentence-transformers/all-MiniLM-L6-v2"
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    text_splitter = RecursiveCharacterTextSplitter.from_huggingface_tokenizer(
        tokenizer, chunk_size=500, chunk_overlap=50
    )
    return text_splitter.split_text(text)

def create_embeddings_and_vectorstore(text_chunks):
    embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
    return FAISS.from_texts(texts=text_chunks, embedding=embeddings)

def query_and_generate_response(user_query, vectorstore, api_key):
    llm = ChatGroq(groq_api_key=api_key, model_name="llama-3.1-8b-instant", temperature=0.3)
    prompt = ChatPromptTemplate.from_template(
        """
        Answer the question based only on the provided context. 
        If the answer is not in the context, say "I cannot answer this based on the provided document."
        
        Context:
        {context}
        
        Question: {input}
        """
    )
    document_chain = create_stuff_documents_chain(llm, prompt)
    retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
    retrieval_chain = create_retrieval_chain(retriever, document_chain)
    return retrieval_chain.invoke({"input": user_query})["answer"]

# ==========================================
# Streamlit User Interface
# ==========================================

st.title("📄 RAG App with Groq & Llama-3")
st.write("Upload a PDF, process it, and ask questions!")

if not GROQ_API_KEY:
    st.error("🚨 GROQ_API_KEY is missing! Please set it in your Space Settings under Secrets.")
    st.stop()

pdf_file = st.file_uploader("Upload your PDF document", type="pdf")

if pdf_file:
    if st.button("Process Document"):
        with st.spinner("Extracting text..."):
            raw_text = extract_text_from_pdf(pdf_file)
            
        with st.spinner("Tokenizing and Chunking..."):
            chunks = tokenize_and_chunk_text(raw_text)
            
        with st.spinner("Creating Embeddings..."):
            st.session_state.vectorstore = create_embeddings_and_vectorstore(chunks)
            st.success("Document processed and vector store built successfully!")

if "vectorstore" in st.session_state:
    st.divider()
    user_query = st.text_input("Ask a question about your document:")
    
    if user_query:
        with st.spinner("Generating answer..."):
            answer = query_and_generate_response(
                user_query, 
                st.session_state.vectorstore, 
                GROQ_API_KEY
            )
            st.write("**Response:**")
            st.write(answer)