From 1fcb2502cf5c8677ab93ca680132fff0458bf6f2 Mon Sep 17 00:00:00 2001 From: David Solanas Sanz <43669187+DavidSolanas@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:51:31 +0200 Subject: [PATCH] fix: prevent offline freeze by fixing stats retry and forwarding local_files_only (#5016) Fixes #2393. - `_utils.py`: `has_internet()` now respects `HF_HUB_OFFLINE` with truthy variant parsing in addition to `TRANSFORMERS_OFFLINE`. - `_utils.py`: replace uncontrolled `except Exception: stats_check()` retry (which had no time limit and could freeze on Kaggle offline mode) with a logged skip. - `loader.py`: forward `local_files_only` from kwargs into all `AutoConfig.from_pretrained` and `PeftConfig.from_pretrained` probes in `FastLanguageModel.from_pretrained` and `FastModel.from_pretrained`, including the PEFT base-model reload paths. --- unsloth/models/_utils.py | 9 +++++++-- unsloth/models/loader.py | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/unsloth/models/_utils.py b/unsloth/models/_utils.py index 71f7db915c..d0cd4ba028 100644 --- a/unsloth/models/_utils.py +++ b/unsloth/models/_utils.py @@ -1350,6 +1350,11 @@ import socket def has_internet(host = "8.8.8.8", port = 53, timeout = 3): if os.environ.get("TRANSFORMERS_OFFLINE", "0") == "1": return False + + OFFLINE_TRUE = {"1", "true", "yes", "on"} + + if os.environ.get("HF_HUB_OFFLINE", "").strip().lower() in OFFLINE_TRUE: + return False try: socket.setdefaulttimeout(timeout) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -1468,8 +1473,8 @@ def _get_statistics(statistics = None, force_download = True): "```" ) except Exception: - # Try no time limit check - stats_check() + logger.debug("Unsloth: stats_check failed with an exception.") + # Don't retry without a time limit — would freeze offline def get_statistics(local_files_only = False): diff --git a/unsloth/models/loader.py b/unsloth/models/loader.py index df97c5c7df..a66a7c6abc 100644 --- a/unsloth/models/loader.py +++ b/unsloth/models/loader.py @@ -439,12 +439,15 @@ class FastLanguageModel(FastLlamaModel): peft_error = None model_config = None peft_config = None + local_files_only = kwargs.get("local_files_only", False) + try: model_config = AutoConfig.from_pretrained( model_name, token = token, revision = revision, trust_remote_code = trust_remote_code, + local_files_only = local_files_only, ) is_model = True except ImportError: @@ -470,6 +473,7 @@ class FastLanguageModel(FastLlamaModel): token = token, revision = revision, trust_remote_code = trust_remote_code, + local_files_only = local_files_only, ) is_peft = True except ImportError: @@ -566,6 +570,7 @@ class FastLanguageModel(FastLlamaModel): model_name, token = token, trust_remote_code = trust_remote_code, + local_files_only = local_files_only, ) if not was_disabled: @@ -1049,12 +1054,15 @@ class FastModel(FastBaseModel): peft_error = None model_config = None peft_config = None + local_files_only = kwargs.get("local_files_only", False) + try: model_config = AutoConfig.from_pretrained( model_name, token = token, revision = revision, trust_remote_code = trust_remote_code, + local_files_only = local_files_only, ) is_model = True except ImportError: @@ -1080,6 +1088,7 @@ class FastModel(FastBaseModel): token = token, revision = revision, trust_remote_code = trust_remote_code, + local_files_only = local_files_only, ) is_peft = True except ImportError: @@ -1330,6 +1339,7 @@ class FastModel(FastBaseModel): model_name, token = token, trust_remote_code = trust_remote_code, + local_files_only = local_files_only, ) if not was_disabled: