Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import os | |
| from PIL import Image | |
| import pytesseract | |
| import shutil | |
| import pytesseract | |
| from langchain_community.document_loaders import PyPDFLoader | |
| from langchain_text_splitters import RecursiveCharacterTextSplitter | |
| from langchain_community.embeddings import HuggingFaceEmbeddings | |
| from langchain_community.vectorstores import FAISS | |
| #from langchain_community.llms import Ollama | |
| from langchain_ollama import OllamaLLM | |
| from langchain_core.documents import Document | |
| vectorstore = None | |
| retriever = None | |
| llm = None | |
| def process_files(files): | |
| global vectorstore, retriever, llm | |
| all_docs = [] | |
| for file in files: | |
| print(" Processing:", file.name) | |
| # PDF Processing | |
| if file.name.endswith(".pdf"): | |
| loader = PyPDFLoader(file.name) | |
| documents = loader.load() | |
| print(" 📄 Pages:", len(documents)) | |
| all_docs.extend(documents) | |
| # Image Processing (OCR) | |
| elif file.name.endswith((".jpg", ".jpeg", ".png")): | |
| img = Image.open(file.name) | |
| text = pytesseract.image_to_string(img) | |
| print(" 🖼 Extracted text length:", len(text)) | |
| image_doc = Document(page_content=text) | |
| all_docs.append(image_doc) | |
| print(" Splitting text into chunks...") | |
| splitter = RecursiveCharacterTextSplitter( | |
| chunk_size=500, | |
| chunk_overlap=100 | |
| ) | |
| chunks = splitter.split_documents(all_docs) | |
| print(" Total chunks:", len(chunks)) | |
| print(" Creating embeddings...") | |
| embeddings = HuggingFaceEmbeddings( | |
| model_name="all-MiniLM-L6-v2" | |
| ) | |
| vectorstore = FAISS.from_documents(chunks, embeddings) | |
| #retriever = vectorstore.as_retriever() #not reading the numbers in the bill so added logging below | |
| retriever = vectorstore.as_retriever(search_kwargs={"k": 8}) | |
| #llm = Ollama(model="llama3") | |
| llm = OllamaLLM(model="llama3") | |
| print(" Multi-source RAG ready!") | |
| return f"{len(files)} files processed successfully!" | |
| def chat_with_docs(question): | |
| global retriever, llm | |
| if retriever is None: | |
| return "Please upload and process files first." | |
| print(" Question:", question) | |
| # docs = retriever.invoke(question) # not reading the numbers in the bill so added logging below | |
| docs = retriever.invoke(question) | |
| print("\n--- Retrieved Context ---") | |
| for i, doc in enumerate(docs): | |
| print(f"\nChunk {i+1}:\n", doc.page_content[:500]) | |
| print("\n-------------------------\n") | |
| # | |
| print(" Retrieved chunks:", len(docs)) | |
| context = "\n\n".join([doc.page_content for doc in docs]) | |
| prompt = f""" | |
| You are a financial assistant. | |
| Use ONLY the provided context. | |
| Context: | |
| {context} | |
| Question: | |
| {question} | |
| Answer: | |
| """ | |
| print(" Sending to LLM...") | |
| response = llm.invoke(prompt) | |
| print(" Response generated.") | |
| return str(response) | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# Multi-Document RAG (PDF + Image)") | |
| gr.Markdown("Upload PDFs and/or Images, then ask questions.") | |
| file_input = gr.File( | |
| file_count="multiple", | |
| file_types=[".pdf", ".jpg", ".jpeg", ".png"] | |
| ) | |
| process_button = gr.Button("Process Files") | |
| status_output = gr.Textbox(label="Status") | |
| question_input = gr.Textbox(label="Ask a Question") | |
| answer_output = gr.Textbox(label="Answer") | |
| process_button.click(process_files, inputs=file_input, outputs=status_output) | |
| question_input.submit(chat_with_docs, inputs=question_input, outputs=answer_output) | |
| demo.launch() | |