nmarafo commited on
Commit
ad68c51
1 Parent(s): 7e684d9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -84
app.py CHANGED
@@ -1,8 +1,7 @@
1
  import gradio as gr
2
-
3
  import os
4
  import spaces
5
- from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer, BitsAndBytesConfig
6
  import torch
7
 
8
  # Cargar el token de Hugging Face desde los secretos
@@ -15,7 +14,7 @@ bnb_config = BitsAndBytesConfig(
15
  load_in_4bit=True, bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16
16
  )
17
 
18
- tokenizer = AutoTokenizer.from_pretrained(model_id,token=token)
19
  model = AutoModelForCausalLM.from_pretrained(
20
  model_id,
21
  torch_dtype=torch.bfloat16,
@@ -24,43 +23,15 @@ model = AutoModelForCausalLM.from_pretrained(
24
  token=token
25
  )
26
 
27
- # Función para generar el prompt dependiendo del idioma seleccionado
28
- def generar_prompt(message, tipo_clasificacion, idioma):
29
- if idioma == "Español":
30
- politicas = {
31
- "Contenido Peligroso": """
32
- * "No al contenido peligroso": El mensaje no debe contener ni buscar la generación de contenido que cause daño a uno mismo o a otros (por ejemplo, acceder o fabricar armas de fuego o explosivos, promoción del terrorismo, instrucciones para el suicidio).
33
- """,
34
- "Acoso": """
35
- * "No al acoso": El mensaje no debe contener ni buscar la generación de contenido que sea malicioso, intimidante, que fomente el bullying o abusivo dirigido a otra persona (por ejemplo, amenazas físicas, negación de eventos trágicos, menosprecio a víctimas de violencia).
36
- """,
37
- "Discurso de Odio": """
38
- * "No al discurso de odio": El mensaje no debe contener ni buscar la generación de contenido que ataque la identidad o atributos protegidos (por ejemplo, insultos raciales, promoción de la discriminación, llamados a la violencia contra grupos protegidos) o que deshumanice, menosprecie o vilipendie por motivos de raza, etnia, religión, discapacidad, edad, nacionalidad, estatus de veterano, orientación sexual, género, identidad de género, casta, u otro estatus protegido.
39
- """,
40
- "Contenido Sexual": """
41
- * "No al contenido sexual explícito": El mensaje no debe contener ni buscar la generación de contenido que haga referencia a actos sexuales u otro contenido lascivo (por ejemplo, descripciones gráficas sexuales, contenido destinado a causar excitación). Los términos médicos o científicos relacionados con la anatomía humana o la educación sexual están permitidos.
42
- """
43
- }
44
- else: # English
45
- politicas = {
46
- "Dangerous Content": """
47
- * "No Dangerous Content": The prompt shall not contain or seek generation of content that harms oneself and/or others (e.g., accessing or building firearms and explosive devices, promotion of terrorism, instructions for suicide).
48
- """,
49
- "Harassment": """
50
- * "No Harassment": The prompt shall not contain or seek generation of content that is malicious, intimidating, bullying, or abusive content targeting another individual (e.g., physical threats, denial of tragic events, disparaging victims of violence).
51
- """,
52
- "Hate Speech": """
53
- * "No Hate Speech": The prompt shall not contain or seek generation of content that targets identity and/or protected attributes (e.g., racial slurs, promotion of discrimination, calls to violence against protected groups) or dehumanizing/belittling/vilifying based on race, ethnicity, religion, disability, age, nationality, veteran status, sexual orientation, gender, gender identity, caste, or any other protected status.
54
- """,
55
- "Sexually Explicit Information": """
56
- * "No Sexually Explicit Information": The prompt shall not contain or seek generation of content that contains references to sexual acts or other lewd content (e.g., sexually graphic descriptions, content aimed at causing arousal). Medical or scientific terms related to human anatomy or sex education are permitted.
57
- """
58
- }
59
-
60
- # Formatear el prompt según el tipo de clasificación seleccionado
61
- politica_seguridad = politicas.get(tipo_clasificacion, "")
62
-
63
  if idioma == "Español":
 
 
 
 
 
 
64
  prompt = f"""Eres un experto en políticas tratando de determinar si un mensaje del usuario
65
  viola las políticas de seguridad definidas.
66
  <inicio_turno>
@@ -68,65 +39,103 @@ def generar_prompt(message, tipo_clasificacion, idioma):
68
  <fin_turno>
69
  Nuestro principio de seguridad se define a continuación:
70
  {politica_seguridad.strip()}
71
- ¿La pregunta del usuario viola el principio anterior? Tu respuesta debe comenzar con
72
  'Sí' o 'No'. Luego, explica paso a paso para asegurarte de que respondemos correctamente.
73
  """
74
- else: # Default to English
 
 
 
 
 
 
75
  prompt = f"""You are a policy expert trying to help determine whether a user prompt is in
76
  violation of the defined safety policies.
77
  <start_of_turn>
78
  Human Question: {message.strip()}
79
  <end_of_turn>
80
- Our safety principle is defined below:
81
  {politica_seguridad.strip()}
82
- Does the human question violate the above principle? Your answer must start with
83
  'Yes' or 'No'. Then walk through step by step to be sure we answer correctly.
84
  """
85
-
86
  return prompt
87
 
88
- @spaces.GPU(duration=150)
89
- # Función para procesar la respuesta y clasificar según las políticas de seguridad
90
- def respond(message, history: list[tuple[str, str]], system_message, max_tokens, temperature, top_p, language, harm_type):
91
- prompt = generar_prompt(message, harm_type, language)
92
-
93
- inputs = tokenizer(prompt, return_tensors="pt").to("cpu") # Forzar a CPU
94
-
95
- with torch.no_grad():
96
- logits = model(**inputs).logits
97
-
98
- # Extraer los logits para los tokens 'Yes'/'No' en inglés o 'Sí'/'No' en español
99
- vocab = tokenizer.get_vocab()
 
 
100
  if language == "Español":
101
- selected_logits = logits[0, -1, [vocab['Sí'], vocab['No']]]
102
  else:
103
- selected_logits = logits[0, -1, [vocab['Yes'], vocab['No']]]
104
-
105
- # Convertir los logits en una probabilidad con softmax
106
- probabilities = torch.softmax(selected_logits, dim=0)
107
-
108
- # Devolver la probabilidad de 'Sí'/'Yes' y la respuesta generada
109
- score_yes = probabilities[0].item()
110
-
111
- if language == "Español":
112
- response = f"Puntuación para 'Sí' (violación): {score_yes:.4f}"
113
  else:
114
- response = f"Score for 'Yes' (violation): {score_yes:.4f}"
115
-
116
- return response
117
-
118
- # Crear la interfaz de Gradio con selección de idioma y tipo de contenido
119
- demo = gr.ChatInterface(
120
- respond,
121
- additional_inputs=[
122
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
123
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
124
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
125
- gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)"),
126
- gr.Dropdown(choices=["English", "Español"], value="English", label="Idioma/Language"),
127
- gr.Dropdown(choices=["Dangerous Content", "Harassment", "Hate Speech", "Sexually Explicit Information"], value="Harassment", label="Harm Type")
128
- ],
129
- )
130
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  demo.launch(debug=True)
 
1
  import gradio as gr
 
2
  import os
3
  import spaces
4
+ from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
5
  import torch
6
 
7
  # Cargar el token de Hugging Face desde los secretos
 
14
  load_in_4bit=True, bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16
15
  )
16
 
17
+ tokenizer = AutoTokenizer.from_pretrained(model_id, token=token)
18
  model = AutoModelForCausalLM.from_pretrained(
19
  model_id,
20
  torch_dtype=torch.bfloat16,
 
23
  token=token
24
  )
25
 
26
+ # Función para generar el prompt incluyendo todas las políticas
27
+ def generar_prompt(message, idioma):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  if idioma == "Español":
29
+ politica_seguridad = """
30
+ * "No al contenido peligroso": El mensaje no debe contener ni buscar la generación de contenido que cause daño a uno mismo o a otros (por ejemplo, acceder o fabricar armas de fuego o explosivos, promoción del terrorismo, instrucciones para el suicidio).
31
+ * "No al acoso": El mensaje no debe contener ni buscar la generación de contenido que sea malicioso, intimidante, que fomente el bullying o abusivo dirigido a otra persona (por ejemplo, amenazas físicas, negación de eventos trágicos, menosprecio a víctimas de violencia).
32
+ * "No al discurso de odio": El mensaje no debe contener ni buscar la generación de contenido que ataque la identidad o atributos protegidos (por ejemplo, insultos raciales, promoción de la discriminación, llamados a la violencia contra grupos protegidos) o que deshumanice, menosprecie o vilipendie por motivos de raza, etnia, religión, discapacidad, edad, nacionalidad, estatus de veterano, orientación sexual, género, identidad de género, casta, u otro estatus protegido.
33
+ * "No al contenido sexual explícito": El mensaje no debe contener ni buscar la generación de contenido que haga referencia a actos sexuales u otro contenido lascivo (por ejemplo, descripciones gráficas sexuales, contenido destinado a causar excitación). Los términos médicos o científicos relacionados con la anatomía humana o la educación sexual están permitidos.
34
+ """
35
  prompt = f"""Eres un experto en políticas tratando de determinar si un mensaje del usuario
36
  viola las políticas de seguridad definidas.
37
  <inicio_turno>
 
39
  <fin_turno>
40
  Nuestro principio de seguridad se define a continuación:
41
  {politica_seguridad.strip()}
42
+ ¿La pregunta del usuario viola alguno de los principios anteriores? Tu respuesta debe comenzar con
43
  'Sí' o 'No'. Luego, explica paso a paso para asegurarte de que respondemos correctamente.
44
  """
45
+ else:
46
+ politica_seguridad = """
47
+ * "No Dangerous Content": The prompt shall not contain or seek generation of content that harms oneself and/or others (e.g., accessing or building firearms and explosive devices, promotion of terrorism, instructions for suicide).
48
+ * "No Harassment": The prompt shall not contain or seek generation of content that is malicious, intimidating, bullying, or abusive content targeting another individual (e.g., physical threats, denial of tragic events, disparaging victims of violence).
49
+ * "No Hate Speech": The prompt shall not contain or seek generation of content that targets identity and/or protected attributes (e.g., racial slurs, promotion of discrimination, calls to violence against protected groups) or dehumanizing/belittling/vilifying based on race, ethnicity, religion, disability, age, nationality, veteran status, sexual orientation, gender, gender identity, caste, or any other protected status.
50
+ * "No Sexually Explicit Information": The prompt shall not contain or seek generation of content that contains references to sexual acts or other lewd content (e.g., sexually graphic descriptions, content aimed at causing arousal). Medical or scientific terms related to human anatomy or sex education are permitted.
51
+ """
52
  prompt = f"""You are a policy expert trying to help determine whether a user prompt is in
53
  violation of the defined safety policies.
54
  <start_of_turn>
55
  Human Question: {message.strip()}
56
  <end_of_turn>
57
+ Our safety principles are defined below:
58
  {politica_seguridad.strip()}
59
+ Does the human question violate any of the above principles? Your answer must start with
60
  'Yes' or 'No'. Then walk through step by step to be sure we answer correctly.
61
  """
 
62
  return prompt
63
 
64
+ # Función para procesar la respuesta y verificar políticas
65
+ def respond(message, history, system_message, max_tokens, temperature, top_p, language):
66
+ # Verificar políticas
67
+ prompt = generar_prompt(message, language)
68
+ inputs = tokenizer(prompt, return_tensors="pt").to("cpu")
69
+ outputs = model.generate(
70
+ **inputs,
71
+ max_new_tokens=50,
72
+ temperature=temperature,
73
+ top_p=top_p,
74
+ do_sample=True,
75
+ )
76
+ response_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
77
+ first_word = response_text.strip().split()[0]
78
  if language == "Español":
79
+ violation_keywords = ['Sí', 'No']
80
  else:
81
+ violation_keywords = ['Yes', 'No']
82
+ if first_word in violation_keywords:
83
+ violation = first_word
 
 
 
 
 
 
 
84
  else:
85
+ violation = violation_keywords[1] # Asumir 'No' si no se puede determinar
86
+ if violation == violation_keywords[0]: # 'Sí' o 'Yes'
87
+ if language == "Español":
88
+ return "Lo siento, pero no puedo ayudar con esa solicitud."
89
+ else:
90
+ return "I'm sorry, but I cannot assist with that request."
91
+ else:
92
+ # Generar respuesta al usuario
93
+ if language == "Español":
94
+ assistant_prompt = f"{system_message}\nUsuario: {message}\nAsistente:"
95
+ else:
96
+ assistant_prompt = f"{system_message}\nUser: {message}\nAssistant:"
97
+ inputs = tokenizer(assistant_prompt, return_tensors="pt").to("cpu")
98
+ outputs = model.generate(
99
+ **inputs,
100
+ max_new_tokens=max_tokens,
101
+ temperature=temperature,
102
+ top_p=top_p,
103
+ do_sample=True,
104
+ )
105
+ assistant_response = tokenizer.decode(outputs[0], skip_special_tokens=True)
106
+ if language == "Español":
107
+ assistant_reply = assistant_response.split("Asistente:")[-1].strip()
108
+ else:
109
+ assistant_reply = assistant_response.split("Assistant:")[-1].strip()
110
+ return assistant_reply
111
+
112
+ # Crear la interfaz de Gradio usando Blocks
113
+ with gr.Blocks() as demo:
114
+ gr.Markdown("# Chatbot con Verificación de Políticas")
115
+ language = gr.Dropdown(choices=["English", "Español"], value="English", label="Idioma/Language")
116
+ system_message = gr.Textbox(value="You are a friendly Chatbot.", label="System message")
117
+ max_tokens = gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens")
118
+ temperature = gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature")
119
+ top_p = gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)")
120
+ chatbot = gr.Chatbot()
121
+ message = gr.Textbox(label="Your message")
122
+ submit_button = gr.Button("Send")
123
+
124
+ def submit_message(user_message, chat_history, system_message, max_tokens, temperature, top_p, language):
125
+ chat_history = chat_history + [[user_message, None]]
126
+ assistant_reply = respond(user_message, chat_history, system_message, max_tokens, temperature, top_p, language)
127
+ chat_history[-1][1] = assistant_reply
128
+ return "", chat_history
129
+
130
+ submit_button.click(
131
+ submit_message,
132
+ inputs=[message, chatbot, system_message, max_tokens, temperature, top_p, language],
133
+ outputs=[message, chatbot],
134
+ )
135
+ message.submit(
136
+ submit_message,
137
+ inputs=[message, chatbot, system_message, max_tokens, temperature, top_p, language],
138
+ outputs=[message, chatbot],
139
+ )
140
 
141
  demo.launch(debug=True)