File size: 3,346 Bytes
d052399
 
 
0061aa0
7a34b6f
0373023
24519b7
3920dd0
b5e7ec8
74b926b
 
d6b3e88
74b926b
d052399
 
 
3920dd0
d052399
 
e40affa
3920dd0
5359240
 
 
1609ba4
45ef991
2c6f1f7
24519b7
5359240
1609ba4
5359240
 
 
 
d052399
 
 
 
 
7a34b6f
d052399
 
 
 
 
 
 
 
 
 
 
 
 
3920dd0
d052399
 
 
3920dd0
d052399
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7a34b6f
d052399
 
 
7a34b6f
d052399
 
 
 
 
 
 
 
 
 
 
7a34b6f
 
d052399
 
 
 
 
74b926b
d052399
3920dd0
d052399
3372d1a
d052399
 
 
74b926b
7a34b6f
a4543a7
 
d052399
7a34b6f
d052399
 
 
7a34b6f
74b926b
7a34b6f
d052399
7a34b6f
d052399
 
 
 
 
 
 
 
 
 
 
74b926b
d052399
 
 
 
 
 
74b926b
7a34b6f
d052399
 
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
import warnings
warnings.filterwarnings("ignore")

import uuid
import gradio as gr
import os

from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import PyPDFLoader
from langchain.chains import RetrievalQA
from langchain_community.embeddings import HuggingFaceEmbeddings


# -------------------------
# LLM (Hugging Face Router API)
# -------------------------

repo_id = "Qwen/Qwen2.5-7B-Instruct"

llm_endpoint = HuggingFaceEndpoint(
    repo_id=repo_id,
    task="text-generation",
    max_new_tokens=512,
    temperature=0.1,
    huggingfacehub_api_token=os.getenv("HF_TOKEN"),
    provider="hf-inference",   # forces router.huggingface.co
    model_kwargs={"wait_for_model": True},
)

llm = ChatHuggingFace(llm=llm_endpoint)


# -------------------------
# Document loader
# -------------------------

def document_loader(file_path: str):
    loader = PyPDFLoader(file_path)
    return loader.load()


# -------------------------
# Text splitter
# -------------------------

def text_splitter(data):
    splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000,
        chunk_overlap=50,
        length_function=len,
    )
    return splitter.split_documents(data)


# -------------------------
# Embedding model
# -------------------------

def embedding_model():
    return HuggingFaceEmbeddings(
        model_name="sentence-transformers/all-MiniLM-L6-v2"
    )


# -------------------------
# Vector DB
# -------------------------

def vector_database(chunks):
    chunks = [
        c for c in chunks
        if c.page_content and c.page_content.strip() and len(c.page_content.strip()) > 10
    ]

    vectordb = Chroma.from_documents(
        documents=chunks,
        embedding=embedding_model(),
        collection_name=f"pdf_chat_{uuid.uuid4().hex}",
    )
    return vectordb


# -------------------------
# Retriever
# -------------------------

def build_retriever(file_path: str):
    docs = document_loader(file_path)
    chunks = text_splitter(docs)
    vectordb = vector_database(chunks)
    return vectordb.as_retriever()


# -------------------------
# QA Chain
# -------------------------

def retriever_qa(file, query):
    retr = build_retriever(file)

    qa = RetrievalQA.from_chain_type(
        llm=llm,
        chain_type="stuff",
        retriever=retr,
        return_source_documents=False,
    )

    result = qa.invoke({"query": query})
    return result["result"]


# -------------------------
# Gradio interface
# -------------------------

rag_application = gr.Interface(
    fn=retriever_qa,
    allow_flagging="never",
    inputs=[
        gr.File(
            label="Upload PDF File",
            file_count="single",
            file_types=[".pdf"],
            type="filepath",
        ),
        gr.Textbox(
            label="Input Query",
            lines=2,
            placeholder="Type your question here...",
        ),
    ],
    outputs=gr.Textbox(label="Output"),
    title="PDF QA Chatbot",
    description=(
        "Upload a PDF document and ask any question. "
        "The chatbot will try to answer using the provided document."
    ),
)

if __name__ == "__main__":
    rag_application.launch()