leandroaraujodev commited on
Commit
4085763
·
verified ·
1 Parent(s): 16152ea

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -54
app.py CHANGED
@@ -15,7 +15,7 @@ from llama_index.core.retrievers import QueryFusionRetriever
15
  from llama_index.vector_stores.chroma import ChromaVectorStore
16
  import chromadb
17
  import nest_asyncio
18
-
19
  import os
20
  from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
21
  from llama_index.llms.huggingface import HuggingFaceLLM
@@ -25,17 +25,17 @@ from typing import List, Optional
25
  from llama_index.core import PromptTemplate
26
  import torch
27
  from llama_index.embeddings.huggingface import HuggingFaceEmbedding
28
-
29
-
30
  import logging
31
  import sys
32
  from PIL import Image
33
-
34
  #Configuração da imagem da aba
35
-
36
  im = Image.open("pngegg.png")
37
  st.set_page_config(page_title = "Chatbot Carômetro", page_icon=im, layout = "wide")
38
-
39
  #Removido loop e adicionado os.makedirs
40
  os.makedirs("bm25_retriever", exist_ok=True)
41
  os.makedirs("chat_store", exist_ok=True)
@@ -43,18 +43,18 @@ os.makedirs("chroma_db", exist_ok=True)
43
  os.makedirs("documentos", exist_ok=True)
44
  os.makedirs("curadoria", exist_ok=True)
45
  os.makedirs("chroma_db_curadoria", exist_ok=True)
46
-
47
  # Configuração do Streamlit
48
  st.sidebar.title("Configuração de LLM")
49
  sidebar_option = st.sidebar.radio("Selecione o LLM", ["gpt-3.5-turbo", "NuExtract-1.5"])
50
  # logo_url = 'app\logos\logo-sicoob.jpg'
51
  # st.sidebar.image(logo_url)
52
  import base64
53
-
54
  #Configuração da imagem da sidebar
55
  with open("sicoob-logo.png", "rb") as f:
56
  data = base64.b64encode(f.read()).decode("utf-8")
57
-
58
  st.sidebar.markdown(
59
  f"""
60
  <div style="display:table;margin-top:-80%;margin-left:0%;">
@@ -63,8 +63,8 @@ with open("sicoob-logo.png", "rb") as f:
63
  """,
64
  unsafe_allow_html=True,
65
  )
66
-
67
-
68
  #if sidebar_option == "Ollama":
69
  # Settings.llm = Ollama(model="llama3.2:latest", request_timeout=500.0, num_gpu=1)
70
  # Settings.embed_model = OllamaEmbedding(model_name="nomic-embed-text:latest")
@@ -74,19 +74,19 @@ if sidebar_option == "gpt-3.5-turbo":
74
  Settings.llm = OpenAI(model="gpt-3.5-turbo")
75
  Settings.embed_model = OpenAIEmbedding(model_name="text-embedding-ada-002")
76
  elif sidebar_option == 'NuExtract-1.5':
77
-
78
  logging.basicConfig(stream=sys.stdout, level=logging.INFO)
79
  logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
80
-
81
  #Embedding do huggingface
82
  Settings.embed_model = HuggingFaceEmbedding(
83
  model_name="BAAI/bge-small-en-v1.5"
84
  )
85
  #Carregamento do modelo local, descomentar o modelo desejado
86
-
87
  llm = HuggingFaceLLM(
88
  context_window=2048,
89
- max_new_tokens=256,
90
  generate_kwargs={"do_sample": False},
91
  #query_wrapper_prompt=query_wrapper_prompt,
92
  #model_name="Qwen/Qwen2.5-Coder-32B-Instruct",
@@ -96,36 +96,36 @@ elif sidebar_option == 'NuExtract-1.5':
96
  # model_name="meta-llama/Meta-Llama-3-8B",
97
  model_name="numind/NuExtract-1.5",
98
  #model_name="meta-llama/Llama-3.2-3B",
99
-
100
  tokenizer_name="numind/NuExtract-1.5",
101
  device_map="auto",
102
- tokenizer_kwargs={"max_length": 2048},
103
  # uncomment this if using CUDA to reduce memory usage
104
  model_kwargs={"torch_dtype": torch.bfloat16},
105
  )
106
  chat = [
107
-
108
  {"role": "user", "content": "Hello, how are you?"},
109
-
110
  {"role": "assistant", "content": "I'm doing great. How can I help you today?"},
111
-
112
  {"role": "user", "content": "I'd like to show off how chat templating works!"},
113
-
114
  ]
115
-
116
  from transformers import AutoTokenizer
117
-
118
  tokenizer = AutoTokenizer.from_pretrained("numind/NuExtract-1.5")
119
-
120
  tokenizer.apply_chat_template(chat, tokenize=False)
121
-
122
-
123
  Settings.chunk_size = 512
124
  Settings.llm = llm
125
-
126
  else:
127
  raise Exception("Opção de LLM inválida!")
128
-
129
  # Diretórios configurados pelo usuário
130
  chat_store_path = os.path.join("chat_store", "chat_store.json")
131
  documents_path = os.path.join("documentos")
@@ -133,24 +133,24 @@ chroma_storage_path = os.path.join("chroma_db") # Diretório para persistência
133
  chroma_storage_path_curadoria = os.path.join("chroma_db_curadoria") # Diretório para 'curadoria'
134
  bm25_persist_path = os.path.join("bm25_retriever")
135
  curadoria_path = os.path.join("curadoria")
136
-
137
-
138
  # Configuração de leitura de documentos
139
  documents = SimpleDirectoryReader(input_dir=documents_path).load_data()
140
-
141
  # Configuração do Chroma e BM25 com persistência
142
  docstore = SimpleDocumentStore()
143
  docstore.add_documents(documents)
144
-
145
  db = chromadb.PersistentClient(path=chroma_storage_path)
146
  chroma_collection = db.get_or_create_collection("dense_vectors")
147
  vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
148
-
149
  # Configuração do StorageContext
150
  storage_context = StorageContext.from_defaults(
151
  docstore=docstore, vector_store=vector_store
152
  )
153
-
154
  # Criação/Recarregamento do índice com embeddings
155
  if os.path.exists(chroma_storage_path):
156
  index = VectorStoreIndex.from_vector_store(vector_store)
@@ -162,7 +162,7 @@ else:
162
  documents, storage_context=storage_context, transformations=[splitter]
163
  )
164
  vector_store.persist()
165
-
166
  # Criação/Recarregamento do BM25 Retriever
167
  if os.path.exists(os.path.join(bm25_persist_path, "params.index.json")):
168
  bm25_retriever = BM25Retriever.from_persist_dir(bm25_persist_path)
@@ -174,22 +174,22 @@ else:
174
  )
175
  os.makedirs(bm25_persist_path, exist_ok=True)
176
  bm25_retriever.persist(bm25_persist_path)
177
-
178
  #Adicionado documentos na pasta curadoria, foi setado para 1200 o chunk pra receber pergunta, contexto e resposta
179
  curadoria_documents = SimpleDirectoryReader(input_dir=curadoria_path).load_data()
180
-
181
  curadoria_docstore = SimpleDocumentStore()
182
  curadoria_docstore.add_documents(curadoria_documents)
183
-
184
  db_curadoria = chromadb.PersistentClient(path=chroma_storage_path_curadoria)
185
  chroma_collection_curadoria = db_curadoria.get_or_create_collection("dense_vectors_curadoria")
186
  vector_store_curadoria = ChromaVectorStore(chroma_collection=chroma_collection_curadoria)
187
-
188
  # Configuração do StorageContext para 'curadoria'
189
  storage_context_curadoria = StorageContext.from_defaults(
190
  docstore=curadoria_docstore, vector_store=vector_store_curadoria
191
  )
192
-
193
  # Criação/Recarregamento do índice com embeddings para 'curadoria'
194
  if os.path.exists(chroma_storage_path_curadoria):
195
  curadoria_index = VectorStoreIndex.from_vector_store(vector_store_curadoria)
@@ -201,15 +201,15 @@ else:
201
  curadoria_documents, storage_context=storage_context_curadoria, transformations=[curadoria_splitter]
202
  )
203
  vector_store_curadoria.persist()
204
-
205
  curadoria_retriever = curadoria_index.as_retriever(similarity_top_k=2)
206
-
207
  # Combinação de Retrievers (Embeddings + BM25)
208
  vector_retriever = index.as_retriever(similarity_top_k=2)
209
  retriever = QueryFusionRetriever(
210
  [vector_retriever, bm25_retriever, curadoria_retriever],
211
  similarity_top_k=2,
212
- num_queries=4,
213
  mode="reciprocal_rerank",
214
  use_async=True,
215
  verbose=True,
@@ -222,7 +222,7 @@ retriever = QueryFusionRetriever(
222
  "Perguntas:\n"
223
  ),
224
  )
225
-
226
  # Configuração do chat engine
227
  nest_asyncio.apply()
228
  memory = ChatMemoryBuffer.from_defaults(token_limit=3900)
@@ -239,26 +239,45 @@ chat_engine = CondensePlusContextChatEngine.from_defaults(
239
  ),
240
  verbose=True,
241
  )
242
-
243
  # Armazenamento do chat
244
  chat_store = SimpleChatStore()
245
  if os.path.exists(chat_store_path):
246
  chat_store = SimpleChatStore.from_persist_path(persist_path=chat_store_path)
247
  else:
248
  chat_store.persist(persist_path=chat_store_path)
249
-
250
  # Interface do Chatbot
251
  st.title("Chatbot Carômetro")
252
  st.write("Este chatbot pode te ajudar a conseguir informações relevantes sobre os carômetros da Sicoob.")
253
- if "chat_history" not in st.session_state:
 
254
  st.session_state.chat_history = []
255
-
 
 
 
 
 
256
  user_input = st.chat_input("Digite sua pergunta")
257
  if user_input:
258
- response = chat_engine.chat(user_input)
 
 
259
  st.session_state.chat_history.append(f"user: {user_input}")
260
- st.session_state.chat_history.append(f"assistant: {response}")
261
- for message in st.session_state.chat_history:
262
- role, text = message.split(":", 1)
263
- with st.chat_message(role.strip().lower()):
264
- st.write(text.strip())
 
 
 
 
 
 
 
 
 
 
 
 
15
  from llama_index.vector_stores.chroma import ChromaVectorStore
16
  import chromadb
17
  import nest_asyncio
18
+
19
  import os
20
  from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
21
  from llama_index.llms.huggingface import HuggingFaceLLM
 
25
  from llama_index.core import PromptTemplate
26
  import torch
27
  from llama_index.embeddings.huggingface import HuggingFaceEmbedding
28
+
29
+
30
  import logging
31
  import sys
32
  from PIL import Image
33
+
34
  #Configuração da imagem da aba
35
+
36
  im = Image.open("pngegg.png")
37
  st.set_page_config(page_title = "Chatbot Carômetro", page_icon=im, layout = "wide")
38
+
39
  #Removido loop e adicionado os.makedirs
40
  os.makedirs("bm25_retriever", exist_ok=True)
41
  os.makedirs("chat_store", exist_ok=True)
 
43
  os.makedirs("documentos", exist_ok=True)
44
  os.makedirs("curadoria", exist_ok=True)
45
  os.makedirs("chroma_db_curadoria", exist_ok=True)
46
+
47
  # Configuração do Streamlit
48
  st.sidebar.title("Configuração de LLM")
49
  sidebar_option = st.sidebar.radio("Selecione o LLM", ["gpt-3.5-turbo", "NuExtract-1.5"])
50
  # logo_url = 'app\logos\logo-sicoob.jpg'
51
  # st.sidebar.image(logo_url)
52
  import base64
53
+
54
  #Configuração da imagem da sidebar
55
  with open("sicoob-logo.png", "rb") as f:
56
  data = base64.b64encode(f.read()).decode("utf-8")
57
+
58
  st.sidebar.markdown(
59
  f"""
60
  <div style="display:table;margin-top:-80%;margin-left:0%;">
 
63
  """,
64
  unsafe_allow_html=True,
65
  )
66
+
67
+
68
  #if sidebar_option == "Ollama":
69
  # Settings.llm = Ollama(model="llama3.2:latest", request_timeout=500.0, num_gpu=1)
70
  # Settings.embed_model = OllamaEmbedding(model_name="nomic-embed-text:latest")
 
74
  Settings.llm = OpenAI(model="gpt-3.5-turbo")
75
  Settings.embed_model = OpenAIEmbedding(model_name="text-embedding-ada-002")
76
  elif sidebar_option == 'NuExtract-1.5':
77
+
78
  logging.basicConfig(stream=sys.stdout, level=logging.INFO)
79
  logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
80
+
81
  #Embedding do huggingface
82
  Settings.embed_model = HuggingFaceEmbedding(
83
  model_name="BAAI/bge-small-en-v1.5"
84
  )
85
  #Carregamento do modelo local, descomentar o modelo desejado
86
+
87
  llm = HuggingFaceLLM(
88
  context_window=2048,
89
+ max_new_tokens=2048,
90
  generate_kwargs={"do_sample": False},
91
  #query_wrapper_prompt=query_wrapper_prompt,
92
  #model_name="Qwen/Qwen2.5-Coder-32B-Instruct",
 
96
  # model_name="meta-llama/Meta-Llama-3-8B",
97
  model_name="numind/NuExtract-1.5",
98
  #model_name="meta-llama/Llama-3.2-3B",
99
+
100
  tokenizer_name="numind/NuExtract-1.5",
101
  device_map="auto",
102
+ tokenizer_kwargs={"max_length": 512},
103
  # uncomment this if using CUDA to reduce memory usage
104
  model_kwargs={"torch_dtype": torch.bfloat16},
105
  )
106
  chat = [
107
+
108
  {"role": "user", "content": "Hello, how are you?"},
109
+
110
  {"role": "assistant", "content": "I'm doing great. How can I help you today?"},
111
+
112
  {"role": "user", "content": "I'd like to show off how chat templating works!"},
113
+
114
  ]
115
+
116
  from transformers import AutoTokenizer
117
+
118
  tokenizer = AutoTokenizer.from_pretrained("numind/NuExtract-1.5")
119
+
120
  tokenizer.apply_chat_template(chat, tokenize=False)
121
+
122
+
123
  Settings.chunk_size = 512
124
  Settings.llm = llm
125
+
126
  else:
127
  raise Exception("Opção de LLM inválida!")
128
+
129
  # Diretórios configurados pelo usuário
130
  chat_store_path = os.path.join("chat_store", "chat_store.json")
131
  documents_path = os.path.join("documentos")
 
133
  chroma_storage_path_curadoria = os.path.join("chroma_db_curadoria") # Diretório para 'curadoria'
134
  bm25_persist_path = os.path.join("bm25_retriever")
135
  curadoria_path = os.path.join("curadoria")
136
+
137
+
138
  # Configuração de leitura de documentos
139
  documents = SimpleDirectoryReader(input_dir=documents_path).load_data()
140
+
141
  # Configuração do Chroma e BM25 com persistência
142
  docstore = SimpleDocumentStore()
143
  docstore.add_documents(documents)
144
+
145
  db = chromadb.PersistentClient(path=chroma_storage_path)
146
  chroma_collection = db.get_or_create_collection("dense_vectors")
147
  vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
148
+
149
  # Configuração do StorageContext
150
  storage_context = StorageContext.from_defaults(
151
  docstore=docstore, vector_store=vector_store
152
  )
153
+
154
  # Criação/Recarregamento do índice com embeddings
155
  if os.path.exists(chroma_storage_path):
156
  index = VectorStoreIndex.from_vector_store(vector_store)
 
162
  documents, storage_context=storage_context, transformations=[splitter]
163
  )
164
  vector_store.persist()
165
+
166
  # Criação/Recarregamento do BM25 Retriever
167
  if os.path.exists(os.path.join(bm25_persist_path, "params.index.json")):
168
  bm25_retriever = BM25Retriever.from_persist_dir(bm25_persist_path)
 
174
  )
175
  os.makedirs(bm25_persist_path, exist_ok=True)
176
  bm25_retriever.persist(bm25_persist_path)
177
+
178
  #Adicionado documentos na pasta curadoria, foi setado para 1200 o chunk pra receber pergunta, contexto e resposta
179
  curadoria_documents = SimpleDirectoryReader(input_dir=curadoria_path).load_data()
180
+
181
  curadoria_docstore = SimpleDocumentStore()
182
  curadoria_docstore.add_documents(curadoria_documents)
183
+
184
  db_curadoria = chromadb.PersistentClient(path=chroma_storage_path_curadoria)
185
  chroma_collection_curadoria = db_curadoria.get_or_create_collection("dense_vectors_curadoria")
186
  vector_store_curadoria = ChromaVectorStore(chroma_collection=chroma_collection_curadoria)
187
+
188
  # Configuração do StorageContext para 'curadoria'
189
  storage_context_curadoria = StorageContext.from_defaults(
190
  docstore=curadoria_docstore, vector_store=vector_store_curadoria
191
  )
192
+
193
  # Criação/Recarregamento do índice com embeddings para 'curadoria'
194
  if os.path.exists(chroma_storage_path_curadoria):
195
  curadoria_index = VectorStoreIndex.from_vector_store(vector_store_curadoria)
 
201
  curadoria_documents, storage_context=storage_context_curadoria, transformations=[curadoria_splitter]
202
  )
203
  vector_store_curadoria.persist()
204
+
205
  curadoria_retriever = curadoria_index.as_retriever(similarity_top_k=2)
206
+
207
  # Combinação de Retrievers (Embeddings + BM25)
208
  vector_retriever = index.as_retriever(similarity_top_k=2)
209
  retriever = QueryFusionRetriever(
210
  [vector_retriever, bm25_retriever, curadoria_retriever],
211
  similarity_top_k=2,
212
+ #num_queries=0,
213
  mode="reciprocal_rerank",
214
  use_async=True,
215
  verbose=True,
 
222
  "Perguntas:\n"
223
  ),
224
  )
225
+
226
  # Configuração do chat engine
227
  nest_asyncio.apply()
228
  memory = ChatMemoryBuffer.from_defaults(token_limit=3900)
 
239
  ),
240
  verbose=True,
241
  )
242
+
243
  # Armazenamento do chat
244
  chat_store = SimpleChatStore()
245
  if os.path.exists(chat_store_path):
246
  chat_store = SimpleChatStore.from_persist_path(persist_path=chat_store_path)
247
  else:
248
  chat_store.persist(persist_path=chat_store_path)
249
+
250
  # Interface do Chatbot
251
  st.title("Chatbot Carômetro")
252
  st.write("Este chatbot pode te ajudar a conseguir informações relevantes sobre os carômetros da Sicoob.")
253
+
254
+ if 'chat_history' not in st.session_state:
255
  st.session_state.chat_history = []
256
+
257
+ for message in st.session_state.chat_history:
258
+ role, text = message.split(":", 1)
259
+ with st.chat_message(role.strip().lower()):
260
+ st.write(text.strip())
261
+
262
  user_input = st.chat_input("Digite sua pergunta")
263
  if user_input:
264
+ # Exibir a mensagem do usuário e adicionar ao histórico
265
+ with st.chat_message('user'):
266
+ st.write(user_input)
267
  st.session_state.chat_history.append(f"user: {user_input}")
268
+
269
+ # Placeholder para a mensagem do assistente
270
+ with st.chat_message('assistant'):
271
+ message_placeholder = st.empty()
272
+ assistant_message = ''
273
+
274
+ # Obter a resposta em streaming do chat_engine
275
+ response = chat_engine.stream_chat(user_input)
276
+ for token in response.response_gen:
277
+ assistant_message += token
278
+ # Atualizar o placeholder da mensagem
279
+ message_placeholder.markdown(assistant_message + "▌")
280
+
281
+ # Remover o cursor após a conclusão
282
+ message_placeholder.markdown(assistant_message)
283
+ st.session_state.chat_history.append(f"assistant: {assistant_message}")