Spaces:
Running
Running
NoeMartinezSanchez commited on
Commit ·
799e578
1
Parent(s): 507c852
Mejora del promt 2
Browse files- models/gemma_wrapper.py +88 -48
models/gemma_wrapper.py
CHANGED
|
@@ -220,6 +220,8 @@ class GemmaWrapper:
|
|
| 220 |
|
| 221 |
response = generated_text[len(prompt):].strip()
|
| 222 |
|
|
|
|
|
|
|
| 223 |
if len(response) < 10:
|
| 224 |
logger.warning(f"Response very short ({len(response)} chars)")
|
| 225 |
return response.strip() if response.strip() else "No se pudo generar una respuesta."
|
|
@@ -256,25 +258,22 @@ class GemmaWrapper:
|
|
| 256 |
Returns:
|
| 257 |
Generated response based on the context.
|
| 258 |
"""
|
| 259 |
-
|
| 260 |
-
context = context[:800] + "..."
|
| 261 |
-
|
| 262 |
-
prompt = self._build_gemma_prompt(context, question)
|
| 263 |
|
| 264 |
logger.info(f"RAG generation - Context length: {len(context)}, Question: {question[:50]}...")
|
| 265 |
return self.generate(
|
| 266 |
prompt=prompt,
|
| 267 |
-
max_new_tokens=
|
| 268 |
-
temperature=0.
|
| 269 |
-
top_p=0.
|
| 270 |
-
repetition_penalty=1.
|
| 271 |
-
no_repeat_ngram_size=
|
| 272 |
early_stopping=True,
|
| 273 |
-
min_new_tokens=
|
| 274 |
)
|
| 275 |
|
| 276 |
-
def
|
| 277 |
-
"""Build
|
| 278 |
|
| 279 |
Args:
|
| 280 |
context: Retrieved context from RAG.
|
|
@@ -285,60 +284,101 @@ class GemmaWrapper:
|
|
| 285 |
"""
|
| 286 |
question_lower = question.lower().strip()
|
| 287 |
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
|
|
|
|
|
|
|
|
|
| 291 |
|
| 292 |
-
elif any(palabra in question_lower for palabra in
|
| 293 |
-
user_message = """
|
| 294 |
-
Despídete de manera amable y deseando éxito en los estudios."""
|
| 295 |
|
| 296 |
-
elif any(palabra in question_lower for palabra in
|
| 297 |
-
user_message = """
|
| 298 |
-
Agradece de manera cálida y ofrece ayuda adicional si la necesita."""
|
| 299 |
|
| 300 |
else:
|
| 301 |
-
system_prompt = """Eres
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
1.
|
| 305 |
-
2.
|
| 306 |
-
3.
|
| 307 |
-
4. Si
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
Respuesta: Sí, puedes dar de baja hasta 3 módulos mediante baja parcial. Esto no afectará tu promedio. Debes solicitarla dentro de las fechas establecidas.
|
| 320 |
-
|
| 321 |
-
Contexto: Los exámenes finales son presenciales en centros SEP asignados.
|
| 322 |
-
Pregunta: dónde presento mis exámenes?
|
| 323 |
-
Respuesta: Los exámenes finales se presentan de forma presencial en los centros asignados por la SEP. Revisa tu calendario para conocer la sede."""
|
| 324 |
|
| 325 |
user_message = f"""{system_prompt}
|
| 326 |
|
| 327 |
-
|
| 328 |
{context}
|
| 329 |
|
| 330 |
-
|
| 331 |
{question}
|
| 332 |
|
| 333 |
-
|
| 334 |
|
| 335 |
prompt = f"""<start_of_turn>user
|
| 336 |
{user_message}<end_of_turn>
|
| 337 |
<start_of_turn>model
|
| 338 |
-
"""
|
| 339 |
|
| 340 |
return prompt
|
| 341 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
def _clear_cache(self) -> None:
|
| 343 |
"""Clear Python and PyTorch garbage and cache."""
|
| 344 |
gc.collect()
|
|
|
|
| 220 |
|
| 221 |
response = generated_text[len(prompt):].strip()
|
| 222 |
|
| 223 |
+
response = self._clean_response(response)
|
| 224 |
+
|
| 225 |
if len(response) < 10:
|
| 226 |
logger.warning(f"Response very short ({len(response)} chars)")
|
| 227 |
return response.strip() if response.strip() else "No se pudo generar una respuesta."
|
|
|
|
| 258 |
Returns:
|
| 259 |
Generated response based on the context.
|
| 260 |
"""
|
| 261 |
+
prompt = self._build_optimized_prompt(context, question)
|
|
|
|
|
|
|
|
|
|
| 262 |
|
| 263 |
logger.info(f"RAG generation - Context length: {len(context)}, Question: {question[:50]}...")
|
| 264 |
return self.generate(
|
| 265 |
prompt=prompt,
|
| 266 |
+
max_new_tokens=512,
|
| 267 |
+
temperature=0.3,
|
| 268 |
+
top_p=0.85,
|
| 269 |
+
repetition_penalty=1.15,
|
| 270 |
+
no_repeat_ngram_size=4,
|
| 271 |
early_stopping=True,
|
| 272 |
+
min_new_tokens=50,
|
| 273 |
)
|
| 274 |
|
| 275 |
+
def _build_optimized_prompt(self, context: str, question: str) -> str:
|
| 276 |
+
"""Build optimized prompt for Gemma.
|
| 277 |
|
| 278 |
Args:
|
| 279 |
context: Retrieved context from RAG.
|
|
|
|
| 284 |
"""
|
| 285 |
question_lower = question.lower().strip()
|
| 286 |
|
| 287 |
+
saludos_keywords = ["hola", "buenos días", "buenas tardes", "buenas", "holi", "hello", "hey", "qué tal", "cómo estás", "qué onda", "buen día"]
|
| 288 |
+
despedidas_keywords = ["adiós", "chao", "bye", "hasta luego", "me voy", "nos vemos", "me retiro"]
|
| 289 |
+
gracias_keywords = ["gracias", "thank", "agradezco", "te agradezco", "muchas gracias"]
|
| 290 |
+
|
| 291 |
+
if any(saludo in question_lower for saludo in saludos_keywords):
|
| 292 |
+
user_message = """¡Hola! Bienvenido a Prepa en Línea SEP. Estoy aquí para ayudarte con cualquier duda sobre trámites, fechas, inscripciones y académicas. ¿En qué puedo ayudarte hoy?"""
|
| 293 |
|
| 294 |
+
elif any(palabra in question_lower for palabra in despedidas_keywords):
|
| 295 |
+
user_message = """¡Hasta luego! Éxito en tu camino por Prepa en Línea SEP. Cuando tengas dudas, vuelve por aquí. ¡Tú puedes!"""
|
|
|
|
| 296 |
|
| 297 |
+
elif any(palabra in question_lower for palabra in gracias_keywords):
|
| 298 |
+
user_message = """¡De nada! Estoy para ayudarte. Si tienes más dudas sobre Prepa en Línea SEP, escríbeme cuando quieras."""
|
|
|
|
| 299 |
|
| 300 |
else:
|
| 301 |
+
system_prompt = """Eres el asistente virtual oficial de Prepa en Línea SEP.
|
| 302 |
+
|
| 303 |
+
REGLAS ESTRICTAS:
|
| 304 |
+
1. NO uses hashtags (#), emojis, asteriscos, ni caracteres especiales.
|
| 305 |
+
2. NO repitas preguntas ni frases del contexto.
|
| 306 |
+
3. Lee y considera TODO el contexto antes de responder.
|
| 307 |
+
4. Si el contexto tiene información, síntela en 2-3 oraciones claras.
|
| 308 |
+
5. Si NO hay información relacionada en el contexto, DI: "No encontré información específica sobre eso en los materiales disponibles. ¿Podrías reformular tu pregunta?"
|
| 309 |
+
6. NO inventes respuestas. Solo usa información del contexto.
|
| 310 |
+
7. NO comiences con palabras truncadas o cortadas.
|
| 311 |
+
8. NO menciones "contexto", "documento", o "fuente" en tu respuesta.
|
| 312 |
+
9. Responde en español claro y directo, como un asesor escolar.
|
| 313 |
+
|
| 314 |
+
Ejemplo de formato de respuesta:
|
| 315 |
+
---
|
| 316 |
+
Pregunta: [pregunta del estudiante]
|
| 317 |
+
Respuesta: [respuesta clara y síntesis de la información relevante]
|
| 318 |
+
---"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
|
| 320 |
user_message = f"""{system_prompt}
|
| 321 |
|
| 322 |
+
CONTENDO OFICIAL (lee completo):
|
| 323 |
{context}
|
| 324 |
|
| 325 |
+
Responde a esta pregunta:
|
| 326 |
{question}
|
| 327 |
|
| 328 |
+
---"""
|
| 329 |
|
| 330 |
prompt = f"""<start_of_turn>user
|
| 331 |
{user_message}<end_of_turn>
|
| 332 |
<start_of_turn>model
|
| 333 |
+
Respuesta: """
|
| 334 |
|
| 335 |
return prompt
|
| 336 |
|
| 337 |
+
def _clean_response(self, response: str) -> str:
|
| 338 |
+
"""Clean and post-process generated response.
|
| 339 |
+
|
| 340 |
+
Args:
|
| 341 |
+
response: Raw response from the model.
|
| 342 |
+
|
| 343 |
+
Returns:
|
| 344 |
+
Cleaned response.
|
| 345 |
+
"""
|
| 346 |
+
import re
|
| 347 |
+
|
| 348 |
+
lines = response.strip().split('\n')
|
| 349 |
+
clean_lines = []
|
| 350 |
+
|
| 351 |
+
for line in lines:
|
| 352 |
+
line = line.strip()
|
| 353 |
+
if not line:
|
| 354 |
+
continue
|
| 355 |
+
if line.startswith('#'):
|
| 356 |
+
continue
|
| 357 |
+
if re.match(r'^---+$', line):
|
| 358 |
+
continue
|
| 359 |
+
clean_lines.append(line)
|
| 360 |
+
|
| 361 |
+
response = ' '.join(clean_lines)
|
| 362 |
+
|
| 363 |
+
response = re.sub(r'#\w+', '', response)
|
| 364 |
+
|
| 365 |
+
response = re.sub(r'\*+', '', response)
|
| 366 |
+
|
| 367 |
+
response = re.sub(r'[{}\[\]()]', '', response)
|
| 368 |
+
|
| 369 |
+
response = re.sub(r'\s+', ' ', response).strip()
|
| 370 |
+
|
| 371 |
+
if response.startswith('Pre ') or response.startswith('El '):
|
| 372 |
+
pass
|
| 373 |
+
elif response.startswith('Res ') or response.startswith('Te '):
|
| 374 |
+
pass
|
| 375 |
+
elif len(response) > 0 and not response[0].isalpha():
|
| 376 |
+
words = response.split()
|
| 377 |
+
if words:
|
| 378 |
+
response = ' '.join(words)
|
| 379 |
+
|
| 380 |
+
return response
|
| 381 |
+
|
| 382 |
def _clear_cache(self) -> None:
|
| 383 |
"""Clear Python and PyTorch garbage and cache."""
|
| 384 |
gc.collect()
|