Files
unslothai--unsloth/studio/backend/utils/hf_xet_fallback.py
T
wehub-resource-sync e93507a09c
Lockfile supply-chain audit / lockfile supply-chain audit (push) Has been cancelled
Windows Studio GGUF CI / GPU prebuilt resolves without Visual Studio (push) Has been cancelled
Windows Studio GGUF CI / setup.ps1 unit tests (VS 2026 / CMake guard) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2022) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-2025-vs2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-latest) (push) Has been cancelled
Windows Studio Update CI / Studio Updating Tests (push) Has been cancelled
Wheel CI / Wheel build + content sanity + import smoke (push) Has been cancelled
Lint CI / Source lint (Python + shell + YAML + JSON + safety nets) (push) Has been cancelled
MLX CI on Mac M1 / dispatch (push) Has been cancelled
Security audit / advisory audit (pip + npm + cargo) (push) Has been cancelled
Security audit / pip scan-packages :: extras (push) Has been cancelled
Security audit / pip scan-packages :: studio (push) Has been cancelled
Security audit / pip scan-packages :: hf-stack (push) Has been cancelled
Security audit / npm scan-packages (Studio frontend tarballs) (push) Has been cancelled
Security audit / workflow-trigger lint (pull_request_target / cache-poisoning) (push) Has been cancelled
Security audit / pytest tests/security (push) Has been cancelled
Security audit / npm provenance + new install-script diff (push) Has been cancelled
Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Backend CI / (Python 3.10) (push) Has been cancelled
Backend CI / (Python 3.11) (push) Has been cancelled
Backend CI / (Python 3.12) (push) Has been cancelled
Backend CI / (Python 3.13) (push) Has been cancelled
Backend CI / Repo tests (CPU) (push) Has been cancelled
Frontend CI / Frontend build + bundle sanity (push) Has been cancelled
Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Mac Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Mac Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-14) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15-intel) (push) Has been cancelled
Mac Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26-intel) (push) Has been cancelled
Mac Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Tauri CI / Tauri Linux debug build (no codesign) (push) Has been cancelled
Mac Studio Update CI / Studio Updating Tests (push) Has been cancelled
Studio UI CI / Chat UI Tests (push) Has been cancelled
Windows Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Windows Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Update CI / Studio Updating Tests (push) Has been cancelled
Core / Core (HF=default + TRL=default) (push) Has been cancelled
Core / Core (HF=4.57.6 + TRL<1) (push) Has been cancelled
Core / Core (HF=latest + TRL=latest) (push) Has been cancelled
Core / llama.cpp build + smoke (push) Has been cancelled
Windows Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Windows Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Windows Studio GGUF CI / JSON, images (push) Has been cancelled
Windows Studio GGUF CI / Studio install + inference without Visual Studio (push) Has been cancelled
Studio export capability / capability (macos-latest) (push) Has been cancelled
Studio export capability / capability (ubuntu-latest) (push) Has been cancelled
Studio export capability / capability (windows-latest) (push) Has been cancelled
Cross-platform parity / parity (macos-latest) (push) Has been cancelled
Cross-platform parity / parity (windows-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Studio load-orchestrator CI / test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:59:56 +08:00

319 lines
12 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
"""Studio shim over the shared ``unsloth_zoo.hf_xet_fallback`` Xet -> HTTP stall fallback.
Re-exports the shared API and injects Studio's marker-aware cache purge
(``prepare_cache_for_transport``) so the download manager keeps its ``.transport``
marker semantics on the HTTP retry.
Import discipline: ``unsloth_zoo``'s ``__init__`` eagerly imports ``transformers``. The workers
import this shim at startup (to decide the per-worker Xet env flip) *before* activating the model's
``transformers`` sidecar. Activation only prepends the sidecar to ``sys.path``, so a ``transformers``
already cached in ``sys.modules`` (via an eager ``unsloth_zoo`` import here) wins -- pinning the
default 4.57.x and regressing Qwen3.5 / GLM-4.7 / gemma-4 training with
``Tokenizer class TokenizersBackend does not exist``. So the shared backend is loaded **lazily**
(``_load_shared``), only on first use of a heavy download helper, i.e. after the sidecar is active.
``child_should_disable_xet`` and the ``DEFAULT_*`` constants are defined locally so importing them
never triggers the heavy load.
"""
from __future__ import annotations
import threading
from typing import Any, Callable, Optional
# Defaults mirror unsloth_zoo.hf_xet_fallback; plain literals so they resolve (including as
# default args below) without importing unsloth_zoo/transformers.
DEFAULT_GRACE_PERIOD = 10.0
DEFAULT_HEARTBEAT_INTERVAL = 30.0
DEFAULT_STALL_TIMEOUT = 180.0
# --- lazy shared-backend loader ----------------------------------------------------------------
_shared: Any = None
_shared_available: Optional[bool] = None # None = not yet attempted
_shared_import_error: Optional[BaseException] = None
_load_lock = threading.Lock()
def _load_shared() -> bool:
"""Import ``unsloth_zoo.hf_xet_fallback`` on demand; return True if available. Deferred so
importing this module at worker startup does not pull transformers in before the sidecar is
activated. Degrades (returns False) rather than crashing when unsloth_zoo is unavailable."""
global _shared, _shared_available, _shared_import_error
if _shared_available is not None:
return _shared_available
with _load_lock:
if _shared_available is not None:
return _shared_available
try:
import unsloth_zoo.hf_xet_fallback as shared
_shared = shared
_shared_available = True
_shared_import_error = None
return True
except Exception as exc: # noqa: BLE001 - any import failure must degrade, not crash
# unsloth_zoo's __init__ runs torch/GPU detection, which raises on a torch-less/GPU-less
# host. The download helper needs none of it, so retry via UNSLOTH_ZOO_DISABLE_GPU_INIT.
_shared_import_error = exc
import os as _os
_prev_gpu_init = _os.environ.get("UNSLOTH_ZOO_DISABLE_GPU_INIT")
_os.environ["UNSLOTH_ZOO_DISABLE_GPU_INIT"] = "1"
try:
import unsloth_zoo.hf_xet_fallback as shared
_shared = shared
_shared_available = True
_shared_import_error = None
return True
except Exception as exc2: # noqa: BLE001 - degrade so Studio still boots with plain HF
_shared_import_error = exc2
_shared_available = False
import logging as _logging
_logging.getLogger(__name__).warning(
"unsloth_zoo.hf_xet_fallback unavailable (%s); the Xet stall watchdog is "
"disabled. Install/upgrade unsloth_zoo (and its torch dependency) to "
"re-enable automatic Xet -> HTTP download recovery.",
_shared_import_error,
)
return False
finally:
if _prev_gpu_init is None:
_os.environ.pop("UNSLOTH_ZOO_DISABLE_GPU_INIT", None)
else:
_os.environ["UNSLOTH_ZOO_DISABLE_GPU_INIT"] = _prev_gpu_init
def child_should_disable_xet(config: dict) -> bool:
"""Single source of truth for the per-worker Xet env flip (mirrors
``unsloth_zoo.hf_xet_fallback.child_should_disable_xet``). Deliberately lightweight: importing or
calling it must NOT pull in unsloth_zoo/transformers, so the worker can decide before activating
the transformers sidecar (see the module docstring)."""
return bool(config.get("disable_xet"))
# --- degraded stubs (used only when unsloth_zoo is unavailable) -------------------------------
class _DegradedDownloadStallError(RuntimeError):
"""Stub mirror so callers' ``except`` clauses resolve; never raised in degraded mode."""
def _degraded_get_hf_download_state(*args: Any, **kwargs: Any) -> None:
return None # unmeasurable -> the (absent) watchdog never fires
def _degraded_start_watchdog(
*,
on_heartbeat: "Optional[Callable[[str], None]]" = None,
interval: float = DEFAULT_HEARTBEAT_INTERVAL,
xet_disabled: bool = False,
**kwargs: Any,
) -> "threading.Event":
# No stall detection, but keep emitting heartbeats so the orchestrator's inactivity deadline
# is not tripped during a long download.
stop = threading.Event()
if on_heartbeat is None:
return stop
transport = "https" if xet_disabled else "xet"
def _beat() -> None:
while not stop.wait(interval):
try:
on_heartbeat(f"Downloading ({transport} transport)...")
except Exception:
pass
threading.Thread(
target = _beat,
daemon = True,
name = "hf-xet-degraded-heartbeat",
).start()
return stop
def _degraded_cancelled(cancel_event: "Optional[threading.Event]") -> bool:
return cancel_event is not None and cancel_event.is_set()
def _degraded_hf_hub_download_with_xet_fallback(
repo_id: str,
filename: str,
token: Optional[str],
*,
repo_type: str = "model",
revision: Optional[str] = None,
cache_dir: Optional[str] = None,
force_download: bool = False,
cancel_event: "Optional[threading.Event]" = None,
**_ignored: Any,
) -> str:
# Keep the cancellation contract: do not start or return a download once cancelled.
if _degraded_cancelled(cancel_event):
raise RuntimeError("Cancelled")
from huggingface_hub import hf_hub_download
path = hf_hub_download(
repo_id = repo_id,
filename = filename,
token = token,
repo_type = repo_type,
revision = revision,
cache_dir = cache_dir,
force_download = force_download,
)
if _degraded_cancelled(cancel_event):
raise RuntimeError("Cancelled")
return path
def _degraded_snapshot_download_with_xet_fallback(
repo_id: str,
*,
revision: Optional[str] = None,
token: Optional[str] = None,
repo_type: str = "model",
cache_dir: Optional[str] = None,
allow_patterns: Optional[Any] = None,
ignore_patterns: Optional[Any] = None,
force_download: bool = False,
cancel_event: "Optional[threading.Event]" = None,
**_ignored: Any,
) -> str:
if _degraded_cancelled(cancel_event):
raise RuntimeError("Cancelled")
from huggingface_hub import snapshot_download
path = snapshot_download(
repo_id = repo_id,
repo_type = repo_type,
revision = revision,
token = token,
cache_dir = cache_dir,
allow_patterns = allow_patterns,
ignore_patterns = ignore_patterns,
force_download = force_download,
)
if _degraded_cancelled(cancel_event):
raise RuntimeError("Cancelled")
return path
# --- lazy attribute access for the heavy shared API -------------------------------------------
# ``DownloadStallError`` (class identity matters for ``except``), ``start_watchdog`` and
# ``get_hf_download_state`` come from the shared backend when available, else the degraded stubs.
# Resolved via PEP 562 ``__getattr__`` so ``from utils.hf_xet_fallback import X`` triggers the load
# only for these heavy names, not for ``child_should_disable_xet`` / ``DEFAULT_*``.
_DEGRADED_ATTRS = {
"DownloadStallError": _DegradedDownloadStallError,
"start_watchdog": _degraded_start_watchdog,
"get_hf_download_state": _degraded_get_hf_download_state,
}
# Annotation-only declarations for the three names above: they bind NO value, so lookup still misses
# and PEP 562 ``__getattr__`` resolves them lazily -- but ruff/pyflakes see them as defined, so listing
# them in ``__all__`` does not trip F822 (while F822 still catches a real typo elsewhere in the list).
DownloadStallError: type
start_watchdog: Any
get_hf_download_state: Any
def __getattr__(name: str) -> Any:
if name in _DEGRADED_ATTRS:
if _load_shared():
return getattr(_shared, name)
return _DEGRADED_ATTRS[name]
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
# Indirection seam the public wrappers call (and tests monkeypatch): lazy-load the shared backend,
# then dispatch to it or the degraded stub. The ``_shared_*`` names preserve the pre-refactor contract.
def _shared_hf_hub_download_with_xet_fallback(*args: Any, **kwargs: Any) -> str:
impl = (
_shared.hf_hub_download_with_xet_fallback
if _load_shared()
else _degraded_hf_hub_download_with_xet_fallback
)
return impl(*args, **kwargs)
def _shared_snapshot_download_with_xet_fallback(*args: Any, **kwargs: Any) -> str:
impl = (
_shared.snapshot_download_with_xet_fallback
if _load_shared()
else _degraded_snapshot_download_with_xet_fallback
)
return impl(*args, **kwargs)
__all__ = [
"DEFAULT_GRACE_PERIOD",
"DEFAULT_HEARTBEAT_INTERVAL",
"DEFAULT_STALL_TIMEOUT",
"DownloadStallError",
"child_should_disable_xet",
"get_hf_download_state",
"start_watchdog",
"hf_hub_download_with_xet_fallback",
"snapshot_download_with_xet_fallback",
]
def _studio_prepare_for_http(repo_type: str, repo_id: str) -> None:
"""Studio's marker-aware purge before an HTTP resume, keeping the download manager's ``.transport``
accounting consistent (vs unsloth_zoo's generic default). Guarded: a purge failure is logged,
not fatal to the retry."""
try:
from hub.utils.download_registry import prepare_cache_for_transport
prepare_cache_for_transport(repo_type, repo_id, "http")
except Exception as exc:
try:
from loggers import get_logger
get_logger(__name__).debug(
"Studio prepare_cache_for_transport failed for %s: %s", repo_id, exc
)
except ModuleNotFoundError as logger_exc:
if logger_exc.name != "loggers":
raise
def hf_hub_download_with_xet_fallback(
repo_id: str,
filename: str,
token: Optional[str],
*,
cancel_event: Optional[threading.Event] = None,
repo_type: str = "model",
revision: Optional[str] = None,
stall_timeout: float = DEFAULT_STALL_TIMEOUT,
interval: float = DEFAULT_HEARTBEAT_INTERVAL,
grace_period: float = DEFAULT_GRACE_PERIOD,
on_status: Optional[Callable[[str], None]] = None,
force_download: bool = False,
) -> str:
"""Single-file download via the shared fallback with Studio's marker-aware HTTP-retry prep.
``force_download`` re-fetches a newer blob over a cached one (Studio's model-update path)."""
return _shared_hf_hub_download_with_xet_fallback(
repo_id,
filename,
token,
cancel_event = cancel_event,
repo_type = repo_type,
revision = revision,
stall_timeout = stall_timeout,
interval = interval,
grace_period = grace_period,
on_status = on_status,
force_download = force_download,
prepare_for_http_fn = _studio_prepare_for_http,
)
def snapshot_download_with_xet_fallback(repo_id: str, **kwargs: Any) -> str:
"""Whole-repo download via the shared fallback with Studio's marker-aware HTTP-retry prep."""
kwargs.setdefault("prepare_for_http_fn", _studio_prepare_for_http)
return _shared_snapshot_download_with_xet_fallback(repo_id, **kwargs)