ailearnings commited on
Commit
bd386c3
·
verified ·
1 Parent(s): 22a56d5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +176 -42
app.py CHANGED
@@ -1,58 +1,190 @@
 
1
  import gradio as gr
2
  from ctransformers import AutoModelForCausalLM
3
  import threading
4
  from langdetect import detect, DetectorFactory
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  # Introducimos un mensaje para el modelo para que hable solo en español y con respeto
7
- system_message = "Eres un asistente que siempre responde en español."
8
 
 
 
 
 
 
9
  def load_llm():
10
- llm = AutoModelForCausalLM.from_pretrained(
11
- "TheBloke/Llama-2-7B-Chat-GGUF",
12
- model_file='llama-2-7b-chat.Q5_K_M.gguf',
13
- model_type='llama',
14
- max_new_tokens=2048,
15
- context_length = 4096,
16
- repetition_penalty=1.13,
17
- temperature=0.1
18
- )
19
- return llm
20
 
21
- def llm_function(message, chat_history):
22
- llm = load_llm()
23
- # Concatenar el mensaje del sistema con el mensaje del usuario
24
- full_message = f"{system_message}\nUser: {message}\nAssistant:"
25
- response = llm(full_message)
26
- # Registrar el mensaje y la respuesta en el archivo de logs
27
- logging.info(f"Message: {message}")
28
- logging.info(f"Response: {response}")
29
-
30
- # Verificar el idioma de la respuesta
31
- try:
32
- response_language = detect(response)
33
- except:
34
- response_language = "error"
35
 
36
- if response_language != 'es':
37
- return "Su pregunta es muy compleja para el modelo. Por favor, elabore preguntas más sencillas para que el modelo pueda responderle. Estamos investigando cómo, en un futuro, pueda utilizar la pregunta que quiera y el modelo le responda correctamente."
 
 
 
 
 
 
 
 
 
 
38
  else:
39
- return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- # Función con límite de tiempo
42
- def llm_function_with_timeout(message, chat_history, timeout=120):
43
- result = [None] # Lista para almacenar el resultado
 
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  def target():
 
46
  result[0] = llm_function(message, chat_history)
47
 
48
  thread = threading.Thread(target=target)
49
  thread.start()
50
  thread.join(timeout)
51
  if thread.is_alive():
 
52
  thread.join()
53
  return "Tu pregunta no ha podido ser respondida en el tiempo estimado. Por favor, intenta de nuevo o reformula tu pregunta."
54
  return result[0]
55
 
 
56
  title = "ChatterIA"
57
 
58
  description = """
@@ -61,7 +193,7 @@ ChatterIA es un modelo de lenguaje que funciona como un asistente con infinidad
61
  <li>Las respuestas de este modelo pueden no ser siempre precisas, al depender de su configuración, capacidad de interpretación y contextualización</li>
62
  <li>Usa este modelo bajo tu responsabilidad.</li>
63
  <li>Si no o obtienes respuesta a tu consulta, intenta volver a reformularla.</li>
64
- <li>Si necesitas alguna aclaraci&oacute;n o tienes cualquier otra duda, puedes enviar un correo electr&oacute;nico a soporte: <a href='mailto:[email protected]'> Mandar email </a>. o revisar nuestras gu&iacute;as: <a href='http://fuentezuelas.com/playground/ChatterIA/index.php#guias' target="_blank"> Acceder a gu&iacute;as </a></li>
65
  <li>Es importante que sepas este sitio es de uso educativo. El env&iacute;o de mensajes masivos puede dar error.</li>
66
  </ul>
67
  """
@@ -70,10 +202,14 @@ theme = 'Taithrah/Minimal'
70
 
71
  examples = [
72
  'Escribe un código de python para conectarte con una base de datos en MySQL y liste todas las tablas.',
73
- 'Escribe un modelo de correo para enviar como felicitación navideña para un amigo y para un familiar.',
74
- 'Explícame porque a día de hoy la economía global no ha cambiado su modelo de capitalismo por uno más sostenible como la economía circular.',
75
- 'Ayudame a programar un juego de tres en raya para jugar en html, css y javascript.',
76
- '¿Cuáles son los reinados de la historia que más han conseguido?'
 
 
 
 
77
  ]
78
  css = """
79
  #component-0 {
@@ -155,8 +291,7 @@ footer{
155
  }
156
  }
157
  """
158
-
159
- demo = gr.ChatInterface(
160
  fn = llm_function_with_timeout,
161
  chatbot=gr.Chatbot(label="ChatterIA"),
162
  textbox= gr.Textbox(placeholder="Envía tu mensaje...", lines=3, max_lines=10),
@@ -164,11 +299,10 @@ demo = gr.ChatInterface(
164
  description = description,
165
  theme = theme,
166
  examples = examples,
167
- #cache_examples=True,
168
- css=css,
169
  submit_btn = "📤 Enviar",
170
  retry_btn = "🔁 Reenviar",
171
  undo_btn = "🔙 Deshacer",
172
  clear_btn= "🗑 Limpiar",
173
- )
174
- demo.launch()
 
1
+ import logging
2
  import gradio as gr
3
  from ctransformers import AutoModelForCausalLM
4
  import threading
5
  from langdetect import detect, DetectorFactory
6
+ from langid import classify
7
+ import spacy
8
+ import os
9
+ import psutil
10
+ import time
11
+
12
+ # Obtener el proceso actual
13
+ process = psutil.Process(os.getpid())
14
+
15
+ # Función para imprimir el uso de CPU y RAM
16
+ def print_resource_usage():
17
+ while True: # Crear un bucle infinito para que se ejecute continuamente
18
+ cpu_usage = process.cpu_percent(interval=1)
19
+ ram_usage = process.memory_info().rss / (1024 * 1024) # Convertir bytes a MB
20
+ pid = str(process.pid)
21
+ print(f"Uso de CPU: {cpu_usage}%")
22
+ print(f"Uso de RAM: {ram_usage} MB")
23
+ print(f"PID: {pid}")
24
+ time.sleep(10) # Esperar 2 segundos antes de la próxima impresión
25
+
26
+ # Crear y empezar un hilo para el monitoreo de recursos
27
+ monitoring_thread = threading.Thread(target=print_resource_usage)
28
+ monitoring_thread.daemon = True # Establecer como un daemon para que no bloquee el programa de terminar
29
+ monitoring_thread.start()
30
+
31
+
32
+ # Configuración del logger
33
+ logging.basicConfig(filename='chatterIA_logs.txt', level=logging.INFO,
34
+ format='%(asctime)s %(levelname)s:%(message)s')
35
+
36
+ DetectorFactory.seed = 0 # Para obtener resultados consistentes en la detección del idioma (outputs)
37
 
38
  # Introducimos un mensaje para el modelo para que hable solo en español y con respeto
39
+ system_message ="Eres un asistente que siempre responde en español. A cualquiera de sus peticiones y nunca hablas en ningún otro idioma"
40
 
41
+ # Cargar el modelo una sola vez
42
+ model_instance = None
43
+
44
+ # Cargar el modelo que detecta el idioma de los mensajes solo 1 vez. (inputs)
45
+ nlp_sm = spacy.load("es_core_news_sm")
46
  def load_llm():
 
 
 
 
 
 
 
 
 
 
47
 
48
+ global model_instance
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ if model_instance is None:
51
+ print("Cargando el modelo...")
52
+ model_instance = AutoModelForCausalLM.from_pretrained(
53
+ "TheBloke/Llama-2-7B-Chat-GGUF",
54
+ model_file='llama-2-7b-chat.Q5_K_M.gguf',
55
+ model_type='llama',
56
+ max_new_tokens=2048,
57
+ context_length = 4096,
58
+ repetition_penalty=1.13,
59
+ temperature=0.1
60
+ )
61
+ print("Modelo cargado éxitosamente")
62
  else:
63
+ print("Ya se ha cargado el modelo anteriormente")
64
+
65
+ return model_instance
66
+ def truncate_history(history, max_tokens=2048):
67
+ truncated_history = []
68
+ total_tokens = 0
69
+ for user_msg, bot_msg in reversed(history):
70
+ # Asegurarse de que ni user_msg ni bot_msg sean None
71
+ user_msg = user_msg if user_msg is not None else ""
72
+ bot_msg = bot_msg if bot_msg is not None else ""
73
+
74
+ msg_tokens = len(user_msg.split()) + len(bot_msg.split())
75
+ if total_tokens + msg_tokens > max_tokens:
76
+ break
77
+ truncated_history.insert(0, (user_msg, bot_msg))
78
+ total_tokens += msg_tokens
79
+ return truncated_history
80
+ def clean_response(response):
81
+ code_block_count = response.count("```")
82
+
83
+ if code_block_count % 2 != 0:
84
+ last_occurrence_index = response.rfind("```")
85
+ response = response[:last_occurrence_index] + response[last_occurrence_index+3:]
86
+
87
+ return response
88
 
89
+ def format_history_for_model(history):
90
+ new_history = "\n".join(f"{user_msg}\n{bot_msg}".strip() for user_msg, bot_msg in history)
91
+ new_history += "\nRespuesta:"
92
+ return new_history
93
 
94
+
95
+ def detectar_idioma_con_spacy(texto):
96
+ doc = nlp_sm(texto, disable=["parser","ner"])
97
+ return True
98
+
99
+ def prepare_message(message):
100
+ # Primero, intenta detectar el idioma con langid
101
+ lang, confidence = classify(message)
102
+ if lang == 'es':
103
+ return str(message) # Si langid está seguro de que es español, retorna el mensaje
104
+
105
+ # Si el mensaje es muy corto y langid no lo clasifica definitivamente como español,
106
+ # utiliza SpaCy como una verificación adicional.
107
+ if len(message.split()) <= 3: # Considera ajustar este umbral según tus necesidades
108
+ es_espanol_spacy = detectar_idioma_con_spacy(message)
109
+ if es_espanol_spacy:
110
+ return str(message) # Si SpaCy procesa el texto sin problemas, asume que es español
111
+
112
+ # Si ninguna de las verificaciones anteriores concluye que el mensaje es en español, retorna None
113
+ return None
114
+
115
+ def llm_function(message, chat_history ):
116
+ try:
117
+ print(f"Mensaje principal:{message}")
118
+ logging.info(f"Tipo de Message: {type(message)}, Message: {message}")
119
+ message = str(message)
120
+ message_str = str(message)
121
+
122
+ # Aquí puedes añadir cualquier validación adicional del mensaje
123
+ if not message_str.strip():
124
+ logging.info("El mensaje está vacío o solo contiene espacios.")
125
+ return "Por favor, envía un mensaje no vacío.", chat_history
126
+
127
+ # Continuar con el procesamiento...
128
+ logging.info(f"Message: {message_str}")
129
+
130
+ print(f"Historial del Chat (segun el chatbot)")
131
+ for i in chat_history:
132
+ print (i)
133
+ print("Fin de variables desde el chat")
134
+
135
+ llm = load_llm()
136
+ message = prepare_message(message)
137
+
138
+ if message is None:
139
+ return f"Por favor, envía tu mensaje en español. Actualmente idioma es: {detect(message)}"
140
+ chat_history = truncate_history(chat_history + [(message, "")]) # Añadir el mensaje actual al historial
141
+
142
+ print("Historial del chat antes de formateo")
143
+ for i in chat_history:
144
+ print (i)
145
+ print("Fin de historial previo a formateo")
146
+ formatted_history = format_history_for_model(chat_history) # Formatear el historial para el modelo
147
+
148
+ full_message = f"{system_message}\n{formatted_history}"
149
+ print (f"Mensaje completo: {full_message}")
150
+ response = llm(full_message) # Generar respuesta
151
+ cleaned_response = clean_response(response)
152
+
153
+ logging.info(f"Message: {message}")
154
+ logging.info(f"Response: {response}")
155
+
156
+ try:
157
+ response_language = detect(response)
158
+ print(f"Idioma en response_language: {response_language}")
159
+ print(f"Response:{response}")
160
+ if response_language != 'es':
161
+ return "Lo siento, pero no puedo responder correctamente en español a esa pregunta."
162
+ else:
163
+ cleaned_response = clean_response(response)
164
+ return cleaned_response
165
+ except Exception as e:
166
+ logging.error(f"Error al detectar el idioma: {e}")
167
+ return "Hubo un error al procesar tu mensaje."
168
+ except Exception as e:
169
+ logging.error(f"Error al procesar el mensaje: {e}")
170
+ return "Hubo un error al procesar tu mensaje, revisa que sea un mensaje completo."
171
+
172
+ def llm_function_with_timeout(message, chat_history, timeout=180):
173
+ result = [None] # Lista para almacenar el resultado
174
  def target():
175
+ # Intentar adquirir el semáforo antes de ejecutar la función
176
  result[0] = llm_function(message, chat_history)
177
 
178
  thread = threading.Thread(target=target)
179
  thread.start()
180
  thread.join(timeout)
181
  if thread.is_alive():
182
+ # Si el thread todavía está vivo después del timeout, se asume que está bloqueado y se debe manejar
183
  thread.join()
184
  return "Tu pregunta no ha podido ser respondida en el tiempo estimado. Por favor, intenta de nuevo o reformula tu pregunta."
185
  return result[0]
186
 
187
+
188
  title = "ChatterIA"
189
 
190
  description = """
 
193
  <li>Las respuestas de este modelo pueden no ser siempre precisas, al depender de su configuración, capacidad de interpretación y contextualización</li>
194
  <li>Usa este modelo bajo tu responsabilidad.</li>
195
  <li>Si no o obtienes respuesta a tu consulta, intenta volver a reformularla.</li>
196
+ <li>Si necesitas alguna aclaraci&oacute;n o tienes cualquier otra duda, puedes enviar un correo electr&oacute;nico a soporte: <a href='mailto:[email protected]'> Mandar email </a>. o revisar nuestras gu&iacute;as: <a href='http://fuentezuelas.com/ia/playground/ChatterIA/index.php#guias'> Acceder a gu&iacute;as </a></li>
197
  <li>Es importante que sepas este sitio es de uso educativo. El env&iacute;o de mensajes masivos puede dar error.</li>
198
  </ul>
199
  """
 
202
 
203
  examples = [
204
  'Escribe un código de python para conectarte con una base de datos en MySQL y liste todas las tablas.',
205
+ 'Escribe un poema sobre el otoño con rima consonante y en forma de soneto.',
206
+ 'Resume el argumento de "El Quijote", y explícaselo a un niño de 5 años para que le interese.',
207
+ 'Dime como fusionar dos diccionarios en Python y diferentes usos que puede tener esto.',
208
+ 'Dime que debo considerar al comprar un coche usado y que me recomiendas saber al respecto.',
209
+ 'Explica la teoría de la relatividad de Einstein para estudiantes de primaria.',
210
+ 'Dime cuáles podrían ser las implicaciones de la inteligencia artificial en el empleo.',
211
+ 'Redacta un correo para mi jefe en el cual, quiero pedirle un aumento de salario.',
212
+ 'Escribe una cancion que dure aproximadamente 2 minutos y que trate sobre la desigualdad en España.'
213
  ]
214
  css = """
215
  #component-0 {
 
291
  }
292
  }
293
  """
294
+ demo= gr.ChatInterface(
 
295
  fn = llm_function_with_timeout,
296
  chatbot=gr.Chatbot(label="ChatterIA"),
297
  textbox= gr.Textbox(placeholder="Envía tu mensaje...", lines=3, max_lines=10),
 
299
  description = description,
300
  theme = theme,
301
  examples = examples,
302
+ css = css,
303
+ cache_examples=False,
304
  submit_btn = "📤 Enviar",
305
  retry_btn = "🔁 Reenviar",
306
  undo_btn = "🔙 Deshacer",
307
  clear_btn= "🗑 Limpiar",
308
+ ).launch()