bitsandbytes 0.50.0__py3-none-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. bitsandbytes/__init__.py +78 -0
  2. bitsandbytes/__main__.py +4 -0
  3. bitsandbytes/_ops.py +510 -0
  4. bitsandbytes/autograd/__init__.py +0 -0
  5. bitsandbytes/autograd/_functions.py +491 -0
  6. bitsandbytes/backends/__init__.py +0 -0
  7. bitsandbytes/backends/cpu/__init__.py +0 -0
  8. bitsandbytes/backends/cpu/ops.py +580 -0
  9. bitsandbytes/backends/cuda/__init__.py +0 -0
  10. bitsandbytes/backends/cuda/ops.py +1199 -0
  11. bitsandbytes/backends/default/__init__.py +0 -0
  12. bitsandbytes/backends/default/ops.py +632 -0
  13. bitsandbytes/backends/hpu/__init__.py +0 -0
  14. bitsandbytes/backends/hpu/ops.py +53 -0
  15. bitsandbytes/backends/mps/__init__.py +0 -0
  16. bitsandbytes/backends/mps/ops.py +277 -0
  17. bitsandbytes/backends/triton/__init__.py +0 -0
  18. bitsandbytes/backends/triton/kernels_4bit.py +577 -0
  19. bitsandbytes/backends/triton/kernels_8bit_quant.py +195 -0
  20. bitsandbytes/backends/triton/kernels_optim.py +1177 -0
  21. bitsandbytes/backends/triton/ops.py +304 -0
  22. bitsandbytes/backends/utils.py +94 -0
  23. bitsandbytes/backends/xpu/__init__.py +0 -0
  24. bitsandbytes/backends/xpu/ops.py +305 -0
  25. bitsandbytes/cextension.py +405 -0
  26. bitsandbytes/consts.py +12 -0
  27. bitsandbytes/cuda_specs.py +111 -0
  28. bitsandbytes/diagnostics/__init__.py +0 -0
  29. bitsandbytes/diagnostics/cuda.py +193 -0
  30. bitsandbytes/diagnostics/main.py +134 -0
  31. bitsandbytes/diagnostics/utils.py +12 -0
  32. bitsandbytes/functional.py +1810 -0
  33. bitsandbytes/libbitsandbytes_cpu.dll +0 -0
  34. bitsandbytes/nn/__init__.py +19 -0
  35. bitsandbytes/nn/modules.py +1220 -0
  36. bitsandbytes/nn/parametrize.py +206 -0
  37. bitsandbytes/optim/__init__.py +22 -0
  38. bitsandbytes/optim/adagrad.py +187 -0
  39. bitsandbytes/optim/adam.py +346 -0
  40. bitsandbytes/optim/adamw.py +337 -0
  41. bitsandbytes/optim/ademamix.py +410 -0
  42. bitsandbytes/optim/lamb.py +190 -0
  43. bitsandbytes/optim/lars.py +259 -0
  44. bitsandbytes/optim/lion.py +266 -0
  45. bitsandbytes/optim/optimizer.py +756 -0
  46. bitsandbytes/optim/rmsprop.py +170 -0
  47. bitsandbytes/optim/sgd.py +152 -0
  48. bitsandbytes/py.typed +0 -0
  49. bitsandbytes/utils.py +208 -0
  50. bitsandbytes-0.50.0.dist-info/METADATA +288 -0
  51. bitsandbytes-0.50.0.dist-info/RECORD +54 -0
  52. bitsandbytes-0.50.0.dist-info/WHEEL +5 -0
  53. bitsandbytes-0.50.0.dist-info/licenses/LICENSE +21 -0
  54. bitsandbytes-0.50.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,193 @@
1
+ from collections.abc import Iterable, Iterator
2
+ import logging
3
+ import os
4
+ from pathlib import Path
5
+
6
+ import torch
7
+
8
+ from bitsandbytes.cextension import HIP_ENVIRONMENT, get_cuda_bnb_library_path
9
+ from bitsandbytes.cuda_specs import CUDASpecs
10
+ from bitsandbytes.diagnostics.utils import print_dedented
11
+
12
+ CUDART_PATH_PREFERRED_ENVVARS = ("CONDA_PREFIX", "LD_LIBRARY_PATH")
13
+
14
+ CUDART_PATH_IGNORED_ENVVARS = {
15
+ "DBUS_SESSION_BUS_ADDRESS", # hardware related
16
+ "GOOGLE_VM_CONFIG_LOCK_FILE", # GCP: requires elevated permissions, causing problems in VMs and Jupyter notebooks
17
+ "HOME", # Linux shell default
18
+ "LESSCLOSE",
19
+ "LESSOPEN", # related to the `less` command
20
+ "MAIL", # something related to emails
21
+ "OLDPWD",
22
+ "PATH", # this is for finding binaries, not libraries
23
+ "PWD", # PWD: this is how the shell keeps track of the current working dir
24
+ "SHELL", # binary for currently invoked shell
25
+ "SSH_AUTH_SOCK", # SSH stuff, therefore unrelated
26
+ "SSH_TTY",
27
+ "TMUX", # Terminal Multiplexer
28
+ "XDG_DATA_DIRS", # XDG: Desktop environment stuff
29
+ "XDG_GREETER_DATA_DIR", # XDG: Desktop environment stuff
30
+ "XDG_RUNTIME_DIR",
31
+ "_", # current Python interpreter
32
+ }
33
+
34
+ CUDA_RUNTIME_LIB_PATTERNS = (
35
+ (
36
+ "libamdhip64.so*", # Linux
37
+ "amdhip64*.dll", # Windows
38
+ )
39
+ if HIP_ENVIRONMENT
40
+ else (
41
+ "cudart64*.dll", # Windows
42
+ "libcudart*.so*", # libcudart.so, libcudart.so.11.0, libcudart.so.12.0, libcudart.so.12.1, libcudart.so.12.2 etc.
43
+ "nvcuda*.dll", # Windows
44
+ )
45
+ )
46
+
47
+ logger = logging.getLogger(__name__)
48
+
49
+
50
+ def find_cuda_libraries_in_path_list(paths_list_candidate: str) -> Iterable[Path]:
51
+ for dir_string in paths_list_candidate.split(os.pathsep):
52
+ if not dir_string:
53
+ continue
54
+ if os.sep not in dir_string:
55
+ continue
56
+ try:
57
+ dir = Path(dir_string)
58
+ try:
59
+ if not dir.exists():
60
+ logger.warning(f"The directory listed in your path is found to be non-existent: {dir}")
61
+ continue
62
+ except OSError: # Assume an esoteric error trying to poke at the directory
63
+ pass
64
+ for lib_pattern in CUDA_RUNTIME_LIB_PATTERNS:
65
+ for pth in dir.glob(lib_pattern):
66
+ if pth.is_file() and not pth.is_symlink():
67
+ yield pth
68
+ except (OSError, PermissionError):
69
+ pass
70
+
71
+
72
+ def is_relevant_candidate_env_var(env_var: str, value: str) -> bool:
73
+ return (
74
+ env_var in CUDART_PATH_PREFERRED_ENVVARS # is a preferred location
75
+ or (
76
+ os.sep in value # might contain a path
77
+ and env_var not in CUDART_PATH_IGNORED_ENVVARS # not ignored
78
+ and "CONDA" not in env_var # not another conda envvar
79
+ and "BASH_FUNC" not in env_var # not a bash function defined via envvar
80
+ and "\n" not in value # likely e.g. a script or something?
81
+ )
82
+ )
83
+
84
+
85
+ def get_potentially_lib_path_containing_env_vars() -> dict[str, str]:
86
+ return {env_var: value for env_var, value in os.environ.items() if is_relevant_candidate_env_var(env_var, value)}
87
+
88
+
89
+ def find_cudart_libraries() -> Iterator[Path]:
90
+ """
91
+ Searches for a cuda installations, in the following order of priority:
92
+ 1. active conda env
93
+ 2. LD_LIBRARY_PATH
94
+ 3. any other env vars, while ignoring those that
95
+ - are known to be unrelated
96
+ - don't contain the path separator `/`
97
+
98
+ If multiple libraries are found in part 3, we optimistically try one,
99
+ while giving a warning message.
100
+ """
101
+ candidate_env_vars = get_potentially_lib_path_containing_env_vars()
102
+
103
+ for envvar in CUDART_PATH_PREFERRED_ENVVARS:
104
+ if envvar in candidate_env_vars:
105
+ directory = candidate_env_vars[envvar]
106
+ yield from find_cuda_libraries_in_path_list(directory)
107
+ candidate_env_vars.pop(envvar)
108
+
109
+ for env_var, value in candidate_env_vars.items():
110
+ yield from find_cuda_libraries_in_path_list(value)
111
+
112
+
113
+ def _print_cuda_diagnostics(cuda_specs: CUDASpecs) -> None:
114
+ print(
115
+ f"PyTorch settings found: CUDA_VERSION={cuda_specs.cuda_version_string}, "
116
+ f"Highest Compute Capability: {cuda_specs.highest_compute_capability}.",
117
+ )
118
+
119
+ binary_path = get_cuda_bnb_library_path(cuda_specs)
120
+ if not binary_path.exists():
121
+ print_dedented(
122
+ f"""
123
+ No compatible CUDA library found (tried: {binary_path.name}). You may need to compile from source:
124
+ https://huggingface.co/docs/bitsandbytes/main/en/installation#cuda-compile
125
+ """,
126
+ )
127
+
128
+ # 7.5 is the minimum CC for int8 tensor cores
129
+ if not cuda_specs.has_imma:
130
+ print_dedented(
131
+ """
132
+ WARNING: Compute capability < 7.5 detected! Only slow 8-bit matmul is supported for your GPU!
133
+ If you run into issues with 8-bit matmul, you can try 4-bit quantization:
134
+ https://huggingface.co/blog/4bit-transformers-bitsandbytes
135
+ """,
136
+ )
137
+
138
+
139
+ def _print_hip_diagnostics(cuda_specs: CUDASpecs) -> None:
140
+ print(f"PyTorch settings found: ROCM_VERSION={cuda_specs.cuda_version_string}")
141
+
142
+ rocm_override = os.environ.get("BNB_ROCM_VERSION")
143
+ if rocm_override:
144
+ print(f"BNB_ROCM_VERSION override: {rocm_override}")
145
+
146
+ binary_path = get_cuda_bnb_library_path(cuda_specs)
147
+ if not binary_path.exists():
148
+ print_dedented(
149
+ f"""
150
+ No compatible ROCm library found (tried: {binary_path.name}). You may need to compile from source:
151
+ https://huggingface.co/docs/bitsandbytes/main/en/installation#rocm-compile
152
+ Use BNB_ROCM_VERSION to force a specific version if needed.
153
+ """,
154
+ )
155
+
156
+ hip_major, hip_minor = cuda_specs.cuda_version_tuple
157
+ if (hip_major, hip_minor) < (6, 1):
158
+ print_dedented(
159
+ """
160
+ WARNING: bitsandbytes is fully supported only from ROCm 6.1.
161
+ """,
162
+ )
163
+
164
+
165
+ def print_diagnostics(cuda_specs: CUDASpecs) -> None:
166
+ if HIP_ENVIRONMENT:
167
+ _print_hip_diagnostics(cuda_specs)
168
+ else:
169
+ _print_cuda_diagnostics(cuda_specs)
170
+
171
+
172
+ def print_runtime_diagnostics() -> None:
173
+ backend = "ROCm" if HIP_ENVIRONMENT else "CUDA"
174
+ runtime_version = torch.version.hip if HIP_ENVIRONMENT else torch.version.cuda
175
+ override_var = "BNB_ROCM_VERSION" if HIP_ENVIRONMENT else "BNB_CUDA_VERSION"
176
+ override_example = "72" if HIP_ENVIRONMENT else "122"
177
+
178
+ cudart_paths = list(find_cudart_libraries())
179
+ if not cudart_paths:
180
+ print(f"{backend} SETUP: WARNING! {backend} runtime files not found in any environmental path.")
181
+ elif len(cudart_paths) > 1:
182
+ print_dedented(
183
+ f"""
184
+ Found duplicate {backend} runtime files (see below).
185
+
186
+ bitsandbytes will use PyTorch's {backend} runtime ({runtime_version}) and auto-select
187
+ the closest available library version. If you need to force a specific version,
188
+ set {override_var}, e.g.:
189
+ export {override_var}={override_example}
190
+ """,
191
+ )
192
+ for pth in cudart_paths:
193
+ print(f"* Found {backend} runtime at: {pth}")
@@ -0,0 +1,134 @@
1
+ import importlib
2
+ import platform
3
+ import sys
4
+ import traceback
5
+
6
+ import torch
7
+
8
+ from bitsandbytes import __version__ as bnb_version
9
+ from bitsandbytes.consts import PACKAGE_GITHUB_URL
10
+ from bitsandbytes.cuda_specs import get_cuda_specs
11
+ from bitsandbytes.diagnostics.cuda import print_diagnostics
12
+ from bitsandbytes.diagnostics.utils import print_dedented, print_header
13
+
14
+ _RELATED_PACKAGES = [
15
+ "accelerate",
16
+ "diffusers",
17
+ "numpy",
18
+ "pip",
19
+ "peft",
20
+ "safetensors",
21
+ "transformers",
22
+ "triton",
23
+ "trl",
24
+ ]
25
+
26
+
27
+ def sanity_check():
28
+ from bitsandbytes.optim import Adam
29
+
30
+ p = torch.nn.Parameter(torch.rand(10, 10).cuda())
31
+ a = torch.rand(10, 10).cuda()
32
+ p1 = p.data.sum().item()
33
+ adam = Adam([p])
34
+ out = a * p
35
+ loss = out.sum()
36
+ loss.backward()
37
+ adam.step()
38
+ p2 = p.data.sum().item()
39
+ assert p1 != p2
40
+
41
+
42
+ def get_package_version(name: str) -> str:
43
+ try:
44
+ version = importlib.metadata.version(name)
45
+ except importlib.metadata.PackageNotFoundError:
46
+ version = "not found"
47
+ return version
48
+
49
+
50
+ def show_environment():
51
+ """Simple utility to print out environment information."""
52
+
53
+ print(f"Platform: {platform.platform()}")
54
+ if platform.system() == "Linux":
55
+ print(f" libc: {'-'.join(platform.libc_ver())}")
56
+
57
+ print(f"Python: {platform.python_version()}")
58
+
59
+ print(f"PyTorch: {torch.__version__}")
60
+ print(f" CUDA: {torch.version.cuda or 'N/A'}")
61
+ print(f" HIP: {torch.version.hip or 'N/A'}")
62
+ print(f" XPU: {getattr(torch.version, 'xpu', 'N/A') or 'N/A'}")
63
+
64
+ print("Related packages:")
65
+ for pkg in _RELATED_PACKAGES:
66
+ version = get_package_version(pkg)
67
+ print(f" {pkg}: {version}")
68
+
69
+
70
+ def main():
71
+ print_header(f"bitsandbytes v{bnb_version}")
72
+ show_environment()
73
+ print_header("")
74
+
75
+ cuda_specs = get_cuda_specs()
76
+
77
+ if cuda_specs:
78
+ print_diagnostics(cuda_specs)
79
+
80
+ has_rocm = torch.version.hip is not None
81
+ has_cuda = not has_rocm and torch.version.cuda is not None and torch.cuda.is_available()
82
+ has_xpu = hasattr(torch, "xpu") and torch.xpu.is_available()
83
+
84
+ from bitsandbytes.cextension import ErrorHandlerMockBNBNativeLibrary, lib
85
+
86
+ lib_loaded = not isinstance(lib, ErrorHandlerMockBNBNativeLibrary)
87
+
88
+ if not (has_cuda or has_rocm or has_xpu):
89
+ print(
90
+ f"No CUDA, ROCm, or XPU detected; CPU library {'loaded successfully' if lib_loaded else 'failed to load'}."
91
+ )
92
+ elif has_xpu:
93
+ from bitsandbytes.backends.utils import triton_available
94
+
95
+ if not isinstance(lib, ErrorHandlerMockBNBNativeLibrary):
96
+ print("XPU native library loaded successfully.")
97
+ elif triton_available:
98
+ print("XPU native library not loaded; using triton fallback.")
99
+ else:
100
+ print("XPU native library not loaded and triton not available.")
101
+ else:
102
+ if not lib_loaded:
103
+ print_dedented(
104
+ f"""
105
+ See above for details on why the library failed to load.
106
+ Please provide this info when creating an issue via {PACKAGE_GITHUB_URL}/issues/new/choose
107
+ WARNING: Please be sure to sanitize sensitive info from the output before posting it.
108
+ """,
109
+ )
110
+ sys.exit(1)
111
+
112
+ print("Checking that the library is importable and callable...")
113
+ try:
114
+ sanity_check()
115
+ print("SUCCESS!")
116
+ return
117
+ except RuntimeError as e:
118
+ if "not available in CPU-only" in str(e):
119
+ print("WARNING: bitsandbytes is running as CPU-only!")
120
+ print("8-bit optimizers and GPU quantization are unavailable.")
121
+ print("If you think this is an error, please report an issue.")
122
+ else:
123
+ raise e
124
+ except Exception:
125
+ traceback.print_exc()
126
+
127
+ print_dedented(
128
+ f"""
129
+ Above we output some debug information.
130
+ Please provide this info when creating an issue via {PACKAGE_GITHUB_URL}/issues/new/choose
131
+ WARNING: Please be sure to sanitize sensitive info from the output before posting it.
132
+ """,
133
+ )
134
+ sys.exit(1)
@@ -0,0 +1,12 @@
1
+ import textwrap
2
+
3
+ HEADER_WIDTH = 60
4
+
5
+
6
+ def print_header(txt: str, width: int = HEADER_WIDTH, filler: str = "=") -> None:
7
+ txt = f" {txt} " if txt else ""
8
+ print(txt.center(width, filler))
9
+
10
+
11
+ def print_dedented(text):
12
+ print("\n".join(textwrap.dedent(text).strip().split("\n")))