From e594c38f3f9ae9bfb9fb69c0d59d966939fef2cd Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Wed, 6 May 2026 07:11:27 +0000 Subject: [PATCH] Fix circular import in trainer.py after _gpu_init refactor The MLX-aware unsloth/__init__.py loads the GPU surface via "from ._gpu_init import *" at line 127. _gpu_init.py:332 then runs "from .trainer import *", and trainer.py:26 was doing "from . import is_bfloat16_supported". That last import asks for the symbol on the `unsloth` package namespace, but `unsloth/__init__.py` is paused at line 127 and the star export from _gpu_init has not yet propagated. Result on a fresh editable install (./install.sh --local): ImportError: cannot import name 'is_bfloat16_supported' from partially initialized module 'unsloth' (most likely due to a circular import) (.../unsloth/__init__.py) PyPI 2026.5.2 is unaffected because that wheel ships the older inline __init__.py which defines is_bfloat16_supported before "from .trainer import *" runs. Fix: import directly from the concrete _utils module, matching the pattern already in models/loader.py and models/llama.py. This bypasses the partially-initialized unsloth namespace and resolves cleanly via unsloth.models._utils, which has already been fully loaded by the preceding "from .models import *" in _gpu_init.py:327. Verified end-to-end: ./install.sh --local on Linux+CUDA imports unsloth cleanly, FastLanguageModel.from_pretrained loads, 10-step LoRA training on Llama-3.2-1B runs (loss 1.76, 5.85 samples/s on B200), post-train generation works. --- unsloth/trainer.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/unsloth/trainer.py b/unsloth/trainer.py index eea985e958..d26389424c 100644 --- a/unsloth/trainer.py +++ b/unsloth/trainer.py @@ -23,7 +23,12 @@ from functools import wraps import trl import inspect from trl import SFTTrainer -from . import is_bfloat16_supported +# Import via the concrete _utils module instead of the partially-initialized +# `unsloth` namespace. The MLX-aware `unsloth/__init__.py` loads the GPU +# surface via `from ._gpu_init import *`, which transitively triggers +# `from .trainer import *` BEFORE the star export has propagated back to +# `unsloth`, so `from . import is_bfloat16_supported` raises at import time. +from .models._utils import is_bfloat16_supported from unsloth.utils import ( configure_padding_free, configure_sample_packing,