Spaces:
Build error
Build error
| import os | |
| import fitz # PyMuPDF | |
| import gradio as gr | |
| import requests | |
| from dotenv import load_dotenv | |
| from sentence_transformers import SentenceTransformer, util | |
| # Load environment variables | |
| load_dotenv() | |
| GROQ_API_KEY = os.getenv("GROQ_API_KEY") | |
| GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions" | |
| MODEL_NAME = "llama3-8b-8192" | |
| # Load sentence-transformer model | |
| embed_model = SentenceTransformer('all-MiniLM-L6-v2') | |
| SYSTEM_PROMPT = """ | |
| You are a helpful AI assistant that answers questions using provided PDF documents. | |
| Always base your answers on the context and include page numbers when possible. | |
| """ | |
| # Extract text from PDF with page numbers | |
| def extract_text_with_pages(file): | |
| doc = fitz.open(file.name) | |
| chunks = [] | |
| for page_num in range(len(doc)): | |
| page = doc.load_page(page_num) | |
| text = page.get_text() | |
| if text.strip(): | |
| chunks.append({"text": text.strip(), "page": page_num + 1}) | |
| return chunks | |
| # Chunking (simple, per page) | |
| def prepare_embeddings(chunks): | |
| texts = [chunk["text"] for chunk in chunks] | |
| embeddings = embed_model.encode(texts, convert_to_tensor=True) | |
| return embeddings | |
| # Retrieve top chunks | |
| def retrieve_top_chunks(query, chunks, embeddings, top_k=3): | |
| query_embedding = embed_model.encode(query, convert_to_tensor=True) | |
| hits = util.semantic_search(query_embedding, embeddings, top_k=top_k)[0] | |
| results = [] | |
| for hit in hits: | |
| matched_chunk = chunks[hit["corpus_id"]] | |
| results.append(f"[Page {matched_chunk['page']}]: {matched_chunk['text']}") | |
| return results | |
| # Query GROQ LLM | |
| def query_groq(question, context, chat_history): | |
| messages = [{"role": "system", "content": SYSTEM_PROMPT}] | |
| for user, bot in chat_history: | |
| messages.append({"role": "user", "content": user}) | |
| messages.append({"role": "assistant", "content": bot}) | |
| messages.append({"role": "user", "content": f"Context:\n{context}\n\nQuestion: {question}"}) | |
| headers = { | |
| "Authorization": f"Bearer {GROQ_API_KEY}", | |
| "Content-Type": "application/json" | |
| } | |
| response = requests.post(GROQ_API_URL, headers=headers, json={ | |
| "model": MODEL_NAME, | |
| "messages": messages, | |
| "temperature": 0.7 | |
| }) | |
| if response.status_code == 200: | |
| return response.json()["choices"][0]["message"]["content"] | |
| else: | |
| return f"Error {response.status_code}: {response.text}" | |
| # Full RAG pipeline | |
| def rag_chatbot(files, question, history): | |
| all_chunks = [] | |
| for file in files: | |
| all_chunks.extend(extract_text_with_pages(file)) | |
| embeddings = prepare_embeddings(all_chunks) | |
| top_chunks = retrieve_top_chunks(question, all_chunks, embeddings) | |
| context = "\n\n".join(top_chunks) | |
| response = query_groq(question, context, history) | |
| history.append((question, response)) | |
| return "", history | |
| # Gradio Interface | |
| with gr.Blocks() as demo: | |
| gr.Markdown("## 📄 RAG PDF Chatbot (Groq + SentenceTransformers)") | |
| gr.Markdown("Upload PDFs and ask questions. The assistant will use document context and show page numbers in answers.") | |
| pdf_files = gr.File(file_types=[".pdf"], file_count="multiple", label="Upload your PDF files") | |
| question = gr.Textbox(label="Ask a question about the documents") | |
| chatbot = gr.Chatbot() | |
| clear_btn = gr.Button("Clear Chat") | |
| state = gr.State([]) | |
| question.submit(rag_chatbot, [pdf_files, question, state], [question, chatbot]) | |
| clear_btn.click(lambda: ([], []), None, [chatbot, state]) | |
| demo.launch() | |