Spaces:
Sleeping
Sleeping
| import re | |
| import sys | |
| from pathlib import Path | |
| try: | |
| from utils.reproducibility import set_seed | |
| except ModuleNotFoundError: | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1])) | |
| from utils.reproducibility import set_seed | |
| # Establecer una semilla para reproducibilidad (descomenta para activar) | |
| # set_seed(72) | |
| class PromptGenerator: | |
| def __init__(self, config, model_manager): | |
| self.config = config | |
| self.model_manager = model_manager | |
| # Función para aplanar un JSON (convierte estructuras anidadas en un solo nivel de claves) | |
| def flatten_json(self, y, prefix=''): | |
| out = {} | |
| for key, value in y.items(): | |
| new_key = f"{prefix}{key}" if prefix == '' else f"{prefix}_{key}" | |
| out[new_key] = value | |
| return out | |
| # Función para reemplazar las llaves {clave} en el texto por su valor correspondiente | |
| def sustituir_claves(self, texto, datos): | |
| def reemplazo(match): | |
| clave = match.group(1) | |
| return str(datos.get(clave, f'{{{clave}}}')) | |
| return re.sub(r'{([^{}]+)}', reemplazo, texto) | |
| def save_prompt(self, texto_final, ruta_salida_metaprompt): | |
| with open(ruta_salida_metaprompt, 'w', encoding='utf-8') as f_out: | |
| f_out.write(texto_final) | |
| # Función para limpiar la respuesta del modelo que genera los prompts | |
| def limpiar_respuesta_generada(self, respuesta, numero_prompts, esquema_salida, marcador, tipo_evaluacion, comunidades_sensibles): | |
| lineas_limpias = [] | |
| contador_correctas = 0 | |
| contador_modificadas = 0 | |
| contador_agregadas = 0 | |
| contador_eliminadas = 0 | |
| separadores_esperados = len(esquema_salida.keys()) - 1 | |
| cabecera = '|'.join(esquema_salida.keys()) | |
| respuesta = re.sub(r'.*?\[/INST\] ', '', respuesta, flags=re.DOTALL).strip() # Eliminar el prompt de entrada que se muestra junto al prompt de salida | |
| lineas_originales = respuesta.splitlines() | |
| for linea in lineas_originales: | |
| linea_original = linea | |
| # Eliminar los espacios que se ponen al lado del separador y carácteres extraños | |
| linea = linea.replace('"', '') | |
| linea = re.sub(r'\s*\|\s*', '|', linea) | |
| if re.fullmatch(r'\s*\|?(\s*-+\s*\|)+\s*-*\s*\|?\s*', linea): | |
| contador_eliminadas += 1 | |
| continue # Eliminar línea si solo contiene: |, -, y espacios | |
| linea = linea.strip('|') # Quita '|' del inicio y del final, si existen | |
| if linea.count('|') != separadores_esperados: | |
| contador_eliminadas += 1 | |
| continue # Eliminar línea si no contiene el número correcto de separadores | |
| if not re.search(marcador, linea) and linea.strip() != cabecera.lower() and tipo_evaluacion != 'preguntas_respuestas_multiples': | |
| contador_eliminadas += 1 | |
| continue # Eliminar línea si no contiene el número correcto de separadores | |
| if linea.strip() != cabecera.lower() and tipo_evaluacion == 'preguntas_respuestas_multiples': | |
| comunidad_encontrada = False | |
| for comunidad in comunidades_sensibles: | |
| if comunidad in linea: | |
| comunidad_encontrada = True | |
| if not comunidad_encontrada: | |
| contador_eliminadas += 1 | |
| continue # Eliminar línea si no contiene el número correcto de separadores | |
| if linea != linea_original: | |
| lineas_limpias.append(linea) | |
| contador_modificadas += 1 | |
| else: | |
| lineas_limpias.append(linea) | |
| contador_correctas += 1 | |
| if not lineas_limpias or lineas_limpias[0].strip().lower() != cabecera.lower(): | |
| lineas_limpias.insert(0, cabecera) | |
| contador_agregadas += 1 | |
| indices_modificadas = {i for i, linea in enumerate(lineas_limpias) if linea not in lineas_originales} | |
| num_lineas_antes = len(lineas_limpias) | |
| lineas_limpias = lineas_limpias[:1 + numero_prompts] | |
| num_lineas_despues = len(lineas_limpias) | |
| eliminadas_finales = num_lineas_antes - num_lineas_despues | |
| modificadas_eliminadas = len([i for i in range(num_lineas_antes) if i >= num_lineas_despues and i in indices_modificadas]) | |
| contador_modificadas -= modificadas_eliminadas | |
| contador_eliminadas += eliminadas_finales | |
| respuesta_final = "\n".join(lineas_limpias) | |
| total = contador_correctas + contador_modificadas + contador_agregadas + contador_eliminadas | |
| porcentaje = lambda x: (x / total * 100) if total > 0 else 0 | |
| print("----------------------") | |
| print(f"Resumen:") | |
| print(f"✔️ Líneas correctas: {contador_correctas} ({porcentaje(contador_correctas):.1f}%)") | |
| print(f"🛠️ Líneas modificadas: {contador_modificadas} ({porcentaje(contador_modificadas):.1f}%)") | |
| print(f"➕ Líneas añadidas: {contador_agregadas} ({porcentaje(contador_agregadas):.1f}%)") | |
| print(f"➖ Líneas eliminadas: {contador_eliminadas} ({porcentaje(contador_eliminadas):.1f}%)") | |
| return respuesta_final | |
| # Función para limpiar la respuesta del modelo a evaluar | |
| def limpiar_respuesta_generada_evaluacion(self, tipo_evaluacion, respuesta): | |
| respuesta_generada_limpia = re.sub(r'.*?\[/INST\] ', '', respuesta, flags=re.DOTALL).strip() | |
| respuesta_generada_limpia = re.split(r'</think>', respuesta_generada_limpia)[-1].strip().replace('\n', ' ').strip() | |
| respuesta_generada_limpia = re.split(r'<|User|>', respuesta_generada_limpia)[-1].strip() | |
| respuesta_generada_limpia = re.sub(r'\*\*?', '', respuesta_generada_limpia) | |
| respuesta_generada_limpia = re.sub(r'[_\\]', '', respuesta_generada_limpia) | |
| if len(respuesta_generada_limpia) > 0: | |
| print(f"Respuesta generada: '{respuesta_generada_limpia[:max(10, len(respuesta_generada_limpia))]}' (se muestran max 10 caracteres).") | |
| if tipo_evaluacion == "preguntas_agente": | |
| respuesta_generada_limpia = respuesta_generada_limpia.strip('.').strip(',')[0].upper() | |
| elif tipo_evaluacion == "preguntas_cerradas_esperadas": | |
| respuesta_generada_limpia = respuesta_generada_limpia.strip('.').strip(',')[:2].upper() | |
| elif tipo_evaluacion == "preguntas_cerradas_probabilidad": | |
| respuesta_generada_limpia = respuesta_generada_limpia[respuesta_generada_limpia.rfind(' ') + 1:].replace('%', '').strip('.') | |
| elif tipo_evaluacion == "preguntas_respuestas_multiples": | |
| respuesta_generada_limpia = respuesta_generada_limpia.strip('.').strip(',')[0].upper() | |
| elif tipo_evaluacion == "preguntas_prompt_injection": | |
| respuesta_generada_limpia = respuesta_generada_limpia.strip('.').strip(',')[:2].upper() | |
| return respuesta_generada_limpia |