Spaces:
Running
Running
Alvaro Romo
commited on
Commit
·
77175ac
1
Parent(s):
8621bb7
Initial commit
Browse files- assets/html/01_model_info.html +12 -0
- assets/html/02_technical_detail.html +16 -0
- assets/html/03_linceses.html +8 -0
- assets/html/04_model_card.html +9 -0
- assets/html/05_checklist.html +8 -0
- assets/images/hf-logo.png +0 -0
- main.py +242 -0
- requirements.txt +9 -0
- src/__init__.py +0 -0
- src/__pycache__/__init__.cpython-310.pyc +0 -0
- src/__pycache__/__init__.cpython-38.pyc +0 -0
- src/__pycache__/check_validity.cpython-310.pyc +0 -0
- src/__pycache__/check_validity.cpython-38.pyc +0 -0
- src/__pycache__/submit.cpython-310.pyc +0 -0
- src/check_validity.py +173 -0
- src/submit.py +27 -0
assets/html/01_model_info.html
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div style="margin-left: 10px;">
|
2 |
+
<h4 style="margin: 0; color: #007BFF;">Model Information</h4>
|
3 |
+
<p>
|
4 |
+
Your model should be <strong>public</strong> on the Hub and follow the
|
5 |
+
<strong>username/model-id</strong> format (e.g., mistralai/Mistral-7B-v0.1).
|
6 |
+
Specify the <strong>revision</strong> (commit hash or branch) and <strong>model type</strong>.
|
7 |
+
</p>
|
8 |
+
<a href="https://huggingface.co/docs/hub/models-uploading" target="_blank"
|
9 |
+
style="color: #007BFF; text-decoration: underline; font-family: monospace;">
|
10 |
+
Model uploading guide →
|
11 |
+
</a>
|
12 |
+
</div>
|
assets/html/02_technical_detail.html
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div style="margin-left: 10px;">
|
2 |
+
<h4 style="margin: 0; color: #007BFF;">Technical Details</h4>
|
3 |
+
<p style="font-size: 0.875rem; color: #6c757d; margin: 0; line-height: 1.5;">
|
4 |
+
Make sure your model can be <strong>loaded locally</strong> before submitting:
|
5 |
+
</p>
|
6 |
+
<div style="background-color: #f5f5f5; padding: 1rem; border-radius: 5px; font-family: monospace; color: #212529;">
|
7 |
+
<pre style="margin: 0; padding: 0; font-size: 1rem; white-space: pre-wrap; word-wrap: break-word;">
|
8 |
+
from transformers import AutoConfig, AutoModel, AutoTokenizer
|
9 |
+
|
10 |
+
config = AutoConfig.from_pretrained("your-username/your-model", revision="main")
|
11 |
+
model = AutoModel.from_pretrained("your-username/your-model", revision="main")
|
12 |
+
tokenizer = AutoTokenizer.from_pretrained("your-username/your-model", revision="main")
|
13 |
+
</pre>
|
14 |
+
</div>
|
15 |
+
<a href="https://huggingface.co/docs/transformers/installation" target="_blank" style="color: #007BFF; text-decoration: underline; font-family: monospace;">Transformers documentation →</a>
|
16 |
+
</div>
|
assets/html/03_linceses.html
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div style="margin-left: 10px;">
|
2 |
+
<h4 style="margin: 0; color: #007BFF;">License Requirements</h4>
|
3 |
+
<p style="font-size: 0.875rem; color: #6c757d;">
|
4 |
+
A <strong>license tag</strong> is required. <strong>Open licenses</strong>
|
5 |
+
(Apache, MIT, etc) are strongly recommended.
|
6 |
+
</p>
|
7 |
+
<a href="https://huggingface.co/docs/hub/repositories-licenses" target="_blank" style="color: #007BFF; text-decoration: underline; font-family: monospace;">About model licenses →</a>
|
8 |
+
</div>
|
assets/html/04_model_card.html
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div style="margin-left: 10px;">
|
2 |
+
<h4 style="margin: 0; color: #007BFF;">Model Card Requirements</h4>
|
3 |
+
<p style="font-size: 0.875rem; color: #6c757d;">
|
4 |
+
Your model card must include: <strong>architecture</strong>,
|
5 |
+
<strong>training details</strong>, <strong>dataset information</strong>, intended use, limitations, and
|
6 |
+
<strong>performance metrics</strong>.
|
7 |
+
</p>
|
8 |
+
<a href="https://huggingface.co/docs/hub/model-cards" target="_blank" style="color: #007BFF; text-decoration: underline; font-family: monospace;">Model cards guide →</a>
|
9 |
+
</div>
|
assets/html/05_checklist.html
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div style="margin-left: 10px;">
|
2 |
+
<h4 style="margin: 0; color: #007BFF;">Checklist</h4>
|
3 |
+
<p style="font-size: 0.875rem; color: #6c757d;">
|
4 |
+
Ensure your model is <strong>public</strong>, uses <strong>safetensors</strong> format,
|
5 |
+
has a <strong>license tag</strong>, and <strong>loads correctly</strong> with the provided code.
|
6 |
+
</p>
|
7 |
+
<a href="https://huggingface.co/docs/hub/repositories-getting-started" target="_blank" style="color: #007BFF; text-decoration: underline; font-family: monospace;">Sharing best practices →</a>
|
8 |
+
</div>
|
assets/images/hf-logo.png
ADDED
![]() |
main.py
ADDED
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import re
|
4 |
+
from datasets import load_dataset
|
5 |
+
import src.check_validity as cv
|
6 |
+
from src.submit import ModelSizeChecker
|
7 |
+
import os
|
8 |
+
from huggingface_hub import HfApi
|
9 |
+
|
10 |
+
st.set_page_config(page_title="IVACE Leaderboard", layout="wide")
|
11 |
+
|
12 |
+
|
13 |
+
def validate_model(model, precision, base_model, weight_type, use_chat_template):
|
14 |
+
"""
|
15 |
+
Validate model with some checkers to assure tha can be evaluated
|
16 |
+
:param model: hf model name
|
17 |
+
:param precision: model parameters data type
|
18 |
+
:param base_model: base model (if it is need it)
|
19 |
+
:param weight_type:
|
20 |
+
:param use_chat_template:
|
21 |
+
:return:
|
22 |
+
"""
|
23 |
+
API = HfApi()
|
24 |
+
|
25 |
+
try:
|
26 |
+
model_info = API.model_info(repo_id=model, revision="main")
|
27 |
+
except Exception as e:
|
28 |
+
return "Could not get your model information. Please fill it up properly."
|
29 |
+
|
30 |
+
# TODO: think if it makes sense. Maybe we need to allow upload sumissions more than once
|
31 |
+
# # Has it been submitted already?
|
32 |
+
# model_key = f"{model}_{model_info.sha}_{precision}"
|
33 |
+
# if model_key in requested_models:
|
34 |
+
# return st.error(
|
35 |
+
# f"The model '{model}' with revision '{model_info.sha}' and precision '{precision}' has already been submitted.")
|
36 |
+
|
37 |
+
# Check model size early
|
38 |
+
model_size, error_text = cv.get_model_size(model_info=model_info, precision=precision, base_model=base_model)
|
39 |
+
if model_size is None:
|
40 |
+
return error_text
|
41 |
+
|
42 |
+
# Absolute size limit for float16 and bfloat16
|
43 |
+
if precision in ["float16", "bfloat16"] and model_size > 100:
|
44 |
+
error_message = f"Sadly, models larger than 100B parameters cannot be submitted in {precision} precision at this time. " \
|
45 |
+
f"Your model size: {model_size:.2f}B parameters."
|
46 |
+
return error_message
|
47 |
+
|
48 |
+
# Precision-adjusted size limit for 8bit, 4bit, and GPTQ
|
49 |
+
if precision in ["8bit", "4bit", "GPTQ"]:
|
50 |
+
size_checker = ModelSizeChecker(model=model, precision=precision, model_size_in_b=model_size)
|
51 |
+
|
52 |
+
if not size_checker.can_evaluate():
|
53 |
+
precision_factor = size_checker.get_precision_factor()
|
54 |
+
max_size = 140 * precision_factor
|
55 |
+
error_message = f"Sadly, models this big ({model_size:.2f}B parameters) cannot be evaluated automatically " \
|
56 |
+
f"at the moment on our cluster. The maximum size for {precision} precision is {max_size:.2f}B parameters."
|
57 |
+
return error_message
|
58 |
+
|
59 |
+
architecture = "?"
|
60 |
+
# Is the model on the hub?
|
61 |
+
if weight_type in ["Delta", "Adapter"]:
|
62 |
+
base_model_on_hub, error, _ = cv.is_model_on_hub(
|
63 |
+
model_name=base_model, revision="main", token=None, test_tokenizer=True
|
64 |
+
)
|
65 |
+
if not base_model_on_hub:
|
66 |
+
return f'Base model "{base_model}" {error}'
|
67 |
+
if not weight_type == "Adapter":
|
68 |
+
model_on_hub, error, model_config = cv.is_model_on_hub(model_name=model, revision=model_info.sha,
|
69 |
+
test_tokenizer=True)
|
70 |
+
if not model_on_hub or model_config is None:
|
71 |
+
return f'Model "{model}" {error}'
|
72 |
+
if model_config is not None:
|
73 |
+
architectures = getattr(model_config, "architectures", None)
|
74 |
+
if architectures:
|
75 |
+
architecture = ";".join(architectures)
|
76 |
+
|
77 |
+
# Were the model card and license filled?
|
78 |
+
try:
|
79 |
+
model_info.cardData["license"]
|
80 |
+
except Exception:
|
81 |
+
return "Please select a license for your model"
|
82 |
+
|
83 |
+
modelcard_OK, error_msg, model_card = cv.check_model_card(model)
|
84 |
+
if not modelcard_OK:
|
85 |
+
return error_msg
|
86 |
+
|
87 |
+
# Check the chat template submission
|
88 |
+
if use_chat_template:
|
89 |
+
chat_template_valid, chat_template_error = cv.check_chat_template(model, "main")
|
90 |
+
if not chat_template_valid:
|
91 |
+
return chat_template_error
|
92 |
+
|
93 |
+
return None
|
94 |
+
|
95 |
+
# Function to send email
|
96 |
+
def log_submission(model_name, description, user_contact):
|
97 |
+
# todo: create email or log in dataset
|
98 |
+
...
|
99 |
+
|
100 |
+
return True
|
101 |
+
|
102 |
+
|
103 |
+
def get_url(html_content):
|
104 |
+
match = re.search(r'href=["\'](https?://[^\s"\']+)', html_content)
|
105 |
+
if match:
|
106 |
+
url = match.group(1)
|
107 |
+
return url
|
108 |
+
|
109 |
+
return None
|
110 |
+
|
111 |
+
|
112 |
+
@st.cache_data
|
113 |
+
def load_data():
|
114 |
+
try:
|
115 |
+
columns = ["eval_name", "Model", "Type", "Average ⬆️", "IFEval", "MMLU-PRO", "GPQA", "MUSR", "CO₂ cost (kg)"]
|
116 |
+
data = load_dataset("open-llm-leaderboard/contents")["train"].to_pandas().head(10)
|
117 |
+
# print(data.columns)
|
118 |
+
data = data[columns]
|
119 |
+
# TODO: check if from submit this is neede it
|
120 |
+
data["Model"] = data["Model"].apply(get_url)
|
121 |
+
data.sort_values(by="Average ⬆️", ascending=False, inplace=True)
|
122 |
+
data.reset_index(drop=True, inplace=True)
|
123 |
+
return data
|
124 |
+
except FileNotFoundError:
|
125 |
+
st.error("open-llm-leaderboard/contents was not found in the hub")
|
126 |
+
return pd.DataFrame()
|
127 |
+
|
128 |
+
|
129 |
+
leaderboard_data = load_data()
|
130 |
+
tabs = st.tabs(["Leaderboard", "Submit model"]) # , "Vote for next model"
|
131 |
+
|
132 |
+
with tabs[0]:
|
133 |
+
# logo
|
134 |
+
cols_logo = st.columns(5, vertical_alignment="center")
|
135 |
+
with cols_logo[2]:
|
136 |
+
st.image("assets/images/hf-logo.png", use_container_width=True)
|
137 |
+
|
138 |
+
# title
|
139 |
+
st.markdown(
|
140 |
+
"""
|
141 |
+
<div style="text-align: center;">
|
142 |
+
<h1>IVACE LLM Leaderboard</h1>
|
143 |
+
<p style="font-size: 1.2rem;">
|
144 |
+
Comparing Large Language Models in an <span style="font-weight: 600;">open</span>
|
145 |
+
and <span style="font-weight: 600;">reproducible</span> way
|
146 |
+
</p>
|
147 |
+
</div>
|
148 |
+
""",
|
149 |
+
unsafe_allow_html=True,
|
150 |
+
)
|
151 |
+
leaderboard_cols = st.columns([0.1, 0.8, 0.1], vertical_alignment="center")
|
152 |
+
with leaderboard_cols[1]:
|
153 |
+
if not leaderboard_data.empty:
|
154 |
+
st.data_editor(
|
155 |
+
leaderboard_data,
|
156 |
+
column_config={
|
157 |
+
"Model": st.column_config.LinkColumn("Model")
|
158 |
+
},
|
159 |
+
hide_index=False,
|
160 |
+
)
|
161 |
+
else:
|
162 |
+
st.write("No data found to display on leaderboard.")
|
163 |
+
|
164 |
+
with tabs[1]:
|
165 |
+
st.header("Submit model")
|
166 |
+
import streamlit as st
|
167 |
+
|
168 |
+
def get_id_number(id_val):
|
169 |
+
html_template = f"""
|
170 |
+
<div style="display: flex; align-items: flex-start; margin-bottom: 1rem;">
|
171 |
+
<div style="
|
172 |
+
width: 32px;
|
173 |
+
height: 32px;
|
174 |
+
border-radius: 50%;
|
175 |
+
display: flex;
|
176 |
+
align-items: center;
|
177 |
+
justify-content: center;
|
178 |
+
border: 1px solid #007BFF;
|
179 |
+
color: #007BFF;
|
180 |
+
font-size: 0.875rem;
|
181 |
+
font-weight: 600;
|
182 |
+
background-color: transparent;">
|
183 |
+
{id_val}
|
184 |
+
</div>"""
|
185 |
+
return html_template
|
186 |
+
|
187 |
+
# create guide info
|
188 |
+
guide_info_list = []
|
189 |
+
html_path = "assets/html"
|
190 |
+
for filename in os.listdir(html_path):
|
191 |
+
file_path = os.path.join(html_path, filename)
|
192 |
+
with open(file_path, 'r', encoding='utf-8') as file:
|
193 |
+
guide_info_list.append(file.read())
|
194 |
+
|
195 |
+
# display adding number id
|
196 |
+
for i, info_div in enumerate(guide_info_list):
|
197 |
+
st.markdown(get_id_number(i+1) + info_div, unsafe_allow_html=True)
|
198 |
+
|
199 |
+
with st.form("submit_model_form"):
|
200 |
+
model_name = st.text_input("Model Name (format: user_name/model_name)",
|
201 |
+
help="Your model should be public on the Hub and follow the username/model-id format (e.g. mistralai/Mistral-7B-v0.1).")
|
202 |
+
description = st.text_area("Description", help="Add a description of the proposed model for the evaluation to help prioritize its evaluation")
|
203 |
+
user_contact = st.text_input("Your Contact Email", help="User e-mail to contact when there are updates")
|
204 |
+
precision_option = st.selectbox(
|
205 |
+
"Choose precision format:",
|
206 |
+
help="Size limits vary by precision: • FP16/BF16: up to 100B parameters • 8-bit: up to 280B parameters (2x) • 4-bit: up to 560B parameters (4x) Choose carefully as incorrect precision can cause evaluation errors.",
|
207 |
+
options=["float16", "bfloat16", "8bit", "4bit", "GPTQ"],
|
208 |
+
index=0
|
209 |
+
)
|
210 |
+
weight_type_option = st.selectbox(
|
211 |
+
"Select what type of weights are being loaded from the checkpoint provided:",
|
212 |
+
help="Original: Complete model weights in safetensors format Delta: Weight differences from base model (requires base model for size calculation) Adapter: Lightweight fine-tuning layers (requires base model for size calculation)",
|
213 |
+
options=["Original", "Adapter", "Delta"],
|
214 |
+
index=0
|
215 |
+
)
|
216 |
+
base_model_name = st.text_input("Base model",
|
217 |
+
help="Required for delta weights or adapters. This information is used to identify the original model and calculate the total parameter count by combining base model and adapter/delta parameters.",
|
218 |
+
value="")
|
219 |
+
model_type = st.selectbox(
|
220 |
+
"Choose model type:",
|
221 |
+
help="🟢 Pretrained: Base models trained on text using masked modeling 🟩 Continuously Pretrained: Extended training on additional corpus 🔶 Fine-tuned: Domain-specific optimization 💬 Chat: Models using RLHF, DPO, or IFT for conversation 🤝 Merge: Combined weights without additional training",
|
222 |
+
options=["🟢 Pretrained", "🟩 Continuously Pretrained", "🔶 Fine-tuned", "💬 Chat", "🤝 Merge"],
|
223 |
+
)
|
224 |
+
submit_button = st.form_submit_button("Submit Request")
|
225 |
+
|
226 |
+
if submit_button:
|
227 |
+
# validate model size, license, chat_templates
|
228 |
+
use_chat_template = True if model_type == "💬 Chat" else False
|
229 |
+
validation_error = validate_model(model_name, precision_option, base_model_name, weight_type_option, use_chat_template)
|
230 |
+
if validation_error is not None:
|
231 |
+
st.error(validation_error)
|
232 |
+
elif not re.match(r"[^@]+@[^@]+\.[^@]+", user_contact):
|
233 |
+
st.error("Invalid email address.")
|
234 |
+
else:
|
235 |
+
if log_submission(model_name, description, user_contact):
|
236 |
+
st.success("Your request has been sent successfully.")
|
237 |
+
else:
|
238 |
+
st.error("Failed to send your request. Please try again later.")
|
239 |
+
|
240 |
+
# with tabs[2]:
|
241 |
+
# st.header("Vote for next model")
|
242 |
+
# st.write("Esta sección estará disponible próximamente.")
|
requirements.txt
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
datasets==2.14.4
|
2 |
+
pandas==2.0.3
|
3 |
+
streamlit==1.40.1
|
4 |
+
scikit-learn==1.3.2
|
5 |
+
matplotlib==3.7.5
|
6 |
+
sentence-transformers==2.2.2
|
7 |
+
transformers==4.48.0
|
8 |
+
huggingface-hub==0.27.1
|
9 |
+
fsspec==2023.9.2
|
src/__init__.py
ADDED
File without changes
|
src/__pycache__/__init__.cpython-310.pyc
ADDED
Binary file (156 Bytes). View file
|
|
src/__pycache__/__init__.cpython-38.pyc
ADDED
Binary file (154 Bytes). View file
|
|
src/__pycache__/check_validity.cpython-310.pyc
ADDED
Binary file (5.85 kB). View file
|
|
src/__pycache__/check_validity.cpython-38.pyc
ADDED
Binary file (5.9 kB). View file
|
|
src/__pycache__/submit.cpython-310.pyc
ADDED
Binary file (1.22 kB). View file
|
|
src/check_validity.py
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import os
|
3 |
+
import re
|
4 |
+
import logging
|
5 |
+
from collections import defaultdict
|
6 |
+
from datetime import datetime, timedelta, timezone
|
7 |
+
|
8 |
+
import huggingface_hub
|
9 |
+
from huggingface_hub import ModelCard, hf_hub_download
|
10 |
+
from huggingface_hub.hf_api import ModelInfo, get_safetensors_metadata, parse_safetensors_file_metadata
|
11 |
+
from transformers import AutoConfig, AutoTokenizer
|
12 |
+
|
13 |
+
# ht to @Wauplin, thank you for the snippet!
|
14 |
+
# See https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard/discussions/317
|
15 |
+
def check_model_card(repo_id: str) -> tuple[bool, str]:
|
16 |
+
# Returns operation status, and error message
|
17 |
+
try:
|
18 |
+
card = ModelCard.load(repo_id)
|
19 |
+
except huggingface_hub.utils.EntryNotFoundError:
|
20 |
+
return False, "Please add a model card to your model to explain how you trained/fine-tuned it.", None
|
21 |
+
|
22 |
+
# Enforce license metadata
|
23 |
+
if card.data.license is None and not ("license_name" in card.data and "license_link" in card.data):
|
24 |
+
return (
|
25 |
+
False,
|
26 |
+
(
|
27 |
+
"License not found. Please add a license to your model card using the `license` metadata or a"
|
28 |
+
" `license_name`/`license_link` pair."
|
29 |
+
),
|
30 |
+
None,
|
31 |
+
)
|
32 |
+
|
33 |
+
# Enforce card content
|
34 |
+
if len(card.text) < 200:
|
35 |
+
return False, "Please add a description to your model card, it is too short.", None
|
36 |
+
|
37 |
+
return True, "", card
|
38 |
+
|
39 |
+
|
40 |
+
def is_model_on_hub(
|
41 |
+
model_name: str, revision: str, token: str | None = None, trust_remote_code: bool = False, test_tokenizer: bool = False,
|
42 |
+
) -> tuple[bool, str, AutoConfig]:
|
43 |
+
try:
|
44 |
+
config = AutoConfig.from_pretrained(
|
45 |
+
model_name, revision=revision, trust_remote_code=trust_remote_code, token=token, force_download=True)
|
46 |
+
if test_tokenizer:
|
47 |
+
try:
|
48 |
+
AutoTokenizer.from_pretrained(
|
49 |
+
model_name, revision=revision, trust_remote_code=trust_remote_code, token=token,
|
50 |
+
)
|
51 |
+
except ValueError as e:
|
52 |
+
return (False, f"uses a tokenizer which is not in a transformers release: {e}", None)
|
53 |
+
except Exception:
|
54 |
+
return (
|
55 |
+
False,
|
56 |
+
"'s tokenizer cannot be loaded. Is your tokenizer class in a stable transformers release, and correctly configured?",
|
57 |
+
None,
|
58 |
+
)
|
59 |
+
except Exception:
|
60 |
+
return (
|
61 |
+
False,
|
62 |
+
"'s tokenizer cannot be loaded. Is your tokenizer class in a stable transformers release, and correctly configured?",
|
63 |
+
None,
|
64 |
+
)
|
65 |
+
return True, None, config
|
66 |
+
|
67 |
+
except ValueError:
|
68 |
+
return (
|
69 |
+
False,
|
70 |
+
"needs to be launched with `trust_remote_code=True`. For safety reason, we do not allow these models to be automatically submitted to the leaderboard.",
|
71 |
+
None,
|
72 |
+
)
|
73 |
+
|
74 |
+
except Exception as e:
|
75 |
+
if "You are trying to access a gated repo." in str(e):
|
76 |
+
return True, "uses a gated model.", None
|
77 |
+
return False, f"was not found or misconfigured on the hub! Error raised was {e.args[0]}", None
|
78 |
+
|
79 |
+
|
80 |
+
def get_model_size(model_info: ModelInfo, precision: str, base_model: str| None) -> tuple[float | None, str]:
|
81 |
+
size_pattern = re.compile(r"(\d+\.)?\d+(b|m)")
|
82 |
+
safetensors = None
|
83 |
+
adapter_safetensors = None
|
84 |
+
# hack way to check that model is adapter
|
85 |
+
is_adapter = "adapter_config.json" in (s.rfilename for s in model_info.siblings)
|
86 |
+
|
87 |
+
try:
|
88 |
+
if is_adapter:
|
89 |
+
if not base_model:
|
90 |
+
return None, "Adapter model submission detected. Please ensure the base model information is provided."
|
91 |
+
|
92 |
+
adapter_safetensors = parse_safetensors_file_metadata(model_info.id, "adapter_model.safetensors")
|
93 |
+
safetensors = get_safetensors_metadata(base_model)
|
94 |
+
else:
|
95 |
+
safetensors = get_safetensors_metadata(model_info.id)
|
96 |
+
except Exception as e:
|
97 |
+
logging.warning(f"Failed to get safetensors metadata for model {model_info.id}: {e!s}")
|
98 |
+
|
99 |
+
if safetensors is not None:
|
100 |
+
model_size = sum(safetensors.parameter_count.values())
|
101 |
+
if adapter_safetensors is not None:
|
102 |
+
model_size += sum(safetensors.parameter_count.values())
|
103 |
+
model_size = round(model_size / 1e9, 3)
|
104 |
+
else:
|
105 |
+
try:
|
106 |
+
size_match = re.search(size_pattern, model_info.id.lower())
|
107 |
+
if size_match:
|
108 |
+
model_size = size_match.group(0)
|
109 |
+
model_size = round(float(model_size[:-1]) if model_size[-1] == "b" else float(model_size[:-1]) / 1e3, 3)
|
110 |
+
else:
|
111 |
+
return None, "Unknown model size"
|
112 |
+
except AttributeError:
|
113 |
+
logging.warning(f"Unable to parse model size from ID: {model_info.id}")
|
114 |
+
return None, "Unknown model size"
|
115 |
+
|
116 |
+
size_factor = 8 if (precision == "GPTQ" or "gptq" in model_info.id.lower()) else 1
|
117 |
+
model_size = size_factor * model_size
|
118 |
+
|
119 |
+
return model_size, ""
|
120 |
+
|
121 |
+
def get_model_arch(model_info: ModelInfo):
|
122 |
+
return model_info.config.get("architectures", "Unknown")
|
123 |
+
|
124 |
+
def check_chat_template(model: str, revision: str) -> tuple[bool, str]:
|
125 |
+
try:
|
126 |
+
# Attempt to download only the tokenizer_config.json file
|
127 |
+
config_file = hf_hub_download(
|
128 |
+
repo_id=model,
|
129 |
+
filename="tokenizer_config.json",
|
130 |
+
revision=revision,
|
131 |
+
repo_type="model"
|
132 |
+
)
|
133 |
+
|
134 |
+
# Read and parse the tokenizer_config.json file
|
135 |
+
with open(config_file, 'r') as f:
|
136 |
+
tokenizer_config = json.load(f)
|
137 |
+
|
138 |
+
# Check if chat_template exists in the tokenizer configuration
|
139 |
+
if 'chat_template' not in tokenizer_config:
|
140 |
+
return False, f"The model {model} doesn't have a chat_template in its tokenizer_config.json. Please add a chat_template before submitting or submit without it."
|
141 |
+
|
142 |
+
return True, ""
|
143 |
+
except Exception as e:
|
144 |
+
return False, f"Error checking chat_template for model {model}: {str(e)}"
|
145 |
+
|
146 |
+
def get_model_tags(model_card, model: str):
|
147 |
+
is_merge_from_metadata = False
|
148 |
+
is_moe_from_metadata = False
|
149 |
+
|
150 |
+
tags = []
|
151 |
+
if model_card is None:
|
152 |
+
return tags
|
153 |
+
if model_card.data.tags:
|
154 |
+
is_merge_from_metadata = any(
|
155 |
+
[tag in model_card.data.tags for tag in ["merge", "moerge", "mergekit", "lazymergekit"]]
|
156 |
+
)
|
157 |
+
is_moe_from_metadata = any([tag in model_card.data.tags for tag in ["moe", "moerge"]])
|
158 |
+
|
159 |
+
is_merge_from_model_card = any(
|
160 |
+
keyword in model_card.text.lower() for keyword in ["merged model", "merge model", "moerge"]
|
161 |
+
)
|
162 |
+
if is_merge_from_model_card or is_merge_from_metadata:
|
163 |
+
tags.append("merge")
|
164 |
+
is_moe_from_model_card = any(keyword in model_card.text.lower() for keyword in ["moe", "mixtral"])
|
165 |
+
# Hardcoding because of gating problem
|
166 |
+
if "Qwen/Qwen1.5-32B" in model:
|
167 |
+
is_moe_from_model_card = False
|
168 |
+
is_moe_from_name = "moe" in model.lower().replace("/", "-").replace("_", "-").split("-")
|
169 |
+
if is_moe_from_model_card or is_moe_from_name or is_moe_from_metadata:
|
170 |
+
tags.append("moe")
|
171 |
+
|
172 |
+
return tags
|
173 |
+
|
src/submit.py
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import AutoConfig
|
2 |
+
from dataclasses import dataclass
|
3 |
+
|
4 |
+
@dataclass
|
5 |
+
class ModelSizeChecker:
|
6 |
+
model: str
|
7 |
+
precision: str
|
8 |
+
model_size_in_b: float
|
9 |
+
|
10 |
+
def get_precision_factor(self):
|
11 |
+
if self.precision in ["float16", "bfloat16"]:
|
12 |
+
return 1
|
13 |
+
elif self.precision == "8bit":
|
14 |
+
return 2
|
15 |
+
elif self.precision == "4bit":
|
16 |
+
return 4
|
17 |
+
elif self.precision == "GPTQ":
|
18 |
+
config = AutoConfig.from_pretrained(self.model)
|
19 |
+
num_bits = int(config.quantization_config["bits"])
|
20 |
+
bits_to_precision_factor = {2: 8, 3: 6, 4: 4, 8: 2}
|
21 |
+
return bits_to_precision_factor.get(num_bits, 1)
|
22 |
+
else:
|
23 |
+
raise Exception(f"Unknown precision {self.precision}.")
|
24 |
+
|
25 |
+
def can_evaluate(self):
|
26 |
+
precision_factor = self.get_precision_factor()
|
27 |
+
return self.model_size_in_b <= 140 * precision_factor
|