KalooAI commited on
Commit
1c18139
Β·
verified Β·
1 Parent(s): b68a78d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -111
app.py CHANGED
@@ -1,143 +1,122 @@
1
- import warnings
2
- warnings.filterwarnings("ignore")
3
-
4
- import uuid
5
- import gradio as gr
6
  import os
 
 
7
 
8
- from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
9
- from langchain_text_splitters import RecursiveCharacterTextSplitter
10
  from langchain_community.vectorstores import Chroma
11
- from langchain_community.document_loaders import PyPDFLoader
12
- from langchain.chains import RetrievalQA
13
  from langchain_community.embeddings import HuggingFaceEmbeddings
 
14
 
15
 
16
- # -------------------------
17
- # LLM (Hugging Face Router API)
18
- # -------------------------
 
 
19
 
20
- repo_id = "Qwen/Qwen2.5-7B-Instruct"
21
-
22
- llm_endpoint = HuggingFaceEndpoint(
23
- repo_id=repo_id,
24
- task="text-generation",
25
- max_new_tokens=512,
26
- temperature=0.1,
27
- huggingfacehub_api_token=os.getenv("HF_TOKEN"),
28
- provider="hf-inference", # forces router.huggingface.co
29
- model_kwargs={"wait_for_model": True},
30
  )
31
 
32
- llm = ChatHuggingFace(llm=llm_endpoint)
33
-
34
 
35
- # -------------------------
36
- # Document loader
37
- # -------------------------
 
 
 
 
 
 
38
 
39
- def document_loader(file_path: str):
40
- loader = PyPDFLoader(file_path)
41
- return loader.load()
42
 
 
 
 
 
 
 
 
 
 
43
 
44
- # -------------------------
45
- # Text splitter
46
- # -------------------------
47
 
48
- def text_splitter(data):
 
 
 
49
  splitter = RecursiveCharacterTextSplitter(
50
- chunk_size=1000,
51
- chunk_overlap=50,
52
- length_function=len,
53
  )
54
- return splitter.split_documents(data)
55
 
56
-
57
- # -------------------------
58
- # Embedding model
59
- # -------------------------
60
-
61
- def embedding_model():
62
- return HuggingFaceEmbeddings(
63
  model_name="sentence-transformers/all-MiniLM-L6-v2"
64
  )
65
 
 
 
 
 
66
 
67
- # -------------------------
68
- # Vector DB
69
- # -------------------------
70
 
71
- def vector_database(chunks):
72
- chunks = [
73
- c for c in chunks
74
- if c.page_content and c.page_content.strip() and len(c.page_content.strip()) > 10
75
- ]
76
 
77
- vectordb = Chroma.from_documents(
78
- documents=chunks,
79
- embedding=embedding_model(),
80
- collection_name=f"pdf_chat_{uuid.uuid4().hex}",
81
- )
82
- return vectordb
83
 
 
 
84
 
85
- # -------------------------
86
- # Retriever
87
- # -------------------------
88
 
89
- def build_retriever(file_path: str):
90
- docs = document_loader(file_path)
91
- chunks = text_splitter(docs)
92
- vectordb = vector_database(chunks)
93
- return vectordb.as_retriever()
94
 
 
 
 
95
 
96
- # -------------------------
97
- # QA Chain
98
- # -------------------------
99
 
100
- def retriever_qa(file, query):
101
- retr = build_retriever(file)
102
 
103
- qa = RetrievalQA.from_chain_type(
104
- llm=llm,
105
- chain_type="stuff",
106
- retriever=retr,
107
- return_source_documents=False,
108
- )
109
 
110
- result = qa.invoke({"query": query})
111
- return result["result"]
112
-
113
-
114
- # -------------------------
115
- # Gradio interface
116
- # -------------------------
117
-
118
- rag_application = gr.Interface(
119
- fn=retriever_qa,
120
- allow_flagging="never",
121
- inputs=[
122
- gr.File(
123
- label="Upload PDF File",
124
- file_count="single",
125
- file_types=[".pdf"],
126
- type="filepath",
127
- ),
128
- gr.Textbox(
129
- label="Input Query",
130
- lines=2,
131
- placeholder="Type your question here...",
132
- ),
133
- ],
134
- outputs=gr.Textbox(label="Output"),
135
- title="PDF QA Chatbot",
136
- description=(
137
- "Upload a PDF document and ask any question. "
138
- "The chatbot will try to answer using the provided document."
139
- ),
140
- )
141
 
142
- if __name__ == "__main__":
143
- rag_application.launch()
 
 
 
 
 
 
1
  import os
2
+ import tempfile
3
+ import gradio as gr
4
 
5
+ from huggingface_hub import InferenceClient
6
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
7
  from langchain_community.vectorstores import Chroma
 
 
8
  from langchain_community.embeddings import HuggingFaceEmbeddings
9
+ from pypdf import PdfReader
10
 
11
 
12
+ # -----------------------------
13
+ # 1. LLM CLIENT (Router API)
14
+ # -----------------------------
15
+ HF_MODEL = "Qwen/Qwen2.5-7B-Instruct"
16
+ HF_TOKEN = os.getenv("HF_TOKEN")
17
 
18
+ client = InferenceClient(
19
+ model=HF_MODEL,
20
+ token=HF_TOKEN
 
 
 
 
 
 
 
21
  )
22
 
 
 
23
 
24
+ def call_llm(prompt: str) -> str:
25
+ """Call the HF Router API using the new chat.completions endpoint."""
26
+ response = client.chat.completions.create(
27
+ model=HF_MODEL,
28
+ messages=[{"role": "user", "content": prompt}],
29
+ max_tokens=512,
30
+ temperature=0.1,
31
+ )
32
+ return response.choices[0].message["content"]
33
 
 
 
 
34
 
35
+ # -----------------------------
36
+ # 2. PDF β†’ TEXT
37
+ # -----------------------------
38
+ def extract_text_from_pdf(pdf_file):
39
+ reader = PdfReader(pdf_file)
40
+ text = ""
41
+ for page in reader.pages:
42
+ text += page.extract_text() or ""
43
+ return text
44
 
 
 
 
45
 
46
+ # -----------------------------
47
+ # 3. TEXT β†’ CHUNKS β†’ EMBEDDINGS β†’ CHROMA
48
+ # -----------------------------
49
+ def build_vectorstore(text: str):
50
  splitter = RecursiveCharacterTextSplitter(
51
+ chunk_size=800,
52
+ chunk_overlap=150
 
53
  )
54
+ chunks = splitter.split_text(text)
55
 
56
+ embeddings = HuggingFaceEmbeddings(
 
 
 
 
 
 
57
  model_name="sentence-transformers/all-MiniLM-L6-v2"
58
  )
59
 
60
+ vectordb = Chroma.from_texts(
61
+ texts=chunks,
62
+ embedding=embeddings
63
+ )
64
 
65
+ return vectordb
 
 
66
 
 
 
 
 
 
67
 
68
+ # -----------------------------
69
+ # 4. RAG PIPELINE
70
+ # -----------------------------
71
+ def rag_answer(pdf_file, question):
72
+ if pdf_file is None:
73
+ return "Please upload a PDF first."
74
 
75
+ # Extract text
76
+ text = extract_text_from_pdf(pdf_file)
77
 
78
+ # Build vectorstore
79
+ vectordb = build_vectorstore(text)
 
80
 
81
+ # Retrieve context
82
+ docs = vectordb.similarity_search(question, k=4)
83
+ context = "\n\n".join([d.page_content for d in docs])
 
 
84
 
85
+ # Build prompt
86
+ prompt = f"""
87
+ You are a helpful assistant. Use ONLY the context below to answer.
88
 
89
+ Context:
90
+ {context}
 
91
 
92
+ Question: {question}
 
93
 
94
+ Answer clearly and concisely:
95
+ """
 
 
 
 
96
 
97
+ # LLM call
98
+ answer = call_llm(prompt)
99
+ return answer
100
+
101
+
102
+ # -----------------------------
103
+ # 5. GRADIO UI
104
+ # -----------------------------
105
+ with gr.Blocks(title="PDF Analyzer") as demo:
106
+ gr.Markdown("# πŸ“„ PDF Analyzer\nAsk questions about your PDF using RAG + HF Router API.")
107
+
108
+ with gr.Row():
109
+ pdf_input = gr.File(label="Upload PDF", file_types=[".pdf"])
110
+ question_input = gr.Textbox(label="Your question")
111
+
112
+ answer_output = gr.Textbox(label="Answer")
113
+
114
+ run_button = gr.Button("Analyze")
115
+
116
+ run_button.click(
117
+ fn=rag_answer,
118
+ inputs=[pdf_input, question_input],
119
+ outputs=answer_output
120
+ )
 
 
 
 
 
 
 
121
 
122
+ demo.launch()