imeesam commited on
Commit
78e71e1
Β·
verified Β·
1 Parent(s): e18b03c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +135 -0
app.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+
4
+ from langchain_community.document_loaders import PyPDFLoader
5
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
6
+ from langchain_community.embeddings import HuggingFaceEmbeddings
7
+ from langchain_community.vectorstores import FAISS
8
+ from langchain_groq import ChatGroq
9
+ from langchain_core.prompts import ChatPromptTemplate
10
+ from langchain_core.runnables import RunnablePassthrough
11
+ from langchain_core.output_parsers import StrOutputParser
12
+
13
+
14
+ # ───────────────────────── CONFIG ─────────────────────────
15
+ EMBED_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
16
+ GROQ_MODEL = "llama-3.1-8b-instant"
17
+ TOP_K = 3
18
+
19
+ os.environ["GROQ_API_KEY"] = os.getenv("GROQ_API_KEY")
20
+
21
+
22
+ # ───────────────────────── INIT MODELS ─────────────────────────
23
+ embeddings = HuggingFaceEmbeddings(
24
+ model_name=EMBED_MODEL,
25
+ model_kwargs={"device": "cpu"},
26
+ encode_kwargs={"normalize_embeddings": True}
27
+ )
28
+
29
+
30
+ def create_llm():
31
+ return ChatGroq(
32
+ model=GROQ_MODEL,
33
+ temperature=0.2,
34
+ max_tokens=1024,
35
+ groq_api_key=os.environ["GROQ_API_KEY"]
36
+ )
37
+
38
+
39
+ RAG_PROMPT = ChatPromptTemplate.from_template("""
40
+ You are a helpful assistant.
41
+ Answer ONLY using the context below.
42
+ If not found, say you don't have enough information.
43
+ Context:
44
+ {context}
45
+ Question: {question}
46
+ Answer:
47
+ """)
48
+
49
+
50
+ def format_docs(docs):
51
+ return "\n\n".join(d.page_content for d in docs)
52
+
53
+
54
+ # ───────────────────────── GLOBAL STATE ─────────────────────────
55
+ vectorstore = None
56
+ rag_chain = None
57
+
58
+
59
+ # ───────────────────────── PROCESS PDF ─────────────────────────
60
+ def process_pdf(file):
61
+ global vectorstore, rag_chain
62
+
63
+ if file is None:
64
+ return "Upload a PDF first."
65
+
66
+ path = file.name
67
+
68
+ # Load
69
+ loader = PyPDFLoader(path)
70
+ docs = loader.load()
71
+
72
+ # Split
73
+ splitter = RecursiveCharacterTextSplitter(
74
+ chunk_size=500,
75
+ chunk_overlap=50
76
+ )
77
+ chunks = splitter.split_documents(docs)
78
+
79
+ # Vector store
80
+ if vectorstore is None:
81
+ vectorstore = FAISS.from_documents(chunks, embeddings)
82
+ else:
83
+ vectorstore.add_documents(chunks)
84
+
85
+ retriever = vectorstore.as_retriever(search_kwargs={"k": TOP_K})
86
+
87
+ llm = create_llm()
88
+
89
+ rag_chain = (
90
+ {
91
+ "context": retriever | format_docs,
92
+ "question": RunnablePassthrough()
93
+ }
94
+ | RAG_PROMPT
95
+ | llm
96
+ | StrOutputParser()
97
+ )
98
+
99
+ return f"βœ… PDF processed successfully!\nChunks: {len(chunks)}"
100
+
101
+
102
+ # ───────────────────────── CHAT FUNCTION ─────────────────────────
103
+ def chat(message, history):
104
+
105
+ if rag_chain is None:
106
+ history.append({"role": "user", "content": message})
107
+ history.append({"role": "assistant", "content": "Please upload a PDF first."})
108
+ return "", history
109
+
110
+ response = rag_chain.invoke(message)
111
+
112
+ history.append({"role": "user", "content": message})
113
+ history.append({"role": "assistant", "content": response})
114
+
115
+ return "", history
116
+
117
+
118
+ # ───────────────────────── UI ─────────────────────────
119
+ with gr.Blocks(title="RAG Chatbot") as demo:
120
+
121
+ gr.Markdown("## πŸ“„ PDF RAG Chatbot (Groq + FAISS + LangChain)")
122
+
123
+ with gr.Row():
124
+ file = gr.File(label="Upload PDF")
125
+ upload_btn = gr.Button("Process PDF")
126
+
127
+ status = gr.Textbox(label="Status")
128
+
129
+ chatbot = gr.Chatbot()
130
+ msg = gr.Textbox(label="Ask a question")
131
+
132
+ upload_btn.click(process_pdf, inputs=file, outputs=status)
133
+ msg.submit(chat, inputs=[msg, chatbot], outputs=[msg, chatbot])
134
+
135
+ demo.launch()