lycoris-lora 3.0.0.dev7__tar.gz → 3.0.0.dev9__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.
Files changed (39) hide show
  1. {lycoris_lora-3.0.0.dev7/lycoris_lora.egg-info → lycoris_lora-3.0.0.dev9}/PKG-INFO +1 -1
  2. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/README.md +8 -1
  3. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/functional/loha.py +1 -3
  4. lycoris_lora-3.0.0.dev9/lycoris/functional/lokr.py +259 -0
  5. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/kohya.py +2 -8
  6. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/__init__.py +2 -1
  7. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/base.py +6 -1
  8. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/boft.py +0 -44
  9. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/diag_oft.py +0 -45
  10. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/dylora.py +3 -44
  11. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/full.py +10 -34
  12. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/glora.py +8 -50
  13. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/ia3.py +0 -43
  14. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/locon.py +7 -48
  15. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/loha.py +4 -47
  16. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/lokr.py +100 -73
  17. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/__init__.py +3 -3
  18. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/bnb.py +3 -0
  19. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9/lycoris_lora.egg-info}/PKG-INFO +1 -1
  20. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/SOURCES.txt +1 -0
  21. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/setup.py +1 -1
  22. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/LICENSE.md +0 -0
  23. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/__init__.py +0 -0
  24. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/config.py +0 -0
  25. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/functional/__init__.py +0 -0
  26. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/functional/general.py +0 -0
  27. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/functional/locon.py +0 -0
  28. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/logging.py +0 -0
  29. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/norms.py +0 -0
  30. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/general.py +0 -0
  31. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/logger.py +0 -0
  32. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/preset.py +0 -0
  33. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/xformers_utils.py +0 -0
  34. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/wrapper.py +0 -0
  35. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/dependency_links.txt +0 -0
  36. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/not-zip-safe +0 -0
  37. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/requires.txt +0 -0
  38. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/top_level.txt +0 -0
  39. {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lycoris_lora
3
- Version: 3.0.0.dev7
3
+ Version: 3.0.0.dev9
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
@@ -74,7 +74,7 @@ In any case, please install this package in the corresponding virtual environmen
74
74
  - through pip
75
75
 
76
76
  ```bash
77
- pip install lycoris_lora
77
+ pip install lycoris-lora
78
78
  ```
79
79
  - or from source
80
80
 
@@ -111,6 +111,8 @@ You can use this package's kohya module to run kohya's training script to train
111
111
 
112
112
  #### HCP-Diffusion
113
113
 
114
+ **The support for HCP-Diffusion has been dropped on LyCORIS3.0.0, we will wait until HCP side finish the implementation of new wrapper**
115
+
114
116
  You can use this package's hcp module to run HCP-Diffusion's training script to train lycoris module for SD models
115
117
 
116
118
  ```bash
@@ -156,6 +158,11 @@ forward_with_lyco = your_model(x)
156
158
 
157
159
  You can check my [HakuPhi](https://github.com/KohakuBlueleaf/HakuPhi) project to see how I utilize LyCORIS to finetune the Phi-1.5 models.
158
160
 
161
+ #### Other method
162
+ After LyCORIS3.0.0, Parametrize API and Functional API have been added, which provide more different ways on utilizing LyCORIS library.
163
+
164
+ Check [xxx] for more informations.
165
+
159
166
  #### Bitsandbytes support
160
167
 
161
168
  See [bnb_example.py](bnb_example.py) for example. Basically as same as standalone wrapper.
@@ -174,9 +174,7 @@ def loha_bypass_forward_diff(
174
174
 
175
175
  if __name__ == "__main__":
176
176
  w = torch.randn(128, 128, 3, 3, 3)
177
- w1d, w2d, w1u, w2u, t1, t2 = loha_weight_gen(
178
- w, 4, tucker=True
179
- )
177
+ w1d, w2d, w1u, w2u, t1, t2 = loha_weight_gen(w, 4, tucker=True)
180
178
  w1u += 0.01
181
179
  extra_args = {"padding": 1}
182
180
 
@@ -0,0 +1,259 @@
1
+ import math
2
+
3
+ import torch
4
+ import torch.nn as nn
5
+ import torch.nn.functional as F
6
+
7
+ from .general import rebuild_tucker, FUNC_LIST
8
+ from .general import factorization
9
+
10
+
11
+ def make_kron(w1, w2, scale):
12
+ for _ in range(w2.dim() - w1.dim()):
13
+ w1 = w1.unsqueeze(-1)
14
+ w2 = w2.contiguous()
15
+ rebuild = torch.kron(w1, w2)
16
+
17
+ return rebuild * scale
18
+
19
+
20
+ def weight_gen(
21
+ org_weight,
22
+ rank,
23
+ tucker=True,
24
+ factor=-1,
25
+ decompose_both=False,
26
+ full_matrix=False,
27
+ unbalanced_factorization=False,
28
+ ):
29
+ """### weight_gen
30
+
31
+ Args:
32
+ org_weight (torch.Tensor): the weight tensor
33
+ rank (int): low rank
34
+
35
+ Returns:
36
+ torch.Tensor | None: w1, w1a, w1b, w2, w2a, w2b, t2
37
+ """
38
+ out_dim, in_dim, *k = org_weight.shape
39
+ w1 = w1a = w1b = None
40
+ w2 = w2a = w2b = None
41
+ t2 = None
42
+ use_w1 = use_w2 = False
43
+
44
+ if k:
45
+ k_size = k
46
+ shape = (out_dim, in_dim, *k_size)
47
+
48
+ in_m, in_n = factorization(in_dim, factor)
49
+ out_l, out_k = factorization(out_dim, factor)
50
+ if unbalanced_factorization:
51
+ out_l, out_k = out_k, out_l
52
+ shape = ((out_l, out_k), (in_m, in_n), *k_size) # ((a, b), (c, d), *k_size)
53
+ tucker = tucker and any(i != 1 for i in k_size)
54
+ if (
55
+ decompose_both
56
+ and rank < max(shape[0][0], shape[1][0]) / 2
57
+ and not full_matrix
58
+ ):
59
+ w1a = torch.empty(shape[0][0], rank)
60
+ w1b = torch.empty(rank, shape[1][0])
61
+ else:
62
+ use_w1 = True
63
+ w1 = torch.empty(shape[0][0], shape[1][0]) # a*c, 1-mode
64
+
65
+ if rank >= max(shape[0][1], shape[1][1]) / 2 or full_matrix:
66
+ use_w2 = True
67
+ w2 = torch.empty(shape[0][1], shape[1][1], *k_size)
68
+ elif tucker:
69
+ t2 = torch.empty(rank, rank, *shape[2:])
70
+ w2a = torch.empty(rank, shape[0][1]) # b, 1-mode
71
+ w2b = torch.empty(rank, shape[1][1]) # d, 2-mode
72
+ else: # Conv2d not tucker
73
+ # bigger part. weight and LoRA. [b, dim] x [dim, d*k1*k2]
74
+ w2a = torch.empty(shape[0][1], rank)
75
+ w2b = torch.empty(rank, shape[1][1], *shape[2:])
76
+ # w1 ⊗ (w2a x w2b) = (a, b)⊗((c, dim)x(dim, d*k1*k2)) = (a, b)⊗(c, d*k1*k2) = (ac, bd*k1*k2)
77
+ else: # Linear
78
+ shape = (out_dim, in_dim)
79
+
80
+ in_m, in_n = factorization(in_dim, factor)
81
+ out_l, out_k = factorization(out_dim, factor)
82
+ if unbalanced_factorization:
83
+ out_l, out_k = out_k, out_l
84
+ shape = (
85
+ (out_l, out_k),
86
+ (in_m, in_n),
87
+ ) # ((a, b), (c, d)), out_dim = a*c, in_dim = b*d
88
+ # smaller part. weight scale
89
+ if decompose_both and rank < max(shape[0][0], shape[1][0]) / 2:
90
+ w1a = torch.empty(shape[0][0], rank)
91
+ w1b = torch.empty(rank, shape[1][0])
92
+ else:
93
+ use_w1 = True
94
+ w1 = torch.empty(shape[0][0], shape[1][0]) # a*c, 1-mode
95
+ if rank < max(shape[0][1], shape[1][1]) / 2:
96
+ # bigger part. weight and LoRA. [b, dim] x [dim, d]
97
+ w2a = torch.empty(shape[0][1], rank)
98
+ w2b = torch.empty(rank, shape[1][1])
99
+ # w1 ⊗ (w2a x w2b) = (a, b)⊗((c, dim)x(dim, d)) = (a, b)⊗(c, d) = (ac, bd)
100
+ else:
101
+ use_w2 = True
102
+ w2 = torch.empty(shape[0][1], shape[1][1])
103
+
104
+ if use_w2:
105
+ torch.nn.init.constant_(w2, 1)
106
+ else:
107
+ if tucker:
108
+ torch.nn.init.kaiming_uniform_(t2, a=math.sqrt(5))
109
+ torch.nn.init.kaiming_uniform_(w2a, a=math.sqrt(5))
110
+ torch.nn.init.constant_(w2b, 1)
111
+
112
+ if use_w1:
113
+ torch.nn.init.kaiming_uniform_(w1, a=math.sqrt(5))
114
+ else:
115
+ torch.nn.init.kaiming_uniform_(w1a, a=math.sqrt(5))
116
+ torch.nn.init.kaiming_uniform_(w1b, a=math.sqrt(5))
117
+
118
+ return w1, w1a, w1b, w2, w2a, w2b, t2
119
+
120
+
121
+ def lokr_diff_weight(w1, w1a, w1b, w2, w2a, w2b, t, gamma=1.0):
122
+ """### lokr_diff_weight
123
+
124
+ Args:
125
+ gamma (float, optional): scale factor, normally alpha/rank here
126
+
127
+ Returns:
128
+ torch.Tensor: ΔW
129
+ """
130
+ if w1a is not None:
131
+ rank = w1a.shape[1]
132
+ elif w2a is not None:
133
+ rank = w2a.shape[1]
134
+ else:
135
+ rank = gamma
136
+ scale = gamma / rank
137
+ if w1 is None:
138
+ w1 = w1a @ w1b
139
+ if w2 is None:
140
+ if t is None:
141
+ r, o, *k = w2b.shape
142
+ w2 = w2a @ w2b.view(r, -1)
143
+ w2 = w2.view(-1, o, *k)
144
+ else:
145
+ w2 = rebuild_tucker(t, w2a, w2b)
146
+ return make_kron(w1, w2, scale)
147
+
148
+
149
+ def lokr_bypass_forward_diff(
150
+ h, w1, w1a, w1b, w2, w2a, w2b, t, gamma=1.0, extra_args={}
151
+ ):
152
+ """### lokr_bypass_forward_diff
153
+
154
+ Args:
155
+ gamma (float, optional): scale factor, normally alpha/rank here
156
+ extra_args (dict, optional): extra args for forward func, \
157
+ e.g. padding, stride for Conv1/2/3d
158
+
159
+ Returns:
160
+ torch.Tensor: output tensor
161
+ """
162
+ use_w1 = w1 is not None
163
+ use_w2 = w2 is not None
164
+ tucker = t is not None
165
+ dim = t.dim() if tucker else w2.dim() if w2 is not None else w2b.dim()
166
+ print(dim)
167
+ rank = w1b.size(0) if not use_w1 else w2b.size(0) if not use_w2 else gamma
168
+ scale = gamma / rank
169
+ is_conv = dim > 2
170
+ op = FUNC_LIST[dim]
171
+
172
+ if is_conv:
173
+ kw_dict = extra_args
174
+ else:
175
+ kw_dict = {}
176
+
177
+ if use_w2:
178
+ ba = w2
179
+ else:
180
+ a = w2b
181
+ b = w2a
182
+
183
+ if t is not None:
184
+ a = a.view(*a.shape, *[1] * (dim - 2))
185
+ b = b.view(*b.shape, *[1] * (dim - 2))
186
+ elif is_conv:
187
+ b = b.view(*b.shape, *[1] * (dim - 2))
188
+
189
+ if use_w1:
190
+ c = w1
191
+ else:
192
+ c = w1a @ w1b
193
+ uq = c.size(1)
194
+
195
+ if is_conv:
196
+ # (b, uq), vq, ...
197
+ B, _, *rest = h.shape
198
+ h_in_group = h.reshape(B * uq, -1, *rest)
199
+ else:
200
+ # b, ..., uq, vq
201
+ h_in_group = h.reshape(*h.shape[:-1], uq, -1)
202
+
203
+ if use_w2:
204
+ hb = op(h_in_group, ba, **kw_dict)
205
+ else:
206
+ if is_conv:
207
+ if tucker:
208
+ ha = op(h_in_group, a)
209
+ ht = op(ha, t, **kw_dict)
210
+ hb = op(ht, b)
211
+ else:
212
+ ha = op(h_in_group, a, **kw_dict)
213
+ hb = op(ha, b)
214
+ else:
215
+ ha = op(h_in_group, a, **kw_dict)
216
+ hb = op(ha, b)
217
+
218
+ if is_conv:
219
+ # (b, uq), vp, ..., f
220
+ # -> b, uq, vp, ..., f
221
+ # -> b, f, vp, ..., uq
222
+ hb = hb.view(B, -1, *hb.shape[1:])
223
+ h_cross_group = hb.transpose(1, -1)
224
+ else:
225
+ # b, ..., uq, vq
226
+ # -> b, ..., vq, uq
227
+ h_cross_group = hb.transpose(-1, -2)
228
+
229
+ hc = F.linear(h_cross_group, c)
230
+ if is_conv:
231
+ # b, f, vp, ..., up
232
+ # -> b, up, vp, ... ,f
233
+ # -> b, c, ..., f
234
+ hc = hc.transpose(1, -1)
235
+ h = hc.reshape(B, -1, *hc.shape[3:])
236
+ else:
237
+ # b, ..., vp, up
238
+ # -> b, ..., up, vp
239
+ # -> b, ..., c
240
+ hc = hc.transpose(-1, -2)
241
+ h = hc.reshape(*hc.shape[:-2], -1)
242
+
243
+ return h * scale
244
+
245
+
246
+ if __name__ == "__main__":
247
+ w = torch.randn(32, 32, 3, 3, 3)
248
+ w1, w1a, w1b, w2, w2a, w2b, t = weight_gen(w, 2, tucker=False)
249
+ extra_args = {"padding": 1}
250
+
251
+ x = torch.randn(1, 32, 8, 8, 8)
252
+ y = FUNC_LIST[w.dim()](x, w, **extra_args)
253
+ diff_w = lokr_diff_weight(w1, w1a, w1b, w2, w2a, w2b, t, 1)
254
+ diff_y_w = FUNC_LIST[w.dim()](x, diff_w, **extra_args)
255
+ diff_y = lokr_bypass_forward_diff(x, w1, w1a, w1b, w2, w2a, w2b, t, 1, extra_args)
256
+
257
+ print(F.mse_loss(y, y + diff_y))
258
+ print(F.mse_loss(w, w + diff_w))
259
+ print(F.mse_loss(diff_y, diff_y_w))
@@ -611,11 +611,8 @@ class LycorisNetworkKohya(LycorisNetwork):
611
611
  # Precalculate model hashes to save time on indexing
612
612
  if metadata is None:
613
613
  metadata = {}
614
- model_hash, legacy_hash = precalculate_safetensors_hashes(
615
- state_dict
616
- )
614
+ model_hash = precalculate_safetensors_hashes(state_dict)
617
615
  metadata["sshs_model_hash"] = model_hash
618
- metadata["sshs_legacy_hash"] = legacy_hash
619
616
 
620
617
  save_file(state_dict, file, metadata)
621
618
  else:
@@ -845,11 +842,8 @@ class IA3Network(torch.nn.Module):
845
842
  # Precalculate model hashes to save time on indexing
846
843
  if metadata is None:
847
844
  metadata = {}
848
- model_hash, legacy_hash = precalculate_safetensors_hashes(
849
- state_dict
850
- )
845
+ model_hash = precalculate_safetensors_hashes(state_dict)
851
846
  metadata["sshs_model_hash"] = model_hash
852
- metadata["sshs_legacy_hash"] = legacy_hash
853
847
 
854
848
  save_file(state_dict, file, metadata)
855
849
  else:
@@ -1,6 +1,7 @@
1
1
  import torch
2
2
  import torch.nn as nn
3
3
 
4
+ from .base import LycorisBaseModule
4
5
  from .locon import LoConModule
5
6
  from .loha import LohaModule
6
7
  from .lokr import LokrModule
@@ -57,7 +58,7 @@ def make_module(lyco_type, params, lora_name, orig_module):
57
58
  module.dora_scale.copy_(dora_scale)
58
59
  elif lyco_type == "kron":
59
60
  w1, w1a, w1b, w2, w2a, w2b, _, t2, alpha, dora_scale = params
60
- full_matrix=False
61
+ full_matrix = False
61
62
  if w1a is not None:
62
63
  lora_dim = w1a.size(1)
63
64
  elif w2a is not None:
@@ -184,6 +184,10 @@ class LycorisBaseModule(ModuleCustomSD):
184
184
 
185
185
  @classmethod
186
186
  def parametrize(cls, org_module, attr, *args, **kwargs):
187
+ from .full import FullModule
188
+
189
+ if cls is FullModule:
190
+ raise RuntimeError("FullModule cannot be used for parametrize.")
187
191
  target_param = getattr(org_module, attr)
188
192
  kwargs["bypass_mode"] = False
189
193
  if target_param.dim() == 2:
@@ -206,11 +210,12 @@ class LycorisBaseModule(ModuleCustomSD):
206
210
  target_param.shape[0],
207
211
  target_param.shape[1],
208
212
  *target_param.shape[2:],
213
+ bias=False,
209
214
  )
210
215
  proxy_module.weight = target_param
211
216
  module_obj = cls("", proxy_module, *args, **kwargs)
212
217
  module_obj.forward = module_obj.parametrize_forward
213
- module_obj.to(target_param.device)
218
+ module_obj.to(target_param)
214
219
  parametrize.register_parametrization(org_module, attr, module_obj)
215
220
  return module_obj
216
221
 
@@ -3,7 +3,6 @@ from math import log2
3
3
 
4
4
  import torch
5
5
  import torch.nn as nn
6
- import torch.nn.functional as F
7
6
 
8
7
  from einops import rearrange
9
8
 
@@ -197,46 +196,3 @@ class ButterflyOFTModule(LycorisBaseModule):
197
196
  w = self.make_weight(scale, x.device)
198
197
  kw_dict = self.kw_dict | {"weight": w, "bias": self.org_module[0].bias}
199
198
  return self.op(x, **kw_dict)
200
-
201
-
202
- if __name__ == "__main__":
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)
@@ -4,8 +4,6 @@ import torch
4
4
  import torch.nn as nn
5
5
  import torch.nn.functional as F
6
6
 
7
- from einops import rearrange
8
-
9
7
  from .base import LycorisBaseModule
10
8
  from ..functional import factorization
11
9
  from ..logging import logger
@@ -182,46 +180,3 @@ class DiagOFTModule(LycorisBaseModule):
182
180
  w = self.make_weight(scale, x.device)
183
181
  kw_dict = self.kw_dict | {"weight": w, "bias": self.org_module[0].bias}
184
182
  return self.op(x, **kw_dict)
185
-
186
-
187
- if __name__ == "__main__":
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)
@@ -3,7 +3,6 @@ import random
3
3
 
4
4
  import torch
5
5
  import torch.nn as nn
6
- import torch.nn.functional as F
7
6
 
8
7
  from .base import LycorisBaseModule
9
8
  from ..utils import product
@@ -80,6 +79,9 @@ class DyLoraModule(LycorisBaseModule):
80
79
  for v in self.up_list:
81
80
  torch.nn.init.zeros_(v)
82
81
 
82
+ def load_state_dict(self, state_dict, strict: bool = True, assign: bool = False):
83
+ return
84
+
83
85
  def custom_state_dict(self):
84
86
  destination = {}
85
87
  destination["alpha"] = self.alpha
@@ -153,46 +155,3 @@ class DyLoraModule(LycorisBaseModule):
153
155
  else self.org_module[0].bias.data
154
156
  )
155
157
  return self.op(x, weight, bias, **self.kw_dict)
156
-
157
-
158
- if __name__ == "__main__":
159
- device = torch.device("cuda")
160
- module = DyLoraModule
161
- with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
162
- base = nn.Linear(128, 128).to(device).half()
163
- net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
164
- print(net)
165
- test_input = torch.randn(1, 128).to(device).half()
166
- test_output = net(test_input)
167
- torch.sum(test_output).backward()
168
- print(test_output.shape)
169
-
170
- base_4bit = LinearNF4(128, 128, device="cuda")
171
- base_4bit.load_state_dict(base.state_dict())
172
- base_4bit.to(device)
173
- qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
174
- print(qnet)
175
- test_input = torch.randn(1, 128).to(device).half()
176
- test_output = qnet(test_input)
177
- torch.sum(test_output).backward()
178
- print(test_output.shape)
179
-
180
- base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
181
- net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
182
- device
183
- )
184
- print(net)
185
- test_input = torch.randn(1, 128, 16, 16).to(device).half()
186
- test_output = net(test_input)
187
- torch.sum(test_output).backward()
188
- print(test_output.shape)
189
-
190
- base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
191
- net = module.parametrize(
192
- base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
193
- ).to(device)
194
- print(base)
195
- test_input = torch.randn(1, 128, 16, 16).to(device).half()
196
- test_output = base(test_input)
197
- torch.sum(test_output).backward()
198
- print(test_output.shape)
@@ -76,6 +76,15 @@ class FullModule(LycorisBaseModule):
76
76
  else:
77
77
  self.org_bias = None
78
78
 
79
+ def restore(self):
80
+ self.org_module[0].forward = self.org_forward
81
+ self.org_module[0].weight = nn.Parameter(self._org_weight[0])
82
+ if self.org_bias is not None:
83
+ self.org_module[0].bias = nn.Parameter(self.org_bias[0])
84
+
85
+ def load_state_dict(self, state_dict, strict: bool = True, assign: bool = False):
86
+ return
87
+
79
88
  def custom_state_dict(self):
80
89
  sd = {"diff": self.weight.data.cpu() - self._org_weight[0]}
81
90
  if self.bias is not None:
@@ -137,7 +146,7 @@ class FullModule(LycorisBaseModule):
137
146
  if shape is not None:
138
147
  weight = weight.view(shape)
139
148
  if bias is not None:
140
- bias = bias.view(shape[0], 1)
149
+ bias = bias.view(shape[0])
141
150
  return weight, bias
142
151
 
143
152
  def forward(self, x: torch.Tensor, *args, **kwargs):
@@ -155,36 +164,3 @@ class FullModule(LycorisBaseModule):
155
164
  weight, bias = self.make_weight(scale, x.device)
156
165
  kw_dict = self.kw_dict | {"weight": weight, "bias": bias}
157
166
  return self.op(x, **kw_dict)
158
-
159
-
160
- if __name__ == "__main__":
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)
@@ -66,17 +66,17 @@ class GLoRAModule(LycorisBaseModule):
66
66
  stride = org_module.stride
67
67
  padding = org_module.padding
68
68
  out_dim = org_module.out_channels
69
- self.tucker = use_tucker and k_size != (1, 1)
69
+ self.tucker = use_tucker and all(i == 1 for i in k_size)
70
70
  self.down_op = self.op
71
71
  self.up_op = self.op
72
72
 
73
73
  # A
74
- self.a2 = self.module(in_dim, lora_dim, (1, 1), bias=False)
75
- self.a1 = self.module(lora_dim, in_dim, (1, 1), bias=False)
74
+ self.a2 = self.module(in_dim, lora_dim, 1, bias=False)
75
+ self.a1 = self.module(lora_dim, in_dim, 1, bias=False)
76
76
 
77
77
  # B
78
- if use_tucker and k_size != (1, 1):
79
- self.b2 = self.module(in_dim, lora_dim, (1, 1), bias=False)
78
+ if use_tucker and any(i != 1 for i in k_size):
79
+ self.b2 = self.module(in_dim, lora_dim, 1, bias=False)
80
80
  self.bm = self.module(
81
81
  lora_dim, lora_dim, k_size, stride, padding, bias=False
82
82
  )
@@ -85,7 +85,7 @@ class GLoRAModule(LycorisBaseModule):
85
85
  self.b2 = self.module(
86
86
  in_dim, lora_dim, k_size, stride, padding, bias=False
87
87
  )
88
- self.b1 = self.module(lora_dim, out_dim, (1, 1), bias=False)
88
+ self.b1 = self.module(lora_dim, out_dim, 1, bias=False)
89
89
  else:
90
90
  self.isconv = False
91
91
  self.down_op = F.linear
@@ -123,6 +123,7 @@ class GLoRAModule(LycorisBaseModule):
123
123
  def make_weight(self, device=None):
124
124
  wa1 = self.a1.weight.view(self.a1.weight.size(0), -1)
125
125
  wa2 = self.a2.weight.view(self.a2.weight.size(0), -1)
126
+ orig = self.org_weight
126
127
 
127
128
  if self.tucker:
128
129
  wb = tucker_weight_from_conv(self.b1.weight, self.b2.weight, self.bm.weight)
@@ -130,7 +131,7 @@ class GLoRAModule(LycorisBaseModule):
130
131
  wb1 = self.b1.weight.view(self.b1.weight.size(0), -1)
131
132
  wb2 = self.b2.weight.view(self.b2.weight.size(0), -1)
132
133
  wb = wb1 @ wb2
133
- orig = self.org_weight
134
+ wb = wb.view(*orig.shape)
134
135
  if orig.dim() > 2:
135
136
  w_wa1 = torch.einsum("o i ..., i j -> o j ...", orig, wa1)
136
137
  w_wa2 = torch.einsum("o i ..., i j -> o j ...", w_wa1, wa2)
@@ -201,46 +202,3 @@ class GLoRAModule(LycorisBaseModule):
201
202
  else self.org_module[0].bias.data
202
203
  )
203
204
  return self.op(x, weight, bias, **self.kw_dict)
204
-
205
-
206
- if __name__ == "__main__":
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)
@@ -128,46 +128,3 @@ class IA3Module(LycorisBaseModule):
128
128
  else self.org_module[0].bias.data
129
129
  )
130
130
  return self.op(x, weight, bias, **self.kw_dict)
131
-
132
-
133
- if __name__ == "__main__":
134
- device = torch.device("cuda")
135
- module = IA3Module
136
- with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
137
- base = nn.Linear(128, 128).to(device).half()
138
- net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
139
- print(net)
140
- test_input = torch.randn(1, 128).to(device).half()
141
- test_output = net(test_input)
142
- torch.sum(test_output).backward()
143
- print(test_output.shape)
144
-
145
- base_4bit = LinearNF4(128, 128, device="cuda")
146
- base_4bit.load_state_dict(base.state_dict())
147
- base_4bit.to(device)
148
- qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
149
- print(qnet)
150
- test_input = torch.randn(1, 128).to(device).half()
151
- test_output = qnet(test_input)
152
- torch.sum(test_output).backward()
153
- print(test_output.shape)
154
-
155
- base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
156
- net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
157
- device
158
- )
159
- print(net)
160
- test_input = torch.randn(1, 128, 16, 16).to(device).half()
161
- test_output = net(test_input)
162
- torch.sum(test_output).backward()
163
- print(test_output.shape)
164
-
165
- base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
166
- net = module.parametrize(
167
- base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
168
- ).to(device)
169
- print(base)
170
- test_input = torch.randn(1, 128, 16, 16).to(device).half()
171
- test_output = base(test_input)
172
- torch.sum(test_output).backward()
173
- print(test_output.shape)
@@ -70,11 +70,11 @@ class LoConModule(LycorisBaseModule):
70
70
  stride = org_module.stride
71
71
  padding = org_module.padding
72
72
  out_dim = org_module.out_channels
73
- self.tucker = use_tucker and k_size != (1, 1)
73
+ self.tucker = use_tucker and any(i != 1 for i in k_size)
74
74
  self.down_op = self.op
75
75
  self.up_op = self.op
76
- if use_tucker and k_size != (1, 1):
77
- self.lora_down = self.module(in_dim, lora_dim, (1, 1), bias=False)
76
+ if use_tucker and any(i != 1 for i in k_size):
77
+ self.lora_down = self.module(in_dim, lora_dim, 1, bias=False)
78
78
  self.lora_mid = self.module(
79
79
  lora_dim, lora_dim, k_size, stride, padding, bias=False
80
80
  )
@@ -83,7 +83,7 @@ class LoConModule(LycorisBaseModule):
83
83
  self.lora_down = self.module(
84
84
  in_dim, lora_dim, k_size, stride, padding, bias=False
85
85
  )
86
- self.lora_up = self.module(lora_dim, out_dim, (1, 1), bias=False)
86
+ self.lora_up = self.module(lora_dim, out_dim, 1, bias=False)
87
87
  elif isinstance(org_module, nn.Linear):
88
88
  self.isconv = False
89
89
  self.down_op = F.linear
@@ -97,7 +97,7 @@ class LoConModule(LycorisBaseModule):
97
97
 
98
98
  self.wd = weight_decompose
99
99
  if self.wd:
100
- org_weight: nn.Parameter = org_module.weight
100
+ org_weight = org_module.weight.cpu().clone().float()
101
101
  self.dora_norm_dims = org_weight.dim() - 1
102
102
  self.dora_scale = nn.Parameter(
103
103
  torch.norm(
@@ -148,6 +148,8 @@ class LoConModule(LycorisBaseModule):
148
148
  del missing_keys[missing_keys.index(key)]
149
149
  if isinstance(self.scalar, nn.Parameter):
150
150
  self.scalar.data.copy_(torch.ones_like(self.scalar))
151
+ elif getattr(self, "scalar", None) is not None:
152
+ self.scalar.copy_(torch.ones_like(self.scalar))
151
153
  else:
152
154
  self.register_buffer(
153
155
  "scalar", torch.ones_like(self.scalar), persistent=False
@@ -275,46 +277,3 @@ class LoConModule(LycorisBaseModule):
275
277
  return self.op(x, weight, bias, **self.kw_dict)
276
278
  else:
277
279
  return self.bypass_forward(x, scale=self.multiplier)
278
-
279
-
280
- if __name__ == "__main__":
281
- device = torch.device("cuda")
282
- module = LoConModule
283
- with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
284
- base = nn.Linear(128, 128).to(device).half()
285
- net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
286
- print(net)
287
- test_input = torch.randn(1, 128).to(device).half()
288
- test_output = net(test_input)
289
- torch.sum(test_output).backward()
290
- print(test_output.shape)
291
-
292
- base_4bit = LinearNF4(128, 128, device="cuda")
293
- base_4bit.load_state_dict(base.state_dict())
294
- base_4bit.to(device)
295
- qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
296
- print(qnet)
297
- test_input = torch.randn(1, 128).to(device).half()
298
- test_output = qnet(test_input)
299
- torch.sum(test_output).backward()
300
- print(test_output.shape)
301
-
302
- base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
303
- net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
304
- device
305
- )
306
- print(net)
307
- test_input = torch.randn(1, 128, 16, 16).to(device).half()
308
- test_output = net(test_input)
309
- torch.sum(test_output).backward()
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)
@@ -2,7 +2,6 @@ import math
2
2
 
3
3
  import torch
4
4
  import torch.nn as nn
5
- import torch.nn.functional as F
6
5
 
7
6
  from .base import LycorisBaseModule
8
7
  from ..functional.loha import loha_diff_weight
@@ -58,12 +57,11 @@ class LohaModule(LycorisBaseModule):
58
57
  k_size = org_module.kernel_size
59
58
  out_dim = org_module.out_channels
60
59
  self.shape = (out_dim, in_dim, *k_size)
61
- self.tucker = use_tucker and k_size != (1, 1)
60
+ self.tucker = use_tucker and any(i != 1 for i in k_size)
62
61
  if self.tucker:
63
62
  w_shape = (out_dim, in_dim, *k_size)
64
63
  else:
65
64
  w_shape = (out_dim, in_dim * torch.tensor(k_size).prod().item())
66
- self.op = F.conv2d
67
65
 
68
66
  if self.tucker:
69
67
  self.hada_t1 = nn.Parameter(torch.empty(lora_dim, lora_dim, *w_shape[2:]))
@@ -90,7 +88,7 @@ class LohaModule(LycorisBaseModule):
90
88
 
91
89
  self.wd = weight_decompose
92
90
  if self.wd:
93
- org_weight: nn.Parameter = org_module.weight
91
+ org_weight = org_module.weight.cpu().clone().float()
94
92
  self.dora_norm_dims = org_weight.dim() - 1
95
93
  self.dora_scale = nn.Parameter(
96
94
  torch.norm(
@@ -140,6 +138,8 @@ class LohaModule(LycorisBaseModule):
140
138
  del missing_keys[missing_keys.index(key)]
141
139
  if isinstance(self.scalar, nn.Parameter):
142
140
  self.scalar.data.copy_(torch.ones_like(self.scalar))
141
+ elif getattr(self, "scalar", None) is not None:
142
+ self.scalar.copy_(torch.ones_like(self.scalar))
143
143
  else:
144
144
  self.register_buffer(
145
145
  "scalar", torch.ones_like(self.scalar), persistent=False
@@ -266,46 +266,3 @@ class LohaModule(LycorisBaseModule):
266
266
  if self.wd:
267
267
  weight = self.apply_weight_decompose(weight)
268
268
  return self.op(x, weight, bias, **self.kw_dict)
269
-
270
-
271
- if __name__ == "__main__":
272
- device = torch.device("cuda")
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)
@@ -9,6 +9,7 @@ from einops import rearrange
9
9
 
10
10
  from .base import LycorisBaseModule
11
11
  from ..functional import factorization, rebuild_tucker
12
+ from ..functional.lokr import make_kron
12
13
  from ..logging import logger
13
14
  from ..utils.bnb import LinearNF4
14
15
 
@@ -22,15 +23,6 @@ def logging_force_full_matrix(lora_dim, dim, factor):
22
23
  )
23
24
 
24
25
 
25
- def make_kron(w1, w2, scale):
26
- if len(w2.shape) == 4:
27
- w1 = w1.unsqueeze(2).unsqueeze(2)
28
- w2 = w2.contiguous()
29
- rebuild = torch.kron(w1, w2)
30
-
31
- return rebuild * scale
32
-
33
-
34
26
  class LokrModule(LycorisBaseModule):
35
27
  support_module = {
36
28
  "linear",
@@ -93,7 +85,7 @@ class LokrModule(LycorisBaseModule):
93
85
  if unbalanced_factorization:
94
86
  out_l, out_k = out_k, out_l
95
87
  shape = ((out_l, out_k), (in_m, in_n), *k_size) # ((a, b), (c, d), *k_size)
96
- self.tucker = use_tucker and k_size != (1, 1)
88
+ self.tucker = use_tucker and any(i != 1 for i in k_size)
97
89
  if (
98
90
  decompose_both
99
91
  and lora_dim < max(shape[0][0], shape[1][0]) / 2
@@ -115,9 +107,7 @@ class LokrModule(LycorisBaseModule):
115
107
  torch.empty(shape[0][1], shape[1][1], *k_size)
116
108
  )
117
109
  elif self.tucker:
118
- self.lokr_t2 = nn.Parameter(
119
- torch.empty(lora_dim, lora_dim, shape[2], shape[3])
120
- )
110
+ self.lokr_t2 = nn.Parameter(torch.empty(lora_dim, lora_dim, *shape[2:]))
121
111
  self.lokr_w2_a = nn.Parameter(
122
112
  torch.empty(lora_dim, shape[0][1])
123
113
  ) # b, 1-mode
@@ -166,7 +156,7 @@ class LokrModule(LycorisBaseModule):
166
156
 
167
157
  self.wd = weight_decompose
168
158
  if self.wd:
169
- org_weight: nn.Parameter = org_module.weight
159
+ org_weight = org_module.weight.cpu().clone().float()
170
160
  self.dora_norm_dims = org_weight.dim() - 1
171
161
  self.dora_scale = nn.Parameter(
172
162
  torch.norm(
@@ -232,6 +222,8 @@ class LokrModule(LycorisBaseModule):
232
222
  del missing_keys[missing_keys.index(key)]
233
223
  if isinstance(self.scalar, nn.Parameter):
234
224
  self.scalar.data.copy_(torch.ones_like(self.scalar))
225
+ elif getattr(self, "scalar", None) is not None:
226
+ self.scalar.copy_(torch.ones_like(self.scalar))
235
227
  else:
236
228
  self.register_buffer(
237
229
  "scalar", torch.ones_like(self.scalar), persistent=False
@@ -337,40 +329,74 @@ class LokrModule(LycorisBaseModule):
337
329
  return scaled, orig_norm * ratio
338
330
 
339
331
  def bypass_forward_diff(self, h, scale=1):
340
- if len(self.shape) > 2 and self.shape[2] > 1:
341
- return (
342
- self.op(h, self.get_weight(self.shape), **self.kw_dict)
343
- * self.multiplier
344
- )
345
- if self.module_type.startswith("conv"):
346
- h = h.transpose(1, -1)
332
+ is_conv = self.module_type.startswith("conv")
347
333
  if self.use_w2:
348
334
  ba = self.lokr_w2
349
335
  else:
350
336
  a = self.lokr_w2_b
351
337
  b = self.lokr_w2_a
338
+
339
+ if self.tucker:
340
+ t = self.lokr_t2
341
+ a = a.view(*a.shape, *[1] * (len(t.shape) - 2))
342
+ b = b.view(*b.shape, *[1] * (len(t.shape) - 2))
343
+ elif is_conv:
344
+ a = a.view(*a.shape, *self.shape[2:])
345
+ b = b.view(*b.shape, *[1] * (len(self.shape) - 2))
346
+
352
347
  if self.use_w1:
353
348
  c = self.lokr_w1
354
349
  else:
355
350
  c = self.lokr_w1_a @ self.lokr_w1_b
356
351
  uq = c.size(1)
357
352
 
353
+ if is_conv:
354
+ # (b, uq), vq, ...
355
+ b, _, *rest = h.shape
356
+ h_in_group = h.reshape(b * uq, -1, *rest)
357
+ else:
358
+ # b, ..., uq, vq
359
+ h_in_group = h.reshape(*h.shape[:-1], uq, -1)
360
+
358
361
  if self.use_w2:
359
- vq = ba.size(1)
360
- h_in_group = rearrange(h, "b ... (uq vq) -> b ... uq vq", uq=uq, vq=vq)
361
- hb = F.linear(h_in_group, ba)
362
+ hb = self.op(h_in_group, ba, **self.kw_dict)
363
+ else:
364
+ if is_conv:
365
+ if self.tucker:
366
+ ha = self.op(h_in_group, a)
367
+ ht = self.op(ha, t, **self.kw_dict)
368
+ hb = self.op(ht, b)
369
+ else:
370
+ ha = self.op(h_in_group, a, **self.kw_dict)
371
+ hb = self.op(ha, b)
372
+ else:
373
+ ha = self.op(h_in_group, a, **self.kw_dict)
374
+ hb = self.op(ha, b)
375
+
376
+ if is_conv:
377
+ # (b, uq), vp, ..., f
378
+ # -> b, uq, vp, ..., f
379
+ # -> b, f, vp, ..., uq
380
+ hb = hb.view(b, -1, *hb.shape[1:])
381
+ h_cross_group = hb.transpose(1, -1)
362
382
  else:
363
- vq = a.size(1)
364
- h_in_group = rearrange(h, "b ... (uq vq) -> b ... uq vq", uq=uq, vq=vq)
365
- ha = F.linear(h_in_group, a)
366
- hb = F.linear(ha, b)
383
+ # b, ..., uq, vq
384
+ # -> b, ..., vq, uq
385
+ h_cross_group = hb.transpose(-1, -2)
367
386
 
368
- h_cross_group = hb.transpose(-1, -2)
369
387
  hc = F.linear(h_cross_group, c)
370
-
371
- h = rearrange(hc, "b ... vp up -> b ... (up vp)")
372
- if self.module_type.startswith("conv"):
373
- h = h.transpose(1, -1)
388
+ if is_conv:
389
+ # b, f, vp, ..., up
390
+ # -> b, up, vp, ... ,f
391
+ # -> b, c, ..., f
392
+ hc = hc.transpose(1, -1)
393
+ h = hc.reshape(b, -1, *hc.shape[3:])
394
+ else:
395
+ # b, ..., vp, up
396
+ # -> b, ..., up, vp
397
+ # -> b, ..., c
398
+ hc = hc.transpose(-1, -2)
399
+ h = hc.reshape(*hc.shape[:-2], -1)
374
400
 
375
401
  return self.drop(h * scale)
376
402
 
@@ -400,43 +426,44 @@ class LokrModule(LycorisBaseModule):
400
426
 
401
427
 
402
428
  if __name__ == "__main__":
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)
429
+ base = nn.Conv2d(128, 128, 3, 1, 1)
430
+ net = LokrModule(
431
+ "",
432
+ base,
433
+ multiplier=1,
434
+ lora_dim=4,
435
+ alpha=1,
436
+ weight_decompose=False,
437
+ use_tucker=False,
438
+ use_scalar=False,
439
+ decompose_both=True,
440
+ )
441
+ net.apply_to()
442
+ sd = net.state_dict()
443
+ for key in sd:
444
+ if key != "alpha":
445
+ sd[key] = torch.randn_like(sd[key])
446
+ net.load_state_dict(sd)
447
+
448
+ test_input = torch.randn(1, 128, 16, 16)
449
+ test_output = net(test_input)
450
+ print(test_output.shape)
451
+
452
+ net2 = LokrModule(
453
+ "",
454
+ base,
455
+ multiplier=1,
456
+ lora_dim=4,
457
+ alpha=1,
458
+ weight_decompose=False,
459
+ use_tucker=False,
460
+ use_scalar=False,
461
+ bypass_mode=True,
462
+ decompose_both=True,
463
+ )
464
+ net2.apply_to()
465
+ net2.load_state_dict(sd)
466
+ print(net2)
467
+
468
+ test_output2 = net(test_input)
469
+ print(F.mse_loss(test_output, test_output2))
@@ -469,12 +469,12 @@ def get_module(lyco_state_dict: Dict, lora_name):
469
469
  def tucker_weight_from_conv(up, down, mid):
470
470
  up = up.reshape(up.size(0), up.size(1))
471
471
  down = down.reshape(down.size(0), down.size(1))
472
- return torch.einsum("m n w h, i m, n j -> i j w h", mid, up, down)
472
+ return torch.einsum("m n ..., i m, n j -> i j ...", mid, up, down)
473
473
 
474
474
 
475
475
  def tucker_weight(wa, wb, t):
476
- temp = torch.einsum("i j k l, j r -> i r k l", t, wb)
477
- return torch.einsum("i j k l, i r -> r j k l", temp, wa)
476
+ temp = torch.einsum("i j ..., j r -> i r ...", t, wb)
477
+ return torch.einsum("i j ..., i r -> r j ...", temp, wa)
478
478
 
479
479
 
480
480
  def apply_dora_scale(org_weight, rebuild, dora_scale, scale):
@@ -2,7 +2,10 @@ from functools import cache
2
2
 
3
3
  try:
4
4
  from bitsandbytes.nn import LinearNF4, Linear8bitLt, LinearFP4
5
+
6
+ SUPPORT_BNB = True
5
7
  except:
8
+ SUPPORT_BNB = False
6
9
  import torch.nn as nn
7
10
 
8
11
  class LinearNF4(nn.Linear):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lycoris_lora
3
- Version: 3.0.0.dev7
3
+ Version: 3.0.0.dev9
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
@@ -10,6 +10,7 @@ lycoris/functional/__init__.py
10
10
  lycoris/functional/general.py
11
11
  lycoris/functional/locon.py
12
12
  lycoris/functional/loha.py
13
+ lycoris/functional/lokr.py
13
14
  lycoris/modules/__init__.py
14
15
  lycoris/modules/base.py
15
16
  lycoris/modules/boft.py
@@ -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.dev7",
7
+ version="3.0.0.dev9",
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",