khysam2022 commited on
Commit
f37b2ee
·
verified ·
1 Parent(s): 444f9a7

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +179 -0
app.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from langchain_community.document_loaders import PyPDFLoader
4
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
5
+ from langchain_community.vectorstores import FAISS
6
+ from langchain_community.embeddings import HuggingFaceEmbeddings
7
+ from transformers import AutoTokenizer, AutoModelForCausalLM
8
+ import torch
9
+
10
+ # Get Hugging Face token from environment (set in Spaces Secrets)
11
+ HF_TOKEN = os.environ.get("HUGGINGFACE_TOKEN")
12
+
13
+ # Model repository details
14
+ HF_USERNAME = "khysam2022"
15
+ HF_MODEL_NAME = "RAG-DSE-PAST-PAPER-2012-ICT"
16
+ MODEL_REPO = f"{HF_USERNAME}/{HF_MODEL_NAME}"
17
+
18
+ # Global variables for model and vectorstore
19
+ model = None
20
+ tokenizer = None
21
+ vectorstore = None
22
+
23
+ def load_model():
24
+ """Load the model and tokenizer"""
25
+ global model, tokenizer
26
+
27
+ if model is not None and tokenizer is not None:
28
+ return model, tokenizer
29
+
30
+ print(f"Loading model {MODEL_REPO}...")
31
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_REPO, token=HF_TOKEN)
32
+ model = AutoModelForCausalLM.from_pretrained(
33
+ MODEL_REPO,
34
+ token=HF_TOKEN,
35
+ torch_dtype=torch.float16,
36
+ device_map="auto"
37
+ )
38
+ return model, tokenizer
39
+
40
+ def process_pdf(pdf_file):
41
+ """Process a PDF for RAG"""
42
+ global vectorstore
43
+
44
+ try:
45
+ # Save the uploaded file
46
+ pdf_path = "uploaded_document.pdf"
47
+ with open(pdf_path, "wb") as f:
48
+ f.write(pdf_file)
49
+
50
+ # Load and split the PDF
51
+ loader = PyPDFLoader(pdf_path)
52
+ documents = loader.load()
53
+
54
+ # Split documents into chunks
55
+ text_splitter = RecursiveCharacterTextSplitter(
56
+ chunk_size=1000,
57
+ chunk_overlap=200,
58
+ separators=["\n\n", "\n", " ", ""]
59
+ )
60
+ chunks = text_splitter.split_documents(documents)
61
+
62
+ # Create embeddings and vectorstore
63
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
64
+ vectorstore = FAISS.from_documents(chunks, embeddings)
65
+
66
+ # Cleanup
67
+ if os.path.exists(pdf_path):
68
+ os.remove(pdf_path)
69
+
70
+ return f"✅ PDF processed successfully! Found {len(chunks)} text chunks."
71
+ except Exception as e:
72
+ return f"❌ Error processing PDF: {str(e)}"
73
+
74
+ def generate_answer(query):
75
+ """Generate answer using the model"""
76
+ if model is None or tokenizer is None:
77
+ try:
78
+ load_model()
79
+ except Exception as e:
80
+ return f"❌ Error loading model: {str(e)}"
81
+
82
+ if vectorstore is None:
83
+ return "Please upload a PDF document first."
84
+
85
+ try:
86
+ # Retrieve relevant context
87
+ relevant_docs = vectorstore.similarity_search(query, k=3)
88
+ context = "\n\n".join([doc.page_content for doc in relevant_docs])
89
+
90
+ # Create prompt with context
91
+ prompt = f"""
92
+ You are a helpful assistant analyzing a document. Using only the provided context, answer the question.
93
+
94
+ Context:
95
+ {context}
96
+
97
+ Question: {query}
98
+
99
+ Answer:
100
+ """
101
+
102
+ # Generate response
103
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
104
+
105
+ outputs = model.generate(
106
+ **inputs,
107
+ max_new_tokens=300,
108
+ do_sample=True,
109
+ temperature=0.7,
110
+ top_p=0.9,
111
+ )
112
+
113
+ # Decode and return response
114
+ response = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
115
+ return response
116
+
117
+ except Exception as e:
118
+ return f"❌ Error generating answer: {str(e)}"
119
+
120
+ def direct_query(message):
121
+ """Direct query without RAG"""
122
+ if model is None or tokenizer is None:
123
+ try:
124
+ load_model()
125
+ except Exception as e:
126
+ return f"❌ Error loading model: {str(e)}"
127
+
128
+ try:
129
+ # Create prompt
130
+ prompt = f"User: {message}\nAssistant: "
131
+
132
+ # Generate response
133
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
134
+
135
+ outputs = model.generate(
136
+ **inputs,
137
+ max_new_tokens=300,
138
+ do_sample=True,
139
+ temperature=0.7,
140
+ top_p=0.9,
141
+ )
142
+
143
+ # Decode and return response
144
+ response = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
145
+ return response
146
+
147
+ except Exception as e:
148
+ return f"❌ Error generating answer: {str(e)}"
149
+
150
+ # Define Gradio interface
151
+ with gr.Blocks() as demo:
152
+ gr.Markdown("# RAG-DSE-PAST-PAPER-2012-ICT")
153
+ gr.Markdown("This demo allows you to chat with the model and ask questions about uploaded documents.")
154
+
155
+ with gr.Tab("RAG Query"):
156
+ with gr.Row():
157
+ with gr.Column():
158
+ pdf_upload = gr.File(label="Upload PDF Document")
159
+ process_button = gr.Button("Process Document")
160
+ status_text = gr.Textbox(label="Processing Status", interactive=False)
161
+
162
+ process_button.click(process_pdf, inputs=[pdf_upload], outputs=[status_text])
163
+
164
+ with gr.Column():
165
+ query_input = gr.Textbox(label="Your Question", placeholder="Ask a question about the document...")
166
+ query_button = gr.Button("Ask Question")
167
+ answer_output = gr.Textbox(label="Answer", interactive=False)
168
+
169
+ query_button.click(generate_answer, inputs=[query_input], outputs=[answer_output])
170
+
171
+ with gr.Tab("Direct Chat"):
172
+ chat_input = gr.Textbox(label="Your Message", placeholder="Type your message here...")
173
+ chat_button = gr.Button("Send Message")
174
+ chat_output = gr.Textbox(label="Response", interactive=False)
175
+
176
+ chat_button.click(direct_query, inputs=[chat_input], outputs=[chat_output])
177
+
178
+ # Launch the app
179
+ demo.launch()