brunneis commited on
Commit
6bf4f4e
1 Parent(s): f8e2509

Refactor leaderboard

Browse files

- Update artifact handling and display logic
- Modify model submission process and evaluation requests
- Refactor data structures and file paths for Solidity-specific use case
- Remove unnecessary fields and simplify UI components
- Update environment variables and repository structure

.gitignore CHANGED
@@ -1,3 +1,4 @@
 
1
  ignore/
2
  auto_evals/
3
  venv/
@@ -6,9 +7,4 @@ __pycache__/
6
  .ipynb_checkpoints
7
  *ipynb
8
  .vscode/
9
-
10
- eval-queue/
11
- eval-results/
12
- eval-queue-bk/
13
- eval-results-bk/
14
  logs/
 
1
+ solbench/
2
  ignore/
3
  auto_evals/
4
  venv/
 
7
  .ipynb_checkpoints
8
  *ipynb
9
  .vscode/
 
 
 
 
 
10
  logs/
README.md CHANGED
@@ -40,10 +40,6 @@ Results files should have the following format and be stored as json files:
40
  }
41
  ```
42
 
43
- Request files are created automatically by this tool.
44
-
45
- If you encounter problem on the space, don't hesitate to restart it to remove the create eval-queue, eval-queue-bk, eval-results and eval-results-bk created folder.
46
-
47
  # Code logic for more complex edits
48
 
49
  You'll find
 
40
  }
41
  ```
42
 
 
 
 
 
43
  # Code logic for more complex edits
44
 
45
  You'll find
app.py CHANGED
@@ -2,6 +2,8 @@
2
  # -*- coding: utf-8 -*-
3
  # flake8: noqa E501
4
 
 
 
5
  import gradio as gr
6
  from apscheduler.schedulers.background import BackgroundScheduler
7
  from gradio_leaderboard import ColumnFilter, Leaderboard, SelectColumns
@@ -10,7 +12,7 @@ from huggingface_hub import snapshot_download
10
  from src.about import (
11
  CITATION_BUTTON_LABEL,
12
  CITATION_BUTTON_TEXT,
13
- EVALUATION_QUEUE_TEXT,
14
  EVALUATION_SCRIPT,
15
  INTRODUCTION_TEXT,
16
  LLM_BENCHMARKS_TEXT,
@@ -28,8 +30,17 @@ from src.display.utils import (
28
  WeightType,
29
  fields,
30
  )
31
- from src.envs import API, EVAL_REQUESTS_PATH, EVAL_RESULTS_PATH, QUEUE_REPO, REPO_ID, RESULTS_REPO, TOKEN
32
- from src.populate import get_evaluation_queue_df, get_leaderboard_df
 
 
 
 
 
 
 
 
 
33
  from src.submission.submit import add_new_eval
34
 
35
 
@@ -37,9 +48,10 @@ def restart_space():
37
  API.restart_space(repo_id=REPO_ID)
38
 
39
  # Space initialisation
 
40
  try:
41
  snapshot_download(
42
- repo_id=QUEUE_REPO,
43
  local_dir=EVAL_REQUESTS_PATH,
44
  repo_type="dataset",
45
  tqdm_class=None,
@@ -48,6 +60,7 @@ try:
48
  )
49
  except Exception:
50
  restart_space()
 
51
  try:
52
  snapshot_download(
53
  repo_id=RESULTS_REPO,
@@ -60,7 +73,6 @@ try:
60
  except Exception:
61
  restart_space()
62
 
63
-
64
  LEADERBOARD_DF = get_leaderboard_df(
65
  EVAL_RESULTS_PATH,
66
  EVAL_REQUESTS_PATH,
@@ -69,10 +81,10 @@ LEADERBOARD_DF = get_leaderboard_df(
69
  )
70
 
71
  (
72
- finished_eval_queue_df,
73
- running_eval_queue_df,
74
- pending_eval_queue_df,
75
- ) = get_evaluation_queue_df(EVAL_REQUESTS_PATH, EVAL_COLS)
76
 
77
  def init_leaderboard(dataframe):
78
  if dataframe is None or dataframe.empty:
@@ -124,85 +136,72 @@ with demo:
124
  with gr.TabItem("🧪 Submissions", elem_id="llm-benchmark-tab-table", id=3):
125
  with gr.Column():
126
  with gr.Row():
127
- gr.Markdown(EVALUATION_QUEUE_TEXT, elem_classes="markdown-text")
128
 
129
  with gr.Column():
130
  with gr.Accordion(
131
- f"✅ Finished Evaluations ({len(finished_eval_queue_df)})",
132
  open=False,
133
  ):
134
  with gr.Row():
135
  finished_eval_table = gr.components.Dataframe(
136
- value=finished_eval_queue_df,
137
- headers=EVAL_COLS,
138
- datatype=EVAL_TYPES,
139
- row_count=5,
140
- )
141
- with gr.Accordion(
142
- f"🔄 Running Evaluation Queue ({len(running_eval_queue_df)})",
143
- open=False,
144
- ):
145
- with gr.Row():
146
- running_eval_table = gr.components.Dataframe(
147
- value=running_eval_queue_df,
148
  headers=EVAL_COLS,
149
  datatype=EVAL_TYPES,
150
  row_count=5,
151
  )
152
 
153
  with gr.Accordion(
154
- f"⏳ Pending Evaluation Queue ({len(pending_eval_queue_df)})",
155
  open=False,
156
  ):
157
  with gr.Row():
158
  pending_eval_table = gr.components.Dataframe(
159
- value=pending_eval_queue_df,
160
  headers=EVAL_COLS,
161
  datatype=EVAL_TYPES,
162
  row_count=5,
163
  )
164
  with gr.Row():
165
- gr.Markdown("# ✉️✨ Submit your model here!", elem_classes="markdown-text")
166
 
167
  with gr.Row():
168
  with gr.Column():
169
  model_name_textbox = gr.Textbox(label="Model name")
170
  revision_name_textbox = gr.Textbox(label="Revision commit", placeholder="main")
171
  model_type = gr.Dropdown(
172
- choices=[t.to_str(" : ") for t in ModelType if t != ModelType.Unknown],
173
  label="Model type",
174
  multiselect=False,
175
  value=None,
176
  interactive=True,
177
  )
178
-
179
- with gr.Column():
180
- precision = gr.Dropdown(
181
- choices=[i.value.name for i in Precision if i != Precision.Unknown],
182
- label="Precision",
183
- multiselect=False,
184
- value="float16",
185
- interactive=True,
186
- )
187
- weight_type = gr.Dropdown(
188
- choices=[i.value.name for i in WeightType],
189
- label="Weights type",
190
- multiselect=False,
191
- value="Original",
192
- interactive=True,
193
- )
194
- base_model_name_textbox = gr.Textbox(label="Base model (for delta or adapter weights)")
195
-
196
- submit_button = gr.Button("Submit Eval")
197
  submission_result = gr.Markdown()
198
  submit_button.click(
199
  add_new_eval,
200
  [
201
  model_name_textbox,
202
- base_model_name_textbox,
203
  revision_name_textbox,
204
- precision,
205
- weight_type,
206
  model_type,
207
  ],
208
  submission_result,
 
2
  # -*- coding: utf-8 -*-
3
  # flake8: noqa E501
4
 
5
+ import shutil
6
+
7
  import gradio as gr
8
  from apscheduler.schedulers.background import BackgroundScheduler
9
  from gradio_leaderboard import ColumnFilter, Leaderboard, SelectColumns
 
12
  from src.about import (
13
  CITATION_BUTTON_LABEL,
14
  CITATION_BUTTON_TEXT,
15
+ EVALUATION_REQUESTS_TEXT,
16
  EVALUATION_SCRIPT,
17
  INTRODUCTION_TEXT,
18
  LLM_BENCHMARKS_TEXT,
 
30
  WeightType,
31
  fields,
32
  )
33
+ from src.envs import (
34
+ API,
35
+ CACHE_PATH,
36
+ EVAL_REQUESTS_PATH,
37
+ EVAL_RESULTS_PATH,
38
+ REPO_ID,
39
+ REQUESTS_REPO,
40
+ RESULTS_REPO,
41
+ TOKEN,
42
+ )
43
+ from src.populate import get_evaluation_requests_df, get_leaderboard_df
44
  from src.submission.submit import add_new_eval
45
 
46
 
 
48
  API.restart_space(repo_id=REPO_ID)
49
 
50
  # Space initialisation
51
+ shutil.rmtree(CACHE_PATH, ignore_errors=True)
52
  try:
53
  snapshot_download(
54
+ repo_id=REQUESTS_REPO,
55
  local_dir=EVAL_REQUESTS_PATH,
56
  repo_type="dataset",
57
  tqdm_class=None,
 
60
  )
61
  except Exception:
62
  restart_space()
63
+
64
  try:
65
  snapshot_download(
66
  repo_id=RESULTS_REPO,
 
73
  except Exception:
74
  restart_space()
75
 
 
76
  LEADERBOARD_DF = get_leaderboard_df(
77
  EVAL_RESULTS_PATH,
78
  EVAL_REQUESTS_PATH,
 
81
  )
82
 
83
  (
84
+ finished_eval_requests_df,
85
+ running_eval_requests_df,
86
+ pending_eval_requests_df,
87
+ ) = get_evaluation_requests_df(EVAL_REQUESTS_PATH, EVAL_COLS)
88
 
89
  def init_leaderboard(dataframe):
90
  if dataframe is None or dataframe.empty:
 
136
  with gr.TabItem("🧪 Submissions", elem_id="llm-benchmark-tab-table", id=3):
137
  with gr.Column():
138
  with gr.Row():
139
+ gr.Markdown(EVALUATION_REQUESTS_TEXT, elem_classes="markdown-text")
140
 
141
  with gr.Column():
142
  with gr.Accordion(
143
+ f"✅ Finished ({len(finished_eval_requests_df)})",
144
  open=False,
145
  ):
146
  with gr.Row():
147
  finished_eval_table = gr.components.Dataframe(
148
+ value=finished_eval_requests_df,
 
 
 
 
 
 
 
 
 
 
 
149
  headers=EVAL_COLS,
150
  datatype=EVAL_TYPES,
151
  row_count=5,
152
  )
153
 
154
  with gr.Accordion(
155
+ f"⏳ Pending ({len(pending_eval_requests_df)})",
156
  open=False,
157
  ):
158
  with gr.Row():
159
  pending_eval_table = gr.components.Dataframe(
160
+ value=pending_eval_requests_df,
161
  headers=EVAL_COLS,
162
  datatype=EVAL_TYPES,
163
  row_count=5,
164
  )
165
  with gr.Row():
166
+ gr.Markdown("# ✉️ Submit a model", elem_classes="markdown-text")
167
 
168
  with gr.Row():
169
  with gr.Column():
170
  model_name_textbox = gr.Textbox(label="Model name")
171
  revision_name_textbox = gr.Textbox(label="Revision commit", placeholder="main")
172
  model_type = gr.Dropdown(
173
+ choices=[t.to_str(" ") for t in ModelType if t != ModelType.Unknown],
174
  label="Model type",
175
  multiselect=False,
176
  value=None,
177
  interactive=True,
178
  )
179
+ # precision = gr.Dropdown(
180
+ # choices=[i.value.name for i in Precision if i != Precision.Unknown],
181
+ # label="Precision",
182
+ # multiselect=False,
183
+ # value="float16",
184
+ # interactive=True,
185
+ # )
186
+ # weight_type = gr.Dropdown(
187
+ # choices=[i.value.name for i in WeightType],
188
+ # label="Weights type",
189
+ # multiselect=False,
190
+ # value="Original",
191
+ # interactive=True,
192
+ # )
193
+ # base_model_name_textbox = gr.Textbox(label="Base model (for delta or adapter weights)")
194
+
195
+ submit_button = gr.Button("Submit")
 
 
196
  submission_result = gr.Markdown()
197
  submit_button.click(
198
  add_new_eval,
199
  [
200
  model_name_textbox,
201
+ # base_model_name_textbox,
202
  revision_name_textbox,
203
+ # precision,
204
+ # weight_type,
205
  model_type,
206
  ],
207
  submission_result,
src/about.py CHANGED
@@ -16,19 +16,18 @@ class Task:
16
  # Select your tasks here
17
  # ---------------------------------------------------
18
  class Tasks(Enum):
19
- # task_key in the json file, metric_key in the json file, name to display in the leaderboard
20
- task0 = Task("hf", "score", "LLM JUDGE")
21
- task1 = Task("rouge1", "score", "ROUGE-unigrams")
22
- task2 = Task("rouge2", "score", "ROUGE-bigrams")
23
- task3 = Task("rougeL", "score", "ROUGE-Longest Common Subsequence")
24
- task4 = Task("rougeLsum", "score", "ROUGE-Lsum")
25
- task5 = Task("bleu", "score", "Bleu")
26
- task6 = Task("brevity_penalty", "score", "Brevity Penalty")
27
- task7 = Task("hf", "score", "LLM JUDGE")
28
- # task = Task("precisions", "score", "Precision")
29
-
30
-
31
- NUM_FEWSHOT = 0 # Change with your few shot
32
  # ---------------------------------------------------
33
 
34
  # Your leaderboard name
@@ -47,7 +46,7 @@ To reproduce our results, here is the commands you can run:
47
 
48
  """
49
 
50
- EVALUATION_QUEUE_TEXT = """
51
  ## Some good practices before submitting a model
52
 
53
  ### 1) Make sure you can load your model and tokenizer using AutoClasses:
@@ -59,22 +58,10 @@ tokenizer = AutoTokenizer.from_pretrained("your model name", revision=revision)
59
  ```
60
  If this step fails, follow the error messages to debug your model before submitting it. It's likely your model has been improperly uploaded.
61
 
62
- Note: make sure your model is public!
63
- Note: if your model needs `use_remote_code=True`, we do not support this option yet but we are working on adding it, stay posted!
64
-
65
- ### 2) Convert your model weights to [safetensors](https://huggingface.co/docs/safetensors/index)
66
- It's a new format for storing weights which is safer and faster to load and use. It will also allow us to add the number of parameters of your model to the `Extended Viewer`!
67
 
68
- ### 3) Make sure your model has an open license!
69
- This is a leaderboard for Open LLMs, and we'd love for as many people as possible to know they can use your model 🤗
70
-
71
- ### 4) Fill up your model card
72
  When we add extra information about models to the leaderboard, it will be automatically taken from the model card
73
-
74
- ## In case of model failure
75
- If your model is displayed in the `FAILED` category, its execution stopped.
76
- Make sure you have followed the above steps first.
77
- If everything is done, check you can launch the EleutherAIHarness on your model locally, using the above command without modifications (you can add `--limit` to limit the number of examples per task).
78
  """
79
  EVALUATION_SCRIPT = ''
80
  CITATION_BUTTON_LABEL = "Copy the following snippet to cite these results"
 
16
  # Select your tasks here
17
  # ---------------------------------------------------
18
  class Tasks(Enum):
19
+ # task_key, metric_key, title
20
+ task00 = Task("human_eval_solidity", "score", "HumanEval for Solidity")
21
+ # task01 = Task("naive_judge", "score", "NaïveJudge Average")
22
+ # task02 = Task("naive_judge_expert", "score", "NaïveJudge Expert")
23
+ # task03 = Task("naive_judge_average", "score", "NaïveJudge Average")
24
+ # task04 = Task("naive_judge_beginner", "score", "NaïveJudge Beginner")
25
+ task05 = Task("rouge1", "score", "ROUGE-unigrams")
26
+ task06 = Task("rouge2", "score", "ROUGE-bigrams")
27
+ task07 = Task("rougeL", "score", "ROUGE-Longest Common Subsequence")
28
+ task08 = Task("rougeLsum", "score", "ROUGE-Lsum")
29
+ task09 = Task("bleu", "score", "Bleu")
30
+ task10 = Task("brevity_penalty", "score", "Brevity Penalty")
 
31
  # ---------------------------------------------------
32
 
33
  # Your leaderboard name
 
46
 
47
  """
48
 
49
+ EVALUATION_REQUESTS_TEXT = """
50
  ## Some good practices before submitting a model
51
 
52
  ### 1) Make sure you can load your model and tokenizer using AutoClasses:
 
58
  ```
59
  If this step fails, follow the error messages to debug your model before submitting it. It's likely your model has been improperly uploaded.
60
 
61
+ Note: make sure your model is public.
 
 
 
 
62
 
63
+ ### 2) Fill up your model card
 
 
 
64
  When we add extra information about models to the leaderboard, it will be automatically taken from the model card
 
 
 
 
 
65
  """
66
  EVALUATION_SCRIPT = ''
67
  CITATION_BUTTON_LABEL = "Copy the following snippet to cite these results"
src/display/utils.py CHANGED
@@ -47,10 +47,10 @@ model_info_columns = [
47
  ("weight_type", "Weight type", "str", False, True),
48
  ("precision", "Precision", "str", False),
49
  ("license", "License", "str", False),
50
- ("params", "Parameters ⚙️", "number", False),
51
- ("likes", "Likes ❤️", "number", False),
52
- ("still_on_hub", "Available on the hub", "bool", False),
53
- ("revision", "Model sha", "str", False, False),
54
  ]
55
 
56
  for col_name, display_name, col_type, displayed_by_default, *args in model_info_columns:
@@ -60,15 +60,15 @@ for col_name, display_name, col_type, displayed_by_default, *args in model_info_
60
  # Create the AutoEvalColumn dataclass
61
  AutoEvalColumn = make_dataclass("AutoEvalColumn", auto_eval_column_dict, frozen=True)()
62
 
63
- # For the queue columns in the submission tab
64
  @dataclass(frozen=True)
65
  class EvalQueueColumn: # Queue column
66
  model = ColumnContent("model", "markdown", True)
67
  revision = ColumnContent("revision", "str", True)
68
- private = ColumnContent("private", "bool", True)
69
- precision = ColumnContent("precision", "str", True)
70
- weight_type = ColumnContent("weight_type", "str", "Original")
71
- status = ColumnContent("status", "str", True)
72
 
73
 
74
  # All the model information that we might need
@@ -80,26 +80,21 @@ class ModelDetails:
80
 
81
 
82
  class ModelType(Enum):
83
- PT = ModelDetails(name="pretrained", symbol="🟢")
84
- FT = ModelDetails(name="fine-tuned", symbol="🔶")
85
- IFT = ModelDetails(name="instruction-tuned", symbol="⭕")
86
- RL = ModelDetails(name="RL-tuned", symbol="🟦")
87
- CS = ModelDetails(name="closed-source", symbol="🔒")
88
  BrainDAO = ModelDetails(name="braindao", symbol="🧠")
89
  Unknown = ModelDetails(name="", symbol="❓")
90
 
91
- def to_str(self, separator=" "):
92
  return f"{self.value.symbol}{separator}{self.value.name}"
93
 
94
  @staticmethod
95
  def from_str(type):
96
- if "fine-tuned" in type or "🔶" in type:
97
  return ModelType.FT
98
- if "pretrained" in type or "🟢" in type:
99
  return ModelType.PT
100
- if "RL-tuned" in type or "🟦" in type:
101
- return ModelType.RL
102
- if "instruction-tuned" in type or "⭕" in type:
103
  return ModelType.IFT
104
  return ModelType.Unknown
105
 
@@ -113,13 +108,19 @@ class WeightType(Enum):
113
  class Precision(Enum):
114
  float16 = ModelDetails("float16")
115
  bfloat16 = ModelDetails("bfloat16")
116
- Unknown = ModelDetails("?")
 
 
117
 
118
  def from_str(precision):
119
  if precision in ["torch.float16", "float16"]:
120
  return Precision.float16
121
  if precision in ["torch.bfloat16", "bfloat16"]:
122
  return Precision.bfloat16
 
 
 
 
123
  return Precision.Unknown
124
 
125
 
 
47
  ("weight_type", "Weight type", "str", False, True),
48
  ("precision", "Precision", "str", False),
49
  ("license", "License", "str", False),
50
+ ("params", "Parameters", "number", False),
51
+ ("likes", "Likes", "number", False),
52
+ ("still_on_hub", "Available on HuggingFace", "bool", False),
53
+ ("revision", "Revision", "str", False, False),
54
  ]
55
 
56
  for col_name, display_name, col_type, displayed_by_default, *args in model_info_columns:
 
60
  # Create the AutoEvalColumn dataclass
61
  AutoEvalColumn = make_dataclass("AutoEvalColumn", auto_eval_column_dict, frozen=True)()
62
 
63
+ # For the requests columns in the submission tab
64
  @dataclass(frozen=True)
65
  class EvalQueueColumn: # Queue column
66
  model = ColumnContent("model", "markdown", True)
67
  revision = ColumnContent("revision", "str", True)
68
+ # private = ColumnContent("private", "bool", True)
69
+ # precision = ColumnContent("precision", "str", True)
70
+ # weight_type = ColumnContent("weight_type", "str", "Original")
71
+ # status = ColumnContent("status", "str", True)
72
 
73
 
74
  # All the model information that we might need
 
80
 
81
 
82
  class ModelType(Enum):
83
+ PT = ModelDetails(name="pretrained", symbol="💎")
84
+ FT = ModelDetails(name="finetuned", symbol="💍")
 
 
 
85
  BrainDAO = ModelDetails(name="braindao", symbol="🧠")
86
  Unknown = ModelDetails(name="", symbol="❓")
87
 
88
+ def to_str(self, separator=" "):
89
  return f"{self.value.symbol}{separator}{self.value.name}"
90
 
91
  @staticmethod
92
  def from_str(type):
93
+ if "finetuned" in type or "💍" in type:
94
  return ModelType.FT
95
+ if "pretrained" in type or "💎" in type:
96
  return ModelType.PT
97
+ if "braindao" in type or "🧠" in type:
 
 
98
  return ModelType.IFT
99
  return ModelType.Unknown
100
 
 
108
  class Precision(Enum):
109
  float16 = ModelDetails("float16")
110
  bfloat16 = ModelDetails("bfloat16")
111
+ float32 = ModelDetails("float32")
112
+ bfloat32 = ModelDetails("bfloat32")
113
+ Unknown = ModelDetails("Unknown")
114
 
115
  def from_str(precision):
116
  if precision in ["torch.float16", "float16"]:
117
  return Precision.float16
118
  if precision in ["torch.bfloat16", "bfloat16"]:
119
  return Precision.bfloat16
120
+ if precision in ["torch.float32", "float32"]:
121
+ return Precision.float32
122
+ if precision in ["torch.bfloat32", "bfloat32"]:
123
+ return Precision.bfloat32
124
  return Precision.Unknown
125
 
126
 
src/envs.py CHANGED
@@ -8,22 +8,20 @@ from huggingface_hub import HfApi
8
 
9
  # Info to change for your repository
10
  # ----------------------------------
11
- TOKEN = os.environ.get("HF_TOKEN") # A read/write token for your org
12
 
13
- OWNER = "braindao" # Change to your org - don't forget to create a results and request dataset, with the correct format!
14
  # ----------------------------------
15
 
16
  REPO_ID = f"{OWNER}/solidity-leaderboard"
17
- QUEUE_REPO = f"{OWNER}/solbench-leaderboard-queue"
18
  RESULTS_REPO = f"{OWNER}/solbench-leaderboard-results"
19
 
20
  # If you setup a cache later, just change HF_HOME
21
- CACHE_PATH = os.getenv("HF_HOME", ".")
22
 
23
  # Local caches
24
- EVAL_REQUESTS_PATH = os.path.join(CACHE_PATH, "eval-queue")
25
- EVAL_RESULTS_PATH = os.path.join(CACHE_PATH, "eval-results")
26
- EVAL_REQUESTS_PATH_BACKEND = os.path.join(CACHE_PATH, "eval-queue-bk")
27
- EVAL_RESULTS_PATH_BACKEND = os.path.join(CACHE_PATH, "eval-results-bk")
28
 
29
  API = HfApi(token=TOKEN)
 
8
 
9
  # Info to change for your repository
10
  # ----------------------------------
11
+ TOKEN = os.environ.get("HF_TOKEN")
12
 
13
+ OWNER = "braindao"
14
  # ----------------------------------
15
 
16
  REPO_ID = f"{OWNER}/solidity-leaderboard"
17
+ REQUESTS_REPO = f"{OWNER}/solbench-leaderboard-requests"
18
  RESULTS_REPO = f"{OWNER}/solbench-leaderboard-results"
19
 
20
  # If you setup a cache later, just change HF_HOME
21
+ CACHE_PATH = os.path.join(os.getenv("HF_HOME", "."), "solbench")
22
 
23
  # Local caches
24
+ EVAL_REQUESTS_PATH = os.path.join(CACHE_PATH, "requests")
25
+ EVAL_RESULTS_PATH = os.path.join(CACHE_PATH, "results")
 
 
26
 
27
  API = HfApi(token=TOKEN)
src/leaderboard/read_evals.py CHANGED
@@ -13,6 +13,7 @@ import numpy as np
13
  from src.display.formatting import make_clickable_model
14
  from src.display.utils import AutoEvalColumn, ModelType, Precision, Tasks, WeightType
15
  from src.submission.check_validity import is_model_on_hub
 
16
 
17
 
18
  @dataclass
@@ -20,7 +21,7 @@ class EvalResult:
20
  """Represents one full evaluation. Built from a combination of the result and request file for a given run.
21
  """
22
  eval_name: str # org_model_precision (uid)
23
- full_model: str # org/model (path on hub)
24
  org: str
25
  model: str
26
  revision: str # commit hash, "" if main
@@ -29,7 +30,7 @@ class EvalResult:
29
  model_type: ModelType = ModelType.Unknown # Pretrained, fine tuned, ...
30
  weight_type: WeightType = WeightType.Original # Original or Adapter
31
  architecture: str = "Unknown"
32
- license: str = "?"
33
  likes: int = 0
34
  num_params: int = 0
35
  date: str = "" # submission date of request file
@@ -41,32 +42,22 @@ class EvalResult:
41
  with open(json_filepath) as fp:
42
  data = json.load(fp)
43
 
 
44
  config = data.get("config")
45
 
46
  # Precision
47
  precision = Precision.from_str(config.get("model_dtype"))
48
 
49
- # Get model and org
50
- org_and_model = config.get("model_name", config.get("model_args", None))
51
- org_and_model = org_and_model.split("/", 1)
52
-
53
- if len(org_and_model) == 1:
54
- org = None
55
- model = org_and_model[0]
56
- result_key = f"{model}_{precision.value.name}"
57
- else:
58
- org = org_and_model[0]
59
- model = org_and_model[1]
60
- result_key = f"{org}_{model}_{precision.value.name}"
61
- full_model = "/".join(org_and_model)
62
 
63
  still_on_hub, _, model_config = is_model_on_hub(
64
- full_model,
65
  config.get("model_sha", "main"),
66
  trust_remote_code=True,
67
  test_tokenizer=False,
68
  )
69
- architecture = "?"
70
  if model_config is not None:
71
  architectures = getattr(model_config, "architectures", None)
72
  if architectures:
@@ -89,7 +80,7 @@ class EvalResult:
89
 
90
  return cls(
91
  eval_name=result_key,
92
- full_model=full_model,
93
  org=org,
94
  model=model,
95
  results=results,
@@ -101,14 +92,19 @@ class EvalResult:
101
 
102
  def update_with_request_file(self, requests_path):
103
  """Finds the relevant request file for the current model and updates info with it"""
104
- request_file = get_request_file_for_model(requests_path, self.full_model, self.precision.value.name)
105
-
 
 
 
 
 
106
  try:
107
  with open(request_file, "r") as f:
108
  request = json.load(f)
109
  self.model_type = ModelType.from_str(request.get("model_type", ""))
110
  self.weight_type = WeightType[request.get("weight_type", "Original")]
111
- self.license = request.get("license", "?")
112
  self.likes = request.get("likes", 0)
113
  self.num_params = request.get("params", 0)
114
  self.date = request.get("submitted_time", "")
@@ -125,7 +121,7 @@ class EvalResult:
125
  AutoEvalColumn.model_type_symbol.name: self.model_type.value.symbol,
126
  AutoEvalColumn.weight_type.name: self.weight_type.value.name,
127
  AutoEvalColumn.architecture.name: self.architecture,
128
- AutoEvalColumn.model.name: make_clickable_model(self.full_model),
129
  AutoEvalColumn.revision.name: self.revision,
130
  AutoEvalColumn.average.name: average,
131
  AutoEvalColumn.license.name: self.license,
@@ -140,26 +136,17 @@ class EvalResult:
140
  return data_dict
141
 
142
 
143
- def get_request_file_for_model(requests_path, model_name, precision):
144
- """Selects the correct request file for a given model. Only keeps runs tagged as FINISHED"""
145
- request_files = os.path.join(
146
- requests_path,
147
- f"{model_name}_eval_request_*.json",
148
- )
149
- request_files = glob.glob(request_files)
150
-
151
- # Select correct request file (precision)
152
- request_file = ""
153
- request_files = sorted(request_files, reverse=True)
154
- for tmp_request_file in request_files:
155
- with open(tmp_request_file, "r") as f:
156
- req_content = json.load(f)
157
- if (
158
- req_content["status"] in ["FINISHED"]
159
- and req_content["precision"] == precision.split(".")[-1]
160
- ):
161
- request_file = tmp_request_file
162
- return request_file
163
 
164
 
165
  def get_raw_eval_results(results_path: str, requests_path: str) -> list[EvalResult]:
 
13
  from src.display.formatting import make_clickable_model
14
  from src.display.utils import AutoEvalColumn, ModelType, Precision, Tasks, WeightType
15
  from src.submission.check_validity import is_model_on_hub
16
+ from src.utils import get_model_name, get_org_and_model_names, get_request_hash
17
 
18
 
19
  @dataclass
 
21
  """Represents one full evaluation. Built from a combination of the result and request file for a given run.
22
  """
23
  eval_name: str # org_model_precision (uid)
24
+ model_name: str # org/model (path on hub)
25
  org: str
26
  model: str
27
  revision: str # commit hash, "" if main
 
30
  model_type: ModelType = ModelType.Unknown # Pretrained, fine tuned, ...
31
  weight_type: WeightType = WeightType.Original # Original or Adapter
32
  architecture: str = "Unknown"
33
+ license: str = "Unknown"
34
  likes: int = 0
35
  num_params: int = 0
36
  date: str = "" # submission date of request file
 
42
  with open(json_filepath) as fp:
43
  data = json.load(fp)
44
 
45
+ org, model = get_org_and_model_names(json_filepath)
46
  config = data.get("config")
47
 
48
  # Precision
49
  precision = Precision.from_str(config.get("model_dtype"))
50
 
51
+ result_key = f"{org}_{model}_{precision.value.name}"
52
+ model_name = get_model_name(json_filepath)
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  still_on_hub, _, model_config = is_model_on_hub(
55
+ model_name,
56
  config.get("model_sha", "main"),
57
  trust_remote_code=True,
58
  test_tokenizer=False,
59
  )
60
+ architecture = "Unknown"
61
  if model_config is not None:
62
  architectures = getattr(model_config, "architectures", None)
63
  if architectures:
 
80
 
81
  return cls(
82
  eval_name=result_key,
83
+ model_name=model_name,
84
  org=org,
85
  model=model,
86
  results=results,
 
92
 
93
  def update_with_request_file(self, requests_path):
94
  """Finds the relevant request file for the current model and updates info with it"""
95
+ request_file = get_request_file_for_model(
96
+ requests_path,
97
+ self.model_name,
98
+ self.revision,
99
+ self.precision.value.name,
100
+ )
101
+
102
  try:
103
  with open(request_file, "r") as f:
104
  request = json.load(f)
105
  self.model_type = ModelType.from_str(request.get("model_type", ""))
106
  self.weight_type = WeightType[request.get("weight_type", "Original")]
107
+ self.license = request.get("license", "Unknown")
108
  self.likes = request.get("likes", 0)
109
  self.num_params = request.get("params", 0)
110
  self.date = request.get("submitted_time", "")
 
121
  AutoEvalColumn.model_type_symbol.name: self.model_type.value.symbol,
122
  AutoEvalColumn.weight_type.name: self.weight_type.value.name,
123
  AutoEvalColumn.architecture.name: self.architecture,
124
+ AutoEvalColumn.model.name: make_clickable_model(self.model_name),
125
  AutoEvalColumn.revision.name: self.revision,
126
  AutoEvalColumn.average.name: average,
127
  AutoEvalColumn.license.name: self.license,
 
136
  return data_dict
137
 
138
 
139
+ def get_request_file_for_model(
140
+ requests_path: str,
141
+ model_name: str,
142
+ revision: str,
143
+ precision: str,
144
+ ):
145
+ request_hash = get_request_hash(model_name, revision, precision)
146
+ filepath = os.path.join(requests_path, model_name, '{}.json'.format(request_hash))
147
+ print(f'Loading {filepath}...')
148
+ filepath = glob.glob(filepath)[0]
149
+ return filepath
 
 
 
 
 
 
 
 
 
150
 
151
 
152
  def get_raw_eval_results(results_path: str, requests_path: str) -> list[EvalResult]:
src/populate.py CHANGED
@@ -10,6 +10,7 @@ import pandas as pd
10
  from src.display.formatting import has_no_nan_values, make_clickable_model
11
  from src.display.utils import AutoEvalColumn, EvalQueueColumn
12
  from src.leaderboard.read_evals import get_raw_eval_results
 
13
 
14
 
15
  def get_leaderboard_df(results_path: str, requests_path: str, cols: list, benchmark_cols: list) -> pd.DataFrame:
@@ -26,48 +27,91 @@ def get_leaderboard_df(results_path: str, requests_path: str, cols: list, benchm
26
  return df
27
 
28
 
29
- def get_evaluation_queue_df(save_path: str, cols: list) -> list[pd.DataFrame]:
30
- """Creates the different dataframes for the evaluation queues requestes"""
31
- entries = [entry for entry in os.listdir(save_path) if not entry.startswith(".")]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  all_evals = []
33
 
34
- for entry in entries:
35
- if ".json" in entry:
36
- file_path = os.path.join(save_path, entry)
37
- try:
38
- with open(file_path, encoding='utf-8') as fp:
39
- data = json.load(fp)
40
- except UnicodeDecodeError as e:
41
- print(f"Unicode decoding error in {file_path}: {e}")
42
- continue
43
-
44
- data[EvalQueueColumn.model.name] = make_clickable_model(data["model"])
45
- data[EvalQueueColumn.revision.name] = data.get("revision", "main")
46
-
47
- all_evals.append(data)
48
- elif ".md" not in entry:
49
- # this is a folder
50
- sub_entries = [e for e in os.listdir(f"{save_path}/{entry}") if not e.startswith(".")]
51
- for sub_entry in sub_entries:
52
- file_path = os.path.join(save_path, entry, sub_entry)
53
- try:
54
- with open(file_path, encoding='utf-8') as fp:
55
- data = json.load(fp)
56
- except json.JSONDecodeError:
57
- print(f"Error reading {file_path}")
58
- continue
59
- except UnicodeDecodeError as e:
60
- print(f"Unicode decoding error in {file_path}: {e}")
61
- continue
62
-
63
- data[EvalQueueColumn.model.name] = make_clickable_model(data["model"])
64
- data[EvalQueueColumn.revision.name] = data.get("revision", "main")
65
- all_evals.append(data)
66
 
67
  pending_list = [e for e in all_evals if e["status"] in ["PENDING", "RERUN"]]
68
  running_list = [e for e in all_evals if e["status"] == "RUNNING"]
69
  finished_list = [e for e in all_evals if e["status"].startswith("FINISHED") or e["status"] == "PENDING_NEW_EVAL"]
 
70
  df_pending = pd.DataFrame.from_records(pending_list, columns=cols)
71
  df_running = pd.DataFrame.from_records(running_list, columns=cols)
72
  df_finished = pd.DataFrame.from_records(finished_list, columns=cols)
 
73
  return df_finished[cols], df_running[cols], df_pending[cols]
 
10
  from src.display.formatting import has_no_nan_values, make_clickable_model
11
  from src.display.utils import AutoEvalColumn, EvalQueueColumn
12
  from src.leaderboard.read_evals import get_raw_eval_results
13
+ from src.utils import get_model_name
14
 
15
 
16
  def get_leaderboard_df(results_path: str, requests_path: str, cols: list, benchmark_cols: list) -> pd.DataFrame:
 
27
  return df
28
 
29
 
30
+ # def get_evaluation_requests_df(save_path: str, cols: list) -> list[pd.DataFrame]:
31
+ # """Creates the different dataframes for the evaluation requestss requestes"""
32
+ # entries = [entry for entry in os.listdir(save_path) if not entry.startswith(".")]
33
+ # all_evals = []
34
+
35
+ # for entry in entries:
36
+ # if ".json" in entry:
37
+ # file_path = os.path.join(save_path, entry)
38
+ # try:
39
+ # with open(file_path, encoding='utf-8') as fp:
40
+ # data = json.load(fp)
41
+ # except UnicodeDecodeError as e:
42
+ # print(f"Unicode decoding error in {file_path}: {e}")
43
+ # continue
44
+
45
+ # # data[EvalQueueColumn.model.name] = make_clickable_model(data["model"])
46
+ # model_name = get_model_name(file_path)
47
+ # data[EvalQueueColumn.model.name] = make_clickable_model(model_name)
48
+
49
+ # data[EvalQueueColumn.revision.name] = data.get("revision", "main")
50
+
51
+ # all_evals.append(data)
52
+
53
+ # elif ".md" not in entry:
54
+ # # this is a folder
55
+ # sub_entries = [e for e in os.listdir(f"{save_path}/{entry}") if not e.startswith(".")]
56
+ # for sub_entry in sub_entries:
57
+ # file_path = os.path.join(save_path, entry, sub_entry)
58
+ # try:
59
+ # with open(file_path, encoding='utf-8') as fp:
60
+ # data = json.load(fp)
61
+ # except json.JSONDecodeError:
62
+ # print(f"Error reading {file_path}")
63
+ # continue
64
+ # except UnicodeDecodeError as e:
65
+ # print(f"Unicode decoding error in {file_path}: {e}")
66
+ # continue
67
+
68
+ # # data[EvalQueueColumn.model.name] = make_clickable_model(data["model"])
69
+ # model_name = get_model_name(file_path)
70
+ # data[EvalQueueColumn.model.name] = make_clickable_model(model_name)
71
+
72
+ # data[EvalQueueColumn.revision.name] = data.get("revision", "main")
73
+ # all_evals.append(data)
74
+
75
+ # pending_list = [e for e in all_evals if e["status"] in ["PENDING", "RERUN"]]
76
+ # running_list = [e for e in all_evals if e["status"] == "RUNNING"]
77
+ # finished_list = [e for e in all_evals if e["status"].startswith("FINISHED") or e["status"] == "PENDING_NEW_EVAL"]
78
+ # df_pending = pd.DataFrame.from_records(pending_list, columns=cols)
79
+ # df_running = pd.DataFrame.from_records(running_list, columns=cols)
80
+ # df_finished = pd.DataFrame.from_records(finished_list, columns=cols)
81
+ # return df_finished[cols], df_running[cols], df_pending[cols]
82
+
83
+ def get_evaluation_requests_df(save_path: str, cols: list) -> list[pd.DataFrame]:
84
+ """Creates the different dataframes for the evaluation requestss requested."""
85
  all_evals = []
86
 
87
+ def process_file(file_path):
88
+ try:
89
+ with open(file_path, 'r', encoding='utf-8') as fp:
90
+ data = json.load(fp)
91
+ except (json.JSONDecodeError, UnicodeDecodeError) as e:
92
+ print(f"Error reading or decoding {file_path}: {e}")
93
+ return None
94
+
95
+ model_name = get_model_name(file_path)
96
+ # data[EvalQueueColumn.model.name] = make_clickable_model(data["model"])
97
+ data[EvalQueueColumn.model.name] = make_clickable_model(model_name)
98
+ data[EvalQueueColumn.revision.name] = data.get("revision", "main")
99
+ return data
100
+
101
+ for root, _, files in os.walk(save_path):
102
+ for file in files:
103
+ if file.endswith('.json'):
104
+ file_path = os.path.join(root, file)
105
+ data = process_file(file_path)
106
+ if data:
107
+ all_evals.append(data)
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  pending_list = [e for e in all_evals if e["status"] in ["PENDING", "RERUN"]]
110
  running_list = [e for e in all_evals if e["status"] == "RUNNING"]
111
  finished_list = [e for e in all_evals if e["status"].startswith("FINISHED") or e["status"] == "PENDING_NEW_EVAL"]
112
+
113
  df_pending = pd.DataFrame.from_records(pending_list, columns=cols)
114
  df_running = pd.DataFrame.from_records(running_list, columns=cols)
115
  df_finished = pd.DataFrame.from_records(finished_list, columns=cols)
116
+
117
  return df_finished[cols], df_running[cols], df_pending[cols]
src/submission/check_validity.py CHANGED
@@ -63,7 +63,7 @@ def is_model_on_hub(model_name: str, revision: str, token: str = None, trust_rem
63
  return False, "was not found on hub!", None
64
 
65
 
66
- def get_model_size(model_info: ModelInfo, precision: str):
67
  """Gets the model size from the configuration, or the model name if the configuration does not contain the information."""
68
  try:
69
  model_size = round(model_info.safetensors["total"] / 1e9, 3)
 
63
  return False, "was not found on hub!", None
64
 
65
 
66
+ def get_model_size(model_info: ModelInfo, precision: str = None):
67
  """Gets the model size from the configuration, or the model name if the configuration does not contain the information."""
68
  try:
69
  model_size = round(model_info.safetensors["total"] / 1e9, 3)
src/submission/submit.py CHANGED
@@ -7,8 +7,9 @@ import os
7
  from datetime import datetime, timezone
8
 
9
  from src.display.formatting import styled_error, styled_message, styled_warning
10
- from src.envs import API, EVAL_REQUESTS_PATH, QUEUE_REPO, TOKEN
11
  from src.submission.check_validity import already_submitted_models, check_model_card, get_model_size, is_model_on_hub
 
12
 
13
  REQUESTED_MODELS = None
14
  USERS_TO_SUBMISSION_DATES = None
@@ -16,12 +17,16 @@ USERS_TO_SUBMISSION_DATES = None
16
 
17
  def add_new_eval(
18
  model: str,
19
- base_model: str,
20
  revision: str,
21
- precision: str,
22
- weight_type: str,
23
  model_type: str,
24
  ):
 
 
 
 
25
  global REQUESTED_MODELS
26
  global USERS_TO_SUBMISSION_DATES
27
  if not REQUESTED_MODELS:
@@ -44,12 +49,12 @@ def add_new_eval(
44
  revision = "main"
45
 
46
  # Is the model on the hub?
47
- if weight_type in ["Delta", "Adapter"]:
48
- base_model_on_hub, error, _ = is_model_on_hub(model_name=base_model, revision=revision, token=TOKEN, test_tokenizer=True)
49
- if not base_model_on_hub:
50
- return styled_error(f'Base model "{base_model}" {error}')
51
 
52
- if not weight_type == "Adapter":
53
  model_on_hub, error, _ = is_model_on_hub(model_name=model, revision=revision, token=TOKEN, test_tokenizer=True)
54
  if not model_on_hub:
55
  return styled_error(f'Model "{model}" {error}')
@@ -60,7 +65,10 @@ def add_new_eval(
60
  except Exception:
61
  return styled_error("Could not get your model information. Please fill it up properly.")
62
 
63
- model_size = get_model_size(model_info=model_info, precision=precision)
 
 
 
64
 
65
  # Were the model card and license filled?
66
  try:
@@ -76,8 +84,8 @@ def add_new_eval(
76
  print("Adding new eval")
77
 
78
  eval_entry = {
79
- "model": model,
80
- "base_model": base_model,
81
  "revision": revision,
82
  "precision": precision,
83
  "weight_type": weight_type,
@@ -91,13 +99,15 @@ def add_new_eval(
91
  }
92
 
93
  # Check for duplicate submission
94
- if f"{model}_{revision}_{precision}" in REQUESTED_MODELS:
 
95
  return styled_warning("This model has been already submitted.")
 
96
 
97
  print("Creating eval file")
98
  OUT_DIR = f"{EVAL_REQUESTS_PATH}/{user_name}"
99
  os.makedirs(OUT_DIR, exist_ok=True)
100
- out_path = f"{OUT_DIR}/{model_path}_eval_request_False_{precision}_{weight_type}.json"
101
 
102
  with open(out_path, "w") as f:
103
  f.write(json.dumps(eval_entry))
@@ -105,15 +115,15 @@ def add_new_eval(
105
  print("Uploading eval file")
106
  API.upload_file(
107
  path_or_fileobj=out_path,
108
- path_in_repo=out_path.split("eval-queue/")[1],
109
- repo_id=QUEUE_REPO,
110
  repo_type="dataset",
111
- commit_message=f"Add {model} to eval queue",
112
  )
113
 
114
  # Remove the local file
115
  os.remove(out_path)
116
 
117
  return styled_message(
118
- "Your request has been submitted to the evaluation queue!\nPlease wait for up to an hour for the model to show in the PENDING list."
119
  )
 
7
  from datetime import datetime, timezone
8
 
9
  from src.display.formatting import styled_error, styled_message, styled_warning
10
+ from src.envs import API, EVAL_REQUESTS_PATH, REQUESTS_REPO, TOKEN
11
  from src.submission.check_validity import already_submitted_models, check_model_card, get_model_size, is_model_on_hub
12
+ from src.utils import get_request_hash, get_request_id
13
 
14
  REQUESTED_MODELS = None
15
  USERS_TO_SUBMISSION_DATES = None
 
17
 
18
  def add_new_eval(
19
  model: str,
20
+ # base_model: str,
21
  revision: str,
22
+ # precision: str,
23
+ # weight_type: str,
24
  model_type: str,
25
  ):
26
+ # Remove if added to the form
27
+ weight_type = 'Original'
28
+ precision = 'Unknown'
29
+
30
  global REQUESTED_MODELS
31
  global USERS_TO_SUBMISSION_DATES
32
  if not REQUESTED_MODELS:
 
49
  revision = "main"
50
 
51
  # Is the model on the hub?
52
+ # if weight_type in ["Delta", "Adapter"]:
53
+ # base_model_on_hub, error, _ = is_model_on_hub(model_name=base_model, revision=revision, token=TOKEN, test_tokenizer=True)
54
+ # if not base_model_on_hub:
55
+ # return styled_error(f'Base model "{base_model}" {error}')
56
 
57
+ if weight_type != "Adapter":
58
  model_on_hub, error, _ = is_model_on_hub(model_name=model, revision=revision, token=TOKEN, test_tokenizer=True)
59
  if not model_on_hub:
60
  return styled_error(f'Model "{model}" {error}')
 
65
  except Exception:
66
  return styled_error("Could not get your model information. Please fill it up properly.")
67
 
68
+ model_size = get_model_size(
69
+ model_info=model_info,
70
+ precision=precision,
71
+ )
72
 
73
  # Were the model card and license filled?
74
  try:
 
84
  print("Adding new eval")
85
 
86
  eval_entry = {
87
+ # "model": model,
88
+ # "base_model": base_model,
89
  "revision": revision,
90
  "precision": precision,
91
  "weight_type": weight_type,
 
99
  }
100
 
101
  # Check for duplicate submission
102
+ request_id = get_request_id(model, revision, precision)
103
+ if request_id in REQUESTED_MODELS:
104
  return styled_warning("This model has been already submitted.")
105
+ request_hash = get_request_hash(model, revision, precision)
106
 
107
  print("Creating eval file")
108
  OUT_DIR = f"{EVAL_REQUESTS_PATH}/{user_name}"
109
  os.makedirs(OUT_DIR, exist_ok=True)
110
+ out_path = f"{OUT_DIR}/{model_path}/{request_hash}.json"
111
 
112
  with open(out_path, "w") as f:
113
  f.write(json.dumps(eval_entry))
 
115
  print("Uploading eval file")
116
  API.upload_file(
117
  path_or_fileobj=out_path,
118
+ path_in_repo=out_path.split("eval-requests/")[1],
119
+ repo_id=REQUESTS_REPO,
120
  repo_type="dataset",
121
+ commit_message=f"Add {model} to eval requests",
122
  )
123
 
124
  # Remove the local file
125
  os.remove(out_path)
126
 
127
  return styled_message(
128
+ "Your request has been submitted to the evaluation requests!\nPlease wait for up to an hour for the model to show in the PENDING list."
129
  )
src/utils.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ import hashlib
5
+
6
+
7
+ def get_org_and_model_names(file_path: str) -> str:
8
+ org, model = file_path.split("/")[-3:-1]
9
+ model = model.removesuffix(".json")
10
+ model = model.split('_request_')[0]
11
+ return org, model
12
+
13
+
14
+ def get_model_name(file_path: str) -> str:
15
+ org, model = get_org_and_model_names(file_path)
16
+ return f"{org}/{model}"
17
+
18
+
19
+ def get_hash(key: str) -> str:
20
+ sha256_hash = hashlib.sha256()
21
+ sha256_hash.update(key.encode('utf-8'))
22
+ return sha256_hash.hexdigest()[:16]
23
+
24
+
25
+ def get_request_id(model: str, revision: str, precision: str) -> str:
26
+ return f"{model}_{revision}_{precision}"
27
+
28
+
29
+ def get_request_hash(model: str, revision: str, precision: str) -> str:
30
+ return get_hash(get_request_id(model, revision, precision))