| import os |
| import streamlit as st |
| from transformers import AutoTokenizer, AutoModel, pipeline |
| import faiss |
| import pickle |
| import pdfplumber |
| from docx import Document |
|
|
| |
| INDEX_FILE = "simple_rag_index.pkl" |
| EMBEDDING_DIM = 384 |
|
|
| |
| if os.path.exists(INDEX_FILE): |
| with open(INDEX_FILE, "rb") as f: |
| document_index, doc_store = pickle.load(f) |
| else: |
| document_index = faiss.IndexFlatL2(EMBEDDING_DIM) |
| doc_store = [] |
|
|
| |
| tokenizer = AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2") |
| model = AutoModel.from_pretrained("sentence-transformers/all-MiniLM-L6-v2") |
|
|
| |
| qa_pipeline = pipeline("question-answering", model="distilbert-base-uncased", tokenizer="distilbert-base-uncased") |
|
|
| |
| st.title("Simple RAG Chatbot ") |
|
|
| |
| def extract_pdf_text(file): |
| with pdfplumber.open(file) as pdf: |
| text = "" |
| for page in pdf.pages: |
| text += page.extract_text() |
| return text |
|
|
| |
| def extract_docx_text(file): |
| doc = Document(file) |
| text = "" |
| for para in doc.paragraphs: |
| text += para.text + "\n" |
| return text |
|
|
| |
| uploaded_file = st.file_uploader("Upload a document (txt, pdf, docx)", type=["txt", "pdf", "docx"]) |
| if uploaded_file: |
| file_extension = uploaded_file.name.split('.')[-1].lower() |
| |
| if file_extension == "txt": |
| document_content = uploaded_file.read().decode("utf-8") |
| |
| elif file_extension == "pdf": |
| document_content = extract_pdf_text(uploaded_file) |
| |
| elif file_extension == "docx": |
| document_content = extract_docx_text(uploaded_file) |
| |
| else: |
| st.error("Unsupported file type!") |
| document_content = None |
| |
| if document_content: |
| st.write("Document uploaded successfully!") |
| doc_store.append(document_content) |
|
|
| |
| tokens = tokenizer(document_content, return_tensors="pt", truncation=True, max_length=512) |
| embedding = model(**tokens).last_hidden_state.mean(dim=1).detach().numpy() |
|
|
| |
| assert embedding.shape[1] == EMBEDDING_DIM, "Embedding dimension mismatch!" |
|
|
| |
| document_index.add(embedding) |
|
|
| |
| with open(INDEX_FILE, "wb") as f: |
| pickle.dump((document_index, doc_store), f) |
|
|
| |
| user_query = st.text_input("Ask a question about the document:") |
| if user_query and len(doc_store) > 0: |
| |
| query_tokens = tokenizer(user_query, return_tensors="pt", truncation=True, max_length=512) |
| query_embedding = model(**query_tokens).last_hidden_state.mean(dim=1).detach().numpy() |
|
|
| |
| distances, indices = document_index.search(query_embedding, k=1) |
| closest_doc = doc_store[indices[0][0]] |
|
|
| st.write("Retrieved Document Context:", closest_doc[:500], "...") |
|
|
| |
| answer = qa_pipeline(question=user_query, context=closest_doc) |
| st.write("Answer:", answer["answer"]) |
|
|