dntwaritag commited on
Commit
ec2e940
·
verified ·
1 Parent(s): fe62881

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +233 -48
app.py CHANGED
@@ -1,64 +1,249 @@
1
- import gradio as gr
2
- from huggingface_hub import InferenceClient
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
8
 
 
 
 
 
 
 
 
9
 
10
- def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
- ):
18
- messages = [{"role": "system", "content": system_message}]
19
 
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
25
 
26
- messages.append({"role": "user", "content": message})
 
 
 
 
 
 
 
27
 
28
- response = ""
 
 
 
 
 
 
29
 
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
 
39
- response += token
40
- yield response
 
41
 
 
 
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
 
46
  demo = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
- ],
60
  )
61
 
62
-
63
  if __name__ == "__main__":
64
- demo.launch()
 
1
+ import os
 
2
 
3
+ # Get the secret key from the environment
4
+ groq_api_key = os.environ.get('legai')
5
+
6
+ ## LLM used for RAG
7
+ from langchain_groq import ChatGroq
8
+
9
+ llm = ChatGroq(model="llama-3.1-70b-versatile",api_key=groq_api_key )
10
+
11
+ from langchain.prompts import ChatPromptTemplate, PromptTemplate
12
+ from langchain.output_parsers import ResponseSchema, StructuredOutputParser
13
+
14
+ import PyPDF2
15
+ # Initialize required components
16
+ TEMPLATE = """
17
+ You are a helpful agent. Your task is to generate a meaningful question and an answer using the following provided "{context}"
18
+ You MUST obey the following criteria:
19
+ - No preamble.
20
+ - Restrict the question to the context information provided and provide answer with its details in summary.
21
+ - Do NOT create a question that cannot be answered from the context.
22
+ - Phrase the question so that it does NOT refer to specific context.
23
+ - For instance, do NOT use phrases like 'given the provided context' or 'in this work' in the question or 'according to the text' in the answer because if the question is asked elsewhere it would not be provided specific context. Replace these terms with specific details.
24
+ - Please do NOT repeat the provided context.
25
+ - Please Only generate a question and an answer without any sentence in advance such as "Here is the generated question and answer:".
26
+ - Please follow the JSON recommended format below.
27
+ - Please ensure that the output is a valid JSON object.
28
+ {format_instructions}
29
  """
 
 
 
30
 
31
+ prompt = ChatPromptTemplate.from_template(template=TEMPLATE)
32
+ response_schemas = [
33
+ {"name": "Question", "description": "The generated question from the provided context"},
34
+ {"name": "Answer", "description": "The corresponding answer from the provided context"}
35
+ ]
36
+ output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
37
+ format_instructions = output_parser.get_format_instructions(only_json=True)
38
 
39
+ # Folder containing PDF files
40
+ folder_path = "./"
 
 
 
 
 
 
 
41
 
42
+ # List to store questions and answers as tuples
43
+ data = []
 
 
 
44
 
45
+ # Function to extract text from PDF
46
+ def extract_text_from_pdf(pdf_path):
47
+ with open(pdf_path, "rb") as file:
48
+ reader = PyPDF2.PdfReader(file)
49
+ text = ""
50
+ for page in reader.pages:
51
+ text += page.extract_text()
52
+ return text
53
 
54
+ # Process each PDF in the folder
55
+ for filename in os.listdir(folder_path):
56
+ if filename.endswith(".pdf"):
57
+ pdf_path = os.path.join(folder_path, filename)
58
+ try:
59
+ # Extract text from the PDF
60
+ context = extract_text_from_pdf(pdf_path)
61
 
62
+ # Split context into manageable chunks (optional)
63
+ chunks = [context[i:i+200] for i in range(0, len(context), 200)]
 
 
 
 
 
 
64
 
65
+ for chunk in chunks:
66
+ # Format the messages
67
+ messages = prompt.format_messages(context=chunk, format_instructions=format_instructions)
68
 
69
+ # Invoke the LLM
70
+ response = llm.invoke(messages)
71
 
72
+ # Parse the response
73
+ output_dict = output_parser.parse(response.content)
74
+
75
+ # Extract question and answer
76
+ question = output_dict["Question"]
77
+ answer = output_dict["Answer"]
78
+
79
+ # Append question and answer as a tuple to the list
80
+ data.append((question, answer))
81
+
82
+ except Exception as e:
83
+ print(f"Error processing file {filename}: {e}")
84
+
85
+ import PyPDF2
86
+
87
+ # Function to extract text from a PDF
88
+ def extract_text_from_pdf(pdf_path):
89
+ with open(pdf_path, 'rb') as file:
90
+ reader = PyPDF2.PdfReader(file)
91
+ text = ""
92
+ for page in reader.pages:
93
+ text += page.extract_text()
94
+ return text
95
+
96
+ # Function to chunk text into pieces of max_length
97
+ def chunk_text(text, max_length=500):
98
+ return [text[i:i + max_length] for i in range(0, len(text), max_length)]
99
+
100
+ # Specify the path to the PDF file
101
+ pdf_path = "./LAW Nº 59 ON THE CRIME OF GENOCIDE IDEOLOGY AND RELATED CRIMES.pdf"
102
+ # List to hold context data
103
+ context_data = []
104
+
105
+ try:
106
+ # Extract text from the PDF
107
+ pdf_text = extract_text_from_pdf(pdf_path)
108
+
109
+ if pdf_text:
110
+ # Create chunks of 500 characters
111
+ chunks = chunk_text(pdf_text, max_length=500)
112
+
113
+ # Add each chunk to context_data list as plain strings
114
+ context_data = [] # Initialize the list
115
+ for chunk in chunks:
116
+ context_data.append(chunk) # Save each chunk as a string
117
+
118
+ # Print the context_data list
119
+ for entry in context_data:
120
+ print(entry)
121
+ print("-" * 40) # Separator for readability
122
+ else:
123
+ print("No text found in the PDF.")
124
+ except Exception as e:
125
+ print(f"Error reading the PDF: {e}")
126
+
127
+ context_data.extend(data)
128
+
129
+ processed_texts = []
130
+
131
+ for element in context_data:
132
+ if isinstance(element, tuple):
133
+ question, answer = element
134
+ processed_texts.append(f"Question: {question} Answer: {answer}")
135
+ elif isinstance(element, str):
136
+
137
+ processed_texts.append(element)
138
+ else:
139
+
140
+ processed_texts.append(str(element))
141
+
142
+ ## Embedding model!
143
+ from langchain_huggingface import HuggingFaceEmbeddings
144
+ embed_model = HuggingFaceEmbeddings(model_name="mixedbread-ai/mxbai-embed-large-v1")
145
+
146
+
147
+
148
+ # create vector store!
149
+ from langchain_chroma import Chroma
150
+
151
+ vectorstore = Chroma(
152
+ collection_name="laws_dataset", # Changed the name to be compliant
153
+ embedding_function=embed_model,
154
+ persist_directory="./",
155
+ )
156
+
157
+ vectorstore.get().keys()
158
+
159
+ # add data to vector nstore
160
+ vectorstore.add_texts(processed_texts)
161
+
162
+ from langchain_core.prompts import PromptTemplate
163
+
164
+ template = ("""Hello there! I'm your legal expert.
165
+ Let's dive right in. Feel free to ask your question.
166
+ You need to provide clear and accurate legal advice based on the context provided.
167
+ If the context isn't relevant or doesn't provide enough information, suggest how to proceed.
168
+ Stick to the answer directly.
169
+ If the message or query is greetings do the same.
170
+ Keep things professional but easy to understand, explaining everything in detail.
171
+ Legal Context: {context}
172
+ Question: {question}
173
+ Legal Advice:""")
174
+
175
+ rag_prompt = PromptTemplate.from_template(template)
176
+
177
+
178
+ retriever = vectorstore.as_retriever()
179
+
180
+ from langchain_core.output_parsers import StrOutputParser
181
+ from langchain_core.runnables import RunnablePassthrough
182
+
183
+ rag_chain = (
184
+ {"context": retriever, "question": RunnablePassthrough()}
185
+ | rag_prompt
186
+ | llm
187
+ | StrOutputParser()
188
+ )
189
+
190
+ import gradio as gr
191
+
192
+ def rag_memory_stream(message, history):
193
+ partial_text = ""
194
+ for new_text in rag_chain.stream(message): # Replace with actual streaming logic
195
+ partial_text += new_text
196
+ yield partial_text
197
+
198
+ # Correctly define examples as a list
199
+ examples =[
200
+ "What is the main purpose of Law Nº 59/2018 of 22/8/2018?",
201
+ "What happens to a person who deliberately conceals or destroys evidence related to genocide?",
202
+ "What are the penalties for violating a specific article?"
203
+ ]
204
+
205
+
206
+ description = (
207
+ "This Regal AI Assistance specializes in LAW Nº 59/2018 OF 22/8/2018 "
208
+ "ON THE CRIME OF GENOCIDE IDEOLOGY AND RELATED CRIMES."
209
+ )
210
+
211
+ title = "⚖️ Chat with me and learn Laws! ⚖️"
212
+
213
+ # Custom CSS for styling the interface
214
+ custom_css = """
215
+ body {
216
+ font-family: "Times New Roman", serif;
217
+ }
218
+ .gradio-container {
219
+ font-family: "Times New Roman", serif;
220
+ }
221
+ .gr-button {
222
+ background-color: #007bff; /* Blue button */
223
+ color: white;
224
+ border: none;
225
+ border-radius: 5px;
226
+ font-size: 16px;
227
+ padding: 10px 20px;
228
+ cursor: pointer;
229
+ }
230
+ .gr-textbox:focus, .gr-button:focus {
231
+ outline: none; /* Remove outline focus for a cleaner look */
232
+ }
233
  """
234
+
235
+
236
+ # Create the Chat Interface
237
  demo = gr.ChatInterface(
238
+ fn=rag_memory_stream,
239
+ type="messages",
240
+ title=title,
241
+ description=description,
242
+ fill_height=True,
243
+ examples=examples, # Pass the corrected examples list
244
+ theme="soft",
245
+ #css=custom_css, # Apply the custom CSS
 
 
 
 
 
246
  )
247
 
 
248
  if __name__ == "__main__":
249
+ demo.launch(share=True, inbrowser=True, height=800, width="100%")