Spaces:
Paused
Paused
import gradio as gr | |
import torch | |
from transformers import AutoTokenizer, AutoModelForSequenceClassification | |
import re | |
import os | |
import csv | |
from huggingface_hub import login | |
from unsloth import FastLanguageModel | |
login(os.environ["HF_TOKEN"]) | |
model, tokenizer = FastLanguageModel.from_pretrained( | |
model_name = "atorojaen/DeepSeek-R1-MiSonGyny", # Modelo base | |
max_seq_length = 2048, | |
dtype = torch.float16, | |
load_in_4bit = True, | |
) | |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
model.eval() | |
FLAG_FILE = "flags_data/flags.csv" | |
os.makedirs(os.path.dirname(FLAG_FILE), exist_ok=True) | |
def clean_lyrics(text): | |
# Elimina caracteres no alfabéticos (excepto espacios y letras acentuadas comunes en español) | |
text = re.sub(r"[^a-zA-ZáéíóúñüÁÉÍÓÚÑÜ ]+", " ", text) | |
# Convierte a minúsculas | |
text = text.lower() | |
# Reduce espacios múltiples | |
text = re.sub(r"\s+", " ", text).strip() | |
return text | |
# Función de predicción | |
def detect_misogyny(text): | |
cleaned_text = clean_lyrics(text) | |
# Construir el prompt de entrada | |
prompt = """ | |
### Instruccion | |
Analiza la siguiente letra de canción y determina si contiene contenido misógino. Evalúa si incluye lenguaje, actitudes o mensajes que: | |
- Degraden o deshumanicen a las mujeres. | |
- Menosprecien a las mujeres de manera explícita o implícita. | |
- Refuercen estereotipos negativos o dañinos sobre las mujeres. | |
- Promuevan violencia física, emocional o sexual contra las mujeres. | |
Piensa cuidadosamente tu respuesta y crea paso a paso una chain of thoughts para dar una respuesta logica. | |
Responde únicamente con "1" si la letra es misógina o con "0" si la letra no es misógina. No proporciones ninguna explicación ni texto adicional. | |
### Letra: | |
{lyrics} | |
### Respuesta: | |
<think>""" | |
prompt = prompt.format(lyrics=text) | |
inputs = tokenizer(prompt, return_tensors="pt").to(model.device) | |
with torch.no_grad(): | |
outputs = model.generate( | |
**inputs, | |
max_new_tokens=2048, | |
do_sample=False, | |
temperature=0.6 | |
) | |
response = tokenizer.decode(outputs[0], skip_special_tokens=True) | |
# Extraer explicación entre <think>...</think> | |
explanation_match = re.search(r"<think>(.*?)</think>", response, re.DOTALL) | |
explanation = explanation_match.group(1).strip() if explanation_match else "" | |
# Extraer "1" o "0" después de </think> | |
label_match = re.search(r"</think>\s*(\d)", response) | |
label = label_match.group(1) if label_match else "" | |
# Combinar resultado final | |
return f"{explanation}\n\nRespuesta final: {label}" if explanation and label else response.strip() | |
def save_flag(user_text, response, flag_type): | |
# Guarda la entrada, salida y si fue correcta o incorrecta en CSV | |
with open(FLAG_FILE, mode="a", newline="", encoding="utf-8") as f: | |
writer = csv.writer(f) | |
writer.writerow([user_text, response, flag_type]) | |
return f"Guardado flag: {flag_type}" | |
with gr.Blocks() as demo: | |
gr.Markdown("# Detector de misoginia en letras de canciones") # Título principal | |
gr.Markdown("Este sistema analiza letras de canciones en español y detecta contenido misógino utilizando el modelo DeepSeek R1 entrenado.") | |
user_input = gr.Textbox(label="Letra de canción", lines=10) | |
result = gr.Textbox(label="Respuesta del modelo", lines=10) | |
btn_analizar = gr.Button("Analizar") | |
btn_analizar.click(fn=detect_misogyny, inputs=user_input, outputs=result) | |
demo.launch() |