unsloth/tests
Daniel Han f44379d9e8
Clear ALLOW_BITSANDBYTES when the bitsandbytes native kernels are not real (#7578)
* Clear ALLOW_BITSANDBYTES when the bitsandbytes native kernels are not real

From bitsandbytes 0.46 a wheel whose native library never loaded still imports and
resolves every ctypes handle: BNBNativeLibrary.__getattr__ returns a throw_on_call
closure, and a dead library is replaced wholesale by ErrorHandlerMockBNBNativeLibrary,
which does the same for every name. Nothing raises while kernels/utils.py binds them
at module scope, so device_type.py's guarded import sees a healthy wheel,
ALLOW_BITSANDBYTES stays true, loader.py forwards the default load_in_4bit=True and
the run dies inside a kernel instead of degrading to 16bit.

Probe the handles the kernels actually bind and clear the flags when they are not
native. A real handle is a ctypes function pointer and carries restype; a deferred
failure is a Python function and does not.

Scoped to the capability flags on purpose. The module stays bound and get_ptr keeps
pointing at bitsandbytes, because these shapes import perfectly well and treating
them as absent would disable a wheel whose Python side works - a CPU-only install is
exactly that shape.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Only clear the flags when the native library is dead, not partially exporting

ALLOW_BITSANDBYTES gates 8bit as well as 4bit - loader.py:505-510 clears both - so
failing the check on one missing 4bit symbol would silently downgrade an otherwise
valid LLM.int8 request to 16bit. A library that exports some of these handles is
alive; only one where none of them is a ctypes function pointer is dead, which is
the CPU-only and ErrorHandlerMockBNBNativeLibrary case this exists for.

A genuinely missing symbol raises where kernels/utils.py binds it, so it is a crash
no capability flag can rescue and not something to trade 8bit for.

* Gate the bitsandbytes ctypes binds on the same verdict as the flags

Clearing ALLOW_BITSANDBYTES is not enough on its own. kernels/utils.py guarded
the bnb.functional.lib.* binds on `bnb is None` alone, so an importable but dead
wheel still reached them at module scope: bitsandbytes 0.45.5, the floor in
pyproject.toml, sets functional.lib = None when the native library fails to load,
and None.cdequantize_blockwise_fp32 raises right there. That kills import unsloth
outright instead of degrading to 16bit, which is the fallback the cleared flag
exists to reach.

Reuse native_kernels_ready so the bind path and the flag path agree, and take the
_bnb_required branch when they say the library is dead. Touches only the guard
expression, not the binds themselves.

* Tighten the comments on the bitsandbytes kernel readiness probe

* Require every probed handle, and license the module Apache like the rest of unsloth

The readiness verdict now gates the module-scope ctypes binds as well as the flags,
so "at least one handle is native" is no longer the right question. A library that
resolves one symbol and not another passed the probe and then raised AttributeError
at the bind the probe exists to prevent. Require all of them.

That costs 8bit in the partial case, since ALLOW_BITSANDBYTES gates both, but a wheel
missing a symbol is a shape no flag can make safe and refusing it beats crashing on
it. Flipped the test that encoded the old behaviour and added the more realistic
shape: the library loaded, one symbol is still a deferred-failure closure.

LICENSE:190 assigns files under unsloth/* to Apache 2.0, and 87 of the 90 modules
there carry that header, so use it here rather than AGPL.

* State the all-handles rule once instead of three times

---------

Co-authored-by: danielhanchen <unslothai@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-28 21:17:33 -07:00
..
fast_inference test: fast end-to-end GRPO fast_inference vLLM rollout test (#7136) 2026-07-26 00:22:48 -07:00
notebooks Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
python Clear ALLOW_BITSANDBYTES when the bitsandbytes native kernels are not real (#7578) 2026-07-28 21:17:33 -07:00
qlora Formatting: ruff line-length 100, kwarg-spacing passes, drop blank after short local imports (#6079) 2026-06-08 04:24:13 -07:00
saving fix: enable XPU support and update hardcoded CUDA selections for tests (#7401) 2026-07-28 15:38:57 -07:00
security tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
sh Installer: wrap install.sh in a function so a piped install cannot report curl (56) (#7548) 2026-07-28 21:16:31 -07:00
studio amd: require bitsandbytes>=0.50.0 in the amd extra (fixes ROCm 4-bit NaNs) (#7535) 2026-07-28 18:12:26 -07:00
studio_setup_ps1 Make Visual Studio + CMake optional on Windows (prebuilt llama.cpp needs no build tools) (#6499) 2026-06-22 01:11:09 -07:00
utils fix: enable XPU support and update hardcoded CUDA selections for tests (#7401) 2026-07-28 15:38:57 -07:00
version_compat test(version-compat): keep GRPO fake-run logits finite on CPU (#7247) 2026-07-19 04:54:17 -07:00
vllm_compat Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
__init__.py Qwen 3, Bug Fixes (#2445) 2025-04-30 22:38:39 -07:00
_zoo_aggressive_cuda_spoof.py Import bitsandbytes before the hardware spoof rewrites torch (#7471) 2026-07-26 05:46:12 -07:00
_zoo_rocm_spoof.py AMD: CI coverage for recent fixes, plus three wrong gfx ids (#7431) 2026-07-25 18:58:02 -05:00
conftest.py Tests: import bitsandbytes before the GPU-free harness spoofs CUDA (#7582) 2026-07-28 18:52:25 -07:00
run_all.sh AMD: CI coverage for recent fixes, plus three wrong gfx ids (#7431) 2026-07-25 18:58:02 -05:00
test_attention_implementation.py fix(gpt-oss): prefer flex attention over sdpa (#5701) 2026-05-22 08:38:38 -07:00
test_attn_impl_honor_explicit.py Honor an explicit sdpa or flex_attention request when flash is disabled (#6847) 2026-07-06 05:45:45 -07:00
test_bad_mappings_redirect.py Keep the newer-mapper probe from replacing the installed FP8 mappers (#7478) 2026-07-27 04:21:27 -07:00
test_callback_signature_drift.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_cli_export_unpacking.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_compressed_export_gpu_release.py studio: shard export checkpoint loads across all visible GPUs (#7215) 2026-07-26 04:16:36 -07:00
test_enforce_kwargs_spacing.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_fa2_fast_generate_bypass.py Bypass fast_generate for flash_attention_2 models (StaticCache + FA2 produces gibberish) (#7429) 2026-07-26 23:07:33 -07:00
test_fast_gemv_dispatch.py Fix fast inference crash on compressed-tensors FP8 models (#7025) 2026-07-09 04:10:59 -07:00
test_fast_generate_slow_guard.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_finetune_last_n_layers.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_fp8_device_context.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_fp8_restore_dropped_scale.py Restore dropped FP8 weight_scale_inv tensors on load (#6978) 2026-07-09 06:44:44 -07:00
test_fp8_tiny_e8m0.py fix: enable XPU support and update hardcoded CUDA selections for tests (#7401) 2026-07-28 15:38:57 -07:00
test_fused_ce_not_return_dict_logits.py fix: use EMPTY_LOGITS on the fused-CE not-return_dict path (#2068) (#6482) 2026-06-23 01:26:55 -07:00
test_gemma4_chat_template.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_gemma_2b_mapper_key.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_generate_kwarg_gate.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_get_model_name.py Keep the newer-mapper probe from replacing the installed FP8 mappers (#7478) 2026-07-27 04:21:27 -07:00
test_gradient_checkpointing_restore.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_ignored_tokenizer_casing.py Match IGNORED_TOKENIZER_NAMES case-insensitively (#6620) 2026-06-23 19:40:50 -03:00
test_import_fixes_drift.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_installer_skip_autostart.py fix(install): fail non-tauri installer errors (#7123) 2026-07-15 04:37:03 -07:00
test_installer_unsloth_version.py Installer: report the installed Unsloth version (#7265) 2026-07-21 03:48:49 -07:00
test_loader_glob_skip.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_missing_torchvision_vlm.py Fix misleading 'only for image models' error for Qwen3-VL when torchvision is missing (#6525) 2026-06-23 01:28:09 -07:00
test_model_registry.py fix(registry): don't register deepseek models at import time (#7227) 2026-07-19 03:37:23 -07:00
test_moe_lora_targets.py Scope MoE expert LoRA detection to actual MLP projection targets (#6849) 2026-07-06 05:45:06 -07:00
test_multi_image_grpo_chunking.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_new_mapper_fetched_fp8.py Cover the FP8 row-scaling path in the newer-mapper probe (#7516) 2026-07-28 16:13:00 -07:00
test_new_mapper_no_global_leak.py Keep the newer-mapper probe from replacing the installed FP8 mappers (#7478) 2026-07-27 04:21:27 -07:00
test_nvfp4_quant_load.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_offline_loading_helpers.py Fix offline checkpoint load/export: "tokenizer is weirdly not loaded" (#6554) 2026-06-25 23:16:53 -07:00
test_offload_embedding_hooks.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_offload_tied_guard.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_peft_tensor_parallel_compat.py fix: keep LoRA reloads working with PEFT 0.19 (#6748) 2026-06-30 20:26:57 +01:00
test_peft_weight_converter_compat.py Formatting: ruff line-length 100, kwarg-spacing passes, drop blank after short local imports (#6079) 2026-06-08 04:24:13 -07:00
test_prefetch_snapshot_scope.py Auto Xet to HTTP download fallback in from_pretrained; share Studio's fallback via unsloth_zoo (#6638) 2026-07-06 05:13:25 -07:00
test_pretrain_compile_reset.py Add regression tests for the stray-forward compile-cache reset (#6569) 2026-06-22 07:22:47 -07:00
test_public_api_surface.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_raw_text.py fix(dataprep): don't emit a degenerate chunk for empty text (#7183) 2026-07-23 00:56:51 -07:00
test_raw_text_json_loading.py Parse a .json dataset file as one JSON document instead of line-by-line (#7422) 2026-07-28 21:40:43 -03:00
test_resolve_model_class.py Formatting: ruff line-length 100, kwarg-spacing passes, drop blank after short local imports (#6079) 2026-06-08 04:24:13 -07:00
test_runtime_text_encoding.py Pin utf-8 on shipping-code text I/O instead of the operator locale (#7486) 2026-07-27 02:14:20 -07:00
test_source_read_encoding.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_studio_install_workspace_guard.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_studio_root_resilience.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_studio_shutdown_thread_wait.py Replace standalone Studio wording with Unsloth (#7221) 2026-07-19 00:47:04 -07:00
test_synthetic_chunk_data.py Fix SyntheticDataKit.chunk_data emitting chunks over max_tokens (#7073) 2026-07-12 05:06:11 -07:00
test_tool_mask_zoo_compat.py tests: read checked-in files as UTF-8 instead of the platform default (#7438) 2026-07-26 23:31:56 -07:00
test_uma_safetensors_load.py Faster safetensors weight loading on unified-memory (integrated) GPUs (#5988) 2026-07-22 05:20:59 -07:00
test_uninitialized_position_ids.py Load DeepSeek-OCR and other VLMs that register AutoModel in auto_map (#6421) 2026-06-18 07:03:43 -07:00
test_video_path_validation.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_vllm_broken_detection.py Fix fast_inference crash on ABI-broken vLLM: probe compiled extensions, not just import vllm (#6621) 2026-06-26 22:43:36 -07:00
test_windows_rocm_bnb_version.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00