abdurrouf14/QuestionAnswering
0
1import streamlit as st2import faiss3from io import BytesIO4from docx import Document5import numpy as np6from pypdf import PdfReader7 8from langchain_text_splitters import CharacterTextSplitter9from langchain_community.embeddings import HuggingFaceEmbeddings10from langchain_community.vectorstores import FAISS11from langchain_community.docstore.in_memory import InMemoryDocstore12from langchain_community.document_loaders import WebBaseLoader13 14from transformers import AutoTokenizer, AutoModelForQuestionAnswering, pipeline15 16# =========================17# Load QA model (CPU, no API key)18# =========================19@st.cache_resource20def load_qa_pipeline():21 model_name = "distilbert-base-uncased-distilled-squad"22 tokenizer = AutoTokenizer.from_pretrained(model_name)23 model = AutoModelForQuestionAnswering.from_pretrained(model_name)24 return pipeline(25 "question-answering",26 model=model,27 tokenizer=tokenizer,28 device=-1 # CPU29 )30 31qa_pipeline = load_qa_pipeline()32 33# =========================34# Build Vector Store35# =========================36def process_input(input_type, inputs):37 all_texts = []38 39 for data in inputs:40 # -------- Link --------41 if input_type == "Link":42 loader = WebBaseLoader(data)43 docs = loader.load()44 splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)45 chunks = splitter.split_documents(docs)46 texts = [c.page_content for c in chunks]47 48 # -------- PDF --------49 elif input_type == "PDF":50 reader = PdfReader(BytesIO(data.read()))51 text = "\n".join([p.extract_text() or "" for p in reader.pages])52 splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)53 texts = splitter.split_text(text)54 55 # -------- DOCX --------56 elif input_type == "DOCX":57 doc = Document(BytesIO(data.read()))58 text = "\n".join([p.text for p in doc.paragraphs])59 splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)60 texts = splitter.split_text(text)61 62 # -------- TXT / Text --------63 else:64 text = data if isinstance(data, str) else data.read().decode("utf-8")65 splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)66 texts = splitter.split_text(text)67 68 all_texts.extend(texts)69 70 # -------- Embeddings --------71 embeddings = HuggingFaceEmbeddings(72 model_name="sentence-transformers/all-mpnet-base-v2",73 model_kwargs={"device": "cpu"}74 )75 76 dim = len(embeddings.embed_query("test"))77 index = faiss.IndexFlatL2(dim)78 79 vectorstore = FAISS(80 embedding_function=embeddings.embed_query,81 index=index,82 docstore=InMemoryDocstore(),83 index_to_docstore_id={}84 )85 vectorstore.add_texts(all_texts)86 87 return vectorstore88 89# =========================90# Answer Question (FIXED)91# =========================92def answer_question(vectorstore, query):93 # โ
FIX: use similarity_search instead of retriever.get_relevant_documents94 docs = vectorstore.similarity_search(query, k=4)95 context = " ".join([d.page_content for d in docs])96 97 if not context.strip():98 return "No relevant context found."99 100 result = qa_pipeline(101 question=query,102 context=context103 )104 return result["answer"]105 106# =========================107# Streamlit UI108# =========================109def main():110 st.set_page_config(page_title="RAG Q&A", layout="wide")111 112 st.markdown("## ๐ RAG Question Answering System")113 114 input_type = st.selectbox(115 "Select Input Type",116 ["Direct Text", "Link", "PDF", "DOCX", "TXT"]117 )118 119 inputs = []120 121 # -------- Direct Text --------122 if input_type == "Direct Text":123 text = st.text_area("Paste your text here")124 if text.strip():125 inputs.append(text)126 127 # -------- Links --------128 elif input_type == "Link":129 n = st.number_input("Number of links", 1, 10, 1)130 for i in range(n):131 url = st.text_input(f"URL {i+1}")132 if url:133 inputs.append(url)134 135 # -------- Files --------136 else:137 types = {138 "PDF": ["pdf"],139 "DOCX": ["docx", "doc"],140 "TXT": ["txt"]141 }142 uploaded = st.file_uploader(143 "Upload files",144 type=types[input_type],145 accept_multiple_files=True146 )147 if uploaded:148 inputs.extend(uploaded)149 150 # -------- Build Vectorstore --------151 if st.button("Create Knowledge Base") and inputs:152 with st.spinner("Processing documents..."):153 st.session_state.vectorstore = process_input(input_type, inputs)154 st.success("Knowledge base ready!")155 156 # -------- Ask Question --------157 if "vectorstore" in st.session_state:158 query = st.text_input("Ask a question")159 if st.button("Get Answer") and query:160 with st.spinner("Thinking..."):161 answer = answer_question(st.session_state.vectorstore, query)162 st.markdown("### โ
Answer")163 st.write(answer)164 165if __name__ == "__main__":166 main()167 