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.
- bitsandbytes/__init__.py +78 -0
- bitsandbytes/__main__.py +4 -0
- bitsandbytes/_ops.py +510 -0
- bitsandbytes/autograd/__init__.py +0 -0
- bitsandbytes/autograd/_functions.py +491 -0
- bitsandbytes/backends/__init__.py +0 -0
- bitsandbytes/backends/cpu/__init__.py +0 -0
- bitsandbytes/backends/cpu/ops.py +580 -0
- bitsandbytes/backends/cuda/__init__.py +0 -0
- bitsandbytes/backends/cuda/ops.py +1199 -0
- bitsandbytes/backends/default/__init__.py +0 -0
- bitsandbytes/backends/default/ops.py +632 -0
- bitsandbytes/backends/hpu/__init__.py +0 -0
- bitsandbytes/backends/hpu/ops.py +53 -0
- bitsandbytes/backends/mps/__init__.py +0 -0
- bitsandbytes/backends/mps/ops.py +277 -0
- bitsandbytes/backends/triton/__init__.py +0 -0
- bitsandbytes/backends/triton/kernels_4bit.py +577 -0
- bitsandbytes/backends/triton/kernels_8bit_quant.py +195 -0
- bitsandbytes/backends/triton/kernels_optim.py +1177 -0
- bitsandbytes/backends/triton/ops.py +304 -0
- bitsandbytes/backends/utils.py +94 -0
- bitsandbytes/backends/xpu/__init__.py +0 -0
- bitsandbytes/backends/xpu/ops.py +305 -0
- bitsandbytes/cextension.py +405 -0
- bitsandbytes/consts.py +12 -0
- bitsandbytes/cuda_specs.py +111 -0
- bitsandbytes/diagnostics/__init__.py +0 -0
- bitsandbytes/diagnostics/cuda.py +193 -0
- bitsandbytes/diagnostics/main.py +134 -0
- bitsandbytes/diagnostics/utils.py +12 -0
- bitsandbytes/functional.py +1810 -0
- bitsandbytes/libbitsandbytes_cpu.dll +0 -0
- bitsandbytes/nn/__init__.py +19 -0
- bitsandbytes/nn/modules.py +1220 -0
- bitsandbytes/nn/parametrize.py +206 -0
- bitsandbytes/optim/__init__.py +22 -0
- bitsandbytes/optim/adagrad.py +187 -0
- bitsandbytes/optim/adam.py +346 -0
- bitsandbytes/optim/adamw.py +337 -0
- bitsandbytes/optim/ademamix.py +410 -0
- bitsandbytes/optim/lamb.py +190 -0
- bitsandbytes/optim/lars.py +259 -0
- bitsandbytes/optim/lion.py +266 -0
- bitsandbytes/optim/optimizer.py +756 -0
- bitsandbytes/optim/rmsprop.py +170 -0
- bitsandbytes/optim/sgd.py +152 -0
- bitsandbytes/py.typed +0 -0
- bitsandbytes/utils.py +208 -0
- bitsandbytes-0.50.0.dist-info/METADATA +288 -0
- bitsandbytes-0.50.0.dist-info/RECORD +54 -0
- bitsandbytes-0.50.0.dist-info/WHEEL +5 -0
- bitsandbytes-0.50.0.dist-info/licenses/LICENSE +21 -0
- bitsandbytes-0.50.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
import math
|
|
3
|
+
from typing import Literal, Optional
|
|
4
|
+
|
|
5
|
+
import torch
|
|
6
|
+
|
|
7
|
+
import bitsandbytes.functional as F
|
|
8
|
+
from bitsandbytes.optim.optimizer import Optimizer2State
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class _ReferenceAdEMAMix(torch.optim.Optimizer):
|
|
12
|
+
"""
|
|
13
|
+
Reference: https://hf.co/papers/2409.03137
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
params: Iterable[torch.nn.Parameter],
|
|
19
|
+
lr: float = 1e-3,
|
|
20
|
+
betas: tuple[float, float, float] = (0.9, 0.999, 0.9999),
|
|
21
|
+
alpha: float = 5.0,
|
|
22
|
+
eps: float = 1e-8,
|
|
23
|
+
weight_decay: float = 1e-2, # default 0.0 or 1e-2?
|
|
24
|
+
t_beta3: Optional[int] = None,
|
|
25
|
+
t_alpha: Optional[int] = None,
|
|
26
|
+
):
|
|
27
|
+
defaults = dict(
|
|
28
|
+
lr=lr, betas=betas, alpha=alpha, eps=eps, weight_decay=weight_decay, t_beta3=t_beta3, t_alpha=t_alpha
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
super().__init__(params, defaults)
|
|
32
|
+
|
|
33
|
+
@torch.no_grad()
|
|
34
|
+
def step(self, closure=None):
|
|
35
|
+
loss = None
|
|
36
|
+
|
|
37
|
+
if closure is not None:
|
|
38
|
+
with torch.enable_grad():
|
|
39
|
+
loss = closure()
|
|
40
|
+
|
|
41
|
+
for group in self.param_groups:
|
|
42
|
+
if "step" in group:
|
|
43
|
+
group["step"] += 1
|
|
44
|
+
else:
|
|
45
|
+
group["step"] = 1
|
|
46
|
+
|
|
47
|
+
lr = group["lr"]
|
|
48
|
+
eps = group["eps"]
|
|
49
|
+
beta1, beta2, beta3 = group["betas"]
|
|
50
|
+
alpha = group["alpha"]
|
|
51
|
+
t_alpha = group["t_alpha"]
|
|
52
|
+
t_beta3 = group["t_beta3"]
|
|
53
|
+
weight_decay = group["weight_decay"]
|
|
54
|
+
|
|
55
|
+
for p in group["params"]:
|
|
56
|
+
if p.grad is None:
|
|
57
|
+
continue
|
|
58
|
+
|
|
59
|
+
grad = p.grad
|
|
60
|
+
state = self.state[p]
|
|
61
|
+
|
|
62
|
+
# State initialization
|
|
63
|
+
if len(state) == 0:
|
|
64
|
+
# For parity with bnb implementation we combine both fast
|
|
65
|
+
# and slow EMA stats into one stacked tensor.
|
|
66
|
+
state["m1_m2"] = p.new_zeros((2, *p.size()))
|
|
67
|
+
state["nu"] = torch.zeros_like(p) # second moment estimate
|
|
68
|
+
|
|
69
|
+
m1, m2, nu = state["m1_m2"][0], state["m1_m2"][1], state["nu"]
|
|
70
|
+
|
|
71
|
+
bias_correction1 = 1 - beta1 ** group["step"]
|
|
72
|
+
|
|
73
|
+
bias_correction2 = 1 - beta2 ** group["step"]
|
|
74
|
+
|
|
75
|
+
# Apply scheduler for alpha
|
|
76
|
+
if t_alpha is not None:
|
|
77
|
+
alpha = min(group["step"] * alpha / t_alpha, alpha)
|
|
78
|
+
|
|
79
|
+
# Apply scheduler for beta3
|
|
80
|
+
if t_beta3 is not None:
|
|
81
|
+
ln_beta1 = math.log(beta1)
|
|
82
|
+
ln_beta3 = math.log(beta3)
|
|
83
|
+
step_scale = group["step"] / t_beta3
|
|
84
|
+
beta3 = min(
|
|
85
|
+
math.exp((ln_beta1 * ln_beta3) / (((1 - step_scale) * ln_beta3) + (step_scale * ln_beta1))),
|
|
86
|
+
beta3,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Update the EMAs
|
|
90
|
+
m1.mul_(beta1).add_(grad, alpha=1 - beta1)
|
|
91
|
+
m2.mul_(beta3).add_(grad, alpha=1 - beta3)
|
|
92
|
+
nu.mul_(beta2).addcmul_(grad, grad, value=1 - beta2)
|
|
93
|
+
|
|
94
|
+
# Compute step
|
|
95
|
+
denom = (nu.sqrt() / (bias_correction2**0.5)).add(eps)
|
|
96
|
+
update = (m1.div(bias_correction1) + alpha * m2) / denom
|
|
97
|
+
|
|
98
|
+
# Add weight decay
|
|
99
|
+
update.add_(p, alpha=weight_decay)
|
|
100
|
+
|
|
101
|
+
# Apply update scaled by learning rate
|
|
102
|
+
p.add_(-lr * update)
|
|
103
|
+
|
|
104
|
+
return loss
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class AdEMAMix(Optimizer2State):
|
|
108
|
+
def __init__(
|
|
109
|
+
self,
|
|
110
|
+
params: Iterable[torch.nn.Parameter],
|
|
111
|
+
lr: float = 1e-3,
|
|
112
|
+
betas: tuple[float, float, float] = (0.9, 0.999, 0.9999),
|
|
113
|
+
alpha: float = 5.0,
|
|
114
|
+
t_alpha: Optional[int] = None,
|
|
115
|
+
t_beta3: Optional[int] = None,
|
|
116
|
+
eps: float = 1e-8,
|
|
117
|
+
weight_decay: float = 1e-2,
|
|
118
|
+
optim_bits: Literal[8, 32] = 32,
|
|
119
|
+
min_8bit_size: int = 4096,
|
|
120
|
+
is_paged: bool = False,
|
|
121
|
+
):
|
|
122
|
+
super().__init__(
|
|
123
|
+
"ademamix",
|
|
124
|
+
params=params,
|
|
125
|
+
lr=lr,
|
|
126
|
+
betas=betas,
|
|
127
|
+
eps=eps,
|
|
128
|
+
weight_decay=weight_decay,
|
|
129
|
+
optim_bits=optim_bits,
|
|
130
|
+
args=None,
|
|
131
|
+
min_8bit_size=min_8bit_size,
|
|
132
|
+
is_paged=is_paged,
|
|
133
|
+
alpha=alpha,
|
|
134
|
+
t_alpha=t_alpha,
|
|
135
|
+
t_beta3=t_beta3,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
@torch.no_grad()
|
|
139
|
+
def init_state(self, group, p, gindex, pindex):
|
|
140
|
+
# In our AdEMAMix implementation, we use `state` to hold
|
|
141
|
+
# both the fast and slow EMAs. Here we override the base
|
|
142
|
+
# `Optimizer2State` to allocate a buffer twice as large.
|
|
143
|
+
|
|
144
|
+
config = self.get_config(gindex, pindex, group)
|
|
145
|
+
|
|
146
|
+
if config["optim_bits"] == 32:
|
|
147
|
+
dtype = torch.float32
|
|
148
|
+
elif config["optim_bits"] == 8:
|
|
149
|
+
dtype = torch.uint8
|
|
150
|
+
else:
|
|
151
|
+
raise NotImplementedError(f"Amount of optimizer bits not supported: {config['optim_bits']}")
|
|
152
|
+
|
|
153
|
+
if p.numel() < config["min_8bit_size"]:
|
|
154
|
+
dtype = torch.float32
|
|
155
|
+
|
|
156
|
+
state = self.state[p]
|
|
157
|
+
state["step"] = 0
|
|
158
|
+
|
|
159
|
+
if dtype == torch.uint8:
|
|
160
|
+
if "dynamic" not in self.name2qmap:
|
|
161
|
+
self.fill_qmap()
|
|
162
|
+
self.name2qmap["dynamic"] = state["qmap1"] = self.name2qmap["dynamic"].to(p.device)
|
|
163
|
+
self.name2qmap["udynamic"] = state["qmap2"] = self.name2qmap["udynamic"].to(p.device)
|
|
164
|
+
|
|
165
|
+
blocksize = 256
|
|
166
|
+
n = p.numel()
|
|
167
|
+
blocks = (n // blocksize) + bool(n % blocksize)
|
|
168
|
+
|
|
169
|
+
state["absmax1"] = torch.zeros((2, blocks), dtype=torch.float32, device=p.device)
|
|
170
|
+
state["absmax2"] = torch.zeros((blocks,), dtype=torch.float32, device=p.device)
|
|
171
|
+
|
|
172
|
+
state["state1"] = self._get_state_double_buffer(p, dtype=dtype)
|
|
173
|
+
state["state2"] = self.get_state_buffer(p, dtype=dtype)
|
|
174
|
+
|
|
175
|
+
@torch.no_grad()
|
|
176
|
+
def update_step(self, group, p, gindex, pindex):
|
|
177
|
+
config = self.get_config(gindex, pindex, group)
|
|
178
|
+
|
|
179
|
+
if not config["t_alpha"] and not config["t_beta3"]:
|
|
180
|
+
# Not using alpha/beta3 scheduler; we can fall through.
|
|
181
|
+
super().update_step(group, p, gindex, pindex)
|
|
182
|
+
return
|
|
183
|
+
|
|
184
|
+
# Ensure contiguous memory layout
|
|
185
|
+
p.data = p.data.contiguous()
|
|
186
|
+
p.grad = p.grad.contiguous()
|
|
187
|
+
|
|
188
|
+
state = self.state[p]
|
|
189
|
+
grad = p.grad
|
|
190
|
+
|
|
191
|
+
state["step"] += 1
|
|
192
|
+
step = state["step"]
|
|
193
|
+
|
|
194
|
+
beta1, beta2, beta3 = config["betas"]
|
|
195
|
+
alpha = config["alpha"]
|
|
196
|
+
t_alpha = config["t_alpha"]
|
|
197
|
+
t_beta3 = config["t_beta3"]
|
|
198
|
+
|
|
199
|
+
# Apply scheduler for alpha
|
|
200
|
+
if t_alpha:
|
|
201
|
+
alpha_t = min(step * alpha / t_alpha, alpha)
|
|
202
|
+
else:
|
|
203
|
+
alpha_t = alpha
|
|
204
|
+
|
|
205
|
+
# Apply scheduler for beta3
|
|
206
|
+
if t_beta3:
|
|
207
|
+
ln_beta1 = math.log(beta1)
|
|
208
|
+
ln_beta3 = math.log(beta3)
|
|
209
|
+
step_scale = step / t_beta3
|
|
210
|
+
beta3_t = min(
|
|
211
|
+
math.exp((ln_beta1 * ln_beta3) / (((1 - step_scale) * ln_beta3) + (step_scale * ln_beta1))), beta3
|
|
212
|
+
)
|
|
213
|
+
else:
|
|
214
|
+
beta3_t = beta3
|
|
215
|
+
|
|
216
|
+
# Apply updates
|
|
217
|
+
if state["state1"].dtype == torch.float32:
|
|
218
|
+
F.optimizer_update_32bit(
|
|
219
|
+
self.optimizer_name,
|
|
220
|
+
grad,
|
|
221
|
+
p,
|
|
222
|
+
state["state1"],
|
|
223
|
+
beta1,
|
|
224
|
+
config["eps"],
|
|
225
|
+
step,
|
|
226
|
+
config["lr"],
|
|
227
|
+
state["state2"],
|
|
228
|
+
beta2,
|
|
229
|
+
beta3_t,
|
|
230
|
+
alpha_t,
|
|
231
|
+
config["weight_decay"],
|
|
232
|
+
gnorm_scale=1.0,
|
|
233
|
+
unorm_vec=state["unorm_vec"] if config["max_unorm"] > 0.0 else None,
|
|
234
|
+
max_unorm=config["max_unorm"],
|
|
235
|
+
skip_zeros=config["skip_zeros"],
|
|
236
|
+
)
|
|
237
|
+
elif state["state1"].dtype == torch.uint8:
|
|
238
|
+
F.optimizer_update_8bit_blockwise(
|
|
239
|
+
self.optimizer_name,
|
|
240
|
+
grad,
|
|
241
|
+
p,
|
|
242
|
+
state["state1"],
|
|
243
|
+
state["state2"],
|
|
244
|
+
config["betas"][0],
|
|
245
|
+
config["betas"][1],
|
|
246
|
+
beta3_t,
|
|
247
|
+
alpha_t,
|
|
248
|
+
config["eps"],
|
|
249
|
+
step,
|
|
250
|
+
config["lr"],
|
|
251
|
+
state["qmap1"],
|
|
252
|
+
state["qmap2"],
|
|
253
|
+
state["absmax1"],
|
|
254
|
+
state["absmax2"],
|
|
255
|
+
config["weight_decay"],
|
|
256
|
+
gnorm_scale=1.0,
|
|
257
|
+
skip_zeros=config["skip_zeros"],
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
def _get_state_double_buffer(self, p, dtype=torch.float32):
|
|
261
|
+
if not self.is_paged or p.numel() < 1e5:
|
|
262
|
+
return torch.zeros((2, *p.size()), dtype=dtype, device=p.device)
|
|
263
|
+
else:
|
|
264
|
+
buff = F.get_paged(*(2, *p.size()), dtype=dtype, device=p.device)
|
|
265
|
+
F.fill(buff, 0)
|
|
266
|
+
self.page_mng.paged_tensors.append(buff)
|
|
267
|
+
return buff
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class AdEMAMix8bit(AdEMAMix):
|
|
271
|
+
def __init__(
|
|
272
|
+
self,
|
|
273
|
+
params: Iterable[torch.nn.Parameter],
|
|
274
|
+
lr: float = 1e-3,
|
|
275
|
+
betas: tuple[float, float, float] = (0.9, 0.999, 0.9999),
|
|
276
|
+
alpha: float = 5.0,
|
|
277
|
+
t_alpha: Optional[int] = None,
|
|
278
|
+
t_beta3: Optional[int] = None,
|
|
279
|
+
eps: float = 1e-8,
|
|
280
|
+
weight_decay: float = 1e-2,
|
|
281
|
+
min_8bit_size: int = 4096,
|
|
282
|
+
is_paged: bool = False,
|
|
283
|
+
):
|
|
284
|
+
super().__init__(
|
|
285
|
+
params,
|
|
286
|
+
lr=lr,
|
|
287
|
+
betas=betas,
|
|
288
|
+
alpha=alpha,
|
|
289
|
+
t_alpha=t_alpha,
|
|
290
|
+
t_beta3=t_beta3,
|
|
291
|
+
eps=eps,
|
|
292
|
+
weight_decay=weight_decay,
|
|
293
|
+
optim_bits=8,
|
|
294
|
+
min_8bit_size=min_8bit_size,
|
|
295
|
+
is_paged=is_paged,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
class PagedAdEMAMix8bit(AdEMAMix8bit):
|
|
300
|
+
def __init__(
|
|
301
|
+
self,
|
|
302
|
+
params: Iterable[torch.nn.Parameter],
|
|
303
|
+
lr: float = 1e-3,
|
|
304
|
+
betas: tuple[float, float, float] = (0.9, 0.999, 0.9999),
|
|
305
|
+
alpha: float = 5.0,
|
|
306
|
+
t_alpha: Optional[int] = None,
|
|
307
|
+
t_beta3: Optional[int] = None,
|
|
308
|
+
eps: float = 1e-8,
|
|
309
|
+
weight_decay: float = 1e-2,
|
|
310
|
+
min_8bit_size: int = 4096,
|
|
311
|
+
):
|
|
312
|
+
super().__init__(
|
|
313
|
+
params,
|
|
314
|
+
lr=lr,
|
|
315
|
+
betas=betas,
|
|
316
|
+
alpha=alpha,
|
|
317
|
+
t_alpha=t_alpha,
|
|
318
|
+
t_beta3=t_beta3,
|
|
319
|
+
eps=eps,
|
|
320
|
+
weight_decay=weight_decay,
|
|
321
|
+
min_8bit_size=min_8bit_size,
|
|
322
|
+
is_paged=True,
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
class PagedAdEMAMix(AdEMAMix):
|
|
327
|
+
def __init__(
|
|
328
|
+
self,
|
|
329
|
+
params: Iterable[torch.nn.Parameter],
|
|
330
|
+
lr: float = 1e-3,
|
|
331
|
+
betas: tuple[float, float, float] = (0.9, 0.999, 0.9999),
|
|
332
|
+
alpha: float = 5.0,
|
|
333
|
+
t_alpha: Optional[int] = None,
|
|
334
|
+
t_beta3: Optional[int] = None,
|
|
335
|
+
eps: float = 1e-8,
|
|
336
|
+
weight_decay: float = 1e-2,
|
|
337
|
+
optim_bits: Literal[8, 32] = 32,
|
|
338
|
+
min_8bit_size: int = 4096,
|
|
339
|
+
):
|
|
340
|
+
super().__init__(
|
|
341
|
+
params,
|
|
342
|
+
lr=lr,
|
|
343
|
+
betas=betas,
|
|
344
|
+
alpha=alpha,
|
|
345
|
+
t_alpha=t_alpha,
|
|
346
|
+
t_beta3=t_beta3,
|
|
347
|
+
eps=eps,
|
|
348
|
+
weight_decay=weight_decay,
|
|
349
|
+
optim_bits=optim_bits,
|
|
350
|
+
min_8bit_size=min_8bit_size,
|
|
351
|
+
is_paged=True,
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
class AdEMAMix32bit(Optimizer2State):
|
|
356
|
+
def __init__(
|
|
357
|
+
self,
|
|
358
|
+
params: Iterable[torch.nn.Parameter],
|
|
359
|
+
lr: float = 1e-3,
|
|
360
|
+
betas: tuple[float, float, float] = (0.9, 0.999, 0.9999),
|
|
361
|
+
alpha: float = 5.0,
|
|
362
|
+
t_alpha: Optional[int] = None,
|
|
363
|
+
t_beta3: Optional[int] = None,
|
|
364
|
+
eps: float = 1e-8,
|
|
365
|
+
weight_decay: float = 1e-2,
|
|
366
|
+
min_8bit_size: int = 4096,
|
|
367
|
+
is_paged: bool = False,
|
|
368
|
+
):
|
|
369
|
+
super().__init__(
|
|
370
|
+
"ademamix",
|
|
371
|
+
params=params,
|
|
372
|
+
lr=lr,
|
|
373
|
+
betas=betas,
|
|
374
|
+
eps=eps,
|
|
375
|
+
weight_decay=weight_decay,
|
|
376
|
+
optim_bits=32,
|
|
377
|
+
args=None,
|
|
378
|
+
min_8bit_size=min_8bit_size,
|
|
379
|
+
is_paged=is_paged,
|
|
380
|
+
alpha=alpha,
|
|
381
|
+
t_alpha=t_alpha,
|
|
382
|
+
t_beta3=t_beta3,
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
class PagedAdEMAMix32bit(AdEMAMix32bit):
|
|
387
|
+
def __init__(
|
|
388
|
+
self,
|
|
389
|
+
params: Iterable[torch.nn.Parameter],
|
|
390
|
+
lr: float = 1e-3,
|
|
391
|
+
betas: tuple[float, float, float] = (0.9, 0.999, 0.9999),
|
|
392
|
+
alpha: float = 5.0,
|
|
393
|
+
t_alpha: Optional[int] = None,
|
|
394
|
+
t_beta3: Optional[int] = None,
|
|
395
|
+
eps: float = 1e-8,
|
|
396
|
+
weight_decay: float = 1e-2,
|
|
397
|
+
min_8bit_size: int = 4096,
|
|
398
|
+
):
|
|
399
|
+
super().__init__(
|
|
400
|
+
params,
|
|
401
|
+
lr=lr,
|
|
402
|
+
betas=betas,
|
|
403
|
+
alpha=alpha,
|
|
404
|
+
t_alpha=t_alpha,
|
|
405
|
+
t_beta3=t_beta3,
|
|
406
|
+
eps=eps,
|
|
407
|
+
weight_decay=weight_decay,
|
|
408
|
+
min_8bit_size=min_8bit_size,
|
|
409
|
+
is_paged=True,
|
|
410
|
+
)
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
|
2
|
+
#
|
|
3
|
+
# This source code is licensed under the MIT license found in the
|
|
4
|
+
# LICENSE file in the root directory of this source tree.
|
|
5
|
+
from bitsandbytes.optim.optimizer import Optimizer2State
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LAMB(Optimizer2State):
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
params,
|
|
12
|
+
lr=1e-3,
|
|
13
|
+
bias_correction=True,
|
|
14
|
+
betas=(0.9, 0.999),
|
|
15
|
+
eps=1e-8,
|
|
16
|
+
weight_decay=0,
|
|
17
|
+
amsgrad=False,
|
|
18
|
+
adam_w_mode=True,
|
|
19
|
+
optim_bits=32,
|
|
20
|
+
args=None,
|
|
21
|
+
min_8bit_size=4096,
|
|
22
|
+
max_unorm=1.0,
|
|
23
|
+
):
|
|
24
|
+
"""
|
|
25
|
+
Base LAMB optimizer.
|
|
26
|
+
|
|
27
|
+
Arguments:
|
|
28
|
+
params (`torch.tensor`):
|
|
29
|
+
The input parameters to optimize.
|
|
30
|
+
lr (`float`, defaults to 1e-3):
|
|
31
|
+
The learning rate.
|
|
32
|
+
bias_correction (`bool`, defaults to `True`):
|
|
33
|
+
Whether to apply bias correction to the first and second-order moments.
|
|
34
|
+
betas (`tuple(float, float)`, defaults to (0.9, 0.999)):
|
|
35
|
+
The beta values are the decay rates of the first and second-order moment of the optimizer.
|
|
36
|
+
eps (`float`, defaults to 1e-8):
|
|
37
|
+
The epsilon value prevents division by zero in the optimizer.
|
|
38
|
+
weight_decay (`float`, defaults to 1e-2):
|
|
39
|
+
The weight decay value for the optimizer.
|
|
40
|
+
amsgrad (`bool`, defaults to `False`):
|
|
41
|
+
Whether to use the [AMSGrad](https://hf.co/papers/1904.09237) variant of Adam that uses the maximum of past squared gradients instead.
|
|
42
|
+
adam_w_mode (`bool`, defaults to `True`):
|
|
43
|
+
Whether to use the AdamW variant.
|
|
44
|
+
optim_bits (`int`, defaults to 32):
|
|
45
|
+
The number of bits of the optimizer state.
|
|
46
|
+
args (`object`, defaults to `None`):
|
|
47
|
+
An object with additional arguments.
|
|
48
|
+
min_8bit_size (`int`, defaults to 4096):
|
|
49
|
+
The minimum number of elements of the parameter tensors for 8-bit optimization.
|
|
50
|
+
max_unorm (`float`, defaults to 1.0):
|
|
51
|
+
The maximum gradient norm.
|
|
52
|
+
"""
|
|
53
|
+
super().__init__(
|
|
54
|
+
"lamb",
|
|
55
|
+
params,
|
|
56
|
+
lr,
|
|
57
|
+
betas,
|
|
58
|
+
eps,
|
|
59
|
+
weight_decay,
|
|
60
|
+
optim_bits,
|
|
61
|
+
args,
|
|
62
|
+
min_8bit_size,
|
|
63
|
+
max_unorm=max_unorm,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class LAMB8bit(Optimizer2State):
|
|
68
|
+
def __init__(
|
|
69
|
+
self,
|
|
70
|
+
params,
|
|
71
|
+
lr=1e-3,
|
|
72
|
+
bias_correction=True,
|
|
73
|
+
betas=(0.9, 0.999),
|
|
74
|
+
eps=1e-8,
|
|
75
|
+
weight_decay=0,
|
|
76
|
+
amsgrad=False,
|
|
77
|
+
adam_w_mode=True,
|
|
78
|
+
args=None,
|
|
79
|
+
min_8bit_size=4096,
|
|
80
|
+
max_unorm=1.0,
|
|
81
|
+
):
|
|
82
|
+
"""
|
|
83
|
+
8-bit LAMB optimizer.
|
|
84
|
+
|
|
85
|
+
Arguments:
|
|
86
|
+
params (`torch.tensor`):
|
|
87
|
+
The input parameters to optimize.
|
|
88
|
+
lr (`float`, defaults to 1e-3):
|
|
89
|
+
The learning rate.
|
|
90
|
+
bias_correction (`bool`, defaults to `True`):
|
|
91
|
+
Whether to apply bias correction to the first and second-order moments.
|
|
92
|
+
betas (`tuple(float, float)`, defaults to (0.9, 0.999)):
|
|
93
|
+
The beta values are the decay rates of the first and second-order moment of the optimizer.
|
|
94
|
+
eps (`float`, defaults to 1e-8):
|
|
95
|
+
The epsilon value prevents division by zero in the optimizer.
|
|
96
|
+
weight_decay (`float`, defaults to 1e-2):
|
|
97
|
+
The weight decay value for the optimizer.
|
|
98
|
+
amsgrad (`bool`, defaults to `False`):
|
|
99
|
+
Whether to use the [AMSGrad](https://hf.co/papers/1904.09237) variant of Adam that uses the maximum of past squared gradients instead.
|
|
100
|
+
Note: This parameter is not supported in LAMB8bit and must be False.
|
|
101
|
+
adam_w_mode (`bool`, defaults to `True`):
|
|
102
|
+
Whether to use the AdamW variant.
|
|
103
|
+
args (`object`, defaults to `None`):
|
|
104
|
+
An object with additional arguments.
|
|
105
|
+
min_8bit_size (`int`, defaults to 4096):
|
|
106
|
+
The minimum number of elements of the parameter tensors for 8-bit optimization.
|
|
107
|
+
max_unorm (`float`, defaults to 1.0):
|
|
108
|
+
The maximum update norm for trust-ratio clipping.
|
|
109
|
+
Note: This parameter is not supported in LAMB8bit and must be left at the
|
|
110
|
+
default 1.0. The 8-bit blockwise update does not implement update-norm
|
|
111
|
+
clipping; it is honored by the 32-bit LAMB / LAMB32bit optimizers.
|
|
112
|
+
"""
|
|
113
|
+
# Validate unsupported parameters
|
|
114
|
+
if amsgrad:
|
|
115
|
+
raise ValueError("LAMB8bit does not support amsgrad=True")
|
|
116
|
+
|
|
117
|
+
if max_unorm != 1.0:
|
|
118
|
+
# We allow the default value of 1.0 to maintain compatibility with the function
|
|
119
|
+
# signature, but the 8-bit blockwise update does not implement update-norm
|
|
120
|
+
# clipping, so any other value would be silently ignored.
|
|
121
|
+
raise ValueError("LAMB8bit only supports max_unorm=1.0 (default value for compatibility)")
|
|
122
|
+
|
|
123
|
+
super().__init__(
|
|
124
|
+
"lamb",
|
|
125
|
+
params,
|
|
126
|
+
lr,
|
|
127
|
+
betas,
|
|
128
|
+
eps,
|
|
129
|
+
weight_decay,
|
|
130
|
+
8,
|
|
131
|
+
args,
|
|
132
|
+
min_8bit_size,
|
|
133
|
+
max_unorm=max_unorm,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class LAMB32bit(Optimizer2State):
|
|
138
|
+
def __init__(
|
|
139
|
+
self,
|
|
140
|
+
params,
|
|
141
|
+
lr=1e-3,
|
|
142
|
+
bias_correction=True,
|
|
143
|
+
betas=(0.9, 0.999),
|
|
144
|
+
eps=1e-8,
|
|
145
|
+
weight_decay=0,
|
|
146
|
+
amsgrad=False,
|
|
147
|
+
adam_w_mode=True,
|
|
148
|
+
args=None,
|
|
149
|
+
min_8bit_size=4096,
|
|
150
|
+
max_unorm=1.0,
|
|
151
|
+
):
|
|
152
|
+
"""
|
|
153
|
+
32-bit LAMB optimizer.
|
|
154
|
+
|
|
155
|
+
Arguments:
|
|
156
|
+
params (`torch.tensor`):
|
|
157
|
+
The input parameters to optimize.
|
|
158
|
+
lr (`float`, defaults to 1e-3):
|
|
159
|
+
The learning rate.
|
|
160
|
+
bias_correction (`bool`, defaults to `True`):
|
|
161
|
+
Whether to apply bias correction to the first and second-order moments.
|
|
162
|
+
betas (`tuple(float, float)`, defaults to (0.9, 0.999)):
|
|
163
|
+
The beta values are the decay rates of the first and second-order moment of the optimizer.
|
|
164
|
+
eps (`float`, defaults to 1e-8):
|
|
165
|
+
The epsilon value prevents division by zero in the optimizer.
|
|
166
|
+
weight_decay (`float`, defaults to 1e-2):
|
|
167
|
+
The weight decay value for the optimizer.
|
|
168
|
+
amsgrad (`bool`, defaults to `False`):
|
|
169
|
+
Whether to use the [AMSGrad](https://hf.co/papers/1904.09237) variant of Adam that uses the maximum of past squared gradients instead.
|
|
170
|
+
adam_w_mode (`bool`, defaults to `True`):
|
|
171
|
+
Whether to use the AdamW variant.
|
|
172
|
+
args (`object`, defaults to `None`):
|
|
173
|
+
An object with additional arguments.
|
|
174
|
+
min_8bit_size (`int`, defaults to 4096):
|
|
175
|
+
The minimum number of elements of the parameter tensors for 8-bit optimization.
|
|
176
|
+
max_unorm (`float`, defaults to 1.0):
|
|
177
|
+
The maximum gradient norm.
|
|
178
|
+
"""
|
|
179
|
+
super().__init__(
|
|
180
|
+
"lamb",
|
|
181
|
+
params,
|
|
182
|
+
lr,
|
|
183
|
+
betas,
|
|
184
|
+
eps,
|
|
185
|
+
weight_decay,
|
|
186
|
+
32,
|
|
187
|
+
args,
|
|
188
|
+
min_8bit_size,
|
|
189
|
+
max_unorm=max_unorm,
|
|
190
|
+
)
|