From 1cdf751f8eaad722be9f248ce097645504d1c3e8 Mon Sep 17 00:00:00 2001 From: Rachel Li Date: Thu, 8 Jan 2026 18:44:22 -0500 Subject: [PATCH 1/7] Fix Kaggle telemetry misclassification when COLAB_ keys exist Problem: Kaggle notebook environments can expose both KAGGLE_* and COLAB_* environment keys. _get_statistics currently checks COLAB_ before KAGGLE_, causing Kaggle sessions to be labeled colab/colabpro. Prefer filesystem markers (e.g. /kaggle/working, /content + /opt/colab) before env-key heuristics, then fall back to the existing env-key checks. This avoids misclassification when providers leak overlapping env vars. Kaggle test notebook: https://www.kaggle.com/code/hnxnq07/kaggle-stats-gathering-test --- unsloth/models/_utils.py | 165 +++++++++++++++++++++------------------ 1 file changed, 90 insertions(+), 75 deletions(-) diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index e6c4a12874..77564c03d5 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -1108,85 +1108,100 @@ def _get_statistics(statistics = None, force_download = True): if statistics is not None: pass - elif "\nCOLAB_" in keynames and n_cpus == 1: - statistics = "colab" - elif "\nCOLAB_" in keynames: - statistics = "colabpro" - elif "\nKAGGLE_" in keynames: - statistics = "kaggle" - elif "\nRUNPOD_" in keynames: - statistics = "runpod" - elif "\nAWS_" in keynames: - statistics = "aws" - elif "\nAZURE_" in keynames: - statistics = "azure" - # elif "\nK_" in keynames or "\nFUNCTION_" in keynames: statistics = "gcp" - elif "\nINVOCATION_ID" in keynames: - statistics = "lambda" - # else: statistics = "other" else: - - def try_vllm_check(): - vendor_files = ( - "/sys/class/dmi/id/product_version", - "/sys/class/dmi/id/bios_vendor", - "/sys/class/dmi/id/product_name", - "/sys/class/dmi/id/chassis_asset_tag", - "/sys/class/dmi/id/sys_vendor", - ) + # Prefer filesystem markers (harder to misidentify) before env-key matching + try: from pathlib import Path - for vendor_file in vendor_files: - path = Path(vendor_file) - if path.is_file(): - file_content = path.read_text().lower() - if "amazon" in file_content: - return "aws" - elif "microsoft corporation" in file_content: - return "azure" - elif "google" in file_content: - return "gcp" - return "other" - - pass - try: - statistics = try_vllm_check() - except: - statistics = "other" - if statistics is not None: - import tempfile - from huggingface_hub import snapshot_download - from unsloth_zoo.rl_environments import execute_with_time_limit - - if has_internet(): - - def stats_check(): - with tempfile.TemporaryDirectory(ignore_cleanup_errors = True) as f: - snapshot_download( - f"unslothai/{statistics}", - force_download = True, - cache_dir = f, - local_dir = f, + if Path("/kaggle/working").exists(): + statistics = "kaggle" + elif Path("/content").exists() and Path("/opt/colab").exists(): + statistics = "colab" if n_cpus == 1 else "colabpro" + elif Path("/runpod-volume").exists(): + statistics = "runpod" + except Exception: + pass + # Fallback to env-key detection + if statistics is None: + if "\nKAGGLE_" in keynames: + statistics = "kaggle" + elif "\nCOLAB_" in keynames and n_cpus == 1: + statistics = "colab" + elif "\nCOLAB_" in keynames: + statistics = "colabpro" + elif "\nRUNPOD_" in keynames: + statistics = "runpod" + elif "\nAWS_" in keynames: + statistics = "aws" + elif "\nAZURE_" in keynames: + statistics = "azure" + # elif "\nK_" in keynames or "\nFUNCTION_" in keynames: statistics = "gcp" + elif "\nINVOCATION_ID" in keynames: + statistics = "lambda" + # else: statistics = "other" + else: + + def try_vllm_check(): + vendor_files = ( + "/sys/class/dmi/id/product_version", + "/sys/class/dmi/id/bios_vendor", + "/sys/class/dmi/id/product_name", + "/sys/class/dmi/id/chassis_asset_tag", + "/sys/class/dmi/id/sys_vendor", ) - - time_limited_stats_check = execute_with_time_limit(120)(stats_check) - try: - time_limited_stats_check() - except TimeoutError: - raise TimeoutError( - "Unsloth: HuggingFace seems to be down after trying for 120 seconds :(\n" - "Check https://status.huggingface.co/ for more details.\n" - "As a temporary measure, use modelscope with the same model name ie:\n" - "```\n" - "pip install modelscope\n" - "import os; os.environ['UNSLOTH_USE_MODELSCOPE'] = '1'\n" - "from unsloth import FastLanguageModel\n" - "model = FastLanguageModel.from_pretrained('unsloth/gpt-oss-20b')\n" - "```" - ) - except: - # Try no time limit check - stats_check() + from pathlib import Path + + for vendor_file in vendor_files: + path = Path(vendor_file) + if path.is_file(): + file_content = path.read_text().lower() + if "amazon" in file_content: + return "aws" + elif "microsoft corporation" in file_content: + return "azure" + elif "google" in file_content: + return "gcp" + return "other" + + pass + try: + statistics = try_vllm_check() + except: + statistics = "other" + if statistics is not None: + import tempfile + from huggingface_hub import snapshot_download + from unsloth_zoo.rl_environments import execute_with_time_limit + + if has_internet(): + + def stats_check(): + with tempfile.TemporaryDirectory(ignore_cleanup_errors = True) as f: + snapshot_download( + f"unslothai/{statistics}", + force_download = True, + cache_dir = f, + local_dir = f, + ) + + time_limited_stats_check = execute_with_time_limit(120)(stats_check) + try: + time_limited_stats_check() + except TimeoutError: + raise TimeoutError( + "Unsloth: HuggingFace seems to be down after trying for 120 seconds :(\n" + "Check https://status.huggingface.co/ for more details.\n" + "As a temporary measure, use modelscope with the same model name ie:\n" + "```\n" + "pip install modelscope\n" + "import os; os.environ['UNSLOTH_USE_MODELSCOPE'] = '1'\n" + "from unsloth import FastLanguageModel\n" + "model = FastLanguageModel.from_pretrained('unsloth/gpt-oss-20b')\n" + "```" + ) + except: + # Try no time limit check + stats_check() def get_statistics(local_files_only = False): From 67bef80b1f2fcfe1f4d6ef0bd96cca2f7955ef83 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 23:49:54 +0000 Subject: [PATCH 2/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- unsloth/models/_utils.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index 77564c03d5..756d884de1 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -1140,7 +1140,7 @@ def _get_statistics(statistics = None, force_download = True): statistics = "lambda" # else: statistics = "other" else: - + def try_vllm_check(): vendor_files = ( "/sys/class/dmi/id/product_version", @@ -1150,7 +1150,7 @@ def _get_statistics(statistics = None, force_download = True): "/sys/class/dmi/id/sys_vendor", ) from pathlib import Path - + for vendor_file in vendor_files: path = Path(vendor_file) if path.is_file(): @@ -1162,7 +1162,7 @@ def _get_statistics(statistics = None, force_download = True): elif "google" in file_content: return "gcp" return "other" - + pass try: statistics = try_vllm_check() @@ -1172,18 +1172,20 @@ def _get_statistics(statistics = None, force_download = True): import tempfile from huggingface_hub import snapshot_download from unsloth_zoo.rl_environments import execute_with_time_limit - + if has_internet(): - + def stats_check(): - with tempfile.TemporaryDirectory(ignore_cleanup_errors = True) as f: + with tempfile.TemporaryDirectory( + ignore_cleanup_errors = True + ) as f: snapshot_download( f"unslothai/{statistics}", force_download = True, cache_dir = f, local_dir = f, ) - + time_limited_stats_check = execute_with_time_limit(120)(stats_check) try: time_limited_stats_check() From e13160ddc8febd25b569bc31970efce7dd9c57a7 Mon Sep 17 00:00:00 2001 From: Rachel Li Date: Thu, 8 Jan 2026 19:04:30 -0500 Subject: [PATCH 3/7] Update _utils.py fixed indentation --- unsloth/models/_utils.py | 68 +++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index 756d884de1..9bf02beb30 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -1121,6 +1121,7 @@ def _get_statistics(statistics = None, force_download = True): statistics = "runpod" except Exception: pass + # Fallback to env-key detection if statistics is None: if "\nKAGGLE_" in keynames: @@ -1168,42 +1169,43 @@ def _get_statistics(statistics = None, force_download = True): statistics = try_vllm_check() except: statistics = "other" - if statistics is not None: - import tempfile - from huggingface_hub import snapshot_download - from unsloth_zoo.rl_environments import execute_with_time_limit + + if statistics is not None: + import tempfile + from huggingface_hub import snapshot_download + from unsloth_zoo.rl_environments import execute_with_time_limit - if has_internet(): + if has_internet(): - def stats_check(): - with tempfile.TemporaryDirectory( - ignore_cleanup_errors = True - ) as f: - snapshot_download( - f"unslothai/{statistics}", - force_download = True, - cache_dir = f, - local_dir = f, - ) - - time_limited_stats_check = execute_with_time_limit(120)(stats_check) - try: - time_limited_stats_check() - except TimeoutError: - raise TimeoutError( - "Unsloth: HuggingFace seems to be down after trying for 120 seconds :(\n" - "Check https://status.huggingface.co/ for more details.\n" - "As a temporary measure, use modelscope with the same model name ie:\n" - "```\n" - "pip install modelscope\n" - "import os; os.environ['UNSLOTH_USE_MODELSCOPE'] = '1'\n" - "from unsloth import FastLanguageModel\n" - "model = FastLanguageModel.from_pretrained('unsloth/gpt-oss-20b')\n" - "```" + def stats_check(): + with tempfile.TemporaryDirectory( + ignore_cleanup_errors = True + ) as f: + snapshot_download( + f"unslothai/{statistics}", + force_download = True, + cache_dir = f, + local_dir = f, ) - except: - # Try no time limit check - stats_check() + + time_limited_stats_check = execute_with_time_limit(120)(stats_check) + try: + time_limited_stats_check() + except TimeoutError: + raise TimeoutError( + "Unsloth: HuggingFace seems to be down after trying for 120 seconds :(\n" + "Check https://status.huggingface.co/ for more details.\n" + "As a temporary measure, use modelscope with the same model name ie:\n" + "```\n" + "pip install modelscope\n" + "import os; os.environ['UNSLOTH_USE_MODELSCOPE'] = '1'\n" + "from unsloth import FastLanguageModel\n" + "model = FastLanguageModel.from_pretrained('unsloth/gpt-oss-20b')\n" + "```" + ) + except: + # Try no time limit check + stats_check() def get_statistics(local_files_only = False): From e7d68f3e5788d21d5afaac182099716c9b5e248e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 00:04:59 +0000 Subject: [PATCH 4/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- unsloth/models/_utils.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index 9bf02beb30..701e6f633c 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -1121,7 +1121,7 @@ def _get_statistics(statistics = None, force_download = True): statistics = "runpod" except Exception: pass - + # Fallback to env-key detection if statistics is None: if "\nKAGGLE_" in keynames: @@ -1169,7 +1169,7 @@ def _get_statistics(statistics = None, force_download = True): statistics = try_vllm_check() except: statistics = "other" - + if statistics is not None: import tempfile from huggingface_hub import snapshot_download @@ -1178,9 +1178,7 @@ def _get_statistics(statistics = None, force_download = True): if has_internet(): def stats_check(): - with tempfile.TemporaryDirectory( - ignore_cleanup_errors = True - ) as f: + with tempfile.TemporaryDirectory(ignore_cleanup_errors = True) as f: snapshot_download( f"unslothai/{statistics}", force_download = True, From 84701c55ffa7437d11d0e32c5d7a6e77681862c4 Mon Sep 17 00:00:00 2001 From: Rachel Li Date: Thu, 8 Jan 2026 19:20:24 -0500 Subject: [PATCH 5/7] Fix telemetry ping regression for explicit statistics Fixed Codex regression: keep snapshot_download pings for explicit statistics values; detection only runs when statistics is None. Also replaced bare except. --- unsloth/models/_utils.py | 62 ++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index 701e6f633c..0cb6c8975e 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -1170,40 +1170,40 @@ def _get_statistics(statistics = None, force_download = True): except: statistics = "other" - if statistics is not None: - import tempfile - from huggingface_hub import snapshot_download - from unsloth_zoo.rl_environments import execute_with_time_limit + if statistics is not None: + import tempfile + from huggingface_hub import snapshot_download + from unsloth_zoo.rl_environments import execute_with_time_limit - if has_internet(): + if has_internet(): - def stats_check(): - with tempfile.TemporaryDirectory(ignore_cleanup_errors = True) as f: - snapshot_download( - f"unslothai/{statistics}", - force_download = True, - cache_dir = f, - local_dir = f, - ) - - time_limited_stats_check = execute_with_time_limit(120)(stats_check) - try: - time_limited_stats_check() - except TimeoutError: - raise TimeoutError( - "Unsloth: HuggingFace seems to be down after trying for 120 seconds :(\n" - "Check https://status.huggingface.co/ for more details.\n" - "As a temporary measure, use modelscope with the same model name ie:\n" - "```\n" - "pip install modelscope\n" - "import os; os.environ['UNSLOTH_USE_MODELSCOPE'] = '1'\n" - "from unsloth import FastLanguageModel\n" - "model = FastLanguageModel.from_pretrained('unsloth/gpt-oss-20b')\n" - "```" + def stats_check(): + with tempfile.TemporaryDirectory(ignore_cleanup_errors = True) as f: + snapshot_download( + f"unslothai/{statistics}", + force_download = True, + cache_dir = f, + local_dir = f, ) - except: - # Try no time limit check - stats_check() + + time_limited_stats_check = execute_with_time_limit(120)(stats_check) + try: + time_limited_stats_check() + except TimeoutError: + raise TimeoutError( + "Unsloth: HuggingFace seems to be down after trying for 120 seconds :(\n" + "Check https://status.huggingface.co/ for more details.\n" + "As a temporary measure, use modelscope with the same model name ie:\n" + "```\n" + "pip install modelscope\n" + "import os; os.environ['UNSLOTH_USE_MODELSCOPE'] = '1'\n" + "from unsloth import FastLanguageModel\n" + "model = FastLanguageModel.from_pretrained('unsloth/gpt-oss-20b')\n" + "```" + ) + except Exception: + # Try no time limit check + stats_check() def get_statistics(local_files_only = False): From 1193c9f5268f33123054a58c8baf699bf2597a80 Mon Sep 17 00:00:00 2001 From: Rachel Li Date: Thu, 8 Jan 2026 19:32:33 -0500 Subject: [PATCH 6/7] Fix Kaggle telemetry detection & address review feedback - Fix Kaggle misclassification by prioritizing filesystem markers over env vars - Preserve telemetry pings when statistics is explicitly provided - Replace bare except with except Exception - Minor cleanup based on automated review feedback --- unsloth/models/_utils.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index 0cb6c8975e..77c8da2576 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -1106,9 +1106,7 @@ def _get_statistics(statistics = None, force_download = True): global USE_MODELSCOPE USE_MODELSCOPE = os.environ.get("UNSLOTH_USE_MODELSCOPE", "0") == "1" - if statistics is not None: - pass - else: + if statistics is None: # Prefer filesystem markers (harder to misidentify) before env-key matching try: from pathlib import Path @@ -1150,7 +1148,6 @@ def _get_statistics(statistics = None, force_download = True): "/sys/class/dmi/id/chassis_asset_tag", "/sys/class/dmi/id/sys_vendor", ) - from pathlib import Path for vendor_file in vendor_files: path = Path(vendor_file) @@ -1163,11 +1160,10 @@ def _get_statistics(statistics = None, force_download = True): elif "google" in file_content: return "gcp" return "other" - - pass + try: statistics = try_vllm_check() - except: + except Exception: statistics = "other" if statistics is not None: From 3ce1060dd162cc6a1451e57ae129e384343878e0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 00:33:00 +0000 Subject: [PATCH 7/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- unsloth/models/_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index 77c8da2576..b0ad0a3082 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -1160,7 +1160,7 @@ def _get_statistics(statistics = None, force_download = True): elif "google" in file_content: return "gcp" return "other" - + try: statistics = try_vllm_check() except Exception: