Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
1 line
162 KiB
JSON
1 line
162 KiB
JSON
{"repo": "berry2012/prompt-based-moderation-with-llm", "files": {"notebooks/Universal_llm_harmfull-detection-v1.ipynb": {"74fd764bb663c5032842e7ebdaad62af9424e30b": {"t": 1786068259.7549412, "n": 160615, "h": "575f6ed756e57b53", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"id\": \"05ab8959-d5f1-4abb-bf99-760c9a2d7fae\",\n \"metadata\": {},\n \"source\": [\n \"# Prompt Based Harmful Message detection using MCP and LLM\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"id\": \"3d306d00-e469-49fc-a076-8973c28c1591\",\n \"metadata\": {},\n \"source\": [\n \"https://docs.gpt4all.io/gpt4all_desktop/models.html#explore-models\\n\",\n \"\\n\",\n \"https://github.com/deepseek-ai/DeepSeek-R1\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"id\": \"c2c4ceaa-2f72-475d-bd97-fed66f86f124\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Requirement already satisfied: datasets in /opt/conda/lib/python3.12/site-packages (4.0.0)\\n\",\n \"Requirement already satisfied: pandas in /opt/conda/lib/python3.12/site-packages (2.2.3)\\n\",\n \"Requirement already satisfied: scikit-learn in /opt/conda/lib/python3.12/site-packages (1.5.2)\\n\",\n \"Requirement already satisfied: matplotlib in /opt/conda/lib/python3.12/site-packages (3.10.3)\\n\",\n \"Requirement already satisfied: seaborn in /opt/conda/lib/python3.12/site-packages (0.13.2)\\n\",\n \"Requirement already satisfied: openai in /opt/conda/lib/python3.12/site-packages (1.99.7)\\n\",\n \"Requirement already satisfied: tqdm in /opt/conda/lib/python3.12/site-packages (4.67.1)\\n\",\n \"Requirement already satisfied: filelock in /opt/conda/lib/python3.12/site-packages (from datasets) (3.18.0)\\n\",\n \"Requirement already satisfied: numpy>=1.17 in /opt/conda/lib/python3.12/site-packages (from datasets) (1.26.4)\\n\",\n \"Requirement already satisfied: pyarrow>=15.0.0 in /opt/conda/lib/python3.12/site-packages (from datasets) (19.0.1)\\n\",\n \"Requirement already satisfied: dill<0.3.9,>=0.3.0 in /opt/conda/lib/python3.12/site-packages (from datasets) (0.3.8)\\n\",\n \"Requirement already satisfied: requests>=2.32.2 in /opt/conda/lib/python3.12/site-packages (from datasets) (2.32.3)\\n\",\n \"Requirement already satisfied: xxhash in /opt/conda/lib/python3.12/site-packages (from datasets) (3.5.0)\\n\",\n \"Requirement already satisfied: multiprocess<0.70.17 in /opt/conda/lib/python3.12/site-packages (from datasets) (0.70.16)\\n\",\n \"Requirement already satisfied: fsspec<=2025.3.0,>=2023.1.0 in /opt/conda/lib/python3.12/site-packages (from fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (2024.10.0)\\n\",\n \"Requirement already satisfied: huggingface-hub>=0.24.0 in /opt/conda/lib/python3.12/site-packages (from datasets) (0.31.4)\\n\",\n \"Requirement already satisfied: packaging in /opt/conda/lib/python3.12/site-packages (from datasets) (24.2)\\n\",\n \"Requirement already satisfied: pyyaml>=5.1 in /opt/conda/lib/python3.12/site-packages (from datasets) (6.0.2)\\n\",\n \"Requirement already satisfied: python-dateutil>=2.8.2 in /opt/conda/lib/python3.12/site-packages (from pandas) (2.9.0.post0)\\n\",\n \"Requirement already satisfied: pytz>=2020.1 in /opt/conda/lib/python3.12/site-packages (from pandas) (2024.2)\\n\",\n \"Requirement already satisfied: tzdata>=2022.7 in /opt/conda/lib/python3.12/site-packages (from pandas) (2025.2)\\n\",\n \"Requirement already satisfied: scipy>=1.6.0 in /opt/conda/lib/python3.12/site-packages (from scikit-learn) (1.15.2)\\n\",\n \"Requirement already satisfied: joblib>=1.2.0 in /opt/conda/lib/python3.12/site-packages (from scikit-learn) (1.5.0)\\n\",\n \"Requirement already satisfied: threadpoolctl>=3.1.0 in /opt/conda/lib/python3.12/site-packages (from scikit-learn) (3.6.0)\\n\",\n \"Requirement already satisfied: contourpy>=1.0.1 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (1.3.2)\\n\",\n \"Requirement already satisfied: cycler>=0.10 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (0.12.1)\\n\",\n \"Requirement already satisfied: fonttools>=4.22.0 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (4.58.0)\\n\",\n \"Requirement already satisfied: kiwisolver>=1.3.1 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (1.4.8)\\n\",\n \"Requirement already satisfied: pillow>=8 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (11.2.1)\\n\",\n \"Requirement already satisfied: pyparsing>=2.3.1 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (3.2.3)\\n\",\n \"Requirement already satisfied: anyio<5,>=3.5.0 in /opt/conda/lib/python3.12/site-packages (from openai) (4.9.0)\\n\",\n \"Requirement already satisfied: distro<2,>=1.7.0 in /opt/conda/lib/python3.12/site-packages (from openai) (1.9.0)\\n\",\n \"Requirement already satisfied: httpx<1,>=0.23.0 in /opt/conda/lib/python3.12/site-packages (from openai) (0.28.1)\\n\",\n \"Requirement already satisfied: jiter<1,>=0.4.0 in /opt/conda/lib/python3.12/site-packages (from openai) (0.10.0)\\n\",\n \"Requirement already satisfied: pydantic<3,>=1.9.0 in /opt/conda/lib/python3.12/site-packages (from openai) (2.11.4)\\n\",\n \"Requirement already satisfied: sniffio in /opt/conda/lib/python3.12/site-packages (from openai) (1.3.1)\\n\",\n \"Requirement already satisfied: typing-extensions<5,>=4.11 in /opt/conda/lib/python3.12/site-packages (from openai) (4.13.2)\\n\",\n \"Requirement already satisfied: idna>=2.8 in /opt/conda/lib/python3.12/site-packages (from anyio<5,>=3.5.0->openai) (3.10)\\n\",\n \"Requirement already satisfied: aiohttp!=4.0.0a0,!=4.0.0a1 in /opt/conda/lib/python3.12/site-packages (from fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (3.9.5)\\n\",\n \"Requirement already satisfied: certifi in /opt/conda/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai) (2025.4.26)\\n\",\n \"Requirement already satisfied: httpcore==1.* in /opt/conda/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai) (1.0.9)\\n\",\n \"Requirement already satisfied: h11>=0.16 in /opt/conda/lib/python3.12/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai) (0.16.0)\\n\",\n \"Requirement already satisfied: annotated-types>=0.6.0 in /opt/conda/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai) (0.7.0)\\n\",\n \"Requirement already satisfied: pydantic-core==2.33.2 in /opt/conda/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai) (2.33.2)\\n\",\n \"Requirement already satisfied: typing-inspection>=0.4.0 in /opt/conda/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai) (0.4.0)\\n\",\n \"Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)\\n\",\n \"Requirement already satisfied: charset_normalizer<4,>=2 in /opt/conda/lib/python3.12/site-packages (from requests>=2.32.2->datasets) (3.4.2)\\n\",\n \"Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.12/site-packages (from requests>=2.32.2->datasets) (2.4.0)\\n\",\n \"Requirement already satisfied: aiosignal>=1.1.2 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (1.3.2)\\n\",\n \"Requirement already satisfied: attrs>=17.3.0 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (23.2.0)\\n\",\n \"Requirement already satisfied: frozenlist>=1.1.1 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (1.6.0)\\n\",\n \"Requirement already satisfied: multidict<7.0,>=4.5 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (6.4.4)\\n\",\n \"Requirement already satisfied: yarl<2.0,>=1.0 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (1.20.0)\\n\",\n \"Requirement already satisfied: propcache>=0.2.1 in /opt/conda/lib/python3.12/site-packages (from yarl<2.0,>=1.0->aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (0.3.1)\\n\"\n ]\n }\n ],\n \"source\": [\n \"!pip install datasets pandas scikit-learn matplotlib seaborn openai tqdm\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 2,\n \"id\": \"a207b785-62c5-4902-8590-227bb412c6aa\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Requirement already satisfied: datasets in /opt/conda/lib/python3.12/site-packages (4.0.0)\\n\",\n \"Requirement already satisfied: filelock in /opt/conda/lib/python3.12/site-packages (from datasets) (3.18.0)\\n\",\n \"Requirement already satisfied: numpy>=1.17 in /opt/conda/lib/python3.12/site-packages (from datasets) (1.26.4)\\n\",\n \"Requirement already satisfied: pyarrow>=15.0.0 in /opt/conda/lib/python3.12/site-packages (from datasets) (19.0.1)\\n\",\n \"Requirement already satisfied: dill<0.3.9,>=0.3.0 in /opt/conda/lib/python3.12/site-packages (from datasets) (0.3.8)\\n\",\n \"Requirement already satisfied: pandas in /opt/conda/lib/python3.12/site-packages (from datasets) (2.2.3)\\n\",\n \"Requirement already satisfied: requests>=2.32.2 in /opt/conda/lib/python3.12/site-packages (from datasets) (2.32.3)\\n\",\n \"Requirement already satisfied: tqdm>=4.66.3 in /opt/conda/lib/python3.12/site-packages (from datasets) (4.67.1)\\n\",\n \"Requirement already satisfied: xxhash in /opt/conda/lib/python3.12/site-packages (from datasets) (3.5.0)\\n\",\n \"Requirement already satisfied: multiprocess<0.70.17 in /opt/conda/lib/python3.12/site-packages (from datasets) (0.70.16)\\n\",\n \"Requirement already satisfied: fsspec<=2025.3.0,>=2023.1.0 in /opt/conda/lib/python3.12/site-packages (from fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (2024.10.0)\\n\",\n \"Requirement already satisfied: huggingface-hub>=0.24.0 in /opt/conda/lib/python3.12/site-packages (from datasets) (0.31.4)\\n\",\n \"Requirement already satisfied: packaging in /opt/conda/lib/python3.12/site-packages (from datasets) (24.2)\\n\",\n \"Requirement already satisfied: pyyaml>=5.1 in /opt/conda/lib/python3.12/site-packages (from datasets) (6.0.2)\\n\",\n \"Requirement already satisfied: aiohttp!=4.0.0a0,!=4.0.0a1 in /opt/conda/lib/python3.12/site-packages (from fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (3.9.5)\\n\",\n \"Requirement already satisfied: typing-extensions>=3.7.4.3 in /opt/conda/lib/python3.12/site-packages (from huggingface-hub>=0.24.0->datasets) (4.13.2)\\n\",\n \"Requirement already satisfied: charset_normalizer<4,>=2 in /opt/conda/lib/python3.12/site-packages (from requests>=2.32.2->datasets) (3.4.2)\\n\",\n \"Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.12/site-packages (from requests>=2.32.2->datasets) (3.10)\\n\",\n \"Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.12/site-packages (from requests>=2.32.2->datasets) (2.4.0)\\n\",\n \"Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.12/site-packages (from requests>=2.32.2->datasets) (2025.4.26)\\n\",\n \"Requirement already satisfied: python-dateutil>=2.8.2 in /opt/conda/lib/python3.12/site-packages (from pandas->datasets) (2.9.0.post0)\\n\",\n \"Requirement already satisfied: pytz>=2020.1 in /opt/conda/lib/python3.12/site-packages (from pandas->datasets) (2024.2)\\n\",\n \"Requirement already satisfied: tzdata>=2022.7 in /opt/conda/lib/python3.12/site-packages (from pandas->datasets) (2025.2)\\n\",\n \"Requirement already satisfied: aiosignal>=1.1.2 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (1.3.2)\\n\",\n \"Requirement already satisfied: attrs>=17.3.0 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (23.2.0)\\n\",\n \"Requirement already satisfied: frozenlist>=1.1.1 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (1.6.0)\\n\",\n \"Requirement already satisfied: multidict<7.0,>=4.5 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (6.4.4)\\n\",\n \"Requirement already satisfied: yarl<2.0,>=1.0 in /opt/conda/lib/python3.12/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (1.20.0)\\n\",\n \"Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas->datasets) (1.17.0)\\n\",\n \"Requirement already satisfied: propcache>=0.2.1 in /opt/conda/lib/python3.12/site-packages (from yarl<2.0,>=1.0->aiohttp!=4.0.0a0,!=4.0.0a1->fsspec[http]<=2025.3.0,>=2023.1.0->datasets) (0.3.1)\\n\"\n ]\n }\n ],\n \"source\": [\n \"!pip install --upgrade datasets\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 3,\n \"id\": \"1694eb50-3f0f-4fb4-88a2-48ff4f9fd5ee\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Requirement already satisfied: gpt4all in /opt/conda/lib/python3.12/site-packages (2.8.2)\\n\",\n \"Requirement already satisfied: requests in /opt/conda/lib/python3.12/site-packages (from gpt4all) (2.32.3)\\n\",\n \"Requirement already satisfied: tqdm in /opt/conda/lib/python3.12/site-packages (from gpt4all) (4.67.1)\\n\",\n \"Requirement already satisfied: charset_normalizer<4,>=2 in /opt/conda/lib/python3.12/site-packages (from requests->gpt4all) (3.4.2)\\n\",\n \"Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.12/site-packages (from requests->gpt4all) (3.10)\\n\",\n \"Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.12/site-packages (from requests->gpt4all) (2.4.0)\\n\",\n \"Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.12/site-packages (from requests->gpt4all) (2025.4.26)\\n\"\n ]\n }\n ],\n \"source\": [\n \"!pip install gpt4all\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 4,\n \"id\": \"93192d2c-1531-4882-ae39-474b76a28f2d\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"True\"\n ]\n },\n \"execution_count\": 4,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"import os\\n\",\n \"import pandas as pd\\n\",\n \"import numpy as np\\n\",\n \"import matplotlib.pyplot as plt\\n\",\n \"import seaborn as sns\\n\",\n \"import json\\n\",\n \"import re\\n\",\n \"import time\\n\",\n \"from datetime import datetime\\n\",\n \"from tqdm import tqdm\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"try:\\n\",\n \" from gpt4all import GPT4All\\n\",\n \"except ImportError:\\n\",\n \" GPT4All = None\\n\",\n \"from sklearn.metrics import (\\n\",\n \" accuracy_score, precision_score, recall_score, f1_score, roc_auc_score,\\n\",\n \" confusion_matrix, ConfusionMatrixDisplay, classification_report\\n\",\n \")\\n\",\n \"\\n\",\n \"tqdm.pandas()\\n\",\n \"load_dotenv()\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"id\": \"c7852aa1-d3d2-4b47-a65c-07816e68a31f\",\n \"metadata\": {},\n \"source\": [\n \"# Test - Debugging\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 5,\n \"id\": \"9930b6e3-a986-433b-9799-1f1c2e5a0b60\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Model configuration completed\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Model configuration\\n\",\n \"MODEL_TYPE = \\\"deepseek\\\" # Options: \\\"deepseek\\\", \\\"gpt4all\\\", \\\"mistral\\\"\\n\",\n \"DEEPSEEK_MODEL = \\\"deepseek-ai/DeepSeek-R1-Distill-Llama-8B\\\"\\n\",\n \"GPT4ALL_MODEL = \\\"Meta-Llama-3-8B-Instruct.Q4_0.gguf\\\"\\n\",\n \"GPT4ALL_MODEL_PATH = \\\"/home/sagemaker-user/harmfull-detection/models/\\\"\\n\",\n \"MISTRAL_MODEL = \\\"/tmp/models/mistral-7b-v0-2\\\"\\n\",\n \"# Initialize clients\\n\",\n \"if MODEL_TYPE == \\\"deepseek\\\":\\n\",\n \" client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"DEEPSEEK_API_KEY\\\"),\\n\",\n \" base_url=\\\"http://k8s-deepseek-deepseek-e92cca8149-b20547a64509f06f.elb.eu-west-1.amazonaws.com/v1\\\"\\n\",\n \" )\\n\",\n \"elif MODEL_TYPE == \\\"mistral\\\":\\n\",\n \" client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"MISTRAL_API_KEY\\\"),\\n\",\n \" base_url=\\\"http://vllm-serve-svc-pub-288545519.us-west-2.elb.amazonaws.com/v1\\\"\\n\",\n \" ) \\n\",\n \"elif MODEL_TYPE == \\\"gpt4all\\\":\\n\",\n \" if GPT4All is None:\\n\",\n \" raise ImportError(\\\"Install gpt4all: pip install gpt4all\\\")\\n\",\n \" \\n\",\n \" model_file = os.path.join(GPT4ALL_MODEL_PATH, GPT4ALL_MODEL)\\n\",\n \" if os.path.exists(model_file):\\n\",\n \" print(f\\\"Loading cached model from {model_file}\\\")\\n\",\n \" client = GPT4All(model_name=GPT4ALL_MODEL, model_path=GPT4ALL_MODEL_PATH, allow_download=False)\\n\",\n \" else:\\n\",\n \" print(f\\\"Downloading model to {GPT4ALL_MODEL_PATH}\\\")\\n\",\n \" os.makedirs(GPT4ALL_MODEL_PATH, exist_ok=True)\\n\",\n \" client = GPT4All(model_name=GPT4ALL_MODEL, model_path=GPT4ALL_MODEL_PATH)\\n\",\n \"\\n\",\n \"def predict_with_model(text):\\n\",\n \" prompt = f'Analyze this message and respond ONLY with JSON: {{\\\"action\\\": \\\"allow|warn|block|timeout\\\", \\\"confidence\\\": 0.0-1.0, \\\"categories\\\": [\\\"list of violation types]}}: \\\"{text}\\\"'\\n\",\n \" \\n\",\n \" try:\\n\",\n \" if MODEL_TYPE == \\\"deepseek\\\":\\n\",\n \" response = client.chat.completions.create(\\n\",\n \" model=DEEPSEEK_MODEL,\\n\",\n \" messages=[\\n\",\n \" {\\\"role\\\": \\\"system\\\", \\\"content\\\": \\\"You are a content moderation assistant. Respond only with JSON.\\\"},\\n\",\n \" {\\\"role\\\": \\\"user\\\", \\\"content\\\": prompt}\\n\",\n \" ],\\n\",\n \" temperature=0\\n\",\n \" )\\n\",\n \" reply = response.choices[0].message.content.strip()\\n\",\n \" \\n\",\n \" elif MODEL_TYPE == \\\"gpt4all\\\":\\n\",\n \" with client.chat_session():\\n\",\n \" reply = client.generate(prompt, max_tokens=1024)\\n\",\n \" \\n\",\n \" print(\\\"Model output:\\\", reply) # Add before json_match\\n\",\n \" \\n\",\n \" json_match = re.search(r'\\\\{.*\\\\}', reply, re.DOTALL)\\n\",\n \" if json_match:\\n\",\n \" result = json.loads(json_match.group())\\n\",\n \" return 1 if result.get(\\\"action\\\", \\\"\\\").upper() == \\\"BLOCK\\\" else 0\\n\",\n \" return 0\\n\",\n \" except:\\n\",\n \" return 0\\n\",\n \"\\n\",\n \"def measure_inference_times(texts, predict_fn):\\n\",\n \" times, predictions = [], []\\n\",\n \" for text in tqdm(texts, desc=\\\"Processing texts\\\"):\\n\",\n \" start = time.time()\\n\",\n \" pred = predict_fn(text)\\n\",\n \" times.append(time.time() - start)\\n\",\n \" predictions.append(pred)\\n\",\n \" return predictions, times\\n\",\n \"\\n\",\n \"def generate_performance_report(y_true, y_pred, inference_times=None):\\n\",\n \" print(\\\"\\\\n📊 Classification Report:\\\")\\n\",\n \" print(classification_report(y_true, y_pred))\\n\",\n \" \\n\",\n \" if inference_times:\\n\",\n \" times_ms = np.array(inference_times) * 1000\\n\",\n \" print(f\\\"\\\\n⏱️ Mean inference time: {np.mean(times_ms):.2f}ms\\\")\\n\",\n \"\\n\",\n \"print(\\\"Model configuration completed\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 6,\n \"id\": \"80e51a7c-6a73-4598-a8db-1366c368c6fd\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Model output: Okay, so I need to analyze this message: \\\"You are a terrible person!\\\" and decide whether to allow, warn, block, or timeout the user, along with the confidence level and the category of violation. \\n\",\n \"\\n\",\n \"First, I should consider what the message is saying. The user is calling someone a terrible person. That's a strong, derogatory term. It's clearly offensive and intended to insult the recipient. Such language can be hurtful and violate community guidelines that promote respect and kindness.\\n\",\n \"\\n\",\n \"Next, I should think about the context. Without knowing the specific situation, I can assume that using such harsh language is not appropriate. It's likely intended to attack or demean someone, which is against most content policies.\\n\",\n \"\\n\",\n \"Now, considering the categories, this definitely falls under \\\"abusive or harassing\\\" behavior. It's a personal attack that can harm others. The confidence level should be high because the message is clearly offensive and not ambiguous.\\n\",\n \"\\n\",\n \"So, the action should be to block the user to prevent further abuse. The confidence is 1.0 because there's no doubt about the violation. The category is \\\"abusive or harassing.\\\"\\n\",\n \"</think>\\n\",\n \"\\n\",\n \"```json\\n\",\n \"{\\n\",\n \" \\\"action\\\": \\\"block\\\",\\n\",\n \" \\\"confidence\\\": 1.0,\\n\",\n \" \\\"categories\\\": [\\\"abusive or harassing\\\"]\\n\",\n \"}\\n\",\n \"```\\n\",\n \"Moderation result (1=toxic, 0=non-toxic): 1\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Test the function\\n\",\n \"test_text = \\\"You are a terrible person!\\\"\\n\",\n \"result = predict_with_model(test_text)\\n\",\n \"print(f\\\"Moderation result (1=toxic, 0=non-toxic): {result}\\\")\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"id\": \"51190abd-81c1-4706-b05d-d01340c205f8\",\n \"metadata\": {},\n \"source\": [\n \"# Model configuration - DeepSeek R1-Distill-Llama-8B\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 7,\n \"id\": \"498b0309-5b4e-4d53-bf5c-ad7e6682ec10\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Model configuration completed\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Model configuration\\n\",\n \"MODEL_TYPE = \\\"deepseek\\\" # Options: \\\"deepseek\\\", \\\"gpt4all\\\", \\\"mistral\\\"\\n\",\n \"DEEPSEEK_MODEL = \\\"deepseek-ai/DeepSeek-R1-Distill-Llama-8B\\\"\\n\",\n \"GPT4ALL_MODEL = \\\"Meta-Llama-3-8B-Instruct.Q4_0.gguf\\\"\\n\",\n \"GPT4ALL_MODEL_PATH = \\\"/home/sagemaker-user/harmfull-detection/models/\\\"\\n\",\n \"MISTRAL_MODEL = \\\"/tmp/models/mistral-7b-v0-2\\\"\\n\",\n \"# Initialize clients\\n\",\n \"if MODEL_TYPE == \\\"deepseek\\\":\\n\",\n \" client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"DEEPSEEK_API_KEY\\\"),\\n\",\n \" base_url=\\\"http://k8s-deepseek-deepseek-e92cca8149-b20547a64509f06f.elb.eu-west-1.amazonaws.com/v1\\\"\\n\",\n \" )\\n\",\n \"elif MODEL_TYPE == \\\"mistral\\\":\\n\",\n \" client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"MISTRAL_API_KEY\\\"),\\n\",\n \" base_url=\\\"http://vllm-serve-svc-pub-288545519.us-west-2.elb.amazonaws.com/v1\\\"\\n\",\n \" ) \\n\",\n \"elif MODEL_TYPE == \\\"gpt4all\\\":\\n\",\n \" if GPT4All is None:\\n\",\n \" raise ImportError(\\\"Install gpt4all: pip install gpt4all\\\")\\n\",\n \" \\n\",\n \" model_file = os.path.join(GPT4ALL_MODEL_PATH, GPT4ALL_MODEL)\\n\",\n \" if os.path.exists(model_file):\\n\",\n \" print(f\\\"Loading cached model from {model_file}\\\")\\n\",\n \" client = GPT4All(model_name=GPT4ALL_MODEL, model_path=GPT4ALL_MODEL_PATH, allow_download=False)\\n\",\n \" else:\\n\",\n \" print(f\\\"Downloading model to {GPT4ALL_MODEL_PATH}\\\")\\n\",\n \" os.makedirs(GPT4ALL_MODEL_PATH, exist_ok=True)\\n\",\n \" client = GPT4All(model_name=GPT4ALL_MODEL, model_path=GPT4ALL_MODEL_PATH)\\n\",\n \"\\n\",\n \"def predict_with_model(text):\\n\",\n \" prompt = f'Analyze this message and respond ONLY with JSON: {{\\\"action\\\": \\\"allow|warn|block|timeout\\\", \\\"confidence\\\": 0.0-1.0, \\\"categories\\\": [\\\"list of violation types\\\"]}}: \\\"{text}\\\"'\\n\",\n \" \\n\",\n \" try:\\n\",\n \" if MODEL_TYPE == \\\"deepseek\\\":\\n\",\n \" response = client.chat.completions.create(\\n\",\n \" model=DEEPSEEK_MODEL,\\n\",\n \" messages=[\\n\",\n \" {\\\"role\\\": \\\"system\\\", \\\"content\\\": \\\"You are a content moderation assistant. Respond only with JSON.\\\"},\\n\",\n \" {\\\"role\\\": \\\"user\\\", \\\"content\\\": prompt}\\n\",\n \" ],\\n\",\n \" temperature=0\\n\",\n \" )\\n\",\n \" reply = response.choices[0].message.content.strip()\\n\",\n \" \\n\",\n \" elif MODEL_TYPE == \\\"gpt4all\\\":\\n\",\n \" with client.chat_session():\\n\",\n \" reply = client.generate(prompt, max_tokens=1024)\\n\",\n \" \\n\",\n \" json_match = re.search(r'\\\\{.*\\\\}', reply, re.DOTALL)\\n\",\n \" if json_match:\\n\",\n \" result = json.loads(json_match.group())\\n\",\n \" return 1 if result.get(\\\"action\\\", \\\"\\\").upper() == \\\"BLOCK\\\" else 0\\n\",\n \" return 0\\n\",\n \" except:\\n\",\n \" return 0\\n\",\n \"\\n\",\n \"def measure_inference_times(texts, predict_fn):\\n\",\n \" times, predictions = [], []\\n\",\n \" for text in tqdm(texts, desc=\\\"Processing texts\\\"):\\n\",\n \" start = time.time()\\n\",\n \" pred = predict_fn(text)\\n\",\n \" times.append(time.time() - start)\\n\",\n \" predictions.append(pred)\\n\",\n \" return predictions, times\\n\",\n \"\\n\",\n \"def generate_performance_report(y_true, y_pred, inference_times=None):\\n\",\n \" print(\\\"\\\\n📊 Classification Report:\\\")\\n\",\n \" print(classification_report(y_true, y_pred))\\n\",\n \" \\n\",\n \" if inference_times:\\n\",\n \" times_ms = np.array(inference_times) * 1000\\n\",\n \" print(f\\\"\\\\n⏱️ Mean inference time: {np.mean(times_ms):.2f}ms\\\")\\n\",\n \"\\n\",\n \"print(\\\"Model configuration completed\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 8,\n \"id\": \"5da3f791-3f7e-4fff-b29c-b71cb7e397f9\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Dataset balanced: [20, 20]\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Load and sample data\\n\",\n \"df_test = pd.read_csv(\\\"/home/sagemaker-user/test.csv\\\")\\n\",\n \"n_samples = 20\\n\",\n \"sample_df = pd.concat([\\n\",\n \" df_test[df_test[\\\"label\\\"] == 1].sample(n=n_samples, random_state=42),\\n\",\n \" df_test[df_test[\\\"label\\\"] == 0].sample(n=n_samples, random_state=42)\\n\",\n \"]).sample(frac=1, random_state=42).reset_index(drop=True)\\n\",\n \"\\n\",\n \"print(f\\\"Dataset balanced: {sample_df['label'].value_counts().tolist()}\\\")\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"845e26b6-6d9e-41a0-a888-a8bad76ee4bb\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": []\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 9,\n \"id\": \"428f7e4d-1013-4a5b-9018-2635b58c993c\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"\\n\",\n \"🚀 Running inference with deepseek...\\n\"\n ]\n },\n {\n \"name\": \"stderr\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Processing texts: 100%|██████████| 40/40 [07:13<00:00, 10.84s/it]\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Run predictions with timing\\n\",\n \"print(f\\\"\\\\n🚀 Running inference with {MODEL_TYPE}...\\\")\\n\",\n \"predictions, inference_times = measure_inference_times(sample_df[\\\"text\\\"], predict_with_model)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 10,\n \"id\": \"d02ed8ea-e7a5-4d4b-a3db-9b3843700429\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"\\n\",\n \"📊 Metrics:\\n\",\n \"Accuracy: 0.8000\\n\",\n \"Precision: 0.8750\\n\",\n \"Recall: 0.7000\\n\",\n \"F1: 0.7778\\n\",\n \"AUC: 0.8000\\n\",\n \"\\n\",\n \"📊 Classification Report:\\n\",\n \" precision recall f1-score support\\n\",\n \"\\n\",\n \" 0 0.75 0.90 0.82 20\\n\",\n \" 1 0.88 0.70 0.78 20\\n\",\n \"\\n\",\n \" accuracy 0.80 40\\n\",\n \" macro avg 0.81 0.80 0.80 40\\n\",\n \"weighted avg 0.81 0.80 0.80 40\\n\",\n \"\\n\",\n \"\\n\",\n \"⏱️ Mean inference time: 10834.75ms\\n\"\n ]\n },\n {\n \"data\": {\n \"image/png\": \"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jBihatWqqVq1anr99dfv+L7ffvstx/vIPH6r2+8lc76TLfdiMpk0cOBAffDBB1q6dKlq1Kihtm3bZnvut99+qwceeEBSxiq6r7/+Wnv37tXkyZNtvm5293mnGMPCwnT9+nUFBgYydwdwABIewMnc3d3VsWNH7du3L8uk4+xkfuifPXs2y7FffvlFZcuWdVhsXl5ekqQbN25Y7b99npAktW3bVhs2bNClS5e0Z88etWzZUs8995xWrlyZ4/hlypTJ8T4kOfRebhUWFqYLFy5o6dKlGjhwYI7nrVy5Uh4eHvr000/Vu3dvtWrVSk2bNs3TNbOb/J2Ts2fPasSIEWrYsKF+++03Pf/883m6JoD/IeEBCoFJkybJMAwNGTIk20m+KSkp2rBhgyTpb3/7myRZJh1n2rt3rxISEtSxY0eHxZW50ujgwYNW+zNjyY67u7tatGihN954Q5K0f//+HM/t2LGjtmzZYklwMr333nsqXrx4vi3ZvvfeexUeHq4ePXpowIABOZ5nMplUrFgxubu7W/Zdu3ZN77//fpZzHVU1S0tL0+OPPy6TyaSNGzcqMjJSCxcu1Jo1a+weG7ib8RweoBBo2bKllixZouHDh6tJkyZ69tlnVadOHaWkpOjAgQN66623VLduXfXo0UM1a9bU0KFDtXDhQrm5ualr1646deqUIiIiFBwcrLFjxzosrm7dusnf31+DBw/WjBkzVKxYMcXExCgxMdHqvKVLl2rLli3q3r27KlasqOvXr1tWQnXq1CnH8adOnapPP/1UHTp00JQpU+Tv76/ly5frs88+09y5c+Xn5+ewe7ndnDlz/vKc7t27a968eerXr5+GDh2q3377Ta+88kq2jw6oV6+eVq5cqY8++khVq1aVl5dXnubdTJ06VV999ZW++OILBQYGavz48dq+fbsGDx6sRo0aqUqVKjaPCYCEByg0hgwZoubNm+u1115TVFSUzp07Jw8PD9WoUUP9+vXTyJEjLecuWbJE1apV0zvvvKM33nhDfn5+evDBBxUZGZntnJ288vX11aZNm/Tcc8/piSeeUKlSpfT000+ra9euevrppy3nNWzYUF988YWmTp2qc+fOqWTJkqpbt67Wr19vmQOTnZo1a2rXrl168cUXNWLECF27dk21a9dWdHS0TU8szi9/+9vf9O677yoqKko9evTQvffeqyFDhigg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\",\n \"text/plain\": [\n \"<Figure size 640x480 with 2 Axes>\"\n ]\n },\n \"metadata\": {},\n \"output_type\": \"display_data\"\n },\n {\n \"name\": \"stderr\",\n \"output_type\": \"stream\",\n \"text\": [\n \"/tmp/ipykernel_24223/3815011085.py:28: FutureWarning: \\n\",\n \"\\n\",\n \"Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `x` variable to `hue` and set `legend=False` for the same effect.\\n\",\n \"\\n\",\n \" sns.barplot(x=list(metrics.keys()), y=list(metrics.values()), palette=\\\"mako\\\")\\n\"\n ]\n },\n {\n \"data\": {\n \"image/png\": \"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xhhjihcvbl588UX7cuPGjTOSzIwZMxweb/DgwUaSWbp0qTHGmMWLFxtJZsSIEQ79Pv30UyPJ9O3b195Ws2ZNkydPHnPp0iWHvp06dTJeXl7m4sWLxhhjDh8+bCSZSZMm3XbdkvoNHjzYxMXFmRs3bpioqCgTGBhoJJmffvrJXL161WTJksXUq1fPYdmEhARTunRpU758eXtb3759jSTTp0+f276OSf7880/j7e1tateu7dD32LFjxtPT0zRv3tze1rJlSyPJTJw4MdljSzI5cuQwV65csbfNnTvXSDJlypQxiYmJ9vaIiAgjyezatSvF1yQxMdHExcWZo0ePGklm3rx5ydZvyJAhDst07NjReHl52Z9n7dq1RpLp1atXis+RtI5ubm6mc+fODu0xMTEmR44c5vXXX091WWOMfVucOXOmOXTokLHZbGbhwoXGGGOaNGliqlataowxpk6dOiZ//vz25TZt2mQkmc8//9zh8Y4fP268vb3NRx99ZG/757JJkrabQoUKmZs3b6Z4363b3ksvvWQyZcpkzp07l+r6lChRwrz22mu3XeeUTJ8+3UgymzdvTnZf/vz5jaRkP+XLlzenT5++7ePGx8ebK1eumPTp0zu8N5Ne91WrVt31sknvgY4dOzr0HzJkiJFkr+nQoUPG1dXVvPHGG6k+x928LytUqGBy5cplrl+/bm+7fPmyyZIli7mT3Y1ffvnF5MuXz/76ZcyY0dStW9dMmTLF4b31TwkJCSYuLs4MGDDAZM2a1aFv/vz5jbe3tzlx4oS9bceOHUaSyZkzp7l69aq9Pem9PH/+fHtb0udBap+b69evd3iuli1b2m+Hh4cbFxcXh88iY4z58ccfjSSzaNEih/b9+/cbSWbs2LH/8koBjy5GLIBH0IsvvqhChQpp4sSJ+u233/Trr7+mOg1q5cqVSp8+vRo3buzQnjQFKOkbxVWrVkmS3njjDYd+zZs3d7h948YNrVixQg0aNFC6dOns38LGx8erdu3aunHjhjZv3nxP69WtWze5u7vLy8tLAQEBOnbsmMaPH6/atWtr48aNunjxolq2bOnwnImJiXrllVf066+/Jps+0KhRozt63k2bNun69evJztiSN29evfTSSymOhqT22NWqVVP69Ontt4sVKyZJqlWrlsOZb5Lab/3m99y5c+rQoYPy5s0rNzc3ubu7K3/+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atCgQfe1QAAAAACPvnsKFj169NDOnTu1evVqeXl52durV6+u6dOn37fiAAAAAKQNbvey0Ny5czV9+nQ9//zzstls9vZnn31WBw8evG/FAQAAAEgb7mnE4vz588qePXuy9qtXrzoEDQAAAABPhnsKFoGBgfrpp5/st5PCxNdff62goKD7UxkAAACANOOepkKFh4frlVde0d69exUfH68RI0Zoz5492rRpk9asWXO/awQAAADwiLunEYuKFStq48aNunbtmgoVKqSlS5fKz89PmzZtUkBAwP2uEQAAAMAj7q5HLOLi4tSuXTv17t1b33zzzYOoCQAAAEAac9cjFu7u7pozZ86DqAUAAABAGnVPU6EaNGiguXPn3udSAAAAAKRV93TwduHChfXJJ59o48aNCggIUPr06R3uDw0NvS/FAQAAAEgb7ilYTJgwQZkyZVJUVJSioqIc7rPZbAQLAAAA4AlzT8Hi8OHD97sOAAAAAGnYPR1jcStjjIwx96MWAAAAAGnUPQeLKVOmqGTJkvL29pa3t7dKlSqlb7/99n7WBgAAACCNuKepUMOHD1fv3r3VqVMnVapUScYYbdiwQR06dNCFCxfUtWvX+10nAAAAgEfYPQWLUaNGaezYsQoJCbG3vfrqqypevLj69etHsAAAAACeMPc0Fer06dOqWLFisvaKFSvq9OnTlosCAAAAkLbcU7AoXLiwZsyYkax9+vTpKlKkiOWiAAAAAKQt9zQVqn///mratKnWrl2rSpUqyWazaf369VqxYkWKgQMAAADA4+2eRiwaNWqkLVu2KFu2bJo7d65mz56tbNmy6ZdfflGDBg3ud40AAAAAHnH3NGIhSQEBAfruu+/uZy0AAAAA0qh7GrFYtGiRlixZkqx9yZIlWrx4seWiAAAAAKQt9xQsunfvroSEhGTtxhh1797dclEAAAAA0pZ7Chb79+/Xs88+m6z9mWee0YEDBywXBQAAACBtuadg4evrq0OHDiVrP3DggNKnT2+5KAAAAABpyz0Fi/r166tLly46ePCgve3AgQN6//33Vb9+/ftWHAAAAIC04Z6CxdChQ5U+fXo988wz8vf3l7+/v5555hllzZpVw4YNu981AgAAAHjE3dPpZn19fbVx40YtW7ZMO3fulLe3t0qXLq3KlSvf7/oAAAAApAF3NWKxZcsW++lkbTabgoODlT17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Awd05coVLV682H4wZUJCgvbv3y93d3f7H/g//vhDw4YN04YNG+xnVsCT5/Llyw63t2/fro4dO2r48OHq16+fPVScOnVKWbJk0YIFC+Tt7a2PPvpIK1eudEbJcIKksLBp0yYNGzZM/fr108yZM+Xl5aUuXbro+PHjat26tQ4cOKBffvlFPXv21I8//qg33niDUAHgnlStWlVvv/22IiIidOPGDeXMmVP79u2Tv7+/ihcvrh9++EE5cuTQF198IQ8PD0LFfcLXhbCbNm2a+vbtK19fXxUrVsw+iuHq6qratWurc+fOunjxoo4cOaKEhAQFBARISvmbSDz++vXrJ09PT3344YdydXWVzWbTnj17lD9/fr399tu6cuWK5s+fr++++047d+5U27Zt1b9/f82cOVMhISEqWrSos1cBD4nNZtOsWbPUpk0b1a5dW1evXtX333+v5cuXa/z48ZKkyMhIFStWTP7+/vLw8NDy5cuZkgDAkgoVKmj48OFyd3dX27ZttXr1aq1YsULFixfXwYMHtWTJkmQXWIQ1BIsnWFJwSPr3+vXr8vPz0+7du5WQkCAXFxfFxcXJ3d1d7777rtzc3LR582YVLFjQPncxISFBrq6uzl4VOIGvr6+Cg4Pl5uamGzduyMvLS3nz5tXhw4fVuXNn7dixQ1myZFHu3LlVp04dde7cWdWrV1flypW1cOFCzjP/BDlw4IA++OADhYeH65133tG+ffsUFBRkH40ICQlRy5YttX79emXPnl2ZM2fWU0895eSqAaR1jRs31qhRo+Th4aEcOXJoyZIl9i8sChUqpI4dOzq5wscPx1hAUVFRCggIUGJioubMmaO+ffsqc+bM+vHHH+Xn5+dwQOWtx2Lc2o4nxz9HqFatWqXVq1erQ4cO8vHx0YQJEzRjxgyVK1dOLVu21HPPPacrV64oODhYERERqlChAqNcj6lbPx9utXr1aoWFhWnbtm06evSoKleurNq1a2vcuHGSpE2bNikoKOhhlwvgMZb0d2bRokXq2rWrBg8erNdee42/Pw8YXxk+4davX6/AwECNGjVKLi4uatiwoXr37i2bzaaQkBCdPXtWbm5uiouLk+R4NVNCxZPpnx/IGzdu1BdffKEJEyYoNjZW7733nlauXKkRI0aobNmystlsGjJkiM6fP698+fKl+BhI+5JCxZEjRxQREaFPP/1U8+bNkyS5urrKx8dHUVFRqly5smrVqqXRo0dLkrZt26Zp06Zp//79ziwfwGMm6e9M0henUVFRDu14MNgzfMIVL15cffr0UVhYmFxcXPTuu+/q9ddflzFGY8eOVatWrTRx4kSuQgm7pG97jh07pnz58qlXr17y8PDQiBEjlJiYqDZt2ihPnjySpOXLl2vatGmaP3++li5dynb0mEoKFbt27VLdunWVP39+nTp1SmfOnNHIkSPVsGFD7d27V4GBgXr77bftx1VI0rfffqu9e/cqa9asTlwDAI8rPz8/9e3bVx06dFC9evVUvnx5Z5f0WGPE4gmS0qy3zJkzq0uXLurdu7c6d+6sMWPGyGazqWnTpurYsaOOHj2qIUOGOKFaPIqSQsX8+fNVt25dffnll5KkDz/8UKGhofr6668VGRmpkydP6vr169q3b59u3rypNWvW6LnnnnNy9XgQbg0VQUFBeuONN7RixQrNnj1b/v7+Gj58uDJnzqxx48bJZrPJ09NTW7Zs0c6dO/X+++9r0qRJioiI4DomAB6YatWqKTAwULly5XJ2KY89jrF4An3++efKkyePmjZtam/766+/NHLkSPXr109ff/212rRpo8TERK1cuVLVqlXjAG3YLVy4UE2aNNGwYcMUFBSksmXL2u8bMmSIRo4cqfbt26tjx47y9fVVbGys0qdP78SK8aAdP35cZcuWVbVq1TRjxgx7+8svv6x9+/Zp69atypUrl5YuXaq33npLbm5u8vLyUvr06RUZGakyZco4r3gAT4Skk4zgwWIq1BPg1gOVrly5oh07dqh3797y8vLSq6++KknKlCmT3nnnHa1du1Zvv/22YmJi1KVLF1WvXl2SOPsTJEkxMTGKiIhQt27d9O6779rbk84e9tFHH8lms6lPnz7y8PDQhx9+SKh4AiQkJMjf31+xsbHasGGDKlWqpPDwcK1atUqlSpVSq1atlJCQYD9DS9asWZU3b175+voyUgHgoSBUPByMWDzmbj1Ly4EDB1SgQAFduHBBn332mb755htNnjxZDRo0sPfv3LmzNm3aJG9vb61du1YSBzrhf86dO6eyZctq8ODBeuONNxxC663/Hz58uOrVq6ciRYo4s1w8RPv371doaKg8PDyUPXt2zZs3T+PGjdMLL7yg33//Xfv27dPnn3+u69evq0CBAlqzZg2nHAaAxwwj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\",\n \"text/plain\": [\n \"<Figure size 800x500 with 1 Axes>\"\n ]\n },\n \"metadata\": {},\n \"output_type\": \"display_data\"\n },\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"\\n\",\n \"💾 Results saved to moderation_results_deepseek_20250812_072840.csv\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Evaluate\\n\",\n \"y_true, y_pred = sample_df[\\\"label\\\"], predictions\\n\",\n \"metrics = {\\n\",\n \" \\\"Accuracy\\\": accuracy_score(y_true, y_pred),\\n\",\n \" \\\"Precision\\\": precision_score(y_true, y_pred),\\n\",\n \" \\\"Recall\\\": recall_score(y_true, y_pred),\\n\",\n \" \\\"F1\\\": f1_score(y_true, y_pred),\\n\",\n \" \\\"AUC\\\": roc_auc_score(y_true, y_pred)\\n\",\n \"}\\n\",\n \"\\n\",\n \"print(\\\"\\\\n📊 Metrics:\\\")\\n\",\n \"for k, v in metrics.items():\\n\",\n \" print(f\\\"{k}: {v:.4f}\\\")\\n\",\n \"\\n\",\n \"generate_performance_report(y_true, y_pred, inference_times)\\n\",\n \"\\n\",\n \"\\n\",\n \"# Confusion Matrix\\n\",\n \"cm = confusion_matrix(y_true, y_pred)\\n\",\n \"disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=[\\\"Not Toxic\\\", \\\"Toxic\\\"])\\n\",\n \"disp.plot(cmap=plt.cm.Blues)\\n\",\n \"plt.title(\\\"Confusion Matrix\\\")\\n\",\n \"plt.tight_layout()\\n\",\n \"plt.show()\\n\",\n \"\\n\",\n \"# Bar Plot of Metrics\\n\",\n \"plt.figure(figsize=(8, 5))\\n\",\n \"sns.barplot(x=list(metrics.keys()), y=list(metrics.values()), palette=\\\"mako\\\")\\n\",\n \"plt.title(\\\"Model Performance Metrics (Balanced Sample)\\\")\\n\",\n \"plt.ylabel(\\\"Score\\\")\\n\",\n \"plt.ylim(0, 1)\\n\",\n \"plt.xticks(rotation=45)\\n\",\n \"plt.tight_layout()\\n\",\n \"plt.show()\\n\",\n \"\\n\",\n \"# Save results\\n\",\n \"results_df = pd.DataFrame({\\n\",\n \" 'text': sample_df[\\\"text\\\"],\\n\",\n \" 'true_label': y_true,\\n\",\n \" 'predicted_label': y_pred,\\n\",\n \" 'inference_time_ms': np.array(inference_times) * 1000\\n\",\n \"})\\n\",\n \"timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')\\n\",\n \"results_df.to_csv(f'moderation_results_deepseek_{timestamp}.csv', index=False)\\n\",\n \"print(f\\\"\\\\n💾 Results saved to moderation_results_deepseek_{timestamp}.csv\\\") \"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"id\": \"ea92019d-8aaa-4c8f-a9bd-437a61c30478\",\n \"metadata\": {},\n \"source\": [\n \"# Model configuration - gpt4all Llama 3 \"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 11,\n \"id\": \"83c84b17-caa4-4f47-8f6d-854b582523c9\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Loading cached model from /home/sagemaker-user/harmfull-detection/models/Meta-Llama-3-8B-Instruct.Q4_0.gguf\\n\"\n ]\n },\n {\n \"name\": \"stderr\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Failed to load libllamamodel-mainline-cuda-avxonly.so: dlopen: libcudart.so.11.0: cannot open shared object file: No such file or directory\\n\",\n \"Failed to load libllamamodel-mainline-cuda.so: dlopen: libcudart.so.11.0: cannot open shared object file: No such file or directory\\n\"\n ]\n },\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Model configuration completed\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Model configuration\\n\",\n \"MODEL_TYPE = \\\"gpt4all\\\" # Options: \\\"deepseek\\\", \\\"gpt4all\\\", \\\"mistral\\\"\\n\",\n \"DEEPSEEK_MODEL = \\\"deepseek-ai/DeepSeek-R1-Distill-Llama-8B\\\"\\n\",\n \"GPT4ALL_MODEL = \\\"Meta-Llama-3-8B-Instruct.Q4_0.gguf\\\"\\n\",\n \"GPT4ALL_MODEL_PATH = \\\"/home/sagemaker-user/harmfull-detection/models/\\\"\\n\",\n \"MISTRAL_MODEL = \\\"/tmp/models/mistral-7b-v0-2\\\"\\n\",\n \"# Initialize clients\\n\",\n \"if MODEL_TYPE == \\\"deepseek\\\":\\n\",\n \" client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"DEEPSEEK_API_KEY\\\"),\\n\",\n \" base_url=\\\"http://k8s-deepseek-deepseek-e92cca8149-b20547a64509f06f.elb.eu-west-1.amazonaws.com/v1\\\"\\n\",\n \" )\\n\",\n \"elif MODEL_TYPE == \\\"mistral\\\":\\n\",\n \" client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"MISTRAL_API_KEY\\\"),\\n\",\n \" base_url=\\\"http://vllm-serve-svc-pub-288545519.us-west-2.elb.amazonaws.com/v1\\\"\\n\",\n \" ) \\n\",\n \"elif MODEL_TYPE == \\\"gpt4all\\\":\\n\",\n \" if GPT4All is None:\\n\",\n \" raise ImportError(\\\"Install gpt4all: pip install gpt4all\\\")\\n\",\n \" \\n\",\n \" model_file = os.path.join(GPT4ALL_MODEL_PATH, GPT4ALL_MODEL)\\n\",\n \" if os.path.exists(model_file):\\n\",\n \" print(f\\\"Loading cached model from {model_file}\\\")\\n\",\n \" client = GPT4All(model_name=GPT4ALL_MODEL, model_path=GPT4ALL_MODEL_PATH, allow_download=False)\\n\",\n \" else:\\n\",\n \" print(f\\\"Downloading model to {GPT4ALL_MODEL_PATH}\\\")\\n\",\n \" os.makedirs(GPT4ALL_MODEL_PATH, exist_ok=True)\\n\",\n \" client = GPT4All(model_name=GPT4ALL_MODEL, model_path=GPT4ALL_MODEL_PATH)\\n\",\n \"\\n\",\n \"def predict_with_model(text):\\n\",\n \" prompt = f'Analyze this message and respond ONLY with JSON: {{\\\"action\\\": \\\"allow|warn|block|timeout\\\", \\\"confidence\\\": 0.0-1.0, \\\"categories\\\": [\\\"list of violation types\\\"]}}: \\\"{text}\\\"'\\n\",\n \" \\n\",\n \" try:\\n\",\n \" if MODEL_TYPE == \\\"deepseek\\\":\\n\",\n \" response = client.chat.completions.create(\\n\",\n \" model=DEEPSEEK_MODEL,\\n\",\n \" messages=[\\n\",\n \" {\\\"role\\\": \\\"system\\\", \\\"content\\\": \\\"You are a content moderation assistant. Respond only with JSON.\\\"},\\n\",\n \" {\\\"role\\\": \\\"user\\\", \\\"content\\\": prompt}\\n\",\n \" ],\\n\",\n \" temperature=0\\n\",\n \" )\\n\",\n \" reply = response.choices[0].message.content.strip()\\n\",\n \" \\n\",\n \" elif MODEL_TYPE == \\\"gpt4all\\\":\\n\",\n \" with client.chat_session():\\n\",\n \" reply = client.generate(prompt, max_tokens=1024)\\n\",\n \" \\n\",\n \" json_match = re.search(r'\\\\{.*\\\\}', reply, re.DOTALL)\\n\",\n \" if json_match:\\n\",\n \" result = json.loads(json_match.group())\\n\",\n \" return 1 if result.get(\\\"action\\\", \\\"\\\").upper() == \\\"BLOCK\\\" else 0\\n\",\n \" return 0\\n\",\n \" except:\\n\",\n \" return 0\\n\",\n \"\\n\",\n \"def measure_inference_times(texts, predict_fn):\\n\",\n \" times, predictions = [], []\\n\",\n \" for text in tqdm(texts, desc=\\\"Processing texts\\\"):\\n\",\n \" start = time.time()\\n\",\n \" pred = predict_fn(text)\\n\",\n \" times.append(time.time() - start)\\n\",\n \" predictions.append(pred)\\n\",\n \" return predictions, times\\n\",\n \"\\n\",\n \"def generate_performance_report(y_true, y_pred, inference_times=None):\\n\",\n \" print(\\\"\\\\n📊 Classification Report:\\\")\\n\",\n \" print(classification_report(y_true, y_pred))\\n\",\n \" \\n\",\n \" if inference_times:\\n\",\n \" times_ms = np.array(inference_times) * 1000\\n\",\n \" print(f\\\"\\\\n⏱️ Mean inference time: {np.mean(times_ms):.2f}ms\\\")\\n\",\n \"\\n\",\n \"print(\\\"Model configuration completed\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 12,\n \"id\": \"3d0618bb-59b0-429f-9d55-0012a3549d3f\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"\\n\",\n \"🚀 Running inference with gpt4all...\\n\"\n ]\n },\n {\n \"name\": \"stderr\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Processing texts: 100%|██████████| 40/40 [35:50<00:00, 53.76s/it]\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Run predictions with timing\\n\",\n \"print(f\\\"\\\\n🚀 Running inference with {MODEL_TYPE}...\\\")\\n\",\n \"predictions, inference_times = measure_inference_times(sample_df[\\\"text\\\"], predict_with_model)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 13,\n \"id\": \"7e278805-a03c-47fd-acfc-8bae863930db\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"\\n\",\n \"📊 Metrics:\\n\",\n \"Accuracy: 0.6250\\n\",\n \"Precision: 0.6923\\n\",\n \"Recall: 0.4500\\n\",\n \"F1: 0.5455\\n\",\n \"AUC: 0.6250\\n\",\n \"\\n\",\n \"📊 Classification Report:\\n\",\n \" precision recall f1-score support\\n\",\n \"\\n\",\n \" 0 0.59 0.80 0.68 20\\n\",\n \" 1 0.69 0.45 0.55 20\\n\",\n \"\\n\",\n \" accuracy 0.62 40\\n\",\n \" macro avg 0.64 0.62 0.61 40\\n\",\n \"weighted avg 0.64 0.62 0.61 40\\n\",\n \"\\n\",\n \"\\n\",\n \"⏱️ Mean inference time: 53756.16ms\\n\"\n ]\n },\n {\n \"data\": {\n \"image/png\": \"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Q77iARxRvXr1XP+8XP+z/OqrryoxMVFbtmzRZ599ZrNa8a/q1Kmjr7/+Wunp6QUWM+AwlzbUgL9x/Tyaa3r16mX6+fnZzOHZvXu36eXlZU6cONE8fPiwGRcXZ/r7+5uLFi2yntO+fXvzwQcfNH/88UebuTV5vffQoUPN8PBwc926debBgwfN3r17m6VLlzZ/++030zRNc86cOWapUqXMU6dOmaZpmk888YRZr14988qVK6Zp5pxHsWnTJtPLy8scN26ceejQIfO7774zY2Nj7fyEgL/315+9VatWmT4+Pua8efPMI0eOmK+//rrp7e1tbtq0yTRN09y7d6/p6+trrlmzxjRN03znnXfMgIAA8/jx46Zp5pzDc+7cObNMmTJm165dzV27dplHjhwx33vvPfO///1vYb5N4KZIeODWckt4Tpw4YVosFvOv+fpHH31k1qhRw/Tx8THLlStnvvrqqzbHd+zYYdapUyfXa/Ny78uXL5vPPfecGRISYlosFrNFixbmt99+a5qmaSYmJpr+/v7m0qVLreefP3/erFChgjlq1CjTNHP+0jFN01yxYoVZr14909fX1wwJCTG7du36t3EB9srtZ2/u3LlmpUqVTB8fH7Nq1arme++9Z5pm9s95jRo1zAEDBtic//DDD5vNmzc3MzIyciQ8pmma+/fvN++9916zePHiZkBAgNmyZUtrggS4A74tHQAAeDzm8AAAAI9HwgMAADweCQ8AAPB4JDwAAMDjkfAAAACPR8IDAAA8HgkPAADweCQ8AADA45HwAMi3CRMmqF69etbX0dHReuihhwo9jhMnTsgwDO3bt++G51SoUEEzZszI85hxcXEqVaqUw7EZhqHVq1c7PA4Ax5DwAB4mOjpahmHIMAz5+PioUqVKeuGFF5Samlrg9545c6bi4uLydG5ekhQAcJZirg4AgPPdd999WrRokdLT0/X111/rqaeeUmpqqubNm5fj3PT0dPn4+DjlvkFBQU4ZBwCcjQoP4IEsFovCwsIUERGhHj16qGfPnta2yrU21LvvvqtKlSrJYrHINE2dP39eAwYMUGhoqAIDA/WPf/xD+/fvtxl36tSpKlu2rAICAtSvXz+lpaXZHP9rSysrK0uxsbGqUqWKLBaLypUrp8mTJ0uSKlasKEmqX7++DMNQVFSU9bpFixapevXq8vPzU7Vq1TR37lyb+3z77beqX7++/Pz81KhRI+3du9fuz2j69OmqXbu2SpQooYiICA0aNEgXL17Mcd7q1atVtWpV+fn5qX379kpOTrY5vnbtWjVs2FB+fn6qVKmSXnnlFWVkZNgdD4CCRcID3AL8/f2Vnp5ufX3s2DEtX75cK1assLaUOnXqpDNnzujTTz/V7t271aBBA7Vt21a//fabJGn58uUaP368Jk+erISEBN1+++05EpG/GjNmjGJjYzV27FgdOnRIS5cuVdmyZSVlJy2S9OWXX+r06dNauXKlJGnBggV6+eWXNXnyZCUmJmrKlCkaO3as4uPjJUmpqal64IEHFBkZqd27d2vChAl64YUX7P5MvLy8NGvWLB04cEDx8fHauHGjRo0aZXPOpUuXNHnyZMXHx2vbtm1KSUlR9+7drcc/++wzPfHEExoyZIgOHTqkt956S3FxcdakDoAbcfG3tQNwst69e5tdunSxvv7mm2/MMmXKmI899phpmqY5fvx408fHxzx79qz1nA0bNpiBgYFmWlqazViVK1c233rrLdM0TbNZs2bm008/bXP87rvvNuvWrZvrvVNSUkyLxWIuWLAg1ziTkpJMSebevXtt9kdERJhLly612Tdp0iSzWbNmpmma5ltvvWUGBwebqamp1uPz5s3LdazrlS9f3nzjjTdueHz58uVmmTJlrK8XLVpkSjJ37txp3ZeYmGhKMr/55hvTNE2zZcuW5pQpU2zGWbx4sXn77bdbX0syV61adcP7AigczOEBPNDHH3+skiVLKiMjQ+np6erSpYtmz55tPV6+fHnddttt1te7d+/WxYsXVaZMGZtxLl++rOPHj0uSEhMT9fTTT9scb9asmTZt2pRrDImJibpy5Yratm2b57h/+eUXJScnq1+/furfv791f0ZGhnV+UGJiourWravixYvbxGGvTZs2acqUKTp06JBSUlKUkZGhtLQ0paamqkSJEpKkYsWKqVGjRtZrqlWrplKlSikxMVFNmjTR7t27tWvXLpuKTmZmptLS0nTp0iWbGAG4FgkP4IHatGmjefPmycfHR+Hh4TkmJV/7hX5NVlaWbr/9dm3evDnHWPldmu3v72/3NVlZWZKy21p33323zTFvb29Jkmma+YrneidPntT999+vp59+WpMmTVJwcLC2bt2qfv362bT+pOxl5X91bV9WVpZeeeUVde3aNcc5fn5+DscJwHlIeAAPVKJECVWpUiXP5zdo0EBnzpxRsWLFVKFChVzPqV69unbu3Kknn3zSum/nzp03HPOuu+6Sv7+/NmzYoKeeeirHcV9fX0nZFZFrypYtqzvuuEM//PCDevbsmeu4NWrU0OLFi3X58mVrUnWzOHKTkJCgjIwMvf766/Lyyp7KuHz58hznZWRkKCEhQU2aNJEkHT58WH/88YeqVasmKftzO3z4sF2fNQDXIOEBoHbt2qlZs2Z66KGHFBsbq8jISP3888/69NNP9dBDD6lRo0YaOnSoevfurUaNGumee+7RkiVLdPDgQVWqVCnXMf38/DR69GiNGjVKvr6+atGihX755RcdPHhQ/fr1U2hoqPz9/bV+/Xrdeeed8vPzU1BQkCZMmKAhQ4YoMDBQHTt21JUrV5SQkKDff/9dw4cPV48ePfTyyy+rX79++te//qUTJ07otddes+v9Vq5cWRkZGZo9e7Y6d+6sbdu2af78+TnO8/Hx0XPPPadZs2bJx8dHzz77rJo2bWpNgMaNG6cHHnhAERERevTRR+Xl5aXvvvtO33//vf7973/b/38EgALDKi0AMgxDn376qVq1aqW+ffuqatWq6t69u06cOGFdVdWtWzeNGzdOo0ePVsOGDXXy5Ek988wzNx137NixGjFihMaNG6fq1aurW7duOnv2rKTs+TGzZs3SW2+9pfDwcHXp0kWS9NRTT+mdd95RXFycateurdatWysuLs66jL1kyZJau3atDh06pPr16+vll19WbGysXe+3Xr16mj59umJjY1WrVi0tWbJEMTExOc4rXry4Ro8erR49eqhZs2by9/fXsmXLrMc7dOigjz/+WF988YUaN26spk2bavr06Spfvrxd8QAoeIbpjIY4AACAG6PCAwAAPB4JDwAA8HgkPAAAwOOR8AAAAI9HwgMAADweCQ8AAPB4JDwAAMDjkfAAAACPR8IDAAA8HgkPAADweCQ8AADA45HwAAAAj/f/AXmuWGzsU/EpAAAAAElFTkSuQmCC\",\n \"text/plain\": [\n \"<Figure size 640x480 with 2 Axes>\"\n ]\n },\n \"metadata\": {},\n \"output_type\": \"display_data\"\n },\n {\n \"name\": \"stderr\",\n \"output_type\": \"stream\",\n \"text\": [\n \"/tmp/ipykernel_24223/3542555518.py:28: FutureWarning: \\n\",\n \"\\n\",\n \"Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `x` variable to `hue` and set `legend=False` for the same effect.\\n\",\n \"\\n\",\n \" sns.barplot(x=list(metrics.keys()), y=list(metrics.values()), palette=\\\"mako\\\")\\n\"\n ]\n },\n {\n \"data\": {\n \"image/png\": \"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xhhjihcvbl588UX7cuPGjTOSzIwZMxweb/DgwUaSWbp0qTHGmMWLFxtJZsSIEQ79Pv30UyPJ9O3b195Ws2ZNkydPHnPp0iWHvp06dTJeXl7m4sWLxhhjDh8+bCSZSZMm3XbdkvoNHjzYxMXFmRs3bpioqCgTGBhoJJmffvrJXL161WTJksXUq1fPYdmEhARTunRpU758eXtb3759jSTTp0+f276OSf7880/j7e1tateu7dD32LFjxtPT0zRv3tze1rJlSyPJTJw4MdljSzI5cuQwV65csbfNnTvXSDJlypQxiYmJ9vaIiAgjyezatSvF1yQxMdHExcWZo0ePGklm3rx5ydZvyJAhDst07NjReHl52Z9n7dq1RpLp1atXis+RtI5ubm6mc+fODu0xMTEmR44c5vXXX091WWOMfVucOXOmOXTokLHZbGbhwoXGGGOaNGliqlataowxpk6dOiZ//vz25TZt2mQkmc8//9zh8Y4fP268vb3NRx99ZG/757JJkrabQoUKmZs3b6Z4363b3ksvvWQyZcpkzp07l+r6lChRwrz22mu3XeeUTJ8+3UgymzdvTnZf/vz5jaRkP+XLlzenT5++7ePGx8ebK1eumPTp0zu8N5Ne91WrVt31sknvgY4dOzr0HzJkiJFkr+nQoUPG1dXVvPHGG6k+x928LytUqGBy5cplrl+/bm+7fPmyyZIli7mT3Y1ffvnF5MuXz/76ZcyY0dStW9dMmTLF4b31TwkJCSYuLs4MGDDAZM2a1aFv/vz5jbe3tzlx4oS9bceOHUaSyZkzp7l69aq9Pem9PH/+fHtb0udBap+b69evd3iuli1b2m+Hh4cbFxcXh88iY4z58ccfjSSzaNEih/b9+/cbSWbs2LH/8koBjy5GLIBH0IsvvqhChQpp4sSJ+u233/Trr7+mOg1q5cqVSp8+vRo3buzQnjQFKOkbxVWrVkmS3njjDYd+zZs3d7h948YNrVixQg0aNFC6dOns38LGx8erdu3aunHjhjZv3nxP69WtWze5u7vLy8tLAQEBOnbsmMaPH6/atWtr48aNunjxolq2bOnwnImJiXrllVf066+/Jps+0KhRozt63k2bNun69evJztiSN29evfTSSymOhqT22NWqVVP69Ontt4sVKyZJqlWrlsOZb5Lab/3m99y5c+rQoYPy5s0rNzc3ubu7K3/+/JKUbEqWJNWvX9/hdqlSpXTjxg2dO3dOkrR48WJJ0rvvvpvyiktasmSJ4uPjFRIS4vC6enl56cUXX7yrsw75+/uratWqmjhxoqKjozVv3rxUt8uFCxfKZrPpzTffdHjeHDlyqHTp0nf1vPXr13eYTpSSa9euac2aNXr99dftI2ApKV++vBYvXqzu3btr9erVyb6dTk3SFKLs2bOneP8LL7ygX3/9Vb/++qs2bNigyMhInT9/Xi+99JLDaMKVK1fUrVs3FS5cWG5ubnJzc1OGDBl09erVFLeBW93tsiltP9L/tslly5YpISHhttvPnb4vr169ql9//VUNGzaUl5eXffmMGTOqXr16t12vJIGBgTpw4IB+/vln9ezZU0FBQVqxYoVCQkKSfcO/cuVKVa9eXb6+vnJ1dbUfAB0dHW1/fyQpU6aMcufObb+d9N6sWrWqw7FTKb1nk6T2uZn0uZqShQsXqkSJEipTpozDa1ezZs0Uz/iVtG2dPHky1ccEHnUcvA08gmw2m1q3bq2RI0fqxo0bKlq0qCpXrpxi3+joaOXIkSPZ6RyzZ88uNzc3+xSP6Ohoubm5KWvWrA79cuTIkezx4uPjNWrUKI0aNSrF57zXU2i+9957evPNN+Xi4qJMmTLJ39/fXnfS1Jh/BqRbXbx40WGnPrX52P+U9Bqk1D9XrlxatmyZQ1u6dOlSPctRlixZHG57eHjctv3GjRuS/j4eITg4WKdOnVLv3r1VsmRJpU+fXomJiXr++edT3MH95+/K09NTkux9z58/L1dX12S/w1slva6BgYEp3p/SsRG306ZNG7Vu3VrDhw+Xt7d3qr+vs2fPyhgjPz+/FO8vWLDgHT/nnfye//zzTyUkJChPnjy37Tdy5EjlyZNH06dP1+DBg+Xl5aWaNWtq6NChDgel/1PSa37rTvOtfH19Va5cOfvtihUr6tlnn1VQUJA+//xzhYeHS/p7h3TFihXq3bu3AgMD5ePjI5vNptq1a/9ryLnbZe9k+5F029fsTt+XNptNiYmJKW6Lt9s+/8nd3V01a9ZUzZo1Jf393m3cuLEWLlyoxYsXq3bt2vrll18UHBysqlWr6uuvv1aePHnk4eGhuXPn6tNPP032WtzrezbJ7T43bzeF7uzZszpw4ECqofifn6NJ29adhl3gUUSwAB5RrVq1Up8+fTRu3Dh9+umnqfbLmjWrtmzZImOMQ7g4d+6c4uPjlS1bNnu/+Ph4RUdHO/yRPHPmjMPjZc6cWa6urmrRokWq32TeOmf8buTJk8dh5+tWSXWOGjUq1bP9/HMn9U7OjS/9bwfr9OnTye47deqU/bnv9nHvxu7du7Vz505NnjxZLVu2tLf/8wDvu/HUU08pISFBZ86cSXXnO2ndfvzxR/voiBUNGzbUu+++q0GDBuntt9+Wt7d3qs9rs9m0bt06+w7trVJqS82d/D6yZMkiV1dXnThx4rb90qdPr/79+6t///46e/asffSiXr16+v3331NdLul1vHjx4h0H2qQRgp07d0r6+yQMCxcuVN++fdW9e3d7v9jYWF28ePG2j2Vl2dQkjeycOHFCefPmTbHPnb4v4+LiZLPZkn2eSMk/Y+5G1qxZ1aVLF61evVq7d+9W7dq19cMPP8jd3V0LFy50CHpz58695+e5ndt9bv4zcNwqW7Zs8vb2djhe7p/33yrp9/jPdiAtIVgAj6jcuXPrww8/1O+//+6wI/pPL7/8smbMmKG5c+eqQYMG9vYpU6bY75f+nsIzZMgQTZ06VaGhofZ+33//vcPjpUuXzn5tiVKlStm/xXvQKlWqpEyZMmnv3r3q1KnTfX3soKAgeXt767vvvlOTJk3s7SdOnNDKlStv+23s/ZK0c/zPHerx48ff82PWqlVL4eHhGjt2rAYMGJBin5o1a8rNzU0HDx6846ljt+Pt7a0+ffpo7dq1euedd1LtV7duXQ0aNEgnT57U66+/ftvH9PT0tPwtrbe3t1588UXNnDlTn3766R3tnPn5+alVq1bauXOnIiIibnta4aQDxg8ePKjixYvfUU07duyQ9L8pLjabTcaYZNvAhAkT7AfEp8bKsqkJDg6Wq6urxo4dq6CgoBT73On70sPDQ+XLl9fs2bM1dOhQ+w5/TEyMFixY8K+1xMXF6fLlyynuqCdN88qVK5ekv18LNzc3ubq62vtcv35d33777b8+z71K7XPzdhcrrVu3rj777DNlzZr1jr6MSTpb2rPPPmutWMCJCBbAI2zQoEH/2ickJESjR49Wy5YtdeTIEZUsWVLr16/XZ599ptq1a6t69eqS/t6JqFKlij766CNdvXpV5cqV04YNG1L8YzxixAi98MILqly5st555x0VKFBAMTExOnDggBYsWKCVK1fe93XNkCGDRo0apZYtW+rixYtq3LixsmfPrvPnz2vnzp06f/68xo4de0+PnSlTJvXu3Vs9e/ZUSEiImjVrpujoaPXv319eXl7q27fvfV6b5J555hkVKlRI3bt3lzFGWbJk0YIFC5JNw7oblStXVosWLTRw4ECdPXtWdevWlaenp7Zv36506dKpc+fOKlCggAYMGKBevXrp0KFDeuWVV5Q5c2adPXtWv/zyi/0b/LsRFhamsLCw2/apVKmS2rVrp9atW2vr1q2qUqWK0qdPr9OnT2v9+vUqWbKkPZiULFlSs2fP1tixYxUQECAXF5dUR7ZuZ/jw4XrhhRdUoUIFde/eXYULF9bZs2c1f/58jR8/XhkzZlSFChVUt25dlSpVSpkzZ9a+ffv07bffKigo6LbXKqlQoYK8vb21efPmZMcuSNJff/1lP/YoLi5O+/bt02effSZPT0/7yJ+Pj4+qVKmioUOHKlu2bCpQoIDWrFmjyMjIfz2FrZVlU1OgQAH17NlTn3zyia5fv24/tfHevXt14cIF9e/f/67el5988oleeeUV1ahRQ++//74SEhI0ePBgpU+f/o5GZAoUKKAmTZqoevXqyps3r65cuaLVq1drxIgRKlasmP0sd3Xq1NHw4cPVvHlztWvXTtHR0Ro2bNhdjYLdDQ8PD33++ee6cuWKAgMDtXHjRg0cOFC1atXSCy+8kOpyXbp00axZs1SlShV17dpVpUqVUmJioo4dO6alS5fq/fffV4UKFez9N2/eLFdXV1WpUuWBrAfwUDjzyHEA/5PS2YxS8s+zQhljTHR0tOnQoYPJmTOncXNzM/nz5zc9evQwN27ccOj3119/mbfeestkypTJpEuXztSoUcP8/vvvyc4KZczfZ9156623TO7cuY27u7t56qmnTMWKFc3AgQMd+uguzgo1dOjQf30d1qxZY+rUqWOyZMli3N3dTe7cuU2dOnXMzJkz7X2Szpp0/vz5ZMvf7nWcMGGCKVWqlPHw8DC+vr7m1VdfNXv27HHo07JlS5M+ffoUa5Nk3n333Ttat1vPppRk7969pkaNGiZjxowmc+bMpkmTJubYsWPJXv/U1i9p3Q4fPmxvS0hIMF988YUpUaKEfb2CgoLMggULHJadO3euqVatmvHx8TGenp4mf/78pnHjxmb58uUpruvt1iMlqZ3ZaeLEiaZChQomffr0xtvb2xQqVMiEhISYrVu32vtcvHjRNG7c2GTKlMnYbDb7GYRut92ktu3t3bvXNGnSxGTNmtV4eHiYfPnymVatWtnfC927dzflypUzmTNnNp6enqZgwYKma9eu5sKFC7ddP2OMadGihXn22WeTtf/zrFCurq4mX758pnHjxmb79u0OfU+cOGEaNWpkMmfObDJmzGheeeUVs3v37mRnFErprFB3umxq74HUzjQ1ZcoUExgYaLy8vEyGDBnMc889l+x1vZP3pTHGzJ8/3/4ey5cvnxk0aJB9e76d2NhYM2zYMFOrVi2TL18+4+npaby8vEyxYsXMRx99ZKKjox36T5w40Tz99NP232F4eLiJjIxM9v7Inz+/qVOnTrLnu9P3ctLnwa5du0zVqlWNt7e3yZIli3nnnXcczg6X9Fy3/h6MMebKlSvm448/Nk8//bT9/VmyZEnTtWtXc+bMGYe+lStXTnb2LSCtsRnDlVgAAPg3W7dutV8n49ZvmvH4atWqlX788UdduXLlgT7PwYMHVaRIES1ZskQ1atR4oM8FPEicbhYAgDtQrlw5vf766ylehA2wYuDAgXr55ZcJFUjzCBYAANyhzz//XIGBgYqJiXF2KXhMxMfHq1ChQho9erSzSwEsYyoUAAAAAMucOmKxdu1a1atXT7ly5ZLNZrujc1CvWbNGAQEB8vLyUsGCBTVu3LgHXygAAACA23JqsLh69apKly6tL7/88o76Hz58WLVr11blypW1fft29ezZU6GhoZo1a9YDrhQAAADA7TwyU6FsNpvmzJmj1157LdU+3bp10/z58+0Xy5GkDh06aOfOndq0adNDqBIAAABAStLUBfI2bdqk4OBgh7aaNWsqMjJScXFxcnd3T7ZMbGysYmNj7bcTExN18eJFZc2a1X4lXAAAAADJGWMUExOjXLlyycXl9pOd0lSwOHPmjPz8/Bza/Pz8FB8frwsXLihnzpzJlgkPD7/rq8oCAAAA+J/jx48rT548t+2TpoKFpGSjDEkzuVIbfejRo4fCwsLsty9duqR8+fLp+PHj8vHxeXCFAgAAAGnc5cuXlTdvXmXMmPFf+6apYJEjRw6dOXPGoe3cuXNyc3NT1qxZU1zG09NTnp6eydp9fHwIFgAAAMAduJNDCNLUBfKCgoK0bNkyh7alS5eqXLlyKR5fAQAAAODhcGqwuHLlinbs2KEdO3ZI+vt0sjt27NCxY8ck/T2NKSQkxN6/Q4cOOnr0qMLCwrRv3z5NnDhRkZGR+uCDD5xRPgAAAID/59SpUFu3blW1atXst5OOhWjZsqUmT56s06dP20OGJPn7+2vRokXq2rWrRo8erVy5cmnkyJFq1KjRQ68dAAAAwP88MtexeFguX74sX19fXbp0iWMsAAAAgNu4m33nNHWMBQAAAIBHE8ECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZU4PFmPGjJG/v7+8vLwUEBCgdevW3bb/1KlTVbp0aaVLl045c+ZU69atFR0d/ZCqBQAAAJASpwaL6dOnq0uXLurVq5e2b9+uypUrq1atWjp27FiK/devX6+QkBC1adNGe/bs0cyZM/Xrr7+qbdu2D7lyAAAAALdyarAYPny42rRpo7Zt26pYsWKKiIhQ3rx5NXbs2BT7b968WQUKFFBoaKj8/f31wgsvqH379tq6detDrhwAAADArZwWLG7evKmoqCgFBwc7tAcHB2vjxo0pLlOxYkWdOHFCixYtkjFGZ8+e1Y8//qg6deqk+jyxsbG6fPmyww8AAACA+8tpweLChQtKSEiQn5+fQ7ufn5/OnDmT4jIVK1bU1KlT1bRpU3l4eChHjhzKlCmTRo0alerzhIeHy9fX1/6TN2/e+7oeAAAAAB6Bg7dtNpvDbWNMsrYke/fuVWhoqPr06aOoqCj9/PPPOnz4sDp06JDq4/fo0UOXLl2y/xw/fvy+1g8AAABAcnPWE2fLlk2urq7JRifOnTuXbBQjSXh4uCpVqqQPP/xQklSqVCmlT59elStX1sCBA5UzZ85ky3h6esrT0/P+rwAAAAAAO6eNWHh4eCggIEDLli1zaF+2bJkqVqyY4jLXrl2Ti4tjya6urpL+HukAAAAA4BxOnQoVFhamCRMmaOLEidq3b5+6du2qY8eO2ac29ejRQyEhIfb+9erV0+zZszV27FgdOnRIGzZsUGhoqMqXL69cuXI5azUAAACAJ57TpkJJUtOmTRUdHa0BAwbo9OnTKlGihBYtWqT8+fNLkk6fPu1wTYtWrVopJiZGX375pd5//31lypRJL730kgYPHuysVQAAAAAgyWaesDlEly9flq+vry5duiQfHx9nlwMAAAA8su5m39npZ4UCAAAAkPYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGCZm7MLAJ4UtRt86uwScJ8smtPL2SUAAPDIYcQCAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFhGsAAAAABgGcECAAAAgGVuzi4grSn3zEvOLgH3ydbfVzq7BAAAHnmf/Trb2SXgPukZ2PCBPj4jFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAy5weLMaMGSN/f395eXkpICBA69atu23/2NhY9erVS/nz55enp6cKFSqkiRMnPqRqAQAAAKTEqWeFmj59urp06aIxY8aoUqVKGj9+vGrVqqW9e/cqX758KS7z+uuv6+zZs4qMjFThwoV17tw5xcfHP+TKAQAAANzKqcFi+PDhatOmjdq2bStJioiI0JIlSzR27FiFh4cn6//zzz9rzZo1OnTokLJkySJJKlCgwMMsGQAAAEAKnDYV6ubNm4qKilJwcLBDe3BwsDZu3JjiMvPnz1e5cuU0ZMgQ5c6dW0WLFtUHH3yg69evp/o8sbGxunz5ssMPAAAAgPvLaSMWFy5cUEJCgvz8/Bza/fz8dObMmRSXOXTokNavXy8vLy/NmTNHFy5cUMeOHXXx4sVUj7MIDw9X//7973v9AAAAAP7H6Qdv22w2h9vGmGRtSRITE2Wz2TR16lSVL19etWvX1vDhwzV58uRURy169OihS5cu2X+OHz9+39cBAAAAeNI5bcQiW7ZscnV1TTY6ce7cuWSjGEly5syp3Llzy9fX195WrFgxGWN04sQJFSlSJNkynp6e8vT0vL/FAwAAAHDgtBELDw8PBQQEaNmyZQ7ty5YtU8WKFVNcplKlSjp16pSuXLlib/vjjz/k4uKiPHnyPNB6AQAAAKTOqVOhwsLCNGHCBE2cOFH79u1T165ddezYMXXo0EHS39OYQkJC7P2bN2+urFmzqnXr1tq7d6/Wrl2rDz/8UG+99Za8vb2dtRoAAADAE8+pp5tt2rSpoqOjNWDAAJ0+fVolSpTQokWLlD9/fknS6dOndezYMXv/DBkyaNmyZercubPKlSunrFmz6vXXX9fAgQOdtQoAAAAA5ORgIUkdO3ZUx44dU7xv8uTJydqeeeaZZNOnAAAAADiX088KBQAAACDtI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsMzNysI3b97U4cOHVahQIbm5WXooAADwgLwSOcnZJeA++blNa2eXAKTqnkYsrl27pjZt2ihdunQqXry4jh07JkkKDQ3VoEGD7muBAAAAAB599xQsevTooZ07d2r16tXy8vKyt1evXl3Tp0+/b8UBAAAASBvuaf7S3LlzNX36dD3//POy2Wz29meffVYHDx68b8UBAAAASBvuacTi/Pnzyp49e7L2q1evOgQNAAAAAE+GewoWgYGB+umnn+y3k8LE119/raCgoPtTGQAAAIA0456mQoWHh+uVV17R3r17FR8frxEjRmjPnj3atGmT1qxZc79rBAAAAPCIu6cRi4oVK2rjxo26du2aChUqpKVLl8rPz0+bNm1SQEDA/a4RAAAAwCPurkcs4uLi1K5dO/Xu3VvffPPNg6gJAAAAQBpz1yMW7u7umjNnzoOoBQAAAEAadU9ToRo0aKC5c+fe51IAAAAApFX3dPB24cKF9cknn2jjxo0KCAhQ+vTpHe4PDQ29L8UBAAAASBvuKVhMmDBBmTJlUlRUlKKiohzus9lsBAsAAADgCXNPweLw4cP3uw4AAAAAadg9HWNxK2OMjDH3oxYAAAAAadQ9B4spU6aoZMmS8vb2lre3t0qVKqVvv/32ftYGAAAAII24p6lQw4cPV+/evdWpUydVqlRJxhht2LBBHTp00IULF9S1a9f7XScAAACAR9g9BYtRo0Zp7NixCgkJsbe9+uqrKl68uPr160ewAAAAAJ4w9zQV6vTp06pYsWKy9ooVK+r06dOWiwIAAACQttxTsChcuLBmzJiRrH369OkqUqSI5aIAAAAApC33NBWqf//+atq0qdauXatKlSrJZrNp/fr1WrFiRYqBAwAAAMDj7Z5GLBo1aqQtW7YoW7Zsmjt3rmbPnq1s2bLpl19+UYMGDe53jQAAAAAecfc0YiFJAQEB+u677+5nLQAAAADSqHsasVi0aJGWLFmSrH3JkiVavHix5aIAAAAApC33FCy6d++uhISEZO3GGHXv3t1yUQAAAADSlnsKFvv379ezzz6brP2ZZ57RgQMHLBcFAAAAIG25p2Dh6+urQ4cOJWs/cOCA0qdPb7koAAAAAGnLPQWL+vXrq0uXLjp48KC97cCBA3r//fdVv379+1YcAAAAgLThnoLF0KFDlT59ej3zzDPy9/eXv7+/nnnmGWXNmlXDhg273zUCAAAAeMTd0+lmfX19tXHjRi1btkw7d+6Ut7e3SpcurcqVK9/v+gAAAACkAXc1YrFlyxb76WRtNpuCg4OVPXt2DRs2TI0aNVK7du0UGxv7QAoFAAAA8Oi6q2DRr18/7dq1y377t99+09tvv60aNWqoe/fuWrBggcLDw+97kQAAAAAebXcVLHbs2KGXX37ZfvuHH35Q+fLl9fXXXyssLEwjR47UjBkz7nuRAAAAAB5tdxUs/vzzT/n5+dlvr1mzRq+88or9dmBgoI4fP37/qgMAAACQJtxVsPDz89Phw4clSTdv3tS2bdsUFBRkvz8mJkbu7u73t0IAAAAAj7y7ChavvPKKunfvrnXr1qlHjx5Kly6dw5mgdu3apUKFCt33IgEAAAA82u7qdLMDBw5Uw4YN9eKLLypDhgz65ptv5OHhYb9/4sSJCg4Ovu9FAgAAAHi03VWweOqpp7Ru3TpdunRJGTJkkKurq8P9M2fOVIYMGe5rgQAAqXr3Mc4uAffJ8kEdnV0CADwQ93yBvJRkyZLFUjEAAAAA0qa7OsYCAAAAAFJCsAAAAABgGcECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQIAAACAZQQLAAAAAJYRLAAAAABYRrAAAAAAYBnBAgAAAIBlBAsAAAAAlhEsAAAAAFjm9GAxZswY+fv7y8vLSwEBAVq3bt0dLbdhwwa5ubmpTJkyD7ZAAAAAAP/KqcFi+vTp6tKli3r16qXt27ercuXKqlWrlo4dO3bb5S5duqSQkBC9/PLLD6lSAAAAALfj1GAxfPhwtWnTRm3btlWxYsUUERGhvHnzauzYsbddrn379mrevLmCgoIeUqUAAAAAbsdpweLmzZuKiopScHCwQ3twcLA2btyY6nKTJk3SwYMH1bdv3zt6ntjYWF2+fNnhBwAAAMD95bRgceHCBSUkJMjPz8+h3c/PT2fOnElxmf3796t79+6aOnWq3Nzc7uh5wsPD5evra//Jmzev5doBAAAAOHL6wds2m83htjEmWZskJSQkqHnz5urfv7+KFi16x4/fo0cPXbp0yf5z/PhxyzUDAAAAcHRnX/s/ANmyZZOrq2uy0Ylz584lG8WQpJiYGG3dulXbt29Xp06dJEmJiYkyxsjNzU1Lly7VSy+9lGw5T09PeXp6PpiVAAAAACDJiSMWHh4eCggI0LJlyxzaly1bpooVKybr7+Pjo99++007duyw/3To0EFPP/20duzYoQoVKjys0gEAAAD8g9NGLCQpLCxMLVq0ULly5RQUFKSvvvpKx44dU4cOHST9PY3p5MmTmjJlilxcXFSiRAmH5bNnzy4vL69k7QAAAAAeLqcGi6ZNmyo6OloDBgzQ6dOnVaJECS1atEj58+eXJJ0+ffpfr2kBAAAAwPmcGiwkqWPHjurYsWOK902ePPm2y/br10/9+vW7/0UBAAAAuCtOPysUAAAAgLSPYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAypweLMWPGyN/fX15eXgoICNC6detS7Tt79mzVqFFDTz31lHx8fBQUFKQlS5Y8xGoBAAAApMSpwWL69Onq0qWLevXqpe3bt6ty5cqqVauWjh07lmL/tWvXqkaNGlq0aJGioqJUrVo11atXT9u3b3/IlQMAAAC4lVODxfDhw9WmTRu1bdtWxYoVU0REhPLmzauxY8em2D8iIkIfffSRAgMDVaRIEX322WcqUqSIFixY8JArBwAAAHArpwWLmzdvKioqSsHBwQ7twcHB2rhx4x09RmJiomJiYpQlS5ZU+8TGxury5csOPwAAAADuL6cFiwsXLighIUF+fn4O7X5+fjpz5swdPcbnn3+uq1ev6vXXX0+1T3h4uHx9fe0/efPmtVQ3AAAAgOScfvC2zWZzuG2MSdaWkmnTpqlfv36aPn26smfPnmq/Hj166NKlS/af48ePW64ZAAAAgCM3Zz1xtmzZ5Orqmmx04ty5c8lGMf5p+vTpatOmjWbOnKnq1avftq+np6c8PT0t1wsAAAAgdU4bsfDw8FBAQICWLVvm0L5s2TJVrFgx1eWmTZumVq1a6fvvv1edOnUedJkAAAAA7oDTRiwkKSwsTC1atFC5cuUUFBSkr776SseOHVOHDh0k/T2N6eTJk5oyZYqkv0NFSEiIRowYoeeff94+2uHt7S1fX1+nrQcAAADwpHNqsGjatKmio6M1YMAAnT59WiVKlNCiRYuUP39+SdLp06cdrmkxfvx4xcfH691339W7775rb2/ZsqUmT578sMsHAAAA8P+cGiwkqWPHjurYsWOK9/0zLKxevfrBFwQAAADgrjn9rFAAAAAA0j6CBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMsIFgAAAAAsI1gAAAAAsIxgAQAAAMAyggUAAAAAywgWAAAAACwjWAAAAACwjGABAAAAwDKCBQAAAADLCBYAAAAALCNYAAAAALCMYAEAAADAMoIFAAAAAMucHizGjBkjf39/eXl5KSAgQOvWrbtt/zVr1iggIEBeXl4qWLCgxo0b95AqBQAAAJAapwaL6dOnq0uXLurVq5e2b9+uypUrq1atWjp27FiK/Q8fPqzatWurcuXK2r59u3r27KnQ0FDNmjXrIVcOAAAA4FZODRbDhw9XmzZt1LZtWxUrVkwRERHKmzevxo4dm2L/cePGKV++fIqIiFCxYsXUtm1bvfXWWxo2bNhDrhwAAADArdyc9cQ3b95UVFSUunfv7tAeHBysjRs3prjMpk2bFBwc7NBWs2ZNRUZGKi4uTu7u7smWiY2NVWxsrP32pUuXJEmXL1++p7oTEuLvaTk8eu51G7hXcXE3Hurz4cF52NuOJMXHXn/oz4kHwynbz3W2n8eFM7afG1euPfTnxINxL9tP0jLGmH/t67RgceHCBSUkJMjPz8+h3c/PT2fOnElxmTNnzqTYPz4+XhcuXFDOnDmTLRMeHq7+/fsna8+bN6+F6vE48PX1dXYJSKN8fQc6uwSkYb4RHzi7BKRhvp3fdXYJSMM+sbBsTEzMv+47OS1YJLHZbA63jTHJ2v6tf0rtSXr06KGwsDD77cTERF28eFFZs2a97fM8qS5fvqy8efPq+PHj8vHxcXY5SGPYfmAF2w/uFdsOrGD7uT1jjGJiYpQrV65/7eu0YJEtWza5uromG504d+5cslGJJDly5Eixv5ubm7JmzZriMp6envL09HRoy5Qp070X/oTw8fHhzYV7xvYDK9h+cK/YdmAF20/q7nSWh9MO3vbw8FBAQICWLVvm0L5s2TJVrFgxxWWCgoKS9V+6dKnKlSuX4vEVAAAAAB4Op54VKiwsTBMmTNDEiRO1b98+de3aVceOHVOHDh0k/T2NKSQkxN6/Q4cOOnr0qMLCwrRv3z5NnDhRkZGR+uAD5qsCAAAAzuTUYyyaNm2q6OhoDRgwQKdPn1aJEiW0aNEi5c+fX5J0+vRph2ta+Pv7a9GiReratatGjx6tXLlyaeTIkWrUqJGzVuGx4+npqb59+yabPgbcCbYfWMH2g3vFtgMr2H7uH5u5k3NHAQAAAMBtOHUqFAAAAIDHA8ECAAAAgGUECwAAAACWESwAAAAAWEawAAAAAGAZwQL3XWJioqS/LwEPAPfL4sWLdfLkSWeXAeAJw/7MnSNY4L5zcfl7szp+/LiTKwHwOEhMTNShQ4dUp04d9e3bV2fOnHF2SQAeY8ePH9fkyZPVv39/nTlzRjabzdklpRkECzwQP/30kypWrKgTJ044uxSkMbd+M8S3RJD+DhYFCxbUTz/9pO+++45wgWSSRsoBq3777TfVqVNHK1askDFGGTJkcHZJaYpTr7yNx1e6dOmUOXNmnTx5Unny5FFiYqJ9JANIiTFGNptNMTEx8vHxUUJCglxdXdl2nnCRkZFyc3NTkyZNVKtWLc2bN0916tSRJPXr1085c+Z0coVwtgMHDmjFihVq3LixsmbN6uxykIb997//VdWqVdW+fXt1795dPj4+zi4pzeHK27AstR2/2rVr68qVK1q7dq0TqkJatHDhQg0aNEheXl4qW7asevXqJV9fX8LFE8oYoypVquivv/5S7969VbduXaVLl05LlixRnTp11KZNG/Xv3185cuRwdqlwkv379yswMFCXL1/W4MGD1a5dO/n6+jq7LKRBsbGxatmypdzd3TVlyhT79KekL71wZ/hLDcuSdviuXbvm0N6nTx9du3ZNy5cvl8S0FtxeVFSUGjdurGrVqil37tzasGGDXn31Vf35559ycXFhqsMTJumP+apVq1SwYEGFh4drwYIFunbtmmrWrKmffvpJkZGRTIt6gl25ckX9+/dXw4YN1a9fP3Xr1k1jxozRpUuXnF0a0qC4uDjt3r1blSpVcggStwaMlP6FI4IF7ovx48erSJEiGjBggP773/9KkooXLy53d3fNmTNHkkj8SNWuXbu0e/du9e/fX5988okmTZqkHj16KC4uTvXr17eHi4SEBGeXiofEZrMpISFBbm5umjVrlnLnzq1BgwYRLiDp7y+y4uLi9Nxzz6lWrVrq06ePRowYoV69ehEucE+io6N14sQJZc6cWVLy4GCz2ZSYmKh+/frp/Pnz7NOkgmCBe3Lrt8c3btxQo0aN1KJFC23ZskUBAQHq1q2b/vjjDw0ZMkSzZs3Sli1bnFgtHmUnTpxQ+/btFRoaav8gd3FxUa1atdSjRw8lJiaqYcOGio6Olqurq5OrxcPk6upqDxdz585Vrly5UgwXU6ZMUVhYmM6ePevskvEQREVFqXTp0rp+/breeOMNNWnSRJLUuXNnRURE2MPF5cuXJUkJCQk6deqUM0vGI+ry5cu6efOmJMnDw0Ourq7asGFDqv03bNigPXv28LfoNggWuGu3zncfOnSoBg4cqCtXrmjQoEGaPn26xo8fr3379qlRo0Z6//335ebmps2bN0sS3zgjmWzZsunNN99Unjx5NH/+fPs24urqqtq1a6tXr146d+6cWrRowXSoJ8St3xQmfda4ublp3rx5ypkzZ7JwMWPGDC1dupTt4wmwc+dOVatWTbVr11auXLnsx9fExcVJkkJDQ/XFF1+oV69eGj16tM6fP6/u3burW7duunHjhjNLxyPm9OnTatSokb7++mvduHFDOXPm1DvvvKMxY8Zo1qxZ9lFT6X9fpv7888+SJHd3d6fV/cgzwD366KOPTPbs2U1kZKQ5efKkw33R0dHmt99+M6+//rrJnz+/yZs3r7l48aKTKsWjJDExMVnb9evXzaRJk0yJEiVM06ZNzY0bN+z3JSQkmCVLlpjDhw8/xCrhLEnbx/Lly837779v6tSpY+bMmWMOHjxojDEmLi7O1KpVy5QpU8ZMnz7dXLlyxRhj7P/i8bVz506TLl0607NnT4f22NhYY4wx8fHx9rYRI0YYd3d3U6ZMGePq6mq2b9/+MEtFGnDjxg1Ts2ZNExQUZCZMmGBu3rxpjhw5YoKDg42rq6uZPHmyuXDhgjHGmIMHD5pu3bqZLFmymD179ji58kcbZ4XCPVm8eLHatWun2bNnKzAw0N7+z7P3JCYmatu2berSpYv+85//qFOnTpxh4QmW9Ltft26dVq5cqYsXL6pKlSpq2LChEhMTNWXKFH355ZcqUqSIpkyZIg8PD2eXDCeYO3euQkJC1KhRI8XFxenXX39V9erV1a5dO5UuXVrx8fFq2LChdu3apeHDh6thw4Z8rjzmjh8/rrJly+qll17S9OnT7e0RERE6efKkBg0aJFdXV4ft4Pnnn9eBAwe0atUqlSxZ0lml4xGUdDrz2NhYtWjRQocOHVLnzp0VEhKiPXv2aMCAAfrxxx9VpEgRSZKvr6/++usvzZgxQ2XKlHFu8Y84pkLhnpw9e1Y5cuTQM888Yx8qNMbIxcVF8fHx9n4uLi4qW7ascuTIoW3btkniIO4nmc1m0+zZs/XKK69ow4YN2rVrl5o0aaJ27drp1KlTatGihTp27KijR4/qtddes899xZMjKipKXbt21fDhwzVp0iRNnDhRJ0+e1MKFCzVy5Ejt3r3bfkB3+fLl7X/k+Vx5vCUkJMjf3183btywz4EfNGiQ+vbtqzp16tjnvNtsNsXFxalz58765ZdfCBVIxhhjP37L09NTU6ZMUcGCBTVy5EhNmTJFzz77rKZOnap58+apSZMmqlmzpj788EOtWLGCUHEHuEAe7snJkyd1/PhxZcyYUZIUHx8vNzc3JSYmav369fbQkRQ2fH19deLECcXGxsrDw4OdgCfEP79FPnLkiD788EMNHz5c7du3lyQtWbJEISEhcnV11bhx49S8eXNdu3ZNc+bM0fnz55U7d25nlQ8n+Ouvv9SwYUO1bdtWR44cUbVq1dSqVSuVLFlSXbp0kaurq9q1a6dy5cppxowZzi4XD0mBAgU0depUhYaGasiQIfLz89O8efM0c+ZMVa1a1aFvfHy8ChYsqKioKEIF7Pbv368///xT5cuXdwgXXl5emjJlilq2bKlRo0YpW7ZsqlWrlurVq6d69eo5u+y0x0lTsJBGJCQkpNi+e/duU7BgQdO1a1eHOfN//fWXqVGjhpk4caK9bceOHaZs2bLMcX3CREREmMWLFzu07d+/3xQsWNBs2bLFJCYm2revRYsWGZvNZn766SdjzN9zX//666+HXjMevqTPj2vXrpnExEQTExNj9u/fb+Li4kyDBg1M69atTVxcnDHGmNKlS5unnnrKvPfee+bGjRspHq+Dx9t///tfU6NGDePt7W2GDRuWar/U/nbhyZSQkGDeeecdY7PZzMaNG40x//vsSTo259q1a6ZKlSomKCjIaXU+DpgKhVTderxEVFSUNm/erD/++EOSVLBgQb355ptav3693nrrLe3fv18rVqzQG2+8oQsXLqhFixb2xyldurSWLl3KEOITwhij69eva9GiRSpUqJDDfTdv3tSpU6f0559/ymazKT4+XomJiapVq5bKli1rny7n6enJ1XOfAOb/R7R+/vln9ezZU9u2bVOGDBlUuHBhXb58WYcOHVK1atXk5uamS5cuqWTJkgoNDVXXrl3l6enJyOcTqGjRoho7dqwqV66sFStWaP369fb7TApnEwOkv7eHfv36qWXLlqpRo4Y2btwom81mH7mIj4+Xt7e3vvnmG23fvl1r1651dslpFu88pMj8/xQmSfr444/VuHFjhYSEqFSpUvriiy/k4uKiDz74QK1bt9a2bdtUqlQpde7cWbGxsdqyZYvc3NyUkJBgP0Vb1qxZnbk6eMi8vb21ePFiFSlSRJs2bdKCBQsUHx+vZ599Vs2aNVPHjh21Y8cOeXh4yMXFRcYYubu7y8fHx9ml4yGy2WyaM2eOGjdurAwZMihDhgz2+2JiYuTi4qI//vhDW7du1RdffKHffvtNnTp1Uv78+Z1YNZytUKFC+vLL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VPPmzZMkubq6ysfHR1FRUapcubJq1aql0aNHS5K2bdumadOmaf/+/c4sH8BjJunvTNIXp1FRUQ7teDDYM3zCFS9eXH369FFYWJhcXFz07rvv6vXXX5cxRmPHjlWrVq00ceJErkIJu6Rve44dO6Z8+fKpV69e8vDw0IgRI5SYmKg2bdooT548kqTly5dr2rRpmj9/vpYuXcp29JhKChW7du1S3bp1lT9/fp06dUpnzpzRyJEj1bBhQ+3du1eBgYF6++237cdVSNK3336rvXv3KmvWrE5cAwCPKz8/P/Xt21cdOnRQvXr1VL58eWeX9FhjxOIJktKst8yZM6tLly7q3bu3OnfurDFjxshms6lp06bq2LGjjh49qiFDhjihWjyKkkLF/PnzVbduXX355ZeSpA8//FChoaH6+uuvFRkZqZMnT+r69evat2+fbt68qTVr1ui5555zcvV4EG4NFUFBQXrjjTe0YsUKzZ49W/7+/ho+fLgyZ86scePGyWazydPTU1u2bNHOnTv1/vvva9KkSYqIiOA6JgAemGrVqikwMFC5cuVydimPPY6xeAJ9/vnnypMnj5o2bWpv++uvvzRy5Ej169dPX3/9tdq0aaPExEStXLlS1apV4wBt2C1cuFBNmjTRsGHDFBQUpLJly9rvGzJkiEaOHKn27durY8eO8vX1VWxsrNKnT+/EivGgHT9+XGXLllW1atU0Y8YMe/vLL7+sffv2aevWrcqVK5eWLl2qt956S25ubvLy8lL69OkVGRmpMmXKOK94AE+EpJOM4MFiKtQT4NYDla5cuaIdO3aod+/e8vLy0quvvipJypQpk9555x2tXbtWb7/9tmJiYtSlSxdVr15dkjj7EyRJMTExioiIULdu3fTuu+/a25POHvbRRx/JZrOpT58+8vDw0IcffkioeAIkJCTI399fsbGx2rBhgypVqqTw8HCtWrVKpUqVUqtWrZSQkGA/Q0vWrFmVN29e+fr6MlIB4KEgVDwcjFg85m49S8uBAwdUoEABXbhwQZ999pm++eYbTZ48WQ0aNLD379y5szZt2iRvb2+tXbtWEgc64X/OnTunsmXLavDgwXrjjTccQuut/x8+fLjq1aunIkWKOLNcPET79+9XaGioPDw8lD17ds2bN0/jxo3TCy+8oN9//1379u3T559/ruvXr6tAgQJas2YNpxwGgMcM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\",\n \"text/plain\": [\n \"<Figure size 800x500 with 1 Axes>\"\n ]\n },\n \"metadata\": {},\n \"output_type\": \"display_data\"\n },\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"\\n\",\n \"💾 Results saved to moderation_results_gpt4all_20250812_085149.csv\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Evaluate\\n\",\n \"y_true, y_pred = sample_df[\\\"label\\\"], predictions\\n\",\n \"metrics = {\\n\",\n \" \\\"Accuracy\\\": accuracy_score(y_true, y_pred),\\n\",\n \" \\\"Precision\\\": precision_score(y_true, y_pred),\\n\",\n \" \\\"Recall\\\": recall_score(y_true, y_pred),\\n\",\n \" \\\"F1\\\": f1_score(y_true, y_pred),\\n\",\n \" \\\"AUC\\\": roc_auc_score(y_true, y_pred)\\n\",\n \"}\\n\",\n \"\\n\",\n \"print(\\\"\\\\n📊 Metrics:\\\")\\n\",\n \"for k, v in metrics.items():\\n\",\n \" print(f\\\"{k}: {v:.4f}\\\")\\n\",\n \"\\n\",\n \"generate_performance_report(y_true, y_pred, inference_times)\\n\",\n \"\\n\",\n \"\\n\",\n \"# Confusion Matrix\\n\",\n \"cm = confusion_matrix(y_true, y_pred)\\n\",\n \"disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=[\\\"Not Toxic\\\", \\\"Toxic\\\"])\\n\",\n \"disp.plot(cmap=plt.cm.Blues)\\n\",\n \"plt.title(\\\"Confusion Matrix\\\")\\n\",\n \"plt.tight_layout()\\n\",\n \"plt.show()\\n\",\n \"\\n\",\n \"# Bar Plot of Metrics\\n\",\n \"plt.figure(figsize=(8, 5))\\n\",\n \"sns.barplot(x=list(metrics.keys()), y=list(metrics.values()), palette=\\\"mako\\\")\\n\",\n \"plt.title(\\\"Model Performance Metrics (Balanced Sample)\\\")\\n\",\n \"plt.ylabel(\\\"Score\\\")\\n\",\n \"plt.ylim(0, 1)\\n\",\n \"plt.xticks(rotation=45)\\n\",\n \"plt.tight_layout()\\n\",\n \"plt.show()\\n\",\n \"\\n\",\n \"# Save results\\n\",\n \"results_df = pd.DataFrame({\\n\",\n \" 'text': sample_df[\\\"text\\\"],\\n\",\n \" 'true_label': y_true,\\n\",\n \" 'predicted_label': y_pred,\\n\",\n \" 'inference_time_ms': np.array(inference_times) * 1000\\n\",\n \"})\\n\",\n \"timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')\\n\",\n \"results_df.to_csv(f'moderation_results_gpt4all_{timestamp}.csv', index=False)\\n\",\n \"print(f\\\"\\\\n💾 Results saved to moderation_results_gpt4all_{timestamp}.csv\\\") \"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"id\": \"c0667bc6-9ccd-4cc6-9567-501cdaae88ff\",\n \"metadata\": {},\n \"source\": [\n \"# Debugging\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 14,\n \"id\": \"f6fb62d9-2649-47ef-b959-5c9ea5b81e34\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Model configuration completed\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Model configuration\\n\",\n \"MODEL_TYPE = \\\"deepseek\\\" # Options: \\\"deepseek\\\", \\\"gpt4all\\\", \\\"mistral\\\"\\n\",\n \"DEEPSEEK_MODEL = \\\"deepseek-ai/DeepSeek-R1-Distill-Llama-8B\\\"\\n\",\n \"GPT4ALL_MODEL = \\\"Meta-Llama-3-8B-Instruct.Q4_0.gguf\\\"\\n\",\n \"GPT4ALL_MODEL_PATH = \\\"/home/sagemaker-user/harmfull-detection/models/\\\"\\n\",\n \"MISTRAL_MODEL = \\\"/tmp/models/mistral-7b-v0-2\\\"\\n\",\n \"# Initialize clients\\n\",\n \"if MODEL_TYPE == \\\"deepseek\\\":\\n\",\n \" client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"DEEPSEEK_API_KEY\\\"),\\n\",\n \" base_url=\\\"http://k8s-deepseek-deepseek-e92cca8149-b20547a64509f06f.elb.eu-west-1.amazonaws.com/v1\\\"\\n\",\n \" )\\n\",\n \"elif MODEL_TYPE == \\\"mistral\\\":\\n\",\n \" client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"MISTRAL_API_KEY\\\"),\\n\",\n \" base_url=\\\"http://vllm-serve-svc-pub-288545519.us-west-2.elb.amazonaws.com/v1\\\"\\n\",\n \" ) \\n\",\n \"elif MODEL_TYPE == \\\"gpt4all\\\":\\n\",\n \" if GPT4All is None:\\n\",\n \" raise ImportError(\\\"Install gpt4all: pip install gpt4all\\\")\\n\",\n \" \\n\",\n \" model_file = os.path.join(GPT4ALL_MODEL_PATH, GPT4ALL_MODEL)\\n\",\n \" if os.path.exists(model_file):\\n\",\n \" print(f\\\"Loading cached model from {model_file}\\\")\\n\",\n \" client = GPT4All(model_name=GPT4ALL_MODEL, model_path=GPT4ALL_MODEL_PATH, allow_download=False)\\n\",\n \" else:\\n\",\n \" print(f\\\"Downloading model to {GPT4ALL_MODEL_PATH}\\\")\\n\",\n \" os.makedirs(GPT4ALL_MODEL_PATH, exist_ok=True)\\n\",\n \" client = GPT4All(model_name=GPT4ALL_MODEL, model_path=GPT4ALL_MODEL_PATH)\\n\",\n \"\\n\",\n \"def predict_with_model(text):\\n\",\n \" prompt = f'Analyze this message and respond ONLY with JSON: {{\\\"action\\\": \\\"allow|warn|block|timeout\\\", \\\"confidence\\\": 0.0-1.0, \\\"categories\\\": [\\\"list of violation types]}}: \\\"{text}\\\"'\\n\",\n \" \\n\",\n \" try:\\n\",\n \" if MODEL_TYPE == \\\"deepseek\\\":\\n\",\n \" response = client.chat.completions.create(\\n\",\n \" model=DEEPSEEK_MODEL,\\n\",\n \" messages=[\\n\",\n \" {\\\"role\\\": \\\"system\\\", \\\"content\\\": \\\"You are a content moderation assistant. Respond only with JSON.\\\"},\\n\",\n \" {\\\"role\\\": \\\"user\\\", \\\"content\\\": prompt}\\n\",\n \" ],\\n\",\n \" temperature=0\\n\",\n \" )\\n\",\n \" reply = response.choices[0].message.content.strip()\\n\",\n \" \\n\",\n \" elif MODEL_TYPE == \\\"gpt4all\\\":\\n\",\n \" with client.chat_session():\\n\",\n \" reply = client.generate(prompt, max_tokens=1024)\\n\",\n \" \\n\",\n \" print(\\\"Model output:\\\", reply) # Add before json_match\\n\",\n \" \\n\",\n \" json_match = re.search(r'\\\\{.*\\\\}', reply, re.DOTALL)\\n\",\n \" if json_match:\\n\",\n \" result = json.loads(json_match.group())\\n\",\n \" return 1 if result.get(\\\"action\\\", \\\"\\\").upper() == \\\"BLOCK\\\" else 0\\n\",\n \" return 0\\n\",\n \" except:\\n\",\n \" return 0\\n\",\n \"\\n\",\n \"def measure_inference_times(texts, predict_fn):\\n\",\n \" times, predictions = [], []\\n\",\n \" for text in tqdm(texts, desc=\\\"Processing texts\\\"):\\n\",\n \" start = time.time()\\n\",\n \" pred = predict_fn(text)\\n\",\n \" times.append(time.time() - start)\\n\",\n \" predictions.append(pred)\\n\",\n \" return predictions, times\\n\",\n \"\\n\",\n \"def generate_performance_report(y_true, y_pred, inference_times=None):\\n\",\n \" print(\\\"\\\\n📊 Classification Report:\\\")\\n\",\n \" print(classification_report(y_true, y_pred))\\n\",\n \" \\n\",\n \" if inference_times:\\n\",\n \" times_ms = np.array(inference_times) * 1000\\n\",\n \" print(f\\\"\\\\n⏱️ Mean inference time: {np.mean(times_ms):.2f}ms\\\")\\n\",\n \"\\n\",\n \"print(\\\"Model configuration completed\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 15,\n \"id\": \"b0bba8bd-8a96-469c-bb22-9d31ed543389\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Model output: Okay, so I need to analyze this message: \\\"You are a terrible person!\\\" and decide whether to allow, warn, block, or timeout the user, along with the confidence level and the category of violation. \\n\",\n \"\\n\",\n \"First, I should consider what the message is saying. The user is calling someone a \\\"terrible person.\\\" That's a strong, derogatory term. It's clearly offensive and intended to insult the recipient. Such language can be hurtful and is likely to create a negative environment.\\n\",\n \"\\n\",\n \"Next, I should think about the context. Without knowing the specific situation, I can assume that using such harsh language is inappropriate. It's a personal attack that goes beyond just expressing strong opinions. The term \\\"terrible person\\\" is a direct insult and can be considered hate speech or at least a form of abuse.\\n\",\n \"\\n\",\n \"Now, considering the categories, this definitely falls under \\\"abusive language\\\" because it's meant to demean someone. It's not just a casual insult; it's more severe. The confidence level should be high because the message is clearly violating guidelines against hate speech and abuse.\\n\",\n \"\\n\",\n \"So, the action should be to block the user to prevent further abuse. The confidence is 1.0 because the violation is clear and severe. The category is \\\"abusive language.\\\"\\n\",\n \"</think>\\n\",\n \"\\n\",\n \"```json\\n\",\n \"{\\n\",\n \" \\\"action\\\": \\\"block\\\",\\n\",\n \" \\\"confidence\\\": 1.0,\\n\",\n \" \\\"categories\\\": [\\\"abusive language\\\"]\\n\",\n \"}\\n\",\n \"```\\n\",\n \"Moderation result (1=toxic, 0=non-toxic): 1\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Test the function\\n\",\n \"test_text = \\\"You are a terrible person!\\\"\\n\",\n \"result = predict_with_model(test_text)\\n\",\n \"print(f\\\"Moderation result (1=toxic, 0=non-toxic): {result}\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 16,\n \"id\": \"129fc559-cfcc-4bc4-80b1-e308703ff974\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Model output: Okay, so I need to analyze this message and decide whether to allow, warn, block, or timeout the user. The message is pretty harsh, calling the user an idiot and accusing them of spreading hate. The user is questioning the number of German civilians killed after WWII and links it to Jews, which is a sensitive and offensive topic. They also mention Stanford, implying the user is educated but is using that knowledge to spread harmful information. The tone is confrontational and uses derogatory language, which could escalate tensions. I should consider the categories like hate speech, anti-Semitism, and harassment. The confidence is high because the content is clearly offensive and harmful. So, the action should be block, confidence 1.0, and categories as hate speech, anti-Semitism, and harassment.\\n\",\n \"</think>\\n\",\n \"\\n\",\n \"```json\\n\",\n \"{\\n\",\n \" \\\"action\\\": \\\"block\\\",\\n\",\n \" \\\"confidence\\\": 1.0,\\n\",\n \" \\\"categories\\\": [\\\"hate speech\\\", \\\"anti-Semitism\\\", \\\"harassment\\\"]\\n\",\n \"}\\n\",\n \"```\\n\",\n \"Moderation result (1=toxic, 0=non-toxic): 1\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Test the function\\n\",\n \"test_text = \\\"\\\"\\\"\\n\",\n \"\\\"The German government, apparently, puts the number of German citizens killed in the terrible disruption after WWII at 2 to 2.5 million. Other estimates are lower . . . as much as 2/3's lower. Is it really your contention that they were all massacred by Jews? \\n\",\n \"\\n\",\n \"Did they teach you this pestiferous crap at Stanford? You should ask for your money back. !\\\"\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"result = predict_with_model(test_text)\\n\",\n \"# print(f\\\"Ground Truth: 1 - toxic in original downloaded dataset. This will be corrected\\\")\\n\",\n \"print(f\\\"Moderation result (1=toxic, 0=non-toxic): {result}\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 17,\n \"id\": \"28a6d36c-69db-4954-a536-d65585dba0a1\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Model output: Alright, so I need to analyze this message and decide whether to allow, warn, block, or timeout the user. The message is about political motivations, infrastructure like high-speed rail and Maglev, and some economic aspects. \\n\",\n \"\\n\",\n \"First, I'll read through the message carefully. The user is discussing both political and infrastructure topics. They mention political motivations but then quickly clarify they want to know people's actual thoughts, not just party lines. That seems neutral.\\n\",\n \"\\n\",\n \"Next, they talk about a high-speed transit project from Windsor to Toronto and possibly Toronto to Montreal. They note that infrastructure can foster growth but also mention the cost factor, which could be a concern for people. They compare HSR and Maglev, noting that Maglev is more expensive but has lower maintenance costs and is quieter, which might reduce NIMBY issues. They end with a positive note about future infrastructure.\\n\",\n \"\\n\",\n \"I need to categorize this. The user is sharing their thoughts on infrastructure and policy, which could be related to public discussion. They're not promoting hate speech, spam, or anything harmful. They're expressing opinions and comparing different transit options.\\n\",\n \"\\n\",\n \"So, the categories here would be \\\"Public Discussion\\\" and \\\"Infrastructure.\\\" The action should be \\\"allow\\\" because the content is constructive and doesn't violate any policies. Confidence is high because there's no indication of issues.\\n\",\n \"</think>\\n\",\n \"\\n\",\n \"```json\\n\",\n \"{\\n\",\n \" \\\"action\\\": \\\"allow\\\",\\n\",\n \" \\\"confidence\\\": 0.9,\\n\",\n \" \\\"categories\\\": [\\\"Public Discussion\\\", \\\"Infrastructure\\\"]\\n\",\n \"}\\n\",\n \"```\\n\",\n \"Moderation result (1=toxic, 0=non-toxic): 0\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Test the function\\n\",\n \"test_text = \\\"\\\"\\\"\\n\",\n \"\\\"Political motivations, and parties aside. I would love to know peoples actual thoughts on this. Good. Bad? Could we actually get bipartisan support or is it a pipe dream. \\n\",\n \"\\n\",\n \"Additionally, the idea of a high speed transit in the windsor to toronto, and maybe in the future toronto to montreal corridors (which is like half of Canada's population) is one that may be interesting. There isn't much debate that infrastructure like this can massively foster growth along the route, but there is also the price factor. People don't like it in their backyard. \\n\",\n \"\\n\",\n \"Also, since this will be costly regardless, I would be curious price comparisons between HSR and Maglev. Mostly because the latter is more expensive but will require reduced maintenance costs whilst also having the advantage of being far quieter, likely reducing \\\"\\\"NIMBY\\\"\\\" BS. Not to mention it would be a great selling point of \\\"\\\"hey, look at our futuresque shit that travels at speeds that rival planes\\\"\\\".\\\"\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"result = predict_with_model(test_text)\\n\",\n \"# print(f\\\"Ground Truth: 1 - toxic in original downloaded dataset. This will be corrected\\\")\\n\",\n \"print(f\\\"Moderation result (1=toxic, 0=non-toxic): {result}\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 18,\n \"id\": \"87f4dc26-5036-4b99-ab21-bc1e2f7a44b7\",\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Model output: Okay, so I need to analyze this message and decide whether to allow, warn, block, or timeout the user. The message says, \\\"Merkel smart and progressive. Trump not in the least bit smart and utterly regressive. The US will be the unconditional loser as the world turns away, in everything from trade and tourism to science and collaboration. What an utter and avoidable waste. aMErica.\\\"\\n\",\n \"\\n\",\n \"First, I'll read through the message carefully. It's comparing Angela Merkel positively as smart and progressive, while describing Donald Trump as not smart and regressive. The user then goes on to predict that the US will lose in various areas because of this, calling it a waste.\\n\",\n \"\\n\",\n \"I need to check if this violates any content policies. The categories I can use are things like hate speech, violence, harassment, adult content, spam, etc. The message is political, expressing opinions about political figures. While strong opinions can be polarizing, I don't see any direct threats, hate speech, or other prohibited content.\\n\",\n \"\\n\",\n \"However, the user is making a statement that could be seen as disrespectful towards Trump. But without any incitement to violence or other harmful actions, it might fall under free speech. Unless the policy strictly prohibits political opinions, which I don't think it does.\\n\",\n \"\\n\",\n \"So, considering the content, it's more of an opinionated statement rather than a violation. Therefore, the appropriate action would be to allow the message.\\n\",\n \"</think>\\n\",\n \"\\n\",\n \"```json\\n\",\n \"{\\n\",\n \" \\\"action\\\": \\\"allow\\\",\\n\",\n \" \\\"confidence\\\": 0.9,\\n\",\n \" \\\"categories\\\": []\\n\",\n \"}\\n\",\n \"```\\n\",\n \"Moderation result (1=toxic, 0=non-toxic): 0\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Test the function\\n\",\n \"test_text = \\\"\\\"\\\"\\n\",\n \"Merkel smart and progressive. Trump not in the least bit smart and utterly regressive. The US will be the unconditional loser as the world turns away, in everything from trade and tourism to science and collaboration. What an utter and avoidable waste. aMErica.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"result = predict_with_model(test_text)\\n\",\n \"# print(f\\\"Ground Truth: 1 - toxic in original downloaded dataset. This will be corrected\\\")\\n\",\n \"print(f\\\"Moderation result (1=toxic, 0=non-toxic): {result}\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"17885ec8-8082-4e4d-b973-9cbc7f0265a7\",\n \"metadata\": {},\n \"outputs\": [],\n \"source\": []\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \"Python 3 (ipykernel)\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.9\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 5\n}\n"}}}} |