From 00cbc82513a3cbbd7cf206fcaa9a804dad3cfbbe Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Sun, 24 May 2026 08:11:37 +0000 Subject: [PATCH] smoke_test.py: import unsloth before unsloth_zoo / transformers / trl / peft unsloth_zoo/__init__.py guards against being imported standalone: if "UNSLOTH_IS_PRESENT" not in os.environ: raise ImportError("Please install Unsloth via `pip install unsloth`!") The env var is set by unsloth/__init__.py at import time, so importing unsloth must happen first. The old check_imports() imported xformers, bnb, transformers, trl, peft, then unsloth_zoo -- which fired the guard because unsloth had not been imported yet. Reorder check_imports() to import unsloth (and unsloth_zoo) first, then the rest. check_unsloth_import() becomes a thin re-import to keep the "FastLanguageModel reachable" banner in the output. Same fix the unsloth README has been recommending for years: "import unsloth at the top of your file, before transformers/trl/peft." --- docker/smoke_test.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/docker/smoke_test.py b/docker/smoke_test.py index 9f46d5546e..a2ca70225f 100644 --- a/docker/smoke_test.py +++ b/docker/smoke_test.py @@ -52,6 +52,17 @@ def check_imports() -> None: import triton print(f"triton {triton.__version__}") + # Import order matters: unsloth must be imported BEFORE transformers / trl / + # peft so its monkey-patches land, and BEFORE unsloth_zoo so the latter sees + # the UNSLOTH_IS_PRESENT env marker that unsloth/__init__.py sets. Doing it + # otherwise trips an explicit guard in unsloth_zoo/__init__.py with + # "ImportError: Please install Unsloth via `pip install unsloth`!". + import unsloth + + print(f"unsloth {unsloth.__version__}") + import unsloth_zoo + + print(f"unsloth_zoo {unsloth_zoo.__version__}") import xformers print(f"xformers {xformers.__version__}") @@ -67,16 +78,12 @@ def check_imports() -> None: import peft print(f"peft {peft.__version__}") - import unsloth_zoo - - print(f"unsloth_zoo {unsloth_zoo.__version__}") def check_unsloth_import() -> None: - banner("unsloth import") - # Unsloth must be imported BEFORE transformers in real training scripts, - # but here we already imported transformers above for the version check. - # That's fine for this smoke -- we're not training Unsloth-patched models yet. + banner("unsloth FastLanguageModel reachable") + # unsloth itself was already imported in check_imports() above (it has to be + # imported first for unsloth_zoo to load). This re-import is a no-op. import unsloth from unsloth import FastLanguageModel