Phoenix21 commited on
Commit
aab72a2
·
1 Parent(s): 55a8d3f

revised app.py and revise requirements.txt(handled for 123 box)

Browse files
Files changed (2) hide show
  1. app.py +155 -47
  2. requirements.txt +13 -12
app.py CHANGED
@@ -1,5 +1,9 @@
1
  import os
2
  import logging
 
 
 
 
3
  from langchain.vectorstores import Chroma
4
  from langchain_core.output_parsers import StrOutputParser
5
  from langchain_core.runnables import RunnablePassthrough
@@ -13,7 +17,18 @@ import chardet
13
  import gradio as gr
14
  import pandas as pd
15
  import json
16
- import re
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  # Enable logging for debugging
19
  logging.basicConfig(level=logging.DEBUG)
@@ -71,33 +86,58 @@ def load_documents(file_paths):
71
  logger.error(f"Error processing file {file_path}: {e}")
72
  return docs
73
 
74
- # Function to ensure the response ends with complete sentences
75
  def ensure_complete_sentences(text):
76
- # Use regex to find all complete sentences
77
- sentences = re.findall(r'[^.!?]*[.!?]', text)
78
  if sentences:
79
- # Join all complete sentences to form the complete answer
80
  return ' '.join(sentences).strip()
81
  return text # Return as is if no complete sentence is found
82
 
83
- # Function to check if input is valid
84
- def is_valid_input(text):
85
  """
86
- Checks if the input text is meaningful.
87
- Returns True if the text contains alphabetic characters.
 
 
 
 
 
 
88
  """
89
  if not text or text.strip() == "":
90
  return False
91
- # Regex to check for at least one alphabetic character
92
- return bool(re.search('[A-Za-z]', text))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
  # Initialize the LLM using ChatGroq with GROQ's API
95
- def initialize_llm(model, temperature, max_tokens):
96
  try:
97
- # Allocate a portion of tokens for the prompt, e.g., 20%
98
- prompt_allocation = int(max_tokens * 0.2)
99
- response_max_tokens = max_tokens - prompt_allocation
100
- if response_max_tokens <= 50:
 
 
 
101
  raise ValueError("max_tokens is too small to allocate for the response.")
102
 
103
  llm = ChatGroq(
@@ -115,12 +155,35 @@ def initialize_llm(model, temperature, max_tokens):
115
  # Create the RAG pipeline
116
  def create_rag_pipeline(file_paths, model, temperature, max_tokens):
117
  try:
118
- llm = initialize_llm(model, temperature, max_tokens)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  docs = load_documents(file_paths)
120
  if not docs:
121
  logger.warning("No documents were loaded. Please check your file paths and formats.")
122
  return None, "No documents were loaded. Please check your file paths and formats."
123
 
 
124
  text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
125
  splits = text_splitter.split_documents(docs)
126
 
@@ -138,21 +201,7 @@ def create_rag_pipeline(file_paths, model, temperature, max_tokens):
138
 
139
  retriever = vectorstore.as_retriever()
140
 
141
- custom_prompt_template = PromptTemplate(
142
- input_variables=["context", "question"],
143
- template="""
144
- You are an AI assistant with expertise in daily wellness. Your aim is to provide detailed and comprehensive solutions regarding daily wellness topics without unnecessary verbosity.
145
-
146
- Context:
147
- {context}
148
-
149
- Question:
150
- {question}
151
-
152
- Provide a thorough and complete answer, including relevant examples and a suggested schedule. Ensure that the response does not end abruptly.
153
- """
154
- )
155
-
156
  rag_chain = RetrievalQA.from_chain_type(
157
  llm=llm,
158
  chain_type="stuff",
@@ -165,41 +214,100 @@ def create_rag_pipeline(file_paths, model, temperature, max_tokens):
165
  logger.error(f"Error creating RAG pipeline: {e}")
166
  return None, f"Error creating RAG pipeline: {e}"
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  # Function to answer questions with input validation and post-processing
169
- def answer_question(file_paths, model, temperature, max_tokens, question):
170
- if not is_valid_input(question):
171
- return "Please provide a valid question or input containing meaningful text."
 
172
 
173
  rag_chain, message = create_rag_pipeline(file_paths, model, temperature, max_tokens)
174
  if rag_chain is None:
175
- return message
 
176
  try:
177
  answer = rag_chain.run(question)
178
  logger.debug("Question answered successfully.")
179
  # Post-process to ensure the answer ends with complete sentences
180
  complete_answer = ensure_complete_sentences(answer)
181
- return complete_answer
 
 
 
 
182
  except Exception as e:
183
  logger.error(f"Error during RAG pipeline execution: {e}")
184
- return f"Error during RAG pipeline execution: {e}"
185
 
186
- # Gradio Interface
187
- def gradio_interface(model, temperature, max_tokens, question):
188
  file_paths = ['AIChatbot.csv'] # Ensure this file is present in your Space root directory
189
- return answer_question(file_paths, model, temperature, max_tokens, question)
190
 
191
  # Define Gradio UI
192
  interface = gr.Interface(
193
  fn=gradio_interface,
194
  inputs=[
195
- gr.Textbox(label="Model Name", value="llama3-8b-8192"),
196
- gr.Slider(label="Temperature", minimum=0, maximum=1, step=0.01, value=0.7),
197
- gr.Slider(label="Max Tokens", minimum=200, maximum=1024, step=1, value=500),
198
- gr.Textbox(label="Question")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  ],
200
- outputs="text",
201
  title="Daily Wellness AI",
202
- description="Ask questions about daily wellness and get detailed solutions."
 
 
 
 
 
203
  )
204
 
205
  # Launch Gradio app without share=True (not supported on Hugging Face Spaces)
 
1
  import os
2
  import logging
3
+ import re
4
+ import nltk
5
+ import spacy
6
+ from nltk.tokenize import sent_tokenize
7
  from langchain.vectorstores import Chroma
8
  from langchain_core.output_parsers import StrOutputParser
9
  from langchain_core.runnables import RunnablePassthrough
 
17
  import gradio as gr
18
  import pandas as pd
19
  import json
20
+
21
+ # Download required nltk resources
22
+ nltk.download('punkt')
23
+
24
+ # Load spaCy English model
25
+ try:
26
+ nlp = spacy.load("en_core_web_sm")
27
+ except OSError:
28
+ # If the model is not found, download it
29
+ from spacy.cli import download
30
+ download("en_core_web_sm")
31
+ nlp = spacy.load("en_core_web_sm")
32
 
33
  # Enable logging for debugging
34
  logging.basicConfig(level=logging.DEBUG)
 
86
  logger.error(f"Error processing file {file_path}: {e}")
87
  return docs
88
 
89
+ # Function to ensure the response ends with complete sentences using nltk
90
  def ensure_complete_sentences(text):
91
+ sentences = sent_tokenize(text)
 
92
  if sentences:
 
93
  return ' '.join(sentences).strip()
94
  return text # Return as is if no complete sentence is found
95
 
96
+ # Advanced input validation using spaCy (Section 8a)
97
+ def is_valid_input_nlp(text, threshold=0.5):
98
  """
99
+ Validates input text using spaCy's NLP capabilities.
100
+
101
+ Parameters:
102
+ - text (str): The input text to validate.
103
+ - threshold (float): The minimum ratio of meaningful tokens required.
104
+
105
+ Returns:
106
+ - bool: True if the input is valid, False otherwise.
107
  """
108
  if not text or text.strip() == "":
109
  return False
110
+ doc = nlp(text)
111
+ meaningful_tokens = [token for token in doc if token.is_alpha]
112
+ if not meaningful_tokens:
113
+ return False
114
+ ratio = len(meaningful_tokens) / len(doc)
115
+ return ratio >= threshold
116
+
117
+ # Function to estimate prompt tokens (simple word count approximation)
118
+ def estimate_prompt_tokens(prompt):
119
+ """
120
+ Estimates the number of tokens in the prompt.
121
+ This is a placeholder function. Replace it with actual token estimation logic.
122
+
123
+ Parameters:
124
+ - prompt (str): The prompt text.
125
+
126
+ Returns:
127
+ - int: Estimated number of tokens.
128
+ """
129
+ return len(prompt.split())
130
 
131
  # Initialize the LLM using ChatGroq with GROQ's API
132
+ def initialize_llm(model, temperature, max_tokens, prompt_template):
133
  try:
134
+ # Estimate prompt tokens
135
+ estimated_prompt_tokens = estimate_prompt_tokens(prompt_template)
136
+
137
+ # Allocate remaining tokens to response
138
+ response_max_tokens = max_tokens - estimated_prompt_tokens
139
+
140
+ if response_max_tokens <= 100:
141
  raise ValueError("max_tokens is too small to allocate for the response.")
142
 
143
  llm = ChatGroq(
 
155
  # Create the RAG pipeline
156
  def create_rag_pipeline(file_paths, model, temperature, max_tokens):
157
  try:
158
+ # Define the prompt template first to estimate tokens
159
+ custom_prompt_template = PromptTemplate(
160
+ input_variables=["context", "question"],
161
+ template="""
162
+ You are an AI assistant with expertise in daily wellness. Your aim is to provide detailed and comprehensive solutions regarding daily wellness topics without unnecessary verbosity.
163
+
164
+ Context:
165
+ {context}
166
+
167
+ Question:
168
+ {question}
169
+
170
+ Provide a thorough and complete answer, including relevant examples and a suggested schedule. Ensure that the response does not end abruptly.
171
+ """
172
+ )
173
+
174
+ # Estimate prompt tokens
175
+ estimated_prompt_tokens = estimate_prompt_tokens(custom_prompt_template.template)
176
+
177
+ # Initialize the LLM with token allocation
178
+ llm = initialize_llm(model, temperature, max_tokens, custom_prompt_template.template)
179
+
180
+ # Load and process documents
181
  docs = load_documents(file_paths)
182
  if not docs:
183
  logger.warning("No documents were loaded. Please check your file paths and formats.")
184
  return None, "No documents were loaded. Please check your file paths and formats."
185
 
186
+ # Split documents into chunks
187
  text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
188
  splits = text_splitter.split_documents(docs)
189
 
 
201
 
202
  retriever = vectorstore.as_retriever()
203
 
204
+ # Create the RetrievalQA chain
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  rag_chain = RetrievalQA.from_chain_type(
206
  llm=llm,
207
  chain_type="stuff",
 
214
  logger.error(f"Error creating RAG pipeline: {e}")
215
  return None, f"Error creating RAG pipeline: {e}"
216
 
217
+ # Function to handle feedback (Section 8d)
218
+ def handle_feedback(feedback_text):
219
+ """
220
+ Handles user feedback by logging it.
221
+ In a production environment, consider storing feedback in a database or external service.
222
+
223
+ Parameters:
224
+ - feedback_text (str): The feedback provided by the user.
225
+
226
+ Returns:
227
+ - str: Acknowledgment message.
228
+ """
229
+ if feedback_text and feedback_text.strip() != "":
230
+ # For demonstration, we'll log the feedback. Replace this with database storage if needed.
231
+ logger.info(f"User Feedback: {feedback_text}")
232
+ return "Thank you for your feedback!"
233
+ else:
234
+ return "No feedback provided."
235
+
236
  # Function to answer questions with input validation and post-processing
237
+ def answer_question(file_paths, model, temperature, max_tokens, question, feedback):
238
+ # Validate input using spaCy-based validation
239
+ if not is_valid_input_nlp(question):
240
+ return "Please provide a valid question or input containing meaningful text.", ""
241
 
242
  rag_chain, message = create_rag_pipeline(file_paths, model, temperature, max_tokens)
243
  if rag_chain is None:
244
+ return message, ""
245
+
246
  try:
247
  answer = rag_chain.run(question)
248
  logger.debug("Question answered successfully.")
249
  # Post-process to ensure the answer ends with complete sentences
250
  complete_answer = ensure_complete_sentences(answer)
251
+
252
+ # Handle feedback
253
+ feedback_response = handle_feedback(feedback)
254
+
255
+ return complete_answer, feedback_response
256
  except Exception as e:
257
  logger.error(f"Error during RAG pipeline execution: {e}")
258
+ return f"Error during RAG pipeline execution: {e}", ""
259
 
260
+ # Gradio Interface with Feedback Mechanism (Section 8d)
261
+ def gradio_interface(model, temperature, max_tokens, question, feedback):
262
  file_paths = ['AIChatbot.csv'] # Ensure this file is present in your Space root directory
263
+ return answer_question(file_paths, model, temperature, max_tokens, question, feedback)
264
 
265
  # Define Gradio UI
266
  interface = gr.Interface(
267
  fn=gradio_interface,
268
  inputs=[
269
+ gr.Textbox(
270
+ label="Model Name",
271
+ value="llama3-8b-8192",
272
+ placeholder="e.g., llama3-8b-8192"
273
+ ),
274
+ gr.Slider(
275
+ label="Temperature",
276
+ minimum=0,
277
+ maximum=1,
278
+ step=0.01,
279
+ value=0.7,
280
+ info="Controls the randomness of the response. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic."
281
+ ),
282
+ gr.Slider(
283
+ label="Max Tokens",
284
+ minimum=200,
285
+ maximum=2048,
286
+ step=1,
287
+ value=500,
288
+ info="Determines the maximum number of tokens in the response. Higher values allow for longer answers."
289
+ ),
290
+ gr.Textbox(
291
+ label="Question",
292
+ placeholder="e.g., What is box breathing and how does it help reduce anxiety?"
293
+ ),
294
+ gr.Textbox(
295
+ label="Feedback",
296
+ placeholder="Provide your feedback here...",
297
+ lines=2
298
+ )
299
+ ],
300
+ outputs=[
301
+ "text",
302
+ "text"
303
  ],
 
304
  title="Daily Wellness AI",
305
+ description="Ask questions about daily wellness and get detailed solutions.",
306
+ examples=[
307
+ ["llama3-8b-8192", 0.7, 500, "What is box breathing and how does it help reduce anxiety?", "Great explanation!"],
308
+ ["llama3-8b-8192", 0.6, 600, "Provide a daily wellness schedule incorporating box breathing techniques.", "Very helpful, thank you!"]
309
+ ],
310
+ allow_flagging="never" # Disable default flagging; using custom feedback
311
  )
312
 
313
  # Launch Gradio app without share=True (not supported on Hugging Face Spaces)
requirements.txt CHANGED
@@ -1,13 +1,14 @@
 
 
 
 
1
  langchain>=0.0.200
2
- langchain-community
3
- langchain_huggingface
4
- langchain_groq
5
- chromadb
6
- chardet
7
- gradio
8
- pandas
9
- sentence-transformers
10
- transformers
11
- accelerate
12
- torch
13
-
 
1
+ accelerate>=0.20.3
2
+ chardet>=5.1.0
3
+ chromadb>=0.4.6
4
+ gradio>=3.32.0
5
  langchain>=0.0.200
6
+ langchain-community>=0.0.4
7
+ langchain_groq>=0.0.1
8
+ langchain_huggingface>=0.0.1
9
+ nltk>=3.8.1
10
+ pandas>=2.0.3
11
+ sentence-transformers>=2.2.2
12
+ spacy>=3.5.3
13
+ torch>=2.0.0
14
+ transformers>=4.30.0