tecuhtli commited on
Commit
9c8e3d6
·
1 Parent(s): 6ff6e86

Actualizando la version para entrega de Mori

Browse files
Files changed (2) hide show
  1. Mori_TechnicalPrompts.py +157 -2
  2. requirements.txt +4 -1
Mori_TechnicalPrompts.py CHANGED
@@ -7,7 +7,7 @@ import unicodedata
7
  import re
8
  from Mori_Chatbot_SpanishCorrections import polish_spanish
9
  from Mori_Technical_RAGwithFAISS import retrieve_docs
10
- import os
11
  import warnings
12
  # ************************************************************************
13
  # Defining default paths for the model to work
@@ -15,11 +15,36 @@ import warnings
15
  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
16
  warnings.filterwarnings("ignore", category=UserWarning)
17
  warnings.filterwarnings("ignore", category=FutureWarning)
18
-
19
  #=====================================================================================
20
  # Functions =========================================================================
21
  #=====================================================================================
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
  def normalize_text(text: str) -> str:
25
 
@@ -196,6 +221,136 @@ def answer_with_mori_plain(tokenizer, model, question: str, modo: str = "exacto"
196
  return polish_spanish(raw_answer), prompt
197
 
198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  def get_gen_kwargs(modo="exacto"):
200
 
201
  """Selecting the Mori personaliuty by using different hyperparameters settigns"""
 
7
  import re
8
  from Mori_Chatbot_SpanishCorrections import polish_spanish
9
  from Mori_Technical_RAGwithFAISS import retrieve_docs
10
+ import os, torch
11
  import warnings
12
  # ************************************************************************
13
  # Defining default paths for the model to work
 
15
  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
16
  warnings.filterwarnings("ignore", category=UserWarning)
17
  warnings.filterwarnings("ignore", category=FutureWarning)
18
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
19
  #=====================================================================================
20
  # Functions =========================================================================
21
  #=====================================================================================
22
 
23
+ def recortar_ultima_oracion(texto):
24
+
25
+ """Remove incomplete generated text"""
26
+ texto = texto.strip()
27
+ if not texto:
28
+ return texto
29
+
30
+ # signos válidos de cierre
31
+ signos = ".?!…"
32
+
33
+ # encontrar la última posición
34
+ posiciones = [texto.rfind(s) for s in signos]
35
+ posiciones = [p for p in posiciones if p != -1]
36
+
37
+ if not posiciones:
38
+ return texto # no hay signos → lo regresamos
39
+
40
+ final = max(posiciones)
41
+
42
+ # aseguramos que no sea demasiado pronto
43
+ if final < len(texto) * 0.3:
44
+ return texto
45
+
46
+ return texto[:final + 1].strip()
47
+
48
 
49
  def normalize_text(text: str) -> str:
50
 
 
221
  return polish_spanish(raw_answer), prompt
222
 
223
 
224
+ def build_qwen_system_prompt(persona: str) -> str:
225
+
226
+ """Generates prompts based on the model personality"""
227
+
228
+ p = (persona or "").lower()
229
+
230
+ base = (
231
+ "Eres Mori Técnico, un asistente de ciencia de datos. "
232
+ "Respondes siempre en español de México, con explicaciones claras y amables. "
233
+ )
234
+
235
+ if "exacto" in p:
236
+ return (
237
+ base +
238
+ "Respondes de forma muy breve, directa y precisa, "
239
+ "en un solo párrafo de máximo 64 palabras, sin listas ni numeración."
240
+ )
241
+ elif "creativo" in p:
242
+ return (
243
+ base +
244
+ "Respondes de forma creativa y entusiasta, con un tono cálido y motivador, "
245
+ "en un solo párrafo de máximo 92 palabras, evitando listas y numeración."
246
+ )
247
+ else:
248
+ return (
249
+ base +
250
+ "Respondes de forma breve, clara y natural, "
251
+ "en un solo párrafo y evitando listas y numeración."
252
+ )
253
+
254
+ def answer_with_qwen_base(
255
+ tokenizer,
256
+ model,
257
+ user_question: str,
258
+ persona: str = "Mori Técnico",
259
+ max_new_tokens: int = 64,
260
+ ) -> str:
261
+ """
262
+ Genera una respuesta usando Qwen base, sin RAG ni fine-tuning.
263
+ - Ajusta el estilo según la personalidad (exacto / creativo).
264
+ - Usa max_new_tokens para controlar el largo de la respuesta.
265
+ """
266
+ if not user_question.strip():
267
+ return "Necesito que me cuentes algo para poder ayudarte 🙂."
268
+
269
+ system_prompt = build_qwen_system_prompt(persona)
270
+ used_chat_template = False
271
+
272
+ # 1) Construimos el prompt de texto
273
+ if hasattr(tokenizer, "apply_chat_template"):
274
+ used_chat_template = True
275
+ messages = [
276
+ {"role": "system", "content": system_prompt},
277
+ {"role": "user", "content": user_question.strip()},
278
+ ]
279
+ # devolvemos string, no tensores
280
+ prompt = tokenizer.apply_chat_template(
281
+ messages,
282
+ tokenize=False,
283
+ add_generation_prompt=True,
284
+ )
285
+ else:
286
+ prompt = (
287
+ f"system {system_prompt}\n"
288
+ f"user {user_question.strip()}\n"
289
+ f"assistant "
290
+ )
291
+
292
+ # 2) Tokenizar el prompt
293
+ inputs = tokenizer(
294
+ prompt,
295
+ return_tensors="pt"
296
+ ).to(device)
297
+
298
+ gen_kwargs = get_gen_kwargs(persona)
299
+ # 3) Generar (aquí usamos max_new_tokens que viene de la UI)
300
+ with torch.no_grad():
301
+ if persona == 'exacto':
302
+ output_ids = model.generate(
303
+ **inputs,
304
+ max_new_tokens=64,
305
+ do_sample=True,
306
+ temperature=0.2,
307
+ num_beams=1,
308
+ top_p=0.8,
309
+ pad_token_id=tokenizer.eos_token_id,
310
+ )
311
+
312
+ elif persona =='creativo':
313
+ output_ids = model.generate(
314
+ **inputs,
315
+ max_new_tokens=256,
316
+ do_sample=True,
317
+ temperature=0.9,
318
+ num_beams=1,
319
+ top_p=0.9,
320
+ pad_token_id=tokenizer.eos_token_id,
321
+ )
322
+
323
+ text = tokenizer.decode(output_ids[0], skip_special_tokens=True)
324
+
325
+ # 4) Recortar el prompt de la salida
326
+ cleaned = text
327
+
328
+ if used_chat_template:
329
+ if cleaned.startswith(prompt):
330
+ cleaned = cleaned[len(prompt):].strip()
331
+ else:
332
+ lower = cleaned.lower()
333
+ marker = "assistant"
334
+ idx = lower.rfind(marker)
335
+ if idx != -1:
336
+ cleaned = cleaned[idx + len(marker):].strip()
337
+ else:
338
+ if cleaned.startswith(prompt):
339
+ cleaned = cleaned[len(prompt):].strip()
340
+ else:
341
+ lower = cleaned.lower()
342
+ marker = "assistant"
343
+ idx = lower.rfind(marker)
344
+ if idx != -1:
345
+ cleaned = cleaned[idx + len(marker):].strip()
346
+
347
+ cleaned = recortar_ultima_oracion(cleaned)
348
+
349
+ return cleaned.strip(), prompt
350
+
351
+
352
+
353
+
354
  def get_gen_kwargs(modo="exacto"):
355
 
356
  """Selecting the Mori personaliuty by using different hyperparameters settigns"""
requirements.txt CHANGED
@@ -9,4 +9,7 @@ torch==2.6.0
9
  joblib
10
  sentence-transformers
11
  faiss-cpu
12
- ujson
 
 
 
 
9
  joblib
10
  sentence-transformers
11
  faiss-cpu
12
+ ujson
13
+ accelerate
14
+ numpy
15
+ protobuf