Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import PyPDF2
|
3 |
+
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
4 |
+
from langchain.embeddings import HuggingFaceEmbeddings
|
5 |
+
import faiss
|
6 |
+
import numpy as np
|
7 |
+
from huggingface_hub import hf_hub_download
|
8 |
+
from llama_cpp import Llama
|
9 |
+
|
10 |
+
def answer_from_pdf(pdf_file, user_question):
|
11 |
+
# ββββββββββββββββββββββ
|
12 |
+
# 1) PDF Text Extraction
|
13 |
+
# ββββββββββββββββββββββ
|
14 |
+
|
15 |
+
pdf_reader = PyPDF2.PdfReader(pdf_file.name)
|
16 |
+
raw_text = ""
|
17 |
+
for page in pdf_reader.pages:
|
18 |
+
raw_text += page.extract_text()
|
19 |
+
|
20 |
+
# ββββββββββββββββββββββ
|
21 |
+
# 2) Chunking with LangChain
|
22 |
+
# ββββββββββββββββββββββ
|
23 |
+
splitter = RecursiveCharacterTextSplitter(
|
24 |
+
chunk_size = 1000,
|
25 |
+
chunk_overlap = 200,
|
26 |
+
separators = ["\n\n", "\n", " ", ""]
|
27 |
+
)
|
28 |
+
chunks = splitter.split_text(raw_text)
|
29 |
+
|
30 |
+
# ββββββββββββββββββββββββββ
|
31 |
+
# 3) Embedding & FAISS Indexing
|
32 |
+
# ββββββββββββββββββββββββββ
|
33 |
+
hf_embedder = HuggingFaceEmbeddings(
|
34 |
+
model_name="sentence-transformers/all-MiniLM-L6-v2",
|
35 |
+
)
|
36 |
+
doc_embeddings = hf_embedder.embed_documents(chunks)
|
37 |
+
emb_array = np.array(doc_embeddings, dtype=np.float32)
|
38 |
+
index = faiss.IndexFlatL2(emb_array.shape[1])
|
39 |
+
index.add(emb_array)
|
40 |
+
|
41 |
+
# ββββββββββββββββββββββββββ
|
42 |
+
# 4) Load LLAma model
|
43 |
+
# ββββββββββββββββββββββββββ
|
44 |
+
gguf_path = hf_hub_download(
|
45 |
+
repo_id="bartowski/Meta-Llama-3.1-8B-Instruct-GGUF",
|
46 |
+
filename="Meta-Llama-3.1-8B-Instruct-Q6_K.gguf",
|
47 |
+
)
|
48 |
+
llama = Llama(model_path=gguf_path, n_ctx=2048)
|
49 |
+
|
50 |
+
# ββββββββββββββββββββββββββ
|
51 |
+
# 5) Retrieval & Prompting
|
52 |
+
# ββββββββββββββββββββββββββ
|
53 |
+
system_msg = (
|
54 |
+
"You are a knowledgeable assistant. "
|
55 |
+
"Use the provided context to answer the user's question concisely, "
|
56 |
+
"if it's not in the provided context, you say I don't know"
|
57 |
+
"avoid hallucinations, and keep answers under 150 words."
|
58 |
+
)
|
59 |
+
q_emb = hf_embedder.embed_query(user_question)
|
60 |
+
q_vec = np.array(q_emb, dtype=np.float32).reshape(1, -1)
|
61 |
+
D, I = index.search(q_vec, k=3)
|
62 |
+
context_chunks = [chunks[i] for i in I[0]]
|
63 |
+
context_text = "\n\n".join(context_chunks)
|
64 |
+
|
65 |
+
prompt = (
|
66 |
+
f"SYSTEM:\n{system_msg}\n\n"
|
67 |
+
f"CONTEXT:\n{context_text}\n\n"
|
68 |
+
f"USER:\n{user_question}\n\n"
|
69 |
+
"ASSISTANT:"
|
70 |
+
)
|
71 |
+
|
72 |
+
resp = llama.create_completion(
|
73 |
+
prompt=prompt,
|
74 |
+
max_tokens=256,
|
75 |
+
temperature=0.7,
|
76 |
+
stop=["\n\n"]
|
77 |
+
)
|
78 |
+
return resp["choices"][0]["text"].strip()
|
79 |
+
|
80 |
+
# Build a chat interface
|
81 |
+
with gr.Blocks() as demo:
|
82 |
+
gr.Markdown("## PDF RAG Chatbot (LangChain + LLaMA)")
|
83 |
+
upload = gr.File(label="Upload PDF")
|
84 |
+
chatbot = gr.Chatbot()
|
85 |
+
user_input = gr.Textbox(placeholder="Type your question and hit Send")
|
86 |
+
send_btn = gr.Button("Send")
|
87 |
+
|
88 |
+
def chat_step(pdf_file, message, chat_history):
|
89 |
+
response = answer_from_pdf(pdf_file, message)
|
90 |
+
chat_history = chat_history + [(message, response)]
|
91 |
+
return chat_history, ""
|
92 |
+
|
93 |
+
send_btn.click(
|
94 |
+
chat_step,
|
95 |
+
inputs=[upload, user_input, chatbot],
|
96 |
+
outputs=[chatbot, user_input]
|
97 |
+
)
|
98 |
+
|
99 |
+
if __name__ == "__main__":
|
100 |
+
demo.launch()
|