File size: 5,286 Bytes
b8cf42f 54ccae4 b8cf42f 1a96650 b8cf42f c862bc5 b8cf42f 1a96650 b8cf42f b817be5 b8cf42f 964c97e 5bbe733 b8cf42f 5bbe733 b8cf42f 5bbe733 b8cf42f 547aa0d b8cf42f 5bbe733 | 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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | # from ibm_watsonx_ai.foundation_models import ModelInference
# from ibm_watsonx_ai.metanames import GenTextParamsMetaNames as GenParams
# from ibm_watsonx_ai.metanames import EmbedTextParamsMetaNames
# from ibm_watsonx_ai import Credentials
# from langchain_ibm import WatsonxLLM, WatsonxEmbeddings
# from langchain.text_splitter import RecursiveCharacterTextSplitter
# from langchain_text_splitters import RecursiveCharacterTextSplitter
import uuid
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import PyPDFLoader
# from langchain.chains import RetrievalQA
from langchain_classic.chains import RetrievalQA
from langchain_community.llms import HuggingFacePipeline
from langchain_community.embeddings import HuggingFaceEmbeddings
# from langchain_huggingface import HuggingFacePipeline
import torch
from huggingface_hub import HfFolder
from huggingface_hub import hf_hub_download
from langchain_community.llms import LlamaCpp
import gradio as gr
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline, BitsAndBytesConfig
## You can use this section to suppress warnings generated by your code:
def warn(*args, **kwargs):
pass
import warnings
warnings.warn = warn
warnings.filterwarnings('ignore')
## LLM
# def get_llm():
# model_id = 'ibm/granite-3-2-8b-instruct'
# parameters = {
# GenParams.MAX_NEW_TOKENS: 256, # This controls the maximum number of tokens in the generated output
# GenParams.TEMPERATURE: 0.5, # This controls randomness or creativity of the model's responses
# }
# project_id = 'skills-network'
# watsonx_llm = WatsonxLLM(
# model_id = model_id,
# url="https://us-south.ml.cloud.ibm.com",
# project_id = project_id,
# params = parameters,
# )
# return watsonx_llm
LLM_INSTANCE = None
def get_llm():
global LLM_INSTANCE
if LLM_INSTANCE is not None:
return LLM_INSTANCE
# Download quantized GGUF model (works on CPU)
model_path = hf_hub_download(
repo_id="TheBloke/Mistral-7B-Instruct-v0.3-GGUF",
filename="mistral-7b-instruct-v0.3.Q4_K_M.gguf",
local_dir=".",
local_dir_use_symlinks=False,
)
llm = LlamaCpp(
model_path=model_path,
n_ctx=4096,
n_threads=4,
temperature=0.3,
top_p=0.9,
verbose=False,
)
LLM_INSTANCE = llm
return llm
## Document loader
def document_loader(file):
loader = PyPDFLoader(file)
loaded_document = loader.load()
return loaded_document
## Text splitter
def text_splitter(data):
text_splitter = RecursiveCharacterTextSplitter(
chunk_size = 1000,
chunk_overlap = 50,
length_function = len,
)
chuncks = text_splitter.split_documents(data)
return chuncks
## Embedding model
# def watsonx_embedding():
# embed_params = {
# EmbedTextParamsMetaNames.TRUNCATE_INPUT_TOKENS: 256,
# EmbedTextParamsMetaNames.RETURN_OPTIONS: {'input_text': True},
# }
# watsonx_embedding = WatsonxEmbeddings(
# model_id = "ibm/slate-125m-english-rtrvr-v2",
# url="https://us-south.ml.cloud.ibm.com",
# project_id = "skills-network",
# params = embed_params,
# )
# return watsonx_embedding
def watsonx_embedding():
model_id = 'sentence-transformers/all-MiniLM-L6-v2'
embedding_model = HuggingFaceEmbeddings(model_name=model_id)
return embedding_model
## Vector db
def vector_database(chunks):
chunks = [
c for c in chunks
if c.page_content and c.page_content.strip() and len(c.page_content.strip()) > 10
]
embedding_model = watsonx_embedding()
# We add 'collection_name' with a random ID (uuid)
# This forces Chroma to create a brand new, empty bucket for every PDF
vectordb = Chroma.from_documents(
documents=chunks,
embedding=embedding_model,
collection_name=f"pdf_chat_{uuid.uuid4().hex}"
)
return vectordb
## Retriever
def retriever(file):
splits = document_loader(file)
chunks = text_splitter(splits)
vectordb = vector_database(chunks)
retriever = vectordb.as_retriever()
return retriever
## QA Chain
def retriever_qa(file, query):
llm = get_llm()
retriever_obj = retriever(file)
qa = RetrievalQA.from_chain_type(
llm = llm,
chain_type = 'stuff',
retriever = retriever_obj,
return_source_documents = False
)
response = qa.invoke(query)
return response['result']
## Create Gradio interface
rag_application = gr.Interface(
fn = retriever_qa,
# allow_flagging = 'never',
flagging_mode = 'never',
inputs = [
gr.File(label = 'Upload PDF File', file_count = 'single', file_types = ['.pdf'], type ='filepath'), # Drag and drop file upload
gr.Textbox(label= 'Input Query', lines = 2, placeholder = 'Type your question here...')
],
outputs = gr.Textbox(label = 'Ouput'),
title= 'PDF QA Chatbot',
description = 'Upload a PDF document and ask any question. The chatbot will try to answer using the provided document.'
)
# Launch the app
rag_application.launch()
|