|
import streamlit as st |
|
from langchain.embeddings import HuggingFaceEmbeddings |
|
from langchain.vectorstores import FAISS |
|
from langchain.text_splitter import RecursiveCharacterTextSplitter |
|
from langchain.llms import HuggingFacePipeline |
|
from langchain.schema import Document |
|
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, pipeline |
|
from sentence_transformers import SentenceTransformer |
|
import torch |
|
from io import BytesIO |
|
import fitz |
|
|
|
|
|
device = "cuda" if torch.cuda.is_available() else "cpu" |
|
|
|
|
|
embedding_model = "all-MiniLM-L6-v2" |
|
embeddings = HuggingFaceEmbeddings(model_name=embedding_model, model_kwargs={'device': 'cpu'}) |
|
|
|
|
|
model_name = "google/flan-t5-small" |
|
tokenizer = AutoTokenizer.from_pretrained(model_name) |
|
model = AutoModelForSeq2SeqLM.from_pretrained(model_name).to(device) |
|
|
|
|
|
generator = pipeline( |
|
"text2text-generation", |
|
model=model, |
|
tokenizer=tokenizer, |
|
device=0 if device == "cuda" else -1, |
|
model_kwargs={"max_length": 256, "temperature": 0.7} |
|
) |
|
|
|
llm = HuggingFacePipeline(pipeline=generator) |
|
|
|
|
|
def main(): |
|
st.title("Chat with Multiple PDFs") |
|
st.write("Upload PDF files and chat with them.") |
|
|
|
|
|
uploaded_files = st.file_uploader("Upload PDF Files", accept_multiple_files=True, type=["pdf"]) |
|
|
|
if uploaded_files: |
|
|
|
documents = [] |
|
for uploaded_file in uploaded_files: |
|
pdf_content = BytesIO(uploaded_file.read()) |
|
doc = fitz.open(stream=pdf_content, filetype="pdf") |
|
text = "" |
|
for page in doc: |
|
text += page.get_text() |
|
doc.close() |
|
|
|
|
|
documents.append(Document(page_content=text, metadata={"file_name": uploaded_file.name})) |
|
|
|
|
|
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100) |
|
chunks = text_splitter.split_documents(documents) |
|
|
|
|
|
vector_store = FAISS.from_documents(chunks, embeddings) |
|
|
|
|
|
st.write("You can now start chatting with your PDFs!") |
|
user_input = st.text_input("Ask a question:") |
|
|
|
if user_input: |
|
|
|
docs = vector_store.similarity_search(user_input, k=3) |
|
|
|
|
|
prompt = "\n".join([doc.page_content for doc in docs]) + "\n\n" + user_input |
|
|
|
|
|
try: |
|
response = generator(prompt, max_new_tokens=50, num_return_sequences=1)[0]["generated_text"] |
|
st.write(response) |
|
except torch.cuda.OutOfMemoryError: |
|
st.error("Out of memory. Try using a smaller model or fewer documents.") |
|
|
|
if __name__ == "__main__": |
|
main() |