Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -61,19 +61,19 @@ A disclaimer at the bottom reminds users about potential LLM inaccuracies and th
|
|
| 61 |
# Check if the LLM model is not already in the session state
|
| 62 |
if "my_llm_model" not in st.session_state:
|
| 63 |
# Set the default LLM model to "mistralai/Mistral-7B-Instruct-v0.3"
|
| 64 |
-
st.session_state[
|
| 65 |
# Check if the SPACE_ID environment variable is not already in the session state
|
| 66 |
if "my_space" not in st.session_state:
|
| 67 |
-
st.session_state[
|
| 68 |
|
| 69 |
# Function to update the LLM model client
|
| 70 |
def update_llm_model():
|
| 71 |
-
if st.session_state[
|
| 72 |
# Initialize the client with the model if SPACE_ID is available
|
| 73 |
-
st.session_state[
|
| 74 |
else:
|
| 75 |
# Initialize the client with the model and token if SPACE_ID is not available
|
| 76 |
-
st.session_state[
|
| 77 |
|
| 78 |
# Check if the client is not already in the session state
|
| 79 |
if "client" not in st.session_state:
|
|
@@ -82,7 +82,7 @@ if "client" not in st.session_state:
|
|
| 82 |
# Check if the embeddings model is not already in the session state
|
| 83 |
if "embeddings_model" not in st.session_state:
|
| 84 |
# We will use the all-MiniLM-L6-v2 model for embeddings
|
| 85 |
-
st.session_state[
|
| 86 |
|
| 87 |
|
| 88 |
my_system_instructions = "You are a helpful assistant. Be brief and concise. Provide your answers in 100 words or less."
|
|
@@ -95,26 +95,26 @@ def delete_chat_messages():
|
|
| 95 |
del st.session_state[key]
|
| 96 |
|
| 97 |
def create_sentences_rag():
|
| 98 |
-
text = st.session_state[
|
| 99 |
|
| 100 |
# Split only on .?!;: followed by space OR on \n
|
| 101 |
pattern = r'(?<=[.?!;:])\s+|\n'
|
| 102 |
-
st.session_state[
|
| 103 |
-
sentences_ids = [i for i in range(len(st.session_state[
|
| 104 |
|
| 105 |
# Rolling window: include partial windows at end
|
| 106 |
-
st.session_state[
|
| 107 |
-
st.session_state[
|
| 108 |
-
for rolling_window_size in range(st.session_state[
|
| 109 |
-
for i in range(0, len(st.session_state[
|
| 110 |
-
chunk = " ".join(st.session_state[
|
| 111 |
if chunk:
|
| 112 |
-
st.session_state[
|
| 113 |
-
st.session_state[
|
| 114 |
# print(f"*****{chunk}*****\n")
|
| 115 |
|
| 116 |
-
print(len(st.session_state[
|
| 117 |
-
st.session_state[
|
| 118 |
|
| 119 |
|
| 120 |
augmented_prompt = ""
|
|
@@ -137,9 +137,9 @@ By using the Software, you agree to the terms and conditions of the disclaimer."
|
|
| 137 |
|
| 138 |
# Add a selectbox for model selection
|
| 139 |
st.selectbox("Select the model to use:",
|
| 140 |
-
[
|
| 141 |
-
|
| 142 |
-
|
| 143 |
key="my_llm_model", on_change=update_llm_model)
|
| 144 |
|
| 145 |
# Add a text are for the system instructions
|
|
@@ -171,9 +171,9 @@ By using the Software, you agree to the terms and conditions of the disclaimer."
|
|
| 171 |
# Check if the chat messages are not already in the session state
|
| 172 |
if "my_chat_messages" not in st.session_state:
|
| 173 |
# Initialize the chat messages list in the session state
|
| 174 |
-
st.session_state[
|
| 175 |
# Add the system instructions to the chat messages
|
| 176 |
-
st.session_state[
|
| 177 |
|
| 178 |
|
| 179 |
# print(100*"-")
|
|
@@ -190,32 +190,32 @@ with column_2:
|
|
| 190 |
messages_container.chat_message("ai", avatar=":material/robot_2:").markdown(first_message)
|
| 191 |
|
| 192 |
# Iterate through the chat messages stored in the session state
|
| 193 |
-
for message in st.session_state[
|
| 194 |
-
if message[
|
| 195 |
# Display user messages with a specific avatar - https://fonts.google.com/icons
|
| 196 |
-
messages_container.chat_message(message[
|
| 197 |
-
elif message[
|
| 198 |
# Display assistant messages with a specific avatar
|
| 199 |
-
messages_container.chat_message(message[
|
| 200 |
|
| 201 |
# Check if there is a new prompt from the user
|
| 202 |
if prompt := st.chat_input("you may ask here your questions"):
|
| 203 |
|
| 204 |
split_prompt = prompt.split(" ")
|
| 205 |
all_sub_prompts = []
|
| 206 |
-
for jj in range(st.session_state[
|
| 207 |
for ii in range(len(split_prompt)):
|
| 208 |
i_split = " ".join(split_prompt[ii:ii+jj]).strip()
|
| 209 |
if i_split:
|
| 210 |
all_sub_prompts.append(i_split)
|
| 211 |
|
| 212 |
-
similarities_to_question = np.zeros(len(st.session_state[
|
| 213 |
for sub_prompt in all_sub_prompts:
|
| 214 |
# Encode the user's prompt to get its embedding
|
| 215 |
my_question_embedding = st.session_state.embeddings_model.encode([sub_prompt])
|
| 216 |
|
| 217 |
# Calculate the cosine similarity between the prompt embedding and stored embeddings
|
| 218 |
-
similarities_to_question += cosine_similarity(my_question_embedding, st.session_state[
|
| 219 |
similarities_to_question /= len(all_sub_prompts)
|
| 220 |
|
| 221 |
# Get the indices of the top similar sentences
|
|
@@ -223,24 +223,24 @@ with column_2:
|
|
| 223 |
sorted_indices_rag = similarities_to_question.argsort()[::-1]
|
| 224 |
sorted_indices_sentences = []
|
| 225 |
max_similarity = 0
|
| 226 |
-
# for irag in range(st.session_state[
|
| 227 |
irag = 0
|
| 228 |
-
while len(set(sorted_indices_sentences))<st.session_state[
|
| 229 |
-
sorted_indices_sentences.extend(st.session_state[
|
| 230 |
max_similarity = max(max_similarity, similarities_to_question[sorted_indices_rag[irag]])
|
| 231 |
with bottom_col1:
|
| 232 |
-
str_conf = f"Confidence: {similarities_to_question[sorted_indices_rag[irag]]:.5f}, Sentences IDs: {st.session_state[
|
| 233 |
with st.expander(f"Chunk: {str(irag+1)} {str_conf}"):
|
| 234 |
-
for idx in st.session_state[
|
| 235 |
-
st.write(f"{st.session_state[
|
| 236 |
irag += 1
|
| 237 |
|
| 238 |
sorted_indices_sentences = sorted(list(set(sorted_indices_sentences)))
|
| 239 |
|
| 240 |
# Construct the augmented prompt with the similar sentences
|
| 241 |
-
if max_similarity > st.session_state[
|
| 242 |
augmented_prompt = "This is my context:" + "\n\n" + 20*"-" + "\n\n"
|
| 243 |
-
augmented_prompt += "\n".join([st.session_state[
|
| 244 |
augmented_prompt += "\n\n" + 20*"-" + "\n\n" + "If the above context is not relevant to the prompt, ignore the context and reply based only on the prompt."
|
| 245 |
augmented_prompt += "\n\n" + 20*"-" + "\n\n" + "If the above context is relevant to the prompt, reply based on the context and the prompt."
|
| 246 |
augmented_prompt += "\n\n" + 20*"-" + "\n\n" + "The prompt is:"
|
|
@@ -255,28 +255,26 @@ with column_2:
|
|
| 255 |
# Display the user's prompt in the chat container with a specific avatar
|
| 256 |
messages_container.chat_message("user", avatar=":material/psychology_alt:").markdown(prompt)
|
| 257 |
# Append the augmented prompt to the chat messages in the session state
|
| 258 |
-
st.session_state[
|
| 259 |
# Create an empty container for the streaming response from the assistant
|
| 260 |
with messages_container.chat_message("ai", avatar=":material/robot_2:"):
|
| 261 |
response_placeholder = st.empty()
|
| 262 |
response = ""
|
| 263 |
# Stream the response from the assistant and update the placeholder
|
| 264 |
-
for chunk in st.session_state[
|
| 265 |
if chunk.choices[0].delta.content:
|
| 266 |
response += chunk.choices[0].delta.content
|
| 267 |
# Use markdown to update the response placeholder with the streamed content
|
| 268 |
response_placeholder.markdown(response)
|
| 269 |
|
| 270 |
# Remove the last message from the chat messages in the session state
|
| 271 |
-
st.session_state[
|
| 272 |
# Append the user's original prompt to the chat messages in the session state
|
| 273 |
-
st.session_state[
|
| 274 |
# Append the assistant's response to the chat messages in the session state
|
| 275 |
-
st.session_state[
|
| 276 |
|
| 277 |
with bottom_col2:
|
| 278 |
# Display the chat messages history
|
| 279 |
st.write("Messages History All:")
|
| 280 |
-
st.json(st.session_state[
|
| 281 |
-
|
| 282 |
-
|
|
|
|
| 61 |
# Check if the LLM model is not already in the session state
|
| 62 |
if "my_llm_model" not in st.session_state:
|
| 63 |
# Set the default LLM model to "mistralai/Mistral-7B-Instruct-v0.3"
|
| 64 |
+
st.session_state['my_llm_model'] = "mistralai/Mistral-7B-Instruct-v0.3"
|
| 65 |
# Check if the SPACE_ID environment variable is not already in the session state
|
| 66 |
if "my_space" not in st.session_state:
|
| 67 |
+
st.session_state['my_space'] = os.environ.get("SPACE_ID")
|
| 68 |
|
| 69 |
# Function to update the LLM model client
|
| 70 |
def update_llm_model():
|
| 71 |
+
if st.session_state['my_space']:
|
| 72 |
# Initialize the client with the model if SPACE_ID is available
|
| 73 |
+
st.session_state['client'] = InferenceClient(st.session_state['my_llm_model'])
|
| 74 |
else:
|
| 75 |
# Initialize the client with the model and token if SPACE_ID is not available
|
| 76 |
+
st.session_state['client'] = InferenceClient(st.session_state['my_llm_model'], token=os.getenv("HF_TOKEN"))
|
| 77 |
|
| 78 |
# Check if the client is not already in the session state
|
| 79 |
if "client" not in st.session_state:
|
|
|
|
| 82 |
# Check if the embeddings model is not already in the session state
|
| 83 |
if "embeddings_model" not in st.session_state:
|
| 84 |
# We will use the all-MiniLM-L6-v2 model for embeddings
|
| 85 |
+
st.session_state['embeddings_model'] = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
|
| 86 |
|
| 87 |
|
| 88 |
my_system_instructions = "You are a helpful assistant. Be brief and concise. Provide your answers in 100 words or less."
|
|
|
|
| 95 |
del st.session_state[key]
|
| 96 |
|
| 97 |
def create_sentences_rag():
|
| 98 |
+
text = st.session_state['my_rag_text']
|
| 99 |
|
| 100 |
# Split only on .?!;: followed by space OR on \n
|
| 101 |
pattern = r'(?<=[.?!;:])\s+|\n'
|
| 102 |
+
st.session_state['my_sentences'] = [sentence.strip() for sentence in re.split(pattern, text) if sentence.strip()]
|
| 103 |
+
sentences_ids = [i for i in range(len(st.session_state['my_sentences']))]
|
| 104 |
|
| 105 |
# Rolling window: include partial windows at end
|
| 106 |
+
st.session_state['my_sentences_rag_ids'] = []
|
| 107 |
+
st.session_state['my_sentences_rag'] = []
|
| 108 |
+
for rolling_window_size in range(st.session_state['min_window_size'], st.session_state['max_window_size']+1):
|
| 109 |
+
for i in range(0, len(st.session_state['my_sentences'])-rolling_window_size+1):
|
| 110 |
+
chunk = " ".join(st.session_state['my_sentences'][i:i+rolling_window_size]).strip()
|
| 111 |
if chunk:
|
| 112 |
+
st.session_state['my_sentences_rag'].append(chunk)
|
| 113 |
+
st.session_state['my_sentences_rag_ids'].append(sentences_ids[i:i+rolling_window_size])
|
| 114 |
# print(f"*****{chunk}*****\n")
|
| 115 |
|
| 116 |
+
print(len(st.session_state['my_sentences_rag']))
|
| 117 |
+
st.session_state['my_embeddings'] = st.session_state['embeddings_model'].encode(st.session_state['my_sentences_rag'])
|
| 118 |
|
| 119 |
|
| 120 |
augmented_prompt = ""
|
|
|
|
| 137 |
|
| 138 |
# Add a selectbox for model selection
|
| 139 |
st.selectbox("Select the model to use:",
|
| 140 |
+
['mistralai/Mistral-7B-Instruct-v0.3',
|
| 141 |
+
'Qwen/Qwen2.5-72B-Instruct',
|
| 142 |
+
'HuggingFaceH4/zephyr-7b-beta'],
|
| 143 |
key="my_llm_model", on_change=update_llm_model)
|
| 144 |
|
| 145 |
# Add a text are for the system instructions
|
|
|
|
| 171 |
# Check if the chat messages are not already in the session state
|
| 172 |
if "my_chat_messages" not in st.session_state:
|
| 173 |
# Initialize the chat messages list in the session state
|
| 174 |
+
st.session_state['my_chat_messages'] = []
|
| 175 |
# Add the system instructions to the chat messages
|
| 176 |
+
st.session_state['my_chat_messages'].append({"role": "system", "content": st.session_state['my_system_instructions']})
|
| 177 |
|
| 178 |
|
| 179 |
# print(100*"-")
|
|
|
|
| 190 |
messages_container.chat_message("ai", avatar=":material/robot_2:").markdown(first_message)
|
| 191 |
|
| 192 |
# Iterate through the chat messages stored in the session state
|
| 193 |
+
for message in st.session_state['my_chat_messages']:
|
| 194 |
+
if message['role'] == "user":
|
| 195 |
# Display user messages with a specific avatar - https://fonts.google.com/icons
|
| 196 |
+
messages_container.chat_message(message['role'], avatar=":material/psychology_alt:").markdown(message['content'])
|
| 197 |
+
elif message['role'] == "assistant":
|
| 198 |
# Display assistant messages with a specific avatar
|
| 199 |
+
messages_container.chat_message(message['role'], avatar=":material/robot_2:").markdown(message['content'])
|
| 200 |
|
| 201 |
# Check if there is a new prompt from the user
|
| 202 |
if prompt := st.chat_input("you may ask here your questions"):
|
| 203 |
|
| 204 |
split_prompt = prompt.split(" ")
|
| 205 |
all_sub_prompts = []
|
| 206 |
+
for jj in range(st.session_state['nof_min_sub_prompts'], st.session_state['nof_max_sub_prompts']+1):
|
| 207 |
for ii in range(len(split_prompt)):
|
| 208 |
i_split = " ".join(split_prompt[ii:ii+jj]).strip()
|
| 209 |
if i_split:
|
| 210 |
all_sub_prompts.append(i_split)
|
| 211 |
|
| 212 |
+
similarities_to_question = np.zeros(len(st.session_state['my_embeddings']))
|
| 213 |
for sub_prompt in all_sub_prompts:
|
| 214 |
# Encode the user's prompt to get its embedding
|
| 215 |
my_question_embedding = st.session_state.embeddings_model.encode([sub_prompt])
|
| 216 |
|
| 217 |
# Calculate the cosine similarity between the prompt embedding and stored embeddings
|
| 218 |
+
similarities_to_question += cosine_similarity(my_question_embedding, st.session_state['my_embeddings']).flatten()
|
| 219 |
similarities_to_question /= len(all_sub_prompts)
|
| 220 |
|
| 221 |
# Get the indices of the top similar sentences
|
|
|
|
| 223 |
sorted_indices_rag = similarities_to_question.argsort()[::-1]
|
| 224 |
sorted_indices_sentences = []
|
| 225 |
max_similarity = 0
|
| 226 |
+
# for irag in range(st.session_state['nof_keep_sentences']):
|
| 227 |
irag = 0
|
| 228 |
+
while len(set(sorted_indices_sentences))<st.session_state['nof_keep_sentences']:
|
| 229 |
+
sorted_indices_sentences.extend(st.session_state['my_sentences_rag_ids'][sorted_indices_rag[irag]])
|
| 230 |
max_similarity = max(max_similarity, similarities_to_question[sorted_indices_rag[irag]])
|
| 231 |
with bottom_col1:
|
| 232 |
+
str_conf = f"Confidence: {similarities_to_question[sorted_indices_rag[irag]]:.5f}, Sentences IDs: {st.session_state['my_sentences_rag_ids'][sorted_indices_rag[irag]]}"
|
| 233 |
with st.expander(f"Chunk: {str(irag+1)} {str_conf}"):
|
| 234 |
+
for idx in st.session_state['my_sentences_rag_ids'][sorted_indices_rag[irag]]:
|
| 235 |
+
st.write(f"{st.session_state['my_sentences'][idx]}")
|
| 236 |
irag += 1
|
| 237 |
|
| 238 |
sorted_indices_sentences = sorted(list(set(sorted_indices_sentences)))
|
| 239 |
|
| 240 |
# Construct the augmented prompt with the similar sentences
|
| 241 |
+
if max_similarity > st.session_state['my_similarity_threshold']:
|
| 242 |
augmented_prompt = "This is my context:" + "\n\n" + 20*"-" + "\n\n"
|
| 243 |
+
augmented_prompt += "\n".join([st.session_state['my_sentences'][idx] for idx in sorted_indices_sentences])
|
| 244 |
augmented_prompt += "\n\n" + 20*"-" + "\n\n" + "If the above context is not relevant to the prompt, ignore the context and reply based only on the prompt."
|
| 245 |
augmented_prompt += "\n\n" + 20*"-" + "\n\n" + "If the above context is relevant to the prompt, reply based on the context and the prompt."
|
| 246 |
augmented_prompt += "\n\n" + 20*"-" + "\n\n" + "The prompt is:"
|
|
|
|
| 255 |
# Display the user's prompt in the chat container with a specific avatar
|
| 256 |
messages_container.chat_message("user", avatar=":material/psychology_alt:").markdown(prompt)
|
| 257 |
# Append the augmented prompt to the chat messages in the session state
|
| 258 |
+
st.session_state['my_chat_messages'].append({"role": "user", "content": augmented_prompt})
|
| 259 |
# Create an empty container for the streaming response from the assistant
|
| 260 |
with messages_container.chat_message("ai", avatar=":material/robot_2:"):
|
| 261 |
response_placeholder = st.empty()
|
| 262 |
response = ""
|
| 263 |
# Stream the response from the assistant and update the placeholder
|
| 264 |
+
for chunk in st.session_state['client'].chat.completions.create(messages=st.session_state['my_chat_messages'], stream=True, max_tokens=512):
|
| 265 |
if chunk.choices[0].delta.content:
|
| 266 |
response += chunk.choices[0].delta.content
|
| 267 |
# Use markdown to update the response placeholder with the streamed content
|
| 268 |
response_placeholder.markdown(response)
|
| 269 |
|
| 270 |
# Remove the last message from the chat messages in the session state
|
| 271 |
+
st.session_state['my_chat_messages'].pop()
|
| 272 |
# Append the user's original prompt to the chat messages in the session state
|
| 273 |
+
st.session_state['my_chat_messages'].append({"role": "user", "content": prompt})
|
| 274 |
# Append the assistant's response to the chat messages in the session state
|
| 275 |
+
st.session_state['my_chat_messages'].append({"role": "assistant", "content": response})
|
| 276 |
|
| 277 |
with bottom_col2:
|
| 278 |
# Display the chat messages history
|
| 279 |
st.write("Messages History All:")
|
| 280 |
+
st.json(st.session_state['my_chat_messages'], expanded=False)
|
|
|
|
|
|