File size: 3,892 Bytes
abb24bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# Import necessary libraries
import gradio as gr
from langchain.document_loaders import OnlinePDFLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.llms import HuggingFaceHub
from langchain.embeddings import HuggingFaceHubEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA

# Define a function to display "Loading..." when loading a PDF
def loading_pdf():
    return "Loading..."

# Define a function to process PDF changes
def pdf_changes(pdf_doc, repo_id):
    # Initialize the OnlinePDFLoader to load the PDF document
    loader = OnlinePDFLoader(pdf_doc.name)
    documents = loader.load()

    # Split the loaded documents into chunks using CharacterTextSplitter
    text_splitter = CharacterTextSplitter(chunk_size=400, chunk_overlap=50)
    texts = text_splitter.split_documents(documents)

    # Initialize HuggingFaceHubEmbeddings for embeddings
    embeddings = HuggingFaceHubEmbeddings()

    # Create a Chroma vector store from the text chunks and embeddings
    db = Chroma.from_documents(texts, embeddings)

    # Convert the vector store to a retriever
    retriever = db.as_retriever()

    # Initialize an HuggingFaceHub language model (LLM)
    llm = HuggingFaceHub(repo_id=repo_id, model_kwargs={"temperature": 0.25, "max_new_tokens": 1000})

    # Create a RetrievalQA chain with the LLM, retriever, and return_source_documents option
    global qa
    qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=True)

    return "Ready"

# Define a function to add text to a history
def add_text(history, text):
    history = history + [(text, None)]
    return history, ""

# Define a bot function to generate responses
def bot(history):
    response = infer(history[-1][0])
    history[-1][1] = response['result']
    return history

# Define an inference function to query the LLM
def infer(query):
    result = qa({"query": query})
    return result

# Define custom CSS styles
css = """
#col-container {max-width: 700px; margin-left: auto; margin-right: auto;}
"""

# Define a title HTML for the interface
title = """
<div style="text-align: center;max-width: 700px;">
    <h1>Chat with PDF</h1>
    <p style="text-align: center;">Upload a .PDF from your computer, click the "Load PDF to LangChain" button, <br />
    when everything is ready, you can start asking questions about the PDF ;)</p>
"""

# Create the Gradio interface
with gr.Blocks(css=css) as demo:
    with gr.Column(elem_id="col-container"):
        gr.HTML(title)

        with gr.Column():
            # Create a file input for loading PDF
            pdf_doc = gr.File(label="Load a PDF", file_types=['.pdf'], type="file", value="AhmedS_Resume.pdf")

            # Create a dropdown for selecting the LLM
            repo_id = gr.Dropdown(label="LLM", choices=["HuggingFaceH4/zephyr-7b-alpha", "CausalLM/14B", "meta-llama/Llama-2-7b-chat-hf"], value="HuggingFaceH4/zephyr-7b-alpha")

            with gr.Row():
                langchain_status = gr.Textbox(label="Status", placeholder="Waiting...", interactive=False)
                load_pdf = gr.Button("Load PDF to LangChain")

        chatbot = gr.Chatbot([], elem_id="chatbot").style(height=350)
        query = gr.Textbox(label="Question", placeholder="Type your question and hit Enter ")
        submit_btn = gr.Button("Send message")

    # Set up actions for UI elements
    repo_id.change(pdf_changes, inputs=[pdf_doc, repo_id], outputs=[langchain_status], queue=False)
    load_pdf.click(pdf_changes, inputs=[pdf_doc, repo_id], outputs=[langchain_status], queue=False)
    question.submit(add_text, [chatbot, question], [chatbot, question]).then(bot, chatbot, chatbot)
    submit_btn.click(add_text, [chatbot, question], [chatbot, question]).then(bot, chatbot, chatbot)

# Launch the Gradio interface
demo.launch()