|
""" |
|
Populate the GuardBench leaderboard from HuggingFace datasets. |
|
""" |
|
|
|
import json |
|
import os |
|
import pandas as pd |
|
import tempfile |
|
from typing import Dict, Tuple, List |
|
from glob import glob |
|
|
|
from huggingface_hub import snapshot_download, hf_hub_download, HfApi |
|
from datasets import load_dataset |
|
|
|
from src.display.utils import GUARDBENCH_COLUMN, DISPLAY_COLS, CATEGORIES |
|
from src.envs import RESULTS_DATASET_ID, TOKEN, LEADERBOARD_FILE, CACHE_PATH |
|
from src.leaderboard.processor import leaderboard_to_dataframe, load_leaderboard_data, save_leaderboard_data, process_jsonl_submission, add_entries_to_leaderboard |
|
|
|
|
|
def get_versioned_leaderboard_file(version="v0"): |
|
""" |
|
Get the versioned leaderboard file path. |
|
""" |
|
base_name, ext = os.path.splitext(LEADERBOARD_FILE) |
|
return f"{base_name}_{version}{ext}" |
|
|
|
|
|
def download_leaderboard_data(version="v0") -> bool: |
|
""" |
|
Download the latest leaderboard data from HuggingFace. |
|
|
|
Args: |
|
version: The dataset version to download |
|
""" |
|
try: |
|
|
|
temp_dir = os.path.join(CACHE_PATH, f"temp_submissions_{version}") |
|
os.makedirs(temp_dir, exist_ok=True) |
|
|
|
|
|
leaderboard_file = get_versioned_leaderboard_file(version) |
|
|
|
|
|
try: |
|
snapshot_path = snapshot_download( |
|
repo_id=RESULTS_DATASET_ID, |
|
repo_type="dataset", |
|
local_dir=temp_dir, |
|
token=TOKEN, |
|
ignore_patterns=["*.md", ".*"], |
|
etag_timeout=30 |
|
) |
|
|
|
|
|
all_entries = [] |
|
submission_files = [] |
|
|
|
|
|
submissions_dir = os.path.join(snapshot_path, "submissions") |
|
version_submissions_dir = os.path.join(snapshot_path, f"submissions_{version}") |
|
|
|
|
|
if os.path.exists(submissions_dir): |
|
submission_files.extend(glob(os.path.join(submissions_dir, "*.jsonl"))) |
|
|
|
if os.path.exists(version_submissions_dir): |
|
submission_files.extend(glob(os.path.join(version_submissions_dir, "*.jsonl"))) |
|
|
|
|
|
submission_files.extend(glob(os.path.join(snapshot_path, f"*_{version}.jsonl"))) |
|
|
|
|
|
if version == "v0" and not submission_files: |
|
submission_files.extend(glob(os.path.join(snapshot_path, "*.jsonl"))) |
|
|
|
|
|
for file_path in submission_files: |
|
entries, _ = process_jsonl_submission(file_path) |
|
|
|
|
|
filtered_entries = [ |
|
entry for entry in entries |
|
if entry.get("version", "v0") == version or "version" not in entry |
|
] |
|
|
|
all_entries.extend(filtered_entries) |
|
|
|
|
|
leaderboard_data = { |
|
"entries": all_entries, |
|
"last_updated": pd.Timestamp.now().isoformat(), |
|
"version": version |
|
} |
|
|
|
|
|
save_leaderboard_data(leaderboard_data, leaderboard_file) |
|
|
|
return True |
|
except Exception as e: |
|
print(f"Error downloading repository: {e}") |
|
|
|
|
|
try: |
|
api = HfApi(token=TOKEN) |
|
files = api.list_repo_files(repo_id=RESULTS_DATASET_ID, repo_type="dataset") |
|
|
|
|
|
submission_files = [ |
|
f for f in files |
|
if (f.endswith(f'_{version}.jsonl') or |
|
f.startswith(f'submissions_{version}/') or |
|
(version == "v0" and f.endswith('.jsonl'))) |
|
] |
|
|
|
all_entries = [] |
|
|
|
for file_path in submission_files: |
|
try: |
|
local_path = hf_hub_download( |
|
repo_id=RESULTS_DATASET_ID, |
|
filename=file_path, |
|
repo_type="dataset", |
|
token=TOKEN |
|
) |
|
entries, _ = process_jsonl_submission(local_path) |
|
|
|
|
|
filtered_entries = [ |
|
entry for entry in entries |
|
if entry.get("version", "v0") == version or "version" not in entry |
|
] |
|
|
|
all_entries.extend(filtered_entries) |
|
except Exception as file_error: |
|
print(f"Error downloading file {file_path}: {file_error}") |
|
|
|
|
|
leaderboard_data = { |
|
"entries": all_entries, |
|
"last_updated": pd.Timestamp.now().isoformat(), |
|
"version": version |
|
} |
|
|
|
|
|
save_leaderboard_data(leaderboard_data, leaderboard_file) |
|
|
|
return True |
|
except Exception as list_error: |
|
print(f"Error listing repository files: {list_error}") |
|
|
|
|
|
if not os.path.exists(leaderboard_file): |
|
empty_data = { |
|
"entries": [], |
|
"last_updated": pd.Timestamp.now().isoformat(), |
|
"version": version |
|
} |
|
save_leaderboard_data(empty_data, leaderboard_file) |
|
|
|
return False |
|
except Exception as e: |
|
print(f"Error downloading leaderboard data: {e}") |
|
|
|
|
|
leaderboard_file = get_versioned_leaderboard_file(version) |
|
if not os.path.exists(leaderboard_file): |
|
empty_data = { |
|
"entries": [], |
|
"last_updated": pd.Timestamp.now().isoformat(), |
|
"version": version |
|
} |
|
save_leaderboard_data(empty_data, leaderboard_file) |
|
|
|
return False |
|
|
|
|
|
def get_leaderboard_df(version="v0") -> pd.DataFrame: |
|
""" |
|
Get the leaderboard data as a DataFrame. |
|
|
|
Args: |
|
version: The dataset version to retrieve |
|
""" |
|
|
|
download_leaderboard_data(version=version) |
|
|
|
|
|
leaderboard_file = get_versioned_leaderboard_file(version) |
|
leaderboard_data = load_leaderboard_data(leaderboard_file) |
|
|
|
|
|
df = leaderboard_to_dataframe(leaderboard_data) |
|
|
|
return df |
|
|
|
|
|
def get_category_leaderboard_df(category: str, version="v0") -> pd.DataFrame: |
|
""" |
|
Get the leaderboard data filtered by a specific category. |
|
|
|
Args: |
|
category: The category to filter by (e.g., "Criminal, Violent, and Terrorist Activity") |
|
version: The dataset version to retrieve |
|
|
|
Returns: |
|
DataFrame with metrics for the specified category |
|
""" |
|
|
|
leaderboard_file = get_versioned_leaderboard_file(version) |
|
leaderboard_data = load_leaderboard_data(leaderboard_file) |
|
|
|
|
|
filtered_entries = [] |
|
|
|
for entry in leaderboard_data.get("entries", []): |
|
|
|
if "per_category_metrics" in entry and category in entry["per_category_metrics"]: |
|
|
|
filtered_entry = { |
|
"model_name": entry.get("model_name", "Unknown Model"), |
|
"model_type": entry.get("model_type", "Unknown"), |
|
"submission_date": entry.get("submission_date", ""), |
|
"version": entry.get("version", version), |
|
} |
|
|
|
|
|
category_metrics = entry["per_category_metrics"][category] |
|
|
|
|
|
for test_type in category_metrics: |
|
if test_type and isinstance(category_metrics[test_type], dict): |
|
for metric, value in category_metrics[test_type].items(): |
|
col_name = f"{test_type}_{metric}" |
|
filtered_entry[col_name] = value |
|
|
|
|
|
f1_values = [] |
|
for test_type in category_metrics: |
|
if test_type and isinstance(category_metrics[test_type], dict) and "f1_binary" in category_metrics[test_type]: |
|
f1_values.append(category_metrics[test_type]["f1_binary"]) |
|
|
|
if f1_values: |
|
filtered_entry["average_f1"] = sum(f1_values) / len(f1_values) |
|
|
|
|
|
for test_type in ["default_prompts", "jailbreaked_prompts", "default_answers", "jailbreaked_answers"]: |
|
if test_type in category_metrics and "f1_binary" in category_metrics[test_type]: |
|
filtered_entry[f"{test_type}_f1"] = category_metrics[test_type]["f1_binary"] |
|
|
|
filtered_entries.append(filtered_entry) |
|
|
|
|
|
filtered_leaderboard = { |
|
"entries": filtered_entries, |
|
"last_updated": leaderboard_data.get("last_updated", pd.Timestamp.now().isoformat()), |
|
"version": version |
|
} |
|
|
|
|
|
df = leaderboard_to_dataframe(filtered_leaderboard) |
|
|
|
return df |
|
|
|
|
|
def get_detailed_model_data(model_name: str, version="v0") -> Dict: |
|
""" |
|
Get detailed data for a specific model. |
|
|
|
Args: |
|
model_name: The name of the model to get data for |
|
version: The dataset version to retrieve |
|
""" |
|
leaderboard_file = get_versioned_leaderboard_file(version) |
|
leaderboard_data = load_leaderboard_data(leaderboard_file) |
|
|
|
for entry in leaderboard_data.get("entries", []): |
|
|
|
entry_version = entry.get("version", "v0") |
|
if entry.get("model_name") == model_name and (entry_version == version or entry_version is None): |
|
return entry |
|
|
|
return {} |
|
|