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,170 @@
|
|
|
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 Optimizer1State
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RMSprop(Optimizer1State):
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
params,
|
|
12
|
+
lr=1e-2,
|
|
13
|
+
alpha=0.99,
|
|
14
|
+
eps=1e-8,
|
|
15
|
+
weight_decay=0,
|
|
16
|
+
momentum=0,
|
|
17
|
+
centered=False,
|
|
18
|
+
optim_bits=32,
|
|
19
|
+
args=None,
|
|
20
|
+
min_8bit_size=4096,
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
Base RMSprop optimizer.
|
|
24
|
+
|
|
25
|
+
Arguments:
|
|
26
|
+
params (`torch.tensor`):
|
|
27
|
+
The input parameters to optimize.
|
|
28
|
+
lr (`float`, defaults to 1e-2):
|
|
29
|
+
The learning rate.
|
|
30
|
+
alpha (`float`, defaults to 0.99):
|
|
31
|
+
The alpha value is the decay rate of the squared gradients of the optimizer.
|
|
32
|
+
eps (`float`, defaults to 1e-8):
|
|
33
|
+
The epsilon value prevents division by zero in the optimizer.
|
|
34
|
+
weight_decay (`float`, defaults to 0.0):
|
|
35
|
+
The weight decay value for the optimizer.
|
|
36
|
+
momentum (`float`, defaults to 0):
|
|
37
|
+
The momentum value speeds up the optimizer by taking bigger steps.
|
|
38
|
+
centered (`bool`, defaults to `False`):
|
|
39
|
+
Whether the gradients are normalized by the variance. If `True`, it can help training at the expense of additional compute.
|
|
40
|
+
optim_bits (`int`, defaults to 32):
|
|
41
|
+
The number of bits of the optimizer state.
|
|
42
|
+
args (`object`, defaults to `None`):
|
|
43
|
+
An object with additional arguments.
|
|
44
|
+
min_8bit_size (`int`, defaults to 4096):
|
|
45
|
+
The minimum number of elements of the parameter tensors for 8-bit optimization.
|
|
46
|
+
"""
|
|
47
|
+
if alpha == 0:
|
|
48
|
+
raise NotImplementedError("RMSprop with alpha==0.0 is not supported!")
|
|
49
|
+
if centered:
|
|
50
|
+
raise NotImplementedError("Centered RMSprop is not supported!")
|
|
51
|
+
super().__init__(
|
|
52
|
+
"rmsprop",
|
|
53
|
+
params,
|
|
54
|
+
lr,
|
|
55
|
+
(alpha, momentum),
|
|
56
|
+
eps,
|
|
57
|
+
weight_decay,
|
|
58
|
+
optim_bits,
|
|
59
|
+
args,
|
|
60
|
+
min_8bit_size,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class RMSprop8bit(Optimizer1State):
|
|
65
|
+
def __init__(
|
|
66
|
+
self,
|
|
67
|
+
params,
|
|
68
|
+
lr=1e-2,
|
|
69
|
+
alpha=0.99,
|
|
70
|
+
eps=1e-8,
|
|
71
|
+
weight_decay=0,
|
|
72
|
+
momentum=0,
|
|
73
|
+
centered=False,
|
|
74
|
+
args=None,
|
|
75
|
+
min_8bit_size=4096,
|
|
76
|
+
):
|
|
77
|
+
"""
|
|
78
|
+
8-bit RMSprop optimizer.
|
|
79
|
+
|
|
80
|
+
Arguments:
|
|
81
|
+
params (`torch.tensor`):
|
|
82
|
+
The input parameters to optimize.
|
|
83
|
+
lr (`float`, defaults to 1e-2):
|
|
84
|
+
The learning rate.
|
|
85
|
+
alpha (`float`, defaults to 0.99):
|
|
86
|
+
The alpha value is the decay rate of the squared gradients of the optimizer.
|
|
87
|
+
eps (`float`, defaults to 1e-8):
|
|
88
|
+
The epsilon value prevents division by zero in the optimizer.
|
|
89
|
+
weight_decay (`float`, defaults to 0.0):
|
|
90
|
+
The weight decay value for the optimizer.
|
|
91
|
+
momentum (`float`, defaults to 0):
|
|
92
|
+
The momentum value speeds up the optimizer by taking bigger steps.
|
|
93
|
+
centered (`bool`, defaults to `False`):
|
|
94
|
+
Whether the gradients are normalized by the variance. If `True`, it can help training at the expense of additional compute.
|
|
95
|
+
args (`object`, defaults to `None`):
|
|
96
|
+
An object with additional arguments.
|
|
97
|
+
min_8bit_size (`int`, defaults to 4096):
|
|
98
|
+
The minimum number of elements of the parameter tensors for 8-bit optimization.
|
|
99
|
+
"""
|
|
100
|
+
if alpha == 0:
|
|
101
|
+
raise NotImplementedError("RMSprop with alpha==0.0 is not supported!")
|
|
102
|
+
if centered:
|
|
103
|
+
raise NotImplementedError("Centered RMSprop is not supported!")
|
|
104
|
+
super().__init__(
|
|
105
|
+
"rmsprop",
|
|
106
|
+
params,
|
|
107
|
+
lr,
|
|
108
|
+
(alpha, momentum),
|
|
109
|
+
eps,
|
|
110
|
+
weight_decay,
|
|
111
|
+
8,
|
|
112
|
+
args,
|
|
113
|
+
min_8bit_size,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class RMSprop32bit(Optimizer1State):
|
|
118
|
+
def __init__(
|
|
119
|
+
self,
|
|
120
|
+
params,
|
|
121
|
+
lr=1e-2,
|
|
122
|
+
alpha=0.99,
|
|
123
|
+
eps=1e-8,
|
|
124
|
+
weight_decay=0,
|
|
125
|
+
momentum=0,
|
|
126
|
+
centered=False,
|
|
127
|
+
args=None,
|
|
128
|
+
min_8bit_size=4096,
|
|
129
|
+
):
|
|
130
|
+
"""
|
|
131
|
+
32-bit RMSprop optimizer.
|
|
132
|
+
|
|
133
|
+
Arguments:
|
|
134
|
+
params (`torch.tensor`):
|
|
135
|
+
The input parameters to optimize.
|
|
136
|
+
lr (`float`, defaults to 1e-2):
|
|
137
|
+
The learning rate.
|
|
138
|
+
alpha (`float`, defaults to 0.99):
|
|
139
|
+
The alpha value is the decay rate of the squared gradients of the optimizer.
|
|
140
|
+
eps (`float`, defaults to 1e-8):
|
|
141
|
+
The epsilon value prevents division by zero in the optimizer.
|
|
142
|
+
weight_decay (`float`, defaults to 0.0):
|
|
143
|
+
The weight decay value for the optimizer.
|
|
144
|
+
momentum (`float`, defaults to 0):
|
|
145
|
+
The momentum value speeds up the optimizer by taking bigger steps.
|
|
146
|
+
centered (`bool`, defaults to `False`):
|
|
147
|
+
Whether the gradients are normalized by the variance. If `True`, it can help training at the expense of additional compute.
|
|
148
|
+
optim_bits (`int`, defaults to 32):
|
|
149
|
+
The number of bits of the optimizer state.
|
|
150
|
+
args (`object`, defaults to `None`):
|
|
151
|
+
An object with additional arguments.
|
|
152
|
+
min_8bit_size (`int`, defaults to 4096):
|
|
153
|
+
The minimum number of elements of the parameter tensors for 8-bit optimization.
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
if alpha == 0:
|
|
157
|
+
raise NotImplementedError("RMSprop with alpha==0.0 is not supported!")
|
|
158
|
+
if centered:
|
|
159
|
+
raise NotImplementedError("Centered RMSprop is not supported!")
|
|
160
|
+
super().__init__(
|
|
161
|
+
"rmsprop",
|
|
162
|
+
params,
|
|
163
|
+
lr,
|
|
164
|
+
(alpha, momentum),
|
|
165
|
+
eps,
|
|
166
|
+
weight_decay,
|
|
167
|
+
32,
|
|
168
|
+
args,
|
|
169
|
+
min_8bit_size,
|
|
170
|
+
)
|
|
@@ -0,0 +1,152 @@
|
|
|
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 Optimizer1State
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SGD(Optimizer1State):
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
params,
|
|
12
|
+
lr,
|
|
13
|
+
momentum=0,
|
|
14
|
+
dampening=0,
|
|
15
|
+
weight_decay=0,
|
|
16
|
+
nesterov=False,
|
|
17
|
+
optim_bits=32,
|
|
18
|
+
args=None,
|
|
19
|
+
min_8bit_size=4096,
|
|
20
|
+
):
|
|
21
|
+
"""
|
|
22
|
+
Base SGD optimizer.
|
|
23
|
+
|
|
24
|
+
Arguments:
|
|
25
|
+
params (`torch.tensor`):
|
|
26
|
+
The input parameters to optimize.
|
|
27
|
+
lr (`float`):
|
|
28
|
+
The learning rate.
|
|
29
|
+
momentum (`float`, defaults to 0):
|
|
30
|
+
The momentum value speeds up the optimizer by taking bigger steps.
|
|
31
|
+
dampening (`float`, defaults to 0):
|
|
32
|
+
The dampening value reduces the momentum of the optimizer.
|
|
33
|
+
weight_decay (`float`, defaults to 0.0):
|
|
34
|
+
The weight decay value for the optimizer.
|
|
35
|
+
nesterov (`bool`, defaults to `False`):
|
|
36
|
+
Whether to use Nesterov momentum.
|
|
37
|
+
optim_bits (`int`, defaults to 32):
|
|
38
|
+
The number of bits of the optimizer state.
|
|
39
|
+
args (`object`, defaults to `None`):
|
|
40
|
+
An object with additional arguments.
|
|
41
|
+
min_8bit_size (`int`, defaults to 4096):
|
|
42
|
+
The minimum number of elements of the parameter tensors for 8-bit optimization.
|
|
43
|
+
"""
|
|
44
|
+
if momentum == 0:
|
|
45
|
+
raise NotImplementedError("SGD without momentum is not supported!")
|
|
46
|
+
super().__init__(
|
|
47
|
+
"momentum",
|
|
48
|
+
params,
|
|
49
|
+
lr,
|
|
50
|
+
(momentum, dampening),
|
|
51
|
+
0.0,
|
|
52
|
+
weight_decay,
|
|
53
|
+
optim_bits,
|
|
54
|
+
args,
|
|
55
|
+
min_8bit_size,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class SGD8bit(Optimizer1State):
|
|
60
|
+
def __init__(
|
|
61
|
+
self,
|
|
62
|
+
params,
|
|
63
|
+
lr,
|
|
64
|
+
momentum=0,
|
|
65
|
+
dampening=0,
|
|
66
|
+
weight_decay=0,
|
|
67
|
+
nesterov=False,
|
|
68
|
+
args=None,
|
|
69
|
+
min_8bit_size=4096,
|
|
70
|
+
):
|
|
71
|
+
"""
|
|
72
|
+
8-bit SGD optimizer.
|
|
73
|
+
|
|
74
|
+
Arguments:
|
|
75
|
+
params (`torch.tensor`):
|
|
76
|
+
The input parameters to optimize.
|
|
77
|
+
lr (`float`):
|
|
78
|
+
The learning rate.
|
|
79
|
+
momentum (`float`, defaults to 0):
|
|
80
|
+
The momentum value speeds up the optimizer by taking bigger steps.
|
|
81
|
+
dampening (`float`, defaults to 0):
|
|
82
|
+
The dampening value reduces the momentum of the optimizer.
|
|
83
|
+
weight_decay (`float`, defaults to 0.0):
|
|
84
|
+
The weight decay value for the optimizer.
|
|
85
|
+
nesterov (`bool`, defaults to `False`):
|
|
86
|
+
Whether to use Nesterov momentum.
|
|
87
|
+
args (`object`, defaults to `None`):
|
|
88
|
+
An object with additional arguments.
|
|
89
|
+
min_8bit_size (`int`, defaults to 4096):
|
|
90
|
+
The minimum number of elements of the parameter tensors for 8-bit optimization.
|
|
91
|
+
"""
|
|
92
|
+
if momentum == 0:
|
|
93
|
+
raise NotImplementedError("SGD without momentum is not supported!")
|
|
94
|
+
super().__init__(
|
|
95
|
+
"momentum",
|
|
96
|
+
params,
|
|
97
|
+
lr,
|
|
98
|
+
(momentum, dampening),
|
|
99
|
+
0.0,
|
|
100
|
+
weight_decay,
|
|
101
|
+
8,
|
|
102
|
+
args,
|
|
103
|
+
min_8bit_size,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class SGD32bit(Optimizer1State):
|
|
108
|
+
def __init__(
|
|
109
|
+
self,
|
|
110
|
+
params,
|
|
111
|
+
lr,
|
|
112
|
+
momentum=0,
|
|
113
|
+
dampening=0,
|
|
114
|
+
weight_decay=0,
|
|
115
|
+
nesterov=False,
|
|
116
|
+
args=None,
|
|
117
|
+
min_8bit_size=4096,
|
|
118
|
+
):
|
|
119
|
+
"""
|
|
120
|
+
32-bit SGD optimizer.
|
|
121
|
+
|
|
122
|
+
Arguments:
|
|
123
|
+
params (`torch.tensor`):
|
|
124
|
+
The input parameters to optimize.
|
|
125
|
+
lr (`float`):
|
|
126
|
+
The learning rate.
|
|
127
|
+
momentum (`float`, defaults to 0):
|
|
128
|
+
The momentum value speeds up the optimizer by taking bigger steps.
|
|
129
|
+
dampening (`float`, defaults to 0):
|
|
130
|
+
The dampening value reduces the momentum of the optimizer.
|
|
131
|
+
weight_decay (`float`, defaults to 0.0):
|
|
132
|
+
The weight decay value for the optimizer.
|
|
133
|
+
nesterov (`bool`, defaults to `False`):
|
|
134
|
+
Whether to use Nesterov momentum.
|
|
135
|
+
args (`object`, defaults to `None`):
|
|
136
|
+
An object with additional arguments.
|
|
137
|
+
min_8bit_size (`int`, defaults to 4096):
|
|
138
|
+
The minimum number of elements of the parameter tensors for 8-bit optimization.
|
|
139
|
+
"""
|
|
140
|
+
if momentum == 0:
|
|
141
|
+
raise NotImplementedError("SGD without momentum is not supported!")
|
|
142
|
+
super().__init__(
|
|
143
|
+
"momentum",
|
|
144
|
+
params,
|
|
145
|
+
lr,
|
|
146
|
+
(momentum, dampening),
|
|
147
|
+
0.0,
|
|
148
|
+
weight_decay,
|
|
149
|
+
32,
|
|
150
|
+
args,
|
|
151
|
+
min_8bit_size,
|
|
152
|
+
)
|
bitsandbytes/py.typed
ADDED
|
File without changes
|
bitsandbytes/utils.py
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import shlex
|
|
4
|
+
import subprocess
|
|
5
|
+
|
|
6
|
+
import torch
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def outlier_hook(module, input):
|
|
12
|
+
assert isinstance(module, torch.nn.Linear)
|
|
13
|
+
tracer = OutlierTracer.get_instance()
|
|
14
|
+
hvalue = tracer.get_hvalue(module.weight)
|
|
15
|
+
if hvalue not in tracer.hvalue2outlier_idx:
|
|
16
|
+
outlier_idx = find_outlier_dims(module.weight)
|
|
17
|
+
tracer.outliers.append(outlier_idx)
|
|
18
|
+
tracer.hvalues.append(hvalue)
|
|
19
|
+
if len(tracer.outliers) > 1:
|
|
20
|
+
# assign the current layer the outlier idx found from the weight
|
|
21
|
+
# of the previous linear layer
|
|
22
|
+
if tracer.outliers[-1].numel() > 0:
|
|
23
|
+
assert tracer.outliers[-1].max() < module.weight.shape[1]
|
|
24
|
+
tracer.hvalue2outlier_idx[hvalue] = tracer.outliers[-1]
|
|
25
|
+
|
|
26
|
+
else:
|
|
27
|
+
# first layer, we cannot use the weight for outlier detection
|
|
28
|
+
# we follow a mixed approach:
|
|
29
|
+
# (1) zscore test of std of hidden dimension
|
|
30
|
+
# (2) magnitude > 6 test
|
|
31
|
+
merged = input[0].view(-1, input[0].shape[-1])
|
|
32
|
+
# (1) zscore test of std of hidden dimension
|
|
33
|
+
outlier_idx = find_outlier_dims(merged, reduction_dim=1, zscore=3)
|
|
34
|
+
# (2) magnitude > 6 test
|
|
35
|
+
dims = (torch.abs(input[0]) > 6).sum(dim=list(range(len(input[0].shape) - 1)))
|
|
36
|
+
outlier_idx2 = torch.where(dims > 0)[0]
|
|
37
|
+
outlier_idx = torch.cat([outlier_idx, outlier_idx2]).unique()
|
|
38
|
+
tracer.hvalue2outlier_idx[hvalue] = outlier_idx
|
|
39
|
+
else:
|
|
40
|
+
for hook in tracer.hooks:
|
|
41
|
+
hook.remove()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class OutlierTracer:
|
|
45
|
+
_instance = None
|
|
46
|
+
|
|
47
|
+
def __init__(self):
|
|
48
|
+
raise RuntimeError("Call get_instance() instead")
|
|
49
|
+
|
|
50
|
+
def initialize(self, model):
|
|
51
|
+
self.last_w = None
|
|
52
|
+
self.current_outlier_dims = None
|
|
53
|
+
self.hvalues = []
|
|
54
|
+
self.outliers = []
|
|
55
|
+
self.hvalue2outlier_idx = {}
|
|
56
|
+
self.initialized = True
|
|
57
|
+
self.hooks = []
|
|
58
|
+
|
|
59
|
+
for n, m in model.named_modules():
|
|
60
|
+
if isinstance(m, torch.nn.Linear):
|
|
61
|
+
self.hooks.append(m.register_forward_pre_hook(outlier_hook))
|
|
62
|
+
|
|
63
|
+
def is_initialized(self):
|
|
64
|
+
return getattr(self, "initialized", False)
|
|
65
|
+
|
|
66
|
+
def get_hvalue(self, weight):
|
|
67
|
+
return weight.data.storage().data_ptr()
|
|
68
|
+
|
|
69
|
+
def get_outliers(self, weight):
|
|
70
|
+
if not self.is_initialized():
|
|
71
|
+
logger.warning("Outlier tracer is not initialized...")
|
|
72
|
+
return None
|
|
73
|
+
hvalue = self.get_hvalue(weight)
|
|
74
|
+
if hvalue in self.hvalue2outlier_idx:
|
|
75
|
+
return self.hvalue2outlier_idx[hvalue]
|
|
76
|
+
else:
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def get_instance(cls):
|
|
81
|
+
if cls._instance is None:
|
|
82
|
+
cls._instance = cls.__new__(cls)
|
|
83
|
+
return cls._instance
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def find_outlier_dims(weight, reduction_dim=0, zscore=4.0, topk=None, rdm=False):
|
|
87
|
+
if rdm:
|
|
88
|
+
return torch.randint(0, weight.shape[1], size=(topk,), device=weight.device).long()
|
|
89
|
+
|
|
90
|
+
std = weight.std(reduction_dim)
|
|
91
|
+
stdm = std.mean()
|
|
92
|
+
stdstd = std.std()
|
|
93
|
+
|
|
94
|
+
zstd = (std - stdm) / stdstd
|
|
95
|
+
|
|
96
|
+
if topk is not None:
|
|
97
|
+
_, idx = torch.topk(std.abs(), k=topk, dim=0)
|
|
98
|
+
else:
|
|
99
|
+
idx = torch.where(zstd > zscore)[0]
|
|
100
|
+
|
|
101
|
+
return idx
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def execute_and_return(command_string: str) -> tuple[str, str]:
|
|
105
|
+
def _decode(subprocess_err_out_tuple):
|
|
106
|
+
return tuple(to_decode.decode("UTF-8").strip() for to_decode in subprocess_err_out_tuple)
|
|
107
|
+
|
|
108
|
+
def execute_and_return_decoded_std_streams(command_string):
|
|
109
|
+
return _decode(
|
|
110
|
+
subprocess.Popen(
|
|
111
|
+
shlex.split(command_string),
|
|
112
|
+
stdout=subprocess.PIPE,
|
|
113
|
+
stderr=subprocess.PIPE,
|
|
114
|
+
).communicate(),
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
std_out, std_err = execute_and_return_decoded_std_streams(command_string)
|
|
118
|
+
return std_out, std_err
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def replace_linear(
|
|
122
|
+
model,
|
|
123
|
+
linear_replacement,
|
|
124
|
+
skip_modules=("lm_head",),
|
|
125
|
+
copy_weights=False,
|
|
126
|
+
post_processing_function=None,
|
|
127
|
+
):
|
|
128
|
+
"""
|
|
129
|
+
Replace linear modules with a new Linear module.
|
|
130
|
+
Parameters:
|
|
131
|
+
model (`torch.nn.Module`):
|
|
132
|
+
Input model or `torch.nn.Module` as the function is run recursively.
|
|
133
|
+
linear_replacement (`torch.nn.Module`):
|
|
134
|
+
The linear module that replaces the old one. Only expects standard arguments.
|
|
135
|
+
If other arguments need to be passed, use a lambda.
|
|
136
|
+
skip_modules (`List[str]`, *optional*, defaults to `lm_head`):
|
|
137
|
+
List of modules names not to convert. Defaults to `lm_head`.
|
|
138
|
+
copy_weights (`bool`):
|
|
139
|
+
Copy the weights from the old linear module to the new one
|
|
140
|
+
post_processing_function (`str`):
|
|
141
|
+
A function name of the replacement linear class that is called
|
|
142
|
+
after processing.
|
|
143
|
+
"""
|
|
144
|
+
for name, module in model.named_children():
|
|
145
|
+
if len(list(module.children())) > 0:
|
|
146
|
+
replace_linear(module, linear_replacement, skip_modules, copy_weights, post_processing_function)
|
|
147
|
+
|
|
148
|
+
if isinstance(module, torch.nn.Linear) and name not in skip_modules:
|
|
149
|
+
old_module = model._modules[name]
|
|
150
|
+
model._modules[name] = linear_replacement(
|
|
151
|
+
module.in_features,
|
|
152
|
+
module.out_features,
|
|
153
|
+
module.bias is not None,
|
|
154
|
+
)
|
|
155
|
+
if copy_weights:
|
|
156
|
+
model._modules[name].weight = old_module.weight
|
|
157
|
+
model._modules[name].bias = old_module.bias
|
|
158
|
+
|
|
159
|
+
if post_processing_function is not None:
|
|
160
|
+
func = getattr(module, post_processing_function, None)
|
|
161
|
+
if func is not None:
|
|
162
|
+
func(module)
|
|
163
|
+
return model
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def pack_dict_to_tensor(source_dict):
|
|
167
|
+
"""
|
|
168
|
+
Pack a dictionary into a torch tensor for storing quant_state items in state_dict.
|
|
169
|
+
|
|
170
|
+
Parameters:
|
|
171
|
+
- source_dict: The dictionary to be packed.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
A torch tensor containing the packed data.
|
|
175
|
+
"""
|
|
176
|
+
json_str = json.dumps(source_dict)
|
|
177
|
+
json_bytes = json_str.encode("utf-8")
|
|
178
|
+
tensor_data = torch.tensor(list(json_bytes), dtype=torch.uint8)
|
|
179
|
+
|
|
180
|
+
return tensor_data
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def unpack_tensor_to_dict(tensor_data):
|
|
184
|
+
"""
|
|
185
|
+
Unpack a torch tensor into a Python dictionary.
|
|
186
|
+
|
|
187
|
+
Parameters:
|
|
188
|
+
- tensor_data: The torch tensor containing the packed data.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
A Python dictionary containing the unpacked data.
|
|
192
|
+
"""
|
|
193
|
+
json_bytes = bytes(tensor_data.cpu().numpy())
|
|
194
|
+
json_str = json_bytes.decode("utf-8")
|
|
195
|
+
unpacked_dict = json.loads(json_str)
|
|
196
|
+
|
|
197
|
+
return unpacked_dict
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
LINEAR_8BIT_WEIGHTS_FORMAT_MAPPING = {"row": 0, "col32": 1, "col_turing": 2, "col_ampere": 3}
|
|
201
|
+
INVERSE_LINEAR_8BIT_WEIGHTS_FORMAT_MAPPING = {val: name for (name, val) in LINEAR_8BIT_WEIGHTS_FORMAT_MAPPING.items()}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def sync_gpu(t: torch.Tensor):
|
|
205
|
+
if t.device.type == "cuda":
|
|
206
|
+
torch.cuda.synchronize()
|
|
207
|
+
elif t.device.type == "xpu":
|
|
208
|
+
torch.xpu.synchronize()
|