From c667bf0de07680d9caaba0426c1816864a6f9a33 Mon Sep 17 00:00:00 2001 From: "C. Regouby" Date: Thu, 21 May 2026 20:05:54 +0200 Subject: [PATCH 1/7] add safetensors conversion script with 2 models --- .github/workflows/models.yaml | 2 +- R/utils.R | 2 +- tools/convert-models.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/workflows/models.yaml b/.github/workflows/models.yaml index 59a30da2..a50b9170 100644 --- a/.github/workflows/models.yaml +++ b/.github/workflows/models.yaml @@ -22,6 +22,6 @@ jobs: - run: | python -m pip install --upgrade pip pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu - pip install boto3 ultralytics + pip install boto3 ultralytics safetensors - run: | python tools/convert-models.py diff --git a/R/utils.R b/R/utils.R index 28cca311..cbb05bed 100644 --- a/R/utils.R +++ b/R/utils.R @@ -12,7 +12,7 @@ download_and_cache <- function(url, redownload = FALSE, prefix = NULL) { if (!file.exists(path) || redownload) { # we should first download to a temporary file because - # download probalems could cause hard to debug errors. + # download problems could be hard to debug errors. tmp <- tempfile(fileext = fs::path_ext(path)) on.exit({try({fs::file_delete(tmp)}, silent = TRUE)}, add = TRUE) diff --git a/tools/convert-models.py b/tools/convert-models.py index b70b3564..c24660af 100644 --- a/tools/convert-models.py +++ b/tools/convert-models.py @@ -4,6 +4,7 @@ import boto3 from botocore.exceptions import ClientError from ultralytics import settings +from safetensors import save_file def upload_blob(bucket_name, source_file_name, destination_blob_name): @@ -147,6 +148,10 @@ def blob_exist(bucket_name, blob_name): 'yolo_v12_s': 'https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo12s.pt', 'yolo_v12_x': 'https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo12x.pt', } +safetensormodels = { + 'tabicl2_classifier': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-classifier-v2-20260212.ckpt?download=true', + 'tabicl2_regressor': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-regressor-v2-20260212.ckpt?download=true', + } os.makedirs("models", exist_ok=True) # yolo specifics @@ -186,3 +191,27 @@ def blob_exist(bucket_name, blob_name): ) # free disk space os.remove(fpath) + + + +for name, url in safetensormodels.items(): + fpath = "models/" + name + ".safetensors" + + if blob_exist("torch-pretrained-models", f"models/vision/v2/{fpath}"): + print(f"--- file {fpath} is already in the bucket. Bypassing conversion") + + else: + # download from url, convert and upload the converted weights + m = load_state_dict_from_url(url, progress=False) + converted = {} + + for nm, par in m.items(): + converted.update([(nm, par.clone())]) + save_file(converted, fpath) + upload_blob( + "torch-pretrained-models", + fpath, + "models/vision/v2/" + fpath + ) + # free disk space + os.remove(fpath) From 773ac044c79df13d37243c750fe1febbea2d581a Mon Sep 17 00:00:00 2001 From: "C. Regouby" Date: Thu, 21 May 2026 20:07:21 +0200 Subject: [PATCH 2/7] typo --- R/utils.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/utils.R b/R/utils.R index cbb05bed..c6d68002 100644 --- a/R/utils.R +++ b/R/utils.R @@ -12,7 +12,7 @@ download_and_cache <- function(url, redownload = FALSE, prefix = NULL) { if (!file.exists(path) || redownload) { # we should first download to a temporary file because - # download problems could be hard to debug errors. + # download problems could cause hard to debug errors. tmp <- tempfile(fileext = fs::path_ext(path)) on.exit({try({fs::file_delete(tmp)}, silent = TRUE)}, add = TRUE) From 9b3fba3a4a84697b92ac3f00e79bf464a72c9765 Mon Sep 17 00:00:00 2001 From: "C. Regouby" Date: Thu, 21 May 2026 20:11:47 +0200 Subject: [PATCH 3/7] fix import --- tools/convert-models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/convert-models.py b/tools/convert-models.py index c24660af..d1ed5c45 100644 --- a/tools/convert-models.py +++ b/tools/convert-models.py @@ -4,7 +4,7 @@ import boto3 from botocore.exceptions import ClientError from ultralytics import settings -from safetensors import save_file +from safetensors.torch import save_file def upload_blob(bucket_name, source_file_name, destination_blob_name): From a975713534076342e0184b02d4395b839a5f3385 Mon Sep 17 00:00:00 2001 From: "C. Regouby" Date: Thu, 21 May 2026 20:20:08 +0200 Subject: [PATCH 4/7] simplify hf links --- tools/convert-models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/convert-models.py b/tools/convert-models.py index d1ed5c45..1ec25c92 100644 --- a/tools/convert-models.py +++ b/tools/convert-models.py @@ -149,8 +149,8 @@ def blob_exist(bucket_name, blob_name): 'yolo_v12_x': 'https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo12x.pt', } safetensormodels = { - 'tabicl2_classifier': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-classifier-v2-20260212.ckpt?download=true', - 'tabicl2_regressor': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-regressor-v2-20260212.ckpt?download=true', + 'tabicl2_classifier': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-classifier-v2-20260212.ckpt', + 'tabicl2_regressor': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-regressor-v2-20260212.ckpt', } os.makedirs("models", exist_ok=True) From 6b569dae362c141711ad8ff01b52e5a45a5ea79f Mon Sep 17 00:00:00 2001 From: "C. Regouby" Date: Thu, 21 May 2026 20:41:35 +0200 Subject: [PATCH 5/7] fix model is in state_dict key --- tools/convert-models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/convert-models.py b/tools/convert-models.py index 1ec25c92..e90ca6aa 100644 --- a/tools/convert-models.py +++ b/tools/convert-models.py @@ -205,7 +205,7 @@ def blob_exist(bucket_name, blob_name): m = load_state_dict_from_url(url, progress=False) converted = {} - for nm, par in m.items(): + for nm, par in m["state_dict"].items(): converted.update([(nm, par.clone())]) save_file(converted, fpath) upload_blob( From 681a1511b5b888eb60b7aa7067fe899f5f139265 Mon Sep 17 00:00:00 2001 From: "C. Regouby" Date: Thu, 28 May 2026 21:43:00 +0200 Subject: [PATCH 6/7] stick to pt format thanks to https://github.com/mlverse/torch/issues/1462 --- .github/workflows/models.yaml | 2 +- tools/convert-models.py | 35 ++++------------------------------- 2 files changed, 5 insertions(+), 32 deletions(-) diff --git a/.github/workflows/models.yaml b/.github/workflows/models.yaml index a50b9170..59a30da2 100644 --- a/.github/workflows/models.yaml +++ b/.github/workflows/models.yaml @@ -22,6 +22,6 @@ jobs: - run: | python -m pip install --upgrade pip pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu - pip install boto3 ultralytics safetensors + pip install boto3 ultralytics - run: | python tools/convert-models.py diff --git a/tools/convert-models.py b/tools/convert-models.py index e90ca6aa..3190fe8a 100644 --- a/tools/convert-models.py +++ b/tools/convert-models.py @@ -4,7 +4,6 @@ import boto3 from botocore.exceptions import ClientError from ultralytics import settings -from safetensors.torch import save_file def upload_blob(bucket_name, source_file_name, destination_blob_name): @@ -147,10 +146,8 @@ def blob_exist(bucket_name, blob_name): 'yolo_v12_n': 'https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo12n.pt', 'yolo_v12_s': 'https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo12s.pt', 'yolo_v12_x': 'https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo12x.pt', - } -safetensormodels = { - 'tabicl2_classifier': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-classifier-v2-20260212.ckpt', - 'tabicl2_regressor': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-regressor-v2-20260212.ckpt', + 'tabicl_classifier_v2': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-classifier-v2-20260212.ckpt', + 'tabicl_regressor_v2': 'https://huggingface.co/jingang/TabICL/resolve/main/tabicl-regressor-v2-20260212.ckpt', } os.makedirs("models", exist_ok=True) @@ -177,8 +174,8 @@ def blob_exist(bucket_name, blob_name): if name.startswith("convnext_") and name.endswith("k"): m = m["model"] - # openmmlab models weights are embedded in a named object - if name.startswith("convnext_") and "_upernet_" in name: + # openmmlab and jingang models weights are embedded in a named object + if name.startswith("convnext_") and "_upernet_" in name) or name.startswith("tabicl_"): m = m["state_dict"] for nm, par in m.items(): @@ -191,27 +188,3 @@ def blob_exist(bucket_name, blob_name): ) # free disk space os.remove(fpath) - - - -for name, url in safetensormodels.items(): - fpath = "models/" + name + ".safetensors" - - if blob_exist("torch-pretrained-models", f"models/vision/v2/{fpath}"): - print(f"--- file {fpath} is already in the bucket. Bypassing conversion") - - else: - # download from url, convert and upload the converted weights - m = load_state_dict_from_url(url, progress=False) - converted = {} - - for nm, par in m["state_dict"].items(): - converted.update([(nm, par.clone())]) - save_file(converted, fpath) - upload_blob( - "torch-pretrained-models", - fpath, - "models/vision/v2/" + fpath - ) - # free disk space - os.remove(fpath) From cbf3a16a0e5b537c35bf6ed030d808df3110ae5c Mon Sep 17 00:00:00 2001 From: "C. Regouby" Date: Thu, 28 May 2026 21:45:30 +0200 Subject: [PATCH 7/7] fix syntax error --- tools/convert-models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/convert-models.py b/tools/convert-models.py index 3190fe8a..db61b692 100644 --- a/tools/convert-models.py +++ b/tools/convert-models.py @@ -175,7 +175,7 @@ def blob_exist(bucket_name, blob_name): m = m["model"] # openmmlab and jingang models weights are embedded in a named object - if name.startswith("convnext_") and "_upernet_" in name) or name.startswith("tabicl_"): + if (name.startswith("convnext_") and "_upernet_" in name) or name.startswith("tabicl_"): m = m["state_dict"] for nm, par in m.items():