From 8bf2bd93355bb872af89743afa6f78bd93095c9e Mon Sep 17 00:00:00 2001 From: bhaskarturkar <150421011+bhaskarturkar@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:04:16 +0530 Subject: [PATCH 01/32] Update README.md --- README.md | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 5178ee42..2d1cc011 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,6 @@ -# oneAPI-GenAI-Hackathon-2023 - Hack2Skill - -Welcome to the official repository for the oneAPI-GenAI-Hackathon-2023 organized by Hack2Skill! - -## Getting Started - -To get started with the oneAPI-GenAI-Hackathon-2023 repository, follow these steps: - -### Submission Instruction: - 1. Fork this repository - 2. Create a folder with your Team Name - 3. Upload all the code and necessary files in the created folder - 4. Upload a **README.md** file in your folder with the below mentioned informations. - 5. Generate a Pull Request with your Team Name. (Example: submission-XYZ_team) - -### README.md must consist of the following information: - -#### Team Name - -#### Problem Statement - -#### Team Leader Email - +#### Team Name - Team Affine +#### Problem Statement - Generative AI Large Language Models Fine Tuned For Legal Practice Platform +#### Team Leader Email - jayanth.ajay@affine.ai ### A Brief of the Prototype: This section must include UML Diagrams and prototype description From c3cc4f94f03a9c1a55f8c7f3c9b15ccc74fcb4c6 Mon Sep 17 00:00:00 2001 From: bhaskarturkar <150421011+bhaskarturkar@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:05:08 +0530 Subject: [PATCH 02/32] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2d1cc011..96e6ade9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -#### Team Name - Team Affine -#### Problem Statement - Generative AI Large Language Models Fine Tuned For Legal Practice Platform -#### Team Leader Email - jayanth.ajay@affine.ai +#### Team Name - **Team Affine** +#### Problem Statement - **Generative AI Large Language Models Fine Tuned For Legal Practice Platform** +#### Team Leader Email - **jayanth.ajay@affine.ai** ### A Brief of the Prototype: This section must include UML Diagrams and prototype description From 0f4771844d0f7af3ccf2f963e033038ae90992cf Mon Sep 17 00:00:00 2001 From: bhaskarturkar <150421011+bhaskarturkar@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:05:29 +0530 Subject: [PATCH 03/32] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 96e6ade9..2d1cc011 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -#### Team Name - **Team Affine** -#### Problem Statement - **Generative AI Large Language Models Fine Tuned For Legal Practice Platform** -#### Team Leader Email - **jayanth.ajay@affine.ai** +#### Team Name - Team Affine +#### Problem Statement - Generative AI Large Language Models Fine Tuned For Legal Practice Platform +#### Team Leader Email - jayanth.ajay@affine.ai ### A Brief of the Prototype: This section must include UML Diagrams and prototype description From 7b3a2bc88ca64759a4d87484d250a7de813f855a Mon Sep 17 00:00:00 2001 From: bhaskarturkar <150421011+bhaskarturkar@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:19:54 +0530 Subject: [PATCH 04/32] Update README.md Stack added --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2d1cc011..7282aaef 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,19 @@ This section must include UML Diagrams and prototype description ### Tech Stack: - List Down all technologies used to Build the prototype + Technologies used (Mark down oneAPI AI Analytics libraries used) +1.Python +2.Hugging Face +3.ChromaDB +4.Langchain +5.Open-docx +6.PyPDF +7.Pytorch + +8.Intel OpenVINO +9.Intel OpenDNN +10.Intel OneAPI Base Toolkit + ### Step-by-Step Code Execution Instructions: This Section must contain a set of instructions required to clone and run the prototype so that it can be tested and deeply analyzed From 6207bdae2362d5f1acef9db4aa14599a9b9f3013 Mon Sep 17 00:00:00 2001 From: bhaskarturkar <150421011+bhaskarturkar@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:21:46 +0530 Subject: [PATCH 05/32] Update README.md --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 7282aaef..7dc12ede 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,18 @@ This section must include UML Diagrams and prototype description ### Tech Stack: - Technologies used (Mark down oneAPI AI Analytics libraries used) -1.Python -2.Hugging Face -3.ChromaDB -4.Langchain -5.Open-docx -6.PyPDF -7.Pytorch + Technologies used (Mark down oneAPI AI Analytics libraries used)
+1.Python
+2.Hugging Face
+3.ChromaDB
+4.Langchain
+5.Open-docx
+6.PyPDF
+7.Pytorch
-8.Intel OpenVINO -9.Intel OpenDNN -10.Intel OneAPI Base Toolkit +8.Intel OpenVINO
+9.Intel OpenDNN
+10.Intel OneAPI Base Toolkit
### Step-by-Step Code Execution Instructions: From 8deefaf4f450ffeee1a6f208bd46330137e6903e Mon Sep 17 00:00:00 2001 From: bhaskarturkar <150421011+bhaskarturkar@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:57:04 +0530 Subject: [PATCH 06/32] Add files via upload added flow diagram. --- process-flow-diagram.JPG | Bin 0 -> 52906 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 process-flow-diagram.JPG diff --git a/process-flow-diagram.JPG b/process-flow-diagram.JPG new file mode 100644 index 0000000000000000000000000000000000000000..7c3efb515c286b416e026e663456340ecdbf7bd3 GIT binary patch literal 52906 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 literal 0 HcmV?d00001 From 70b43b985e8def3cd9fc0eab9e2c6fe06c3b93e3 Mon Sep 17 00:00:00 2001 From: bhaskarturkar <150421011+bhaskarturkar@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:59:14 +0530 Subject: [PATCH 07/32] Update README.md added flow diagram --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7dc12ede..ca18d321 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,9 @@ #### Team Leader Email - jayanth.ajay@affine.ai ### A Brief of the Prototype: - This section must include UML Diagrams and prototype description + ![Image](https://github.com/bhaskarturkar/oneAPI-GenAI-Hackathon-2023/blob/main/process-flow-diagram.JPG) + + ### Tech Stack: Technologies used (Mark down oneAPI AI Analytics libraries used)
From bcdfecf09d78d887ce90b9809e4111474f2fae05 Mon Sep 17 00:00:00 2001 From: bhaskarturkar <150421011+bhaskarturkar@users.noreply.github.com> Date: Wed, 6 Dec 2023 20:04:50 +0530 Subject: [PATCH 08/32] Add files via upload --- images/affine.jpg | Bin 0 -> 19437 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/affine.jpg diff --git a/images/affine.jpg b/images/affine.jpg new file mode 100644 index 0000000000000000000000000000000000000000..774067648cbb049413529fc294028fbadf1fe487 GIT binary patch literal 19437 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 IM6N<$f(#;|HUIzs literal 0 HcmV?d00001 From 9f7e3df3d6088ec69152bf415f2565310656db18 Mon Sep 17 00:00:00 2001 From: bhaskarturkar <150421011+bhaskarturkar@users.noreply.github.com> Date: Wed, 6 Dec 2023 20:08:32 +0530 Subject: [PATCH 09/32] Add files via upload --- Homepage.py | 60 ++++++ pages/compare_doc.py | 475 +++++++++++++++++++++++++++++++++++++++++++ src/entity.py | 153 ++++++++++++++ 3 files changed, 688 insertions(+) create mode 100644 Homepage.py create mode 100644 pages/compare_doc.py create mode 100644 src/entity.py diff --git a/Homepage.py b/Homepage.py new file mode 100644 index 00000000..54602a25 --- /dev/null +++ b/Homepage.py @@ -0,0 +1,60 @@ +import streamlit as st +from PIL import Image + +img = Image.open("images/affine.jpg") + +page_config = {"page_title":"Contract_comparison_tool.io","page_icon":img,"layout":"wide"} + +st.set_page_config(**page_config) + +## Divide the user interface into two parts: column 1 (small) and column 2 (large). +#"""This code assigns the st.columns([1, 8]) statement to the variables col1 and col2, +#which divide the user interface into two columns. Column 1 will be smaller in width, +# while column 2 will be larger. +#""" + +hide_streamlit_style = """ + + """ +st.markdown(hide_streamlit_style, unsafe_allow_html=True) + +col1, col2,col3,col4 = st.columns([2.5,2.5,8.5,0.5]) +with col1: + st.write(' ') +with col2: + #img = Image.open("images/affine.jpg") + st.image(img,width = 130) + +with col3: + st.markdown(""" +

+ + Contract Comparator + +""", unsafe_allow_html=True) +with col4: + st.write(' ') + +st.write("\n") +st.write("\n") +st.write("\n") +st.write("\n") +st.write("\n") +st.write("\n") +st.write("**It is a tool that can compare two different versions of the same contract and mention all the major changes that were made between the two documents .**") + + + # key=col1._text_input() + # Left column: Upload PDF text + # st.header("Dashboard") + + + +# Extract the text from uploaded pdf diff --git a/pages/compare_doc.py b/pages/compare_doc.py new file mode 100644 index 00000000..69fc5fbe --- /dev/null +++ b/pages/compare_doc.py @@ -0,0 +1,475 @@ +from langchain.embeddings import HuggingFaceEmbeddings +from langchain import HuggingFacePipeline +import sys +import site +from pathlib import Path +import os +from langchain.embeddings import HuggingFaceEmbeddings +from langchain import HuggingFacePipeline +import logging +import os +import random +import re +import warnings +import torch +import intel_extension_for_pytorch as ipex + +from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline +from transformers import LlamaTokenizer, LlamaForCausalLM +from transformers import BertTokenizer, BertForSequenceClassification +from langchain import HuggingFacePipeline + + +from langchain.chains import RetrievalQA +from langchain.chains.question_answering import load_qa_chain +from langchain.indexes import VectorstoreIndexCreator +import base64 +import streamlit as st +import os +# import json +from pathlib import Path +# import ast + +from langchain.chains import RetrievalQA +from langchain.document_loaders import PyPDFLoader +from langchain.text_splitter import RecursiveCharacterTextSplitter +from langchain.vectorstores import Chroma +from langchain.prompts import PromptTemplate +from prettytable import PrettyTable as pt +from dotenv import load_dotenv +import time +from langchain.document_loaders import PyPDFLoader +from PIL import Image +import pathlib +from PyPDF2 import PdfReader +import src.entity as entity +from src.entity import QAModel +import shutil +import logging +from difflib import SequenceMatcher +import re + + + +# Suppress warnings for a cleaner output +warnings.filterwarnings("ignore") +# os.environ['TRANSFORMERS_CACHE'] = './my_llama_model' +os.environ["SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS"] = "1" +os.environ["ENABLE_SDP_FUSION"] = "1" + +# Get Python version +def get_python_version(): + return "python" + ".".join(map(str, sys.version_info[:2])) + +# Set local binary path for system paths +def set_local_bin_path(): + local_bin = str(Path.home() / ".local" / "bin") + local_site_packages = str( + Path.home() / ".local" / "lib" / get_python_version() / "site-packages" + ) + sys.path.append(local_bin) + sys.path.insert(0, site.getusersitepackages()) + sys.path.insert(0, sys.path.pop(sys.path.index(local_site_packages))) + +set_local_bin_path() + +# Check if Torch XPU is available and set seed +if torch.xpu.is_available(): + seed = 88 + random.seed(seed) + torch.xpu.manual_seed(seed) + torch.xpu.manual_seed_all(seed) + +def select_device(preferred_device=None): + """ + Selects the best available XPU device or the preferred device if specified. + + Args: + preferred_device (str, optional): Preferred device string (e.g., "cpu", "xpu", "xpu:0", "xpu:1", etc.). If None, a random available XPU device will be selected or CPU if no XPU devices are available. + + Returns: + torch.device: The selected device object. + """ + try: + if preferred_device and preferred_device.startswith("cpu"): + print("Using CPU.") + return torch.device("cpu") + if preferred_device and preferred_device.startswith("xpu"): + if preferred_device == "xpu" or ( + ":" in preferred_device + and int(preferred_device.split(":")[1]) >= torch.xpu.device_count() + ): + preferred_device = ( + None # Handle as if no preferred device was specified + ) + else: + device = torch.device(preferred_device) + if device.type == "xpu" and device.index < torch.xpu.device_count(): + vram_used = torch.xpu.memory_allocated(device) / ( + 1024**2 + ) # In MB + print( + f"Using preferred device: {device}, VRAM used: {vram_used:.2f} MB" + ) + return device + + if torch.xpu.is_available(): + device_id = random.choice( + range(torch.xpu.device_count()) + ) # Select a random available XPU device + device = torch.device(f"xpu:{device_id}") + vram_used = torch.xpu.memory_allocated(device) / (1024**2) # In MB + print(f"Selected device: {device}, VRAM used: {vram_used:.2f} MB") + return device + except Exception as e: + print(f"An error occurred while selecting the device: {e}") + print("No XPU devices available or preferred device not found. Using CPU.") + return torch.device("cpu") + +########################################################################################### +# Cache path for the model +MODEL_CACHE_PATH = "./my_llama_model" + +class hf_model(): + """ + ChatBotModel is a class for generating responses based on text prompts using a pretrained model. + + Attributes: + - device: The device to run the model on. Default is "xpu" if available, otherwise "cpu". + - model: The loaded model for text generation. + - tokenizer: The loaded tokenizer for the model. + - torch_dtype: The data type to use in the model. + """ + + def __init__( + self, + model_id_or_path: str ="meta-llama/Llama-2-7b-chat-hf",#"meta-llama/Llama-2-13b-chat-hf",#"circulus/Llama-2-13b-orca-v1", #"my_llama_model",# "circulus/Llama-2-13b-orca-v1",#"microsoft/Orca-2-13b",#"01-ai/Yi-34B",#"bhenrym14/platypus-yi-34b",#"tiiuae/hf-7b-instruct", #"Intel/neural-chat-7b-v3-1", # "Writer/camel-5b-hf", #tiiuae/hf-7b-instruct + torch_dtype: torch.dtype = torch.bfloat16, + optimize: bool = True, + ) -> None: + """ + The initializer for ChatBotModel class. + + Parameters: + - model_id_or_path: The identifier or path of the pretrained model. + - torch_dtype: The data type to use in the model. Default is torch.bfloat16. + - optimize: If True, ipex is used to optimized the model + """ + self.torch_dtype = torch_dtype + self.device = select_device("xpu") + self.model_id_or_path = model_id_or_path + # local_model_id = self.model_id_or_path.replace("/", "--") + # model_id_or_path = os.path.join(MODEL_CACHE_PATH, local_model_id) #local_model_path = "meta-llama/Llama-2-13b-chat-hf" + # local_model_path = "my-model" + # model_id_or_path = "meta-llama/Llama-2-13b-chat-hf" + local_model_id = self.model_id_or_path.replace("/", "--") + local_model_path = os.path.join(MODEL_CACHE_PATH, local_model_id) + + if ( + self.device == self.device.startswith("xpu") + if isinstance(self.device, str) + else self.device.type == "xpu" + ): + + self.autocast = torch.xpu.amp.autocast + else: + self.autocast = torch.cpu.amp.autocast + self.torch_dtype = torch_dtype + try: + if "llama" in model_id_or_path: + self.tokenizer = LlamaTokenizer.from_pretrained(local_model_path,use_auth_token=token,cache_dir="my_llama_model/") + self.model = ( + LlamaForCausalLM.from_pretrained( + local_model_path,use_auth_token=token, + low_cpu_mem_usage=True, + torch_dtype=self.torch_dtype,cache_dir="my_llama_model/" + ) + .to(self.device) + .eval() + ) + else: + self.tokenizer = AutoTokenizer.from_pretrained( + local_model_path, trust_remote_code=True,cache_dir="my_llama_model/" + ) + self.model = ( + AutoModelForCausalLM.from_pretrained( + local_model_path, + low_cpu_mem_usage=True, + trust_remote_code=True, + torch_dtype=self.torch_dtype,cache_dir="my_llama_model/" + ) + .to(self.device) + .eval() + ) + except (OSError, ValueError, EnvironmentError) as e: + logging.info( + f"Tokenizer / model not found locally. Downloading tokenizer / model for {self.model_id_or_path} to cache...: {e}" + ) + if "llama" in model_id_or_path: + self.tokenizer = LlamaTokenizer.from_pretrained(self.model_id_or_path,use_auth_token=token,cache_dir="my_llama_model/") + self.model = ( + LlamaForCausalLM.from_pretrained( + self.model_id_or_path, + low_cpu_mem_usage=True,use_auth_token=token, + torch_dtype=self.torch_dtype,cache_dir="my_llama_model/" + ) + .to(self.device) + .eval() + ) + else: + self.tokenizer = AutoTokenizer.from_pretrained( + self.model_id_or_path, trust_remote_code=True,cache_dir="my_llama_model/" + ) + self.model = ( + AutoModelForCausalLM.from_pretrained( + self.model_id_or_path, + low_cpu_mem_usage=True, + trust_remote_code=True, + torch_dtype=self.torch_dtype,cache_dir="my_llama_model/" + ) + .to(self.device) + .eval() + ) + + + + self.max_length = 256 + + if optimize: + if hasattr(ipex, "optimize_transformers"): + try: + ipex.optimize_transformers(self.model, dtype=self.torch_dtype) + except: + ipex.optimize(self.model, dtype=self.torch_dtype) + else: + ipex.optimize(self.model, dtype=self.torch_dtype) + + + def generate_text(self): + gt = pipeline(task="text-generation", model=self.model, tokenizer=self.tokenizer) + + return gt +################################################################# + +# HuggingFacePipeline for the Model +token = "hugging face token" +# LangChain HuggingFacePipeline set to our transformer pipeline +hf_model_obj=hf_model() +hf_pipeline = HuggingFacePipeline(pipeline=hf_model_obj.generate_text()) + +# Image for the Streamlit page +img = Image.open("images/affine.jpg") + +# Streamlit page configuration +page_config = {"page_title":"invoice_tool.io","page_icon":img,"layout":"wide"} +st.set_page_config(**page_config) + +## Divide the user interface into two parts: column 1 (small) and column 2 (large). +#"""This code assigns the st.columns([1, 8]) statement to the variables col1 and col2, +#which divide the user interface into two columns. Column 1 will be smaller in width, +# while column 2 will be larger. +#""" + +hide_streamlit_style = """ + + """ +st.markdown(hide_streamlit_style, unsafe_allow_html=True) + +col1, col2,col3,col4 = st.columns([2.5,2.5,8.5,0.5]) +with col1: + st.write(' ') +with col2: + #img = Image.open("images/affine.jpg") + st.image(img,width = 130) + +with col3: + st.markdown(""" +

+ + Contract Comparator + +

+ +""", unsafe_allow_html=True) + + st.write("**Get Comparison of two contracts**") + +with col4: + st.write(' ') + +st.write("\n") +st.write("\n") + +path = "data/Contracts/" + +with st.sidebar: + # key=col1._text_input() + # Left column: Upload PDF text + # st.header("Dashboard") + st.markdown(""" +
+

+ + Contract Comparator + + + + +

+
+""", unsafe_allow_html=True) + + subdirs = os.listdir(path) + subdirs.insert(0,"Select2") + subdirs.insert(0,"Select1") + + print(subdirs) + doc1 = st.selectbox('**Pick the First document :**', sorted(subdirs), key="0") + + doc2 = st.selectbox('**Pick the Second document :**', sorted(subdirs), key="1") + if doc1 !="Select" and doc2 !="Select": + + st.write("**Click the below button if you want to compare two documents :**") + trigger_1 = st.button("Compare") + + st.write("\n") + st.write("\n") + + + +qa_model=QAModel() + + +file_1 = f"{path}{doc1}" +file_2 = f"{path}{doc2}" + +footer = """ """ +special_characters = r"[]{}()^$.*+?|\\" + + # Escape special characters by adding a backslash before them +escaped_string = re.sub(f"[{''.join(re.escape(char) for char in special_characters)}]", r"\\\g<0>", footer) +pattern = re.sub(r'\s+', r'\\s*', escaped_string) +replacement = " footer " + +if trigger_1 : + + if os.path.exists('.chroma'): + shutil.rmtree('.chroma') + + # Load file one and store the embeddings + + pdf_reader1=PyPDFLoader(file_1) + #documents1 = pdf_reader1.load() + if file_1 is not None: + pdf_reader = PdfReader(file_1) + print('PDF LOADED') + documents1 = "" + for page in pdf_reader.pages: + documents1 += ' '.join(page.extract_text().splitlines()) + # split into chunks + documents1 = re.sub(pattern, replacement, documents1) + document_chunks1=qa_model.document_splitter_assistant(documents1,user_input_chunk_size = 2000,user_input_chunk_overlap = 300) + + vectorstore_doc1 = qa_model.create_embedding_assistant(document_chunks1) + pdf_reader2=PyPDFLoader(file_2) + if file_2 is not None: + pdf_reader = PdfReader(file_2) + print('PDF LOADED') + documents2 = "" + for page in pdf_reader.pages: + #result = re.sub(pattern, replacement, page.extract_text()) + documents2 += ' '.join(page.extract_text().splitlines()) + # split into chunks + + documents2 = re.sub(pattern, replacement, documents2) + document_chunks2=qa_model.document_splitter_assistant(documents2,user_input_chunk_size = 2000,user_input_chunk_overlap = 300) + + + # Define the retraiver + vectorstore_doc2=qa_model.create_embedding_assistant(document_chunks2) + + + st.write("Comparison : ") + st.write("\n") + changes =[] + changes_1 = [] + highlight_1 = [] + ct = 0 + for i in document_chunks2: + print("*"*100) + print("Chunk Counter : ") + text = i + print(i) + # QA Model to process the further things with each chunk of text + + query= "Find a context that matches the text : {}".format(text) + custom_prompt_template ="""Use the following pieces of context to answer the question at the end. Don't try to make up an answer that is not present in the document. + Below is the context provided to you: + {context} + You are an editor of a company who has to provide insight on the changes that were made in the new version of a document compared to the older version and + explain the changes. + Below is the old version of the document : + {text} + Compare the details of text containing older version of document with details of context containing the new version of document , and explain the + changes that were made in the text with reference to context in the below format : + • Change: If there are any difference between the text and context then explain the difference otherwise say 'None'. + + Dont add anything other than the above provided format + Question: {question} + Answer from the given document chunk. The answer for question is """ + + + llm=hf_pipeline + custom_prompt_template=custom_prompt_template + query=query + + PROMPT = PromptTemplate( + template = custom_prompt_template, input_variables = ["context","question"], + partial_variables={"text": text} + ) + chain_type_kwargs = {"prompt": PROMPT} + # retriever=chroma_db.as_retriever(type = "similarity", search_kwargs={"k":1}) + custom_qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", + retriever=vectorstore_doc1.as_retriever(type = "similarity",search_kwargs={"k":3}), + chain_type_kwargs=chain_type_kwargs, + return_source_documents = True) + + try: + response = custom_qa({"query": query}) + #st.write(response) + result = response['result'] + change = result.split("Change:")[-1] + + if change not in ["None"," None","• Change: None","None.","Change: None","""• Change: None + + The provided text matches the context in the document without any differences."""] : + changes.append(change) + j = i.split("footer") + if isinstance(j, str): + highlight_1.append(j) + else: + highlight_1.extend(j) + changes_1.append(change) + ct+=1 + st.write(str(ct)+'. '+change) + st.write('\n') + #st.write('\n') + except: + continue + st.write('\n') + st.write('\n') + path_1= qa_model.pdf_highlight(file_2,highlight_1) + qa_model.displayPDF(path_1) + st.write('\n') + st.write('\n') + diff --git a/src/entity.py b/src/entity.py new file mode 100644 index 00000000..eef8f253 --- /dev/null +++ b/src/entity.py @@ -0,0 +1,153 @@ +# Import necessary libraries and modules +from langchain.chains import RetrievalQA +import base64 +import os +import fitz +import json +from pathlib import Path +import ast +import streamlit as st +from langchain.chains import RetrievalQA +from langchain.document_loaders import PyPDFLoader +from langchain.text_splitter import RecursiveCharacterTextSplitter +from langchain.vectorstores import Chroma +from langchain.prompts import PromptTemplate +import chromadb +from prettytable import PrettyTable as pt +from langchain.embeddings import HuggingFaceEmbeddings +from langchain import HuggingFacePipeline + + +class QAModel: + def __init__(self): + pass + + + def displayPDF(self,file): + """ + Displays a PDF file in the browser. + + Parameters: + file (str): The path to the PDF file. + + Returns: + None + + """ + # Opening file from file path + with open(file, "rb") as f: + base64_pdf = base64.b64encode(f.read()).decode('utf-8') + + # Embedding PDF in HTML + #pdf_display = F'' + pdf_display = F'