Fix bitsandbytes zombie module breaking test collection on CPU runners (#7580)
* Fix bitsandbytes zombie module breaking test collection A partially failed `import bitsandbytes` leaves the package half-imported: CPython evicts only the parent from sys.modules and keeps every submodule it had already loaded. The next import re-executes __init__ but every `from .x import y` is served from cache, so the submodule attributes are never rebound. The package imports "successfully" while `bnb.functional` is gone. Bind the submodule via `import bitsandbytes.functional as bnb_functional`, which reads sys.modules directly and survives that state, and import bitsandbytes in tests/conftest.py on the real CPU path before torch.cuda.is_available() is mocked, so the half-imported state is never created in the first place. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
f44379d9e8
commit
7b068090b2
2 changed files with 23 additions and 10 deletions
|
|
@ -303,13 +303,19 @@ if DEVICE_TYPE == "cuda":
|
|||
# Try loading bitsandbytes and triton
|
||||
try:
|
||||
import bitsandbytes as bnb
|
||||
|
||||
# Bind the submodule by name: a half-imported bitsandbytes leaves the parent
|
||||
# without a `functional` attribute, which would otherwise be misreported below
|
||||
# as a CUDA linking failure. See unsloth/kernels/utils.py.
|
||||
import bitsandbytes.functional as bnb_functional
|
||||
except:
|
||||
print(
|
||||
"Unsloth: `bitsandbytes` is not installed - 4bit QLoRA unallowed, but 16bit and full finetuning works!"
|
||||
)
|
||||
bnb = None
|
||||
bnb_functional = None
|
||||
try:
|
||||
cdequantize_blockwise_fp32 = bnb.functional.lib.cdequantize_blockwise_fp32
|
||||
cdequantize_blockwise_fp32 = bnb_functional.lib.cdequantize_blockwise_fp32
|
||||
libcuda_dirs()
|
||||
except:
|
||||
if hasattr(os, "geteuid") and os.geteuid() == 0:
|
||||
|
|
@ -351,7 +357,7 @@ if DEVICE_TYPE == "cuda":
|
|||
pass
|
||||
else:
|
||||
from triton.common.build import libcuda_dirs
|
||||
cdequantize_blockwise_fp32 = bnb.functional.lib.cdequantize_blockwise_fp32
|
||||
cdequantize_blockwise_fp32 = bnb_functional.lib.cdequantize_blockwise_fp32
|
||||
libcuda_dirs()
|
||||
except:
|
||||
warnings.warn(
|
||||
|
|
|
|||
|
|
@ -136,11 +136,18 @@ def calculate_settings(
|
|||
HAS_CUDA_STREAM = False
|
||||
try:
|
||||
import bitsandbytes as bnb
|
||||
|
||||
# If an earlier `import bitsandbytes` died inside __init__, CPython evicts only
|
||||
# the parent from sys.modules and keeps its submodules, so this retry re-executes
|
||||
# __init__ without rebinding `bnb.functional`. `import x.y as z` reads sys.modules
|
||||
# directly and survives that, plain attribute access does not.
|
||||
import bitsandbytes.functional as bnb_functional
|
||||
except Exception:
|
||||
# device_type.py already degrades to 16bit/full finetuning when bnb is missing
|
||||
# (e.g. gfx906, whose generic wheel has no kernels). Keep the import working and
|
||||
# fail only if a 4bit path is actually entered.
|
||||
bnb = None
|
||||
bnb_functional = None
|
||||
|
||||
|
||||
def _bnb_required(*args, **kwargs):
|
||||
|
|
@ -153,7 +160,7 @@ def _bnb_required(*args, **kwargs):
|
|||
if bnb is not None:
|
||||
# https://github.com/bitsandbytes-foundation/bitsandbytes/pull/1330/files
|
||||
HAS_CUDA_STREAM = Version(bnb.__version__) > Version("0.43.3")
|
||||
get_ptr = bnb.functional.get_ptr
|
||||
get_ptr = bnb_functional.get_ptr
|
||||
else:
|
||||
get_ptr = _bnb_required
|
||||
|
||||
|
|
@ -263,18 +270,18 @@ if bnb is None or not native_kernels_ready(bnb, DEVICE_TYPE):
|
|||
cgemm_4bit_inference_naive_fp16 = _bnb_required
|
||||
cgemm_4bit_inference_naive_bf16 = _bnb_required
|
||||
else:
|
||||
cdequantize_blockwise_fp32 = bnb.functional.lib.cdequantize_blockwise_fp32
|
||||
cdequantize_blockwise_fp16_nf4 = bnb.functional.lib.cdequantize_blockwise_fp16_nf4
|
||||
cdequantize_blockwise_bf16_nf4 = bnb.functional.lib.cdequantize_blockwise_bf16_nf4
|
||||
cdequantize_blockwise_fp32 = bnb_functional.lib.cdequantize_blockwise_fp32
|
||||
cdequantize_blockwise_fp16_nf4 = bnb_functional.lib.cdequantize_blockwise_fp16_nf4
|
||||
cdequantize_blockwise_bf16_nf4 = bnb_functional.lib.cdequantize_blockwise_bf16_nf4
|
||||
|
||||
if DEVICE_TYPE == "xpu":
|
||||
# https://github.com/bitsandbytes-foundation/bitsandbytes/blob/c3b8de268fdb55a88f92feada23fc811a1e6877a/bitsandbytes/backends/xpu/ops.py#L115
|
||||
# for xpu, inference gemv using above link
|
||||
cgemm_4bit_inference_naive_fp16 = bnb.functional.lib.cgemv_4bit_inference_fp16
|
||||
cgemm_4bit_inference_naive_bf16 = bnb.functional.lib.cgemv_4bit_inference_bf16
|
||||
cgemm_4bit_inference_naive_fp16 = bnb_functional.lib.cgemv_4bit_inference_fp16
|
||||
cgemm_4bit_inference_naive_bf16 = bnb_functional.lib.cgemv_4bit_inference_bf16
|
||||
else:
|
||||
cgemm_4bit_inference_naive_fp16 = bnb.functional.lib.cgemm_4bit_inference_naive_fp16
|
||||
cgemm_4bit_inference_naive_bf16 = bnb.functional.lib.cgemm_4bit_inference_naive_bf16
|
||||
cgemm_4bit_inference_naive_fp16 = bnb_functional.lib.cgemm_4bit_inference_naive_fp16
|
||||
cgemm_4bit_inference_naive_bf16 = bnb_functional.lib.cgemm_4bit_inference_naive_bf16
|
||||
|
||||
|
||||
torch_device_stream = (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue