File size: 17,011 Bytes
d59eb2d e23e46b d59eb2d e23e46b d59eb2d e23e46b d59eb2d e23e46b d59eb2d e23e46b d59eb2d e23e46b d59eb2d e23e46b d59eb2d e23e46b 70a8440 e23e46b a68c636 e23e46b a68c636 e23e46b a68c636 e23e46b a68c636 e23e46b a68c636 e23e46b a68c636 e23e46b a68c636 e23e46b a68c636 e23e46b d59eb2d e23e46b d59eb2d e23e46b a68c636 d59eb2d e23e46b d59eb2d e23e46b a68c636 e23e46b d59eb2d 70a8440 a68c636 70a8440 d59eb2d a68c636 d59eb2d e23e46b d59eb2d e23e46b d59eb2d a68c636 d59eb2d e23e46b d59eb2d 70a8440 e23e46b d59eb2d a68c636 d59eb2d e23e46b a68c636 d59eb2d 70a8440 e23e46b a68c636 e23e46b d59eb2d e23e46b d59eb2d e23e46b 70a8440 a68c636 d59eb2d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 |
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"name": "moderat-speed-test.ipynb"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# π‘οΈ moderat - Speed Test & Benchmark\n",
"\n",
"Test inference speeds for the dual-mode content moderation model with PII detection.\n",
"\n",
"**Model:** [darwinkernelpanic/moderat](https://huggingface.co/darwinkernelpanic/moderat)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 1. Install dependencies\n",
"!pip install -q scikit-learn huggingface-hub"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 2. Download model and files from Hugging Face\n",
"from huggingface_hub import hf_hub_download\n",
"import pickle\n",
"\n",
"MODEL_REPO = \"darwinkernelpanic/moderat\"\n",
"\n",
"# Download model\n",
"model_path = hf_hub_download(\n",
" repo_id=MODEL_REPO,\n",
" filename=\"moderation_model.pkl\"\n",
")\n",
"\n",
"# Download PII extension\n",
"pii_path = hf_hub_download(\n",
" repo_id=MODEL_REPO,\n",
" filename=\"pii_extension.py\"\n",
")\n",
"\n",
"print(f\"β
Model and PII extension downloaded from {MODEL_REPO}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 3. Import and setup\n",
"import sys\n",
"sys.path.insert(0, pii_path.replace('/pii_extension.py', ''))\n",
"\n",
"from enum import Enum\n",
"import time\n",
"import re\n",
"\n",
"# Load model\n",
"with open(model_path, 'rb') as f:\n",
" pipeline = pickle.load(f)\n",
"\n",
"# Define enums\n",
"class ContentLabel(Enum):\n",
" SAFE = 0\n",
" HARASSMENT = 1\n",
" SWEARING_REACTION = 2\n",
" SWEARING_AGGRESSIVE = 3\n",
" HATE_SPEECH = 4\n",
" SPAM = 5\n",
"\n",
"print(\"β
Setup complete\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 4. Unicode Deobfuscator\n", "class UnicodeDeobfuscator:\n", " CIRCLED_MAP = {\n", " 'β': 'a', 'β': 'b', 'β': 'c', 'β': 'd', 'β': 'e',\n", " 'β': 'f', 'β': 'g', 'β': 'h', 'β': 'i', 'β': 'j',\n", " 'β': 'k', 'β': 'l', 'β': 'm', 'β': 'n', 'β': 'o',\n", " 'β': 'p', 'β ': 'q', 'β‘': 'r', 'β’': 's', 'β£': 't',\n", " 'β€': 'u', 'β₯': 'v', 'β¦': 'w', 'β§': 'x', 'β¨': 'y', 'β©': 'z',\n", " 'βΆ': 'A', 'β·': 'B', 'βΈ': 'C', 'βΉ': 'D', 'βΊ': 'E',\n", " 'β»': 'F', 'βΌ': 'G', 'β½': 'H', 'βΎ': 'I', 'βΏ': 'J',\n", " 'β': 'K', 'β': 'L', 'β': 'M', 'β': 'N', 'β': 'O',\n", " 'β
': 'P', 'β': 'Q', 'β': 'R', 'β': 'S', 'β': 'T',\n", " 'β': 'U', 'β': 'V', 'β': 'W', 'β': 'X', 'β': 'Y', 'β': 'Z',\n", " }\n", " \n", " @classmethod\n", " def detect(cls, text):\n", " suspicious = []\n", " normalized = []\n", " for char in text:\n", " if char in cls.CIRCLED_MAP:\n", " suspicious.append((char, 'circled'))\n", " normalized.append(cls.CIRCLED_MAP[char])\n", " else:\n", " normalized.append(char)\n", " return len(suspicious) > 0, suspicious, ''.join(normalized)\n", "\n", "# @title 5. PII Detector Class (FIXED)\n",
"class PIIDetector:\n",
" \"\"\"Detect PII with proper age-based social media rules\"\"\"\n",
" \n",
" def __init__(self):\n",
" self.email_pattern = re.compile(r'\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b')\n",
" self.phone_patterns = [\n",
" re.compile(r'\\b\\d{3}[-.]?\\d{3}[-.]?\\d{4}\\b'),\n",
" re.compile(r'\\b\\(\\d{3}\\)\\s?\\d{3}[-.]?\\d{4}\\b'),\n",
" re.compile(r'\\b\\d{4}\\s?\\d{3}\\s?\\d{3}\\b'),\n",
" re.compile(r'\\b\\d{3}[-.]?\\d{4}\\b'),\n",
" ]\n",
" self.address_pattern = re.compile(r'\\b\\d+\\s+[A-Za-z]+\\s+(?:Street|St|Avenue|Ave|Road|Rd|Lane|Ln|Drive|Dr)\\b', re.IGNORECASE)\n",
" self.cc_pattern = re.compile(r'\\b(?:\\d{4}[-\\s]?){3}\\d{4}\\b|\\b\\d{16}\\b')\n",
" self.social_media_domains = ['instagram.com', 'instagr.am', 'twitter.com', 'x.com', 'tiktok.com', 'snapchat.com', 'discord.com', 'discord.gg']\n",
" self.grooming_keywords = ['dm me', 'private chat', 'dont tell your parents', 'secret', 'send me pics', 'our little secret', 'meet up']\n",
" \n",
" def scan(self, text, age):\n",
" pii_types = []\n",
" text_lower = text.lower()\n",
" \n",
" # Check email\n",
" if self.email_pattern.search(text):\n",
" pii_types.append('email')\n",
" \n",
" # Check phone\n",
" for pattern in self.phone_patterns:\n",
" if pattern.search(text):\n",
" pii_types.append('phone')\n",
" break\n",
" \n",
" # Check address\n",
" if self.address_pattern.search(text):\n",
" pii_types.append('address')\n",
" \n",
" # Check credit card\n",
" if self.cc_pattern.search(text):\n",
" pii_types.append('credit_card')\n",
" \n",
" # Check grooming\n",
" grooming_risk = sum(1 for kw in self.grooming_keywords if kw in text_lower)\n",
" \n",
" # Priority: Critical PII first (blocked for all ages)\n",
" if any(pii in ['email', 'phone', 'address', 'credit_card'] for pii in pii_types):\n",
" return {'blocked': True, 'reason': f'PII detected: {pii_types}', 'pii': pii_types}\n",
" \n",
" # Social media check\n",
" has_social = any(domain in text_lower for domain in self.social_media_domains)\n",
" has_social = has_social or any(x in text_lower for x in ['instagram', 'snapchat', 'discord', 'tiktok'])\n",
" \n",
" if has_social:\n",
" pii_types.append('social_media')\n",
" if age < 13:\n",
" return {'blocked': True, 'reason': 'Social media not allowed under 13', 'pii': pii_types}\n",
" elif grooming_risk > 0:\n",
" return {'blocked': True, 'reason': f'Potential grooming (risk: {grooming_risk})', 'pii': pii_types}\n",
" else:\n",
" return {'blocked': False, 'reason': 'Social media OK for 13+', 'pii': pii_types}\n",
" \n",
" return {'blocked': False, 'reason': 'No PII', 'pii': []}\n",
"\n",
"pii_detector = PIIDetector()\n",
"print(\"β
PII detector ready (FIXED)\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 5. Combined Filter Function\n",
"def check_content(text, age):\n",
" \"\"\"Combined content moderation + PII check\"\"\"\n",
" \n",
" # Step 1: PII Check\n",
" pii_result = pii_detector.scan(text, age)\n",
" if pii_result['blocked']:\n",
" return {\n",
" 'allowed': False,\n",
" 'reason': pii_result['reason'],\n",
" 'violation': 'PII',\n",
" 'pii': pii_result['pii']\n",
" }\n",
" \n",
" # Step 2: Content Moderation\n",
" prediction = pipeline.predict([text])[0]\n",
" probs = pipeline.predict_proba([text])[0]\n",
" confidence = max(probs)\n",
" label = ContentLabel(prediction)\n",
" \n",
" # Age-based rules\n",
" under_13_blocked = [1, 2, 3, 4, 5] # All except SAFE\n",
" teen_plus_blocked = [1, 3, 4, 5] # Allow SWEARING_REACTION\n",
" \n",
" if age >= 13:\n",
" allowed = label.value not in teen_plus_blocked\n",
" else:\n",
" allowed = label.value not in under_13_blocked\n",
" \n",
" # Allow reaction swearing for 13+\n",
" if not allowed and label == ContentLabel.SWEARING_REACTION and age >= 13:\n",
" allowed = True\n",
" reason = 'Swearing permitted as reaction (13+)'\n",
" elif not allowed:\n",
" reason = f'{label.name} detected'\n",
" else:\n",
" reason = 'Safe'\n",
" \n",
" return {\n",
" 'allowed': allowed,\n",
" 'reason': reason,\n",
" 'violation': 'CONTENT' if not allowed else None,\n",
" 'label': label.name,\n",
" 'confidence': confidence,\n",
" 'pii': pii_result.get('pii', [])\n",
" }\n",
"\n",
"print(\"β
Combined filter ready\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 6. Unicode Deobfuscation Tests\n", "print(\"π€ Unicode Deobfuscation Tests\\n\")\n", "\n", "unicode_tests = [\n", " (\"have you tried like β/ βk\", 15),\n", " (\"you're a βββββ of β’βββ£\", 15),\n", " (\"ββββ yourself\", 15),\n", "]\n", "\n", "for text, age in unicode_tests:\n", " is_obf, chars, norm = UnicodeDeobfuscator.detect(text)\n", " result = check_content(text, age)\n", " status = \"β
\" if result['allowed'] else \"β\"\n", " print(f\"{status} Original: {text}\")\n", " print(f\" Normalized: {norm}\")\n", " print(f\" β {result['reason']}\")\n", " print()\n", "\n", "# @title 7. PII Detection Tests (FIXED)\n",
"print(\"π PII Detection Results (Fixed)\\n\")\n",
"print(\"Expected: Address and Credit Card now detected correctly\")\n",
"print(\"Expected: Social media ALLOWED for 13+ (unless grooming)\\n\")\n",
"print(\"=\"*70)\n",
"\n",
"pii_tests = [\n",
" (\"Contact me at john@example.com\", 15, \"Email - should block\"),\n",
" (\"Call me 555-123-4567\", 16, \"Phone - should block\"),\n",
" (\"I'm at 123 Main Street\", 14, \"Address - should block\"),\n",
" (\"My credit card is 4111-1111-1111-1111\", 15, \"Credit Card - should block\"),\n",
" (\"Follow my instagram @cool\", 10, \"Social <13 - should block\"),\n",
" (\"Follow my instagram @cool\", 15, \"Social 13+ - should ALLOW\"),\n",
" (\"DM me on snapchat, it's secret\", 15, \"Grooming - should block\"),\n",
" (\"Check my tiktok\", 16, \"Social 16+ - should ALLOW\"),\n",
"]\n",
"\n",
"for text, age, note in pii_tests:\n",
" result = check_content(text, age)\n",
" status = \"β
\" if result['allowed'] else \"β\"\n",
" print(f\"{status} Age {age}: {text[:45]}\")\n",
" print(f\" β {result['reason']}\")\n",
" if result.get('pii'):\n",
" print(f\" PII: {result['pii']}\")\n",
" print(f\" Note: {note}\")\n",
" print()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 8. Speed Test - Single Inference\n",
"test_text = \"damn that's crazy\"\n",
"\n",
"# Warm up\n",
"_ = check_content(test_text, 15)\n",
"\n",
"# Time single inference\n",
"times = []\n",
"for _ in range(100):\n",
" start = time.perf_counter()\n",
" result = check_content(test_text, 15)\n",
" end = time.perf_counter()\n",
" times.append((end - start) * 1000)\n",
"\n",
"avg_time = sum(times) / len(times)\n",
"print(f\"π Single Inference Speed (100 runs, with PII check)\")\n",
"print(f\" Average: {avg_time:.3f} ms\")\n",
"print(f\" Min: {min(times):.3f} ms\")\n",
"print(f\" Max: {max(times):.3f} ms\")\n",
"print(f\" Throughput: {1000/avg_time:.1f} inferences/second\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 9. Dual-Mode Content Test\n",
"test_cases = [\n",
" (\"that was a great game\", 10),\n",
" (\"that was a great game\", 15),\n",
" (\"shit that sucks\", 10),\n",
" (\"shit that sucks\", 15),\n",
" (\"you're a piece of shit\", 15),\n",
" (\"kill yourself\", 12),\n",
" (\"damn that's crazy\", 10),\n",
"]\n",
"\n",
"print(\"π Dual-Mode Content Results\\n\")\n",
"print(f\"{'Text':<30} {'Age':<6} {'Status':<10} {'Reason':<30}\")\n",
"print(\"-\" * 80)\n",
"\n",
"for text, age in test_cases:\n",
" result = check_content(text, age)\n",
" status = \"β
ALLOW\" if result['allowed'] else \"β BLOCK\"\n",
" print(f\"{text:<30} {age:<6} {status:<10} {result['reason'][:28]:<30}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 10. Batch Processing Speed Test\n",
"batch_texts = [\n",
" \"that was a great game\",\n",
" \"shit that sucks\",\n",
" \"you're awesome\",\n",
" \"My email is test@test.com\",\n",
" \"Follow me on instagram\",\n",
" \"kill yourself\",\n",
" \"nice work\",\n",
" \"Check my tiktok\",\n",
"] * 50 # 400 texts\n",
"\n",
"ages = [15] * len(batch_texts)\n",
"\n",
"print(f\"Processing batch of {len(batch_texts)} texts...\")\n",
"start = time.perf_counter()\n",
"results = [check_content(t, a) for t, a in zip(batch_texts, ages)]\n",
"end = time.perf_counter()\n",
"\n",
"total_time = (end - start) * 1000\n",
"print(f\"\\nπ Batch Results\")\n",
"print(f\" Total time: {total_time:.1f} ms\")\n",
"print(f\" Average: {total_time/len(batch_texts):.3f} ms/text\")\n",
"print(f\" Throughput: {len(batch_texts)/(total_time/1000):.1f} texts/sec\")\n",
"\n",
"allowed = sum(1 for r in results if r['allowed'])\n",
"blocked = len(results) - allowed\n",
"print(f\"\\n Allowed: {allowed} | Blocked: {blocked}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title 11. Summary\n",
"print(\"π moderat Summary\")\n",
"print(\"=\"*60)\n",
"print(\"\")\n",
"print(\"β
Content Moderation:\")\n",
"print(\" - 6 categories (Safe, Harassment, Swearing, Hate, Spam)\")\n",
"print(\" - Dual-mode: <13 strict, 13+ laxed\")\n",
"print(\"\")\n",
"print(\"β
PII Detection:\")\n",
"print(\" - Email, Phone, Address, Credit Card (all ages blocked)\")\n",
"print(\" - Social Media: <13 blocked, 13+ allowed\")\n",
"print(\" - Grooming detection for 13+\")\n",
"print(\"\")\n",
"print(\"π Speed:\")\n",
"print(\" - ~3-7ms per inference (with PII)\")\n",
"print(\" - ~200-500 texts/sec batch\")\n",
"print(\"\")\n",
"print(\"π https://huggingface.co/darwinkernelpanic/moderat\")"
]
}
]
}
|