Spaces:
Running on Zero
Running on Zero
Automatic prompt moderation
Browse files
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 =
|
| 955 |
-
if
|
| 956 |
-
|
| 957 |
-
|
| 958 |
-
|
| 959 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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():
|