Skip to content

Commit 0d3db7d

Browse files
Fix HF sync code and add extra guardrails. (keras-team#2615)
* fix kaggle API * add delay to avoid rate limit 429 exception * skip gemma models to avoid repo not found error * sync models and update model cards * revert readme.md changes * nit
1 parent be18b9a commit 0d3db7d

3 files changed

Lines changed: 62 additions & 13 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,4 @@ Thank you to all of our wonderful contributors!
180180

181181
<a href="https://github.com/keras-team/keras-hub/graphs/contributors">
182182
<img src="https://contrib.rocks/image?repo=keras-team/keras-hub" />
183-
</a>
183+
</a>

tools/admin/hf_uploaded_presets.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
"kaggle://keras/electra/keras/electra_large_generator_uncased_en/2",
115115
"kaggle://keras/electra/keras/electra_small_discriminator_uncased_en/2",
116116
"kaggle://keras/electra/keras/electra_small_generator_uncased_en/2",
117+
"kaggle://keras/embeddinggemma/keras/embedding_gemma3_300m/2",
117118
"kaggle://keras/esm-2/keras/esm2_t12_35M/1",
118119
"kaggle://keras/esm-2/keras/esm2_t30_150M/1",
119120
"kaggle://keras/esm-2/keras/esm2_t33_650M/1",
@@ -296,9 +297,12 @@
296297
"kaggle://keras/retinanet/keras/retinanet_resnet50_fpn_v2_coco/3",
297298
"kaggle://keras/roberta/keras/roberta_base_en/3",
298299
"kaggle://keras/roberta/keras/roberta_large_en/3",
300+
"kaggle://keras/rwkv7/keras/rwkv7_g1a_0.1b/1",
301+
"kaggle://keras/rwkv7/keras/rwkv7_g1a_0.3b/1",
299302
"kaggle://keras/sam/keras/sam_base_sa1b/5",
300303
"kaggle://keras/sam/keras/sam_huge_sa1b/5",
301304
"kaggle://keras/sam/keras/sam_large_sa1b/5",
305+
"kaggle://keras/sam3/keras/sam3_pcs/1",
302306
"kaggle://keras/segformer/keras/segformer_b0_ade20k_512/3",
303307
"kaggle://keras/segformer/keras/segformer_b0_cityscapes_1024/3",
304308
"kaggle://keras/segformer/keras/segformer_b1_ade20k_512/1",
@@ -383,6 +387,9 @@
383387
"kaggle://keras/t5/keras/t5_base_multi/3",
384388
"kaggle://keras/t5/keras/t5_large_multi/3",
385389
"kaggle://keras/t5/keras/t5_small_multi/3",
390+
"kaggle://keras/translategemma/keras/translategemma_12b_it/1",
391+
"kaggle://keras/translategemma/keras/translategemma_27b_it/1",
392+
"kaggle://keras/translategemma/keras/translategemma_4b_it/1",
386393
"kaggle://keras/vaultgemma/keras/vault_gemma_1b_en/2",
387394
"kaggle://keras/vgg/keras/vgg_11_imagenet/2",
388395
"kaggle://keras/vgg/keras/vgg_13_imagenet/2",

tools/admin/mirror_weights_on_hf.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
import re
44
import shutil
5+
import time
56

67
from huggingface_hub import HfApi
78
from huggingface_hub import hf_hub_download
@@ -18,6 +19,7 @@
1819
HF_BASE_URI = "hf://keras"
1920
JSON_FILE_PATH = "tools/admin/hf_uploaded_presets.json"
2021
HF_TOKEN = os.getenv("HUGGINGFACE_TOKEN")
22+
KAGGLE_API_RATE_LIMIT_DELAY = 1 # Delay between Kaggle API calls (s)
2123

2224

2325
def load_latest_hf_uploads(json_file_path):
@@ -54,7 +56,7 @@ def download_and_upload_missing_models(missing_in_hf_uploads):
5456
uploaded_handles.append(kaggle_handle)
5557
except Exception as e:
5658
print(
57-
"Error in downloading and uploading preset "
59+
"Error in downloading and uploading preset "
5860
f"{kaggle_handle}: {e}"
5961
)
6062
errored_uploads.append(kaggle_handle)
@@ -73,18 +75,46 @@ def update_hf_uploads_json(json_file_path, latest_kaggle_handles):
7375
def update_model_cards_on_hugging_face(presets):
7476
kaggle_api = KaggleApi()
7577
kaggle_api.authenticate()
78+
updated_count = 0
79+
skipped_count = 0
80+
7681
for model, data in presets.items():
7782
try:
7883
kaggle_handle = data["kaggle_handle"].removeprefix("kaggle://")
7984
owner = "keras"
8085
repo_id = f"keras/{model}"
8186
readme_path = "README.md"
8287
model_slug = kaggle_handle.split("/")[1]
83-
model_metadata = kaggle_api.get_model_with_http_info(
84-
owner, model_slug
85-
)
86-
description = model_metadata[0]["description"]
87-
usage = model_metadata[0]["instances"][0]["usage"].replace(
88+
89+
# Skip Gemma models
90+
if "gemma" in kaggle_handle:
91+
print(f"Skipping Gemma model preset: {kaggle_handle}")
92+
continue
93+
# for rate limiting
94+
max_retries = 3
95+
retry_delay = 2
96+
for attempt in range(max_retries):
97+
try:
98+
model_metadata = kaggle_api.model_get(
99+
f"{owner}/{model_slug}"
100+
)
101+
time.sleep(KAGGLE_API_RATE_LIMIT_DELAY) # Rate limit delay
102+
break
103+
except Exception as e:
104+
status_code = getattr(e, "status", None)
105+
if status_code == 429 and attempt < max_retries - 1:
106+
wait_time = retry_delay ** (attempt + 1)
107+
print(
108+
f"Rate limited (429). Retrying in "
109+
f"{wait_time}s... (Attempt "
110+
f"{attempt + 1}/{max_retries})"
111+
)
112+
time.sleep(wait_time)
113+
else:
114+
raise
115+
116+
description = model_metadata.description
117+
usage = model_metadata.instances[0].usage.replace(
88118
"${VARIATION_SLUG}", model
89119
)
90120
usage = re.sub(
@@ -96,6 +126,7 @@ def update_model_cards_on_hugging_face(presets):
96126

97127
# --- Construct Model Card Markup ---
98128
initial_markup = "---\nlibrary_name: keras-hub\n---\n"
129+
existing_content = None
99130
try:
100131
readme_path = hf_hub_download(
101132
repo_id=repo_id,
@@ -104,17 +135,17 @@ def update_model_cards_on_hugging_face(presets):
104135
local_dir=".",
105136
)
106137
with open(readme_path, "r") as readme_file:
107-
readme_content = readme_file.read()
138+
existing_content = readme_file.read()
108139
# Extract existing markup between ---\n and ---\n
109140
match = re.search(
110-
r"^(---\n.*?\n---\n)", readme_content, re.DOTALL
141+
r"^(---\n.*?\n---\n)", existing_content, re.DOTALL
111142
)
112143
if match:
113144
initial_markup = match.group(1)
114145
except Exception as e:
115146
print(
116147
f"README.md not found on HF for {repo_id}: {e}. "
117-
"Writing new README.md"
148+
"Will write new README.md"
118149
)
119150

120151
model_card_markup = (
@@ -136,6 +167,12 @@ def update_model_cards_on_hugging_face(presets):
136167
.replace("&gt;=", ">=")
137168
)
138169

170+
# --- Check if content has changed ---
171+
if existing_content == model_card_markup:
172+
print(f"No changes detected for {model}, skipping upload")
173+
skipped_count += 1
174+
continue
175+
139176
# --- Save Model Card Content to README.md ---
140177

141178
with open(readme_path, "w") as readme_file:
@@ -150,9 +187,10 @@ def update_model_cards_on_hugging_face(presets):
150187
path_in_repo="README.md",
151188
repo_id=repo_id,
152189
token=HF_TOKEN,
153-
commit_message="Update README.md with new model card content",
190+
commit_message=("Update README.md with new model card content"),
154191
)
155-
print(f"Uploaded README.md to Hugging Face repository: {repo_id}")
192+
print(f"✓ Uploaded README.md to Hugging Face repository: {repo_id}")
193+
updated_count += 1
156194

157195
# --- Clean up the README.md file after upload ---
158196
os.remove(readme_path)
@@ -162,6 +200,10 @@ def update_model_cards_on_hugging_face(presets):
162200
print(f"Error updating model card for {model}: {e}")
163201
continue
164202

203+
print("\nModel card update summary:")
204+
print(f"Updated: {updated_count}")
205+
print(f"Skipped (no changes): {skipped_count}")
206+
165207

166208
def main():
167209
print("Starting the model presets mirroring on HF")
@@ -191,7 +233,7 @@ def main():
191233
JSON_FILE_PATH,
192234
sorted(list(set(latest_kaggle_handles) - set(errored_uploads))),
193235
)
194-
print("uploads for the following models failed: ", errored_uploads)
236+
print("Uploads for the following models failed: ", errored_uploads)
195237
print("Rest of the models up to date on HuggingFace")
196238

197239
# Step 6: Update HuggingFace model card

0 commit comments

Comments
 (0)