CoolFace
Apppublic

abdurrouf14/QuestionAnswering

sourceHugging Faceupdated 8mo agoView on Hugging Face
0likes
app.py167 linesDownload Raw Back to root
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