lycoris-lora 3.0.0.dev2__tar.gz → 3.0.0.dev4__tar.gz
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.
- {lycoris_lora-3.0.0.dev2/lycoris_lora.egg-info → lycoris_lora-3.0.0.dev4}/PKG-INFO +1 -4
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/functional/general.py +2 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/base.py +38 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/boft.py +41 -31
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/diag_oft.py +41 -25
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/full.py +30 -15
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/glora.py +103 -53
- lycoris_lora-3.0.0.dev4/lycoris/modules/ia3.py +179 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/locon.py +19 -9
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/loha.py +45 -30
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/lokr.py +51 -29
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4/lycoris_lora.egg-info}/PKG-INFO +1 -4
- lycoris_lora-3.0.0.dev4/lycoris_lora.egg-info/requires.txt +3 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/setup.py +1 -4
- lycoris_lora-3.0.0.dev2/lycoris/modules/ia3.py +0 -67
- lycoris_lora-3.0.0.dev2/lycoris_lora.egg-info/requires.txt +0 -6
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/LICENSE.md +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/README.md +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/config.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/functional/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/functional/locon.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/functional/loha.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/kohya.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/logging.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/dylora.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/modules/norms.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/utils/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/utils/bnb.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/utils/logger.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/utils/preset.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/utils/xformers_utils.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris/wrapper.py +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/SOURCES.txt +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/dependency_links.txt +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/not-zip-safe +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/top_level.txt +0 -0
- {lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lycoris_lora
|
|
3
|
-
Version: 3.0.0.
|
|
3
|
+
Version: 3.0.0.dev4
|
|
4
4
|
Summary: Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion
|
|
5
5
|
Home-page: https://github.com/KohakuBlueleaf/LyCORIS
|
|
6
6
|
Author: Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao
|
|
@@ -8,8 +8,5 @@ Author-email: apolloyeh0123@gmail.com
|
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
9
|
License-File: LICENSE.md
|
|
10
10
|
Requires-Dist: torch
|
|
11
|
-
Requires-Dist: safetensors
|
|
12
|
-
Requires-Dist: diffusers
|
|
13
|
-
Requires-Dist: transformers
|
|
14
11
|
Requires-Dist: einops
|
|
15
12
|
Requires-Dist: toml
|
|
@@ -3,6 +3,7 @@ from collections import OrderedDict
|
|
|
3
3
|
import torch
|
|
4
4
|
import torch.nn as nn
|
|
5
5
|
import torch.nn.functional as F
|
|
6
|
+
import torch.nn.utils.parametrize as parametrize
|
|
6
7
|
|
|
7
8
|
from ..utils.bnb import QuantLinears, log_bypass
|
|
8
9
|
|
|
@@ -181,6 +182,38 @@ class LycorisBaseModule(ModuleCustomSD):
|
|
|
181
182
|
self.org_forward = org_module.forward
|
|
182
183
|
self.org_module = [org_module]
|
|
183
184
|
|
|
185
|
+
@classmethod
|
|
186
|
+
def parametrize(cls, org_module, attr, *args, **kwargs):
|
|
187
|
+
target_param = getattr(org_module, attr)
|
|
188
|
+
kwargs["bypass_mode"] = False
|
|
189
|
+
if target_param.dim() == 2:
|
|
190
|
+
proxy_module = nn.Linear(
|
|
191
|
+
target_param.shape[0], target_param.shape[1], bias=False
|
|
192
|
+
)
|
|
193
|
+
proxy_module.weight = target_param
|
|
194
|
+
elif target_param.dim() > 2:
|
|
195
|
+
module_type = [
|
|
196
|
+
None,
|
|
197
|
+
None,
|
|
198
|
+
None,
|
|
199
|
+
nn.Conv1d,
|
|
200
|
+
nn.Conv2d,
|
|
201
|
+
nn.Conv3d,
|
|
202
|
+
None,
|
|
203
|
+
None,
|
|
204
|
+
][target_param.dim()]
|
|
205
|
+
proxy_module = module_type(
|
|
206
|
+
target_param.shape[0],
|
|
207
|
+
target_param.shape[1],
|
|
208
|
+
*target_param.shape[2:],
|
|
209
|
+
)
|
|
210
|
+
proxy_module.weight = target_param
|
|
211
|
+
module_obj = cls("", proxy_module, *args, **kwargs)
|
|
212
|
+
module_obj.forward = module_obj.parametrize_forward
|
|
213
|
+
module_obj.to(target_param.device)
|
|
214
|
+
parametrize.register_parametrization(org_module, attr, module_obj)
|
|
215
|
+
return module_obj
|
|
216
|
+
|
|
184
217
|
@property
|
|
185
218
|
def dtype(self):
|
|
186
219
|
return self.dtype_tensor.dtype
|
|
@@ -231,5 +264,10 @@ class LycorisBaseModule(ModuleCustomSD):
|
|
|
231
264
|
def bypass_forward(self, x, scale=1):
|
|
232
265
|
raise NotImplementedError
|
|
233
266
|
|
|
267
|
+
def parametrize_forward(self, x: torch.Tensor, *args, **kwargs):
|
|
268
|
+
return self.get_merged_weight(
|
|
269
|
+
multiplier=self.multiplier, shape=x.shape, device=x.device
|
|
270
|
+
)[0].to(x.dtype)
|
|
271
|
+
|
|
234
272
|
def forward(self, *args, **kwargs):
|
|
235
273
|
raise NotImplementedError
|
|
@@ -136,7 +136,7 @@ class ButterflyOFTModule(LycorisBaseModule):
|
|
|
136
136
|
diff = self.make_weight(scale=multiplier, device=device, diff=True)
|
|
137
137
|
if shape is not None:
|
|
138
138
|
diff = diff.view(shape)
|
|
139
|
-
return diff
|
|
139
|
+
return diff, None
|
|
140
140
|
|
|
141
141
|
def get_merged_weight(self, multiplier=1, shape=None, device=None):
|
|
142
142
|
diff = self.make_weight(scale=multiplier, device=device)
|
|
@@ -200,33 +200,43 @@ class ButterflyOFTModule(LycorisBaseModule):
|
|
|
200
200
|
|
|
201
201
|
|
|
202
202
|
if __name__ == "__main__":
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
"test", base_4bit, 1, 4, 1, weight_decompose=False
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
203
|
+
device = torch.device("cuda")
|
|
204
|
+
module = ButterflyOFTModule
|
|
205
|
+
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
206
|
+
base = nn.Linear(128, 128).to(device).half()
|
|
207
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
208
|
+
print(net)
|
|
209
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
210
|
+
test_output = net(test_input)
|
|
211
|
+
torch.sum(test_output).backward()
|
|
212
|
+
print(test_output.shape)
|
|
213
|
+
|
|
214
|
+
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
215
|
+
base_4bit.load_state_dict(base.state_dict())
|
|
216
|
+
base_4bit.to(device)
|
|
217
|
+
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
218
|
+
print(qnet)
|
|
219
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
220
|
+
test_output = qnet(test_input)
|
|
221
|
+
torch.sum(test_output).backward()
|
|
222
|
+
print(test_output.shape)
|
|
223
|
+
|
|
224
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
225
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
226
|
+
device
|
|
227
|
+
)
|
|
228
|
+
print(net)
|
|
229
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
230
|
+
test_output = net(test_input)
|
|
231
|
+
torch.sum(test_output).backward()
|
|
232
|
+
print(test_output.shape)
|
|
233
|
+
|
|
234
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
235
|
+
net = module.parametrize(
|
|
236
|
+
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
237
|
+
).to(device)
|
|
238
|
+
print(base)
|
|
239
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
240
|
+
test_output = base(test_input)
|
|
241
|
+
torch.sum(test_output).backward()
|
|
242
|
+
print(test_output.shape)
|
|
@@ -119,7 +119,7 @@ class DiagOFTModule(LycorisBaseModule):
|
|
|
119
119
|
diff = self.make_weight(scale=multiplier, device=device, diff=True)
|
|
120
120
|
if shape is not None:
|
|
121
121
|
diff = diff.view(shape)
|
|
122
|
-
return diff
|
|
122
|
+
return diff, None
|
|
123
123
|
|
|
124
124
|
def get_merged_weight(self, multiplier=1, shape=None, device=None):
|
|
125
125
|
diff = self.make_weight(scale=multiplier, device=device)
|
|
@@ -185,27 +185,43 @@ class DiagOFTModule(LycorisBaseModule):
|
|
|
185
185
|
|
|
186
186
|
|
|
187
187
|
if __name__ == "__main__":
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
188
|
+
device = torch.device("cuda")
|
|
189
|
+
module = DiagOFTModule
|
|
190
|
+
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
191
|
+
base = nn.Linear(128, 128).to(device).half()
|
|
192
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
193
|
+
print(net)
|
|
194
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
195
|
+
test_output = net(test_input)
|
|
196
|
+
torch.sum(test_output).backward()
|
|
197
|
+
print(test_output.shape)
|
|
198
|
+
|
|
199
|
+
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
200
|
+
base_4bit.load_state_dict(base.state_dict())
|
|
201
|
+
base_4bit.to(device)
|
|
202
|
+
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
203
|
+
print(qnet)
|
|
204
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
205
|
+
test_output = qnet(test_input)
|
|
206
|
+
torch.sum(test_output).backward()
|
|
207
|
+
print(test_output.shape)
|
|
208
|
+
|
|
209
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
210
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
211
|
+
device
|
|
212
|
+
)
|
|
213
|
+
print(net)
|
|
214
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
215
|
+
test_output = net(test_input)
|
|
216
|
+
torch.sum(test_output).backward()
|
|
217
|
+
print(test_output.shape)
|
|
218
|
+
|
|
219
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
220
|
+
net = module.parametrize(
|
|
221
|
+
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
222
|
+
).to(device)
|
|
223
|
+
print(base)
|
|
224
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
225
|
+
test_output = base(test_input)
|
|
226
|
+
torch.sum(test_output).backward()
|
|
227
|
+
print(test_output.shape)
|
|
@@ -158,18 +158,33 @@ class FullModule(LycorisBaseModule):
|
|
|
158
158
|
|
|
159
159
|
|
|
160
160
|
if __name__ == "__main__":
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
161
|
+
device = torch.device("cuda")
|
|
162
|
+
module = FullModule
|
|
163
|
+
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
164
|
+
base = nn.Linear(128, 128).to(device).half()
|
|
165
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
166
|
+
print(net)
|
|
167
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
168
|
+
test_output = net(test_input)
|
|
169
|
+
torch.sum(test_output).backward()
|
|
170
|
+
print(test_output.shape)
|
|
171
|
+
|
|
172
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
173
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
174
|
+
device
|
|
175
|
+
)
|
|
176
|
+
print(net)
|
|
177
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
178
|
+
test_output = net(test_input)
|
|
179
|
+
torch.sum(test_output).backward()
|
|
180
|
+
print(test_output.shape)
|
|
181
|
+
|
|
182
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
183
|
+
net = module.parametrize(
|
|
184
|
+
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
185
|
+
).to(device)
|
|
186
|
+
print(base)
|
|
187
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
188
|
+
test_output = base(test_input)
|
|
189
|
+
torch.sum(test_output).backward()
|
|
190
|
+
print(test_output.shape)
|
|
@@ -5,6 +5,7 @@ import torch.nn as nn
|
|
|
5
5
|
import torch.nn.functional as F
|
|
6
6
|
|
|
7
7
|
from .base import LycorisBaseModule
|
|
8
|
+
from ..utils import tucker_weight_from_conv
|
|
8
9
|
from ..utils.bnb import LinearNF4
|
|
9
10
|
|
|
10
11
|
|
|
@@ -52,7 +53,7 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
52
53
|
bypass_mode,
|
|
53
54
|
)
|
|
54
55
|
if self.module_type not in self.support_module:
|
|
55
|
-
raise ValueError(f"{self.module_type} is not supported in
|
|
56
|
+
raise ValueError(f"{self.module_type} is not supported in GLoRA algo.")
|
|
56
57
|
self.lora_dim = lora_dim
|
|
57
58
|
self.tucker = False
|
|
58
59
|
self.rs_lora = rs_lora
|
|
@@ -68,17 +69,12 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
68
69
|
self.tucker = use_tucker and k_size != (1, 1)
|
|
69
70
|
self.down_op = self.op
|
|
70
71
|
self.up_op = self.op
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
lora_dim, lora_dim, k_size, stride, padding, bias=False
|
|
75
|
-
)
|
|
76
|
-
self.tucker = True
|
|
77
|
-
else:
|
|
78
|
-
self.a2 = self.module(
|
|
79
|
-
in_dim, lora_dim, k_size, stride, padding, bias=False
|
|
80
|
-
)
|
|
72
|
+
|
|
73
|
+
# A
|
|
74
|
+
self.a2 = self.module(in_dim, lora_dim, (1, 1), bias=False)
|
|
81
75
|
self.a1 = self.module(lora_dim, in_dim, (1, 1), bias=False)
|
|
76
|
+
|
|
77
|
+
# B
|
|
82
78
|
if use_tucker and k_size != (1, 1):
|
|
83
79
|
self.b2 = self.module(in_dim, lora_dim, (1, 1), bias=False)
|
|
84
80
|
self.bm = self.module(
|
|
@@ -90,7 +86,7 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
90
86
|
in_dim, lora_dim, k_size, stride, padding, bias=False
|
|
91
87
|
)
|
|
92
88
|
self.b1 = self.module(lora_dim, out_dim, (1, 1), bias=False)
|
|
93
|
-
|
|
89
|
+
else:
|
|
94
90
|
self.isconv = False
|
|
95
91
|
self.down_op = F.linear
|
|
96
92
|
self.up_op = F.linear
|
|
@@ -100,8 +96,6 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
100
96
|
self.a1 = nn.Linear(lora_dim, in_dim, bias=False)
|
|
101
97
|
self.b2 = nn.Linear(in_dim, lora_dim, bias=False)
|
|
102
98
|
self.b1 = nn.Linear(lora_dim, out_dim, bias=False)
|
|
103
|
-
else:
|
|
104
|
-
raise NotImplementedError
|
|
105
99
|
|
|
106
100
|
if type(alpha) == torch.Tensor:
|
|
107
101
|
alpha = alpha.detach().float().numpy() # without casting, bf16 causes error
|
|
@@ -129,19 +123,35 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
129
123
|
def make_weight(self, device=None):
|
|
130
124
|
wa1 = self.a1.weight.view(self.a1.weight.size(0), -1)
|
|
131
125
|
wa2 = self.a2.weight.view(self.a2.weight.size(0), -1)
|
|
132
|
-
wb1 = self.b1.weight.view(self.b1.weight.size(0), -1)
|
|
133
|
-
wb2 = self.b2.weight.view(self.b2.weight.size(0), -1)
|
|
134
|
-
orig = self.org_weight.view(self.org_module[0].weight.size(0), -1)
|
|
135
|
-
return (wb2 @ wb1) + ((orig @ wa2) @ wa1)
|
|
136
126
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
127
|
+
if self.tucker:
|
|
128
|
+
wb = tucker_weight_from_conv(self.b1.weight, self.b2.weight, self.bm.weight)
|
|
129
|
+
else:
|
|
130
|
+
wb1 = self.b1.weight.view(self.b1.weight.size(0), -1)
|
|
131
|
+
wb2 = self.b2.weight.view(self.b2.weight.size(0), -1)
|
|
132
|
+
wb = wb1 @ wb2
|
|
133
|
+
orig = self.org_weight
|
|
134
|
+
if orig.dim() > 2:
|
|
135
|
+
w_wa1 = torch.einsum("o i ..., i j -> o j ...", orig, wa1)
|
|
136
|
+
w_wa2 = torch.einsum("o i ..., i j -> o j ...", w_wa1, wa2)
|
|
137
|
+
else:
|
|
138
|
+
w_wa2 = (orig @ wa1) @ wa2
|
|
139
|
+
return (wb + w_wa2) * self.scale
|
|
140
|
+
|
|
141
|
+
def get_diff_weight(self, multiplier=1.0, shape=None, device=None):
|
|
142
|
+
weight = self.make_weight(device) * multiplier
|
|
143
|
+
if shape is not None:
|
|
144
|
+
weight = weight.view(shape)
|
|
145
|
+
return weight, None
|
|
146
|
+
|
|
147
|
+
def get_merged_weight(self, multiplier=1, shape=None, device=None):
|
|
148
|
+
diff_w, _ = self.get_diff_weight(multiplier, shape, device)
|
|
149
|
+
return self.org_weight + diff_w, None
|
|
142
150
|
|
|
143
|
-
|
|
144
|
-
|
|
151
|
+
def _bypass_forward(self, x, scale=1, diff=False):
|
|
152
|
+
scale = self.scale * scale
|
|
153
|
+
ax_mid = self.a2(x) * scale
|
|
154
|
+
bx_mid = self.b2(x) * scale
|
|
145
155
|
|
|
146
156
|
if self.rank_dropout and self.training:
|
|
147
157
|
drop_a = (
|
|
@@ -161,36 +171,76 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
161
171
|
drop_b = drop_b.view(*[1] * (dims - 1), -1)
|
|
162
172
|
ax_mid = ax_mid * drop_a
|
|
163
173
|
bx_mid = bx_mid * drop_b
|
|
164
|
-
|
|
165
174
|
return (
|
|
166
|
-
self.org_forward(
|
|
167
|
-
|
|
175
|
+
self.org_forward(
|
|
176
|
+
(0 if diff else x) + self.drop(self.a1(ax_mid)) * self.scale
|
|
177
|
+
)
|
|
178
|
+
+ self.drop(self.b1(bx_mid)) * self.scale
|
|
168
179
|
)
|
|
169
180
|
|
|
181
|
+
def bypass_forward_diff(self, x, scale=1):
|
|
182
|
+
return self._bypass_forward(x, scale=scale, diff=True)
|
|
183
|
+
|
|
184
|
+
def bypass_forward(self, x, scale=1):
|
|
185
|
+
return self._bypass_forward(x, scale=scale, diff=False)
|
|
186
|
+
|
|
187
|
+
def forward(self, x, *args, **kwargs):
|
|
188
|
+
if self.module_dropout and self.training:
|
|
189
|
+
if torch.rand(1) < self.module_dropout:
|
|
190
|
+
return self.org_forward(x)
|
|
191
|
+
if self.bypass_mode:
|
|
192
|
+
return self.bypass_forward(x, self.multiplier)
|
|
193
|
+
else:
|
|
194
|
+
weight = (
|
|
195
|
+
self.org_module[0].weight.data.to(self.dtype)
|
|
196
|
+
+ self.get_diff_weight(multiplier=self.multiplier)[0]
|
|
197
|
+
)
|
|
198
|
+
bias = (
|
|
199
|
+
None
|
|
200
|
+
if self.org_module[0].bias is None
|
|
201
|
+
else self.org_module[0].bias.data
|
|
202
|
+
)
|
|
203
|
+
return self.op(x, weight, bias, **self.kw_dict)
|
|
204
|
+
|
|
170
205
|
|
|
171
206
|
if __name__ == "__main__":
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
207
|
+
device = torch.device("cuda")
|
|
208
|
+
module = GLoRAModule
|
|
209
|
+
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
210
|
+
base = nn.Linear(128, 128).to(device).half()
|
|
211
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
212
|
+
print(net)
|
|
213
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
214
|
+
test_output = net(test_input)
|
|
215
|
+
torch.sum(test_output).backward()
|
|
216
|
+
print(test_output.shape)
|
|
217
|
+
|
|
218
|
+
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
219
|
+
base_4bit.load_state_dict(base.state_dict())
|
|
220
|
+
base_4bit.to(device)
|
|
221
|
+
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
222
|
+
print(qnet)
|
|
223
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
224
|
+
test_output = qnet(test_input)
|
|
225
|
+
torch.sum(test_output).backward()
|
|
226
|
+
print(test_output.shape)
|
|
227
|
+
|
|
228
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
229
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
230
|
+
device
|
|
231
|
+
)
|
|
232
|
+
print(net)
|
|
233
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
234
|
+
test_output = net(test_input)
|
|
235
|
+
torch.sum(test_output).backward()
|
|
236
|
+
print(test_output.shape)
|
|
237
|
+
|
|
238
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
239
|
+
net = module.parametrize(
|
|
240
|
+
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
241
|
+
).to(device)
|
|
242
|
+
print(base)
|
|
243
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
244
|
+
test_output = base(test_input)
|
|
245
|
+
torch.sum(test_output).backward()
|
|
246
|
+
print(test_output.shape)
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn as nn
|
|
3
|
+
|
|
4
|
+
from .base import LycorisBaseModule
|
|
5
|
+
from ..utils.bnb import LinearNF4
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class IA3Module(LycorisBaseModule):
|
|
9
|
+
support_module = {
|
|
10
|
+
"linear",
|
|
11
|
+
"conv1d",
|
|
12
|
+
"conv2d",
|
|
13
|
+
"conv3d",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
lora_name,
|
|
19
|
+
org_module: nn.Module,
|
|
20
|
+
multiplier=1.0,
|
|
21
|
+
lora_dim=4,
|
|
22
|
+
alpha=1,
|
|
23
|
+
dropout=0.0,
|
|
24
|
+
rank_dropout=0.0,
|
|
25
|
+
module_dropout=0.0,
|
|
26
|
+
use_tucker=False,
|
|
27
|
+
use_scalar=False,
|
|
28
|
+
rank_dropout_scale=False,
|
|
29
|
+
weight_decompose=False,
|
|
30
|
+
bypass_mode=False,
|
|
31
|
+
rs_lora=False,
|
|
32
|
+
train_on_input=False,
|
|
33
|
+
**kwargs,
|
|
34
|
+
):
|
|
35
|
+
"""if alpha == 0 or None, alpha is rank (no scaling)."""
|
|
36
|
+
super().__init__(
|
|
37
|
+
lora_name,
|
|
38
|
+
org_module,
|
|
39
|
+
multiplier,
|
|
40
|
+
dropout,
|
|
41
|
+
rank_dropout,
|
|
42
|
+
module_dropout,
|
|
43
|
+
rank_dropout_scale,
|
|
44
|
+
bypass_mode,
|
|
45
|
+
)
|
|
46
|
+
if self.module_type not in self.support_module:
|
|
47
|
+
raise ValueError(f"{self.module_type} is not supported in IA^3 algo.")
|
|
48
|
+
self.lora_dim = lora_dim
|
|
49
|
+
self.tucker = False
|
|
50
|
+
self.rs_lora = rs_lora
|
|
51
|
+
|
|
52
|
+
self.shape = org_module.weight.shape
|
|
53
|
+
if self.module_type.startswith("conv"):
|
|
54
|
+
self.isconv = True
|
|
55
|
+
in_dim = org_module.in_channels
|
|
56
|
+
out_dim = org_module.out_channels
|
|
57
|
+
if train_on_input:
|
|
58
|
+
train_dim = in_dim
|
|
59
|
+
else:
|
|
60
|
+
train_dim = out_dim
|
|
61
|
+
self.weight = nn.Parameter(
|
|
62
|
+
torch.empty(1, train_dim, *(1 for _ in self.shape[2:]))
|
|
63
|
+
)
|
|
64
|
+
else:
|
|
65
|
+
in_dim = org_module.in_features
|
|
66
|
+
out_dim = org_module.out_features
|
|
67
|
+
if train_on_input:
|
|
68
|
+
train_dim = in_dim
|
|
69
|
+
else:
|
|
70
|
+
train_dim = out_dim
|
|
71
|
+
|
|
72
|
+
self.weight = nn.Parameter(torch.empty(train_dim))
|
|
73
|
+
|
|
74
|
+
# Need more experiences on init method
|
|
75
|
+
torch.nn.init.constant_(self.weight, 0)
|
|
76
|
+
|
|
77
|
+
self.multiplier = multiplier
|
|
78
|
+
self.train_input = train_on_input
|
|
79
|
+
self.register_buffer("on_input", torch.tensor(int(train_on_input)))
|
|
80
|
+
|
|
81
|
+
def apply_to(self):
|
|
82
|
+
self.org_forward = self.org_module[0].forward
|
|
83
|
+
self.org_module[0].forward = self.forward
|
|
84
|
+
|
|
85
|
+
def make_weight(self, multiplier=1, shape=None, device=None, diff=False):
|
|
86
|
+
weight = self.weight * multiplier + int(not diff)
|
|
87
|
+
if self.train_input:
|
|
88
|
+
diff = self.org_weight * weight
|
|
89
|
+
else:
|
|
90
|
+
diff = self.org_weight.transpose(0, 1) * weight
|
|
91
|
+
diff = diff.transpose(0, 1)
|
|
92
|
+
if shape is not None:
|
|
93
|
+
diff = diff.view(shape)
|
|
94
|
+
if device is not None:
|
|
95
|
+
diff = diff.to(device)
|
|
96
|
+
return diff
|
|
97
|
+
|
|
98
|
+
def get_diff_weight(self, multiplier=1, shape=None, device=None):
|
|
99
|
+
diff = self.make_weight(
|
|
100
|
+
multiplier=multiplier, shape=shape, device=device, diff=True
|
|
101
|
+
)
|
|
102
|
+
return diff, None
|
|
103
|
+
|
|
104
|
+
def get_merged_weight(self, multiplier=1, shape=None, device=None):
|
|
105
|
+
diff = self.make_weight(multiplier=multiplier, shape=shape, device=device)
|
|
106
|
+
return diff, None
|
|
107
|
+
|
|
108
|
+
def _bypass_forward(self, x, scale=1, diff=False):
|
|
109
|
+
weight = self.weight * scale + int(not diff)
|
|
110
|
+
if self.train_input:
|
|
111
|
+
x = x * weight
|
|
112
|
+
out = self.org_forward(x)
|
|
113
|
+
if not self.train_input:
|
|
114
|
+
out = out * weight
|
|
115
|
+
return out
|
|
116
|
+
|
|
117
|
+
def bypass_forward_diff(self, x, scale=1):
|
|
118
|
+
return self._bypass_forward(x, scale, diff=True)
|
|
119
|
+
|
|
120
|
+
def bypass_forward(self, x, scale=1):
|
|
121
|
+
return self._bypass_forward(x, scale, diff=False)
|
|
122
|
+
|
|
123
|
+
def forward(self, x, *args, **kwargs):
|
|
124
|
+
if self.module_dropout and self.training:
|
|
125
|
+
if torch.rand(1) < self.module_dropout:
|
|
126
|
+
return self.org_forward(x)
|
|
127
|
+
if self.bypass_mode:
|
|
128
|
+
return self.bypass_forward(x, self.multiplier)
|
|
129
|
+
else:
|
|
130
|
+
weight = self.get_merged_weight(multiplier=self.multiplier)[0]
|
|
131
|
+
bias = (
|
|
132
|
+
None
|
|
133
|
+
if self.org_module[0].bias is None
|
|
134
|
+
else self.org_module[0].bias.data
|
|
135
|
+
)
|
|
136
|
+
return self.op(x, weight, bias, **self.kw_dict)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
if __name__ == "__main__":
|
|
140
|
+
device = torch.device("cuda")
|
|
141
|
+
module = IA3Module
|
|
142
|
+
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
143
|
+
base = nn.Linear(128, 128).to(device).half()
|
|
144
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
145
|
+
print(net)
|
|
146
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
147
|
+
test_output = net(test_input)
|
|
148
|
+
torch.sum(test_output).backward()
|
|
149
|
+
print(test_output.shape)
|
|
150
|
+
|
|
151
|
+
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
152
|
+
base_4bit.load_state_dict(base.state_dict())
|
|
153
|
+
base_4bit.to(device)
|
|
154
|
+
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
155
|
+
print(qnet)
|
|
156
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
157
|
+
test_output = qnet(test_input)
|
|
158
|
+
torch.sum(test_output).backward()
|
|
159
|
+
print(test_output.shape)
|
|
160
|
+
|
|
161
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
162
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
163
|
+
device
|
|
164
|
+
)
|
|
165
|
+
print(net)
|
|
166
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
167
|
+
test_output = net(test_input)
|
|
168
|
+
torch.sum(test_output).backward()
|
|
169
|
+
print(test_output.shape)
|
|
170
|
+
|
|
171
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
172
|
+
net = module.parametrize(
|
|
173
|
+
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
174
|
+
).to(device)
|
|
175
|
+
print(base)
|
|
176
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
177
|
+
test_output = base(test_input)
|
|
178
|
+
torch.sum(test_output).backward()
|
|
179
|
+
print(test_output.shape)
|
|
@@ -183,11 +183,12 @@ class LoConModule(LycorisBaseModule):
|
|
|
183
183
|
diff = diff.view(shape)
|
|
184
184
|
if device is not None:
|
|
185
185
|
diff = diff.to(device)
|
|
186
|
-
return diff
|
|
186
|
+
return diff, None
|
|
187
187
|
|
|
188
188
|
def get_merged_weight(self, multiplier=1, shape=None, device=None):
|
|
189
|
-
merged =
|
|
190
|
-
|
|
189
|
+
merged = (
|
|
190
|
+
self.org_module[0].weight.data
|
|
191
|
+
+ self.get_diff_weight(multiplier=multiplier, shape=shape, device=device)[0]
|
|
191
192
|
)
|
|
192
193
|
if self.wd:
|
|
193
194
|
merged = self.apply_weight_decompose(merged)
|
|
@@ -278,9 +279,10 @@ class LoConModule(LycorisBaseModule):
|
|
|
278
279
|
|
|
279
280
|
if __name__ == "__main__":
|
|
280
281
|
device = torch.device("cuda")
|
|
282
|
+
module = LoConModule
|
|
281
283
|
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
282
284
|
base = nn.Linear(128, 128).to(device).half()
|
|
283
|
-
net =
|
|
285
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
284
286
|
print(net)
|
|
285
287
|
test_input = torch.randn(1, 128).to(device).half()
|
|
286
288
|
test_output = net(test_input)
|
|
@@ -290,9 +292,7 @@ if __name__ == "__main__":
|
|
|
290
292
|
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
291
293
|
base_4bit.load_state_dict(base.state_dict())
|
|
292
294
|
base_4bit.to(device)
|
|
293
|
-
qnet =
|
|
294
|
-
device
|
|
295
|
-
)
|
|
295
|
+
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
296
296
|
print(qnet)
|
|
297
297
|
test_input = torch.randn(1, 128).to(device).half()
|
|
298
298
|
test_output = qnet(test_input)
|
|
@@ -300,11 +300,21 @@ if __name__ == "__main__":
|
|
|
300
300
|
print(test_output.shape)
|
|
301
301
|
|
|
302
302
|
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
303
|
-
net =
|
|
304
|
-
|
|
303
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
304
|
+
device
|
|
305
305
|
)
|
|
306
306
|
print(net)
|
|
307
307
|
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
308
308
|
test_output = net(test_input)
|
|
309
309
|
torch.sum(test_output).backward()
|
|
310
310
|
print(test_output.shape)
|
|
311
|
+
|
|
312
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
313
|
+
net = module.parametrize(
|
|
314
|
+
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
315
|
+
)
|
|
316
|
+
print(base)
|
|
317
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
318
|
+
test_output = base(test_input)
|
|
319
|
+
torch.sum(test_output).backward()
|
|
320
|
+
print(test_output.shape)
|
|
@@ -181,15 +181,16 @@ class LohaModule(LycorisBaseModule):
|
|
|
181
181
|
diff = self.get_weight(shape) * scale
|
|
182
182
|
if device is not None:
|
|
183
183
|
diff = diff.to(device)
|
|
184
|
-
return diff
|
|
184
|
+
return diff, None
|
|
185
185
|
|
|
186
186
|
def get_merged_weight(self, multiplier=1, shape=None, device=None):
|
|
187
|
-
merged =
|
|
188
|
-
|
|
187
|
+
merged = (
|
|
188
|
+
self.org_module[0].weight.data
|
|
189
|
+
+ self.get_diff_weight(multiplier=multiplier, shape=shape, device=device)[0]
|
|
189
190
|
)
|
|
190
191
|
if self.wd:
|
|
191
192
|
merged = self.apply_weight_decompose(merged)
|
|
192
|
-
return merged
|
|
193
|
+
return merged, None
|
|
193
194
|
|
|
194
195
|
def apply_weight_decompose(self, weight):
|
|
195
196
|
weight = weight.to(self.dora_scale.dtype)
|
|
@@ -264,33 +265,47 @@ class LohaModule(LycorisBaseModule):
|
|
|
264
265
|
|
|
265
266
|
if self.wd:
|
|
266
267
|
weight = self.apply_weight_decompose(weight)
|
|
267
|
-
return self.op(x, weight
|
|
268
|
+
return self.op(x, weight, bias, **self.kw_dict)
|
|
268
269
|
|
|
269
270
|
|
|
270
271
|
if __name__ == "__main__":
|
|
271
272
|
device = torch.device("cuda")
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
273
|
+
module = LohaModule
|
|
274
|
+
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
275
|
+
base = nn.Linear(128, 128).to(device).half()
|
|
276
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
277
|
+
print(net)
|
|
278
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
279
|
+
test_output = net(test_input)
|
|
280
|
+
torch.sum(test_output).backward()
|
|
281
|
+
print(test_output.shape)
|
|
282
|
+
|
|
283
|
+
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
284
|
+
base_4bit.load_state_dict(base.state_dict())
|
|
285
|
+
base_4bit.to(device)
|
|
286
|
+
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
287
|
+
print(qnet)
|
|
288
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
289
|
+
test_output = qnet(test_input)
|
|
290
|
+
torch.sum(test_output).backward()
|
|
291
|
+
print(test_output.shape)
|
|
292
|
+
|
|
293
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
294
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
295
|
+
device
|
|
296
|
+
)
|
|
297
|
+
print(net)
|
|
298
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
299
|
+
test_output = net(test_input)
|
|
300
|
+
torch.sum(test_output).backward()
|
|
301
|
+
print(test_output.shape)
|
|
302
|
+
|
|
303
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
304
|
+
net = module.parametrize(
|
|
305
|
+
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
306
|
+
)
|
|
307
|
+
print(base)
|
|
308
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
309
|
+
test_output = base(test_input)
|
|
310
|
+
torch.sum(test_output).backward()
|
|
311
|
+
print(test_output.shape)
|
|
@@ -72,7 +72,7 @@ class LokrModule(LycorisBaseModule):
|
|
|
72
72
|
bypass_mode,
|
|
73
73
|
)
|
|
74
74
|
if self.module_type not in self.support_module:
|
|
75
|
-
raise ValueError(f"{self.module_type} is not supported in
|
|
75
|
+
raise ValueError(f"{self.module_type} is not supported in LoKr algo.")
|
|
76
76
|
|
|
77
77
|
factor = int(factor)
|
|
78
78
|
self.lora_dim = lora_dim
|
|
@@ -262,15 +262,21 @@ class LokrModule(LycorisBaseModule):
|
|
|
262
262
|
weight *= drop
|
|
263
263
|
return weight
|
|
264
264
|
|
|
265
|
-
def
|
|
265
|
+
def get_diff_weight(self, multiplier=1, shape=None, device=None):
|
|
266
266
|
scale = self.scale * multiplier
|
|
267
267
|
diff = self.get_weight(shape) * scale
|
|
268
268
|
if device is not None:
|
|
269
269
|
diff = diff.to(device)
|
|
270
|
-
|
|
270
|
+
return diff, None
|
|
271
|
+
|
|
272
|
+
def get_merged_weight(self, multiplier=1, shape=None, device=None):
|
|
273
|
+
merged = (
|
|
274
|
+
self.org_module[0].weight.data
|
|
275
|
+
+ self.get_diff_weight(multiplier=multiplier, shape=shape, device=device)[0]
|
|
276
|
+
)
|
|
271
277
|
if self.wd:
|
|
272
278
|
merged = self.apply_weight_decompose(merged)
|
|
273
|
-
return merged
|
|
279
|
+
return merged, None
|
|
274
280
|
|
|
275
281
|
def apply_weight_decompose(self, weight):
|
|
276
282
|
weight = weight.to(self.dora_scale.dtype)
|
|
@@ -390,31 +396,47 @@ class LokrModule(LycorisBaseModule):
|
|
|
390
396
|
|
|
391
397
|
if self.wd:
|
|
392
398
|
weight = self.apply_weight_decompose(weight)
|
|
393
|
-
return self.op(x, weight
|
|
399
|
+
return self.op(x, weight, bias, **self.kw_dict)
|
|
394
400
|
|
|
395
401
|
|
|
396
402
|
if __name__ == "__main__":
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
403
|
+
device = torch.device("cuda")
|
|
404
|
+
module = LokrModule
|
|
405
|
+
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
406
|
+
base = nn.Linear(128, 128).to(device).half()
|
|
407
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
408
|
+
print(net)
|
|
409
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
410
|
+
test_output = net(test_input)
|
|
411
|
+
torch.sum(test_output).backward()
|
|
412
|
+
print(test_output.shape)
|
|
413
|
+
|
|
414
|
+
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
415
|
+
base_4bit.load_state_dict(base.state_dict())
|
|
416
|
+
base_4bit.to(device)
|
|
417
|
+
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
418
|
+
print(qnet)
|
|
419
|
+
test_input = torch.randn(1, 128).to(device).half()
|
|
420
|
+
test_output = qnet(test_input)
|
|
421
|
+
torch.sum(test_output).backward()
|
|
422
|
+
print(test_output.shape)
|
|
423
|
+
|
|
424
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
425
|
+
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
426
|
+
device
|
|
427
|
+
)
|
|
428
|
+
print(net)
|
|
429
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
430
|
+
test_output = net(test_input)
|
|
431
|
+
torch.sum(test_output).backward()
|
|
432
|
+
print(test_output.shape)
|
|
433
|
+
|
|
434
|
+
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
435
|
+
net = module.parametrize(
|
|
436
|
+
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
437
|
+
)
|
|
438
|
+
print(base)
|
|
439
|
+
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
440
|
+
test_output = base(test_input)
|
|
441
|
+
torch.sum(test_output).backward()
|
|
442
|
+
print(test_output.shape)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lycoris_lora
|
|
3
|
-
Version: 3.0.0.
|
|
3
|
+
Version: 3.0.0.dev4
|
|
4
4
|
Summary: Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion
|
|
5
5
|
Home-page: https://github.com/KohakuBlueleaf/LyCORIS
|
|
6
6
|
Author: Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao
|
|
@@ -8,8 +8,5 @@ Author-email: apolloyeh0123@gmail.com
|
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
9
|
License-File: LICENSE.md
|
|
10
10
|
Requires-Dist: torch
|
|
11
|
-
Requires-Dist: safetensors
|
|
12
|
-
Requires-Dist: diffusers
|
|
13
|
-
Requires-Dist: transformers
|
|
14
11
|
Requires-Dist: einops
|
|
15
12
|
Requires-Dist: toml
|
|
@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
|
|
|
4
4
|
setup(
|
|
5
5
|
name="lycoris_lora",
|
|
6
6
|
packages=find_packages(),
|
|
7
|
-
version="3.0.0.
|
|
7
|
+
version="3.0.0.dev4",
|
|
8
8
|
url="https://github.com/KohakuBlueleaf/LyCORIS",
|
|
9
9
|
description="Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion",
|
|
10
10
|
author="Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao",
|
|
@@ -12,9 +12,6 @@ setup(
|
|
|
12
12
|
zip_safe=False,
|
|
13
13
|
install_requires=[
|
|
14
14
|
"torch",
|
|
15
|
-
"safetensors",
|
|
16
|
-
"diffusers",
|
|
17
|
-
"transformers",
|
|
18
15
|
"einops",
|
|
19
16
|
"toml",
|
|
20
17
|
],
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import torch
|
|
2
|
-
import torch.nn as nn
|
|
3
|
-
|
|
4
|
-
from .base import ModuleCustomSD
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class IA3Module(ModuleCustomSD):
|
|
8
|
-
"""
|
|
9
|
-
Hadamard product Implementaion for Low Rank Adaptation
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
def __init__(
|
|
13
|
-
self,
|
|
14
|
-
lora_name,
|
|
15
|
-
org_module: nn.Module,
|
|
16
|
-
multiplier=1.0,
|
|
17
|
-
train_on_input=False,
|
|
18
|
-
**kwargs
|
|
19
|
-
):
|
|
20
|
-
"""if alpha == 0 or None, alpha is rank (no scaling)."""
|
|
21
|
-
super().__init__()
|
|
22
|
-
self.lora_name = lora_name
|
|
23
|
-
self.tucker = False
|
|
24
|
-
|
|
25
|
-
self.shape = org_module.weight.shape
|
|
26
|
-
if org_module.__class__.__name__ == "Conv2d":
|
|
27
|
-
in_dim = org_module.in_channels
|
|
28
|
-
out_dim = org_module.out_channels
|
|
29
|
-
if train_on_input:
|
|
30
|
-
train_dim = in_dim
|
|
31
|
-
else:
|
|
32
|
-
train_dim = out_dim
|
|
33
|
-
self.weight = nn.Parameter(torch.empty(1, train_dim, 1, 1))
|
|
34
|
-
else:
|
|
35
|
-
in_dim = org_module.in_features
|
|
36
|
-
out_dim = org_module.out_features
|
|
37
|
-
if train_on_input:
|
|
38
|
-
train_dim = in_dim
|
|
39
|
-
else:
|
|
40
|
-
train_dim = out_dim
|
|
41
|
-
|
|
42
|
-
self.weight = nn.Parameter(torch.empty(train_dim))
|
|
43
|
-
|
|
44
|
-
# Need more experiences on init method
|
|
45
|
-
torch.nn.init.constant_(self.weight, 0)
|
|
46
|
-
|
|
47
|
-
self.multiplier = multiplier
|
|
48
|
-
self.org_forward = None
|
|
49
|
-
self.org_module = [org_module] # remove in applying
|
|
50
|
-
self.grad_ckpt = False
|
|
51
|
-
self.train_input = train_on_input
|
|
52
|
-
self.register_buffer("on_input", torch.tensor(int(train_on_input)))
|
|
53
|
-
|
|
54
|
-
def apply_to(self):
|
|
55
|
-
self.org_forward = self.org_module[0].forward
|
|
56
|
-
self.org_module[0].forward = self.forward
|
|
57
|
-
|
|
58
|
-
@torch.enable_grad()
|
|
59
|
-
def forward(self, x):
|
|
60
|
-
if self.train_input:
|
|
61
|
-
x = x * (1 + self.weight * self.multiplier)
|
|
62
|
-
out = self.org_forward(x)
|
|
63
|
-
dtype = out.dtype
|
|
64
|
-
if not self.train_input:
|
|
65
|
-
out = out * (1 + self.weight * self.multiplier)
|
|
66
|
-
out = out.to(dtype)
|
|
67
|
-
return out
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lycoris_lora-3.0.0.dev2 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|