simran40 commited on
Commit
72523e8
Β·
verified Β·
1 Parent(s): ead3409

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -53
app.py CHANGED
@@ -1,5 +1,5 @@
1
  import gradio as gr
2
- import fitz # PyMuPDF
3
  import re
4
  import faiss
5
  import torch
@@ -10,15 +10,12 @@ from transformers import AutoTokenizer, AutoModelForCausalLM
10
 
11
 
12
  # ===============================
13
- # MODEL LOADING (ONCE)
14
  # ===============================
15
 
16
- # Embedding model (lightweight & fast)
17
  embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
18
 
19
- # Open-source LLM (CPU friendly)
20
  LLM_NAME = "TinyLlama/TinyLlama-1.1B-Chat-v1.0"
21
-
22
  tokenizer = AutoTokenizer.from_pretrained(LLM_NAME)
23
  llm = AutoModelForCausalLM.from_pretrained(
24
  LLM_NAME,
@@ -29,7 +26,7 @@ llm.eval()
29
 
30
 
31
  # ===============================
32
- # PDF PROCESSING FUNCTIONS
33
  # ===============================
34
 
35
  def extract_text_from_pdf(pdf_path):
@@ -47,48 +44,41 @@ def clean_text(text):
47
  def chunk_text(text, chunk_size=500, overlap=50):
48
  chunks = []
49
  start = 0
50
- text_length = len(text)
51
-
52
- while start < text_length:
53
  end = start + chunk_size
54
  chunks.append(text[start:end])
55
  start = end - overlap
56
-
57
  return chunks
58
 
59
 
60
  # ===============================
61
- # VECTOR DATABASE (FAISS)
62
  # ===============================
63
 
64
  def build_faiss_index(chunks):
65
  embeddings = embedding_model.encode(chunks)
66
  embeddings = np.array(embeddings).astype("float32")
67
-
68
  index = faiss.IndexFlatL2(embeddings.shape[1])
69
  index.add(embeddings)
70
-
71
  return index, chunks
72
 
73
 
74
  def retrieve_relevant_chunks(query, index, chunks, top_k=3):
75
  query_embedding = embedding_model.encode([query]).astype("float32")
76
  _, indices = index.search(query_embedding, top_k)
77
-
78
  return [chunks[i] for i in indices[0]]
79
 
80
 
81
  # ===============================
82
- # ANSWER GENERATION (LLM)
83
  # ===============================
84
 
85
  def generate_answer(question, context_chunks):
86
  context = "\n\n".join(context_chunks)
87
 
88
  prompt = f"""
89
- You are an AI assistant.
90
  Answer the question strictly using the given context.
91
- If the answer is not found, reply:
92
  "Information not found in the document."
93
 
94
  Context:
@@ -109,72 +99,61 @@ Answer:
109
  temperature=0.2
110
  )
111
 
112
- decoded_output = tokenizer.decode(output[0], skip_special_tokens=True)
113
- return decoded_output.split("Answer:")[-1].strip()
114
 
115
 
116
  # ===============================
117
- # MAIN RAG PIPELINE
118
  # ===============================
119
 
120
  def pdf_rag_chat(pdf_file, question):
121
  if pdf_file is None or question.strip() == "":
122
  return "Please upload a PDF and enter a question."
123
 
124
- # 1. Extract & preprocess text
125
- raw_text = extract_text_from_pdf(pdf_file.name)
126
- cleaned_text = clean_text(raw_text)
127
 
128
- # 2. Chunking
129
- chunks = chunk_text(cleaned_text)
130
-
131
- # 3. Vector DB
132
  index, chunks = build_faiss_index(chunks)
 
133
 
134
- # 4. Retrieval
135
- relevant_chunks = retrieve_relevant_chunks(question, index, chunks)
136
-
137
- # 5. LLM Answer
138
- return generate_answer(question, relevant_chunks)
139
 
140
 
141
  # ===============================
142
- # GRADIO UI (PRODUCTION READY)
143
  # ===============================
144
 
145
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
146
 
147
  gr.Markdown("""
148
  # πŸ“„ PDF RAG Chatbot (Open-Source AI)
149
 
150
- Upload a **PDF document** and ask questions based **only on its content**.
151
- This system uses a **Retrieval Augmented Generation (RAG)** architecture with
152
- **open-source Hugging Face models**, running entirely on **free CPU**.
153
-
154
- ---
155
  """)
156
 
157
  with gr.Row():
158
  with gr.Column(scale=1):
159
  pdf_input = gr.File(
160
  label="πŸ“€ Upload PDF",
161
- file_types=[".pdf"],
162
- file_count="single"
163
  )
164
 
165
  question_input = gr.Textbox(
166
- label="❓ Ask your question",
167
  placeholder="e.g. What is the objective of the project?",
168
  lines=2
169
  )
170
 
171
- submit_btn = gr.Button("πŸ” Get Answer", variant="primary")
172
 
173
  with gr.Column(scale=2):
174
  answer_output = gr.Textbox(
175
  label="πŸ“Œ Answer",
176
- lines=10,
177
- show_copy_button=True
178
  )
179
 
180
  submit_btn.click(
@@ -185,14 +164,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
185
 
186
  gr.Markdown("""
187
  ---
188
- ### βš™οΈ System Information
189
- - **LLM:** TinyLlama (Open-Source, Hugging Face)
190
- - **Embeddings:** Sentence Transformers
191
- - **Vector Store:** FAISS
192
- - **Deployment:** Hugging Face Spaces (Free CPU)
193
-
194
- ---
195
- Β© **Simranpreet Kaur**
196
  **NIELIT Ropar | AIML Six Months Training | 2026**
197
  """)
198
 
 
1
  import gradio as gr
2
+ import fitz
3
  import re
4
  import faiss
5
  import torch
 
10
 
11
 
12
  # ===============================
13
+ # MODEL LOADING
14
  # ===============================
15
 
 
16
  embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
17
 
 
18
  LLM_NAME = "TinyLlama/TinyLlama-1.1B-Chat-v1.0"
 
19
  tokenizer = AutoTokenizer.from_pretrained(LLM_NAME)
20
  llm = AutoModelForCausalLM.from_pretrained(
21
  LLM_NAME,
 
26
 
27
 
28
  # ===============================
29
+ # PDF PROCESSING
30
  # ===============================
31
 
32
  def extract_text_from_pdf(pdf_path):
 
44
  def chunk_text(text, chunk_size=500, overlap=50):
45
  chunks = []
46
  start = 0
47
+ while start < len(text):
 
 
48
  end = start + chunk_size
49
  chunks.append(text[start:end])
50
  start = end - overlap
 
51
  return chunks
52
 
53
 
54
  # ===============================
55
+ # VECTOR DB (FAISS)
56
  # ===============================
57
 
58
  def build_faiss_index(chunks):
59
  embeddings = embedding_model.encode(chunks)
60
  embeddings = np.array(embeddings).astype("float32")
 
61
  index = faiss.IndexFlatL2(embeddings.shape[1])
62
  index.add(embeddings)
 
63
  return index, chunks
64
 
65
 
66
  def retrieve_relevant_chunks(query, index, chunks, top_k=3):
67
  query_embedding = embedding_model.encode([query]).astype("float32")
68
  _, indices = index.search(query_embedding, top_k)
 
69
  return [chunks[i] for i in indices[0]]
70
 
71
 
72
  # ===============================
73
+ # LLM ANSWER
74
  # ===============================
75
 
76
  def generate_answer(question, context_chunks):
77
  context = "\n\n".join(context_chunks)
78
 
79
  prompt = f"""
 
80
  Answer the question strictly using the given context.
81
+ If the answer is not found, say:
82
  "Information not found in the document."
83
 
84
  Context:
 
99
  temperature=0.2
100
  )
101
 
102
+ decoded = tokenizer.decode(output[0], skip_special_tokens=True)
103
+ return decoded.split("Answer:")[-1].strip()
104
 
105
 
106
  # ===============================
107
+ # MAIN PIPELINE
108
  # ===============================
109
 
110
  def pdf_rag_chat(pdf_file, question):
111
  if pdf_file is None or question.strip() == "":
112
  return "Please upload a PDF and enter a question."
113
 
114
+ text = extract_text_from_pdf(pdf_file.name)
115
+ text = clean_text(text)
 
116
 
117
+ chunks = chunk_text(text)
 
 
 
118
  index, chunks = build_faiss_index(chunks)
119
+ context = retrieve_relevant_chunks(question, index, chunks)
120
 
121
+ return generate_answer(question, context)
 
 
 
 
122
 
123
 
124
  # ===============================
125
+ # GRADIO UI (GRADIO 6 SAFE)
126
  # ===============================
127
 
128
+ with gr.Blocks() as demo:
129
 
130
  gr.Markdown("""
131
  # πŸ“„ PDF RAG Chatbot (Open-Source AI)
132
 
133
+ Upload a **PDF** and ask questions based **only on its content**.
134
+ Built using **Retrieval Augmented Generation (RAG)** and
135
+ **open-source Hugging Face models**, running on **free CPU**.
 
 
136
  """)
137
 
138
  with gr.Row():
139
  with gr.Column(scale=1):
140
  pdf_input = gr.File(
141
  label="πŸ“€ Upload PDF",
142
+ file_types=[".pdf"]
 
143
  )
144
 
145
  question_input = gr.Textbox(
146
+ label="❓ Ask a question",
147
  placeholder="e.g. What is the objective of the project?",
148
  lines=2
149
  )
150
 
151
+ submit_btn = gr.Button("πŸ” Get Answer")
152
 
153
  with gr.Column(scale=2):
154
  answer_output = gr.Textbox(
155
  label="πŸ“Œ Answer",
156
+ lines=10
 
157
  )
158
 
159
  submit_btn.click(
 
164
 
165
  gr.Markdown("""
166
  ---
167
+ **Β© Simranpreet Kaur**
 
 
 
 
 
 
 
168
  **NIELIT Ropar | AIML Six Months Training | 2026**
169
  """)
170