Resham2987 commited on
Commit
0bb86b0
·
verified ·
1 Parent(s): 1ac3c5f

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -344
app.py DELETED
@@ -1,344 +0,0 @@
1
- # import os
2
- # import gradio as gr
3
- # from pathlib import Path
4
- # from pypdf import PdfReader
5
- # from sentence_transformers import SentenceTransformer
6
- # import faiss
7
- # import numpy as np
8
- # from groq import Groq
9
-
10
- # # ── Config ─────────────────────────────────────────────────────────────────────
11
- # EMBEDDING_MODEL = "all-MiniLM-L6-v2"
12
- # CHUNK_SIZE = 500
13
- # CHUNK_OVERLAP = 100
14
- # TOP_K = 5
15
- # LLM_MODEL = "llama3-8b-8192"
16
-
17
- # # ── Load embedder once at startup ──────────────────────────────────────────────
18
- # embedder = SentenceTransformer(EMBEDDING_MODEL)
19
-
20
- # # ── RAG helpers ────────────────────────────────────────────────────────────────
21
-
22
- # def extract_text(pdf_path: str) -> str:
23
- # reader = PdfReader(pdf_path)
24
- # return "".join(page.extract_text() or "" for page in reader.pages)
25
-
26
- # def chunk_text(text: str) -> list:
27
- # chunks, start = [], 0
28
- # while start < len(text):
29
- # chunks.append(text[start : start + CHUNK_SIZE])
30
- # start += CHUNK_SIZE - CHUNK_OVERLAP
31
- # return chunks
32
-
33
- # def build_index(chunks: list):
34
- # vecs = embedder.encode(chunks, show_progress_bar=False).astype("float32")
35
- # idx = faiss.IndexFlatL2(vecs.shape[1])
36
- # idx.add(vecs)
37
- # return idx
38
-
39
- # def retrieve(query: str, index, chunks: list) -> list:
40
- # q_vec = embedder.encode([query], show_progress_bar=False).astype("float32")
41
- # _, ids = index.search(q_vec, TOP_K)
42
- # return [chunks[i] for i in ids[0] if i < len(chunks)]
43
-
44
- # # ── Process PDF ────────────────────────────────────────────────────────────────
45
-
46
- # def process_pdf(pdf_file, index_state, chunks_state):
47
- # if pdf_file is None:
48
- # return "⚠️ Please upload a PDF.", index_state, chunks_state
49
- # try:
50
- # text = extract_text(pdf_file)
51
- # except Exception as e:
52
- # return f"❌ Failed to read PDF: {e}", index_state, chunks_state
53
- # if not text.strip():
54
- # return "❌ No text found. Use a text-based PDF.", index_state, chunks_state
55
- # chunks = chunk_text(text)
56
- # index = build_index(chunks)
57
- # name = Path(pdf_file).stem
58
- # return f"✅ **{name}** — {len(chunks)} chunks indexed. Start chatting!", index, chunks
59
-
60
- # # ── Chat ───────────────────────────────────────────────────────────────────────
61
-
62
- # def respond(
63
- # message,
64
- # history: list[dict],
65
- # system_message,
66
- # max_tokens,
67
- # temperature,
68
- # top_p,
69
- # groq_api_key,
70
- # index_state,
71
- # chunks_state,
72
- # ):
73
- # if not groq_api_key.strip():
74
- # yield "⚠️ Please enter your Groq API key in the sidebar."
75
- # return
76
- # if index_state is None:
77
- # yield "⚠️ Please upload and process a PDF first."
78
- # return
79
-
80
- # context = retrieve(message, index_state, chunks_state)
81
- # rag_system = (
82
- # system_message + "\n\n"
83
- # "Answer ONLY from the document context below. "
84
- # "If the answer is not there, say you don't know.\n\n"
85
- # "DOCUMENT CONTEXT:\n" + "\n\n---\n\n".join(context)
86
- # )
87
-
88
- # messages = [{"role": "system", "content": rag_system}]
89
- # messages.extend(history)
90
- # messages.append({"role": "user", "content": message})
91
-
92
- # client = Groq(api_key=groq_api_key.strip())
93
- # response = ""
94
-
95
- # try:
96
- # stream = client.chat.completions.create(
97
- # model=LLM_MODEL,
98
- # messages=messages,
99
- # max_tokens=max_tokens,
100
- # temperature=temperature,
101
- # top_p=top_p,
102
- # stream=True,
103
- # )
104
- # for chunk in stream:
105
- # token = chunk.choices[0].delta.content or ""
106
- # response += token
107
- # yield response
108
- # except Exception as e:
109
- # yield f"❌ Groq error: {e}"
110
-
111
- # # ── UI ─────────────────────────────────────────────────────────────────────────
112
-
113
- # with gr.Blocks(title="RAG PDF Chatbot") as demo:
114
-
115
- # # State lives here — one place only, shared with everything below
116
- # index_state = gr.State(None)
117
- # chunks_state = gr.State(None)
118
-
119
- # with gr.Sidebar():
120
- # gr.Markdown("## 🔑 Groq API Key")
121
- # groq_key = gr.Textbox(
122
- # label="API Key",
123
- # placeholder="gsk_...",
124
- # type="password",
125
- # info="Free at console.groq.com",
126
- # )
127
-
128
- # gr.Markdown("---")
129
- # gr.Markdown("## 📄 Upload PDF")
130
- # pdf_upload = gr.File(label="PDF file", file_types=[".pdf"], type="filepath")
131
- # process_btn = gr.Button("⚡ Process PDF", variant="primary")
132
- # status_box = gr.Markdown("Upload a PDF to begin.")
133
-
134
- # gr.Markdown("---")
135
- # gr.Markdown(
136
- # "**Model:** Llama 3 8B (Groq)\n\n"
137
- # "**Embeddings:** all-MiniLM-L6-v2\n\n"
138
- # "**Vector store:** FAISS top-5"
139
- # )
140
-
141
- # # PDF processing updates the shared state
142
- # process_btn.click(
143
- # fn=process_pdf,
144
- # inputs=[pdf_upload, index_state, chunks_state],
145
- # outputs=[status_box, index_state, chunks_state],
146
- # )
147
-
148
- # # ChatInterface reuses the SAME groq_key, index_state, chunks_state objects
149
- # # defined above — NOT new gr.State() instances
150
- # gr.ChatInterface(
151
- # fn=respond,
152
- # additional_inputs=[
153
- # gr.Textbox(
154
- # value="You are a helpful assistant that answers questions about documents.",
155
- # label="System message",
156
- # ),
157
- # gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
158
- # gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
159
- # gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p"),
160
- # groq_key, # same textbox object from sidebar
161
- # index_state, # same State object — not a new one
162
- # chunks_state, # same State object — not a new one
163
- # ],
164
- # )
165
-
166
- # if __name__ == "__main__":
167
- # demo.queue().launch()
168
-
169
- import os
170
- import gradio as gr
171
- from pathlib import Path
172
- from pypdf import PdfReader
173
- from sentence_transformers import SentenceTransformer
174
- import faiss
175
- import numpy as np
176
- from groq import Groq
177
-
178
- # ── Config ─────────────────────────────────────────────────────────────────────
179
- EMBEDDING_MODEL = "all-MiniLM-L6-v2"
180
- CHUNK_SIZE = 500
181
- CHUNK_OVERLAP = 100
182
- TOP_K = 5
183
- LLM_MODEL = "llama3-8b-8192"
184
-
185
- # ── Load embedder once at startup ──────────────────────────────────────────────
186
- embedder = SentenceTransformer(EMBEDDING_MODEL)
187
-
188
- # ── RAG helpers ────────────────────────────────────────────────────────────────
189
-
190
- def extract_text(pdf_path: str) -> str:
191
- reader = PdfReader(pdf_path)
192
- return "".join(page.extract_text() or "" for page in reader.pages)
193
-
194
- def chunk_text(text: str) -> list:
195
- chunks, start = [], 0
196
- while start < len(text):
197
- chunks.append(text[start : start + CHUNK_SIZE])
198
- start += CHUNK_SIZE - CHUNK_OVERLAP
199
- return chunks
200
-
201
- def build_index(chunks: list):
202
- vecs = embedder.encode(chunks, show_progress_bar=False).astype("float32")
203
- idx = faiss.IndexFlatL2(vecs.shape[1])
204
- idx.add(vecs)
205
- return idx
206
-
207
- def retrieve(query: str, index, chunks: list) -> list:
208
- q_vec = embedder.encode([query], show_progress_bar=False).astype("float32")
209
- _, ids = index.search(q_vec, TOP_K)
210
- return [chunks[i] for i in ids[0] if i < len(chunks)]
211
-
212
- # ── Process PDF ────────────────────────────────────────────────────────────────
213
-
214
- def process_pdf(pdf_file, index_state, chunks_state):
215
- if pdf_file is None:
216
- return "⚠️ Please upload a PDF first.", index_state, chunks_state
217
- try:
218
- text = extract_text(pdf_file)
219
- except Exception as e:
220
- return f"❌ Failed to read PDF: {e}", index_state, chunks_state
221
- if not text.strip():
222
- return "❌ No text found. Use a text-based PDF.", index_state, chunks_state
223
- chunks = chunk_text(text)
224
- index = build_index(chunks)
225
- name = Path(pdf_file).stem
226
- return f"✅ **{name}** — {len(chunks)} chunks indexed. Ready to chat!", index, chunks
227
-
228
- # ── Chat ───────────────────────────────────────────────────────────────────────
229
-
230
- def respond(
231
- message,
232
- history,
233
- groq_api_key,
234
- pdf_file,
235
- system_message,
236
- max_tokens,
237
- temperature,
238
- top_p,
239
- index_state,
240
- chunks_state,
241
- ):
242
- # Auto-process PDF if not yet indexed
243
- if index_state is None:
244
- if pdf_file is None:
245
- yield "⚠️ Please upload a PDF using the panel on the left."
246
- return
247
- try:
248
- text = extract_text(pdf_file)
249
- chunks = chunk_text(text)
250
- index_state = build_index(chunks)
251
- chunks_state = chunks
252
- except Exception as e:
253
- yield f"❌ Failed to process PDF: {e}"
254
- return
255
-
256
- if not groq_api_key or not groq_api_key.strip():
257
- yield "⚠️ Please enter your Groq API key in the panel on the left."
258
- return
259
-
260
- context = retrieve(message, index_state, chunks_state)
261
- rag_system = (
262
- system_message + "\n\n"
263
- "Answer ONLY from the document context below. "
264
- "If the answer is not there, say you don't know.\n\n"
265
- "DOCUMENT CONTEXT:\n" + "\n\n---\n\n".join(context)
266
- )
267
-
268
- messages = [{"role": "system", "content": rag_system}]
269
- messages.extend(history)
270
- messages.append({"role": "user", "content": message})
271
-
272
- response = ""
273
- try:
274
- client = Groq(api_key=groq_api_key.strip())
275
- stream = client.chat.completions.create(
276
- model=LLM_MODEL,
277
- messages=messages,
278
- max_tokens=max_tokens,
279
- temperature=temperature,
280
- top_p=top_p,
281
- stream=True,
282
- )
283
- for chunk in stream:
284
- token = chunk.choices[0].delta.content or ""
285
- response += token
286
- yield response
287
- except Exception as e:
288
- yield f"❌ Groq error: {e}"
289
-
290
- # ── UI ─────────────────────────────────────────────────────────────────────────
291
-
292
- with gr.Blocks(title="RAG PDF Chatbot") as demo:
293
-
294
- index_state = gr.State(None)
295
- chunks_state = gr.State(None)
296
-
297
- with gr.Sidebar():
298
- gr.Markdown("## 🔑 Groq API Key")
299
- groq_key = gr.Textbox(
300
- label="API Key",
301
- placeholder="gsk_...",
302
- type="password",
303
- info="Free at console.groq.com",
304
- )
305
-
306
- gr.Markdown("---")
307
- gr.Markdown("## 📄 PDF Document")
308
- pdf_upload = gr.File(label="Upload PDF", file_types=[".pdf"], type="filepath")
309
- process_btn = gr.Button("⚡ Process PDF", variant="primary")
310
- status_box = gr.Markdown("Upload a PDF to begin.")
311
-
312
- gr.Markdown("---")
313
- gr.Markdown(
314
- "**Model:** Llama 3 8B (Groq)\n\n"
315
- "**Embeddings:** all-MiniLM-L6-v2\n\n"
316
- "**Vector store:** FAISS top-5"
317
- )
318
-
319
- process_btn.click(
320
- fn=process_pdf,
321
- inputs=[pdf_upload, index_state, chunks_state],
322
- outputs=[status_box, index_state, chunks_state],
323
- )
324
-
325
- gr.ChatInterface(
326
- fn=respond,
327
- additional_inputs=[
328
- groq_key, # ← exact same object as sidebar
329
- pdf_upload, # ← exact same object as sidebar
330
- gr.Textbox(
331
- value="You are a helpful assistant that answers questions about documents.",
332
- label="System message",
333
- ),
334
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
335
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
336
- gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p"),
337
- index_state, # ← exact same State object
338
- chunks_state, # ← exact same State object
339
- ],
340
- additional_inputs_accordion=gr.Accordion("⚙️ Settings", open=False),
341
- )
342
-
343
- if __name__ == "__main__":
344
- demo.queue().launch()