CodeSoft commited on
Commit
1c81644
·
verified ·
1 Parent(s): f9e82ab

Automatic prompt moderation

Browse files
Files changed (1) hide show
  1. app.py +92 -7
app.py CHANGED
@@ -56,6 +56,29 @@ BASE_MODEL_DISPLAY: Dict[str, str] = {
56
 
57
  FALLBACK_IDS: Dict[str, str] = {}
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  INIT_RATING = 1000
60
  K_FACTOR = 32
61
  SCALE = 400
@@ -723,7 +746,6 @@ def build_inputs(tokenizer, model_id: str, prompt: str):
723
  def is_diffusion_model(model_id: str) -> bool:
724
  return "metadiffusion" in model_id.lower()
725
 
726
- @spaces.GPU(duration=120)
727
  def generate_for_model(model_id: str, prompt: str) -> str:
728
  ensure_models_loaded()
729
  if model_id not in models or model_id not in tokenizers:
@@ -934,6 +956,58 @@ def create_demo() -> gr.Blocks:
934
  # -------------------------------------------------------------------
935
  # Event handlers
936
  # -------------------------------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
937
  def on_submit(spec: ArenaSpec, user_prompt: str, last_pair_val):
938
  user_prompt = (user_prompt or "").strip()
939
  if not user_prompt:
@@ -951,12 +1025,23 @@ def create_demo() -> gr.Blocks:
951
  "", "", False, user_prompt, last_pair_val,
952
  leaderboard_dataframe(load_elo(spec), spec)
953
  )
954
- a, b = pick_random_pair(spec, exclude_pair=last_pair_val)
955
- if random.random() < 0.5:
956
- a, b = b, a
957
- ensure_models_loaded()
958
- resp_a = generate_for_model(a, user_prompt)
959
- resp_b = generate_for_model(b, user_prompt)
 
 
 
 
 
 
 
 
 
 
 
960
  if not resp_a.strip():
961
  resp_a = "[No output... model returned empty]"
962
  if not resp_b.strip():
 
56
 
57
  FALLBACK_IDS: Dict[str, str] = {}
58
 
59
+ MODERATION_MODEL_ID = "ifmain/ModerationBERT-En-02"
60
+ MODERATION_CATEGORIES = [
61
+ "harassment",
62
+ "harassment_threatening",
63
+ "hate",
64
+ "hate_threatening",
65
+ "self_harm",
66
+ "self_harm_instructions",
67
+ "self_harm_intent",
68
+ "sexual",
69
+ "sexual_minors",
70
+ "violence",
71
+ "violence_graphic",
72
+ "self-harm",
73
+ "sexual/minors",
74
+ "hate/threatening",
75
+ "violence/graphic",
76
+ "self-harm/intent",
77
+ "self-harm/instructions",
78
+ "harassment/threatening",
79
+ ]
80
+ MODERATION_THRESHOLD = 0.35
81
+
82
  INIT_RATING = 1000
83
  K_FACTOR = 32
84
  SCALE = 400
 
746
  def is_diffusion_model(model_id: str) -> bool:
747
  return "metadiffusion" in model_id.lower()
748
 
 
749
  def generate_for_model(model_id: str, prompt: str) -> str:
750
  ensure_models_loaded()
751
  if model_id not in models or model_id not in tokenizers:
 
956
  # -------------------------------------------------------------------
957
  # Event handlers
958
  # -------------------------------------------------------------------
959
+ moderation_model = None
960
+ moderation_tokenizer = None
961
+
962
+ def load_moderation():
963
+ nonlocal moderation_model, moderation_tokenizer
964
+ if moderation_model is not None:
965
+ return
966
+ from transformers import BertTokenizer, BertForSequenceClassification
967
+ moderation_tokenizer = BertTokenizer.from_pretrained(MODERATION_MODEL_ID)
968
+ moderation_model = BertForSequenceClassification.from_pretrained(MODERATION_MODEL_ID, num_labels=18)
969
+ moderation_model.to(DEVICE)
970
+ moderation_model.eval()
971
+
972
+ def moderate_prompt_impl(prompt: str):
973
+ try:
974
+ load_moderation()
975
+ encoding = moderation_tokenizer(
976
+ prompt,
977
+ add_special_tokens=True,
978
+ max_length=128,
979
+ padding="max_length",
980
+ truncation=True,
981
+ return_attention_mask=True,
982
+ return_tensors="pt",
983
+ )
984
+ with torch.no_grad():
985
+ outputs = moderation_model(
986
+ encoding["input_ids"].to(moderation_model.device),
987
+ attention_mask=encoding["attention_mask"].to(moderation_model.device),
988
+ )
989
+ scores = torch.sigmoid(outputs.logits)[0]
990
+ flagged = [MODERATION_CATEGORIES[i] for i in range(len(MODERATION_CATEGORIES)) if scores[i].item() >= MODERATION_THRESHOLD]
991
+ if not flagged:
992
+ return None
993
+ return ", ".join(flagged)
994
+ except Exception as e:
995
+ logger.error(f"Moderation check failed, allowing prompt: {e}\n{traceback.format_exc()}")
996
+ return None
997
+
998
+ @spaces.GPU(duration=120)
999
+ def battle_gpu(spec: ArenaSpec, user_prompt: str, last_pair_val):
1000
+ reason = moderate_prompt_impl(user_prompt)
1001
+ if reason is not None:
1002
+ return reason, None, None, None, None
1003
+ a, b = pick_random_pair(spec, exclude_pair=last_pair_val)
1004
+ if random.random() < 0.5:
1005
+ a, b = b, a
1006
+ ensure_models_loaded()
1007
+ resp_a = generate_for_model(a, user_prompt)
1008
+ resp_b = generate_for_model(b, user_prompt)
1009
+ return None, resp_a, resp_b, a, b
1010
+
1011
  def on_submit(spec: ArenaSpec, user_prompt: str, last_pair_val):
1012
  user_prompt = (user_prompt or "").strip()
1013
  if not user_prompt:
 
1025
  "", "", False, user_prompt, last_pair_val,
1026
  leaderboard_dataframe(load_elo(spec), spec)
1027
  )
1028
+ reason, resp_a, resp_b, a, b = battle_gpu(spec, user_prompt, last_pair_val)
1029
+ if reason is not None:
1030
+ flag_text = f"This prompt was flagged for: {reason}"
1031
+ return (
1032
+ gr.update(value=flag_text),
1033
+ gr.update(value=flag_text),
1034
+ gr.update(visible=False),
1035
+ gr.update(visible=False),
1036
+ gr.update(visible=False, value=""),
1037
+ gr.update(interactive=False),
1038
+ gr.update(interactive=False),
1039
+ gr.update(interactive=False),
1040
+ gr.update(interactive=False),
1041
+ gr.update(visible=False),
1042
+ "", "", False, user_prompt, last_pair_val,
1043
+ leaderboard_dataframe(load_elo(spec), spec)
1044
+ )
1045
  if not resp_a.strip():
1046
  resp_a = "[No output... model returned empty]"
1047
  if not resp_b.strip():