lamalunderscore commited on
Commit
045caa8
·
1 Parent(s): 6f9479e

Merge of Content Moderation and Jailbreak leaderboard

Browse files
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .venv/
2
+ **/__pycache__
3
+ *.egg-info
4
+ **.DS_Store
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 🔥
4
  colorFrom: green
5
  colorTo: red
6
  sdk: gradio
7
- sdk_version: 6.8.0
8
  app_file: app.py
9
  pinned: false
10
  license: cc-by-nc-sa-4.0
 
4
  colorFrom: green
5
  colorTo: red
6
  sdk: gradio
7
+ sdk_version: 6.0.2
8
  app_file: app.py
9
  pinned: false
10
  license: cc-by-nc-sa-4.0
app.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from content_moderation import build_cm_tab
3
+ from jailbreak import build_jailbreak_tab
4
+ from shared import GLOBAL_CSS, build_footer
5
+
6
+
7
+ with gr.Blocks() as demo:
8
+ gr.HTML(GLOBAL_CSS)
9
+
10
+ gr.Markdown("# BELLS-O Leaderboard")
11
+
12
+ with gr.Column(elem_classes=["intro-section"]):
13
+ gr.Markdown(
14
+ """
15
+ **BELLS-O** stands for **Benchmark for the Evaluation of LLM Supervision Systems – Operational**. It is the first operational benchmark that systematically evaluates the operation cost of running LLM guardrails.
16
+
17
+ This benchmark tests specialized guardrails as well as generalist LLMs across Input and Output Content Moderation, as well as Jailbreak detection.
18
+ """
19
+ )
20
+
21
+ with gr.Tabs():
22
+ with gr.Tab("Content Moderation - Input"):
23
+ build_cm_tab("input")
24
+
25
+ with gr.Tab("Content Moderation - Output"):
26
+ build_cm_tab("output")
27
+
28
+ with gr.Tab("Jailbreak"):
29
+ build_jailbreak_tab()
30
+
31
+ build_footer()
32
+
33
+ if __name__ == "__main__":
34
+ demo.launch()
cesia_logo.png ADDED
content_moderation.py ADDED
@@ -0,0 +1,625 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from pathlib import Path
3
+ from typing import Any, Dict, List
4
+
5
+ import gradio as gr
6
+ import pandas as pd
7
+
8
+ from shared import (
9
+ CATEGORY_TABLE_CSS,
10
+ DEFAULT_WEIGHTS,
11
+ LEADERBOARD_DARK_MODE_CSS,
12
+ LEADERBOARD_TABLE_CSS,
13
+ build_pareto_figure,
14
+ build_weights,
15
+ create_empty_pareto_figure,
16
+ create_weight_bar_html,
17
+ escape_html,
18
+ get_color_for_accuracy,
19
+ sort_by_overall_score,
20
+ )
21
+
22
+ # ── Data loading ────────────────────────────────────────────────────────
23
+
24
+ _DATA_DIR = Path(__file__).parent / "data"
25
+
26
+ def _load_metrics() -> Dict[str, Any]:
27
+ metrics_path = _DATA_DIR / "content_moderation_metrics.json"
28
+ if not metrics_path.exists():
29
+ print(f"Warning: {metrics_path} not found")
30
+ return {}
31
+ with open(metrics_path, "r") as f:
32
+ return json.load(f)
33
+
34
+ METRICS_DATA = _load_metrics()
35
+
36
+
37
+ # ── Constants ───────────────────────────────────────────────────────────
38
+
39
+ CATEGORY_LABELS = {
40
+ "hate speech": "Hate Speech",
41
+ "harmful manipulation": "Harmful Manipulation",
42
+ "privacy": "Privacy",
43
+ "cyber": "Cyber",
44
+ "physical harm": "Physical Harm",
45
+ "sexual content": "Sexual Content",
46
+ "integrity & quality violations": "Integrity & Quality",
47
+ "cbrn": "CBRN",
48
+ "illegal activities": "Illegal Activities",
49
+ "self-harm": "Self-Harm",
50
+ "harm to minors": "Harm to Minors",
51
+ }
52
+
53
+ DATASET_DESCRIPTIONS: Dict[str, Dict[str, Any]] = {
54
+ "input": {
55
+ "url": "https://huggingface.co/datasets/bells-o-project/content-moderation-input",
56
+ "label": "BELLS-O Content Moderation Input Dataset",
57
+ "summary": "This dataset contains 1,400 samples across 11 harm categories for evaluating input content moderation. It includes 300 benign prompts (for FPR evaluation) and 1,100 harmful prompts (100 per category). Samples were constructed using three methods: AI-generated (27%), extracted from existing datasets (44%), and handcrafted by experts (29%).",
58
+ "categories": {cat_key: "" for cat_key in CATEGORY_LABELS},
59
+ "accuracy_categories": list(CATEGORY_LABELS.keys()),
60
+ "fpr_categories": ["benign"],
61
+ },
62
+ "output": {
63
+ "url": "https://huggingface.co/datasets/bells-o-project/content-moderation-output",
64
+ "label": "BELLS-O Content Moderation Output Dataset",
65
+ "summary": "This dataset contains 1,400 samples across 11 harm categories for evaluating output content moderation. It includes 300 benign outputs (for FPR evaluation) and 1,100 harmful outputs (100 per category). Samples were constructed using three methods: AI-generated (27%), extracted from existing datasets (44%), and handcrafted by experts (29%).",
66
+ "categories": {cat_key: "" for cat_key in CATEGORY_LABELS},
67
+ "accuracy_categories": list(CATEGORY_LABELS.keys()),
68
+ "fpr_categories": ["benign"],
69
+ },
70
+ }
71
+
72
+
73
+ def create_dataset_info_html(dataset_type: str) -> str:
74
+ """Create an HTML info box describing the selected dataset."""
75
+ info = DATASET_DESCRIPTIONS.get(dataset_type)
76
+ if not info:
77
+ return ""
78
+
79
+ ds_label = info.get("label", dataset_type)
80
+ url = info.get("url", "")
81
+ summary = info.get("summary", "")
82
+ categories = info.get("categories", {})
83
+ accuracy_categories = info.get("accuracy_categories", [])
84
+ fpr_categories = info.get("fpr_categories", [])
85
+
86
+ title_html = f'<a href="{url}" target="_blank">{ds_label}</a>' if url else ds_label
87
+
88
+ html = """<style>
89
+ .ds-info-box {
90
+ background: #f8fafc;
91
+ border: 1px solid #e2e8f0;
92
+ border-radius: 8px;
93
+ padding: 16px;
94
+ margin: 12px 0;
95
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
96
+ }
97
+ .ds-info-box .ds-title { margin: 0 0 8px 0 !important; padding: 0 !important; color: #1e293b; }
98
+ .ds-info-box .ds-title a { color: #1e293b; text-decoration: underline; }
99
+ .ds-info-box .ds-text { color: #475569; font-size: 14px; }
100
+ .ds-info-box .ds-cat-item { color: #475569; font-size: 13px; margin-bottom: 2px; }
101
+ @media (prefers-color-scheme: dark) {
102
+ .ds-info-box {
103
+ background: #2a2a2a !important;
104
+ border-color: #4a4a4a !important;
105
+ }
106
+ .ds-info-box .ds-title,
107
+ .ds-info-box .ds-title a { color: #f3f4f6 !important; }
108
+ .ds-info-box .ds-text { color: #d1d5db !important; }
109
+ .ds-info-box .ds-cat-item { color: #d1d5db !important; }
110
+ }
111
+ </style>"""
112
+
113
+ html += f'<div class="ds-info-box"><h4 class="ds-title">{title_html}</h4>'
114
+
115
+ if summary:
116
+ html += f'<p class="ds-text" style="margin:0 0 8px 0;">{summary}</p>'
117
+
118
+ # Only show categories list if descriptions are non-empty
119
+ non_empty_cats = {k: v for k, v in categories.items() if v}
120
+ if non_empty_cats:
121
+ html += '<div style="margin-top:8px;"><strong class="ds-text">Categories:</strong>'
122
+ html += '<ul style="margin:4px 0 0 0; padding-left:20px; list-style:none;">'
123
+ for cat_key, cat_desc in non_empty_cats.items():
124
+ cat_label = CATEGORY_LABELS.get(cat_key, cat_key)
125
+ html += f'<li class="ds-cat-item"><strong>{cat_label}:</strong> {cat_desc}</li>'
126
+ html += "</ul></div>"
127
+
128
+ if accuracy_categories:
129
+ cat_names = ", ".join(CATEGORY_LABELS.get(c, c) for c in accuracy_categories)
130
+ html += f'<p class="ds-text" style="margin:8px 0 0 0;"><strong>Detection Rate from:</strong> {cat_names}</p>'
131
+
132
+ if fpr_categories:
133
+ cat_names = ", ".join(CATEGORY_LABELS.get(c, c) for c in fpr_categories)
134
+ html += f'<p class="ds-text" style="margin:4px 0 0 0;"><strong>FPR from:</strong> {cat_names}</p>'
135
+
136
+ html += "</div>"
137
+ return html
138
+
139
+
140
+ # ── Data helpers ────────────────────────────────────────────────────────
141
+
142
+ def filter_metrics_by_dataset(dataset_type: str) -> Dict[str, Any]:
143
+ dataset_name = f"bells-o-project-content-moderation-{dataset_type}"
144
+ return {k: v for k, v in METRICS_DATA.items() if v.get("dataset_name") == dataset_name}
145
+
146
+
147
+ def prepare_leaderboard_data(selected_categories: List[str] | None = None, dataset_type: str = "input") -> pd.DataFrame:
148
+ metrics_data = filter_metrics_by_dataset(dataset_type)
149
+
150
+ if not metrics_data:
151
+ return pd.DataFrame(
152
+ columns=[
153
+ "Model Snapshot", "Model Developer", "Provider", "Detection Rate (%)",
154
+ "FPR (%)", "Latency CI 95% (ms)", "Mean Latency (ms)", "Compute Access",
155
+ "Total Cost", "Cost per 1M units", "Cost per h", "Cost Additional Info",
156
+ "Model Type", "Execution Info",
157
+ ]
158
+ )
159
+
160
+ all_categories = set()
161
+ for data in metrics_data.values():
162
+ all_categories.update(data.get("accuracy_per_category", {}).keys())
163
+
164
+ use_overall = (
165
+ selected_categories is None or len(selected_categories) == 0 or set(selected_categories) == all_categories
166
+ )
167
+
168
+ rows = []
169
+ for key, data in metrics_data.items():
170
+ latency_ci = data.get("latency_ci_95", {})
171
+ cost_info = data.get("cost_info", {})
172
+
173
+ latency_ci_str = (
174
+ f"[{int(round(latency_ci.get('lower', 0), 3) * 1000)}, {int(round(latency_ci.get('upper', 0), 3) * 1000)}]"
175
+ )
176
+
177
+ cost_input = cost_info.get("cost_per_1M_input_tokens", "N/A")
178
+ cost_output = cost_info.get("cost_per_1M_output_tokens", "N/A")
179
+ if cost_input == "N/A" or cost_output == "N/A":
180
+ cost_str = "Unknown"
181
+ else:
182
+ cost_str = f"Input: ${round(cost_input, 2)}/1M, Output: ${round(cost_output, 2)}/1M"
183
+
184
+ if use_overall:
185
+ accuracy = data.get("accuracy", 0)
186
+ else:
187
+ accuracy_per_category = data.get("accuracy_per_category", {})
188
+ selected_accuracies = [
189
+ accuracy_per_category.get(cat, 0) for cat in selected_categories if cat in accuracy_per_category
190
+ ]
191
+ accuracy = sum(selected_accuracies) / len(selected_accuracies) if selected_accuracies else 0
192
+
193
+ accuracy_pct = accuracy * 100
194
+ fpr_pct = data.get("fpr", 0) * 100
195
+
196
+ cost_per_h_value = data["cost_info"].get("cost_per_h", "Unknown")
197
+ cost_per_h_str = f"${cost_per_h_value}" if cost_per_h_value != "N/A" else cost_per_h_value
198
+
199
+ rows.append(
200
+ {
201
+ "Model Snapshot": data.get("model_name", ""),
202
+ "Model URL": data.get("model_url", ""),
203
+ "Model Developer": data.get("model_developer", ""),
204
+ "Provider": data.get("provider", ""),
205
+ "Detection Rate (%)": round(accuracy_pct, 2),
206
+ "FPR (%)": round(fpr_pct, 2),
207
+ "Latency CI 95% (ms)": latency_ci_str,
208
+ "Mean Latency (ms)": int(round(data.get("mean_latency", 0), 3) * 1000),
209
+ "Compute Access": data["execution_specifications"].get("type", "Unknown"),
210
+ "Total Cost": f"{round(data['cost_info'].get('total_cost', 'Unknown') * 100, 1)} ct",
211
+ "Cost per 1M units": cost_str,
212
+ "Cost per h": cost_per_h_str,
213
+ "Cost Additional Info": data["cost_info"].get("cost_additional_info", ""),
214
+ "Model Type": data.get("model_type", "Unknown"),
215
+ "Execution Info": data["execution_specifications"].get("details", "Unknown"),
216
+ "_accuracy": accuracy,
217
+ "_fpr": data.get("fpr", 0),
218
+ "_mean_latency": int(round(data.get("mean_latency", 0), 3) * 1000),
219
+ "_total_cost": round(data["cost_info"].get("total_cost", "Unknown") * 100, 1),
220
+ }
221
+ )
222
+
223
+ return pd.DataFrame(rows)
224
+
225
+
226
+ # ── Leaderboard HTML ────────────────────────────────────────────────────
227
+
228
+ def create_leaderboard_html(
229
+ sort_by: str = "Detection Rate (%)",
230
+ selected_categories: List[str] | None = None,
231
+ dataset_type: str = "input",
232
+ weights: Dict[str, float] | None = None,
233
+ ) -> str:
234
+ leaderboard_df = prepare_leaderboard_data(selected_categories=selected_categories, dataset_type=dataset_type)
235
+
236
+ sort_mapping = {
237
+ "Detection Rate (%)": "_accuracy",
238
+ "FPR (%)": "_fpr",
239
+ "Mean Latency (ms)": "_mean_latency",
240
+ "Total Cost": "_total_cost",
241
+ }
242
+
243
+ sort_column = sort_mapping.get(sort_by, "_accuracy")
244
+
245
+ if sort_by == "Overall Score":
246
+ sorted_df = sort_by_overall_score(leaderboard_df, weights).copy()
247
+ elif sort_by == "Detection Rate (%)":
248
+ sorted_df = leaderboard_df.sort_values(by=sort_column, ascending=False).copy()
249
+ elif sort_by in ["FPR (%)", "Mean Latency (ms)", "Total Cost"]:
250
+ sorted_df = leaderboard_df.sort_values(by=[sort_column, "_accuracy"], ascending=[True, False]).copy()
251
+ else:
252
+ sorted_df = leaderboard_df.sort_values(by=sort_column, ascending=False).copy()
253
+
254
+ sorted_df = sorted_df.reset_index(drop=True)
255
+
256
+ html = LEADERBOARD_TABLE_CSS
257
+ html += """
258
+ <div class="leaderboard-container">
259
+ <div class="footnotes-section" style="margin-top: 1.5rem; padding: 1rem; background: #f9fafb; border-radius: 8px; font-size: 13px; color: #374151; line-height: 1.6;">
260
+ <h4 style="margin-top: 0; margin-bottom: 0.75rem; font-size: 14px; font-weight: 600; color: #111827;">Column Explanations</h4>
261
+ <p style="margin: 0.5rem 0;"><sup>1</sup> <strong>Model Type:</strong> Shows if the supervisor is a repurposed generalist model or a specialized model made for content moderation.</p>
262
+ <p style="margin: 0.5rem 0;"><sup>2</sup> <strong>Detection Rate (%):</strong> Accuracy on harmful content.</p>
263
+ <p style="margin: 0.5rem 0;"><sup>3</sup> <strong>FPR (%):</strong> False Positive Rate on benign content.</p>
264
+ <p style="margin: 0.5rem 0;"><sup>4</sup> <strong>Compute Access:</strong> Shows how this supervisor was run. Can be 'Local' or 'API'.</p>
265
+ <p style="margin: 0.5rem 0;"><sup>5</sup> <strong>Total Cost:</strong> The total cost was measured differently for local inference and API supervisors. For local inference, it is total_latency * cost_per_h. For API supervisors it is calculated using the usage metrics and pricing information.</p>
266
+ <p style="margin: 0.5rem 0;"><sup>6</sup> <strong>Cost per 1M units:</strong> Different systems calculate usage in different units (e.g. characters, tokens, requests). This column shows the cost per 1M measured units.</p>
267
+ <p style="margin: 0.5rem 0;"><sup>7</sup> <strong>Cost per h:</strong> Only applicable for local inference. This is the pricing information for the GPU pod (see the "Execution Info" column for more details).</p>
268
+ </div>
269
+ <table class="leaderboard-table">
270
+ <thead>
271
+ <tr>
272
+ <th>Rank</th>
273
+ <th>Model Snapshot</th>
274
+ <th>Model Developer</th>
275
+ <th>Provider</th>
276
+ <th title="Shows if the supervisor is a repurposed generalist model or a specialized model made for content moderation.">Model Type <sup>1</sup></th>
277
+ <th title="Accuracy on harmful content.">Detection Rate (%) <sup>2</sup></th>
278
+ <th title="False Positive Rate on benign content.">FPR (%) <sup>3</sup></th>
279
+ <th>Latency CI 95% (ms)</th>
280
+ <th>Mean Latency (ms)</th>
281
+ <th title="Shows how this supervisor was ran. Can be 'Local' or 'API'.">Compute Access <sup>4</sup></th>
282
+ <th title="The total cost was measured differently for local inference and API supervisors. For local inference, it is total_latency * cost_per_h. For API supervisors it is calculated using the usage metrics and pricing information.">Total Cost <sup>5</sup></th>
283
+ <th title="Different systems calculate usage in different units (e.g. characters, tokens, requests). This column shows the cost per 1M measured units.">Cost per 1M units <sup>6</sup></th>
284
+ <th title="Only applicable for local inference. All models were run on RunPod.">Cost per h <sup>7</sup></th>
285
+ <th>Cost Additional Info</th>
286
+ <th>Execution Info</th>
287
+ </tr>
288
+ </thead>
289
+ <tbody>
290
+ """
291
+
292
+ for idx, row in sorted_df.iterrows():
293
+ rank = idx + 1
294
+ detection_rate = row["Detection Rate (%)"]
295
+ fpr = row["FPR (%)"]
296
+ latency = row["Mean Latency (ms)"]
297
+ model_type = row["Model Type"]
298
+ type_class = "type-specialized" if model_type == "specialized" else "type-generalist"
299
+
300
+ model_name = escape_html(row["Model Snapshot"])
301
+ model_url = str(row["Model URL"]) if row["Model URL"] else ""
302
+ developer = escape_html(row["Model Developer"])
303
+ provider = escape_html(row["Provider"])
304
+ compute_access = escape_html(row["Compute Access"])
305
+ total_cost = escape_html(row["Total Cost"])
306
+ cost_per_1m = escape_html(row["Cost per 1M units"])
307
+ cost_per_h = escape_html(row["Cost per h"])
308
+ cost_add_info = escape_html(row["Cost Additional Info"])
309
+ latency_ci = escape_html(row["Latency CI 95% (ms)"])
310
+ exec_info = escape_html(row["Execution Info"])
311
+
312
+ if model_url and model_url != "None":
313
+ model_name_html = f'<a href="{model_url}" target="_blank" rel="noopener noreferrer" style="color: inherit; text-decoration: none; border-bottom: 1px dotted currentColor;">{model_name}</a>'
314
+ else:
315
+ model_name_html = model_name
316
+
317
+ html += f"""
318
+ <tr>
319
+ <td><span class="rank-badge">{rank}</span></td>
320
+ <td class="model-name">{model_name_html}</td>
321
+ <td class="model-developer">{developer}</td>
322
+ <td><span class="provider-badge">{provider}</span></td>
323
+ <td><span class="model-type-badge {type_class}">{model_type.title()}</span></td>
324
+ <td class="detection-rate metric-value">{detection_rate:.2f}%</td>
325
+ <td class="metric-value">{fpr:.2f}%</td>
326
+ <td>{latency_ci}</td>
327
+ <td class="metric-value">{latency:d}</td>
328
+ <td>{compute_access}</td>
329
+ <td>{total_cost}</td>
330
+ <td style="font-size: 12px;">{cost_per_1m}</td>
331
+ <td>{cost_per_h}</td>
332
+ <td style="font-size: 12px; color: #6b7280;">{cost_add_info}</td>
333
+ <td style="font-size: 12px; color: #6b7280;">{exec_info}</td>
334
+ </tr>
335
+ """
336
+
337
+ html += """
338
+ </tbody>
339
+ </table>
340
+ </div>
341
+ """
342
+ html += LEADERBOARD_DARK_MODE_CSS
343
+ return html
344
+
345
+
346
+ # ── Category table ──────────────────────────────────────────────────────
347
+
348
+ def create_category_accuracy_table_html(selected_models: List[str] | None = None, dataset_type: str = "input") -> str:
349
+ metrics_data = filter_metrics_by_dataset(dataset_type)
350
+
351
+ if selected_models is None or len(selected_models) == 0:
352
+ selected_models = [data.get("model_name", "") for data in metrics_data.values()]
353
+
354
+ all_categories = set()
355
+ for data in metrics_data.values():
356
+ all_categories.update(data.get("accuracy_per_category", {}).keys())
357
+
358
+ category_order = list(CATEGORY_LABELS.keys())
359
+ sorted_categories = [cat for cat in category_order if cat in all_categories]
360
+ sorted_categories.extend([cat for cat in all_categories if cat not in category_order])
361
+
362
+ html = CATEGORY_TABLE_CSS
363
+ html += '<div class="category-table-container"><table class="category-table">'
364
+
365
+ html += "<thead><tr><th>Model</th>"
366
+ for category in sorted_categories:
367
+ category_label = CATEGORY_LABELS.get(category, category.title())
368
+ html += f"<th>{category_label}</th>"
369
+ html += "</tr></thead>"
370
+
371
+ html += "<tbody>"
372
+ for key, data in metrics_data.items():
373
+ model_name = data.get("model_name", "")
374
+ if model_name not in selected_models:
375
+ continue
376
+
377
+ html += f"<tr><td>{escape_html(model_name)}</td>"
378
+ accuracy_per_category = data.get("accuracy_per_category", {})
379
+ for category in sorted_categories:
380
+ accuracy = accuracy_per_category.get(category, 0)
381
+ acc_pct = round(accuracy * 100, 1)
382
+ bg_color = get_color_for_accuracy(accuracy)
383
+ html += f'<td style="background-color: {bg_color};">{acc_pct}%</td>'
384
+ html += "</tr>"
385
+
386
+ html += "</tbody></table></div>"
387
+ return html
388
+
389
+
390
+ # ── Helpers ─────────────────────────────────────────────────────────────
391
+
392
+ def get_available_categories(dataset_type: str = "input") -> List[tuple]:
393
+ metrics_data = filter_metrics_by_dataset(dataset_type)
394
+ all_categories = set()
395
+ for data in metrics_data.values():
396
+ all_categories.update(data.get("accuracy_per_category", {}).keys())
397
+
398
+ category_order = list(CATEGORY_LABELS.keys())
399
+ sorted_categories = [cat for cat in category_order if cat in all_categories]
400
+ sorted_categories.extend([cat for cat in all_categories if cat not in category_order])
401
+ return [(CATEGORY_LABELS.get(cat, cat.title()), cat) for cat in sorted_categories]
402
+
403
+
404
+ def get_available_models(dataset_type: str = "input") -> List[str]:
405
+ metrics_data = filter_metrics_by_dataset(dataset_type)
406
+ return sorted([data.get("model_name", "") for data in metrics_data.values()])
407
+
408
+
409
+ # ── Pareto ──────────────────────────────────────────────────────────────
410
+
411
+ _PARETO_METRIC_MAP = {
412
+ "Detection Rate in %": ("_accuracy", False),
413
+ "FPR in %": ("_fpr", True),
414
+ "Mean Latency in ms": ("_mean_latency", True),
415
+ "Total Cost in ct": ("_total_cost", True),
416
+ }
417
+
418
+
419
+ def create_pareto_plot_interactive(x_metric, y_metric, dataset_type="input"):
420
+ df = prepare_leaderboard_data(None, dataset_type)
421
+ return build_pareto_figure(df, x_metric, y_metric, _PARETO_METRIC_MAP)
422
+
423
+
424
+ # ── Tab builder ─────────────────────────────────────────────────────────
425
+
426
+ def build_cm_tab(dataset_type: str):
427
+ """Build the three sub-tabs (Leaderboard, Category Performance, Pareto Frontier)
428
+ for a given content-moderation dataset type ('input' or 'output')."""
429
+ label = "Input" if dataset_type == "input" else "Output"
430
+
431
+ with gr.Tabs():
432
+ # ── Leaderboard sub-tab ─────────────────────────────────────
433
+ with gr.Tab("Leaderboard"):
434
+ with gr.Column():
435
+ gr.Markdown(f"### Interactive Leaderboard - {label} Dataset")
436
+ gr.Markdown(
437
+ "Sort the leaderboard by different metrics to compare model performance. "
438
+ "Use the dropdown below to change the sorting order. "
439
+ "Select specific categories to see detection rates calculated only for those categories."
440
+ )
441
+
442
+ category_choices = get_available_categories(dataset_type)
443
+
444
+ with gr.Row():
445
+ sort_metric = gr.Dropdown(
446
+ choices=[
447
+ "Overall Score",
448
+ "Detection Rate (%)",
449
+ "FPR (%)",
450
+ "Mean Latency (ms)",
451
+ "Total Cost",
452
+ ],
453
+ value="Overall Score",
454
+ label="Sort by Metric",
455
+ interactive=True,
456
+ info="Higher detection rate is better. Lower FPR and latency are better.",
457
+ )
458
+
459
+ with gr.Group(visible=True) as weight_row:
460
+ with gr.Row():
461
+ weight_detection = gr.Number(
462
+ value=DEFAULT_WEIGHTS["Detection Rate (%)"],
463
+ label="Detection Rate weight",
464
+ minimum=0.0,
465
+ interactive=True,
466
+ )
467
+ weight_fpr = gr.Number(
468
+ value=DEFAULT_WEIGHTS["FPR (%)"],
469
+ label="FPR weight",
470
+ minimum=0.0,
471
+ interactive=True,
472
+ )
473
+ weight_latency = gr.Number(
474
+ value=DEFAULT_WEIGHTS["Mean Latency (ms)"],
475
+ label="Latency weight",
476
+ minimum=0.0,
477
+ interactive=True,
478
+ )
479
+ weight_cost = gr.Number(
480
+ value=DEFAULT_WEIGHTS["Total Cost"],
481
+ label="Cost weight",
482
+ minimum=0.0,
483
+ interactive=True,
484
+ )
485
+ weight_bar = gr.HTML(value=create_weight_bar_html(DEFAULT_WEIGHTS))
486
+ weight_inputs = [weight_detection, weight_fpr, weight_latency, weight_cost]
487
+
488
+ gr.HTML(value=create_dataset_info_html(dataset_type))
489
+
490
+ with gr.Row():
491
+ category_selector = gr.CheckboxGroup(
492
+ choices=category_choices,
493
+ value=[cat for _, cat in category_choices],
494
+ label="Select Categories for Detection Rate",
495
+ interactive=True,
496
+ info="Select categories to calculate detection rate. By default, all categories are selected (overall detection rate).",
497
+ )
498
+
499
+ leaderboard_html = gr.HTML(
500
+ value=create_leaderboard_html(sort_by="Overall Score", dataset_type=dataset_type, weights=DEFAULT_WEIGHTS),
501
+ label="Model Rankings",
502
+ )
503
+
504
+ def update_leaderboard(sort_by, selected_categories, w_det, w_fpr, w_lat, w_cost):
505
+ weights = build_weights(w_det, w_fpr, w_lat, w_cost)
506
+ html = create_leaderboard_html(
507
+ sort_by=sort_by,
508
+ selected_categories=selected_categories,
509
+ dataset_type=dataset_type,
510
+ weights=weights,
511
+ )
512
+ bar = create_weight_bar_html(weights)
513
+ return html, bar
514
+
515
+ def on_sort_change(sort_by, selected_categories, w_det, w_fpr, w_lat, w_cost):
516
+ weights = build_weights(w_det, w_fpr, w_lat, w_cost)
517
+ new_html = create_leaderboard_html(
518
+ sort_by=sort_by,
519
+ selected_categories=selected_categories,
520
+ dataset_type=dataset_type,
521
+ weights=weights,
522
+ )
523
+ visible = sort_by == "Overall Score"
524
+ bar = create_weight_bar_html(weights)
525
+ return gr.update(visible=visible), new_html, bar
526
+
527
+ all_inputs = [sort_metric, category_selector] + weight_inputs
528
+
529
+ sort_metric.change(
530
+ fn=on_sort_change,
531
+ inputs=all_inputs,
532
+ outputs=[weight_row, leaderboard_html, weight_bar],
533
+ )
534
+
535
+ category_selector.change(
536
+ fn=update_leaderboard,
537
+ inputs=all_inputs,
538
+ outputs=[leaderboard_html, weight_bar],
539
+ )
540
+
541
+ for w_input in weight_inputs:
542
+ w_input.change(
543
+ fn=update_leaderboard,
544
+ inputs=all_inputs,
545
+ outputs=[leaderboard_html, weight_bar],
546
+ )
547
+
548
+ # ── Category Performance sub-tab ────────────────────────────
549
+ with gr.Tab("Category Performance"):
550
+ with gr.Column():
551
+ gr.Markdown(f"### Accuracy per Category by Model - {label} Dataset")
552
+ gr.Markdown(
553
+ "Compare how different models perform across the 11 harm categories. "
554
+ "Each cell shows the detection rate (accuracy) for that model-category combination. "
555
+ "Cell colors indicate performance: darker green = higher accuracy (closer to 100%), lighter colors = lower accuracy."
556
+ )
557
+
558
+ gr.HTML(value=create_dataset_info_html(dataset_type))
559
+
560
+ model_choices = get_available_models(dataset_type)
561
+ model_selector = gr.CheckboxGroup(
562
+ choices=model_choices,
563
+ value=model_choices,
564
+ label="Select Models to Compare",
565
+ interactive=True,
566
+ info="Select one or more models to compare their performance across categories.",
567
+ )
568
+
569
+ category_table_html = gr.HTML(
570
+ value=create_category_accuracy_table_html(model_choices, dataset_type=dataset_type),
571
+ label="Category Accuracy Comparison",
572
+ )
573
+
574
+ model_selector.change(
575
+ fn=lambda models: create_category_accuracy_table_html(models, dataset_type=dataset_type),
576
+ inputs=model_selector,
577
+ outputs=category_table_html,
578
+ )
579
+
580
+ # ── Pareto Frontier sub-tab ─────────────────────────────────
581
+ with gr.Tab("Pareto Frontier"):
582
+ with gr.Column():
583
+ gr.Markdown(f"### Pareto Frontier Analysis - {label} Dataset")
584
+ gr.Markdown(
585
+ "Visualize trade-offs between different metrics. Models on the Pareto frontier "
586
+ "represent optimal trade-offs where improving one metric would require sacrificing another. "
587
+ "Hover over points to see the model name."
588
+ )
589
+
590
+ with gr.Row():
591
+ pareto_x_metric = gr.Dropdown(
592
+ choices=["Detection Rate in %", "FPR in %", "Mean Latency in ms", "Total Cost in ct"],
593
+ value="Detection Rate in %",
594
+ label="X-Axis Metric",
595
+ interactive=True,
596
+ )
597
+ pareto_y_metric = gr.Dropdown(
598
+ choices=["Detection Rate in %", "FPR in %", "Mean Latency in ms", "Total Cost in ct"],
599
+ value="FPR in %",
600
+ label="Y-Axis Metric",
601
+ interactive=True,
602
+ )
603
+
604
+ with gr.Column():
605
+ gr.HTML('<div style="display:flex; justify-content:center;">', visible=False)
606
+ pareto_plot = gr.Plot(
607
+ value=create_pareto_plot_interactive("Detection Rate in %", "FPR in %", dataset_type)
608
+ )
609
+ gr.HTML("</div>", visible=False)
610
+
611
+ def _update_pareto(x_metric, y_metric):
612
+ if x_metric == y_metric:
613
+ return create_empty_pareto_figure()
614
+ return create_pareto_plot_interactive(x_metric, y_metric, dataset_type)
615
+
616
+ pareto_x_metric.change(
617
+ fn=_update_pareto,
618
+ inputs=[pareto_x_metric, pareto_y_metric],
619
+ outputs=pareto_plot,
620
+ )
621
+ pareto_y_metric.change(
622
+ fn=_update_pareto,
623
+ inputs=[pareto_x_metric, pareto_y_metric],
624
+ outputs=pareto_plot,
625
+ )
data/cm_model_info_mapping.json ADDED
@@ -0,0 +1,679 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_comment": "Consolidated model information mapping. Contains developer, type, cost information, and execution specifications for each model.",
3
+ "_units": {
4
+ "api_costs": "cost per 1M input tokens + cost per 1M output tokens (if applicable)",
5
+ "local_costs": "cost per 1M tokens (calculated using formula)"
6
+ },
7
+ "anthropic/claude-haiku-4-5": {
8
+ "model_developer": "Anthropic",
9
+ "model_type": "generalist",
10
+ "url": "https://platform.claude.com/docs/en/about-claude/models/overview",
11
+ "cost_info": {
12
+ "cost_per_1M_input_tokens": 1.0,
13
+ "cost_per_1M_output_tokens": 5.0,
14
+ "source": "Claude API pricing",
15
+ "cost_per_h": "N/A",
16
+ "additional_info": ""
17
+ },
18
+ "execution_specifications": {
19
+ "type": "API",
20
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
21
+ }
22
+ },
23
+ "anthropic/claude-sonnet-4-5": {
24
+ "model_developer": "Anthropic",
25
+ "model_type": "generalist",
26
+ "url": "https://platform.claude.com/docs/en/about-claude/models/overview",
27
+ "cost_info": {
28
+ "cost_per_1M_input_tokens": 3.0,
29
+ "cost_per_1M_output_tokens": 15.0,
30
+ "source": "Claude API pricing",
31
+ "cost_per_h": "N/A",
32
+ "additional_info": ""
33
+ },
34
+ "execution_specifications": {
35
+ "type": "API",
36
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
37
+ }
38
+ },
39
+ "azure/analyze-text": {
40
+ "model_developer": "Azure",
41
+ "model_type": "specialized",
42
+ "url": "https://learn.microsoft.com/en-us/azure/ai-services/content-safety/overview",
43
+ "cost_info": {
44
+ "cost_per_1M_input_tokens": 380.0,
45
+ "cost_per_1M_output_tokens": 0.0,
46
+ "source": "Azure AI Content Safety",
47
+ "cost_per_h": "N/A",
48
+ "additional_info": "Usage is measured in text records. One text record may contain up to 1000 characters. Only the input string is considered in the text record.\n1000 text records cost $0.38. Assuming an average length of 500 characters for a message, and a token length of approx. 4 characters: Estimated cost per 1M input tokens = 1M/(500/4) text records * $0.38/1000 text records) = $3.04.\nCost per 1M input tokens (not records) = 3.04$.\n\nThe benchmark was run on the free plan."
49
+ },
50
+ "execution_specifications": {
51
+ "type": "API",
52
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
53
+ }
54
+ },
55
+ "google/gemini-2.5-flash": {
56
+ "model_developer": "Google",
57
+ "model_type": "generalist",
58
+ "url": "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash",
59
+ "cost_info": {
60
+ "cost_per_1M_input_tokens": 0.3,
61
+ "cost_per_1M_output_tokens": 2.5,
62
+ "source": "Gemini Developer API pricing",
63
+ "cost_per_h": "N/A",
64
+ "additional_info": ""
65
+ },
66
+ "execution_specifications": {
67
+ "type": "API",
68
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
69
+ }
70
+ },
71
+ "lakera/lakera-guard_default": {
72
+ "model_developer": "Lakera",
73
+ "model_type": "specialized",
74
+ "url": "https://www.lakera.ai/lakera-guard",
75
+ "cost_info": {
76
+ "cost_per_1M_input_tokens": 0.0,
77
+ "cost_per_1M_output_tokens": 0.0,
78
+ "source": "Lakera API pricing",
79
+ "cost_per_h": "N/A",
80
+ "additional_info": "Free for 10,000 API requests/month; Allows prompt size up to 8,000 tokens per request."
81
+ },
82
+ "execution_specifications": {
83
+ "type": "API",
84
+ "details": "This is the LakeraGuard API with the default policy. REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
85
+ }
86
+ },
87
+ "meta/llama-guard-4-12b": {
88
+ "model_developer": "Meta",
89
+ "model_type": "specialized",
90
+ "url": "https://www.llama.com/docs/model-cards-and-prompt-formats/llama-guard-4/",
91
+ "cost_info": {
92
+ "cost_per_1M_input_tokens": 0.2,
93
+ "cost_per_1M_output_tokens": 0.0,
94
+ "source": "Together AI pricing",
95
+ "cost_per_h": "N/A",
96
+ "additional_info": ""
97
+ },
98
+ "execution_specifications": {
99
+ "type": "API",
100
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
101
+ }
102
+ },
103
+ "mistral/ministral-3b-2512": {
104
+ "model_developer": "Mistral AI",
105
+ "model_type": "generalist",
106
+ "url": "https://docs.mistral.ai/models/ministral-3-3b-25-12",
107
+ "cost_info": {
108
+ "cost_per_1M_input_tokens": 0.04,
109
+ "cost_per_1M_output_tokens": 0.04,
110
+ "source": "Ministral API pricing",
111
+ "cost_per_h": "N/A",
112
+ "additional_info": ""
113
+ },
114
+ "execution_specifications": {
115
+ "type": "API",
116
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
117
+ }
118
+ },
119
+ "mistral/mistral-large-3": {
120
+ "model_developer": "Mistral AI",
121
+ "model_type": "generalist",
122
+ "url": "https://docs.mistral.ai/models/mistral-large-3-25-12",
123
+ "cost_info": {
124
+ "cost_per_1M_input_tokens": 4.0,
125
+ "cost_per_1M_output_tokens": 12.0,
126
+ "source": "Mistral API pricing",
127
+ "cost_per_h": "N/A",
128
+ "additional_info": ""
129
+ },
130
+ "execution_specifications": {
131
+ "type": "API",
132
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
133
+ }
134
+ },
135
+ "openai/gpt-5-nano": {
136
+ "model_developer": "OpenAI",
137
+ "model_type": "generalist",
138
+ "url": "https://platform.openai.com/docs/models/gpt-5-nano",
139
+ "cost_info": {
140
+ "cost_per_1M_input_tokens": 0.05,
141
+ "cost_per_1M_output_tokens": 0.4,
142
+ "source": "OpenAI API pricing",
143
+ "cost_per_h": "N/A",
144
+ "additional_info": ""
145
+ },
146
+ "execution_specifications": {
147
+ "type": "API",
148
+ "details": "Reasoning effort set to minimal; see OpenAI API docs. REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
149
+ }
150
+ },
151
+ "openai/gpt-5.2": {
152
+ "model_developer": "OpenAI",
153
+ "model_type": "generalist",
154
+ "url": "https://platform.openai.com/docs/models/gpt-5.2",
155
+ "cost_info": {
156
+ "cost_per_1M_input_tokens": 1.75,
157
+ "cost_per_1M_output_tokens": 14.0,
158
+ "source": "OpenAI API pricing",
159
+ "cost_per_h": "N/A",
160
+ "additional_info": ""
161
+ },
162
+ "execution_specifications": {
163
+ "type": "API",
164
+ "details": "Reasoning effort set to low; see OpenAI API docs. REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
165
+ }
166
+ },
167
+ "openai/gpt-oss-20b": {
168
+ "model_developer": "OpenAI",
169
+ "model_type": "generalist",
170
+ "url": "https://www.together.ai/models/gpt-oss-20b",
171
+ "cost_info": {
172
+ "cost_per_1M_input_tokens": 0.05,
173
+ "cost_per_1M_output_tokens": 0.2,
174
+ "source": "Together AI API pricing",
175
+ "cost_per_h": "N/A",
176
+ "additional_info": ""
177
+ },
178
+ "execution_specifications": {
179
+ "type": "API",
180
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
181
+ }
182
+ },
183
+ "openai/gpt-oss-120b": {
184
+ "model_developer": "OpenAI",
185
+ "model_type": "generalist",
186
+ "url": "https://www.together.ai/models/gpt-oss-120b",
187
+ "cost_info": {
188
+ "cost_per_1M_input_tokens": 0.05,
189
+ "cost_per_1M_output_tokens": 0.2,
190
+ "source": "Together AI API pricing",
191
+ "cost_per_h": "N/A",
192
+ "additional_info": ""
193
+ },
194
+ "execution_specifications": {
195
+ "type": "API",
196
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
197
+ }
198
+ },
199
+ "openai/gpt-oss-safeguard-20b": {
200
+ "model_developer": "OpenAI",
201
+ "model_type": "specialized",
202
+ "url": "https://huggingface.co/openai/gpt-oss-safeguard-20b",
203
+ "cost_info": {
204
+ "cost_per_1M_input_tokens": 0.07,
205
+ "cost_per_1M_output_tokens": 0.3,
206
+ "source": "OpenRouter API pricing",
207
+ "cost_per_h": "N/A",
208
+ "additional_info": ""
209
+ },
210
+ "execution_specifications": {
211
+ "type": "API",
212
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
213
+ }
214
+ },
215
+ "openai/omni-moderation": {
216
+ "model_developer": "OpenAI",
217
+ "model_type": "specialized",
218
+ "url": "https://platform.openai.com/docs/models/omni-moderation-latest",
219
+ "cost_info": {
220
+ "cost_per_1M_input_tokens": 0.0,
221
+ "cost_per_1M_output_tokens": 0.0,
222
+ "source": "OpenAI Moderation API pricing",
223
+ "cost_per_h": "N/A",
224
+ "additional_info": "The Omni Moderation endpoint is free to use but has low rate limits in the free tier. Your usage tier on the OpenAI API determines these rate limits."
225
+ },
226
+ "execution_specifications": {
227
+ "type": "API",
228
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
229
+ }
230
+ },
231
+ "virtue-ai/virtueguard-text-lite": {
232
+ "model_developer": "Virtue AI",
233
+ "model_type": "specialized",
234
+ "url": "https://www.together.ai/models/virtueguard-text-lite",
235
+ "cost_info": {
236
+ "cost_per_1M_input_tokens": 0.2,
237
+ "cost_per_1M_output_tokens": 0.0,
238
+ "source": "Together AI API pricing",
239
+ "cost_per_h": "N/A",
240
+ "additional_info": ""
241
+ },
242
+ "execution_specifications": {
243
+ "type": "API",
244
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
245
+ }
246
+ },
247
+ "x-ai/grok-4-1-fast-non-reasoning": {
248
+ "model_developer": "X-AI",
249
+ "model_type": "generalist",
250
+ "url": "https://docs.x.ai/docs/models/grok-4-1-fast-non-reasoning",
251
+ "cost_info": {
252
+ "cost_per_1M_input_tokens": 0.2,
253
+ "cost_per_1M_output_tokens": 0.5,
254
+ "source": "X-AI API pricing",
255
+ "cost_per_h": "N/A",
256
+ "additional_info": ""
257
+ },
258
+ "execution_specifications": {
259
+ "type": "API",
260
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
261
+ }
262
+ },
263
+ "aws/bedrock-guardrail": {
264
+ "model_developer": "Amazon Web Services",
265
+ "model_type": "specialized",
266
+ "url": "https://aws.amazon.com/bedrock/guardrails/",
267
+ "cost_info": {
268
+ "cost_per_1M_input_tokens": 150.0,
269
+ "cost_per_1M_output_tokens": 0.0,
270
+ "source": "Amazon Bedrock API pricing",
271
+ "cost_per_h": "N/A",
272
+ "additional_info": "Usage is measured in text units. One text unit may contain up to 1000 characters. Only the input string is considered in the text unit.\n1000 text units cost $0.15. Assuming an average length of 500 characters for a message, and a token length of approx. 4 characters: Estimated cost per 1M input tokens = 1M/(500/4) text units * $0.15/1000 text units) = $1.2.\nCost per 1M input tokens (not units) = 1.2$."
273
+ },
274
+ "execution_specifications": {
275
+ "type": "API",
276
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
277
+ }
278
+ },
279
+ "nvidia/aegis-ai-content-safety-llamaguard-defensive-1.0": {
280
+ "model_developer": "NVIDIA",
281
+ "model_type": "specialized",
282
+ "url": "https://huggingface.co/nvidia/Aegis-AI-Content-Safety-LlamaGuard-Defensive-1.0",
283
+ "cost_info": {
284
+ "cost_per_1M_input_tokens": "N/A",
285
+ "cost_per_1M_output_tokens": "N/A",
286
+ "source": "RunPod",
287
+ "cost_per_h": 2.39,
288
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
289
+ },
290
+ "execution_specifications": {
291
+ "type": "Local",
292
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
293
+ }
294
+ },
295
+ "google/shieldgemma-2b": {
296
+ "model_developer": "Google",
297
+ "model_type": "specialized",
298
+ "url": "https://huggingface.co/google/shieldgemma-2b",
299
+ "cost_info": {
300
+ "cost_per_1M_input_tokens": "N/A",
301
+ "cost_per_1M_output_tokens": "N/A",
302
+ "source": "RunPod",
303
+ "cost_per_h": 2.39,
304
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
305
+ },
306
+ "execution_specifications": {
307
+ "type": "Local",
308
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
309
+ }
310
+ },
311
+ "google/shieldgemma-9b": {
312
+ "model_developer": "Google",
313
+ "url": "https://huggingface.co/google/shieldgemma-9b",
314
+ "model_type": "specialized",
315
+ "cost_info": {
316
+ "cost_per_1M_input_tokens": "N/A",
317
+ "cost_per_1M_output_tokens": "N/A",
318
+ "source": "RunPod",
319
+ "cost_per_h": 2.39,
320
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
321
+ },
322
+ "execution_specifications": {
323
+ "type": "Local",
324
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
325
+ }
326
+ },
327
+ "google/shieldgemma-27b": {
328
+ "model_developer": "Google",
329
+ "model_type": "specialized",
330
+ "url": "https://huggingface.co/google/shieldgemma-27b",
331
+ "cost_info": {
332
+ "cost_per_1M_input_tokens": "N/A",
333
+ "cost_per_1M_output_tokens": "N/A",
334
+ "source": "RunPod",
335
+ "cost_per_h": 2.39,
336
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
337
+ },
338
+ "execution_specifications": {
339
+ "type": "Local",
340
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
341
+ }
342
+ },
343
+ "saillab/xguard": {
344
+ "model_developer": "SAIL Lab",
345
+ "model_type": "specialized",
346
+ "url": "https://huggingface.co/saillab/x-guard",
347
+ "cost_info": {
348
+ "cost_per_1M_input_tokens": "N/A",
349
+ "cost_per_1M_output_tokens": "N/A",
350
+ "source": "RunPod",
351
+ "cost_per_h": 2.39,
352
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
353
+ },
354
+ "execution_specifications": {
355
+ "type": "Local",
356
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
357
+ }
358
+ },
359
+ "openai/gpt-oss-safeguard-120b": {
360
+ "model_developer": "OpenAI",
361
+ "model_type": "specialized",
362
+ "url": "https://huggingface.co/openai/gpt-oss-safeguard-120b",
363
+ "cost_info": {
364
+ "cost_per_1M_input_tokens": "N/A",
365
+ "cost_per_1M_output_tokens": "N/A",
366
+ "source": "RunPod",
367
+ "cost_per_h": 3.07,
368
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
369
+ },
370
+ "execution_specifications": {
371
+ "type": "Local",
372
+ "details": "This model was ran on an H100 (94GB NVL) on RunPod using vLLM."
373
+ }
374
+ },
375
+ "qwen/qwen3guard-gen-8b": {
376
+ "model_developer": "Qwen",
377
+ "model_type": "specialized",
378
+ "url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-8B",
379
+ "cost_info": {
380
+ "cost_per_1M_input_tokens": "N/A",
381
+ "cost_per_1M_output_tokens": "N/A",
382
+ "source": "RunPod",
383
+ "cost_per_h": 2.39,
384
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
385
+ },
386
+ "execution_specifications": {
387
+ "type": "Local",
388
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
389
+ }
390
+ },
391
+ "qwen/qwen3guard-gen-4b": {
392
+ "model_developer": "Qwen",
393
+ "model_type": "specialized",
394
+ "url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-4B",
395
+ "cost_info": {
396
+ "cost_per_1M_input_tokens": "N/A",
397
+ "cost_per_1M_output_tokens": "N/A",
398
+ "source": "RunPod",
399
+ "cost_per_h": 2.39,
400
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
401
+ },
402
+ "execution_specifications": {
403
+ "type": "Local",
404
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
405
+ }
406
+ },
407
+ "qwen/qwen3guard-gen-0.6b": {
408
+ "model_developer": "Qwen",
409
+ "model_type": "specialized",
410
+ "url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-0.6B",
411
+ "cost_info": {
412
+ "cost_per_1M_input_tokens": "N/A",
413
+ "cost_per_1M_output_tokens": "N/A",
414
+ "source": "RunPod",
415
+ "cost_per_h": 2.39,
416
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
417
+ },
418
+ "execution_specifications": {
419
+ "type": "Local",
420
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
421
+ }
422
+ },
423
+ "nvidia/llama-3.1-nemotron-safety-guard-8b-v3": {
424
+ "model_developer": "NVIDIA",
425
+ "model_type": "specialized",
426
+ "url": "https://huggingface.co/nvidia/Llama-3.1-Nemotron-Safety-Guard-8B-v3",
427
+ "cost_info": {
428
+ "cost_per_1M_input_tokens": "N/A",
429
+ "cost_per_1M_output_tokens": "N/A",
430
+ "source": "RunPod",
431
+ "cost_per_h": 2.39,
432
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
433
+ },
434
+ "execution_specifications": {
435
+ "type": "Local",
436
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
437
+ }
438
+ },
439
+ "rakancorle1/thinkguard": {
440
+ "model_developer": "RakanCorle1",
441
+ "model_type": "specialized",
442
+ "url": "https://huggingface.co/Rakancorle1/ThinkGuard",
443
+ "cost_info": {
444
+ "cost_per_1M_input_tokens": "N/A",
445
+ "cost_per_1M_output_tokens": "N/A",
446
+ "source": "RunPod",
447
+ "cost_per_h": 2.39,
448
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
449
+ },
450
+ "execution_specifications": {
451
+ "type": "Local",
452
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
453
+ }
454
+ },
455
+ "allenai/wildguard": {
456
+ "model_developer": "AllenAI",
457
+ "model_type": "specialized",
458
+ "url": "https://huggingface.co/allenai/wildguard",
459
+ "cost_info": {
460
+ "cost_per_1M_input_tokens": "N/A",
461
+ "cost_per_1M_output_tokens": "N/A",
462
+ "source": "RunPod",
463
+ "cost_per_h": 2.39,
464
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
465
+ },
466
+ "execution_specifications": {
467
+ "type": "Local",
468
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
469
+ }
470
+ },
471
+ "toxicityprompts/polyguard-ministral": {
472
+ "model_developer": "ToxicityPrompts",
473
+ "model_type": "specialized",
474
+ "url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Ministral",
475
+ "cost_info": {
476
+ "cost_per_1M_input_tokens": "N/A",
477
+ "cost_per_1M_output_tokens": "N/A",
478
+ "source": "RunPod",
479
+ "cost_per_h": 2.39,
480
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
481
+ },
482
+ "execution_specifications": {
483
+ "type": "Local",
484
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
485
+ }
486
+ },
487
+ "toxicityprompts/polyguard-qwen": {
488
+ "model_developer": "ToxicityPrompts",
489
+ "model_type": "specialized",
490
+ "url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Qwen",
491
+ "cost_info": {
492
+ "cost_per_1M_input_tokens": "N/A",
493
+ "cost_per_1M_output_tokens": "N/A",
494
+ "source": "RunPod",
495
+ "cost_per_h": 2.39,
496
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
497
+ },
498
+ "execution_specifications": {
499
+ "type": "Local",
500
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
501
+ }
502
+ },
503
+ "toxicityprompts/polyguard-qwen-smol": {
504
+ "model_developer": "ToxicityPrompts",
505
+ "model_type": "specialized",
506
+ "url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Qwen-Smol",
507
+ "cost_info": {
508
+ "cost_per_1M_input_tokens": "N/A",
509
+ "cost_per_1M_output_tokens": "N/A",
510
+ "source": "RunPod",
511
+ "cost_per_h": 2.39,
512
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
513
+ },
514
+ "execution_specifications": {
515
+ "type": "Local",
516
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
517
+ }
518
+ },
519
+ "ibm-granite/granite-guardian-3.0-2b": {
520
+ "model_developer": "IBM",
521
+ "model_type": "specialized",
522
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.0-2b",
523
+ "cost_info": {
524
+ "cost_per_1M_input_tokens": "N/A",
525
+ "cost_per_1M_output_tokens": "N/A",
526
+ "source": "RunPod",
527
+ "cost_per_h": 2.39,
528
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
529
+ },
530
+ "execution_specifications": {
531
+ "type": "Local",
532
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
533
+ }
534
+ },
535
+ "ibm-granite/granite-guardian-3.0-8b": {
536
+ "model_developer": "IBM",
537
+ "model_type": "specialized",
538
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.0-8b",
539
+ "cost_info": {
540
+ "cost_per_1M_input_tokens": "N/A",
541
+ "cost_per_1M_output_tokens": "N/A",
542
+ "source": "RunPod",
543
+ "cost_per_h": 2.39,
544
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
545
+ },
546
+ "execution_specifications": {
547
+ "type": "Local",
548
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
549
+ }
550
+ },
551
+ "ibm-granite/granite-guardian-3.1-2b": {
552
+ "model_developer": "IBM",
553
+ "model_type": "specialized",
554
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.1-2b",
555
+ "cost_info": {
556
+ "cost_per_1M_input_tokens": "N/A",
557
+ "cost_per_1M_output_tokens": "N/A",
558
+ "source": "RunPod",
559
+ "cost_per_h": 2.39,
560
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
561
+ },
562
+ "execution_specifications": {
563
+ "type": "Local",
564
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
565
+ }
566
+ },
567
+ "ibm-granite/granite-guardian-3.1-8b": {
568
+ "model_developer": "IBM",
569
+ "model_type": "specialized",
570
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.1-8b",
571
+ "cost_info": {
572
+ "cost_per_1M_input_tokens": "N/A",
573
+ "cost_per_1M_output_tokens": "N/A",
574
+ "source": "RunPod",
575
+ "cost_per_h": 2.39,
576
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
577
+ },
578
+ "execution_specifications": {
579
+ "type": "Local",
580
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
581
+ }
582
+ },
583
+ "ibm-granite/granite-guardian-3.2-5b": {
584
+ "model_developer": "IBM",
585
+ "model_type": "specialized",
586
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.2-5b",
587
+ "cost_info": {
588
+ "cost_per_1M_input_tokens": "N/A",
589
+ "cost_per_1M_output_tokens": "N/A",
590
+ "source": "RunPod",
591
+ "cost_per_h": 2.39,
592
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
593
+ },
594
+ "execution_specifications": {
595
+ "type": "Local",
596
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
597
+ }
598
+ },
599
+ "ibm-granite/granite-guardian-3.2-3b-a800m": {
600
+ "model_developer": "IBM",
601
+ "model_type": "specialized",
602
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.2-3b-a800m",
603
+ "cost_info": {
604
+ "cost_per_1M_input_tokens": "N/A",
605
+ "cost_per_1M_output_tokens": "N/A",
606
+ "source": "RunPod",
607
+ "cost_per_h": 2.39,
608
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
609
+ },
610
+ "execution_specifications": {
611
+ "type": "Local",
612
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
613
+ }
614
+ },
615
+ "ibm-granite/granite-guardian-3.3-8b": {
616
+ "model_developer": "IBM",
617
+ "model_type": "specialized",
618
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.3-8b",
619
+ "cost_info": {
620
+ "cost_per_1M_input_tokens": "N/A",
621
+ "cost_per_1M_output_tokens": "N/A",
622
+ "source": "RunPod",
623
+ "cost_per_h": 2.39,
624
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
625
+ },
626
+ "execution_specifications": {
627
+ "type": "Local",
628
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
629
+ }
630
+ },
631
+ "govtech/lionguard-2": {
632
+ "model_developer": "GovTech",
633
+ "model_type": "specialized",
634
+ "url": "https://huggingface.co/govtech/lionguard-2",
635
+ "cost_info": {
636
+ "cost_per_1M_input_tokens": "N/A",
637
+ "cost_per_1M_output_tokens": "N/A",
638
+ "source": "RunPod",
639
+ "cost_per_h": 2.39,
640
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
641
+ },
642
+ "execution_specifications": {
643
+ "type": "Local",
644
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
645
+ }
646
+ },
647
+ "govtech/lionguard-2.1": {
648
+ "model_developer": "GovTech",
649
+ "model_type": "specialized",
650
+ "url": "https://huggingface.co/govtech/lionguard-2.1",
651
+ "cost_info": {
652
+ "cost_per_1M_input_tokens": "N/A",
653
+ "cost_per_1M_output_tokens": "N/A",
654
+ "source": "RunPod",
655
+ "cost_per_h": 2.39,
656
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
657
+ },
658
+ "execution_specifications": {
659
+ "type": "Local",
660
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
661
+ }
662
+ },
663
+ "govtech/lionguard-2-lite": {
664
+ "model_developer": "GovTech",
665
+ "model_type": "specialized",
666
+ "url": "https://huggingface.co/govtech/lionguard-2-lite",
667
+ "cost_info": {
668
+ "cost_per_1M_input_tokens": "N/A",
669
+ "cost_per_1M_output_tokens": "N/A",
670
+ "source": "RunPod",
671
+ "cost_per_h": 2.39,
672
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
673
+ },
674
+ "execution_specifications": {
675
+ "type": "Local",
676
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
677
+ }
678
+ }
679
+ }
data/content_moderation_metrics.json ADDED
@@ -0,0 +1,2702 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "allenai/bells-o-project-content-moderation-input/wildguard": {
3
+ "model_provider_use_case": "allenai",
4
+ "dataset_name": "bells-o-project-content-moderation-input",
5
+ "model_name": "wildguard",
6
+ "accuracy": 0.9209090909090909,
7
+ "accuracy_per_category": {
8
+ "harmful manipulation": 0.92,
9
+ "privacy": 0.93,
10
+ "hate speech": 0.83,
11
+ "sexual content": 0.98,
12
+ "cbrn": 0.93,
13
+ "harm to minors": 0.98,
14
+ "integrity & quality violations": 0.91,
15
+ "illegal activities": 0.94,
16
+ "self-harm": 0.81,
17
+ "physical harm": 0.94,
18
+ "cyber": 0.96
19
+ },
20
+ "fpr": 0.01,
21
+ "mean_latency": 0.16794882569994246,
22
+ "latency_ci_95": {
23
+ "lower": 0.1672896153698199,
24
+ "upper": 0.16860803603006502,
25
+ "mean": 0.16794882569994246,
26
+ "std_dev": 0.012584383679289867,
27
+ "n": 1400
28
+ },
29
+ "provider": "RunPod",
30
+ "model_type": "specialized",
31
+ "model_developer": "AllenAI",
32
+ "model_url": "https://huggingface.co/allenai/wildguard",
33
+ "cost_info": {
34
+ "cost_per_1M_input_tokens": 0.7238035981627982,
35
+ "cost_per_1M_output_tokens": 0.0,
36
+ "cost_per_h": 2.39,
37
+ "cost_source": "RunPod",
38
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
39
+ "total_cost": 0.15609910299777988
40
+ },
41
+ "execution_specifications": {
42
+ "type": "Local",
43
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
44
+ },
45
+ "num_samples": 1400
46
+ },
47
+ "allenai/bells-o-project-content-moderation-output/wildguard": {
48
+ "model_provider_use_case": "allenai",
49
+ "dataset_name": "bells-o-project-content-moderation-output",
50
+ "model_name": "wildguard",
51
+ "accuracy": 0.9,
52
+ "accuracy_per_category": {
53
+ "hate speech": 0.82,
54
+ "physical harm": 0.97,
55
+ "harmful manipulation": 0.83,
56
+ "self-harm": 0.85,
57
+ "privacy": 0.99,
58
+ "cbrn": 0.92,
59
+ "harm to minors": 0.98,
60
+ "cyber": 0.9,
61
+ "sexual content": 0.94,
62
+ "illegal activities": 0.95,
63
+ "integrity & quality violations": 0.75
64
+ },
65
+ "fpr": 0.0,
66
+ "mean_latency": 0.17618908030646188,
67
+ "latency_ci_95": {
68
+ "lower": 0.17568036971954096,
69
+ "upper": 0.1766977908933828,
70
+ "mean": 0.17618908030646188,
71
+ "std_dev": 0.009711330231034699,
72
+ "n": 1400
73
+ },
74
+ "provider": "RunPod",
75
+ "model_type": "specialized",
76
+ "model_developer": "AllenAI",
77
+ "model_url": "https://huggingface.co/allenai/wildguard",
78
+ "cost_info": {
79
+ "cost_per_1M_input_tokens": 0.25754181310468993,
80
+ "cost_per_1M_output_tokens": 0.0,
81
+ "cost_per_h": 2.39,
82
+ "cost_source": "RunPod",
83
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
84
+ "total_cost": 0.1637579618626171
85
+ },
86
+ "execution_specifications": {
87
+ "type": "Local",
88
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
89
+ },
90
+ "num_samples": 1400
91
+ },
92
+ "anthropic/bells-o-project-content-moderation-input/claude-haiku-4-5": {
93
+ "model_provider_use_case": "anthropic",
94
+ "dataset_name": "bells-o-project-content-moderation-input",
95
+ "model_name": "claude-haiku-4-5",
96
+ "accuracy": 0.64,
97
+ "accuracy_per_category": {
98
+ "harmful manipulation": 0.48,
99
+ "privacy": 0.49,
100
+ "hate speech": 0.6,
101
+ "sexual content": 0.74,
102
+ "cbrn": 0.74,
103
+ "harm to minors": 0.94,
104
+ "integrity & quality violations": 0.42,
105
+ "illegal activities": 0.77,
106
+ "self-harm": 0.38,
107
+ "physical harm": 0.67,
108
+ "cyber": 0.81
109
+ },
110
+ "fpr": 0.0,
111
+ "mean_latency": 0.6755487293856485,
112
+ "latency_ci_95": {
113
+ "lower": 0.6616969457280298,
114
+ "upper": 0.6894005130432671,
115
+ "mean": 0.6755487293856485,
116
+ "std_dev": 0.26443177878838336,
117
+ "n": 1400
118
+ },
119
+ "provider": "Anthropic",
120
+ "model_type": "generalist",
121
+ "model_developer": "Anthropic",
122
+ "model_url": "https://platform.claude.com/docs/en/about-claude/models/overview",
123
+ "cost_info": {
124
+ "cost_per_1M_input_tokens": 1.0,
125
+ "cost_per_1M_output_tokens": 5.0,
126
+ "cost_per_h": "N/A",
127
+ "cost_source": "Claude API pricing",
128
+ "cost_additional_info": "",
129
+ "total_cost": 0.145574
130
+ },
131
+ "execution_specifications": {
132
+ "type": "API",
133
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
134
+ },
135
+ "num_samples": 1400
136
+ },
137
+ "anthropic/bells-o-project-content-moderation-input/claude-sonnet-4-5": {
138
+ "model_provider_use_case": "anthropic",
139
+ "dataset_name": "bells-o-project-content-moderation-input",
140
+ "model_name": "claude-sonnet-4-5",
141
+ "accuracy": 0.7909090909090909,
142
+ "accuracy_per_category": {
143
+ "harmful manipulation": 0.73,
144
+ "privacy": 0.68,
145
+ "hate speech": 0.65,
146
+ "sexual content": 0.81,
147
+ "cbrn": 0.94,
148
+ "harm to minors": 0.95,
149
+ "integrity & quality violations": 0.7,
150
+ "illegal activities": 0.87,
151
+ "self-harm": 0.59,
152
+ "physical harm": 0.83,
153
+ "cyber": 0.95
154
+ },
155
+ "fpr": 0.01,
156
+ "mean_latency": 2.0321146711281366,
157
+ "latency_ci_95": {
158
+ "lower": 1.9980452484611515,
159
+ "upper": 2.0661840937951217,
160
+ "mean": 2.0321146711281366,
161
+ "std_dev": 0.6503883009441236,
162
+ "n": 1400
163
+ },
164
+ "provider": "Anthropic",
165
+ "model_type": "generalist",
166
+ "model_developer": "Anthropic",
167
+ "model_url": "https://platform.claude.com/docs/en/about-claude/models/overview",
168
+ "cost_info": {
169
+ "cost_per_1M_input_tokens": 3.0,
170
+ "cost_per_1M_output_tokens": 15.0,
171
+ "cost_per_h": "N/A",
172
+ "cost_source": "Claude API pricing",
173
+ "cost_additional_info": "",
174
+ "total_cost": 0.443607
175
+ },
176
+ "execution_specifications": {
177
+ "type": "API",
178
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
179
+ },
180
+ "num_samples": 1400
181
+ },
182
+ "anthropic/bells-o-project-content-moderation-output/claude-haiku-4-5": {
183
+ "model_provider_use_case": "anthropic",
184
+ "dataset_name": "bells-o-project-content-moderation-output",
185
+ "model_name": "claude-haiku-4-5",
186
+ "accuracy": 0.9118181818181819,
187
+ "accuracy_per_category": {
188
+ "hate speech": 0.78,
189
+ "physical harm": 0.97,
190
+ "harmful manipulation": 0.88,
191
+ "self-harm": 0.88,
192
+ "privacy": 0.91,
193
+ "cbrn": 1.0,
194
+ "harm to minors": 1.0,
195
+ "cyber": 0.97,
196
+ "sexual content": 0.89,
197
+ "illegal activities": 0.96,
198
+ "integrity & quality violations": 0.79
199
+ },
200
+ "fpr": 0.0,
201
+ "mean_latency": 0.660408535855157,
202
+ "latency_ci_95": {
203
+ "lower": 0.6482668563627765,
204
+ "upper": 0.6725502153475376,
205
+ "mean": 0.660408535855157,
206
+ "std_dev": 0.23178573857401796,
207
+ "n": 1400
208
+ },
209
+ "provider": "Anthropic",
210
+ "model_type": "generalist",
211
+ "model_developer": "Anthropic",
212
+ "model_url": "https://platform.claude.com/docs/en/about-claude/models/overview",
213
+ "cost_info": {
214
+ "cost_per_1M_input_tokens": 1.0,
215
+ "cost_per_1M_output_tokens": 5.0,
216
+ "cost_per_h": "N/A",
217
+ "cost_source": "Claude API pricing",
218
+ "cost_additional_info": "",
219
+ "total_cost": 0.545895
220
+ },
221
+ "execution_specifications": {
222
+ "type": "API",
223
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
224
+ },
225
+ "num_samples": 1400
226
+ },
227
+ "anthropic/bells-o-project-content-moderation-output/claude-sonnet-4-5": {
228
+ "model_provider_use_case": "anthropic",
229
+ "dataset_name": "bells-o-project-content-moderation-output",
230
+ "model_name": "claude-sonnet-4-5",
231
+ "accuracy": 0.8690909090909091,
232
+ "accuracy_per_category": {
233
+ "hate speech": 0.65,
234
+ "physical harm": 0.94,
235
+ "harmful manipulation": 0.87,
236
+ "self-harm": 0.76,
237
+ "privacy": 0.86,
238
+ "cbrn": 0.96,
239
+ "harm to minors": 0.99,
240
+ "cyber": 0.97,
241
+ "sexual content": 0.86,
242
+ "illegal activities": 0.95,
243
+ "integrity & quality violations": 0.75
244
+ },
245
+ "fpr": 0.0,
246
+ "mean_latency": 1.980507916041783,
247
+ "latency_ci_95": {
248
+ "lower": 1.9466451605985857,
249
+ "upper": 2.01437067148498,
250
+ "mean": 1.980507916041783,
251
+ "std_dev": 0.6464430053089691,
252
+ "n": 1400
253
+ },
254
+ "provider": "Anthropic",
255
+ "model_type": "generalist",
256
+ "model_developer": "Anthropic",
257
+ "model_url": "https://platform.claude.com/docs/en/about-claude/models/overview",
258
+ "cost_info": {
259
+ "cost_per_1M_input_tokens": 3.0,
260
+ "cost_per_1M_output_tokens": 15.0,
261
+ "cost_per_h": "N/A",
262
+ "cost_source": "Claude API pricing",
263
+ "cost_additional_info": "",
264
+ "total_cost": 1.6417950000000001
265
+ },
266
+ "execution_specifications": {
267
+ "type": "API",
268
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
269
+ },
270
+ "num_samples": 1400
271
+ },
272
+ "aws/bells-o-project-content-moderation-input/bedrock-guardrail": {
273
+ "model_provider_use_case": "aws",
274
+ "dataset_name": "bells-o-project-content-moderation-input",
275
+ "model_name": "bedrock-guardrail",
276
+ "accuracy": 0.7318181818181818,
277
+ "accuracy_per_category": {
278
+ "harmful manipulation": 0.44,
279
+ "privacy": 0.53,
280
+ "hate speech": 0.8,
281
+ "sexual content": 0.93,
282
+ "cbrn": 0.67,
283
+ "harm to minors": 0.93,
284
+ "integrity & quality violations": 0.49,
285
+ "illegal activities": 0.82,
286
+ "self-harm": 0.61,
287
+ "physical harm": 0.91,
288
+ "cyber": 0.92
289
+ },
290
+ "fpr": 0.0,
291
+ "mean_latency": 0.3027071602003915,
292
+ "latency_ci_95": {
293
+ "lower": 0.2893886246223259,
294
+ "upper": 0.3160256957784571,
295
+ "mean": 0.3027071602003915,
296
+ "std_dev": 0.2542520256463307,
297
+ "n": 1400
298
+ },
299
+ "provider": "AWS",
300
+ "model_type": "specialized",
301
+ "model_developer": "Amazon Web Services",
302
+ "model_url": "https://aws.amazon.com/bedrock/guardrails/",
303
+ "cost_info": {
304
+ "cost_per_1M_input_tokens": 150.0,
305
+ "cost_per_1M_output_tokens": 0.0,
306
+ "cost_per_h": "N/A",
307
+ "cost_source": "Amazon Bedrock API pricing",
308
+ "cost_additional_info": "Usage is measured in text units. One text unit may contain up to 1000 characters. Only the input string is considered in the text unit.\n1000 text units cost $0.15. Assuming an average length of 500 characters for a message, and a token length of approx. 4 characters: Estimated cost per 1M input tokens = 1M/(500/4) text units * $0.15/1000 text units) = $1.2.\nCost per 1M input tokens (not units) = 1.2$.",
309
+ "total_cost": 0.2157
310
+ },
311
+ "execution_specifications": {
312
+ "type": "API",
313
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
314
+ },
315
+ "num_samples": 1400
316
+ },
317
+ "aws/bells-o-project-content-moderation-output/bedrock-guardrail": {
318
+ "model_provider_use_case": "aws",
319
+ "dataset_name": "bells-o-project-content-moderation-output",
320
+ "model_name": "bedrock-guardrail",
321
+ "accuracy": 0.78,
322
+ "accuracy_per_category": {
323
+ "hate speech": 0.71,
324
+ "physical harm": 0.96,
325
+ "harmful manipulation": 0.49,
326
+ "self-harm": 0.7,
327
+ "privacy": 0.73,
328
+ "cbrn": 0.83,
329
+ "harm to minors": 0.93,
330
+ "cyber": 0.89,
331
+ "sexual content": 0.94,
332
+ "illegal activities": 0.91,
333
+ "integrity & quality violations": 0.49
334
+ },
335
+ "fpr": 0.0033333333333333335,
336
+ "mean_latency": 0.3212733970369612,
337
+ "latency_ci_95": {
338
+ "lower": 0.3112962016769463,
339
+ "upper": 0.331250592396976,
340
+ "mean": 0.3212733970369612,
341
+ "std_dev": 0.1904655444800315,
342
+ "n": 1400
343
+ },
344
+ "provider": "AWS",
345
+ "model_type": "specialized",
346
+ "model_developer": "Amazon Web Services",
347
+ "model_url": "https://aws.amazon.com/bedrock/guardrails/",
348
+ "cost_info": {
349
+ "cost_per_1M_input_tokens": 150.0,
350
+ "cost_per_1M_output_tokens": 0.0,
351
+ "cost_per_h": "N/A",
352
+ "cost_source": "Amazon Bedrock API pricing",
353
+ "cost_additional_info": "Usage is measured in text units. One text unit may contain up to 1000 characters. Only the input string is considered in the text unit.\n1000 text units cost $0.15. Assuming an average length of 500 characters for a message, and a token length of approx. 4 characters: Estimated cost per 1M input tokens = 1M/(500/4) text units * $0.15/1000 text units) = $1.2.\nCost per 1M input tokens (not units) = 1.2$.",
354
+ "total_cost": 0.3981
355
+ },
356
+ "execution_specifications": {
357
+ "type": "API",
358
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
359
+ },
360
+ "num_samples": 1400
361
+ },
362
+ "azure/bells-o-project-content-moderation-input/analyze-text": {
363
+ "model_provider_use_case": "azure",
364
+ "dataset_name": "bells-o-project-content-moderation-input",
365
+ "model_name": "analyze-text",
366
+ "accuracy": 0.5009090909090909,
367
+ "accuracy_per_category": {
368
+ "harmful manipulation": 0.24,
369
+ "privacy": 0.1,
370
+ "hate speech": 0.87,
371
+ "sexual content": 0.9,
372
+ "cbrn": 0.51,
373
+ "harm to minors": 0.8,
374
+ "integrity & quality violations": 0.13,
375
+ "illegal activities": 0.28,
376
+ "self-harm": 0.89,
377
+ "physical harm": 0.72,
378
+ "cyber": 0.07
379
+ },
380
+ "fpr": 0.01,
381
+ "mean_latency": 0.6510780201639448,
382
+ "latency_ci_95": {
383
+ "lower": 0.6438075360683082,
384
+ "upper": 0.6583485042595814,
385
+ "mean": 0.6510780201639448,
386
+ "std_dev": 0.13879418633602486,
387
+ "n": 1400
388
+ },
389
+ "provider": "Azure",
390
+ "model_type": "specialized",
391
+ "model_developer": "Azure",
392
+ "model_url": "https://learn.microsoft.com/en-us/azure/ai-services/content-safety/overview",
393
+ "cost_info": {
394
+ "cost_per_1M_input_tokens": 380.0,
395
+ "cost_per_1M_output_tokens": 0.0,
396
+ "cost_per_h": "N/A",
397
+ "cost_source": "Azure AI Content Safety",
398
+ "cost_additional_info": "Usage is measured in text records. One text record may contain up to 1000 characters. Only the input string is considered in the text record.\n1000 text records cost $0.38. Assuming an average length of 500 characters for a message, and a token length of approx. 4 characters: Estimated cost per 1M input tokens = 1M/(500/4) text records * $0.38/1000 text records) = $3.04.\nCost per 1M input tokens (not records) = 3.04$.\n\nThe benchmark was run on the free plan.",
399
+ "total_cost": 0.54644
400
+ },
401
+ "execution_specifications": {
402
+ "type": "API",
403
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
404
+ },
405
+ "num_samples": 1400
406
+ },
407
+ "azure/bells-o-project-content-moderation-output/analyze-text": {
408
+ "model_provider_use_case": "azure",
409
+ "dataset_name": "bells-o-project-content-moderation-output",
410
+ "model_name": "analyze-text",
411
+ "accuracy": 0.6090909090909091,
412
+ "accuracy_per_category": {
413
+ "hate speech": 0.92,
414
+ "physical harm": 0.91,
415
+ "harmful manipulation": 0.38,
416
+ "self-harm": 0.86,
417
+ "privacy": 0.26,
418
+ "cbrn": 0.8,
419
+ "harm to minors": 0.71,
420
+ "cyber": 0.16,
421
+ "sexual content": 0.89,
422
+ "illegal activities": 0.47,
423
+ "integrity & quality violations": 0.34
424
+ },
425
+ "fpr": 0.013333333333333334,
426
+ "mean_latency": 0.597562814269747,
427
+ "latency_ci_95": {
428
+ "lower": 0.5849396956294183,
429
+ "upper": 0.6101859329100757,
430
+ "mean": 0.597562814269747,
431
+ "std_dev": 0.24097645461586636,
432
+ "n": 1400
433
+ },
434
+ "provider": "Azure",
435
+ "model_type": "specialized",
436
+ "model_developer": "Azure",
437
+ "model_url": "https://learn.microsoft.com/en-us/azure/ai-services/content-safety/overview",
438
+ "cost_info": {
439
+ "cost_per_1M_input_tokens": 380.0,
440
+ "cost_per_1M_output_tokens": 0.0,
441
+ "cost_per_h": "N/A",
442
+ "cost_source": "Azure AI Content Safety",
443
+ "cost_additional_info": "Usage is measured in text records. One text record may contain up to 1000 characters. Only the input string is considered in the text record.\n1000 text records cost $0.38. Assuming an average length of 500 characters for a message, and a token length of approx. 4 characters: Estimated cost per 1M input tokens = 1M/(500/4) text records * $0.38/1000 text records) = $3.04.\nCost per 1M input tokens (not records) = 3.04$.\n\nThe benchmark was run on the free plan.",
444
+ "total_cost": 1.00852
445
+ },
446
+ "execution_specifications": {
447
+ "type": "API",
448
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
449
+ },
450
+ "num_samples": 1400
451
+ },
452
+ "google/bells-o-project-content-moderation-input/gemini-2.5-flash": {
453
+ "model_provider_use_case": "google",
454
+ "dataset_name": "bells-o-project-content-moderation-input",
455
+ "model_name": "gemini-2.5-flash",
456
+ "accuracy": 0.8818181818181818,
457
+ "accuracy_per_category": {
458
+ "harmful manipulation": 0.95,
459
+ "privacy": 0.98,
460
+ "hate speech": 0.86,
461
+ "sexual content": 0.78,
462
+ "cbrn": 0.99,
463
+ "harm to minors": 0.56,
464
+ "integrity & quality violations": 0.88,
465
+ "illegal activities": 0.98,
466
+ "self-harm": 0.78,
467
+ "physical harm": 0.95,
468
+ "cyber": 0.99
469
+ },
470
+ "fpr": 0.016666666666666666,
471
+ "mean_latency": 1.4193411101613727,
472
+ "latency_ci_95": {
473
+ "lower": 1.3612213357967249,
474
+ "upper": 1.4774608845260204,
475
+ "mean": 1.4193411101613727,
476
+ "std_dev": 1.1095116483118301,
477
+ "n": 1400
478
+ },
479
+ "provider": "GoogleAIStudio",
480
+ "model_type": "generalist",
481
+ "model_developer": "Google",
482
+ "model_url": "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash",
483
+ "cost_info": {
484
+ "cost_per_1M_input_tokens": 0.3,
485
+ "cost_per_1M_output_tokens": 2.5,
486
+ "cost_per_h": "N/A",
487
+ "cost_source": "Gemini Developer API pricing",
488
+ "cost_additional_info": "",
489
+ "total_cost": 0.5480927
490
+ },
491
+ "execution_specifications": {
492
+ "type": "API",
493
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
494
+ },
495
+ "num_samples": 1400
496
+ },
497
+ "google/bells-o-project-content-moderation-input/shieldgemma-27b": {
498
+ "model_provider_use_case": "google",
499
+ "dataset_name": "bells-o-project-content-moderation-input",
500
+ "model_name": "shieldgemma-27b",
501
+ "accuracy": 0.5809090909090909,
502
+ "accuracy_per_category": {
503
+ "harmful manipulation": 0.32,
504
+ "privacy": 0.09,
505
+ "hate speech": 0.73,
506
+ "sexual content": 0.84,
507
+ "cbrn": 0.91,
508
+ "harm to minors": 0.8,
509
+ "integrity & quality violations": 0.18,
510
+ "illegal activities": 0.64,
511
+ "self-harm": 0.72,
512
+ "physical harm": 0.87,
513
+ "cyber": 0.29
514
+ },
515
+ "fpr": 0.0033333333333333335,
516
+ "mean_latency": 0.1099088318007333,
517
+ "latency_ci_95": {
518
+ "lower": 0.1090000827959994,
519
+ "upper": 0.11081758080546719,
520
+ "mean": 0.1099088318007333,
521
+ "std_dev": 0.0173480991137042,
522
+ "n": 1400
523
+ },
524
+ "provider": "RunPod",
525
+ "model_type": "specialized",
526
+ "model_developer": "Google",
527
+ "model_url": "https://huggingface.co/google/shieldgemma-27b",
528
+ "cost_info": {
529
+ "cost_per_1M_input_tokens": 0.19256129687083262,
530
+ "cost_per_1M_output_tokens": 0.0,
531
+ "cost_per_h": 2.39,
532
+ "cost_source": "RunPod",
533
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
534
+ "total_cost": 0.10215415311257045
535
+ },
536
+ "execution_specifications": {
537
+ "type": "Local",
538
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
539
+ },
540
+ "num_samples": 1400
541
+ },
542
+ "google/bells-o-project-content-moderation-input/shieldgemma-2b": {
543
+ "model_provider_use_case": "google",
544
+ "dataset_name": "bells-o-project-content-moderation-input",
545
+ "model_name": "shieldgemma-2b",
546
+ "accuracy": 0.24818181818181817,
547
+ "accuracy_per_category": {
548
+ "harmful manipulation": 0.08,
549
+ "privacy": 0.02,
550
+ "hate speech": 0.1,
551
+ "sexual content": 0.21,
552
+ "cbrn": 0.48,
553
+ "harm to minors": 0.34,
554
+ "integrity & quality violations": 0.05,
555
+ "illegal activities": 0.38,
556
+ "self-harm": 0.39,
557
+ "physical harm": 0.53,
558
+ "cyber": 0.15
559
+ },
560
+ "fpr": 0.01,
561
+ "mean_latency": 0.031726044927324566,
562
+ "latency_ci_95": {
563
+ "lower": 0.031453915259710516,
564
+ "upper": 0.031998174594938616,
565
+ "mean": 0.031726044927324566,
566
+ "std_dev": 0.005194979494839089,
567
+ "n": 1400
568
+ },
569
+ "provider": "RunPod",
570
+ "model_type": "specialized",
571
+ "model_developer": "Google",
572
+ "model_url": "https://huggingface.co/google/shieldgemma-2b",
573
+ "cost_info": {
574
+ "cost_per_1M_input_tokens": 0.05558432617011184,
575
+ "cost_per_1M_output_tokens": 0.0,
576
+ "cost_per_h": 2.39,
577
+ "cost_source": "RunPod",
578
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
579
+ "total_cost": 0.02948759620189667
580
+ },
581
+ "execution_specifications": {
582
+ "type": "Local",
583
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
584
+ },
585
+ "num_samples": 1400
586
+ },
587
+ "google/bells-o-project-content-moderation-output/gemini-2.5-flash": {
588
+ "model_provider_use_case": "google",
589
+ "dataset_name": "bells-o-project-content-moderation-output",
590
+ "model_name": "gemini-2.5-flash",
591
+ "accuracy": 0.8909090909090909,
592
+ "accuracy_per_category": {
593
+ "hate speech": 0.88,
594
+ "physical harm": 0.98,
595
+ "harmful manipulation": 0.91,
596
+ "self-harm": 0.92,
597
+ "privacy": 0.97,
598
+ "cbrn": 0.97,
599
+ "harm to minors": 0.6,
600
+ "cyber": 0.95,
601
+ "sexual content": 0.83,
602
+ "illegal activities": 0.91,
603
+ "integrity & quality violations": 0.88
604
+ },
605
+ "fpr": 0.0,
606
+ "mean_latency": 2.131153161866324,
607
+ "latency_ci_95": {
608
+ "lower": 2.0531708906747133,
609
+ "upper": 2.209135433057935,
610
+ "mean": 2.131153161866324,
611
+ "std_dev": 1.4886884747015303,
612
+ "n": 1400
613
+ },
614
+ "provider": "GoogleAIStudio",
615
+ "model_type": "generalist",
616
+ "model_developer": "Google",
617
+ "model_url": "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash",
618
+ "cost_info": {
619
+ "cost_per_1M_input_tokens": 0.3,
620
+ "cost_per_1M_output_tokens": 2.5,
621
+ "cost_per_h": "N/A",
622
+ "cost_source": "Gemini Developer API pricing",
623
+ "cost_additional_info": "",
624
+ "total_cost": 1.1270327
625
+ },
626
+ "execution_specifications": {
627
+ "type": "API",
628
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
629
+ },
630
+ "num_samples": 1400
631
+ },
632
+ "google/bells-o-project-content-moderation-output/shieldgemma-27b": {
633
+ "model_provider_use_case": "google",
634
+ "dataset_name": "bells-o-project-content-moderation-output",
635
+ "model_name": "shieldgemma-27b",
636
+ "accuracy": 0.6336363636363637,
637
+ "accuracy_per_category": {
638
+ "hate speech": 0.73,
639
+ "physical harm": 0.91,
640
+ "harmful manipulation": 0.42,
641
+ "self-harm": 0.74,
642
+ "privacy": 0.32,
643
+ "cbrn": 0.96,
644
+ "harm to minors": 0.75,
645
+ "cyber": 0.33,
646
+ "sexual content": 0.82,
647
+ "illegal activities": 0.7,
648
+ "integrity & quality violations": 0.29
649
+ },
650
+ "fpr": 0.006666666666666667,
651
+ "mean_latency": 0.13334267480032785,
652
+ "latency_ci_95": {
653
+ "lower": 0.13205096274443018,
654
+ "upper": 0.13463438685622553,
655
+ "mean": 0.13334267480032785,
656
+ "std_dev": 0.024658897732318774,
657
+ "n": 1400
658
+ },
659
+ "provider": "RunPod",
660
+ "model_type": "specialized",
661
+ "model_developer": "Google",
662
+ "model_url": "https://huggingface.co/google/shieldgemma-27b",
663
+ "cost_info": {
664
+ "cost_per_1M_input_tokens": 0.1388315066243309,
665
+ "cost_per_1M_output_tokens": 0.0,
666
+ "cost_per_h": 2.39,
667
+ "cost_source": "RunPod",
668
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
669
+ "total_cost": 0.12393460830052694
670
+ },
671
+ "execution_specifications": {
672
+ "type": "Local",
673
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
674
+ },
675
+ "num_samples": 1400
676
+ },
677
+ "google/bells-o-project-content-moderation-output/shieldgemma-2b": {
678
+ "model_provider_use_case": "google",
679
+ "dataset_name": "bells-o-project-content-moderation-output",
680
+ "model_name": "shieldgemma-2b",
681
+ "accuracy": 0.26636363636363636,
682
+ "accuracy_per_category": {
683
+ "hate speech": 0.17,
684
+ "physical harm": 0.58,
685
+ "harmful manipulation": 0.14,
686
+ "self-harm": 0.44,
687
+ "privacy": 0.08,
688
+ "cbrn": 0.38,
689
+ "harm to minors": 0.34,
690
+ "cyber": 0.14,
691
+ "sexual content": 0.22,
692
+ "illegal activities": 0.39,
693
+ "integrity & quality violations": 0.05
694
+ },
695
+ "fpr": 0.006666666666666667,
696
+ "mean_latency": 0.037216948441096714,
697
+ "latency_ci_95": {
698
+ "lower": 0.036785634085487344,
699
+ "upper": 0.037648262796706085,
700
+ "mean": 0.037216948441096714,
701
+ "std_dev": 0.008233829309629823,
702
+ "n": 1400
703
+ },
704
+ "provider": "RunPod",
705
+ "model_type": "specialized",
706
+ "model_developer": "Google",
707
+ "model_url": "https://huggingface.co/google/shieldgemma-2b",
708
+ "cost_info": {
709
+ "cost_per_1M_input_tokens": 0.03874892289189925,
710
+ "cost_per_1M_output_tokens": 0.0,
711
+ "cost_per_h": 2.39,
712
+ "cost_source": "RunPod",
713
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
714
+ "total_cost": 0.03459108596775267
715
+ },
716
+ "execution_specifications": {
717
+ "type": "Local",
718
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
719
+ },
720
+ "num_samples": 1400
721
+ },
722
+ "govtech/bells-o-project-content-moderation-input/lionguard-2": {
723
+ "model_provider_use_case": "govtech",
724
+ "dataset_name": "bells-o-project-content-moderation-input",
725
+ "model_name": "lionguard-2",
726
+ "accuracy": 0.8845454545454545,
727
+ "accuracy_per_category": {
728
+ "harmful manipulation": 0.83,
729
+ "privacy": 0.67,
730
+ "hate speech": 0.83,
731
+ "sexual content": 0.98,
732
+ "cbrn": 0.91,
733
+ "harm to minors": 0.97,
734
+ "integrity & quality violations": 0.79,
735
+ "illegal activities": 0.96,
736
+ "self-harm": 0.93,
737
+ "physical harm": 0.92,
738
+ "cyber": 0.94
739
+ },
740
+ "fpr": 0.01,
741
+ "mean_latency": 0.009503273112433297,
742
+ "latency_ci_95": {
743
+ "lower": 0.009311582881572434,
744
+ "upper": 0.00969496334329416,
745
+ "mean": 0.009503273112433297,
746
+ "std_dev": 0.0036593835115966812,
747
+ "n": 1400
748
+ },
749
+ "provider": "RunPod",
750
+ "model_type": "specialized",
751
+ "model_developer": "GovTech",
752
+ "model_url": "https://huggingface.co/govtech/lionguard-2",
753
+ "cost_info": {
754
+ "cost_per_1M_input_tokens": 0.1812443960764434,
755
+ "cost_per_1M_output_tokens": 0.0,
756
+ "cost_per_h": 2.39,
757
+ "cost_source": "RunPod",
758
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
759
+ "total_cost": 0.008832764398389393
760
+ },
761
+ "execution_specifications": {
762
+ "type": "Local",
763
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
764
+ },
765
+ "num_samples": 1400
766
+ },
767
+ "govtech/bells-o-project-content-moderation-output/lionguard-2": {
768
+ "model_provider_use_case": "govtech",
769
+ "dataset_name": "bells-o-project-content-moderation-output",
770
+ "model_name": "lionguard-2",
771
+ "accuracy": 0.9036363636363637,
772
+ "accuracy_per_category": {
773
+ "hate speech": 0.79,
774
+ "physical harm": 0.98,
775
+ "harmful manipulation": 0.77,
776
+ "self-harm": 0.94,
777
+ "privacy": 0.85,
778
+ "cbrn": 0.95,
779
+ "harm to minors": 0.96,
780
+ "cyber": 0.93,
781
+ "sexual content": 0.99,
782
+ "illegal activities": 0.97,
783
+ "integrity & quality violations": 0.81
784
+ },
785
+ "fpr": 0.01,
786
+ "mean_latency": 0.009445810999189104,
787
+ "latency_ci_95": {
788
+ "lower": 0.009313593155526146,
789
+ "upper": 0.009578028842852061,
790
+ "mean": 0.009445810999189104,
791
+ "std_dev": 0.0025240503643103483,
792
+ "n": 1400
793
+ },
794
+ "provider": "RunPod",
795
+ "model_type": "specialized",
796
+ "model_developer": "GovTech",
797
+ "model_url": "https://huggingface.co/govtech/lionguard-2",
798
+ "cost_info": {
799
+ "cost_per_1M_input_tokens": 0.021758170584833442,
800
+ "cost_per_1M_output_tokens": 0.0,
801
+ "cost_per_h": 2.39,
802
+ "cost_source": "RunPod",
803
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
804
+ "total_cost": 0.00877935655646854
805
+ },
806
+ "execution_specifications": {
807
+ "type": "Local",
808
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
809
+ },
810
+ "num_samples": 1400
811
+ },
812
+ "ibm-granite/bells-o-project-content-moderation-input/granite-guardian-3.3-8b": {
813
+ "model_provider_use_case": "ibm-granite",
814
+ "dataset_name": "bells-o-project-content-moderation-input",
815
+ "model_name": "granite-guardian-3.3-8b",
816
+ "accuracy": 0.9272727272727272,
817
+ "accuracy_per_category": {
818
+ "harmful manipulation": 0.94,
819
+ "privacy": 0.92,
820
+ "hate speech": 0.84,
821
+ "sexual content": 0.97,
822
+ "cbrn": 1.0,
823
+ "harm to minors": 0.99,
824
+ "integrity & quality violations": 0.8,
825
+ "illegal activities": 0.98,
826
+ "self-harm": 0.8,
827
+ "physical harm": 0.98,
828
+ "cyber": 0.98
829
+ },
830
+ "fpr": 0.0033333333333333335,
831
+ "mean_latency": 0.19252273099763054,
832
+ "latency_ci_95": {
833
+ "lower": 0.19230705557305205,
834
+ "upper": 0.19273840642220902,
835
+ "mean": 0.19252273099763054,
836
+ "std_dev": 0.004117262987345297,
837
+ "n": 1400
838
+ },
839
+ "provider": "RunPod",
840
+ "model_type": "specialized",
841
+ "model_developer": "IBM",
842
+ "model_url": "https://huggingface.co/ibm-granite/granite-guardian-3.3-8b",
843
+ "cost_info": {
844
+ "cost_per_1M_input_tokens": 0.8130975128709368,
845
+ "cost_per_1M_output_tokens": 0.0,
846
+ "cost_per_h": 2.39,
847
+ "cost_source": "RunPod",
848
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
849
+ "total_cost": 0.17893918275501994
850
+ },
851
+ "execution_specifications": {
852
+ "type": "Local",
853
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
854
+ },
855
+ "num_samples": 1400
856
+ },
857
+ "ibm-granite/bells-o-project-content-moderation-output/granite-guardian-3.3-8b": {
858
+ "model_provider_use_case": "ibm-granite",
859
+ "dataset_name": "bells-o-project-content-moderation-output",
860
+ "model_name": "granite-guardian-3.3-8b",
861
+ "accuracy": 0.9054545454545454,
862
+ "accuracy_per_category": {
863
+ "hate speech": 0.86,
864
+ "physical harm": 0.99,
865
+ "harmful manipulation": 0.78,
866
+ "self-harm": 0.85,
867
+ "privacy": 0.91,
868
+ "cbrn": 0.99,
869
+ "harm to minors": 0.99,
870
+ "cyber": 0.94,
871
+ "sexual content": 0.98,
872
+ "illegal activities": 0.93,
873
+ "integrity & quality violations": 0.74
874
+ },
875
+ "fpr": 0.0,
876
+ "mean_latency": 0.20689634186880929,
877
+ "latency_ci_95": {
878
+ "lower": 0.2061988732441346,
879
+ "upper": 0.20759381049348397,
880
+ "mean": 0.20689634186880929,
881
+ "std_dev": 0.013314737916107277,
882
+ "n": 1400
883
+ },
884
+ "provider": "RunPod",
885
+ "model_type": "specialized",
886
+ "model_developer": "IBM",
887
+ "model_url": "https://huggingface.co/ibm-granite/granite-guardian-3.3-8b",
888
+ "cost_info": {
889
+ "cost_per_1M_input_tokens": 0.2968973859968493,
890
+ "cost_per_1M_output_tokens": 0.0,
891
+ "cost_per_h": 2.39,
892
+ "cost_source": "RunPod",
893
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
894
+ "total_cost": 0.1922986555258433
895
+ },
896
+ "execution_specifications": {
897
+ "type": "Local",
898
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
899
+ },
900
+ "num_samples": 1400
901
+ },
902
+ "lakera/bells-o-project-content-moderation-input/lakera-guard_default": {
903
+ "model_provider_use_case": "lakera",
904
+ "dataset_name": "bells-o-project-content-moderation-input",
905
+ "model_name": "lakera-guard_default",
906
+ "accuracy": 0.9081818181818182,
907
+ "accuracy_per_category": {
908
+ "harmful manipulation": 0.9,
909
+ "privacy": 0.84,
910
+ "hate speech": 0.87,
911
+ "sexual content": 1.0,
912
+ "cbrn": 0.97,
913
+ "harm to minors": 0.98,
914
+ "integrity & quality violations": 0.78,
915
+ "illegal activities": 0.95,
916
+ "self-harm": 0.79,
917
+ "physical harm": 0.96,
918
+ "cyber": 0.95
919
+ },
920
+ "fpr": 0.16,
921
+ "mean_latency": 0.20956397243908473,
922
+ "latency_ci_95": {
923
+ "lower": 0.20730703245330986,
924
+ "upper": 0.2118209124248596,
925
+ "mean": 0.20956397243908473,
926
+ "std_dev": 0.04308518453714262,
927
+ "n": 1400
928
+ },
929
+ "provider": "Lakera",
930
+ "model_type": "specialized",
931
+ "model_developer": "Lakera",
932
+ "model_url": "https://www.lakera.ai/lakera-guard",
933
+ "cost_info": {
934
+ "cost_per_1M_input_tokens": 0.0,
935
+ "cost_per_1M_output_tokens": 0.0,
936
+ "cost_per_h": "N/A",
937
+ "cost_source": "Lakera API pricing",
938
+ "cost_additional_info": "Free for 10,000 API requests/month; Allows prompt size up to 8,000 tokens per request.",
939
+ "total_cost": 0.0
940
+ },
941
+ "execution_specifications": {
942
+ "type": "API",
943
+ "details": "This is the LakeraGuard API with the default policy. REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
944
+ },
945
+ "num_samples": 1400
946
+ },
947
+ "lakera/bells-o-project-content-moderation-output/lakera-guard_default": {
948
+ "model_provider_use_case": "lakera",
949
+ "dataset_name": "bells-o-project-content-moderation-output",
950
+ "model_name": "lakera-guard_default",
951
+ "accuracy": 0.860909090909091,
952
+ "accuracy_per_category": {
953
+ "hate speech": 0.77,
954
+ "physical harm": 0.96,
955
+ "harmful manipulation": 0.76,
956
+ "self-harm": 0.84,
957
+ "privacy": 0.88,
958
+ "cbrn": 0.89,
959
+ "harm to minors": 0.91,
960
+ "cyber": 0.87,
961
+ "sexual content": 0.96,
962
+ "illegal activities": 0.94,
963
+ "integrity & quality violations": 0.69
964
+ },
965
+ "fpr": 0.14333333333333334,
966
+ "mean_latency": 0.20940651042120798,
967
+ "latency_ci_95": {
968
+ "lower": 0.20735007341754588,
969
+ "upper": 0.21146294742487007,
970
+ "mean": 0.20940651042120798,
971
+ "std_dev": 0.03925756482238554,
972
+ "n": 1400
973
+ },
974
+ "provider": "Lakera",
975
+ "model_type": "specialized",
976
+ "model_developer": "Lakera",
977
+ "model_url": "https://www.lakera.ai/lakera-guard",
978
+ "cost_info": {
979
+ "cost_per_1M_input_tokens": 0.0,
980
+ "cost_per_1M_output_tokens": 0.0,
981
+ "cost_per_h": "N/A",
982
+ "cost_source": "Lakera API pricing",
983
+ "cost_additional_info": "Free for 10,000 API requests/month; Allows prompt size up to 8,000 tokens per request.",
984
+ "total_cost": 0.0
985
+ },
986
+ "execution_specifications": {
987
+ "type": "API",
988
+ "details": "This is the LakeraGuard API with the default policy. REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
989
+ },
990
+ "num_samples": 1400
991
+ },
992
+ "meta/bells-o-project-content-moderation-input/llama-guard-4-12b": {
993
+ "model_provider_use_case": "meta",
994
+ "dataset_name": "bells-o-project-content-moderation-input",
995
+ "model_name": "llama-guard-4-12b",
996
+ "accuracy": 0.7054545454545454,
997
+ "accuracy_per_category": {
998
+ "harmful manipulation": 0.49,
999
+ "privacy": 0.69,
1000
+ "hate speech": 0.42,
1001
+ "sexual content": 0.79,
1002
+ "cbrn": 0.78,
1003
+ "harm to minors": 0.87,
1004
+ "integrity & quality violations": 0.47,
1005
+ "illegal activities": 0.84,
1006
+ "self-harm": 0.69,
1007
+ "physical harm": 0.86,
1008
+ "cyber": 0.86
1009
+ },
1010
+ "fpr": 0.03,
1011
+ "mean_latency": 0.2919416810785021,
1012
+ "latency_ci_95": {
1013
+ "lower": 0.2889681782255528,
1014
+ "upper": 0.2949151839314514,
1015
+ "mean": 0.2919416810785021,
1016
+ "std_dev": 0.05676443323638302,
1017
+ "n": 1400
1018
+ },
1019
+ "provider": "Together AI",
1020
+ "model_type": "specialized",
1021
+ "model_developer": "Meta",
1022
+ "model_url": "https://www.llama.com/docs/model-cards-and-prompt-formats/llama-guard-4/",
1023
+ "cost_info": {
1024
+ "cost_per_1M_input_tokens": 0.2,
1025
+ "cost_per_1M_output_tokens": 0.0,
1026
+ "cost_per_h": "N/A",
1027
+ "cost_source": "Together AI pricing",
1028
+ "cost_additional_info": "",
1029
+ "total_cost": 0.0671434
1030
+ },
1031
+ "execution_specifications": {
1032
+ "type": "API",
1033
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1034
+ },
1035
+ "num_samples": 1400
1036
+ },
1037
+ "meta/bells-o-project-content-moderation-output/llama-guard-4-12b": {
1038
+ "model_provider_use_case": "meta",
1039
+ "dataset_name": "bells-o-project-content-moderation-output",
1040
+ "model_name": "llama-guard-4-12b",
1041
+ "accuracy": 0.8036363636363636,
1042
+ "accuracy_per_category": {
1043
+ "hate speech": 0.62,
1044
+ "physical harm": 0.94,
1045
+ "harmful manipulation": 0.54,
1046
+ "self-harm": 0.88,
1047
+ "privacy": 0.85,
1048
+ "cbrn": 0.94,
1049
+ "harm to minors": 0.95,
1050
+ "cyber": 0.89,
1051
+ "sexual content": 0.89,
1052
+ "illegal activities": 0.9,
1053
+ "integrity & quality violations": 0.44
1054
+ },
1055
+ "fpr": 0.04,
1056
+ "mean_latency": 0.3172705331870488,
1057
+ "latency_ci_95": {
1058
+ "lower": 0.29924274832923003,
1059
+ "upper": 0.33529831804486754,
1060
+ "mean": 0.3172705331870488,
1061
+ "std_dev": 0.3441520121450457,
1062
+ "n": 1400
1063
+ },
1064
+ "provider": "Together AI",
1065
+ "model_type": "specialized",
1066
+ "model_developer": "Meta",
1067
+ "model_url": "https://www.llama.com/docs/model-cards-and-prompt-formats/llama-guard-4/",
1068
+ "cost_info": {
1069
+ "cost_per_1M_input_tokens": 0.2,
1070
+ "cost_per_1M_output_tokens": 0.0,
1071
+ "cost_per_h": "N/A",
1072
+ "cost_source": "Together AI pricing",
1073
+ "cost_additional_info": "",
1074
+ "total_cost": 0.1373716
1075
+ },
1076
+ "execution_specifications": {
1077
+ "type": "API",
1078
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1079
+ },
1080
+ "num_samples": 1400
1081
+ },
1082
+ "mistral/bells-o-project-content-moderation-input/ministral-3b-2512": {
1083
+ "model_provider_use_case": "mistral",
1084
+ "dataset_name": "bells-o-project-content-moderation-input",
1085
+ "model_name": "ministral-3b-2512",
1086
+ "accuracy": 0.9345454545454546,
1087
+ "accuracy_per_category": {
1088
+ "harmful manipulation": 0.94,
1089
+ "privacy": 0.86,
1090
+ "hate speech": 0.9,
1091
+ "sexual content": 0.97,
1092
+ "cbrn": 0.95,
1093
+ "harm to minors": 0.96,
1094
+ "integrity & quality violations": 0.86,
1095
+ "illegal activities": 0.95,
1096
+ "self-harm": 0.96,
1097
+ "physical harm": 0.97,
1098
+ "cyber": 0.96
1099
+ },
1100
+ "fpr": 0.023333333333333334,
1101
+ "mean_latency": 0.4279132558618273,
1102
+ "latency_ci_95": {
1103
+ "lower": 0.4038809537163048,
1104
+ "upper": 0.45194555800734987,
1105
+ "mean": 0.4279132558618273,
1106
+ "std_dev": 0.4587787798162123,
1107
+ "n": 1400
1108
+ },
1109
+ "provider": "Mistral",
1110
+ "model_type": "generalist",
1111
+ "model_developer": "Mistral AI",
1112
+ "model_url": "https://docs.mistral.ai/models/ministral-3-3b-25-12",
1113
+ "cost_info": {
1114
+ "cost_per_1M_input_tokens": 0.04,
1115
+ "cost_per_1M_output_tokens": 0.04,
1116
+ "cost_per_h": "N/A",
1117
+ "cost_source": "Ministral API pricing",
1118
+ "cost_additional_info": "",
1119
+ "total_cost": 0.00413752
1120
+ },
1121
+ "execution_specifications": {
1122
+ "type": "API",
1123
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1124
+ },
1125
+ "num_samples": 1400
1126
+ },
1127
+ "mistral/bells-o-project-content-moderation-input/mistral-large-3": {
1128
+ "model_provider_use_case": "mistral",
1129
+ "dataset_name": "bells-o-project-content-moderation-input",
1130
+ "model_name": "mistral-large-3",
1131
+ "accuracy": 0.9072727272727272,
1132
+ "accuracy_per_category": {
1133
+ "harmful manipulation": 0.88,
1134
+ "privacy": 0.79,
1135
+ "hate speech": 0.85,
1136
+ "sexual content": 0.96,
1137
+ "cbrn": 0.96,
1138
+ "harm to minors": 0.97,
1139
+ "integrity & quality violations": 0.75,
1140
+ "illegal activities": 0.95,
1141
+ "self-harm": 0.93,
1142
+ "physical harm": 0.97,
1143
+ "cyber": 0.97
1144
+ },
1145
+ "fpr": 0.0033333333333333335,
1146
+ "mean_latency": 0.7675250434875488,
1147
+ "latency_ci_95": {
1148
+ "lower": 0.7033643424555687,
1149
+ "upper": 0.8316857445195289,
1150
+ "mean": 0.7675250434875488,
1151
+ "std_dev": 1.2248334742699123,
1152
+ "n": 1400
1153
+ },
1154
+ "provider": "Mistral",
1155
+ "model_type": "generalist",
1156
+ "model_developer": "Mistral AI",
1157
+ "model_url": "https://docs.mistral.ai/models/mistral-large-3-25-12",
1158
+ "cost_info": {
1159
+ "cost_per_1M_input_tokens": 4.0,
1160
+ "cost_per_1M_output_tokens": 12.0,
1161
+ "cost_per_h": "N/A",
1162
+ "cost_source": "Mistral API pricing",
1163
+ "cost_additional_info": "",
1164
+ "total_cost": 0.43615200000000004
1165
+ },
1166
+ "execution_specifications": {
1167
+ "type": "API",
1168
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1169
+ },
1170
+ "num_samples": 1400
1171
+ },
1172
+ "mistral/bells-o-project-content-moderation-output/ministral-3b-2512": {
1173
+ "model_provider_use_case": "mistral",
1174
+ "dataset_name": "bells-o-project-content-moderation-output",
1175
+ "model_name": "ministral-3b-2512",
1176
+ "accuracy": 0.9518181818181818,
1177
+ "accuracy_per_category": {
1178
+ "hate speech": 0.97,
1179
+ "physical harm": 0.98,
1180
+ "harmful manipulation": 0.92,
1181
+ "self-harm": 0.9,
1182
+ "privacy": 0.91,
1183
+ "cbrn": 1.0,
1184
+ "harm to minors": 0.98,
1185
+ "cyber": 0.97,
1186
+ "sexual content": 0.93,
1187
+ "illegal activities": 0.99,
1188
+ "integrity & quality violations": 0.92
1189
+ },
1190
+ "fpr": 0.07,
1191
+ "mean_latency": 0.4416024809224265,
1192
+ "latency_ci_95": {
1193
+ "lower": 0.41586757287002707,
1194
+ "upper": 0.4673373889748259,
1195
+ "mean": 0.4416024809224265,
1196
+ "std_dev": 0.491281677613309,
1197
+ "n": 1400
1198
+ },
1199
+ "provider": "Mistral",
1200
+ "model_type": "generalist",
1201
+ "model_developer": "Mistral AI",
1202
+ "model_url": "https://docs.mistral.ai/models/ministral-3-3b-25-12",
1203
+ "cost_info": {
1204
+ "cost_per_1M_input_tokens": 0.04,
1205
+ "cost_per_1M_output_tokens": 0.04,
1206
+ "cost_per_h": "N/A",
1207
+ "cost_source": "Ministral API pricing",
1208
+ "cost_additional_info": "",
1209
+ "total_cost": 0.01877732
1210
+ },
1211
+ "execution_specifications": {
1212
+ "type": "API",
1213
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1214
+ },
1215
+ "num_samples": 1400
1216
+ },
1217
+ "mistral/bells-o-project-content-moderation-output/mistral-large-3": {
1218
+ "model_provider_use_case": "mistral",
1219
+ "dataset_name": "bells-o-project-content-moderation-output",
1220
+ "model_name": "mistral-large-3",
1221
+ "accuracy": 0.9190909090909091,
1222
+ "accuracy_per_category": {
1223
+ "hate speech": 0.94,
1224
+ "physical harm": 0.99,
1225
+ "harmful manipulation": 0.78,
1226
+ "self-harm": 0.9,
1227
+ "privacy": 0.96,
1228
+ "cbrn": 0.99,
1229
+ "harm to minors": 1.0,
1230
+ "cyber": 0.94,
1231
+ "sexual content": 0.92,
1232
+ "illegal activities": 0.92,
1233
+ "integrity & quality violations": 0.77
1234
+ },
1235
+ "fpr": 0.0,
1236
+ "mean_latency": 0.8493295400483267,
1237
+ "latency_ci_95": {
1238
+ "lower": 0.7685226981889265,
1239
+ "upper": 0.930136381907727,
1240
+ "mean": 0.8493295400483267,
1241
+ "std_dev": 1.5426097793117277,
1242
+ "n": 1400
1243
+ },
1244
+ "provider": "Mistral",
1245
+ "model_type": "generalist",
1246
+ "model_developer": "Mistral AI",
1247
+ "model_url": "https://docs.mistral.ai/models/mistral-large-3-25-12",
1248
+ "cost_info": {
1249
+ "cost_per_1M_input_tokens": 4.0,
1250
+ "cost_per_1M_output_tokens": 12.0,
1251
+ "cost_per_h": "N/A",
1252
+ "cost_source": "Mistral API pricing",
1253
+ "cost_additional_info": "",
1254
+ "total_cost": 1.898772
1255
+ },
1256
+ "execution_specifications": {
1257
+ "type": "API",
1258
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1259
+ },
1260
+ "num_samples": 1400
1261
+ },
1262
+ "nvidia/bells-o-project-content-moderation-input/llama-3.1-nemotron-safety-guard-8b-v3": {
1263
+ "model_provider_use_case": "nvidia",
1264
+ "dataset_name": "bells-o-project-content-moderation-input",
1265
+ "model_name": "llama-3.1-nemotron-safety-guard-8b-v3",
1266
+ "accuracy": 0.8636363636363636,
1267
+ "accuracy_per_category": {
1268
+ "harmful manipulation": 0.62,
1269
+ "privacy": 0.9,
1270
+ "hate speech": 0.78,
1271
+ "sexual content": 0.97,
1272
+ "cbrn": 0.94,
1273
+ "harm to minors": 0.93,
1274
+ "integrity & quality violations": 0.66,
1275
+ "illegal activities": 0.92,
1276
+ "self-harm": 0.85,
1277
+ "physical harm": 0.97,
1278
+ "cyber": 0.96
1279
+ },
1280
+ "fpr": 0.043333333333333335,
1281
+ "mean_latency": 0.15576645374298095,
1282
+ "latency_ci_95": {
1283
+ "lower": 0.15397129295656875,
1284
+ "upper": 0.15756161452939316,
1285
+ "mean": 0.15576645374298095,
1286
+ "std_dev": 0.03426977865778628,
1287
+ "n": 1400
1288
+ },
1289
+ "provider": "RunPod",
1290
+ "model_type": "specialized",
1291
+ "model_developer": "NVIDIA",
1292
+ "model_url": "https://huggingface.co/nvidia/Llama-3.1-Nemotron-Safety-Guard-8B-v3",
1293
+ "cost_info": {
1294
+ "cost_per_1M_input_tokens": 0.22782226487771615,
1295
+ "cost_per_1M_output_tokens": 0.0,
1296
+ "cost_per_h": 2.39,
1297
+ "cost_source": "RunPod",
1298
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
1299
+ "total_cost": 0.14477626506222618
1300
+ },
1301
+ "execution_specifications": {
1302
+ "type": "Local",
1303
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
1304
+ },
1305
+ "num_samples": 1400
1306
+ },
1307
+ "nvidia/bells-o-project-content-moderation-output/llama-3.1-nemotron-safety-guard-8b-v3": {
1308
+ "model_provider_use_case": "nvidia",
1309
+ "dataset_name": "bells-o-project-content-moderation-output",
1310
+ "model_name": "llama-3.1-nemotron-safety-guard-8b-v3",
1311
+ "accuracy": 0.9054545454545454,
1312
+ "accuracy_per_category": {
1313
+ "hate speech": 0.87,
1314
+ "physical harm": 0.99,
1315
+ "harmful manipulation": 0.73,
1316
+ "self-harm": 0.86,
1317
+ "privacy": 0.96,
1318
+ "cbrn": 1.0,
1319
+ "harm to minors": 0.95,
1320
+ "cyber": 0.95,
1321
+ "sexual content": 0.97,
1322
+ "illegal activities": 0.96,
1323
+ "integrity & quality violations": 0.72
1324
+ },
1325
+ "fpr": 0.056666666666666664,
1326
+ "mean_latency": 0.18621215888432094,
1327
+ "latency_ci_95": {
1328
+ "lower": 0.18557276212673715,
1329
+ "upper": 0.18685155564190473,
1330
+ "mean": 0.18621215888432094,
1331
+ "std_dev": 0.01220614082190163,
1332
+ "n": 1400
1333
+ },
1334
+ "provider": "RunPod",
1335
+ "model_type": "specialized",
1336
+ "model_developer": "NVIDIA",
1337
+ "model_url": "https://huggingface.co/nvidia/Llama-3.1-Nemotron-Safety-Guard-8B-v3",
1338
+ "cost_info": {
1339
+ "cost_per_1M_input_tokens": 0.17354468328880082,
1340
+ "cost_per_1M_output_tokens": 0.0,
1341
+ "cost_per_h": 2.39,
1342
+ "cost_source": "RunPod",
1343
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
1344
+ "total_cost": 0.1730738565630383
1345
+ },
1346
+ "execution_specifications": {
1347
+ "type": "Local",
1348
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
1349
+ },
1350
+ "num_samples": 1400
1351
+ },
1352
+ "openai/bells-o-project-content-moderation-input/gpt-5-nano": {
1353
+ "model_provider_use_case": "openai",
1354
+ "dataset_name": "bells-o-project-content-moderation-input",
1355
+ "model_name": "gpt-5-nano",
1356
+ "accuracy": 0.9254545454545454,
1357
+ "accuracy_per_category": {
1358
+ "harmful manipulation": 0.98,
1359
+ "privacy": 0.96,
1360
+ "hate speech": 0.8,
1361
+ "sexual content": 0.75,
1362
+ "cbrn": 1.0,
1363
+ "harm to minors": 0.98,
1364
+ "integrity & quality violations": 0.79,
1365
+ "illegal activities": 1.0,
1366
+ "self-harm": 0.92,
1367
+ "physical harm": 1.0,
1368
+ "cyber": 1.0
1369
+ },
1370
+ "fpr": 0.006666666666666667,
1371
+ "mean_latency": 1.5597400277001516,
1372
+ "latency_ci_95": {
1373
+ "lower": 1.5193856746455585,
1374
+ "upper": 1.6000943807547447,
1375
+ "mean": 1.5597400277001516,
1376
+ "std_dev": 0.7703681795673553,
1377
+ "n": 1400
1378
+ },
1379
+ "provider": "OpenAI",
1380
+ "model_type": "generalist",
1381
+ "model_developer": "OpenAI",
1382
+ "model_url": "https://platform.openai.com/docs/models/gpt-5-nano",
1383
+ "cost_info": {
1384
+ "cost_per_1M_input_tokens": 0.05,
1385
+ "cost_per_1M_output_tokens": 0.4,
1386
+ "cost_per_h": "N/A",
1387
+ "cost_source": "OpenAI API pricing",
1388
+ "cost_additional_info": "",
1389
+ "total_cost": 0.048563300000000004
1390
+ },
1391
+ "execution_specifications": {
1392
+ "type": "API",
1393
+ "details": "Reasoning effort set to minimal; see OpenAI API docs. REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1394
+ },
1395
+ "num_samples": 1400
1396
+ },
1397
+ "openai/bells-o-project-content-moderation-input/gpt-5.2": {
1398
+ "model_provider_use_case": "openai",
1399
+ "dataset_name": "bells-o-project-content-moderation-input",
1400
+ "model_name": "gpt-5.2",
1401
+ "accuracy": 0.9381818181818182,
1402
+ "accuracy_per_category": {
1403
+ "harmful manipulation": 0.94,
1404
+ "privacy": 0.93,
1405
+ "hate speech": 0.78,
1406
+ "sexual content": 0.97,
1407
+ "cbrn": 0.99,
1408
+ "harm to minors": 0.97,
1409
+ "integrity & quality violations": 0.83,
1410
+ "illegal activities": 0.98,
1411
+ "self-harm": 0.96,
1412
+ "physical harm": 0.98,
1413
+ "cyber": 0.99
1414
+ },
1415
+ "fpr": 0.0033333333333333335,
1416
+ "mean_latency": 1.0442856402056557,
1417
+ "latency_ci_95": {
1418
+ "lower": 1.0024455032847635,
1419
+ "upper": 1.086125777126548,
1420
+ "mean": 1.0442856402056557,
1421
+ "std_dev": 0.7987319253759664,
1422
+ "n": 1400
1423
+ },
1424
+ "provider": "OpenAI",
1425
+ "model_type": "generalist",
1426
+ "model_developer": "OpenAI",
1427
+ "model_url": "https://platform.openai.com/docs/models/gpt-5.2",
1428
+ "cost_info": {
1429
+ "cost_per_1M_input_tokens": 1.75,
1430
+ "cost_per_1M_output_tokens": 14.0,
1431
+ "cost_per_h": "N/A",
1432
+ "cost_source": "OpenAI API pricing",
1433
+ "cost_additional_info": "",
1434
+ "total_cost": 0.6885235000000001
1435
+ },
1436
+ "execution_specifications": {
1437
+ "type": "API",
1438
+ "details": "Reasoning effort set to low; see OpenAI API docs. REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1439
+ },
1440
+ "num_samples": 1400
1441
+ },
1442
+ "openai/bells-o-project-content-moderation-input/gpt-oss-120b": {
1443
+ "model_provider_use_case": "openai",
1444
+ "dataset_name": "bells-o-project-content-moderation-input",
1445
+ "model_name": "gpt-oss-120b",
1446
+ "accuracy": 0.9318181818181818,
1447
+ "accuracy_per_category": {
1448
+ "harmful manipulation": 0.97,
1449
+ "privacy": 0.96,
1450
+ "hate speech": 0.77,
1451
+ "sexual content": 0.87,
1452
+ "cbrn": 0.99,
1453
+ "harm to minors": 0.98,
1454
+ "integrity & quality violations": 0.84,
1455
+ "illegal activities": 0.97,
1456
+ "self-harm": 0.92,
1457
+ "physical harm": 0.99,
1458
+ "cyber": 0.99
1459
+ },
1460
+ "fpr": 0.0,
1461
+ "mean_latency": 0.7237181276934488,
1462
+ "latency_ci_95": {
1463
+ "lower": 0.708643406560615,
1464
+ "upper": 0.7387928488262826,
1465
+ "mean": 0.7237181276934488,
1466
+ "std_dev": 0.28777776367461705,
1467
+ "n": 1400
1468
+ },
1469
+ "provider": "Together AI",
1470
+ "model_type": "generalist",
1471
+ "model_developer": "OpenAI",
1472
+ "model_url": "https://www.together.ai/models/gpt-oss-120b",
1473
+ "cost_info": {
1474
+ "cost_per_1M_input_tokens": 0.05,
1475
+ "cost_per_1M_output_tokens": 0.2,
1476
+ "cost_per_h": "N/A",
1477
+ "cost_source": "Together AI API pricing",
1478
+ "cost_additional_info": "",
1479
+ "total_cost": 0.032422900000000004
1480
+ },
1481
+ "execution_specifications": {
1482
+ "type": "API",
1483
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1484
+ },
1485
+ "num_samples": 1400
1486
+ },
1487
+ "openai/bells-o-project-content-moderation-input/gpt-oss-20b": {
1488
+ "model_provider_use_case": "openai",
1489
+ "dataset_name": "bells-o-project-content-moderation-input",
1490
+ "model_name": "gpt-oss-20b",
1491
+ "accuracy": 0.6218181818181818,
1492
+ "accuracy_per_category": {
1493
+ "harmful manipulation": 0.54,
1494
+ "privacy": 0.69,
1495
+ "hate speech": 0.69,
1496
+ "sexual content": 0.62,
1497
+ "cbrn": 0.58,
1498
+ "harm to minors": 0.61,
1499
+ "integrity & quality violations": 0.47,
1500
+ "illegal activities": 0.69,
1501
+ "self-harm": 0.72,
1502
+ "physical harm": 0.62,
1503
+ "cyber": 0.61
1504
+ },
1505
+ "fpr": 0.02,
1506
+ "mean_latency": 1.7985665757315499,
1507
+ "latency_ci_95": {
1508
+ "lower": 1.7140022692418668,
1509
+ "upper": 1.883130882221233,
1510
+ "mean": 1.7985665757315499,
1511
+ "std_dev": 1.6143401124211116,
1512
+ "n": 1400
1513
+ },
1514
+ "provider": "Together AI",
1515
+ "model_type": "generalist",
1516
+ "model_developer": "OpenAI",
1517
+ "model_url": "https://www.together.ai/models/gpt-oss-20b",
1518
+ "cost_info": {
1519
+ "cost_per_1M_input_tokens": 0.05,
1520
+ "cost_per_1M_output_tokens": 0.2,
1521
+ "cost_per_h": "N/A",
1522
+ "cost_source": "Together AI API pricing",
1523
+ "cost_additional_info": "",
1524
+ "total_cost": 0.06419470000000001
1525
+ },
1526
+ "execution_specifications": {
1527
+ "type": "API",
1528
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1529
+ },
1530
+ "num_samples": 1400
1531
+ },
1532
+ "openai/bells-o-project-content-moderation-input/gpt-oss-safeguard-120b": {
1533
+ "model_provider_use_case": "openai",
1534
+ "dataset_name": "bells-o-project-content-moderation-input",
1535
+ "model_name": "gpt-oss-safeguard-120b",
1536
+ "accuracy": 0.8781818181818182,
1537
+ "accuracy_per_category": {
1538
+ "harmful manipulation": 0.82,
1539
+ "privacy": 0.94,
1540
+ "hate speech": 0.7,
1541
+ "sexual content": 0.73,
1542
+ "cbrn": 1.0,
1543
+ "harm to minors": 0.96,
1544
+ "integrity & quality violations": 0.69,
1545
+ "illegal activities": 0.95,
1546
+ "self-harm": 0.9,
1547
+ "physical harm": 0.98,
1548
+ "cyber": 0.99
1549
+ },
1550
+ "fpr": 0.0,
1551
+ "mean_latency": 0.9912308720179966,
1552
+ "latency_ci_95": {
1553
+ "lower": 0.9414346608201876,
1554
+ "upper": 1.0410270832158057,
1555
+ "mean": 0.9912308720179966,
1556
+ "std_dev": 0.950614089089987,
1557
+ "n": 1400
1558
+ },
1559
+ "provider": "RunPod",
1560
+ "model_type": "specialized",
1561
+ "model_developer": "OpenAI",
1562
+ "model_url": "https://huggingface.co/openai/gpt-oss-safeguard-120b",
1563
+ "cost_info": {
1564
+ "cost_per_1M_input_tokens": 5.898870113479002,
1565
+ "cost_per_1M_output_tokens": 0.0,
1566
+ "cost_per_h": 3.07,
1567
+ "cost_source": "RunPod",
1568
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
1569
+ "total_cost": 1.1834195244259302
1570
+ },
1571
+ "execution_specifications": {
1572
+ "type": "Local",
1573
+ "details": "This model was ran on an H100 (94GB NVL) on RunPod using vLLM."
1574
+ },
1575
+ "num_samples": 1400
1576
+ },
1577
+ "openai/bells-o-project-content-moderation-input/gpt-oss-safeguard-20b": {
1578
+ "model_provider_use_case": "openai",
1579
+ "dataset_name": "bells-o-project-content-moderation-input",
1580
+ "model_name": "gpt-oss-safeguard-20b",
1581
+ "accuracy": 0.8881818181818182,
1582
+ "accuracy_per_category": {
1583
+ "harmful manipulation": 0.9,
1584
+ "privacy": 0.93,
1585
+ "hate speech": 0.71,
1586
+ "sexual content": 0.79,
1587
+ "cbrn": 0.99,
1588
+ "harm to minors": 0.98,
1589
+ "integrity & quality violations": 0.71,
1590
+ "illegal activities": 0.94,
1591
+ "self-harm": 0.88,
1592
+ "physical harm": 0.95,
1593
+ "cyber": 0.99
1594
+ },
1595
+ "fpr": 0.0,
1596
+ "mean_latency": 0.5077587234973907,
1597
+ "latency_ci_95": {
1598
+ "lower": 0.4910731057974469,
1599
+ "upper": 0.5244443411973345,
1600
+ "mean": 0.5077587234973907,
1601
+ "std_dev": 0.3185299220402077,
1602
+ "n": 1400
1603
+ },
1604
+ "provider": "OpenRouter",
1605
+ "model_type": "specialized",
1606
+ "model_developer": "OpenAI",
1607
+ "model_url": "https://huggingface.co/openai/gpt-oss-safeguard-20b",
1608
+ "cost_info": {
1609
+ "cost_per_1M_input_tokens": 0.07,
1610
+ "cost_per_1M_output_tokens": 0.3,
1611
+ "cost_per_h": "N/A",
1612
+ "cost_source": "OpenRouter API pricing",
1613
+ "cost_additional_info": "",
1614
+ "total_cost": 0.10993276
1615
+ },
1616
+ "execution_specifications": {
1617
+ "type": "API",
1618
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1619
+ },
1620
+ "num_samples": 1400
1621
+ },
1622
+ "openai/bells-o-project-content-moderation-input/omni-moderation": {
1623
+ "model_provider_use_case": "openai",
1624
+ "dataset_name": "bells-o-project-content-moderation-input",
1625
+ "model_name": "omni-moderation",
1626
+ "accuracy": 0.74,
1627
+ "accuracy_per_category": {
1628
+ "harmful manipulation": 0.38,
1629
+ "privacy": 0.46,
1630
+ "hate speech": 0.76,
1631
+ "sexual content": 0.68,
1632
+ "cbrn": 0.88,
1633
+ "harm to minors": 0.95,
1634
+ "integrity & quality violations": 0.47,
1635
+ "illegal activities": 0.84,
1636
+ "self-harm": 0.87,
1637
+ "physical harm": 0.95,
1638
+ "cyber": 0.9
1639
+ },
1640
+ "fpr": 0.023333333333333334,
1641
+ "mean_latency": 0.3429920823233468,
1642
+ "latency_ci_95": {
1643
+ "lower": 0.33798123785984197,
1644
+ "upper": 0.3480029267868517,
1645
+ "mean": 0.3429920823233468,
1646
+ "std_dev": 0.09565746531044984,
1647
+ "n": 1400
1648
+ },
1649
+ "provider": "OpenAI",
1650
+ "model_type": "specialized",
1651
+ "model_developer": "OpenAI",
1652
+ "model_url": "https://platform.openai.com/docs/models/omni-moderation-latest",
1653
+ "cost_info": {
1654
+ "cost_per_1M_input_tokens": 0.0,
1655
+ "cost_per_1M_output_tokens": 0.0,
1656
+ "cost_per_h": "N/A",
1657
+ "cost_source": "OpenAI Moderation API pricing",
1658
+ "cost_additional_info": "The Omni Moderation endpoint is free to use but has low rate limits in the free tier. Your usage tier on the OpenAI API determines these rate limits.",
1659
+ "total_cost": 0.0
1660
+ },
1661
+ "execution_specifications": {
1662
+ "type": "API",
1663
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1664
+ },
1665
+ "num_samples": 1400
1666
+ },
1667
+ "openai/bells-o-project-content-moderation-output/gpt-5-nano": {
1668
+ "model_provider_use_case": "openai",
1669
+ "dataset_name": "bells-o-project-content-moderation-output",
1670
+ "model_name": "gpt-5-nano",
1671
+ "accuracy": 0.9027272727272727,
1672
+ "accuracy_per_category": {
1673
+ "hate speech": 0.92,
1674
+ "physical harm": 0.99,
1675
+ "harmful manipulation": 0.83,
1676
+ "self-harm": 0.93,
1677
+ "privacy": 0.96,
1678
+ "cbrn": 0.99,
1679
+ "harm to minors": 0.99,
1680
+ "cyber": 0.96,
1681
+ "sexual content": 0.67,
1682
+ "illegal activities": 0.94,
1683
+ "integrity & quality violations": 0.75
1684
+ },
1685
+ "fpr": 0.0033333333333333335,
1686
+ "mean_latency": 1.4641724479198457,
1687
+ "latency_ci_95": {
1688
+ "lower": 1.4271079360623544,
1689
+ "upper": 1.501236959777337,
1690
+ "mean": 1.4641724479198457,
1691
+ "std_dev": 0.7075648192793513,
1692
+ "n": 1400
1693
+ },
1694
+ "provider": "OpenAI",
1695
+ "model_type": "generalist",
1696
+ "model_developer": "OpenAI",
1697
+ "model_url": "https://platform.openai.com/docs/models/gpt-5-nano",
1698
+ "cost_info": {
1699
+ "cost_per_1M_input_tokens": 0.05,
1700
+ "cost_per_1M_output_tokens": 0.4,
1701
+ "cost_per_h": "N/A",
1702
+ "cost_source": "OpenAI API pricing",
1703
+ "cost_additional_info": "",
1704
+ "total_cost": 0.05068805
1705
+ },
1706
+ "execution_specifications": {
1707
+ "type": "API",
1708
+ "details": "Reasoning effort set to minimal; see OpenAI API docs. REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1709
+ },
1710
+ "num_samples": 1400
1711
+ },
1712
+ "openai/bells-o-project-content-moderation-output/gpt-5.2": {
1713
+ "model_provider_use_case": "openai",
1714
+ "dataset_name": "bells-o-project-content-moderation-output",
1715
+ "model_name": "gpt-5.2",
1716
+ "accuracy": 0.9518181818181818,
1717
+ "accuracy_per_category": {
1718
+ "hate speech": 0.88,
1719
+ "physical harm": 0.99,
1720
+ "harmful manipulation": 0.92,
1721
+ "self-harm": 0.96,
1722
+ "privacy": 0.97,
1723
+ "cbrn": 0.99,
1724
+ "harm to minors": 0.98,
1725
+ "cyber": 0.98,
1726
+ "sexual content": 0.97,
1727
+ "illegal activities": 0.98,
1728
+ "integrity & quality violations": 0.85
1729
+ },
1730
+ "fpr": 0.0,
1731
+ "mean_latency": 1.1199401940618243,
1732
+ "latency_ci_95": {
1733
+ "lower": 1.0988383402519575,
1734
+ "upper": 1.1410420478716912,
1735
+ "mean": 1.1199401940618243,
1736
+ "std_dev": 0.40283626113424703,
1737
+ "n": 1400
1738
+ },
1739
+ "provider": "OpenAI",
1740
+ "model_type": "generalist",
1741
+ "model_developer": "OpenAI",
1742
+ "model_url": "https://platform.openai.com/docs/models/gpt-5.2",
1743
+ "cost_info": {
1744
+ "cost_per_1M_input_tokens": 1.75,
1745
+ "cost_per_1M_output_tokens": 14.0,
1746
+ "cost_per_h": "N/A",
1747
+ "cost_source": "OpenAI API pricing",
1748
+ "cost_additional_info": "",
1749
+ "total_cost": 1.3295257500000002
1750
+ },
1751
+ "execution_specifications": {
1752
+ "type": "API",
1753
+ "details": "Reasoning effort set to low; see OpenAI API docs. REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1754
+ },
1755
+ "num_samples": 1400
1756
+ },
1757
+ "openai/bells-o-project-content-moderation-output/gpt-oss-120b": {
1758
+ "model_provider_use_case": "openai",
1759
+ "dataset_name": "bells-o-project-content-moderation-output",
1760
+ "model_name": "gpt-oss-120b",
1761
+ "accuracy": 0.9281818181818182,
1762
+ "accuracy_per_category": {
1763
+ "hate speech": 0.81,
1764
+ "physical harm": 0.97,
1765
+ "harmful manipulation": 0.9,
1766
+ "self-harm": 0.93,
1767
+ "privacy": 0.98,
1768
+ "cbrn": 0.98,
1769
+ "harm to minors": 0.99,
1770
+ "cyber": 0.99,
1771
+ "sexual content": 0.85,
1772
+ "illegal activities": 0.96,
1773
+ "integrity & quality violations": 0.85
1774
+ },
1775
+ "fpr": 0.0,
1776
+ "mean_latency": 0.7561430590493339,
1777
+ "latency_ci_95": {
1778
+ "lower": 0.7382452744998518,
1779
+ "upper": 0.774040843598816,
1780
+ "mean": 0.7561430590493339,
1781
+ "std_dev": 0.34167029472682847,
1782
+ "n": 1400
1783
+ },
1784
+ "provider": "Together AI",
1785
+ "model_type": "generalist",
1786
+ "model_developer": "OpenAI",
1787
+ "model_url": "https://www.together.ai/models/gpt-oss-120b",
1788
+ "cost_info": {
1789
+ "cost_per_1M_input_tokens": 0.05,
1790
+ "cost_per_1M_output_tokens": 0.2,
1791
+ "cost_per_h": "N/A",
1792
+ "cost_source": "Together AI API pricing",
1793
+ "cost_additional_info": "",
1794
+ "total_cost": 0.051996850000000004
1795
+ },
1796
+ "execution_specifications": {
1797
+ "type": "API",
1798
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1799
+ },
1800
+ "num_samples": 1400
1801
+ },
1802
+ "openai/bells-o-project-content-moderation-output/gpt-oss-20b": {
1803
+ "model_provider_use_case": "openai",
1804
+ "dataset_name": "bells-o-project-content-moderation-output",
1805
+ "model_name": "gpt-oss-20b",
1806
+ "accuracy": 0.7181818181818181,
1807
+ "accuracy_per_category": {
1808
+ "hate speech": 0.76,
1809
+ "physical harm": 0.76,
1810
+ "harmful manipulation": 0.72,
1811
+ "self-harm": 0.79,
1812
+ "privacy": 0.72,
1813
+ "cbrn": 0.7,
1814
+ "harm to minors": 0.7,
1815
+ "cyber": 0.76,
1816
+ "sexual content": 0.68,
1817
+ "illegal activities": 0.65,
1818
+ "integrity & quality violations": 0.66
1819
+ },
1820
+ "fpr": 0.0033333333333333335,
1821
+ "mean_latency": 1.757279393843242,
1822
+ "latency_ci_95": {
1823
+ "lower": 1.6735166402449926,
1824
+ "upper": 1.8410421474414915,
1825
+ "mean": 1.757279393843242,
1826
+ "std_dev": 1.5990383966194697,
1827
+ "n": 1400
1828
+ },
1829
+ "provider": "Together AI",
1830
+ "model_type": "generalist",
1831
+ "model_developer": "OpenAI",
1832
+ "model_url": "https://www.together.ai/models/gpt-oss-20b",
1833
+ "cost_info": {
1834
+ "cost_per_1M_input_tokens": 0.05,
1835
+ "cost_per_1M_output_tokens": 0.2,
1836
+ "cost_per_h": "N/A",
1837
+ "cost_source": "Together AI API pricing",
1838
+ "cost_additional_info": "",
1839
+ "total_cost": 0.08121905
1840
+ },
1841
+ "execution_specifications": {
1842
+ "type": "API",
1843
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1844
+ },
1845
+ "num_samples": 1400
1846
+ },
1847
+ "openai/bells-o-project-content-moderation-output/gpt-oss-safeguard-120b": {
1848
+ "model_provider_use_case": "openai",
1849
+ "dataset_name": "bells-o-project-content-moderation-output",
1850
+ "model_name": "gpt-oss-safeguard-120b",
1851
+ "accuracy": 0.8418181818181818,
1852
+ "accuracy_per_category": {
1853
+ "hate speech": 0.68,
1854
+ "physical harm": 0.93,
1855
+ "harmful manipulation": 0.72,
1856
+ "self-harm": 0.9,
1857
+ "privacy": 0.92,
1858
+ "cbrn": 0.99,
1859
+ "harm to minors": 0.96,
1860
+ "cyber": 0.97,
1861
+ "sexual content": 0.56,
1862
+ "illegal activities": 0.95,
1863
+ "integrity & quality violations": 0.68
1864
+ },
1865
+ "fpr": 0.0,
1866
+ "mean_latency": 1.1339499698366438,
1867
+ "latency_ci_95": {
1868
+ "lower": 1.0827253500645733,
1869
+ "upper": 1.1851745896087142,
1870
+ "mean": 1.1339499698366438,
1871
+ "std_dev": 0.9778825354839475,
1872
+ "n": 1400
1873
+ },
1874
+ "provider": "RunPod",
1875
+ "model_type": "specialized",
1876
+ "model_developer": "OpenAI",
1877
+ "model_url": "https://huggingface.co/openai/gpt-oss-safeguard-120b",
1878
+ "cost_info": {
1879
+ "cost_per_1M_input_tokens": 2.437501498074139,
1880
+ "cost_per_1M_output_tokens": 0.0,
1881
+ "cost_per_h": 3.07,
1882
+ "cost_source": "RunPod",
1883
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
1884
+ "total_cost": 1.3538102695438596
1885
+ },
1886
+ "execution_specifications": {
1887
+ "type": "Local",
1888
+ "details": "This model was ran on an H100 (94GB NVL) on RunPod using vLLM."
1889
+ },
1890
+ "num_samples": 1400
1891
+ },
1892
+ "openai/bells-o-project-content-moderation-output/gpt-oss-safeguard-20b": {
1893
+ "model_provider_use_case": "openai",
1894
+ "dataset_name": "bells-o-project-content-moderation-output",
1895
+ "model_name": "gpt-oss-safeguard-20b",
1896
+ "accuracy": 0.8927272727272727,
1897
+ "accuracy_per_category": {
1898
+ "hate speech": 0.75,
1899
+ "physical harm": 0.96,
1900
+ "harmful manipulation": 0.93,
1901
+ "self-harm": 0.85,
1902
+ "privacy": 0.94,
1903
+ "cbrn": 0.98,
1904
+ "harm to minors": 0.97,
1905
+ "cyber": 0.97,
1906
+ "sexual content": 0.78,
1907
+ "illegal activities": 0.92,
1908
+ "integrity & quality violations": 0.77
1909
+ },
1910
+ "fpr": 0.0,
1911
+ "mean_latency": 0.5182382569994245,
1912
+ "latency_ci_95": {
1913
+ "lower": 0.5020243010997294,
1914
+ "upper": 0.5344522128991196,
1915
+ "mean": 0.5182382569994245,
1916
+ "std_dev": 0.309525856433271,
1917
+ "n": 1400
1918
+ },
1919
+ "provider": "OpenRouter",
1920
+ "model_type": "specialized",
1921
+ "model_developer": "OpenAI",
1922
+ "model_url": "https://huggingface.co/openai/gpt-oss-safeguard-20b",
1923
+ "cost_info": {
1924
+ "cost_per_1M_input_tokens": 0.07,
1925
+ "cost_per_1M_output_tokens": 0.3,
1926
+ "cost_per_h": "N/A",
1927
+ "cost_source": "OpenRouter API pricing",
1928
+ "cost_additional_info": "",
1929
+ "total_cost": 0.13713153
1930
+ },
1931
+ "execution_specifications": {
1932
+ "type": "API",
1933
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1934
+ },
1935
+ "num_samples": 1400
1936
+ },
1937
+ "openai/bells-o-project-content-moderation-output/omni-moderation": {
1938
+ "model_provider_use_case": "openai",
1939
+ "dataset_name": "bells-o-project-content-moderation-output",
1940
+ "model_name": "omni-moderation",
1941
+ "accuracy": 0.7090909090909091,
1942
+ "accuracy_per_category": {
1943
+ "hate speech": 0.81,
1944
+ "physical harm": 0.93,
1945
+ "harmful manipulation": 0.32,
1946
+ "self-harm": 0.84,
1947
+ "privacy": 0.72,
1948
+ "cbrn": 0.84,
1949
+ "harm to minors": 0.79,
1950
+ "cyber": 0.75,
1951
+ "sexual content": 0.64,
1952
+ "illegal activities": 0.76,
1953
+ "integrity & quality violations": 0.4
1954
+ },
1955
+ "fpr": 0.006666666666666667,
1956
+ "mean_latency": 0.3155126539298466,
1957
+ "latency_ci_95": {
1958
+ "lower": 0.3097630727618276,
1959
+ "upper": 0.32126223509786567,
1960
+ "mean": 0.3155126539298466,
1961
+ "std_dev": 0.1097600145315037,
1962
+ "n": 1400
1963
+ },
1964
+ "provider": "OpenAI",
1965
+ "model_type": "specialized",
1966
+ "model_developer": "OpenAI",
1967
+ "model_url": "https://platform.openai.com/docs/models/omni-moderation-latest",
1968
+ "cost_info": {
1969
+ "cost_per_1M_input_tokens": 0.0,
1970
+ "cost_per_1M_output_tokens": 0.0,
1971
+ "cost_per_h": "N/A",
1972
+ "cost_source": "OpenAI Moderation API pricing",
1973
+ "cost_additional_info": "The Omni Moderation endpoint is free to use but has low rate limits in the free tier. Your usage tier on the OpenAI API determines these rate limits.",
1974
+ "total_cost": 0.0
1975
+ },
1976
+ "execution_specifications": {
1977
+ "type": "API",
1978
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
1979
+ },
1980
+ "num_samples": 1400
1981
+ },
1982
+ "qwen/bells-o-project-content-moderation-input/qwen3guard-gen-0.6b": {
1983
+ "model_provider_use_case": "qwen",
1984
+ "dataset_name": "bells-o-project-content-moderation-input",
1985
+ "model_name": "qwen3guard-gen-0.6b",
1986
+ "accuracy": 0.9245454545454546,
1987
+ "accuracy_per_category": {
1988
+ "harmful manipulation": 0.92,
1989
+ "privacy": 0.93,
1990
+ "hate speech": 0.84,
1991
+ "sexual content": 1.0,
1992
+ "cbrn": 0.95,
1993
+ "harm to minors": 0.97,
1994
+ "integrity & quality violations": 0.85,
1995
+ "illegal activities": 0.96,
1996
+ "self-harm": 0.8,
1997
+ "physical harm": 0.97,
1998
+ "cyber": 0.98
1999
+ },
2000
+ "fpr": 0.02666666666666667,
2001
+ "mean_latency": 0.19419640813555036,
2002
+ "latency_ci_95": {
2003
+ "lower": 0.19107999562025785,
2004
+ "upper": 0.19731282065084288,
2005
+ "mean": 0.19419640813555036,
2006
+ "std_dev": 0.05949259136775017,
2007
+ "n": 1400
2008
+ },
2009
+ "provider": "RunPod",
2010
+ "model_type": "specialized",
2011
+ "model_developer": "Qwen",
2012
+ "model_url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-0.6B",
2013
+ "cost_info": {
2014
+ "cost_per_1M_input_tokens": 0.38936574188219714,
2015
+ "cost_per_1M_output_tokens": 0.0,
2016
+ "cost_per_h": 2.39,
2017
+ "cost_source": "RunPod",
2018
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2019
+ "total_cost": 0.1804947726726532
2020
+ },
2021
+ "execution_specifications": {
2022
+ "type": "Local",
2023
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2024
+ },
2025
+ "num_samples": 1400
2026
+ },
2027
+ "qwen/bells-o-project-content-moderation-input/qwen3guard-gen-8b": {
2028
+ "model_provider_use_case": "qwen",
2029
+ "dataset_name": "bells-o-project-content-moderation-input",
2030
+ "model_name": "qwen3guard-gen-8b",
2031
+ "accuracy": 0.9454545454545454,
2032
+ "accuracy_per_category": {
2033
+ "harmful manipulation": 0.95,
2034
+ "privacy": 0.94,
2035
+ "hate speech": 0.85,
2036
+ "sexual content": 0.98,
2037
+ "cbrn": 1.0,
2038
+ "harm to minors": 0.99,
2039
+ "integrity & quality violations": 0.84,
2040
+ "illegal activities": 0.97,
2041
+ "self-harm": 0.9,
2042
+ "physical harm": 0.98,
2043
+ "cyber": 1.0
2044
+ },
2045
+ "fpr": 0.006666666666666667,
2046
+ "mean_latency": 0.19008652653012956,
2047
+ "latency_ci_95": {
2048
+ "lower": 0.18743975410113897,
2049
+ "upper": 0.19273329895912014,
2050
+ "mean": 0.19008652653012956,
2051
+ "std_dev": 0.05052712045939928,
2052
+ "n": 1400
2053
+ },
2054
+ "provider": "RunPod",
2055
+ "model_type": "specialized",
2056
+ "model_developer": "Qwen",
2057
+ "model_url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-8B",
2058
+ "cost_info": {
2059
+ "cost_per_1M_input_tokens": 0.38112538813051666,
2060
+ "cost_per_1M_output_tokens": 0.0,
2061
+ "cost_per_h": 2.39,
2062
+ "cost_source": "RunPod",
2063
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2064
+ "total_cost": 0.17667486604717045
2065
+ },
2066
+ "execution_specifications": {
2067
+ "type": "Local",
2068
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2069
+ },
2070
+ "num_samples": 1400
2071
+ },
2072
+ "qwen/bells-o-project-content-moderation-output/qwen3guard-gen-0.6b": {
2073
+ "model_provider_use_case": "qwen",
2074
+ "dataset_name": "bells-o-project-content-moderation-output",
2075
+ "model_name": "qwen3guard-gen-0.6b",
2076
+ "accuracy": 0.9227272727272727,
2077
+ "accuracy_per_category": {
2078
+ "hate speech": 0.92,
2079
+ "physical harm": 0.99,
2080
+ "harmful manipulation": 0.83,
2081
+ "self-harm": 0.86,
2082
+ "privacy": 0.96,
2083
+ "cbrn": 0.94,
2084
+ "harm to minors": 0.99,
2085
+ "cyber": 0.96,
2086
+ "sexual content": 0.96,
2087
+ "illegal activities": 0.94,
2088
+ "integrity & quality violations": 0.8
2089
+ },
2090
+ "fpr": 0.016666666666666666,
2091
+ "mean_latency": 0.048780372994286676,
2092
+ "latency_ci_95": {
2093
+ "lower": 0.0480823539105477,
2094
+ "upper": 0.04947839207802565,
2095
+ "mean": 0.048780372994286676,
2096
+ "std_dev": 0.013325246228475014,
2097
+ "n": 1400
2098
+ },
2099
+ "provider": "RunPod",
2100
+ "model_type": "specialized",
2101
+ "model_developer": "Qwen",
2102
+ "model_url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-0.6B",
2103
+ "cost_info": {
2104
+ "cost_per_1M_input_tokens": 0.05528456019474252,
2105
+ "cost_per_1M_output_tokens": 0.0,
2106
+ "cost_per_h": 2.39,
2107
+ "cost_source": "RunPod",
2108
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2109
+ "total_cost": 0.04533864667746756
2110
+ },
2111
+ "execution_specifications": {
2112
+ "type": "Local",
2113
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2114
+ },
2115
+ "num_samples": 1400
2116
+ },
2117
+ "qwen/bells-o-project-content-moderation-output/qwen3guard-gen-8b": {
2118
+ "model_provider_use_case": "qwen",
2119
+ "dataset_name": "bells-o-project-content-moderation-output",
2120
+ "model_name": "qwen3guard-gen-8b",
2121
+ "accuracy": 0.9545454545454546,
2122
+ "accuracy_per_category": {
2123
+ "hate speech": 0.92,
2124
+ "physical harm": 1.0,
2125
+ "harmful manipulation": 0.93,
2126
+ "self-harm": 0.91,
2127
+ "privacy": 0.98,
2128
+ "cbrn": 0.98,
2129
+ "harm to minors": 1.0,
2130
+ "cyber": 0.97,
2131
+ "sexual content": 0.99,
2132
+ "illegal activities": 0.99,
2133
+ "integrity & quality violations": 0.83
2134
+ },
2135
+ "fpr": 0.016666666666666666,
2136
+ "mean_latency": 0.13238392829895018,
2137
+ "latency_ci_95": {
2138
+ "lower": 0.13105481108714015,
2139
+ "upper": 0.13371304551076021,
2140
+ "mean": 0.13238392829895018,
2141
+ "std_dev": 0.025372965476823234,
2142
+ "n": 1400
2143
+ },
2144
+ "provider": "RunPod",
2145
+ "model_type": "specialized",
2146
+ "model_developer": "Qwen",
2147
+ "model_url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-8B",
2148
+ "cost_info": {
2149
+ "cost_per_1M_input_tokens": 0.1500354918097283,
2150
+ "cost_per_1M_output_tokens": 0.0,
2151
+ "cost_per_h": 2.39,
2152
+ "cost_source": "RunPod",
2153
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2154
+ "total_cost": 0.12304350669119093
2155
+ },
2156
+ "execution_specifications": {
2157
+ "type": "Local",
2158
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2159
+ },
2160
+ "num_samples": 1400
2161
+ },
2162
+ "rakancorle1/bells-o-project-content-moderation-input/thinkguard": {
2163
+ "model_provider_use_case": "rakancorle1",
2164
+ "dataset_name": "bells-o-project-content-moderation-input",
2165
+ "model_name": "thinkguard",
2166
+ "accuracy": 0.7781818181818182,
2167
+ "accuracy_per_category": {
2168
+ "harmful manipulation": 0.69,
2169
+ "privacy": 0.73,
2170
+ "hate speech": 0.72,
2171
+ "sexual content": 0.86,
2172
+ "cbrn": 0.84,
2173
+ "harm to minors": 0.86,
2174
+ "integrity & quality violations": 0.63,
2175
+ "illegal activities": 0.83,
2176
+ "self-harm": 0.64,
2177
+ "physical harm": 0.9,
2178
+ "cyber": 0.86
2179
+ },
2180
+ "fpr": 0.08,
2181
+ "mean_latency": 0.1785528426510947,
2182
+ "latency_ci_95": {
2183
+ "lower": 0.17834486711263356,
2184
+ "upper": 0.17876081818955583,
2185
+ "mean": 0.1785528426510947,
2186
+ "std_dev": 0.003970271478323348,
2187
+ "n": 1400
2188
+ },
2189
+ "provider": "RunPod",
2190
+ "model_type": "specialized",
2191
+ "model_developer": "RakanCorle1",
2192
+ "model_url": "https://huggingface.co/Rakancorle1/ThinkGuard",
2193
+ "cost_info": {
2194
+ "cost_per_1M_input_tokens": 0.2906798634516623,
2195
+ "cost_per_1M_output_tokens": 0.0,
2196
+ "cost_per_h": 2.39,
2197
+ "cost_source": "RunPod",
2198
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2199
+ "total_cost": 0.16595494764182303
2200
+ },
2201
+ "execution_specifications": {
2202
+ "type": "Local",
2203
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2204
+ },
2205
+ "num_samples": 1400
2206
+ },
2207
+ "rakancorle1/bells-o-project-content-moderation-output/thinkguard": {
2208
+ "model_provider_use_case": "rakancorle1",
2209
+ "dataset_name": "bells-o-project-content-moderation-output",
2210
+ "model_name": "thinkguard",
2211
+ "accuracy": 0.8145454545454546,
2212
+ "accuracy_per_category": {
2213
+ "hate speech": 0.71,
2214
+ "physical harm": 0.94,
2215
+ "harmful manipulation": 0.74,
2216
+ "self-harm": 0.69,
2217
+ "privacy": 0.87,
2218
+ "cbrn": 0.86,
2219
+ "harm to minors": 0.92,
2220
+ "cyber": 0.84,
2221
+ "sexual content": 0.86,
2222
+ "illegal activities": 0.91,
2223
+ "integrity & quality violations": 0.62
2224
+ },
2225
+ "fpr": 0.08333333333333333,
2226
+ "mean_latency": 0.18875198875154767,
2227
+ "latency_ci_95": {
2228
+ "lower": 0.1882683485403946,
2229
+ "upper": 0.18923562896270074,
2230
+ "mean": 0.18875198875154767,
2231
+ "std_dev": 0.00923273453368272,
2232
+ "n": 1400
2233
+ },
2234
+ "provider": "RunPod",
2235
+ "model_type": "specialized",
2236
+ "model_developer": "RakanCorle1",
2237
+ "model_url": "https://huggingface.co/Rakancorle1/ThinkGuard",
2238
+ "cost_info": {
2239
+ "cost_per_1M_input_tokens": 0.19000934406913317,
2240
+ "cost_per_1M_output_tokens": 0.0,
2241
+ "cost_per_h": 2.39,
2242
+ "cost_source": "RunPod",
2243
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2244
+ "total_cost": 0.17543448732296626
2245
+ },
2246
+ "execution_specifications": {
2247
+ "type": "Local",
2248
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2249
+ },
2250
+ "num_samples": 1400
2251
+ },
2252
+ "saillab/bells-o-project-content-moderation-input/xguard": {
2253
+ "model_provider_use_case": "saillab",
2254
+ "dataset_name": "bells-o-project-content-moderation-input",
2255
+ "model_name": "xguard",
2256
+ "accuracy": 0.8281818181818181,
2257
+ "accuracy_per_category": {
2258
+ "harmful manipulation": 0.77,
2259
+ "privacy": 0.82,
2260
+ "hate speech": 0.76,
2261
+ "sexual content": 0.87,
2262
+ "cbrn": 0.92,
2263
+ "harm to minors": 0.9,
2264
+ "integrity & quality violations": 0.65,
2265
+ "illegal activities": 0.91,
2266
+ "self-harm": 0.72,
2267
+ "physical harm": 0.9,
2268
+ "cyber": 0.89
2269
+ },
2270
+ "fpr": 0.0,
2271
+ "mean_latency": 1.438086905990328,
2272
+ "latency_ci_95": {
2273
+ "lower": 1.4220830667384288,
2274
+ "upper": 1.4540907452422274,
2275
+ "mean": 1.438086905990328,
2276
+ "std_dev": 0.30551471098781485,
2277
+ "n": 1400
2278
+ },
2279
+ "provider": "RunPod",
2280
+ "model_type": "specialized",
2281
+ "model_developer": "SAIL Lab",
2282
+ "model_url": "https://huggingface.co/saillab/x-guard",
2283
+ "cost_info": {
2284
+ "cost_per_1M_input_tokens": 11.345572408123338,
2285
+ "cost_per_1M_output_tokens": 0.0,
2286
+ "cost_per_h": 2.39,
2287
+ "cost_source": "RunPod",
2288
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2289
+ "total_cost": 1.3366218854010106
2290
+ },
2291
+ "execution_specifications": {
2292
+ "type": "Local",
2293
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2294
+ },
2295
+ "num_samples": 1400
2296
+ },
2297
+ "saillab/bells-o-project-content-moderation-output/xguard": {
2298
+ "model_provider_use_case": "saillab",
2299
+ "dataset_name": "bells-o-project-content-moderation-output",
2300
+ "model_name": "xguard",
2301
+ "accuracy": 0.9009090909090909,
2302
+ "accuracy_per_category": {
2303
+ "hate speech": 0.86,
2304
+ "physical harm": 0.98,
2305
+ "harmful manipulation": 0.77,
2306
+ "self-harm": 0.9,
2307
+ "privacy": 0.94,
2308
+ "cbrn": 0.94,
2309
+ "harm to minors": 0.98,
2310
+ "cyber": 0.91,
2311
+ "sexual content": 0.95,
2312
+ "illegal activities": 0.96,
2313
+ "integrity & quality violations": 0.72
2314
+ },
2315
+ "fpr": 0.0033333333333333335,
2316
+ "mean_latency": 0.4900521091052464,
2317
+ "latency_ci_95": {
2318
+ "lower": 0.4689487805620818,
2319
+ "upper": 0.511155437648411,
2320
+ "mean": 0.4900521091052464,
2321
+ "std_dev": 0.40286441392372,
2322
+ "n": 1400
2323
+ },
2324
+ "provider": "RunPod",
2325
+ "model_type": "specialized",
2326
+ "model_developer": "SAIL Lab",
2327
+ "model_url": "https://huggingface.co/saillab/x-guard",
2328
+ "cost_info": {
2329
+ "cost_per_1M_input_tokens": 0.9604441053405044,
2330
+ "cost_per_1M_output_tokens": 0.0,
2331
+ "cost_per_h": 2.39,
2332
+ "cost_source": "RunPod",
2333
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2334
+ "total_cost": 0.4554762102961541
2335
+ },
2336
+ "execution_specifications": {
2337
+ "type": "Local",
2338
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2339
+ },
2340
+ "num_samples": 1400
2341
+ },
2342
+ "toxicityprompts/bells-o-project-content-moderation-input/polyguard-ministral": {
2343
+ "model_provider_use_case": "toxicityprompts",
2344
+ "dataset_name": "bells-o-project-content-moderation-input",
2345
+ "model_name": "polyguard-ministral",
2346
+ "accuracy": 0.92,
2347
+ "accuracy_per_category": {
2348
+ "harmful manipulation": 0.89,
2349
+ "privacy": 0.84,
2350
+ "hate speech": 0.82,
2351
+ "sexual content": 0.99,
2352
+ "cbrn": 1.0,
2353
+ "harm to minors": 0.99,
2354
+ "integrity & quality violations": 0.8,
2355
+ "illegal activities": 0.95,
2356
+ "self-harm": 0.89,
2357
+ "physical harm": 0.97,
2358
+ "cyber": 0.98
2359
+ },
2360
+ "fpr": 0.0033333333333333335,
2361
+ "mean_latency": 0.17871589626584733,
2362
+ "latency_ci_95": {
2363
+ "lower": 0.17849986671699192,
2364
+ "upper": 0.17893192581470274,
2365
+ "mean": 0.17871589626584733,
2366
+ "std_dev": 0.0041240232512055235,
2367
+ "n": 1400
2368
+ },
2369
+ "provider": "RunPod",
2370
+ "model_type": "specialized",
2371
+ "model_developer": "ToxicityPrompts",
2372
+ "model_url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Ministral",
2373
+ "cost_info": {
2374
+ "cost_per_1M_input_tokens": 0.4409996758824333,
2375
+ "cost_per_1M_output_tokens": 0.0,
2376
+ "cost_per_h": 2.39,
2377
+ "cost_source": "RunPod",
2378
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2379
+ "total_cost": 0.16610649691820145
2380
+ },
2381
+ "execution_specifications": {
2382
+ "type": "Local",
2383
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2384
+ },
2385
+ "num_samples": 1400
2386
+ },
2387
+ "toxicityprompts/bells-o-project-content-moderation-input/polyguard-qwen": {
2388
+ "model_provider_use_case": "toxicityprompts",
2389
+ "dataset_name": "bells-o-project-content-moderation-input",
2390
+ "model_name": "polyguard-qwen",
2391
+ "accuracy": 0.9354545454545454,
2392
+ "accuracy_per_category": {
2393
+ "harmful manipulation": 0.88,
2394
+ "privacy": 0.93,
2395
+ "hate speech": 0.83,
2396
+ "sexual content": 1.0,
2397
+ "cbrn": 0.99,
2398
+ "harm to minors": 0.98,
2399
+ "integrity & quality violations": 0.84,
2400
+ "illegal activities": 0.98,
2401
+ "self-harm": 0.91,
2402
+ "physical harm": 0.97,
2403
+ "cyber": 0.98
2404
+ },
2405
+ "fpr": 0.0,
2406
+ "mean_latency": 0.16735810961042133,
2407
+ "latency_ci_95": {
2408
+ "lower": 0.167181707969697,
2409
+ "upper": 0.16753451125114566,
2410
+ "mean": 0.16735810961042133,
2411
+ "std_dev": 0.0033675229696693413,
2412
+ "n": 1400
2413
+ },
2414
+ "provider": "RunPod",
2415
+ "model_type": "specialized",
2416
+ "model_developer": "ToxicityPrompts",
2417
+ "model_url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Qwen",
2418
+ "cost_info": {
2419
+ "cost_per_1M_input_tokens": 0.42708542860944143,
2420
+ "cost_per_1M_output_tokens": 0.0,
2421
+ "cost_per_h": 2.39,
2422
+ "cost_source": "RunPod",
2423
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2424
+ "total_cost": 0.15555006521013048
2425
+ },
2426
+ "execution_specifications": {
2427
+ "type": "Local",
2428
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2429
+ },
2430
+ "num_samples": 1400
2431
+ },
2432
+ "toxicityprompts/bells-o-project-content-moderation-output/polyguard-ministral": {
2433
+ "model_provider_use_case": "toxicityprompts",
2434
+ "dataset_name": "bells-o-project-content-moderation-output",
2435
+ "model_name": "polyguard-ministral",
2436
+ "accuracy": 0.9318181818181818,
2437
+ "accuracy_per_category": {
2438
+ "hate speech": 0.83,
2439
+ "physical harm": 0.99,
2440
+ "harmful manipulation": 0.88,
2441
+ "self-harm": 0.88,
2442
+ "privacy": 0.97,
2443
+ "cbrn": 0.99,
2444
+ "harm to minors": 0.98,
2445
+ "cyber": 0.96,
2446
+ "sexual content": 0.97,
2447
+ "illegal activities": 0.97,
2448
+ "integrity & quality violations": 0.83
2449
+ },
2450
+ "fpr": 0.013333333333333334,
2451
+ "mean_latency": 0.3748241812842233,
2452
+ "latency_ci_95": {
2453
+ "lower": 0.37309410657377223,
2454
+ "upper": 0.37655425599467435,
2455
+ "mean": 0.3748241812842233,
2456
+ "std_dev": 0.03302727969403025,
2457
+ "n": 1400
2458
+ },
2459
+ "provider": "RunPod",
2460
+ "model_type": "specialized",
2461
+ "model_developer": "ToxicityPrompts",
2462
+ "model_url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Ministral",
2463
+ "cost_info": {
2464
+ "cost_per_1M_input_tokens": 0.4686604178361155,
2465
+ "cost_per_1M_output_tokens": 0.0,
2466
+ "cost_per_h": 2.39,
2467
+ "cost_source": "RunPod",
2468
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2469
+ "total_cost": 0.34837825293805863
2470
+ },
2471
+ "execution_specifications": {
2472
+ "type": "Local",
2473
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2474
+ },
2475
+ "num_samples": 1400
2476
+ },
2477
+ "toxicityprompts/bells-o-project-content-moderation-output/polyguard-qwen": {
2478
+ "model_provider_use_case": "toxicityprompts",
2479
+ "dataset_name": "bells-o-project-content-moderation-output",
2480
+ "model_name": "polyguard-qwen",
2481
+ "accuracy": 0.9572727272727273,
2482
+ "accuracy_per_category": {
2483
+ "hate speech": 0.92,
2484
+ "physical harm": 1.0,
2485
+ "harmful manipulation": 0.88,
2486
+ "self-harm": 0.93,
2487
+ "privacy": 0.98,
2488
+ "cbrn": 1.0,
2489
+ "harm to minors": 1.0,
2490
+ "cyber": 0.98,
2491
+ "sexual content": 0.98,
2492
+ "illegal activities": 1.0,
2493
+ "integrity & quality violations": 0.86
2494
+ },
2495
+ "fpr": 0.013333333333333334,
2496
+ "mean_latency": 0.3705882680416107,
2497
+ "latency_ci_95": {
2498
+ "lower": 0.3683706245632213,
2499
+ "upper": 0.37280591152000014,
2500
+ "mean": 0.3705882680416107,
2501
+ "std_dev": 0.04233501072523893,
2502
+ "n": 1400
2503
+ },
2504
+ "provider": "RunPod",
2505
+ "model_type": "specialized",
2506
+ "model_developer": "ToxicityPrompts",
2507
+ "model_url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Qwen",
2508
+ "cost_info": {
2509
+ "cost_per_1M_input_tokens": 0.47809043060129436,
2510
+ "cost_per_1M_output_tokens": 0.0,
2511
+ "cost_per_h": 2.39,
2512
+ "cost_source": "RunPod",
2513
+ "cost_additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens).",
2514
+ "total_cost": 0.34444120690756375
2515
+ },
2516
+ "execution_specifications": {
2517
+ "type": "Local",
2518
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
2519
+ },
2520
+ "num_samples": 1400
2521
+ },
2522
+ "virtue-ai/bells-o-project-content-moderation-input/virtueguard-text-lite": {
2523
+ "model_provider_use_case": "virtue-ai",
2524
+ "dataset_name": "bells-o-project-content-moderation-input",
2525
+ "model_name": "virtueguard-text-lite",
2526
+ "accuracy": 0.7290909090909091,
2527
+ "accuracy_per_category": {
2528
+ "harmful manipulation": 0.68,
2529
+ "privacy": 0.61,
2530
+ "hate speech": 0.57,
2531
+ "sexual content": 0.64,
2532
+ "cbrn": 0.86,
2533
+ "harm to minors": 0.9,
2534
+ "integrity & quality violations": 0.61,
2535
+ "illegal activities": 0.86,
2536
+ "self-harm": 0.62,
2537
+ "physical harm": 0.84,
2538
+ "cyber": 0.83
2539
+ },
2540
+ "fpr": 0.0,
2541
+ "mean_latency": 0.24810820971216474,
2542
+ "latency_ci_95": {
2543
+ "lower": 0.22206087989181125,
2544
+ "upper": 0.27415553953251826,
2545
+ "mean": 0.24810820971216474,
2546
+ "std_dev": 0.4972458368778715,
2547
+ "n": 1400
2548
+ },
2549
+ "provider": "Together AI",
2550
+ "model_type": "specialized",
2551
+ "model_developer": "Virtue AI",
2552
+ "model_url": "https://www.together.ai/models/virtueguard-text-lite",
2553
+ "cost_info": {
2554
+ "cost_per_1M_input_tokens": 0.2,
2555
+ "cost_per_1M_output_tokens": 0.0,
2556
+ "cost_per_h": "N/A",
2557
+ "cost_source": "Together AI API pricing",
2558
+ "cost_additional_info": "",
2559
+ "total_cost": 0.0098006
2560
+ },
2561
+ "execution_specifications": {
2562
+ "type": "API",
2563
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
2564
+ },
2565
+ "num_samples": 1400
2566
+ },
2567
+ "virtue-ai/bells-o-project-content-moderation-output/virtueguard-text-lite": {
2568
+ "model_provider_use_case": "virtue-ai",
2569
+ "dataset_name": "bells-o-project-content-moderation-output",
2570
+ "model_name": "virtueguard-text-lite",
2571
+ "accuracy": 0.11181818181818182,
2572
+ "accuracy_per_category": {
2573
+ "hate speech": 0.02,
2574
+ "physical harm": 0.01,
2575
+ "harmful manipulation": 0.12,
2576
+ "self-harm": 0.0,
2577
+ "privacy": 0.08,
2578
+ "cbrn": 0.25,
2579
+ "harm to minors": 0.1,
2580
+ "cyber": 0.27,
2581
+ "sexual content": 0.11,
2582
+ "illegal activities": 0.14,
2583
+ "integrity & quality violations": 0.13
2584
+ },
2585
+ "fpr": 0.0033333333333333335,
2586
+ "mean_latency": 0.31551449128559655,
2587
+ "latency_ci_95": {
2588
+ "lower": 0.2464019144914514,
2589
+ "upper": 0.3846270680797417,
2590
+ "mean": 0.31551449128559655,
2591
+ "std_dev": 1.3193652218407883,
2592
+ "n": 1400
2593
+ },
2594
+ "provider": "Together AI",
2595
+ "model_type": "specialized",
2596
+ "model_developer": "Virtue AI",
2597
+ "model_url": "https://www.together.ai/models/virtueguard-text-lite",
2598
+ "cost_info": {
2599
+ "cost_per_1M_input_tokens": 0.2,
2600
+ "cost_per_1M_output_tokens": 0.0,
2601
+ "cost_per_h": "N/A",
2602
+ "cost_source": "Together AI API pricing",
2603
+ "cost_additional_info": "",
2604
+ "total_cost": 0.0810904
2605
+ },
2606
+ "execution_specifications": {
2607
+ "type": "API",
2608
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
2609
+ },
2610
+ "num_samples": 1400
2611
+ },
2612
+ "x-ai/bells-o-project-content-moderation-input/grok-4-1-fast-non-reasoning": {
2613
+ "model_provider_use_case": "x-ai",
2614
+ "dataset_name": "bells-o-project-content-moderation-input",
2615
+ "model_name": "grok-4-1-fast-non-reasoning",
2616
+ "accuracy": 0.8263636363636364,
2617
+ "accuracy_per_category": {
2618
+ "harmful manipulation": 0.9,
2619
+ "privacy": 0.76,
2620
+ "hate speech": 0.48,
2621
+ "sexual content": 0.72,
2622
+ "cbrn": 0.93,
2623
+ "harm to minors": 0.98,
2624
+ "integrity & quality violations": 0.73,
2625
+ "illegal activities": 0.97,
2626
+ "self-harm": 0.66,
2627
+ "physical harm": 0.97,
2628
+ "cyber": 0.99
2629
+ },
2630
+ "fpr": 0.0,
2631
+ "mean_latency": 0.9228259367602212,
2632
+ "latency_ci_95": {
2633
+ "lower": 0.6722643846420433,
2634
+ "upper": 1.173387488878399,
2635
+ "mean": 0.9228259367602212,
2636
+ "std_dev": 4.783242256757777,
2637
+ "n": 1400
2638
+ },
2639
+ "provider": "xAI",
2640
+ "model_type": "generalist",
2641
+ "model_developer": "X-AI",
2642
+ "model_url": "https://docs.x.ai/docs/models/grok-4-1-fast-non-reasoning",
2643
+ "cost_info": {
2644
+ "cost_per_1M_input_tokens": 0.2,
2645
+ "cost_per_1M_output_tokens": 0.5,
2646
+ "cost_per_h": "N/A",
2647
+ "cost_source": "X-AI API pricing",
2648
+ "cost_additional_info": "",
2649
+ "total_cost": 0.06539510000000001
2650
+ },
2651
+ "execution_specifications": {
2652
+ "type": "API",
2653
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
2654
+ },
2655
+ "num_samples": 1400
2656
+ },
2657
+ "x-ai/bells-o-project-content-moderation-output/grok-4-1-fast-non-reasoning": {
2658
+ "model_provider_use_case": "x-ai",
2659
+ "dataset_name": "bells-o-project-content-moderation-output",
2660
+ "model_name": "grok-4-1-fast-non-reasoning",
2661
+ "accuracy": 0.8363636363636363,
2662
+ "accuracy_per_category": {
2663
+ "hate speech": 0.64,
2664
+ "physical harm": 0.95,
2665
+ "harmful manipulation": 0.83,
2666
+ "self-harm": 0.9,
2667
+ "privacy": 0.91,
2668
+ "cbrn": 0.75,
2669
+ "harm to minors": 0.96,
2670
+ "cyber": 0.96,
2671
+ "sexual content": 0.63,
2672
+ "illegal activities": 0.95,
2673
+ "integrity & quality violations": 0.72
2674
+ },
2675
+ "fpr": 0.0,
2676
+ "mean_latency": 0.8401098469325474,
2677
+ "latency_ci_95": {
2678
+ "lower": 0.6645747595715246,
2679
+ "upper": 1.0156449342935703,
2680
+ "mean": 0.8401098469325474,
2681
+ "std_dev": 3.350980389093776,
2682
+ "n": 1400
2683
+ },
2684
+ "provider": "xAI",
2685
+ "model_type": "generalist",
2686
+ "model_developer": "X-AI",
2687
+ "model_url": "https://docs.x.ai/docs/models/grok-4-1-fast-non-reasoning",
2688
+ "cost_info": {
2689
+ "cost_per_1M_input_tokens": 0.2,
2690
+ "cost_per_1M_output_tokens": 0.5,
2691
+ "cost_per_h": "N/A",
2692
+ "cost_source": "X-AI API pricing",
2693
+ "cost_additional_info": "",
2694
+ "total_cost": 0.1310404
2695
+ },
2696
+ "execution_specifications": {
2697
+ "type": "API",
2698
+ "details": "REST API accessed through a 'Memory-Optimized 32GB RAM' CPU RunPod instance from US-KS-2."
2699
+ },
2700
+ "num_samples": 1400
2701
+ }
2702
+ }
data/jailbreak_metrics.json ADDED
The diff for this file is too large to render. See raw diff
 
data/jb_model_info_mapping.json ADDED
@@ -0,0 +1,775 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_comment": "Consolidated model information mapping. Contains developer, type, cost information, and execution specifications for each model.",
3
+ "_units": {
4
+ "api_costs": "cost per 1M input tokens + cost per 1M output tokens (if applicable)",
5
+ "local_costs": "cost per 1M tokens (calculated using formula)"
6
+ },
7
+ "anthropic/claude-haiku-4-5": {
8
+ "model_developer": "Anthropic",
9
+ "model_type": "generalist",
10
+ "url": "https://platform.claude.com/docs/en/about-claude/models/overview",
11
+ "cost_info": {
12
+ "cost_per_1M_input_tokens": 1.0,
13
+ "cost_per_1M_output_tokens": 5.0,
14
+ "source": "Claude API pricing",
15
+ "cost_per_h": "N/A",
16
+ "additional_info": ""
17
+ },
18
+ "execution_specifications": {
19
+ "type": "API",
20
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
21
+ }
22
+ },
23
+ "anthropic/claude-sonnet-4-5": {
24
+ "model_developer": "Anthropic",
25
+ "model_type": "generalist",
26
+ "url": "https://platform.claude.com/docs/en/about-claude/models/overview",
27
+ "cost_info": {
28
+ "cost_per_1M_input_tokens": 3.0,
29
+ "cost_per_1M_output_tokens": 15.0,
30
+ "source": "Claude API pricing",
31
+ "cost_per_h": "N/A",
32
+ "additional_info": ""
33
+ },
34
+ "execution_specifications": {
35
+ "type": "API",
36
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
37
+ }
38
+ },
39
+ "azure/analyze-text": {
40
+ "model_developer": "Azure",
41
+ "model_type": "specialized",
42
+ "url": "https://learn.microsoft.com/en-us/azure/ai-services/content-safety/overview",
43
+ "cost_info": {
44
+ "cost_per_1M_input_tokens": 380.0,
45
+ "cost_per_1M_output_tokens": 0.0,
46
+ "source": "Azure AI Content Safety",
47
+ "cost_per_h": "N/A",
48
+ "additional_info": "Usage is measured in text records. One text record may contain up to 1000 characters. Only the input string is considered in the text record.\n1000 text records cost $0.38. Assuming an average length of 500 characters for a message, and a token length of approx. 4 characters: Estimated cost per 1M input tokens = 1M/(500/4) text records * $0.38/1000 text records) = $3.04.\nCost per 1M input tokens (not records) = 3.04$.\n\nThe benchmark was run on the free plan."
49
+ },
50
+ "execution_specifications": {
51
+ "type": "API",
52
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
53
+ }
54
+ },
55
+ "azure/promptshield": {
56
+ "model_developer": "Azure",
57
+ "model_type": "specialized",
58
+ "url": "https://learn.microsoft.com/en-us/azure/ai-foundry/openai/concepts/content-filter-prompt-shields?view=foundry-classic#prompt-shields-for-user-prompts",
59
+ "cost_info": {
60
+ "cost_per_1M_input_tokens": 380.0,
61
+ "cost_per_1M_output_tokens": 0.0,
62
+ "source": "Azure AI Content Safety",
63
+ "cost_per_h": "N/A",
64
+ "additional_info": "Usage is measured in text records. One text record may contain up to 1000 characters. Only the input string is considered in the text record.\n1000 text records cost $0.38. Assuming an average length of 500 characters for a message, and a token length of approx. 4 characters: Estimated cost per 1M input tokens = 1M/(500/4) text records * $0.38/1000 text records) = $3.04.\nCost per 1M input tokens (not records) = 3.04$.\n\nThe benchmark was run on the free plan."
65
+ },
66
+ "execution_specifications": {
67
+ "type": "API",
68
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
69
+ }
70
+ },
71
+ "google/gemini-2.5-flash": {
72
+ "model_developer": "Google",
73
+ "model_type": "generalist",
74
+ "url": "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash",
75
+ "cost_info": {
76
+ "cost_per_1M_input_tokens": 0.3,
77
+ "cost_per_1M_output_tokens": 2.5,
78
+ "source": "Gemini Developer API pricing",
79
+ "cost_per_h": "N/A",
80
+ "additional_info": ""
81
+ },
82
+ "execution_specifications": {
83
+ "type": "API",
84
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
85
+ }
86
+ },
87
+ "lakera/lakera-guard_default": {
88
+ "model_developer": "Lakera",
89
+ "model_type": "specialized",
90
+ "url": "https://www.lakera.ai/lakera-guard",
91
+ "cost_info": {
92
+ "cost_per_1M_input_tokens": 0.0,
93
+ "cost_per_1M_output_tokens": 0.0,
94
+ "source": "Lakera API pricing",
95
+ "cost_per_h": "N/A",
96
+ "additional_info": "Free for 10,000 API requests/month; Allows prompt size up to 8,000 tokens per request."
97
+ },
98
+ "execution_specifications": {
99
+ "type": "API",
100
+ "details": "This is the LakeraGuard API with the default policy. REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
101
+ }
102
+ },
103
+ "meta/llama-guard-4-12b": {
104
+ "model_developer": "Meta",
105
+ "model_type": "specialized",
106
+ "url": "https://www.llama.com/docs/model-cards-and-prompt-formats/llama-guard-4/",
107
+ "cost_info": {
108
+ "cost_per_1M_input_tokens": 0.2,
109
+ "cost_per_1M_output_tokens": 0.0,
110
+ "source": "Together AI pricing",
111
+ "cost_per_h": "N/A",
112
+ "additional_info": ""
113
+ },
114
+ "execution_specifications": {
115
+ "type": "API",
116
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
117
+ }
118
+ },
119
+ "mistral/ministral-3b-2512": {
120
+ "model_developer": "Mistral AI",
121
+ "model_type": "generalist",
122
+ "url": "https://docs.mistral.ai/models/ministral-3-3b-25-12",
123
+ "cost_info": {
124
+ "cost_per_1M_input_tokens": 0.04,
125
+ "cost_per_1M_output_tokens": 0.04,
126
+ "source": "Ministral API pricing",
127
+ "cost_per_h": "N/A",
128
+ "additional_info": ""
129
+ },
130
+ "execution_specifications": {
131
+ "type": "API",
132
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
133
+ }
134
+ },
135
+ "mistral/mistral-large-3": {
136
+ "model_developer": "Mistral AI",
137
+ "model_type": "generalist",
138
+ "url": "https://docs.mistral.ai/models/mistral-large-3-25-12",
139
+ "cost_info": {
140
+ "cost_per_1M_input_tokens": 4.0,
141
+ "cost_per_1M_output_tokens": 12.0,
142
+ "source": "Mistral API pricing",
143
+ "cost_per_h": "N/A",
144
+ "additional_info": ""
145
+ },
146
+ "execution_specifications": {
147
+ "type": "API",
148
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
149
+ }
150
+ },
151
+ "openai/gpt-5-nano": {
152
+ "model_developer": "OpenAI",
153
+ "model_type": "generalist",
154
+ "url": "https://platform.openai.com/docs/models/gpt-5-nano",
155
+ "cost_info": {
156
+ "cost_per_1M_input_tokens": 0.05,
157
+ "cost_per_1M_output_tokens": 0.4,
158
+ "source": "OpenAI API pricing",
159
+ "cost_per_h": "N/A",
160
+ "additional_info": ""
161
+ },
162
+ "execution_specifications": {
163
+ "type": "API",
164
+ "details": "Reasoning effort set to minimal; see OpenAI API docs. REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
165
+ }
166
+ },
167
+ "openai/gpt-5.2": {
168
+ "model_developer": "OpenAI",
169
+ "model_type": "generalist",
170
+ "url": "https://platform.openai.com/docs/models/gpt-5.2",
171
+ "cost_info": {
172
+ "cost_per_1M_input_tokens": 1.75,
173
+ "cost_per_1M_output_tokens": 14.0,
174
+ "source": "OpenAI API pricing",
175
+ "cost_per_h": "N/A",
176
+ "additional_info": ""
177
+ },
178
+ "execution_specifications": {
179
+ "type": "API",
180
+ "details": "Reasoning effort set to low; see OpenAI API docs. REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
181
+ }
182
+ },
183
+ "openai/gpt-oss-20b": {
184
+ "model_developer": "OpenAI",
185
+ "model_type": "generalist",
186
+ "url": "https://www.together.ai/models/gpt-oss-20b",
187
+ "cost_info": {
188
+ "cost_per_1M_input_tokens": 0.05,
189
+ "cost_per_1M_output_tokens": 0.2,
190
+ "source": "Together AI API pricing",
191
+ "cost_per_h": "N/A",
192
+ "additional_info": ""
193
+ },
194
+ "execution_specifications": {
195
+ "type": "API",
196
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
197
+ }
198
+ },
199
+ "openai/gpt-oss-120b": {
200
+ "model_developer": "OpenAI",
201
+ "model_type": "generalist",
202
+ "url": "https://www.together.ai/models/gpt-oss-120b",
203
+ "cost_info": {
204
+ "cost_per_1M_input_tokens": 0.05,
205
+ "cost_per_1M_output_tokens": 0.2,
206
+ "source": "Together AI API pricing",
207
+ "cost_per_h": "N/A",
208
+ "additional_info": ""
209
+ },
210
+ "execution_specifications": {
211
+ "type": "API",
212
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
213
+ }
214
+ },
215
+ "openai/gpt-oss-safeguard-20b": {
216
+ "model_developer": "OpenAI",
217
+ "model_type": "specialized",
218
+ "url": "https://huggingface.co/openai/gpt-oss-safeguard-20b",
219
+ "cost_info": {
220
+ "cost_per_1M_input_tokens": 0.07,
221
+ "cost_per_1M_output_tokens": 0.3,
222
+ "source": "OpenRouter API pricing",
223
+ "cost_per_h": "N/A",
224
+ "additional_info": ""
225
+ },
226
+ "execution_specifications": {
227
+ "type": "API",
228
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
229
+ }
230
+ },
231
+ "openai/omni-moderation": {
232
+ "model_developer": "OpenAI",
233
+ "model_type": "specialized",
234
+ "url": "https://platform.openai.com/docs/models/omni-moderation-latest",
235
+ "cost_info": {
236
+ "cost_per_1M_input_tokens": 0.0,
237
+ "cost_per_1M_output_tokens": 0.0,
238
+ "source": "OpenAI Moderation API pricing",
239
+ "cost_per_h": "N/A",
240
+ "additional_info": "The Omni Moderation endpoint is free to use but has low rate limits in the free tier. Your usage tier on the OpenAI API determines these rate limits."
241
+ },
242
+ "execution_specifications": {
243
+ "type": "API",
244
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
245
+ }
246
+ },
247
+ "virtue-ai/virtueguard-text-lite": {
248
+ "model_developer": "Virtue AI",
249
+ "model_type": "specialized",
250
+ "url": "https://www.together.ai/models/virtueguard-text-lite",
251
+ "cost_info": {
252
+ "cost_per_1M_input_tokens": 0.2,
253
+ "cost_per_1M_output_tokens": 0.0,
254
+ "source": "Together AI API pricing",
255
+ "cost_per_h": "N/A",
256
+ "additional_info": ""
257
+ },
258
+ "execution_specifications": {
259
+ "type": "API",
260
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
261
+ }
262
+ },
263
+ "x-ai/grok-4-1-fast-non-reasoning": {
264
+ "model_developer": "X-AI",
265
+ "model_type": "generalist",
266
+ "url": "https://docs.x.ai/docs/models/grok-4-1-fast-non-reasoning",
267
+ "cost_info": {
268
+ "cost_per_1M_input_tokens": 0.2,
269
+ "cost_per_1M_output_tokens": 0.5,
270
+ "source": "X-AI API pricing",
271
+ "cost_per_h": "N/A",
272
+ "additional_info": ""
273
+ },
274
+ "execution_specifications": {
275
+ "type": "API",
276
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
277
+ }
278
+ },
279
+ "aws/bedrock-guardrail": {
280
+ "model_developer": "Amazon Web Services",
281
+ "model_type": "specialized",
282
+ "url": "https://aws.amazon.com/bedrock/guardrails/",
283
+ "cost_info": {
284
+ "cost_per_1M_input_tokens": 150.0,
285
+ "cost_per_1M_output_tokens": 0.0,
286
+ "source": "Amazon Bedrock API pricing",
287
+ "cost_per_h": "N/A",
288
+ "additional_info": "Usage is measured in text units. One text unit may contain up to 1000 characters. Only the input string is considered in the text unit.\n1000 text units cost $0.15. Assuming an average length of 500 characters for a message, and a token length of approx. 4 characters: Estimated cost per 1M input tokens = 1M/(500/4) text units * $0.15/1000 text units) = $1.2.\nCost per 1M input tokens (not units) = 1.2$."
289
+ },
290
+ "execution_specifications": {
291
+ "type": "API",
292
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
293
+ }
294
+ },
295
+ "nvidia/aegis-ai-content-safety-llamaguard-defensive-1.0": {
296
+ "model_developer": "NVIDIA",
297
+ "model_type": "specialized",
298
+ "url": "https://huggingface.co/nvidia/Aegis-AI-Content-Safety-LlamaGuard-Defensive-1.0",
299
+ "cost_info": {
300
+ "cost_per_1M_input_tokens": "N/A",
301
+ "cost_per_1M_output_tokens": "N/A",
302
+ "source": "RunPod",
303
+ "cost_per_h": 2.39,
304
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
305
+ },
306
+ "execution_specifications": {
307
+ "type": "Local",
308
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
309
+ }
310
+ },
311
+ "google/shieldgemma-2b": {
312
+ "model_developer": "Google",
313
+ "model_type": "specialized",
314
+ "url": "https://huggingface.co/google/shieldgemma-2b",
315
+ "cost_info": {
316
+ "cost_per_1M_input_tokens": "N/A",
317
+ "cost_per_1M_output_tokens": "N/A",
318
+ "source": "RunPod",
319
+ "cost_per_h": 2.39,
320
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
321
+ },
322
+ "execution_specifications": {
323
+ "type": "Local",
324
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
325
+ }
326
+ },
327
+ "google/shieldgemma-9b": {
328
+ "model_developer": "Google",
329
+ "url": "https://huggingface.co/google/shieldgemma-9b",
330
+ "model_type": "specialized",
331
+ "cost_info": {
332
+ "cost_per_1M_input_tokens": "N/A",
333
+ "cost_per_1M_output_tokens": "N/A",
334
+ "source": "RunPod",
335
+ "cost_per_h": 2.39,
336
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
337
+ },
338
+ "execution_specifications": {
339
+ "type": "Local",
340
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
341
+ }
342
+ },
343
+ "google/shieldgemma-27b": {
344
+ "model_developer": "Google",
345
+ "model_type": "specialized",
346
+ "url": "https://huggingface.co/google/shieldgemma-27b",
347
+ "cost_info": {
348
+ "cost_per_1M_input_tokens": "N/A",
349
+ "cost_per_1M_output_tokens": "N/A",
350
+ "source": "RunPod",
351
+ "cost_per_h": 2.39,
352
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
353
+ },
354
+ "execution_specifications": {
355
+ "type": "Local",
356
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
357
+ }
358
+ },
359
+ "saillab/xguard": {
360
+ "model_developer": "SAIL Lab",
361
+ "model_type": "specialized",
362
+ "url": "https://huggingface.co/saillab/x-guard",
363
+ "cost_info": {
364
+ "cost_per_1M_input_tokens": "N/A",
365
+ "cost_per_1M_output_tokens": "N/A",
366
+ "source": "RunPod",
367
+ "cost_per_h": 2.39,
368
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
369
+ },
370
+ "execution_specifications": {
371
+ "type": "Local",
372
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
373
+ }
374
+ },
375
+ "openai/gpt-oss-safeguard-120b": {
376
+ "model_developer": "OpenAI",
377
+ "model_type": "specialized",
378
+ "url": "https://huggingface.co/openai/gpt-oss-safeguard-120b",
379
+ "cost_info": {
380
+ "cost_per_1M_input_tokens": "N/A",
381
+ "cost_per_1M_output_tokens": "N/A",
382
+ "source": "RunPod",
383
+ "cost_per_h": 3.07,
384
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
385
+ },
386
+ "execution_specifications": {
387
+ "type": "Local",
388
+ "details": "This model was ran on an H100 (94GB NVL) on RunPod using vLLM."
389
+ }
390
+ },
391
+ "qwen/qwen3guard-gen-8b": {
392
+ "model_developer": "Qwen",
393
+ "model_type": "specialized",
394
+ "url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-8B",
395
+ "cost_info": {
396
+ "cost_per_1M_input_tokens": "N/A",
397
+ "cost_per_1M_output_tokens": "N/A",
398
+ "source": "RunPod",
399
+ "cost_per_h": 2.39,
400
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
401
+ },
402
+ "execution_specifications": {
403
+ "type": "Local",
404
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
405
+ }
406
+ },
407
+ "qwen/qwen3guard-gen-4b": {
408
+ "model_developer": "Qwen",
409
+ "model_type": "specialized",
410
+ "url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-4B",
411
+ "cost_info": {
412
+ "cost_per_1M_input_tokens": "N/A",
413
+ "cost_per_1M_output_tokens": "N/A",
414
+ "source": "RunPod",
415
+ "cost_per_h": 2.39,
416
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
417
+ },
418
+ "execution_specifications": {
419
+ "type": "Local",
420
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
421
+ }
422
+ },
423
+ "qwen/qwen3guard-gen-0.6b": {
424
+ "model_developer": "Qwen",
425
+ "model_type": "specialized",
426
+ "url": "https://huggingface.co/Qwen/Qwen3Guard-Gen-0.6B",
427
+ "cost_info": {
428
+ "cost_per_1M_input_tokens": "N/A",
429
+ "cost_per_1M_output_tokens": "N/A",
430
+ "source": "RunPod",
431
+ "cost_per_h": 2.39,
432
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
433
+ },
434
+ "execution_specifications": {
435
+ "type": "Local",
436
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
437
+ }
438
+ },
439
+ "nvidia/llama-3.1-nemotron-safety-guard-8b-v3": {
440
+ "model_developer": "NVIDIA",
441
+ "model_type": "specialized",
442
+ "url": "https://huggingface.co/nvidia/Llama-3.1-Nemotron-Safety-Guard-8B-v3",
443
+ "cost_info": {
444
+ "cost_per_1M_input_tokens": "N/A",
445
+ "cost_per_1M_output_tokens": "N/A",
446
+ "source": "RunPod",
447
+ "cost_per_h": 2.39,
448
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
449
+ },
450
+ "execution_specifications": {
451
+ "type": "Local",
452
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
453
+ }
454
+ },
455
+ "rakancorle1/thinkguard": {
456
+ "model_developer": "RakanCorle1",
457
+ "model_type": "specialized",
458
+ "url": "https://huggingface.co/Rakancorle1/ThinkGuard",
459
+ "cost_info": {
460
+ "cost_per_1M_input_tokens": "N/A",
461
+ "cost_per_1M_output_tokens": "N/A",
462
+ "source": "RunPod",
463
+ "cost_per_h": 2.39,
464
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
465
+ },
466
+ "execution_specifications": {
467
+ "type": "Local",
468
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
469
+ }
470
+ },
471
+ "allenai/wildguard": {
472
+ "model_developer": "AllenAI",
473
+ "model_type": "specialized",
474
+ "url": "https://huggingface.co/allenai/wildguard",
475
+ "cost_info": {
476
+ "cost_per_1M_input_tokens": "N/A",
477
+ "cost_per_1M_output_tokens": "N/A",
478
+ "source": "RunPod",
479
+ "cost_per_h": 2.39,
480
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
481
+ },
482
+ "execution_specifications": {
483
+ "type": "Local",
484
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
485
+ }
486
+ },
487
+ "toxicityprompts/polyguard-ministral": {
488
+ "model_developer": "ToxicityPrompts",
489
+ "model_type": "specialized",
490
+ "url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Ministral",
491
+ "cost_info": {
492
+ "cost_per_1M_input_tokens": "N/A",
493
+ "cost_per_1M_output_tokens": "N/A",
494
+ "source": "RunPod",
495
+ "cost_per_h": 2.39,
496
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
497
+ },
498
+ "execution_specifications": {
499
+ "type": "Local",
500
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
501
+ }
502
+ },
503
+ "toxicityprompts/polyguard-qwen": {
504
+ "model_developer": "ToxicityPrompts",
505
+ "model_type": "specialized",
506
+ "url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Qwen",
507
+ "cost_info": {
508
+ "cost_per_1M_input_tokens": "N/A",
509
+ "cost_per_1M_output_tokens": "N/A",
510
+ "source": "RunPod",
511
+ "cost_per_h": 2.39,
512
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
513
+ },
514
+ "execution_specifications": {
515
+ "type": "Local",
516
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
517
+ }
518
+ },
519
+ "toxicityprompts/polyguard-qwen-smol": {
520
+ "model_developer": "ToxicityPrompts",
521
+ "model_type": "specialized",
522
+ "url": "https://huggingface.co/ToxicityPrompts/PolyGuard-Qwen-Smol",
523
+ "cost_info": {
524
+ "cost_per_1M_input_tokens": "N/A",
525
+ "cost_per_1M_output_tokens": "N/A",
526
+ "source": "RunPod",
527
+ "cost_per_h": 2.39,
528
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
529
+ },
530
+ "execution_specifications": {
531
+ "type": "Local",
532
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
533
+ }
534
+ },
535
+ "ibm-granite/granite-guardian-3.0-2b": {
536
+ "model_developer": "IBM",
537
+ "model_type": "specialized",
538
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.0-2b",
539
+ "cost_info": {
540
+ "cost_per_1M_input_tokens": "N/A",
541
+ "cost_per_1M_output_tokens": "N/A",
542
+ "source": "RunPod",
543
+ "cost_per_h": 2.39,
544
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
545
+ },
546
+ "execution_specifications": {
547
+ "type": "Local",
548
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
549
+ }
550
+ },
551
+ "ibm-granite/granite-guardian-3.0-8b": {
552
+ "model_developer": "IBM",
553
+ "model_type": "specialized",
554
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.0-8b",
555
+ "cost_info": {
556
+ "cost_per_1M_input_tokens": "N/A",
557
+ "cost_per_1M_output_tokens": "N/A",
558
+ "source": "RunPod",
559
+ "cost_per_h": 2.39,
560
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
561
+ },
562
+ "execution_specifications": {
563
+ "type": "Local",
564
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
565
+ }
566
+ },
567
+ "ibm-granite/granite-guardian-3.1-2b": {
568
+ "model_developer": "IBM",
569
+ "model_type": "specialized",
570
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.1-2b",
571
+ "cost_info": {
572
+ "cost_per_1M_input_tokens": "N/A",
573
+ "cost_per_1M_output_tokens": "N/A",
574
+ "source": "RunPod",
575
+ "cost_per_h": 2.39,
576
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
577
+ },
578
+ "execution_specifications": {
579
+ "type": "Local",
580
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
581
+ }
582
+ },
583
+ "ibm-granite/granite-guardian-3.1-8b": {
584
+ "model_developer": "IBM",
585
+ "model_type": "specialized",
586
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.1-8b",
587
+ "cost_info": {
588
+ "cost_per_1M_input_tokens": "N/A",
589
+ "cost_per_1M_output_tokens": "N/A",
590
+ "source": "RunPod",
591
+ "cost_per_h": 2.39,
592
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
593
+ },
594
+ "execution_specifications": {
595
+ "type": "Local",
596
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
597
+ }
598
+ },
599
+ "ibm-granite/granite-guardian-3.2-5b": {
600
+ "model_developer": "IBM",
601
+ "model_type": "specialized",
602
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.2-5b",
603
+ "cost_info": {
604
+ "cost_per_1M_input_tokens": "N/A",
605
+ "cost_per_1M_output_tokens": "N/A",
606
+ "source": "RunPod",
607
+ "cost_per_h": 2.39,
608
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
609
+ },
610
+ "execution_specifications": {
611
+ "type": "Local",
612
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
613
+ }
614
+ },
615
+ "ibm-granite/granite-guardian-3.2-3b-a800m": {
616
+ "model_developer": "IBM",
617
+ "model_type": "specialized",
618
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.2-3b-a800m",
619
+ "cost_info": {
620
+ "cost_per_1M_input_tokens": "N/A",
621
+ "cost_per_1M_output_tokens": "N/A",
622
+ "source": "RunPod",
623
+ "cost_per_h": 2.39,
624
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
625
+ },
626
+ "execution_specifications": {
627
+ "type": "Local",
628
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
629
+ }
630
+ },
631
+ "ibm-granite/granite-guardian-3.3-8b": {
632
+ "model_developer": "IBM",
633
+ "model_type": "specialized",
634
+ "url": "https://huggingface.co/ibm-granite/granite-guardian-3.3-8b",
635
+ "cost_info": {
636
+ "cost_per_1M_input_tokens": "N/A",
637
+ "cost_per_1M_output_tokens": "N/A",
638
+ "source": "RunPod",
639
+ "cost_per_h": 2.39,
640
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
641
+ },
642
+ "execution_specifications": {
643
+ "type": "Local",
644
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using vLLM."
645
+ }
646
+ },
647
+ "govtech/lionguard-2": {
648
+ "model_developer": "GovTech",
649
+ "model_type": "specialized",
650
+ "url": "https://huggingface.co/govtech/lionguard-2",
651
+ "cost_info": {
652
+ "cost_per_1M_input_tokens": "N/A",
653
+ "cost_per_1M_output_tokens": "N/A",
654
+ "source": "RunPod",
655
+ "cost_per_h": 2.39,
656
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
657
+ },
658
+ "execution_specifications": {
659
+ "type": "Local",
660
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
661
+ }
662
+ },
663
+ "govtech/lionguard-2.1": {
664
+ "model_developer": "GovTech",
665
+ "model_type": "specialized",
666
+ "url": "https://huggingface.co/govtech/lionguard-2.1",
667
+ "cost_info": {
668
+ "cost_per_1M_input_tokens": "N/A",
669
+ "cost_per_1M_output_tokens": "N/A",
670
+ "source": "RunPod",
671
+ "cost_per_h": 2.39,
672
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
673
+ },
674
+ "execution_specifications": {
675
+ "type": "Local",
676
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
677
+ }
678
+ },
679
+ "govtech/lionguard-2-lite": {
680
+ "model_developer": "GovTech",
681
+ "model_type": "specialized",
682
+ "url": "https://huggingface.co/govtech/lionguard-2-lite",
683
+ "cost_info": {
684
+ "cost_per_1M_input_tokens": "N/A",
685
+ "cost_per_1M_output_tokens": "N/A",
686
+ "source": "RunPod",
687
+ "cost_per_h": 2.39,
688
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
689
+ },
690
+ "execution_specifications": {
691
+ "type": "Local",
692
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
693
+ }
694
+ },
695
+ "leolee99/piguard": {
696
+ "model_developer": "Leolee99",
697
+ "model_type": "specialized",
698
+ "url": "https://huggingface.co/leolee99/PIGuard",
699
+ "cost_info": {
700
+ "cost_per_1M_input_tokens": "N/A",
701
+ "cost_per_1M_output_tokens": "N/A",
702
+ "source": "RunPod",
703
+ "cost_per_h": 2.39,
704
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
705
+ },
706
+ "execution_specifications": {
707
+ "type": "Local",
708
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
709
+ }
710
+ },
711
+ "meta-llama/llama-prompt-guard-2-22m": {
712
+ "model_developer": "Meta",
713
+ "model_type": "specialized",
714
+ "url": "https://huggingface.co/meta-llama/Llama-Prompt-Guard-2-22M",
715
+ "cost_info": {
716
+ "cost_per_1M_input_tokens": "N/A",
717
+ "cost_per_1M_output_tokens": "N/A",
718
+ "source": "RunPod",
719
+ "cost_per_h": 2.39,
720
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
721
+ },
722
+ "execution_specifications": {
723
+ "type": "Local",
724
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
725
+ }
726
+ },
727
+ "meta-llama/llama-prompt-guard-2-86m": {
728
+ "model_developer": "Meta",
729
+ "model_type": "specialized",
730
+ "url": "https://huggingface.co/meta-llama/Llama-Prompt-Guard-2-86M",
731
+ "cost_info": {
732
+ "cost_per_1M_input_tokens": "N/A",
733
+ "cost_per_1M_output_tokens": "N/A",
734
+ "source": "RunPod",
735
+ "cost_per_h": 2.39,
736
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
737
+ },
738
+ "execution_specifications": {
739
+ "type": "Local",
740
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the transformers Library."
741
+ }
742
+ },
743
+ "protectai/llm-guard": {
744
+ "model_developer": "ProtectAI",
745
+ "model_type": "specialized",
746
+ "url": "https://protectai.github.io/llm-guard/input_scanners/prompt_injection/",
747
+ "cost_info": {
748
+ "cost_per_1M_input_tokens": "N/A",
749
+ "cost_per_1M_output_tokens": "N/A",
750
+ "source": "RunPod",
751
+ "cost_per_h": 2.39,
752
+ "additional_info": "Output token cost is disregarded. The cost per 1M input tokens is estimated as total_cost * (1,000,000 / total_input_tokens)."
753
+ },
754
+ "execution_specifications": {
755
+ "type": "Local",
756
+ "details": "This model was ran on an H100 (80GB PCIe) on RunPod using the llm-guard Python SDK."
757
+ }
758
+ },
759
+ "neuraltrust/promptguard": {
760
+ "model_developer": "NeuralTrust",
761
+ "model_type": "specialized",
762
+ "url": "https://neuraltrust.ai/prompt-guard",
763
+ "cost_info": {
764
+ "cost_per_1M_input_tokens": 0.0,
765
+ "cost_per_1M_output_tokens": 0.0,
766
+ "source": "NeuralTrust",
767
+ "cost_per_h": "N/A",
768
+ "additional_info": "Usage is free on the API. We were banned after about 1800 requests."
769
+ },
770
+ "execution_specifications": {
771
+ "type": "API",
772
+ "details": "REST API accessed through a 'Memory-Optimized 16GB RAM' CPU3 RunPod instance from US-KS-2."
773
+ }
774
+ }
775
+ }
jailbreak.py ADDED
@@ -0,0 +1,981 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from pathlib import Path
3
+ from typing import Any, Dict, List
4
+
5
+ import gradio as gr
6
+ import pandas as pd
7
+
8
+ from shared import (
9
+ CATEGORY_TABLE_CSS,
10
+ DEFAULT_WEIGHTS,
11
+ LEADERBOARD_DARK_MODE_CSS,
12
+ LEADERBOARD_TABLE_CSS,
13
+ build_pareto_figure,
14
+ build_weights,
15
+ create_empty_pareto_figure,
16
+ create_weight_bar_html,
17
+ escape_html,
18
+ get_color_for_accuracy,
19
+ sort_by_overall_score,
20
+ )
21
+
22
+ # ── Data loading ────────────────────────────────────────────────────────
23
+
24
+ _DATA_DIR = Path(__file__).parent / "data"
25
+
26
+
27
+ def _load_metrics() -> Dict[str, Any]:
28
+ metrics_path = _DATA_DIR / "jailbreak_metrics.json"
29
+ if not metrics_path.exists():
30
+ print(f"Warning: {metrics_path} not found")
31
+ return {}
32
+ with open(metrics_path, "r") as f:
33
+ return json.load(f)
34
+
35
+
36
+ METRICS_DATA = _load_metrics()
37
+
38
+
39
+ # ── Constants ───────────────────────────────────────────────────────────
40
+
41
+ AGGREGATE_OPTION = "Aggregate (All Datasets)"
42
+ OVERVIEW_OPTION = "Overview (All Datasets)"
43
+
44
+ DATASET_DESCRIPTIONS: Dict[str, Dict[str, Any]] = {
45
+ "allenai-wildjailbreak": {
46
+ "url": "https://huggingface.co/datasets/allenai/wildjailbreak",
47
+ "summary": "This dataset generated adversarial prompt using WildTeaming (https://github.com/allenai/wildteaming).\nWe are using the eval split of this dataset. It only contains prompts that look like jailbreaks, but do not necessarily have harmful content.",
48
+ "categories": {
49
+ "adversarial_harmful": "Jailbreak prompts with harmful content.",
50
+ "adversarial_benign": "Jailbreak prompts with benign content.",
51
+ },
52
+ "accuracy_categories": ["adversarial_harmful"],
53
+ "fpr_categories": ["adversarial_benign"],
54
+ },
55
+ "bells-o-project-jailbreak-dataset": {
56
+ "url": "https://huggingface.co/datasets/centrepourlasecuriteia/jailbreak-dataset",
57
+ "summary": "This dataset generated adversarial prompts from the companion dataset centrepourlasecuriteia/content-moderation-input utilizing uncensored models.",
58
+ "categories": {
59
+ "Benign": "Adversarial prompts with benign content.",
60
+ "CBRN": "Adversarial prompts with harmful CBRN content.",
61
+ "Cyber": "Adversarial prompts with harmful Cyber content.",
62
+ "Harm to Minors": "Adversarial prompts with harmful content regarding Harm to Minors.",
63
+ "Harmful Manipulation": "Adversarial prompts with harmful content regarding manipulation.",
64
+ "Illegal Activities": "Adversarial prompts with harmful content regarding Illegal Activities.",
65
+ "Integrity & Quality": "Adversarial prompts with harmful content regarding Integrity & Quality.",
66
+ "Physical Harm": "Adversarial prompts with Physical Harm content.",
67
+ "Privacy": "Adversarial prompts with harmful Privacy content.",
68
+ "Self-Harm": "Adversarial prompts with harmful Self-Harm\t content.",
69
+ "Sexual Content": "Adversarial prompts with harmful sexual content.",
70
+ },
71
+ "fpr_categories": ["Benign"],
72
+ "accuracy_categories": [
73
+ "CBRN", "Cyber", "Harm to Minors", "Harmful Manipulation",
74
+ "Illegal Activities", "Integrity & Quality", "Physical Harm",
75
+ "Privacy", "Self-Harm", "Sexual Content",
76
+ ],
77
+ },
78
+ "bells-o-project-BET-jailbreak-dataset": {
79
+ "url": "https://huggingface.co/datasets/centrepourlasecuriteia/BET-jailbreak-dataset",
80
+ "summary": "This dataset generated adversarial prompts from the companion dataset centrepourlasecuriteia/content-moderation-input using BET (https://github.com/qfeuilla/BehaviorEliciationTool).",
81
+ "categories": {
82
+ "Benign": "Adversarial prompts with benign content.",
83
+ "CBRN": "Adversarial prompts with harmful CBRN content.",
84
+ "Cyber": "Adversarial prompts with harmful Cyber content.",
85
+ "Harm to Minors": "Adversarial prompts with harmful content regarding Harm to Minors.",
86
+ "Harmful Manipulation": "Adversarial prompts with harmful content regarding manipulation.",
87
+ "Illegal Activities": "Adversarial prompts with harmful content regarding Illegal Activities.",
88
+ "Integrity & Quality": "Adversarial prompts with harmful content regarding Integrity & Quality.",
89
+ "Physical Harm": "Adversarial prompts with Physical Harm content.",
90
+ "Privacy": "Adversarial prompts with harmful Privacy content.",
91
+ "Self-Harm": "Adversarial prompts with harmful Self-Harm content.",
92
+ "Sexual Content": "Adversarial prompts with harmful sexual content.",
93
+ },
94
+ "fpr_categories": ["Benign"],
95
+ "accuracy_categories": [
96
+ "CBRN", "Cyber", "Harm to Minors", "Harmful Manipulation",
97
+ "Illegal Activities", "Integrity & Quality", "Physical Harm",
98
+ "Privacy", "Self-Harm", "Sexual Content",
99
+ ],
100
+ },
101
+ "deepset-prompt-injections": {
102
+ "url": "https://huggingface.co/datasets/deepset/prompt-injections",
103
+ "summary": "The prompt injections dataset by Deepset.",
104
+ "categories": {"1": "Adversarial prompts with harmful content.", "0": "Normal prompts with benign content."},
105
+ "accuracy_categories": ["1"],
106
+ "fpr_categories": ["0"],
107
+ },
108
+ "local_datasets-malignant": {
109
+ "url": "https://www.kaggle.com/datasets/marycamilainfo/prompt-injection-malignant",
110
+ "summary": "This dataset is specifically curated for jailbreak prompt injection instances.",
111
+ "categories": {
112
+ "conversation": "Normal prompts with benign content, extracted from the Persona-Chat dataset (https://www.kaggle.com/datasets/atharvjairath/personachat).",
113
+ "act_as": "Role-playing prompts with benign content.",
114
+ "jailbreak": "Adversarial prompts with harmful content.",
115
+ },
116
+ "accuracy_categories": ["jailbreak"],
117
+ "fpr_categories": ["act_as", "conversation"],
118
+ },
119
+ "TrustAIRLab-in-the-wild-jailbreak-prompts": {
120
+ "url": "https://huggingface.co/datasets/TrustAIRLab/in-the-wild-jailbreak-prompts",
121
+ "summary": "This dataset consists of jailbreak prompts that were collected from Reddit, Discord, and websites. We are using the 'jailbreak_2023_12_25' version. It does not contain any benign samples.",
122
+ "categories": {
123
+ "true": "Adversarial prompts with harmful content.",
124
+ },
125
+ "accuracy_categories": ["true"],
126
+ "fpr_categories": ["N/A"],
127
+ },
128
+ }
129
+
130
+ DATASET_LABELS = {
131
+ "allenai-wildjailbreak": "WildJailbreak (AllenAI)",
132
+ "bells-o-project-jailbreak-dataset": "BELLS-O Jailbreak (CeSIA)",
133
+ "bells-o-project-BET-jailbreak-dataset": "BELLS-O BET Jailbreak (CeSIA)",
134
+ "deepset-prompt-injections": "Prompt Injections (Deepset)",
135
+ "local_datasets-malignant": "Prompt Injection Malignant (Mary Camila)",
136
+ "TrustAIRLab-in-the-wild-jailbreak-prompts": "In-the-Wild Jailbreak Prompts (TrustAIRLab)",
137
+ }
138
+
139
+ CATEGORY_LABELS = {
140
+ "hate speech": "Hate Speech",
141
+ "harmful manipulation": "Harmful Manipulation",
142
+ "privacy": "Privacy",
143
+ "cyber": "Cyber",
144
+ "physical harm": "Physical Harm",
145
+ "sexual content": "Sexual Content",
146
+ "integrity & quality violations": "Integrity & Quality",
147
+ "cbrn": "CBRN",
148
+ "illegal activities": "Illegal Activities",
149
+ "self-harm": "Self-Harm",
150
+ "harm to minors": "Harm to Minors",
151
+ }
152
+
153
+
154
+ # ── Dataset info HTML ───────────────────────────────────────────────────
155
+
156
+ def create_dataset_info_html(dataset_name: str) -> str:
157
+ info = DATASET_DESCRIPTIONS.get(dataset_name)
158
+ if not info:
159
+ return ""
160
+
161
+ ds_label = DATASET_LABELS.get(dataset_name, dataset_name)
162
+ url = info.get("url", "")
163
+ summary = info.get("summary", "")
164
+ categories = info.get("categories", {})
165
+ accuracy_categories = info.get("accuracy_categories", [])
166
+ fpr_categories = info.get("fpr_categories", [])
167
+
168
+ title_html = f'<a href="{url}" target="_blank">{ds_label}</a>' if url else ds_label
169
+
170
+ html = """<style>
171
+ .ds-info-box {
172
+ background: #f8fafc;
173
+ border: 1px solid #e2e8f0;
174
+ border-radius: 8px;
175
+ padding: 16px;
176
+ margin: 12px 0;
177
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
178
+ }
179
+ .ds-info-box .ds-title { margin: 0 0 8px 0 !important; padding: 0 !important; color: #1e293b; }
180
+ .ds-info-box .ds-title a { color: #1e293b; text-decoration: underline; }
181
+ .ds-info-box .ds-text { color: #475569; font-size: 14px; }
182
+ .ds-info-box .ds-cat-item { color: #475569; font-size: 13px; margin-bottom: 2px; }
183
+ @media (prefers-color-scheme: dark) {
184
+ .ds-info-box {
185
+ background: #2a2a2a !important;
186
+ border-color: #4a4a4a !important;
187
+ }
188
+ .ds-info-box .ds-title,
189
+ .ds-info-box .ds-title a { color: #f3f4f6 !important; }
190
+ .ds-info-box .ds-text { color: #d1d5db !important; }
191
+ .ds-info-box .ds-cat-item { color: #d1d5db !important; }
192
+ }
193
+ </style>"""
194
+
195
+ html += f'<div class="ds-info-box"><h4 class="ds-title">{title_html}</h4>'
196
+
197
+ if summary:
198
+ html += f'<p class="ds-text" style="margin:0 0 8px 0;">{summary}</p>'
199
+
200
+ if categories:
201
+ html += '<div style="margin-top:8px;"><strong class="ds-text">Categories:</strong>'
202
+ html += '<ul style="margin:4px 0 0 0; padding-left:20px; list-style:none;">'
203
+ for cat_key, cat_desc in categories.items():
204
+ cat_label = CATEGORY_LABELS.get(cat_key, cat_key)
205
+ html += f'<li class="ds-cat-item"><strong>{cat_label}:</strong> {cat_desc}</li>'
206
+ html += "</ul></div>"
207
+
208
+ if accuracy_categories:
209
+ cat_names = ", ".join(CATEGORY_LABELS.get(c, c) for c in accuracy_categories)
210
+ html += f'<p class="ds-text" style="margin:8px 0 0 0;"><strong>Detection Rate from:</strong> {cat_names}</p>'
211
+
212
+ if fpr_categories:
213
+ cat_names = ", ".join(CATEGORY_LABELS.get(c, c) for c in fpr_categories)
214
+ html += f'<p class="ds-text" style="margin:4px 0 0 0;"><strong>FPR from:</strong> {cat_names}</p>'
215
+
216
+ html += "</div>"
217
+ return html
218
+
219
+
220
+ # ── Data helpers ────────────────────────────────────────────────────────
221
+
222
+ def get_available_datasets() -> List[str]:
223
+ datasets = set()
224
+ for data in METRICS_DATA.values():
225
+ ds = data.get("dataset_name", "")
226
+ if ds:
227
+ datasets.add(ds)
228
+ return sorted(datasets)
229
+
230
+
231
+ def get_dataset_choices() -> List[tuple]:
232
+ available = get_available_datasets()
233
+ choices = [(AGGREGATE_OPTION, AGGREGATE_OPTION)]
234
+ for ds in available:
235
+ label = DATASET_LABELS.get(ds, ds)
236
+ choices.append((label, ds))
237
+ return choices
238
+
239
+
240
+ def filter_metrics_by_dataset(dataset_name: str) -> Dict[str, Any]:
241
+ return {k: v for k, v in METRICS_DATA.items() if v.get("dataset_name") == dataset_name}
242
+
243
+
244
+ def _get_model_identity_key(data: dict) -> str:
245
+ return f"{data.get('model_provider_use_case', '')}/{data.get('model_name', '')}"
246
+
247
+
248
+ def compute_aggregate_metrics() -> Dict[str, Any]:
249
+ model_groups: Dict[str, List[Dict[str, Any]]] = {}
250
+ for key, data in METRICS_DATA.items():
251
+ identity = _get_model_identity_key(data)
252
+ if identity not in model_groups:
253
+ model_groups[identity] = []
254
+ model_groups[identity].append(data)
255
+
256
+ aggregated = {}
257
+ for identity, entries in model_groups.items():
258
+ template = entries[0].copy()
259
+
260
+ template["accuracy"] = sum(e.get("accuracy", 0) for e in entries) / len(entries)
261
+ fpr_values = [e.get("fpr") for e in entries if isinstance(e.get("fpr"), (int, float))]
262
+ if fpr_values:
263
+ template["fpr"] = sum(fpr_values) / len(fpr_values)
264
+ else:
265
+ template["fpr"] = "N/A"
266
+ template["mean_latency"] = sum(e.get("mean_latency", 0) for e in entries) / len(entries)
267
+
268
+ all_categories = set()
269
+ for e in entries:
270
+ all_categories.update(e.get("accuracy_per_category", {}).keys())
271
+
272
+ agg_categories = {}
273
+ for cat in all_categories:
274
+ values = [
275
+ e.get("accuracy_per_category", {}).get(cat, 0)
276
+ for e in entries
277
+ if cat in e.get("accuracy_per_category", {})
278
+ ]
279
+ if values:
280
+ agg_categories[cat] = sum(values) / len(values)
281
+ template["accuracy_per_category"] = agg_categories
282
+
283
+ ci_entries = [e.get("latency_ci_95", {}) for e in entries]
284
+ if ci_entries:
285
+ template["latency_ci_95"] = {
286
+ "lower": sum(c.get("lower", 0) for c in ci_entries) / len(ci_entries),
287
+ "upper": sum(c.get("upper", 0) for c in ci_entries) / len(ci_entries),
288
+ "mean": sum(c.get("mean", 0) for c in ci_entries) / len(ci_entries),
289
+ "std_dev": sum(c.get("std_dev", 0) for c in ci_entries) / len(ci_entries),
290
+ "n": sum(c.get("n", 0) for c in ci_entries),
291
+ }
292
+
293
+ total_cost = 0
294
+ for e in entries:
295
+ tc = e.get("cost_info", {}).get("total_cost", 0)
296
+ if isinstance(tc, (int, float)):
297
+ total_cost += tc
298
+ template_cost = template.get("cost_info", {}).copy()
299
+ template_cost["total_cost"] = total_cost
300
+ template["cost_info"] = template_cost
301
+
302
+ template["dataset_name"] = AGGREGATE_OPTION
303
+ template["num_datasets"] = len(entries)
304
+
305
+ agg_key = f"aggregate/{identity}"
306
+ aggregated[agg_key] = template
307
+
308
+ return aggregated
309
+
310
+
311
+ def get_metrics_for_display(dataset_name: str) -> Dict[str, Any]:
312
+ if dataset_name == AGGREGATE_OPTION:
313
+ return compute_aggregate_metrics()
314
+ return filter_metrics_by_dataset(dataset_name)
315
+
316
+
317
+ def prepare_leaderboard_data(
318
+ selected_categories: List[str] | None = None, dataset_name: str = AGGREGATE_OPTION
319
+ ) -> pd.DataFrame:
320
+ metrics_data = get_metrics_for_display(dataset_name)
321
+
322
+ if not metrics_data:
323
+ return pd.DataFrame(
324
+ columns=[
325
+ "Model Snapshot", "Model Developer", "Provider", "Detection Rate (%)",
326
+ "FPR (%)", "Latency CI 95% (ms)", "Mean Latency (ms)", "Compute Access",
327
+ "Total Cost", "Cost per 1M units", "Cost per h", "Cost Additional Info",
328
+ "Model Type", "Execution Info",
329
+ ]
330
+ )
331
+
332
+ all_categories = set()
333
+ for data in metrics_data.values():
334
+ all_categories.update(data.get("accuracy_per_category", {}).keys())
335
+
336
+ use_overall = (
337
+ selected_categories is None or len(selected_categories) == 0 or set(selected_categories) == all_categories
338
+ )
339
+
340
+ rows = []
341
+ for key, data in metrics_data.items():
342
+ latency_ci = data.get("latency_ci_95", {})
343
+ cost_info = data.get("cost_info", {})
344
+
345
+ latency_ci_str = (
346
+ f"[{int(round(latency_ci.get('lower', 0), 3) * 1000)}, {int(round(latency_ci.get('upper', 0), 3) * 1000)}]"
347
+ )
348
+
349
+ cost_input = cost_info.get("cost_per_1M_input_tokens", "N/A")
350
+ cost_output = cost_info.get("cost_per_1M_output_tokens", "N/A")
351
+ if cost_input == "N/A" or cost_output == "N/A":
352
+ cost_str = "Unknown"
353
+ else:
354
+ cost_str = f"Input: ${round(cost_input, 2)}/1M, Output: ${round(cost_output, 2)}/1M"
355
+
356
+ if use_overall:
357
+ accuracy = data.get("accuracy", 0)
358
+ else:
359
+ accuracy_per_category = data.get("accuracy_per_category", {})
360
+ selected_accuracies = [
361
+ accuracy_per_category.get(cat, 0) for cat in selected_categories if cat in accuracy_per_category
362
+ ]
363
+ accuracy = sum(selected_accuracies) / len(selected_accuracies) if selected_accuracies else 0
364
+
365
+ accuracy_pct = accuracy * 100
366
+
367
+ fpr = data.get("fpr", 0)
368
+ if isinstance(fpr, float):
369
+ fpr = f"{round(fpr * 100, 2):.2f}%"
370
+
371
+ cost_per_h_value = data["cost_info"].get("cost_per_h", "Unknown")
372
+ cost_per_h_str = f"${cost_per_h_value}" if cost_per_h_value != "N/A" else cost_per_h_value
373
+
374
+ total_cost_raw = data["cost_info"].get("total_cost", 0)
375
+ if isinstance(total_cost_raw, (int, float)):
376
+ total_cost_display = f"${round(total_cost_raw, 2)}"
377
+ total_cost_sort = total_cost_raw
378
+ else:
379
+ total_cost_display = "Unknown"
380
+ total_cost_sort = float("inf")
381
+
382
+ rows.append(
383
+ {
384
+ "Model Snapshot": data.get("model_name", ""),
385
+ "Model URL": data.get("model_url", ""),
386
+ "Model Developer": data.get("model_developer", ""),
387
+ "Provider": data.get("provider", ""),
388
+ "Detection Rate (%)": round(accuracy_pct, 2),
389
+ "FPR (%)": fpr,
390
+ "Latency CI 95% (ms)": latency_ci_str,
391
+ "Mean Latency (ms)": int(round(data.get("mean_latency", 0), 3) * 1000),
392
+ "Compute Access": data["execution_specifications"].get("type", "Unknown"),
393
+ "Total Cost": total_cost_display,
394
+ "Cost per 1M units": cost_str,
395
+ "Cost per h": cost_per_h_str,
396
+ "Cost Additional Info": data["cost_info"].get("cost_additional_info", ""),
397
+ "Model Type": data.get("model_type", "Unknown"),
398
+ "Execution Info": data["execution_specifications"].get("details", "Unknown"),
399
+ "_accuracy": accuracy,
400
+ "_fpr": data.get("fpr", 0),
401
+ "_mean_latency": int(round(data.get("mean_latency", 0), 3) * 1000),
402
+ "_total_cost": total_cost_sort,
403
+ }
404
+ )
405
+
406
+ return pd.DataFrame(rows)
407
+
408
+
409
+ # ── Leaderboard HTML ────────────────────────────────────────────────────
410
+
411
+ def create_leaderboard_html(
412
+ sort_by: str = "Detection Rate (%)",
413
+ selected_categories: List[str] | None = None,
414
+ dataset_name: str = AGGREGATE_OPTION,
415
+ weights: Dict[str, float] | None = None,
416
+ ) -> str:
417
+ leaderboard_df = prepare_leaderboard_data(selected_categories=selected_categories, dataset_name=dataset_name)
418
+
419
+ sort_mapping = {
420
+ "Detection Rate (%)": "_accuracy",
421
+ "FPR (%)": "_fpr",
422
+ "Mean Latency (ms)": "_mean_latency",
423
+ "Total Cost": "_total_cost",
424
+ }
425
+
426
+ sort_column = sort_mapping.get(sort_by, "_accuracy")
427
+
428
+ if sort_by == "Overall Score":
429
+ sorted_df = sort_by_overall_score(leaderboard_df, weights).copy()
430
+ elif sort_by == "Detection Rate (%)":
431
+ sorted_df = leaderboard_df.sort_values(by=sort_column, ascending=False).copy()
432
+ elif sort_by in ["FPR (%)", "Mean Latency (ms)", "Total Cost"]:
433
+ sorted_df = leaderboard_df.sort_values(by=[sort_column, "_accuracy"], ascending=[True, False]).copy()
434
+ else:
435
+ sorted_df = leaderboard_df.sort_values(by=sort_column, ascending=False).copy()
436
+
437
+ sorted_df = sorted_df.reset_index(drop=True)
438
+
439
+ html = LEADERBOARD_TABLE_CSS
440
+ html += """
441
+ <div class="leaderboard-container">
442
+ <div class="footnotes-section" style="margin-top: 1.5rem; padding: 1rem; background: #f9fafb; border-radius: 8px; font-size: 13px; color: #374151; line-height: 1.6;">
443
+ <h4 style="margin-top: 0; margin-bottom: 0.75rem; font-size: 14px; font-weight: 600; color: #111827;">Column Explanations</h4>
444
+ <p style="margin: 0.5rem 0;"><sup>1</sup> <strong>Model Type:</strong> Shows if the supervisor is a repurposed generalist model or a specialized model made for jailbreak detection.</p>
445
+ <p style="margin: 0.5rem 0;"><sup>2</sup> <strong>Detection Rate (%):</strong> Accuracy on harmful/jailbreak content.</p>
446
+ <p style="margin: 0.5rem 0;"><sup>3</sup> <strong>FPR (%):</strong> False Positive Rate on benign content.</p>
447
+ <p style="margin: 0.5rem 0;"><sup>4</sup> <strong>Compute Access:</strong> Shows how this supervisor was run. Can be 'Local' or 'API'.</p>
448
+ <p style="margin: 0.5rem 0;"><sup>5</sup> <strong>Total Cost:</strong> The total cost was measured differently for local inference and API supervisors. For local inference, it is total_latency * cost_per_h. For API supervisors it is calculated using the usage metrics and pricing information.</p>
449
+ <p style="margin: 0.5rem 0;"><sup>6</sup> <strong>Cost per 1M units:</strong> Different systems calculate usage in different units (e.g. characters, tokens, requests). This column shows the cost per 1M measured units.</p>
450
+ <p style="margin: 0.5rem 0;"><sup>7</sup> <strong>Cost per h:</strong> Only applicable for local inference. This is the pricing information for the GPU pod (see the "Execution Info" column for more details).</p>
451
+ </div>
452
+ <table class="leaderboard-table">
453
+ <thead>
454
+ <tr>
455
+ <th>Rank</th>
456
+ <th>Model Snapshot</th>
457
+ <th>Model Developer</th>
458
+ <th>Provider</th>
459
+ <th title="Shows if the supervisor is a repurposed generalist model or a specialized model made for jailbreak detection.">Model Type <sup>1</sup></th>
460
+ <th title="Accuracy on harmful/jailbreak content.">Detection Rate (%) <sup>2</sup></th>
461
+ <th title="False Positive Rate on benign content.">FPR (%) <sup>3</sup></th>
462
+ <th>Latency CI 95% (ms)</th>
463
+ <th>Mean Latency (ms)</th>
464
+ <th title="Shows how this supervisor was ran. Can be 'Local' or 'API'.">Compute Access <sup>4</sup></th>
465
+ <th title="The total cost was measured differently for local inference and API supervisors. For local inference, it is total_latency * cost_per_h. For API supervisors it is calculated using the usage metrics and pricing information.">Total Cost <sup>5</sup></th>
466
+ <th title="Different systems calculate usage in different units (e.g. characters, tokens, requests). This column shows the cost per 1M measured units.">Cost per 1M units <sup>6</sup></th>
467
+ <th title="Only applicable for local inference. All models were run on RunPod.">Cost per h <sup>7</sup></th>
468
+ <th>Cost Additional Info</th>
469
+ <th>Execution Info</th>
470
+ </tr>
471
+ </thead>
472
+ <tbody>
473
+ """
474
+
475
+ for idx, row in sorted_df.iterrows():
476
+ rank = idx + 1
477
+ detection_rate = row["Detection Rate (%)"]
478
+ fpr = row["FPR (%)"]
479
+ latency = row["Mean Latency (ms)"]
480
+ model_type = row["Model Type"]
481
+ type_class = "type-specialized" if model_type == "specialized" else "type-generalist"
482
+
483
+ model_name = escape_html(row["Model Snapshot"])
484
+ model_url = str(row["Model URL"]) if row["Model URL"] else ""
485
+ developer = escape_html(row["Model Developer"])
486
+ provider = escape_html(row["Provider"])
487
+ compute_access = escape_html(row["Compute Access"])
488
+ total_cost = escape_html(row["Total Cost"])
489
+ cost_per_1m = escape_html(row["Cost per 1M units"])
490
+ cost_per_h = escape_html(row["Cost per h"])
491
+ cost_add_info = escape_html(row["Cost Additional Info"])
492
+ latency_ci = escape_html(row["Latency CI 95% (ms)"])
493
+ exec_info = escape_html(row["Execution Info"])
494
+
495
+ if model_url and model_url != "None":
496
+ model_name_html = f'<a href="{model_url}" target="_blank" rel="noopener noreferrer" style="color: inherit; text-decoration: none; border-bottom: 1px dotted currentColor;">{model_name}</a>'
497
+ else:
498
+ model_name_html = model_name
499
+
500
+ html += f"""
501
+ <tr>
502
+ <td><span class="rank-badge">{rank}</span></td>
503
+ <td class="model-name">{model_name_html}</td>
504
+ <td class="model-developer">{developer}</td>
505
+ <td><span class="provider-badge">{provider}</span></td>
506
+ <td><span class="model-type-badge {type_class}">{model_type.title()}</span></td>
507
+ <td class="detection-rate metric-value">{detection_rate:.2f}%</td>
508
+ <td class="metric-value">{fpr}</td>
509
+ <td>{latency_ci}</td>
510
+ <td class="metric-value">{latency:d}</td>
511
+ <td>{compute_access}</td>
512
+ <td>{total_cost}</td>
513
+ <td style="font-size: 12px;">{cost_per_1m}</td>
514
+ <td>{cost_per_h}</td>
515
+ <td style="font-size: 12px; color: #6b7280;">{cost_add_info}</td>
516
+ <td style="font-size: 12px; color: #6b7280;">{exec_info}</td>
517
+ </tr>
518
+ """
519
+
520
+ html += """
521
+ </tbody>
522
+ </table>
523
+ </div>
524
+ """
525
+ html += LEADERBOARD_DARK_MODE_CSS
526
+ return html
527
+
528
+
529
+ # ── Category tables ─────────────────────────────────────────────────────
530
+
531
+ def create_category_accuracy_table_html(
532
+ selected_models: List[str] | None = None, dataset_name: str = AGGREGATE_OPTION
533
+ ) -> str:
534
+ metrics_data = get_metrics_for_display(dataset_name)
535
+
536
+ if selected_models is None or len(selected_models) == 0:
537
+ selected_models = [data.get("model_name", "") for data in metrics_data.values()]
538
+
539
+ all_categories = set()
540
+ for data in metrics_data.values():
541
+ all_categories.update(data.get("accuracy_per_category", {}).keys())
542
+
543
+ category_order = list(CATEGORY_LABELS.keys())
544
+ sorted_categories = [cat for cat in category_order if cat in all_categories]
545
+ sorted_categories.extend([cat for cat in all_categories if cat not in category_order])
546
+
547
+ html = CATEGORY_TABLE_CSS
548
+ html += '<div class="category-table-container"><table class="category-table">'
549
+
550
+ html += "<thead><tr><th>Model</th>"
551
+ for category in sorted_categories:
552
+ category_label = CATEGORY_LABELS.get(category, category.title())
553
+ html += f"<th>{category_label}</th>"
554
+ html += "</tr></thead>"
555
+
556
+ html += "<tbody>"
557
+ for key, data in metrics_data.items():
558
+ model_name = data.get("model_name", "")
559
+ if model_name not in selected_models:
560
+ continue
561
+
562
+ html += f"<tr><td>{escape_html(model_name)}</td>"
563
+ accuracy_per_category = data.get("accuracy_per_category", {})
564
+ for category in sorted_categories:
565
+ accuracy = accuracy_per_category.get(category, 0)
566
+ acc_pct = round(accuracy * 100, 1)
567
+ bg_color = get_color_for_accuracy(accuracy)
568
+ html += f'<td style="background-color: {bg_color};">{acc_pct}%</td>'
569
+ html += "</tr>"
570
+
571
+ html += "</tbody></table></div>"
572
+ return html
573
+
574
+
575
+ def create_category_overview_html(selected_models: List[str] | None = None, metric: str = "Detection Rate") -> str:
576
+ datasets = get_available_datasets()
577
+ metric_key = "accuracy" if metric == "Detection Rate" else "fpr"
578
+
579
+ dataset_metrics: Dict[str, Dict[str, Any]] = {}
580
+ all_models: List[str] = []
581
+ for ds in datasets:
582
+ ds_data = filter_metrics_by_dataset(ds)
583
+ values_by_model: Dict[str, Any] = {}
584
+ for data in ds_data.values():
585
+ model = data.get("model_name", "")
586
+ values_by_model[model] = data.get(metric_key, 0)
587
+ if model not in all_models:
588
+ all_models.append(model)
589
+ dataset_metrics[ds] = values_by_model
590
+
591
+ all_models.sort()
592
+ if selected_models is not None and len(selected_models) > 0:
593
+ all_models = [m for m in all_models if m in selected_models]
594
+
595
+ html = CATEGORY_TABLE_CSS
596
+ html += '<div class="category-table-container"><table class="category-table">'
597
+
598
+ html += "<thead><tr><th>Model</th>"
599
+ for ds in datasets:
600
+ ds_label = DATASET_LABELS.get(ds, ds)
601
+ html += f"<th>{ds_label}</th>"
602
+ html += "</tr></thead>"
603
+
604
+ html += "<tbody>"
605
+ for model in all_models:
606
+ html += f"<tr><td>{escape_html(model)}</td>"
607
+ for ds in datasets:
608
+ val = dataset_metrics[ds].get(model)
609
+ if val is None or val == "N/A" or not isinstance(val, (int, float)):
610
+ html += '<td style="text-align: center; color: #9ca3af;">N/A</td>'
611
+ else:
612
+ val_pct = round(val * 100, 1)
613
+ if metric == "Detection Rate":
614
+ bg_color = get_color_for_accuracy(val)
615
+ else:
616
+ bg_color = get_color_for_accuracy(1.0 - val)
617
+ html += f'<td style="background-color: {bg_color};">{val_pct}%</td>'
618
+ html += "</tr>"
619
+
620
+ html += "</tbody></table></div>"
621
+ return html
622
+
623
+
624
+ # ── Helpers ─────────────────────────────────────────────────────────────
625
+
626
+ def get_available_categories(dataset_name: str = AGGREGATE_OPTION) -> List[tuple]:
627
+ metrics_data = get_metrics_for_display(dataset_name)
628
+ all_categories = set()
629
+ for data in metrics_data.values():
630
+ all_categories.update(data.get("accuracy_per_category", {}).keys())
631
+
632
+ category_order = list(CATEGORY_LABELS.keys())
633
+ sorted_categories = [cat for cat in category_order if cat in all_categories]
634
+ sorted_categories.extend([cat for cat in all_categories if cat not in category_order])
635
+ return [(CATEGORY_LABELS.get(cat, cat.title()), cat) for cat in sorted_categories]
636
+
637
+
638
+ def get_available_models(dataset_name: str = AGGREGATE_OPTION) -> List[str]:
639
+ metrics_data = get_metrics_for_display(dataset_name)
640
+ return sorted(set(data.get("model_name", "") for data in metrics_data.values()))
641
+
642
+
643
+ # ── Pareto ──────────────────────────────────────────────────────────────
644
+
645
+ _PARETO_METRIC_MAP = {
646
+ "Detection Rate in %": ("_accuracy", False),
647
+ "FPR in %": ("_fpr", True),
648
+ "Mean Latency in ms": ("_mean_latency", True),
649
+ "Total Cost in USD": ("_total_cost", True),
650
+ }
651
+
652
+
653
+ def create_pareto_plot_interactive(x_metric, y_metric, dataset_name=AGGREGATE_OPTION):
654
+ df = prepare_leaderboard_data(None, dataset_name)
655
+ return build_pareto_figure(df, x_metric, y_metric, _PARETO_METRIC_MAP)
656
+
657
+
658
+ # ── Tab builder ─────────────────────────────────────────────────────────
659
+
660
+ def build_jailbreak_tab():
661
+ """Build the three sub-tabs (Leaderboard, Category Performance, Pareto Frontier)
662
+ for the jailbreak detection leaderboard."""
663
+
664
+ dataset_choices = get_dataset_choices()
665
+ default_dataset = AGGREGATE_OPTION
666
+
667
+ with gr.Tabs():
668
+ # ── Leaderboard sub-tab ─────────────────────────────────────
669
+ with gr.Tab("Leaderboard"):
670
+ with gr.Column():
671
+ gr.Markdown("### Interactive Leaderboard")
672
+ gr.Markdown(
673
+ "Sort the leaderboard by different metrics to compare model performance. "
674
+ "Use the dropdowns below to change the sorting order and dataset. "
675
+ "Select specific categories to see detection rates calculated only for those categories."
676
+ )
677
+
678
+ with gr.Row():
679
+ dataset_selector_lb = gr.Dropdown(
680
+ choices=dataset_choices,
681
+ value=default_dataset,
682
+ label="Dataset",
683
+ interactive=True,
684
+ info="Select a specific dataset or aggregate across all datasets.",
685
+ )
686
+ sort_metric = gr.Dropdown(
687
+ choices=[
688
+ "Overall Score",
689
+ "Detection Rate (%)",
690
+ "FPR (%)",
691
+ "Mean Latency (ms)",
692
+ "Total Cost",
693
+ ],
694
+ value="Overall Score",
695
+ label="Sort by Metric",
696
+ interactive=True,
697
+ info="Higher detection rate is better. Lower FPR and latency are better.",
698
+ )
699
+
700
+ with gr.Group(visible=True) as weight_row:
701
+ with gr.Row():
702
+ weight_detection = gr.Number(
703
+ value=DEFAULT_WEIGHTS["Detection Rate (%)"],
704
+ label="Detection Rate weight",
705
+ minimum=0.0,
706
+ interactive=True,
707
+ )
708
+ weight_fpr = gr.Number(
709
+ value=DEFAULT_WEIGHTS["FPR (%)"],
710
+ label="FPR weight",
711
+ minimum=0.0,
712
+ interactive=True,
713
+ )
714
+ weight_latency = gr.Number(
715
+ value=DEFAULT_WEIGHTS["Mean Latency (ms)"],
716
+ label="Latency weight",
717
+ minimum=0.0,
718
+ interactive=True,
719
+ )
720
+ weight_cost = gr.Number(
721
+ value=DEFAULT_WEIGHTS["Total Cost"],
722
+ label="Cost weight",
723
+ minimum=0.0,
724
+ interactive=True,
725
+ )
726
+ weight_bar = gr.HTML(value=create_weight_bar_html(DEFAULT_WEIGHTS))
727
+ weight_inputs = [weight_detection, weight_fpr, weight_latency, weight_cost]
728
+
729
+ dataset_info_html = gr.HTML(value="")
730
+
731
+ with gr.Row():
732
+ category_selector = gr.CheckboxGroup(
733
+ choices=[],
734
+ value=[],
735
+ label="Select Categories for Detection Rate",
736
+ interactive=False,
737
+ visible=False,
738
+ info="Select categories to calculate detection rate. Only available for individual datasets.",
739
+ )
740
+
741
+ leaderboard_html = gr.HTML(
742
+ value=create_leaderboard_html(
743
+ sort_by="Overall Score", dataset_name=default_dataset, weights=DEFAULT_WEIGHTS
744
+ ),
745
+ label="Model Rankings",
746
+ )
747
+
748
+ def update_leaderboard(sort_by, selected_categories, dataset_name, w_det, w_fpr, w_lat, w_cost):
749
+ weights = build_weights(w_det, w_fpr, w_lat, w_cost)
750
+ html = create_leaderboard_html(
751
+ sort_by=sort_by,
752
+ selected_categories=selected_categories,
753
+ dataset_name=dataset_name,
754
+ weights=weights,
755
+ )
756
+ bar = create_weight_bar_html(weights)
757
+ is_aggregate = dataset_name == AGGREGATE_OPTION
758
+ info = "" if is_aggregate else create_dataset_info_html(dataset_name)
759
+ return html, bar, info
760
+
761
+ def on_sort_change(sort_by, selected_categories, dataset_name, w_det, w_fpr, w_lat, w_cost):
762
+ weights = build_weights(w_det, w_fpr, w_lat, w_cost)
763
+ new_html = create_leaderboard_html(
764
+ sort_by=sort_by,
765
+ selected_categories=selected_categories,
766
+ dataset_name=dataset_name,
767
+ weights=weights,
768
+ )
769
+ visible = sort_by == "Overall Score"
770
+ bar = create_weight_bar_html(weights)
771
+ is_aggregate = dataset_name == AGGREGATE_OPTION
772
+ info = "" if is_aggregate else create_dataset_info_html(dataset_name)
773
+ return (
774
+ gr.update(visible=visible),
775
+ new_html,
776
+ bar,
777
+ info,
778
+ )
779
+
780
+ def update_categories_on_dataset_change(dataset_name, sort_by, w_det, w_fpr, w_lat, w_cost):
781
+ weights = build_weights(w_det, w_fpr, w_lat, w_cost)
782
+ new_html = create_leaderboard_html(sort_by=sort_by, dataset_name=dataset_name, weights=weights)
783
+ is_aggregate = dataset_name == AGGREGATE_OPTION
784
+ info = "" if is_aggregate else create_dataset_info_html(dataset_name)
785
+ if is_aggregate:
786
+ return (
787
+ gr.update(choices=[], value=[], interactive=False, visible=False),
788
+ new_html,
789
+ info,
790
+ )
791
+ else:
792
+ new_choices = get_available_categories(dataset_name)
793
+ new_values = [cat for _, cat in new_choices]
794
+ return (
795
+ gr.update(choices=new_choices, value=new_values, interactive=True, visible=True),
796
+ new_html,
797
+ info,
798
+ )
799
+
800
+ all_inputs = [sort_metric, category_selector, dataset_selector_lb] + weight_inputs
801
+
802
+ dataset_selector_lb.change(
803
+ fn=update_categories_on_dataset_change,
804
+ inputs=[dataset_selector_lb, sort_metric] + weight_inputs,
805
+ outputs=[category_selector, leaderboard_html, dataset_info_html],
806
+ )
807
+
808
+ sort_metric.change(
809
+ fn=on_sort_change,
810
+ inputs=all_inputs,
811
+ outputs=[weight_row, leaderboard_html, weight_bar, dataset_info_html],
812
+ )
813
+
814
+ category_selector.change(
815
+ fn=update_leaderboard,
816
+ inputs=all_inputs,
817
+ outputs=[leaderboard_html, weight_bar, dataset_info_html],
818
+ )
819
+
820
+ for w_input in weight_inputs:
821
+ w_input.change(
822
+ fn=update_leaderboard,
823
+ inputs=all_inputs,
824
+ outputs=[leaderboard_html, weight_bar, dataset_info_html],
825
+ )
826
+
827
+ # ── Category Performance sub-tab ────────────────────────────
828
+ with gr.Tab("Category Performance"):
829
+ with gr.Column():
830
+ gr.Markdown("### Performance per Category by Model")
831
+ gr.Markdown(
832
+ "Compare how different models perform across harm categories. "
833
+ "Each cell shows the detection rate (accuracy) for that model-category combination. "
834
+ "Cell colors indicate performance: darker green = higher accuracy (closer to 100%), lighter colors = lower accuracy."
835
+ )
836
+
837
+ dataset_choices_cat = [(OVERVIEW_OPTION, OVERVIEW_OPTION)] + [
838
+ c
839
+ for c in dataset_choices
840
+ if c[1] != AGGREGATE_OPTION and len(get_available_categories(c[1])) > 1
841
+ ]
842
+ cat_default_dataset = OVERVIEW_OPTION
843
+
844
+ with gr.Row():
845
+ dataset_selector_cat = gr.Dropdown(
846
+ choices=dataset_choices_cat,
847
+ value=cat_default_dataset,
848
+ label="Dataset",
849
+ interactive=True,
850
+ info="Select a dataset or Overview. Datasets with only one category are excluded.",
851
+ )
852
+ metric_selector_cat = gr.Dropdown(
853
+ choices=["Detection Rate", "FPR"],
854
+ value="Detection Rate",
855
+ label="Metric",
856
+ interactive=True,
857
+ visible=True,
858
+ info="Choose which metric to display. Only changeable in Overview mode.",
859
+ )
860
+
861
+ dataset_info_cat = gr.HTML(value="")
862
+
863
+ initial_model_choices = get_available_models(AGGREGATE_OPTION)
864
+ model_selector = gr.CheckboxGroup(
865
+ choices=initial_model_choices,
866
+ value=initial_model_choices,
867
+ label="Select Models to Compare",
868
+ interactive=True,
869
+ info="Select one or more models to compare their performance across categories.",
870
+ )
871
+
872
+ category_table_html = gr.HTML(
873
+ value=create_category_overview_html(initial_model_choices),
874
+ label="Category Accuracy Comparison",
875
+ )
876
+
877
+ def update_cat_table(models, dataset_name, metric):
878
+ if dataset_name == OVERVIEW_OPTION:
879
+ return create_category_overview_html(models, metric=metric), ""
880
+ table = create_category_accuracy_table_html(models, dataset_name=dataset_name)
881
+ info = create_dataset_info_html(dataset_name)
882
+ return table, info
883
+
884
+ def update_models_on_dataset_change(dataset_name, metric):
885
+ is_overview = dataset_name == OVERVIEW_OPTION
886
+ if is_overview:
887
+ new_models = get_available_models(AGGREGATE_OPTION)
888
+ new_html = create_category_overview_html(new_models, metric=metric)
889
+ else:
890
+ new_models = get_available_models(dataset_name)
891
+ new_html = create_category_accuracy_table_html(new_models, dataset_name=dataset_name)
892
+ info = "" if is_overview else create_dataset_info_html(dataset_name)
893
+ if is_overview:
894
+ metric_update = gr.update(value=metric, interactive=True)
895
+ else:
896
+ metric_update = gr.update(value="Detection Rate", interactive=False)
897
+ return (
898
+ gr.update(choices=new_models, value=new_models),
899
+ new_html,
900
+ metric_update,
901
+ info,
902
+ )
903
+
904
+ dataset_selector_cat.change(
905
+ fn=update_models_on_dataset_change,
906
+ inputs=[dataset_selector_cat, metric_selector_cat],
907
+ outputs=[model_selector, category_table_html, metric_selector_cat, dataset_info_cat],
908
+ )
909
+
910
+ model_selector.change(
911
+ fn=update_cat_table,
912
+ inputs=[model_selector, dataset_selector_cat, metric_selector_cat],
913
+ outputs=[category_table_html, dataset_info_cat],
914
+ )
915
+
916
+ metric_selector_cat.change(
917
+ fn=update_cat_table,
918
+ inputs=[model_selector, dataset_selector_cat, metric_selector_cat],
919
+ outputs=[category_table_html, dataset_info_cat],
920
+ )
921
+
922
+ # ── Pareto Frontier sub-tab ─────────────────────────────────
923
+ with gr.Tab("Pareto Frontier"):
924
+ with gr.Column():
925
+ gr.Markdown("### Pareto Frontier Analysis")
926
+ gr.Markdown(
927
+ "Visualize trade-offs between different metrics. Models on the Pareto frontier "
928
+ "represent optimal trade-offs where improving one metric would require sacrificing another. "
929
+ "Hover over points to see the model name."
930
+ )
931
+
932
+ with gr.Row():
933
+ dataset_selector_pareto = gr.Dropdown(
934
+ choices=dataset_choices,
935
+ value=default_dataset,
936
+ label="Dataset",
937
+ interactive=True,
938
+ info="Select a specific dataset or aggregate across all datasets.",
939
+ )
940
+
941
+ with gr.Row():
942
+ pareto_x_metric = gr.Dropdown(
943
+ choices=["Detection Rate in %", "FPR in %", "Mean Latency in ms", "Total Cost in USD"],
944
+ value="Detection Rate in %",
945
+ label="X-Axis Metric",
946
+ interactive=True,
947
+ )
948
+ pareto_y_metric = gr.Dropdown(
949
+ choices=["Detection Rate in %", "FPR in %", "Mean Latency in ms", "Total Cost in USD"],
950
+ value="FPR in %",
951
+ label="Y-Axis Metric",
952
+ interactive=True,
953
+ )
954
+
955
+ with gr.Column():
956
+ gr.HTML('<div style="display:flex; justify-content:center;">', visible=False)
957
+ pareto_plot = gr.Plot(
958
+ value=create_pareto_plot_interactive("Detection Rate in %", "FPR in %", default_dataset)
959
+ )
960
+ gr.HTML("</div>", visible=False)
961
+
962
+ def _update_pareto(x_metric, y_metric, dataset_name):
963
+ if x_metric == y_metric:
964
+ return create_empty_pareto_figure()
965
+ return create_pareto_plot_interactive(x_metric, y_metric, dataset_name)
966
+
967
+ pareto_x_metric.change(
968
+ fn=_update_pareto,
969
+ inputs=[pareto_x_metric, pareto_y_metric, dataset_selector_pareto],
970
+ outputs=pareto_plot,
971
+ )
972
+ pareto_y_metric.change(
973
+ fn=_update_pareto,
974
+ inputs=[pareto_x_metric, pareto_y_metric, dataset_selector_pareto],
975
+ outputs=pareto_plot,
976
+ )
977
+ dataset_selector_pareto.change(
978
+ fn=_update_pareto,
979
+ inputs=[pareto_x_metric, pareto_y_metric, dataset_selector_pareto],
980
+ outputs=pareto_plot,
981
+ )
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio>=4.0.0
2
+ pandas>=2.0.0
3
+ plotly>=5.0.0
4
+ scipy>=1.16.0
shared.py ADDED
@@ -0,0 +1,869 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import base64
2
+ from pathlib import Path
3
+ from typing import Dict
4
+
5
+ import gradio as gr
6
+ import numpy as np
7
+ import plotly.graph_objects as go
8
+ from scipy.interpolate import UnivariateSpline
9
+ from scipy.optimize import curve_fit
10
+
11
+
12
+ def get_color_for_accuracy(accuracy: float) -> str:
13
+ """Get background color based on accuracy (0-1). Closer to 1.0 = greener."""
14
+ acc_pct = accuracy * 100
15
+
16
+ if acc_pct >= 90:
17
+ green = 200 + int((acc_pct - 90) * 5.5)
18
+ return f"rgb({255 - green}, {min(255, green)}, {100})"
19
+ elif acc_pct >= 70:
20
+ green = 150 + int((acc_pct - 70) * 2.5)
21
+ return f"rgb({255 - green}, {min(255, green)}, {50})"
22
+ elif acc_pct >= 50:
23
+ yellow = 200 + int((acc_pct - 50) * 2.75)
24
+ return f"rgb({255}, {min(255, yellow)}, {100})"
25
+ elif acc_pct >= 30:
26
+ red = 255 - int((acc_pct - 30) * 2.75)
27
+ return f"rgb({red}, {150 + int((acc_pct - 30) * 2.75)}, {50})"
28
+ else:
29
+ red = 255
30
+ green = 100 + int(acc_pct * 1.67)
31
+ return f"rgb({red}, {green}, {100})"
32
+
33
+
34
+ def _short_label(name: str, max_len: int = 35) -> str:
35
+ return name if len(name) <= max_len else name[: max_len - 1] + "\u2026"
36
+
37
+
38
+ def escape_html(s: str) -> str:
39
+ return str(s).replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
40
+
41
+
42
+ # ── Weight / Overall-Score helpers ──────────────────────────────────────
43
+
44
+ DEFAULT_WEIGHTS = {
45
+ "Detection Rate (%)": 1.0,
46
+ "FPR (%)": 1.0,
47
+ "Mean Latency (ms)": 1.0,
48
+ "Total Cost": 1.0,
49
+ }
50
+
51
+ _RANK_CONFIG = {
52
+ "Detection Rate (%)": ("_accuracy", False),
53
+ "FPR (%)": ("_fpr", True),
54
+ "Mean Latency (ms)": ("_mean_latency", True),
55
+ "Total Cost": ("_total_cost", True),
56
+ }
57
+
58
+ _WEIGHT_COLORS = {
59
+ "Detection Rate (%)": "#22c55e",
60
+ "FPR (%)": "#ef4444",
61
+ "Mean Latency (ms)": "#3b82f6",
62
+ "Total Cost": "#f59e0b",
63
+ }
64
+
65
+ _WEIGHT_SHORT_LABELS = {
66
+ "Detection Rate (%)": "Detection",
67
+ "FPR (%)": "FPR",
68
+ "Mean Latency (ms)": "Latency",
69
+ "Total Cost": "Cost",
70
+ }
71
+
72
+
73
+ def sort_by_overall_score(df, weights: Dict[str, float] | None = None):
74
+ """Sort dataframe by weighted average rank across metrics."""
75
+ if weights is None:
76
+ weights = DEFAULT_WEIGHTS
77
+
78
+ rank_cols = []
79
+ for metric, (col, ascending) in _RANK_CONFIG.items():
80
+ w = weights.get(metric, 0.0)
81
+ if w == 0.0:
82
+ continue
83
+ rank_col = f"_rank_{col}"
84
+ df[rank_col] = df[col].rank(ascending=ascending, method="min")
85
+ rank_cols.append((rank_col, w))
86
+
87
+ if not rank_cols:
88
+ return df
89
+
90
+ df["_overall_score"] = sum(df[rc] * w for rc, w in rank_cols) / sum(w for _, w in rank_cols)
91
+ df = df.sort_values(by="_overall_score", ascending=True)
92
+ return df
93
+
94
+
95
+ def create_weight_bar_html(weights: Dict[str, float] | None = None) -> str:
96
+ """Create an HTML horizontal stacked bar showing the weight distribution."""
97
+ if weights is None:
98
+ weights = DEFAULT_WEIGHTS
99
+
100
+ total = sum(max(w, 0) for w in weights.values())
101
+ if total == 0:
102
+ return '<div style="height:28px; background:#e5e7eb; border-radius:6px;"></div>'
103
+
104
+ segments = ""
105
+ for metric, w in weights.items():
106
+ if w <= 0:
107
+ continue
108
+ pct = w / total * 100
109
+ color = _WEIGHT_COLORS.get(metric, "#6b7280")
110
+ label = _WEIGHT_SHORT_LABELS.get(metric, metric)
111
+ text = f"{label} {pct:.0f}%" if pct >= 12 else f"{pct:.0f}%" if pct >= 5 else ""
112
+ segments += (
113
+ f'<div style="width:{pct}%; background:{color}; color:white; display:flex;'
114
+ f" align-items:center; justify-content:center; font-size:12px; font-weight:600;"
115
+ f' white-space:nowrap; overflow:hidden; text-overflow:ellipsis; padding:0 4px;">'
116
+ f"{text}</div>"
117
+ )
118
+
119
+ return (
120
+ f'<div style="display:flex; height:28px; border-radius:6px; overflow:hidden;'
121
+ f' box-shadow:0 1px 3px rgba(0,0,0,0.1);">{segments}</div>'
122
+ )
123
+
124
+
125
+ def build_weights(w_det, w_fpr, w_lat, w_cost):
126
+ return {
127
+ "Detection Rate (%)": w_det if w_det is not None else 0.0,
128
+ "FPR (%)": w_fpr if w_fpr is not None else 0.0,
129
+ "Mean Latency (ms)": w_lat if w_lat is not None else 0.0,
130
+ "Total Cost": w_cost if w_cost is not None else 0.0,
131
+ }
132
+
133
+
134
+ # ── Pareto helpers ──────────────────────────────────────────────────────
135
+
136
+ def create_empty_pareto_figure(message: str = "Please select different metrics for X and Y axes"):
137
+ fig = go.Figure()
138
+ fig.add_annotation(
139
+ text=message,
140
+ x=0.5,
141
+ y=0.5,
142
+ showarrow=False,
143
+ font={"size": 16},
144
+ xref="paper",
145
+ yref="paper",
146
+ )
147
+ fig.update_layout(
148
+ xaxis={"visible": False},
149
+ yaxis={"visible": False},
150
+ template="plotly_white",
151
+ )
152
+ return fig
153
+
154
+
155
+ def build_pareto_figure(df, x_metric, y_metric, metric_map):
156
+ """Build a Pareto frontier plot from a prepared leaderboard dataframe.
157
+
158
+ Args:
159
+ df: DataFrame with columns including Model Snapshot and internal sort columns.
160
+ x_metric: Display name of x metric (key in metric_map).
161
+ y_metric: Display name of y metric (key in metric_map).
162
+ metric_map: Dict mapping display metric name to (column_name, minimize_bool).
163
+ """
164
+ if df.empty:
165
+ return create_empty_pareto_figure("No data available for the selected dataset")
166
+
167
+ x_col, x_minimize = metric_map[x_metric]
168
+ y_col, y_minimize = metric_map[y_metric]
169
+
170
+ x = df[x_col]
171
+ y = df[y_col]
172
+
173
+ # Pareto detection
174
+ is_pareto = []
175
+ for i in range(len(df)):
176
+ dominated = False
177
+ for j in range(len(df)):
178
+ if i == j:
179
+ continue
180
+ better_x = (x.iloc[j] <= x.iloc[i]) if x_minimize else (x.iloc[j] >= x.iloc[i])
181
+ better_y = (y.iloc[j] <= y.iloc[i]) if y_minimize else (y.iloc[j] >= y.iloc[i])
182
+ strictly = (x.iloc[j] != x.iloc[i]) or (y.iloc[j] != y.iloc[i])
183
+ if better_x and better_y and strictly:
184
+ dominated = True
185
+ break
186
+ is_pareto.append(not dominated)
187
+
188
+ df["pareto"] = is_pareto
189
+
190
+ fig = go.Figure()
191
+
192
+ # Dominated points
193
+ fig.add_trace(
194
+ go.Scatter(
195
+ x=df.loc[~df.pareto, x_col],
196
+ y=df.loc[~df.pareto, y_col],
197
+ mode="markers",
198
+ name="Dominated",
199
+ marker=dict(size=10, color="gray"),
200
+ customdata=[
201
+ [model, xv, yv]
202
+ for model, xv, yv in zip(
203
+ df.loc[~df.pareto, "Model Snapshot"], df.loc[~df.pareto, x_col], df.loc[~df.pareto, y_col]
204
+ )
205
+ ],
206
+ hovertemplate=(
207
+ "<b>%{customdata[0]}</b><br>"
208
+ f"{x_metric}:"
209
+ " %{customdata[1]:.3f}<br>"
210
+ f"{y_metric}:"
211
+ " %{customdata[2]:.3f}"
212
+ "<extra></extra>"
213
+ ),
214
+ )
215
+ )
216
+
217
+ pareto_df = df[df.pareto].reset_index(drop=True)
218
+ pareto_df_sorted = pareto_df.sort_values(by=x_col).reset_index(drop=True)
219
+
220
+ # Pareto frontier curve
221
+ if len(pareto_df_sorted) >= 2:
222
+ try:
223
+ x_pareto = np.array(pareto_df_sorted[x_col].tolist(), dtype=float)
224
+ y_pareto = np.array(pareto_df_sorted[y_col].tolist(), dtype=float)
225
+
226
+ if x_minimize != y_minimize:
227
+ def pareto_func(xv, a, b):
228
+ return a * np.power(np.clip(xv, 1e-10, None), b)
229
+ else:
230
+ def pareto_func(xv, a, b):
231
+ return a * np.power(np.clip(1 - xv, 1e-10, None), b)
232
+
233
+ try:
234
+ popt, _ = curve_fit(pareto_func, x_pareto, y_pareto, p0=[1.0, 1.0], maxfev=5000)
235
+
236
+ x_is_bounded = "Detection Rate" in x_metric or "FPR" in x_metric
237
+ y_is_bounded = "Detection Rate" in y_metric or "FPR" in y_metric
238
+
239
+ if x_is_bounded:
240
+ x_curve = np.linspace(0, 1, 500)
241
+ else:
242
+ x_all = np.array(df[x_col].tolist(), dtype=float)
243
+ x_min_val = max(0, float(np.min(x_all)))
244
+ x_max_val = float(np.max(x_all)) * 1.2
245
+ x_curve = np.linspace(x_min_val, x_max_val, 500)
246
+
247
+ y_curve = pareto_func(x_curve, *popt)
248
+
249
+ if y_is_bounded:
250
+ valid_indices = np.where((y_curve >= 0) & (y_curve <= 1))[0]
251
+ else:
252
+ valid_indices = np.where((y_curve >= 0) & (y_curve <= max(df[y_col])))[0]
253
+
254
+ if len(valid_indices) > 0:
255
+ x_curve_valid = x_curve[valid_indices]
256
+ y_curve_valid = y_curve[valid_indices]
257
+
258
+ fig.add_trace(
259
+ go.Scatter(
260
+ x=x_curve_valid.tolist(),
261
+ y=y_curve_valid.tolist(),
262
+ mode="lines",
263
+ name="Pareto Frontier Curve",
264
+ line={"color": "red", "width": 3},
265
+ showlegend=True,
266
+ hoverinfo="skip",
267
+ )
268
+ )
269
+ except Exception:
270
+ k = min(3, len(x_pareto) - 1)
271
+ spline = UnivariateSpline(x_pareto, y_pareto, k=k, s=0)
272
+ x_curve = np.linspace(0, 1, 500)
273
+ y_curve = np.clip(spline(x_curve), 0, 1)
274
+
275
+ fig.add_trace(
276
+ go.Scatter(
277
+ x=x_curve.tolist(),
278
+ y=y_curve.tolist(),
279
+ mode="lines",
280
+ name="Pareto Frontier Curve",
281
+ line={"color": "red", "width": 3},
282
+ showlegend=True,
283
+ hoverinfo="skip",
284
+ )
285
+ )
286
+ except Exception as e:
287
+ print(f"Warning: Could not create Pareto frontier curve: {e}")
288
+
289
+ # Pareto points with labels
290
+ text_positions = ["top center", "bottom center"]
291
+ text_pos = [text_positions[i % 2] for i in range(len(pareto_df))]
292
+
293
+ fig.add_trace(
294
+ go.Scatter(
295
+ x=pareto_df[x_col],
296
+ y=pareto_df[y_col],
297
+ mode="markers+text",
298
+ name="Pareto Frontier",
299
+ marker=dict(size=14, color="red"),
300
+ text=[_short_label(m) for m in pareto_df["Model Snapshot"]],
301
+ textposition=text_pos,
302
+ customdata=[
303
+ [model, xv, yv]
304
+ for model, xv, yv in zip(pareto_df["Model Snapshot"], pareto_df[x_col], pareto_df[y_col])
305
+ ],
306
+ hovertemplate=(
307
+ "<b>%{customdata[0]}</b><br>"
308
+ f"{x_metric}:"
309
+ " %{customdata[1]:.3f}<br>"
310
+ f"{y_metric}:"
311
+ " %{customdata[2]:.3f}"
312
+ "<extra></extra>"
313
+ ),
314
+ )
315
+ )
316
+
317
+ fig.update_layout(
318
+ autosize=True,
319
+ height=800,
320
+ xaxis_title=x_metric,
321
+ yaxis_title=y_metric,
322
+ hovermode="closest",
323
+ template="plotly_white",
324
+ )
325
+
326
+ if x_minimize:
327
+ fig.update_xaxes(autorange="reversed")
328
+ if y_minimize:
329
+ fig.update_yaxes(autorange="reversed")
330
+
331
+ return fig
332
+
333
+
334
+ # ── Footer ──────────────────────────────────────────────────────────────
335
+
336
+ def build_footer():
337
+ logo_path = Path(__file__).parent / "cesia_logo.png"
338
+ if logo_path.exists():
339
+ with open(logo_path, "rb") as logo_file:
340
+ logo_data = base64.b64encode(logo_file.read()).decode()
341
+ logo_src = f"data:image/png;base64,{logo_data}"
342
+ else:
343
+ logo_src = ""
344
+
345
+ span_display = "display:inline;" if not logo_src else "display:none;"
346
+ footer_html = f"""
347
+ <div class="footer-section">
348
+ <div class="footer-content">
349
+ <p class="footer-text">This project is led by</p>
350
+ {"<img src='" + logo_src + "' alt='CeSIA Logo' class='footer-logo' style='height:36px;vertical-align:middle;margin-bottom:4px;'>" if logo_src else ""}
351
+ <span style="{span_display} color: #4338ca; font-weight: 600;">Centre pour la S&eacute;curit&eacute; de l'IA (CeSIA)</span>
352
+ </div>
353
+ </div>
354
+ """
355
+ gr.HTML(footer_html)
356
+
357
+
358
+ # ── Global CSS ──────────────────────────────────────────────────────────
359
+
360
+ GLOBAL_CSS = """
361
+ <style>
362
+ .gradio-container {
363
+ max-width: 100% !important;
364
+ width: 100% !important;
365
+ margin: 0 !important;
366
+ padding-left: 0 !important;
367
+ padding-right: 0 !important;
368
+ }
369
+
370
+ .contain {
371
+ max-width: 100% !important;
372
+ width: 100% !important;
373
+ }
374
+
375
+ .block {
376
+ max-width: 100% !important;
377
+ }
378
+ .gradio-container {
379
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
380
+ }
381
+
382
+ h1 {
383
+ font-size: 2.5rem;
384
+ font-weight: 700;
385
+ color: #111827;
386
+ margin-bottom: 1rem;
387
+ letter-spacing: -0.02em;
388
+ }
389
+
390
+ h2 {
391
+ font-size: 1.75rem;
392
+ font-weight: 600;
393
+ color: #111827;
394
+ margin-top: 2rem;
395
+ margin-bottom: 1rem;
396
+ }
397
+
398
+ h3 {
399
+ font-size: 1.25rem;
400
+ font-weight: 600;
401
+ color: #374151;
402
+ margin-top: 1.5rem;
403
+ margin-bottom: 0.75rem;
404
+ }
405
+
406
+ @media (max-width: 768px) {
407
+ h1 {
408
+ font-size: 1.75rem;
409
+ }
410
+ h2 {
411
+ font-size: 1.5rem;
412
+ margin-top: 1.5rem;
413
+ }
414
+ h3 {
415
+ font-size: 1.125rem;
416
+ }
417
+ }
418
+
419
+ @media (prefers-color-scheme: dark) {
420
+ .gradio-container {
421
+ background: #1a1a1a !important;
422
+ color: #e5e7eb !important;
423
+ }
424
+ h1, h2, h3 {
425
+ color: #f3f4f6 !important;
426
+ }
427
+ }
428
+
429
+ .footer-section {
430
+ text-align: center;
431
+ margin-top: 3rem;
432
+ margin-bottom: 2rem;
433
+ padding: 1.5rem 0;
434
+ }
435
+
436
+ .footer-content {
437
+ display: flex;
438
+ align-items: center;
439
+ justify-content: center;
440
+ gap: 0.5rem;
441
+ flex-wrap: wrap;
442
+ }
443
+
444
+ .footer-text {
445
+ margin: 0;
446
+ display: inline;
447
+ }
448
+
449
+ .footer-logo {
450
+ display: inline-block;
451
+ vertical-align: middle;
452
+ }
453
+
454
+ .gradio-tabs {
455
+ margin-top: 2rem;
456
+ }
457
+
458
+ .gradio-tab-nav {
459
+ border-bottom: 2px solid #e5e7eb;
460
+ }
461
+
462
+ .gradio-tab-nav button {
463
+ font-size: 1.1rem;
464
+ font-weight: 600;
465
+ padding: 1rem 1.5rem;
466
+ transition: all 0.2s ease;
467
+ }
468
+
469
+ .gradio-tab-nav button.selected {
470
+ border-bottom: 3px solid #4338ca;
471
+ color: #4338ca;
472
+ }
473
+
474
+ .center-column {
475
+ display: flex;
476
+ justify-content: center;
477
+ align-items: center;
478
+ }
479
+
480
+ .center-column .plotly-graph-div {
481
+ width: auto !important;
482
+ max-width: 100%;
483
+ margin-left: auto !important;
484
+ margin-right: auto !important;
485
+ }
486
+ </style>
487
+ """
488
+
489
+
490
+ # ── Shared CSS snippets for leaderboard & category tables ───────────────
491
+
492
+ LEADERBOARD_TABLE_CSS = """
493
+ <style>
494
+ .leaderboard-container {
495
+ width: 100%;
496
+ overflow-x: auto;
497
+ margin: 20px 0;
498
+ -webkit-overflow-scrolling: touch;
499
+ }
500
+ .leaderboard-table {
501
+ width: 100%;
502
+ min-width: 1300px;
503
+ border-collapse: collapse;
504
+ background: white;
505
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
506
+ border-radius: 8px;
507
+ overflow: hidden;
508
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
509
+ }
510
+ @media (max-width: 1024px) {
511
+ .leaderboard-table {
512
+ min-width: 1000px;
513
+ font-size: 13px;
514
+ }
515
+ .leaderboard-table th,
516
+ .leaderboard-table td {
517
+ padding: 12px 10px;
518
+ }
519
+ .rank-badge {
520
+ width: 28px;
521
+ height: 28px;
522
+ line-height: 28px;
523
+ font-size: 12px;
524
+ }
525
+ }
526
+
527
+ @media (max-width: 768px) {
528
+ .leaderboard-container {
529
+ margin: 10px 0;
530
+ }
531
+ .leaderboard-table {
532
+ min-width: 900px;
533
+ font-size: 11px;
534
+ }
535
+ .leaderboard-table th {
536
+ padding: 10px 8px;
537
+ font-size: 10px;
538
+ }
539
+ .leaderboard-table td {
540
+ padding: 8px 6px;
541
+ font-size: 11px;
542
+ }
543
+ .rank-badge {
544
+ width: 24px;
545
+ height: 24px;
546
+ line-height: 24px;
547
+ font-size: 11px;
548
+ }
549
+ .provider-badge,
550
+ .model-type-badge {
551
+ padding: 3px 8px;
552
+ font-size: 10px;
553
+ }
554
+ .detection-rate {
555
+ font-size: 13px;
556
+ }
557
+ }
558
+
559
+ @media (max-width: 480px) {
560
+ .leaderboard-table {
561
+ min-width: 800px;
562
+ font-size: 10px;
563
+ }
564
+ .leaderboard-table th,
565
+ .leaderboard-table td {
566
+ padding: 6px 4px;
567
+ }
568
+ }
569
+ .leaderboard-table thead {
570
+ background: #e5e7eb;
571
+ color: #111827;
572
+ }
573
+ .leaderboard-table th {
574
+ padding: 16px 12px;
575
+ text-align: left;
576
+ font-weight: 600;
577
+ font-size: 13px;
578
+ text-transform: uppercase;
579
+ letter-spacing: 0.5px;
580
+ border-bottom: 2px solid #d1d5db;
581
+ }
582
+ .leaderboard-table th:first-child {
583
+ padding-left: 20px;
584
+ }
585
+ .leaderboard-table th:last-child {
586
+ padding-right: 20px;
587
+ }
588
+ .leaderboard-table tbody tr {
589
+ border-bottom: 1px solid #e5e7eb;
590
+ transition: all 0.2s ease;
591
+ }
592
+ .leaderboard-table tbody tr:hover {
593
+ background-color: #f8fafc;
594
+ transform: scale(1.01);
595
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
596
+ }
597
+ .leaderboard-table tbody tr:last-child {
598
+ border-bottom: none;
599
+ }
600
+ .leaderboard-table td {
601
+ padding: 14px 12px;
602
+ font-size: 14px;
603
+ color: #374151;
604
+ }
605
+ .leaderboard-table td:first-child {
606
+ padding-left: 20px;
607
+ font-weight: 600;
608
+ color: #111827;
609
+ }
610
+ .leaderboard-table td:last-child {
611
+ padding-right: 20px;
612
+ }
613
+ .rank-badge {
614
+ display: inline-block;
615
+ width: 32px;
616
+ height: 32px;
617
+ line-height: 32px;
618
+ text-align: center;
619
+ border-radius: 50%;
620
+ font-weight: 700;
621
+ font-size: 14px;
622
+ background: #f3f4f6;
623
+ color: #6b7280;
624
+ }
625
+ .metric-value {
626
+ font-weight: 600;
627
+ }
628
+ .detection-rate {
629
+ font-weight: 700;
630
+ font-size: 15px;
631
+ }
632
+ .model-name {
633
+ font-weight: 600;
634
+ color: #1f2937;
635
+ }
636
+ .model-name a:hover {
637
+ color: #4338ca !important;
638
+ border-bottom-style: solid !important;
639
+ }
640
+ .model-developer {
641
+ color: #6b7280;
642
+ font-size: 13px;
643
+ }
644
+ .provider-badge {
645
+ display: inline-block;
646
+ padding: 4px 10px;
647
+ border-radius: 12px;
648
+ font-size: 12px;
649
+ font-weight: 500;
650
+ background: #e0e7ff;
651
+ color: #4338ca;
652
+ }
653
+ .model-type-badge {
654
+ display: inline-block;
655
+ padding: 4px 10px;
656
+ border-radius: 12px;
657
+ font-size: 12px;
658
+ font-weight: 500;
659
+ }
660
+ .type-specialized {
661
+ background: #dcfce7;
662
+ color: #166534;
663
+ }
664
+ .type-generalist {
665
+ background: #dbeafe;
666
+ color: #1e40af;
667
+ }
668
+ .sort-indicator {
669
+ margin-left: 4px;
670
+ font-size: 10px;
671
+ }
672
+ </style>
673
+ """
674
+
675
+ LEADERBOARD_DARK_MODE_CSS = """
676
+ <style>
677
+ @media (prefers-color-scheme: dark) {
678
+ .leaderboard-table {
679
+ background: #2a2a2a !important;
680
+ }
681
+ .leaderboard-table thead {
682
+ background: #3a3a3a !important;
683
+ color: #f3f4f6 !important;
684
+ }
685
+ .leaderboard-table th {
686
+ border-bottom: 2px solid #4a4a4a !important;
687
+ color: #f3f4f6 !important;
688
+ }
689
+ .leaderboard-table tbody tr {
690
+ border-bottom: 1px solid #3a3a3a !important;
691
+ }
692
+ .leaderboard-table tbody tr:hover {
693
+ background-color: #333333 !important;
694
+ }
695
+ .leaderboard-table td {
696
+ color: #d1d5db !important;
697
+ }
698
+ .leaderboard-table td:first-child {
699
+ color: #f3f4f6 !important;
700
+ }
701
+ .rank-badge {
702
+ background: #3a3a3a !important;
703
+ color: #d1d5db !important;
704
+ }
705
+ .model-name {
706
+ color: #f3f4f6 !important;
707
+ }
708
+ .model-name a {
709
+ color: #f3f4f6 !important;
710
+ }
711
+ .model-name a:hover {
712
+ color: #a5b4fc !important;
713
+ }
714
+ .model-developer {
715
+ color: #9ca3af !important;
716
+ }
717
+ .provider-badge {
718
+ background: #3a3a3a !important;
719
+ color: #a5b4fc !important;
720
+ }
721
+ .type-specialized {
722
+ background: #1a3a2a !important;
723
+ color: #86efac !important;
724
+ }
725
+ .type-generalist {
726
+ background: #1e2a4a !important;
727
+ color: #93c5fd !important;
728
+ }
729
+ .footnotes-section {
730
+ background: #2a2a2a !important;
731
+ color: #d1d5db !important;
732
+ }
733
+ .footnotes-section h4 {
734
+ color: #f3f4f6 !important;
735
+ }
736
+ }
737
+ </style>
738
+ """
739
+
740
+ CATEGORY_TABLE_CSS = """
741
+ <style>
742
+ .category-table-container {
743
+ width: 100%;
744
+ overflow-x: auto;
745
+ margin: 20px 0;
746
+ -webkit-overflow-scrolling: touch;
747
+ }
748
+ .category-table {
749
+ width: 100%;
750
+ min-width: 800px;
751
+ border-collapse: collapse;
752
+ background: white;
753
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
754
+ border-radius: 8px;
755
+ overflow: hidden;
756
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
757
+ }
758
+ .category-table thead {
759
+ background: #e5e7eb;
760
+ color: #111827;
761
+ }
762
+ .category-table th {
763
+ padding: 14px 12px;
764
+ text-align: left;
765
+ font-weight: 600;
766
+ font-size: 12px;
767
+ text-transform: uppercase;
768
+ letter-spacing: 0.5px;
769
+ border-bottom: 2px solid #d1d5db;
770
+ }
771
+ .category-table th:first-child {
772
+ padding-left: 20px;
773
+ text-align: left;
774
+ }
775
+ .category-table th:not(:first-child) {
776
+ text-align: center;
777
+ }
778
+ .category-table tbody tr {
779
+ border-bottom: 1px solid #e5e7eb;
780
+ transition: background-color 0.2s ease;
781
+ }
782
+ .category-table tbody tr:hover {
783
+ background-color: #f8fafc;
784
+ }
785
+ .category-table tbody tr:last-child {
786
+ border-bottom: none;
787
+ }
788
+ .category-table td {
789
+ padding: 12px;
790
+ font-size: 13px;
791
+ color: #374151;
792
+ }
793
+ .category-table td:first-child {
794
+ padding-left: 20px;
795
+ font-weight: 600;
796
+ color: #111827;
797
+ }
798
+ .category-table td:not(:first-child) {
799
+ text-align: center;
800
+ font-weight: 500;
801
+ }
802
+
803
+ @media (max-width: 1024px) {
804
+ .category-table {
805
+ min-width: 700px;
806
+ font-size: 12px;
807
+ }
808
+ .category-table th,
809
+ .category-table td {
810
+ padding: 10px 8px;
811
+ }
812
+ }
813
+
814
+ @media (max-width: 768px) {
815
+ .category-table-container {
816
+ margin: 10px 0;
817
+ }
818
+ .category-table {
819
+ min-width: 600px;
820
+ font-size: 11px;
821
+ }
822
+ .category-table th {
823
+ padding: 8px 6px;
824
+ font-size: 10px;
825
+ }
826
+ .category-table td {
827
+ padding: 8px 6px;
828
+ font-size: 11px;
829
+ }
830
+ }
831
+
832
+ @media (max-width: 480px) {
833
+ .category-table {
834
+ min-width: 500px;
835
+ font-size: 10px;
836
+ }
837
+ .category-table th,
838
+ .category-table td {
839
+ padding: 6px 4px;
840
+ }
841
+ }
842
+
843
+ @media (prefers-color-scheme: dark) {
844
+ .category-table {
845
+ background: #2a2a2a !important;
846
+ }
847
+ .category-table thead {
848
+ background: #3a3a3a !important;
849
+ color: #f3f4f6 !important;
850
+ }
851
+ .category-table th {
852
+ border-bottom: 2px solid #4a4a4a !important;
853
+ color: #f3f4f6 !important;
854
+ }
855
+ .category-table tbody tr {
856
+ border-bottom: 1px solid #3a3a3a !important;
857
+ }
858
+ .category-table tbody tr:hover {
859
+ background-color: #333333 !important;
860
+ }
861
+ .category-table td:first-child {
862
+ color: #f3f4f6 !important;
863
+ }
864
+ .category-table td:not(:first-child) {
865
+ color: #1f2937 !important;
866
+ }
867
+ }
868
+ </style>
869
+ """