I have written a code to create a PDF QA Bot. The code for it is - “”“import numpy as np
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.document_loaders import PyPDFLoader
from langchain import HuggingFacePipeline
from langchain import PromptTemplate
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferWindowMemory
from sentence_transformers import SentenceTransformer
import gradio as gr
from langchain_community.vectorstores import FAISS

#nltk.download()
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, pipeline, TextStreamer


def create_multipage_pdf(text, filename=‘output.pdf’, font_size=12, margin=50):
# Split text into chunks that fit on one page
chunks = []
chunk_size = 50 # Number of characters per chunk
for i in range(0, len(text), chunk_size):
chunks.append(text[i:i+chunk_size])

# Create PDF
c = canvas.Canvas(filename, pagesize=letter)
width, height = letter
y = height - margin
for chunk in chunks:
# Draw text
text_object = c.beginText(margin, y)
text_object.setFont(“Helvetica”, font_size)
text_object.textLines(chunk)
c.drawText(text_object)

# Update y position
y -= (font_size + 4) # Adjust spacing between lines

# Check if we need to start a new page
if y <= margin:
c.showPage()
y = height - margin

c.save()

# Example usage
#create_multipage_pdf(text, filename=‘document.pdf’)

bnb_config = BitsAndBytesConfig(load_in_4bit=True,
bnb_4bit_quant_type=“nf4”,
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=False)

model_id = “meta-llama/Llama-2-7b-chat-hf”

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config = bnb_config,device_map={”“:0})

import json
import textwrap

B_INST, E_INST = “
”, “
”
B_SYS, E_SYS = “
\n”, “\n
\n\n”
DEFAULT_SYSTEM_PROMPT = “””<br/>You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.

If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don’t know the answer to a question, please don’t share false information.“”“



def get_prompt(instruction, new_system_prompt=DEFAULT_SYSTEM_PROMPT ):
SYSTEM_PROMPT = B_SYS + new_system_prompt + E_SYS
prompt_template = B_INST + SYSTEM_PROMPT + instruction + E_INST
return prompt_template


loader = PyPDFLoader(“document.pdf”)

text_splitter = RecursiveCharacterTextSplitter(
# Set a really small chunk size, just to show.
chunk_size = 500,
chunk_overlap = 20,
length_function = len,
)

pages = loader.load_and_split(text_splitter)
# testing with embeddings
embeddings = HuggingFaceEmbeddings(model_name=“hkunlp/instructor-xl”, model_kwargs={‘device’: ‘cuda’})
#embeddings = HuggingFaceEmbeddings(model_name=“sentence-transformers/all-mpnet-base-v2”, model_kwargs={‘device’: ‘cuda’})
print(“OK1”)
db = FAISS.from_documents(pages, embedding=embeddings)
#db = Chroma.from_documents(pages, embedding=embeddings)
print(“OK2”)
instruction = “Given the context that has been provided. \n {context}, Answer the following question - \n{question}”

# This part was remove from first line of the system_prompt for testing purposes. Be precise in your answers wherever possible.
system_prompt = “”“You are an honest virtual assistant. You will be given a context to answer from. In case you are sure you don’t know the answer then you say that based on the context you don’t know the answer. In all other instances you provide an answer to the best of your capability. Cite context when you can access them maintaining formatting. Don’t say 'based on the context provided more than once.””“

get_prompt(instruction, system_prompt)

”“”## Setting up with LangChain"“”

template = get_prompt(instruction, system_prompt)
print(template)

prompt = PromptTemplate(template=template, input_variables=[“context”, “question”])

memory = ConversationBufferWindowMemory(
memory_key=“chat_history”, k=5,
return_messages=True
)

retriever = db.as_retriever(search_kwargs={‘k’: 10})

def create_pipeline(max_new_tokens=1024):
pipe = pipeline(“text-generation”,
model=model,
tokenizer = tokenizer,
max_new_tokens = max_new_tokens,
temperature = 0.6)
return pipe

class ChessBot:
# send re_ranked docs instead of retriever for advanced RAG
def init(self, memory, prompt, task:str = “text-generation”, retriever = retriever):
self.memory = memory
self.prompt = prompt
self.retriever = retriever



def create_chat_bot(self, max_new_tokens = 1024):
hf_pipe = create_pipeline(max_new_tokens)
llm = HuggingFacePipeline(pipeline =hf_pipe)
qa = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=self.retriever,
memory=self.memory,
combine_docs_chain_kwargs={“prompt”: self.prompt}
)
return qa

chess_bot = ChessBot(memory = memory, prompt = prompt)

bot = chess_bot.create_chat_bot()



def clear_llm_memory():
bot.memory.clear()

def update_prompt(sys_prompt):
if sys_prompt == “”:
sys_prompt = system_prompt
template = get_prompt(instruction, sys_prompt)

prompt = PromptTemplate(template=template, input_variables=[“context”, “question”])

bot.combine_docs_chain.llm_chain.prompt = prompt

“”“1. Not using API
2. Use cases are not defined
3. Just a POC emphasis
”“”

with gr.Blocks() as demo:
gr.Markdown(
“”“
#
Please ask your questions!
“””)
# Commenting update prompt option
#update_sys_prompt = gr.Textbox(label = “Update System Prompt”)
chatbot = gr.Chatbot(label=“SAMSUNG SDS”, height = 300)
msg = gr.Textbox(label = “Enter your query!”)
with gr.Column(scale=1):
clear = gr.ClearButton([msg, chatbot])
with gr.Column(scale=1):
clear_memory = gr.Button(value = “Clear LLM Memory”)

def respond(message, chat_history):
print(“Query:::”, message)
bot_message = bot({“question”: message})[‘answer’]
chat_history.append((message, bot_message))
return “”, chat_history

msg.submit(respond, inputs=[msg, chatbot], outputs=[msg, chatbot])
clear_memory.click(clear_llm_memory)
# Commenting update prompt option
#update_sys_prompt.submit(update_prompt, inputs=update_sys_prompt)

demo.launch(share=False, server_name=‘216.48.177.144’, server_port=8502)
“”“. Now, I want to incorporate this logic to my existing code - “”“from langchain.document_transformers import LongContextReorder
from langchain.retrievers import ContextualCompressionRetriever, DocumentCompressorPipeline


reordering = LongContextReorder()

pipeline_compressor = DocumentCompressorPipeline(
transformers=[
reordering
]
)

compression_retriever = ContextualCompressionRetriever(base_compressor=pipeline_compressor, base_retriever=vector_store.as_retriever())

qa = ConversationalRetrievalChain.from_llm(llm=llm, retriever=compression_retriever, memory=memory, return_source_documents=True)””". Rewrite the complete code using this logic. You can skip the gradio and import part