Spaces:
Sleeping
Sleeping
Clémentine
commited on
Commit
•
3777786
1
Parent(s):
77c51de
Added rate limiting system to the leaderboard to prevent abuse
Browse files- app.py +14 -2
- src/load_from_hub.py +11 -3
- src/rate_limiting.py +16 -0
app.py
CHANGED
@@ -26,6 +26,7 @@ from src.display_models.utils import (
|
|
26 |
styled_warning,
|
27 |
)
|
28 |
from src.load_from_hub import get_evaluation_queue_df, get_leaderboard_df, is_model_on_hub, load_all_info_from_hub
|
|
|
29 |
|
30 |
pd.set_option("display.precision", 1)
|
31 |
|
@@ -52,6 +53,9 @@ api = HfApi(token=H4_TOKEN)
|
|
52 |
def restart_space():
|
53 |
api.restart_space(repo_id="HuggingFaceH4/open_llm_leaderboard", token=H4_TOKEN)
|
54 |
|
|
|
|
|
|
|
55 |
|
56 |
# Column selection
|
57 |
COLS = [c.name for c in fields(AutoEvalColumn) if not c.hidden]
|
@@ -77,12 +81,12 @@ BENCHMARK_COLS = [
|
|
77 |
]
|
78 |
|
79 |
## LOAD INFO FROM HUB
|
80 |
-
eval_queue, requested_models, eval_results = load_all_info_from_hub(
|
81 |
QUEUE_REPO, RESULTS_REPO, EVAL_REQUESTS_PATH, EVAL_RESULTS_PATH
|
82 |
)
|
83 |
|
84 |
if not IS_PUBLIC:
|
85 |
-
(eval_queue_private, requested_models_private, eval_results_private,) = load_all_info_from_hub(
|
86 |
PRIVATE_QUEUE_REPO,
|
87 |
PRIVATE_RESULTS_REPO,
|
88 |
EVAL_REQUESTS_PATH_PRIVATE,
|
@@ -122,6 +126,14 @@ def add_new_eval(
|
|
122 |
precision = precision.split(" ")[0]
|
123 |
current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
if model_type is None or model_type == "":
|
126 |
return styled_error("Please select a model type.")
|
127 |
|
|
|
26 |
styled_warning,
|
27 |
)
|
28 |
from src.load_from_hub import get_evaluation_queue_df, get_leaderboard_df, is_model_on_hub, load_all_info_from_hub
|
29 |
+
from src.rate_limiting import user_submission_permission
|
30 |
|
31 |
pd.set_option("display.precision", 1)
|
32 |
|
|
|
53 |
def restart_space():
|
54 |
api.restart_space(repo_id="HuggingFaceH4/open_llm_leaderboard", token=H4_TOKEN)
|
55 |
|
56 |
+
# Rate limit variables
|
57 |
+
RATE_LIMIT_PERIOD = 7
|
58 |
+
RATE_LIMIT_QUOTA = 5
|
59 |
|
60 |
# Column selection
|
61 |
COLS = [c.name for c in fields(AutoEvalColumn) if not c.hidden]
|
|
|
81 |
]
|
82 |
|
83 |
## LOAD INFO FROM HUB
|
84 |
+
eval_queue, requested_models, eval_results, users_to_submission_dates = load_all_info_from_hub(
|
85 |
QUEUE_REPO, RESULTS_REPO, EVAL_REQUESTS_PATH, EVAL_RESULTS_PATH
|
86 |
)
|
87 |
|
88 |
if not IS_PUBLIC:
|
89 |
+
(eval_queue_private, requested_models_private, eval_results_private, _) = load_all_info_from_hub(
|
90 |
PRIVATE_QUEUE_REPO,
|
91 |
PRIVATE_RESULTS_REPO,
|
92 |
EVAL_REQUESTS_PATH_PRIVATE,
|
|
|
126 |
precision = precision.split(" ")[0]
|
127 |
current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
128 |
|
129 |
+
num_models_submitted_in_period = user_submission_permission(model, users_to_submission_dates, RATE_LIMIT_PERIOD)
|
130 |
+
if num_models_submitted_in_period > RATE_LIMIT_QUOTA:
|
131 |
+
error_msg = f"Organisation or user `{model.split('/')[0]}`"
|
132 |
+
error_msg += f"already has {num_models_submitted_in_period} model requests submitted to the leaderboard "
|
133 |
+
error_msg += f"in the last {RATE_LIMIT_PERIOD} days.\n"
|
134 |
+
error_msg += "Please wait a couple of days before resubmitting, so that everybody can enjoy using the leaderboard 🤗"
|
135 |
+
return styled_error(error_msg)
|
136 |
+
|
137 |
if model_type is None or model_type == "":
|
138 |
return styled_error("Please select a model type.")
|
139 |
|
src/load_from_hub.py
CHANGED
@@ -4,6 +4,7 @@ import os
|
|
4 |
import pandas as pd
|
5 |
from huggingface_hub import Repository
|
6 |
from transformers import AutoConfig
|
|
|
7 |
|
8 |
from src.assets.hardcoded_evals import baseline, gpt4_values, gpt35_values
|
9 |
from src.display_models.get_model_metadata import apply_metadata
|
@@ -16,6 +17,7 @@ IS_PUBLIC = bool(os.environ.get("IS_PUBLIC", True))
|
|
16 |
def get_all_requested_models(requested_models_dir: str) -> set[str]:
|
17 |
depth = 1
|
18 |
file_names = []
|
|
|
19 |
|
20 |
for root, _, files in os.walk(requested_models_dir):
|
21 |
current_depth = root.count(os.sep) - requested_models_dir.count(os.sep)
|
@@ -26,7 +28,13 @@ def get_all_requested_models(requested_models_dir: str) -> set[str]:
|
|
26 |
info = json.load(f)
|
27 |
file_names.append(f"{info['model']}_{info['revision']}_{info['precision']}")
|
28 |
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
|
32 |
def load_all_info_from_hub(QUEUE_REPO: str, RESULTS_REPO: str, QUEUE_PATH: str, RESULTS_PATH: str) -> list[Repository]:
|
@@ -50,9 +58,9 @@ def load_all_info_from_hub(QUEUE_REPO: str, RESULTS_REPO: str, QUEUE_PATH: str,
|
|
50 |
)
|
51 |
eval_results_repo.git_pull()
|
52 |
|
53 |
-
requested_models = get_all_requested_models("eval-queue")
|
54 |
|
55 |
-
return eval_queue_repo, requested_models, eval_results_repo
|
56 |
|
57 |
|
58 |
def get_leaderboard_df(
|
|
|
4 |
import pandas as pd
|
5 |
from huggingface_hub import Repository
|
6 |
from transformers import AutoConfig
|
7 |
+
from collections import defaultdict
|
8 |
|
9 |
from src.assets.hardcoded_evals import baseline, gpt4_values, gpt35_values
|
10 |
from src.display_models.get_model_metadata import apply_metadata
|
|
|
17 |
def get_all_requested_models(requested_models_dir: str) -> set[str]:
|
18 |
depth = 1
|
19 |
file_names = []
|
20 |
+
users_to_submission_dates = defaultdict(list)
|
21 |
|
22 |
for root, _, files in os.walk(requested_models_dir):
|
23 |
current_depth = root.count(os.sep) - requested_models_dir.count(os.sep)
|
|
|
28 |
info = json.load(f)
|
29 |
file_names.append(f"{info['model']}_{info['revision']}_{info['precision']}")
|
30 |
|
31 |
+
# Select organisation
|
32 |
+
if info["model"].count("/") == 0 or "submitted_time" not in info:
|
33 |
+
continue
|
34 |
+
organisation, _ = info["model"].split("/")
|
35 |
+
users_to_submission_dates[organisation].append(info["submitted_time"])
|
36 |
+
|
37 |
+
return set(file_names), users_to_submission_dates
|
38 |
|
39 |
|
40 |
def load_all_info_from_hub(QUEUE_REPO: str, RESULTS_REPO: str, QUEUE_PATH: str, RESULTS_PATH: str) -> list[Repository]:
|
|
|
58 |
)
|
59 |
eval_results_repo.git_pull()
|
60 |
|
61 |
+
requested_models, users_to_submission_dates = get_all_requested_models("eval-queue")
|
62 |
|
63 |
+
return eval_queue_repo, requested_models, eval_results_repo, users_to_submission_dates
|
64 |
|
65 |
|
66 |
def get_leaderboard_df(
|
src/rate_limiting.py
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
from datetime import datetime, timezone, timedelta
|
3 |
+
|
4 |
+
|
5 |
+
def user_submission_permission(submission_name, users_to_submission_dates, rate_limit_period):
|
6 |
+
org_or_user, _ = submission_name.split("/")
|
7 |
+
if org_or_user not in users_to_submission_dates:
|
8 |
+
return 0
|
9 |
+
submission_dates = sorted(users_to_submission_dates[org_or_user])
|
10 |
+
|
11 |
+
time_limit = (datetime.now(timezone.utc) - timedelta(days=rate_limit_period)).strftime("%Y-%m-%dT%H:%M:%SZ")
|
12 |
+
submissions_after_timelimit = [d for d in submission_dates if d > time_limit]
|
13 |
+
|
14 |
+
return len(submissions_after_timelimit)
|
15 |
+
|
16 |
+
|