lycoris-lora 2.1.0.dev3__tar.gz → 2.1.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.
Files changed (45) hide show
  1. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/PKG-INFO +1 -1
  2. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/kohya/__init__.py +24 -45
  3. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/dylora.py +1 -3
  4. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/utils/__init__.py +141 -218
  5. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/wrapper.py +6 -3
  6. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris_lora.egg-info/PKG-INFO +1 -1
  7. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/setup.py +1 -1
  8. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/LICENSE.md +0 -0
  9. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/README.md +0 -0
  10. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/__init__.py +0 -0
  11. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/config.py +0 -0
  12. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/hcp/__init__.py +0 -0
  13. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/hcp/base.py +0 -0
  14. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/hcp/diag_oft.py +0 -0
  15. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/hcp/loha.py +0 -0
  16. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/hcp/lokr.py +0 -0
  17. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/kohya/model_utils.py +0 -0
  18. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/kohya/original_unet.py +0 -0
  19. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/kohya/sdxl_model_util.py +0 -0
  20. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/kohya/sdxl_original_unet.py +0 -0
  21. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/kohya/utils.py +0 -0
  22. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/__init__.py +0 -0
  23. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/attention.py +0 -0
  24. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/base.py +0 -0
  25. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/diag_oft.py +0 -0
  26. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/full.py +0 -0
  27. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/glokr.py +0 -0
  28. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/glora.py +0 -0
  29. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/hypernet/__init__.py +0 -0
  30. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/hypernet/generater.py +0 -0
  31. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/hypernet/text_encoder.py +0 -0
  32. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/ia3.py +0 -0
  33. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/locon.py +0 -0
  34. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/loha.py +0 -0
  35. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/lokr.py +0 -0
  36. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/modules/norms.py +0 -0
  37. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/utils/logger.py +0 -0
  38. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/utils/preset.py +0 -0
  39. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris/utils/xformers_utils.py +0 -0
  40. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris_lora.egg-info/SOURCES.txt +0 -0
  41. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris_lora.egg-info/dependency_links.txt +0 -0
  42. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris_lora.egg-info/not-zip-safe +0 -0
  43. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris_lora.egg-info/requires.txt +0 -0
  44. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/lycoris_lora.egg-info/top_level.txt +0 -0
  45. {lycoris_lora-2.1.0.dev3 → lycoris_lora-2.1.0.dev4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lycoris_lora
3
- Version: 2.1.0.dev3
3
+ Version: 2.1.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
@@ -15,6 +15,7 @@ import torch
15
15
  import torch.utils.checkpoint as checkpoint
16
16
 
17
17
  from .utils import *
18
+ from ..wrapper import LycorisNetwork
18
19
  from ..modules.locon import LoConModule
19
20
  from ..modules.loha import LohaModule
20
21
  from ..modules.ia3 import IA3Module
@@ -186,9 +187,7 @@ def create_network_from_weights(
186
187
  else:
187
188
  prefix = LycorisNetworkKohya.LORA_PREFIX_TEXT_ENCODER
188
189
  for name, modules in te.named_modules():
189
- lora_name = f"{prefix}_{name}".replace(
190
- ".", "_"
191
- )
190
+ lora_name = f"{prefix}_{name}".replace(".", "_")
192
191
  if lora_name in te_loras:
193
192
  te_loras[lora_name] = modules
194
193
 
@@ -279,7 +278,7 @@ def create_hypernetwork(
279
278
  )
280
279
 
281
280
 
282
- class LycorisNetworkKohya(torch.nn.Module):
281
+ class LycorisNetworkKohya(LycorisNetwork):
283
282
  """
284
283
  LoRA + LoCon
285
284
  """
@@ -343,7 +342,7 @@ class LycorisNetworkKohya(torch.nn.Module):
343
342
  train_norm=False,
344
343
  **kwargs,
345
344
  ) -> None:
346
- super().__init__()
345
+ torch.nn.Module.__init__(self)
347
346
  root_kwargs = kwargs
348
347
  self.multiplier = multiplier
349
348
  self.lora_dim = lora_dim
@@ -548,19 +547,15 @@ class LycorisNetworkKohya(torch.nn.Module):
548
547
 
549
548
  self.weights_sd = None
550
549
 
550
+ self.loras = self.text_encoder_loras + self.unet_loras
551
551
  # assertion
552
552
  names = set()
553
- for lora in self.text_encoder_loras + self.unet_loras:
553
+ for lora in self.loras:
554
554
  assert (
555
555
  lora.lora_name not in names
556
556
  ), f"duplicated lora name: {lora.lora_name}"
557
557
  names.add(lora.lora_name)
558
558
 
559
- def set_multiplier(self, multiplier):
560
- self.multiplier = multiplier
561
- for lora in self.text_encoder_loras + self.unet_loras:
562
- lora.multiplier = self.multiplier
563
-
564
559
  def load_weights(self, file):
565
560
  if os.path.splitext(file)[1] == ".safetensors":
566
561
  from safetensors.torch import load_file, safe_open
@@ -600,34 +595,27 @@ class LycorisNetworkKohya(torch.nn.Module):
600
595
  info = self.load_state_dict(self.weights_sd, False)
601
596
  print(f"weights are loaded: {info}")
602
597
 
603
- def apply_max_norm_regularization(self, max_norm_value, device):
604
- key_scaled = 0
605
- norms = []
606
- for model in self.unet_loras:
607
- if hasattr(model, "apply_max_norm"):
608
- scaled, norm = model.apply_max_norm(max_norm_value, device)
609
- norms.append(norm)
610
- key_scaled += scaled
598
+ # TODO refactor to common function with apply_to
599
+ def merge_to(self, text_encoder, unet, weights_sd, dtype, device):
600
+ apply_text_encoder = apply_unet = False
601
+ for key in weights_sd.keys():
602
+ if key.startswith(LycorisNetworkKohya.LORA_PREFIX_TEXT_ENCODER):
603
+ apply_text_encoder = True
604
+ elif key.startswith(LycorisNetworkKohya.LORA_PREFIX_UNET):
605
+ apply_unet = True
611
606
 
612
- for model in self.text_encoder_loras:
613
- if hasattr(model, "apply_max_norm"):
614
- scaled, norm = model.apply_max_norm(max_norm_value, device)
615
- norms.append(norm)
616
- key_scaled += scaled
617
-
618
- if key_scaled == 0:
619
- return key_scaled, 0, 0
620
-
621
- return key_scaled, sum(norms) / len(norms), max(norms)
607
+ if apply_text_encoder:
608
+ print("enable LoRA for text encoder")
609
+ else:
610
+ self.text_encoder_loras = []
622
611
 
623
- def enable_gradient_checkpointing(self):
624
- # not supported
625
- def make_ckpt(module):
626
- if isinstance(module, torch.nn.Module):
627
- module.grad_ckpt = True
612
+ if apply_unet:
613
+ print("enable LoRA for U-Net")
614
+ else:
615
+ self.unet_loras = []
628
616
 
629
- self.apply(make_ckpt)
630
- pass
617
+ self.loras = self.text_encoder_loras + self.unet_loras
618
+ super().merge_to(1)
631
619
 
632
620
  def prepare_optimizer_params(self, text_encoder_lr, unet_lr, learning_rate):
633
621
  def enumerate_params(loras):
@@ -653,15 +641,6 @@ class LycorisNetworkKohya(torch.nn.Module):
653
641
 
654
642
  return all_params
655
643
 
656
- def prepare_grad_etc(self, text_encoder, unet):
657
- self.requires_grad_(True)
658
-
659
- def on_epoch_start(self, text_encoder, unet):
660
- self.train()
661
-
662
- def get_trainable_params(self):
663
- return self.parameters()
664
-
665
644
  def save_weights(self, file, dtype, metadata):
666
645
  if metadata is not None and len(metadata) == 0:
667
646
  metadata = None
@@ -103,9 +103,7 @@ class DyLoraModule(ModuleCustomSD):
103
103
  self.org_module[0].forward = self.org_forward
104
104
 
105
105
  def merge_to(self, multiplier=1.0):
106
- up = torch.concat(
107
- list(self.up_list), dim=1
108
- )
106
+ up = torch.concat(list(self.up_list), dim=1)
109
107
  down = torch.concat(list(self.down_list))
110
108
  diff_weight = up @ down * self.scale * multiplier / up.size(1)
111
109
  self.org_module[0].weight.data.add_(diff_weight)
@@ -67,7 +67,7 @@ def extract_conv(
67
67
 
68
68
  U = U[:, :lora_rank]
69
69
  S = S[:lora_rank]
70
- U = U @ torch.diag(S)
70
+ U = U @ torch.diag(S).to(device)
71
71
  Vh = Vh[:lora_rank, :]
72
72
 
73
73
  diff = (weight - (U @ Vh).reshape(out_ch, in_ch, kernel_size, kernel_size)).detach()
@@ -115,7 +115,7 @@ def extract_linear(
115
115
 
116
116
  U = U[:, :lora_rank]
117
117
  S = S[:lora_rank]
118
- U = U @ torch.diag(S)
118
+ U = U @ torch.diag(S).to(device)
119
119
  Vh = Vh[:lora_rank, :]
120
120
 
121
121
  diff = (weight - U @ Vh).detach()
@@ -125,6 +125,7 @@ def extract_linear(
125
125
  return (extract_weight_A, extract_weight_B, diff), "low rank"
126
126
 
127
127
 
128
+ @torch.no_grad()
128
129
  def extract_diff(
129
130
  base_tes,
130
131
  db_tes,
@@ -139,19 +140,19 @@ def extract_diff(
139
140
  small_conv=True,
140
141
  ):
141
142
  UNET_TARGET_REPLACE_MODULE = [
142
- "Transformer2DModel",
143
- "Attention",
144
- "ResnetBlock2D",
145
- "Downsample2D",
146
- "Upsample2D",
143
+ "Linear",
144
+ "Conv2d",
145
+ "LayerNorm",
146
+ "GroupNorm",
147
+ "GroupNorm32",
147
148
  ]
148
- UNET_TARGET_REPLACE_NAME = [
149
- "conv_in",
150
- "conv_out",
151
- "time_embedding.linear_1",
152
- "time_embedding.linear_2",
149
+ TEXT_ENCODER_TARGET_REPLACE_MODULE = [
150
+ "Linear",
151
+ "Conv2d",
152
+ "LayerNorm",
153
+ "GroupNorm",
154
+ "GroupNorm32",
153
155
  ]
154
- TEXT_ENCODER_TARGET_REPLACE_MODULE = ["CLIPAttention", "CLIPMLP"]
155
156
  LORA_PREFIX_UNET = "lora_unet"
156
157
  LORA_PREFIX_TEXT_ENCODER = "lora_te"
157
158
 
@@ -160,235 +161,157 @@ def extract_diff(
160
161
  root_module: torch.nn.Module,
161
162
  target_module: torch.nn.Module,
162
163
  target_replace_modules,
163
- target_replace_names=[],
164
164
  ):
165
165
  loras = {}
166
166
  temp = {}
167
- temp_name = {}
168
167
 
169
168
  for name, module in root_module.named_modules():
170
169
  if module.__class__.__name__ in target_replace_modules:
171
- temp[name] = {}
172
- for child_name, child_module in module.named_modules():
173
- if child_module.__class__.__name__ not in {"Linear", "Conv2d"}:
174
- continue
175
- temp[name][child_name] = child_module
176
- elif name in target_replace_names:
177
- temp_name[name] = module
170
+ temp[name] = module
178
171
 
179
- for name, module in tqdm(list(target_module.named_modules())):
180
- if name in temp:
181
- weights = temp[name]
182
- for child_name, child_module in module.named_modules():
183
- lora_name = prefix + "." + name + "." + child_name
184
- lora_name = lora_name.replace(".", "_")
185
- layer = child_module.__class__.__name__
186
- if layer in {"Linear", "Conv2d"}:
187
- root_weight = child_module.weight
188
- if torch.allclose(root_weight, weights[child_name].weight):
189
- continue
190
-
191
- if layer == "Linear":
192
- weight, decompose_mode = extract_linear(
193
- (child_module.weight - weights[child_name].weight),
194
- mode,
195
- linear_mode_param,
196
- device=extract_device,
197
- )
198
- if decompose_mode == "low rank":
199
- extract_a, extract_b, diff = weight
200
- elif layer == "Conv2d":
201
- is_linear = (
202
- child_module.weight.shape[2] == 1
203
- and child_module.weight.shape[3] == 1
204
- )
205
- weight, decompose_mode = extract_conv(
206
- (child_module.weight - weights[child_name].weight),
207
- mode,
208
- linear_mode_param if is_linear else conv_mode_param,
209
- device=extract_device,
210
- )
211
- if decompose_mode == "low rank":
212
- extract_a, extract_b, diff = weight
213
- if (
214
- small_conv
215
- and not is_linear
216
- and decompose_mode == "low rank"
217
- ):
218
- dim = extract_a.size(0)
219
- (extract_c, extract_a, _), _ = extract_conv(
220
- extract_a.transpose(0, 1),
221
- "fixed",
222
- dim,
223
- extract_device,
224
- True,
225
- )
226
- extract_a = extract_a.transpose(0, 1)
227
- extract_c = extract_c.transpose(0, 1)
228
- loras[f"{lora_name}.lora_mid.weight"] = (
229
- extract_c.detach().cpu().contiguous().half()
230
- )
231
- diff = (
232
- child_module.weight
233
- - torch.einsum(
234
- "i j k l, j r, p i -> p r k l",
235
- extract_c,
236
- extract_a.flatten(1, -1),
237
- extract_b.flatten(1, -1),
238
- )
239
- .detach()
240
- .cpu()
241
- .contiguous()
242
- )
243
- del extract_c
244
- else:
245
- continue
246
- if decompose_mode == "low rank":
247
- loras[f"{lora_name}.lora_down.weight"] = (
248
- extract_a.detach().cpu().contiguous().half()
249
- )
250
- loras[f"{lora_name}.lora_up.weight"] = (
251
- extract_b.detach().cpu().contiguous().half()
252
- )
253
- loras[f"{lora_name}.alpha"] = torch.Tensor(
254
- [extract_a.shape[0]]
255
- ).half()
256
- if use_bias:
257
- diff = diff.detach().cpu().reshape(extract_b.size(0), -1)
258
- sparse_diff = (
259
- make_sparse(diff, sparsity).to_sparse().coalesce()
260
- )
261
-
262
- indices = sparse_diff.indices().to(torch.int16)
263
- values = sparse_diff.values().half()
264
- loras[f"{lora_name}.bias_indices"] = indices
265
- loras[f"{lora_name}.bias_values"] = values
266
- loras[f"{lora_name}.bias_size"] = torch.tensor(
267
- diff.shape
268
- ).to(torch.int16)
269
- del extract_a, extract_b, diff
270
- elif decompose_mode == "full":
271
- loras[f"{lora_name}.diff"] = (
272
- weight.detach().cpu().contiguous().half()
273
- )
274
- if weights[child_name].bias is not None:
275
- bias_diff = child_module.bias - weights[child_name].bias
276
- loras[f"{lora_name}.diff_b"] = (
277
- bias_diff.detach().cpu().contiguous().half()
278
- )
279
- else:
280
- raise NotImplementedError
281
- elif name in temp_name:
282
- weights = temp_name[name]
283
- lora_name = prefix + "." + name
284
- lora_name = lora_name.replace(".", "_")
285
- layer = module.__class__.__name__
286
-
287
- if layer in {"Linear", "Conv2d"}:
288
- root_weight = module.weight
289
- if torch.allclose(root_weight, weights.weight):
290
- continue
291
-
292
- if layer == "Linear":
293
- weight, decompose_mode = extract_linear(
294
- (root_weight - weights.weight),
295
- mode,
296
- linear_mode_param,
297
- device=extract_device,
298
- )
299
- if decompose_mode == "low rank":
300
- extract_a, extract_b, diff = weight
301
- elif layer == "Conv2d":
302
- is_linear = root_weight.shape[2] == 1 and root_weight.shape[3] == 1
303
- weight, decompose_mode = extract_conv(
304
- (root_weight - weights.weight),
305
- mode,
306
- linear_mode_param if is_linear else conv_mode_param,
307
- device=extract_device,
308
- )
309
- if decompose_mode == "low rank":
310
- extract_a, extract_b, diff = weight
311
- if small_conv and not is_linear and decompose_mode == "low rank":
312
- dim = extract_a.size(0)
313
- (extract_c, extract_a, _), _ = extract_conv(
314
- extract_a.transpose(0, 1),
315
- "fixed",
316
- dim,
317
- extract_device,
318
- True,
319
- )
320
- extract_a = extract_a.transpose(0, 1)
321
- extract_c = extract_c.transpose(0, 1)
322
- loras[f"{lora_name}.lora_mid.weight"] = (
323
- extract_c.detach().cpu().contiguous().half()
324
- )
325
- diff = (
326
- root_weight
327
- - torch.einsum(
328
- "i j k l, j r, p i -> p r k l",
329
- extract_c,
330
- extract_a.flatten(1, -1),
331
- extract_b.flatten(1, -1),
332
- )
333
- .detach()
334
- .cpu()
335
- .contiguous()
336
- )
337
- del extract_c
338
- else:
172
+ for name, module in tqdm(
173
+ list((n, m) for n, m in target_module.named_modules() if n in temp)
174
+ ):
175
+ weights = temp[name]
176
+ lora_name = prefix + "." + name
177
+ lora_name = lora_name.replace(".", "_")
178
+ layer = module.__class__.__name__
179
+
180
+ if layer in {
181
+ "Linear",
182
+ "Conv2d",
183
+ "LayerNorm",
184
+ "GroupNorm",
185
+ "GroupNorm32",
186
+ }:
187
+ root_weight = module.weight
188
+ if torch.allclose(root_weight, weights.weight):
339
189
  continue
190
+ else:
191
+ continue
192
+ module = module.to(extract_device)
193
+ weights = weights.to(extract_device)
194
+
195
+ if mode == "full":
196
+ decompose_mode = "full"
197
+ elif layer == "Linear":
198
+ weight, decompose_mode = extract_linear(
199
+ (root_weight - weights.weight),
200
+ mode,
201
+ linear_mode_param,
202
+ device=extract_device,
203
+ )
204
+ if decompose_mode == "low rank":
205
+ extract_a, extract_b, diff = weight
206
+ elif layer == "Conv2d":
207
+ is_linear = root_weight.shape[2] == 1 and root_weight.shape[3] == 1
208
+ weight, decompose_mode = extract_conv(
209
+ (root_weight - weights.weight),
210
+ mode,
211
+ linear_mode_param if is_linear else conv_mode_param,
212
+ device=extract_device,
213
+ )
340
214
  if decompose_mode == "low rank":
341
- loras[f"{lora_name}.lora_down.weight"] = (
342
- extract_a.detach().cpu().contiguous().half()
215
+ extract_a, extract_b, diff = weight
216
+ if small_conv and not is_linear and decompose_mode == "low rank":
217
+ dim = extract_a.size(0)
218
+ (extract_c, extract_a, _), _ = extract_conv(
219
+ extract_a.transpose(0, 1),
220
+ "fixed",
221
+ dim,
222
+ extract_device,
223
+ True,
343
224
  )
344
- loras[f"{lora_name}.lora_up.weight"] = (
345
- extract_b.detach().cpu().contiguous().half()
225
+ extract_a = extract_a.transpose(0, 1)
226
+ extract_c = extract_c.transpose(0, 1)
227
+ loras[f"{lora_name}.lora_mid.weight"] = (
228
+ extract_c.detach().cpu().contiguous().half()
346
229
  )
347
- loras[f"{lora_name}.alpha"] = torch.Tensor(
348
- [extract_a.shape[0]]
349
- ).half()
350
- if use_bias:
351
- diff = diff.detach().cpu().reshape(extract_b.size(0), -1)
352
- sparse_diff = make_sparse(diff, sparsity).to_sparse().coalesce()
353
-
354
- indices = sparse_diff.indices().to(torch.int16)
355
- values = sparse_diff.values().half()
356
- loras[f"{lora_name}.bias_indices"] = indices
357
- loras[f"{lora_name}.bias_values"] = values
358
- loras[f"{lora_name}.bias_size"] = torch.tensor(diff.shape).to(
359
- torch.int16
230
+ diff = (
231
+ root_weight
232
+ - torch.einsum(
233
+ "i j k l, j r, p i -> p r k l",
234
+ extract_c,
235
+ extract_a.flatten(1, -1),
236
+ extract_b.flatten(1, -1),
360
237
  )
361
- del extract_a, extract_b, diff
362
- elif decompose_mode == "full":
363
- loras[f"{lora_name}.diff"] = (
364
- weight.detach().cpu().contiguous().half()
238
+ .detach()
239
+ .cpu()
240
+ .contiguous()
365
241
  )
366
- if weights.bias is not None:
367
- bias_diff = module.bias - weights.bias
368
- loras[f"{lora_name}.diff_b"] = (
369
- bias_diff.detach().cpu().contiguous().half()
370
- )
242
+ del extract_c
243
+ else:
244
+ module = module.to("cpu")
245
+ weights = weights.to("cpu")
246
+ continue
247
+
248
+ if decompose_mode == "low rank":
249
+ loras[f"{lora_name}.lora_down.weight"] = (
250
+ extract_a.detach().cpu().contiguous().half()
251
+ )
252
+ loras[f"{lora_name}.lora_up.weight"] = (
253
+ extract_b.detach().cpu().contiguous().half()
254
+ )
255
+ loras[f"{lora_name}.alpha"] = torch.Tensor([extract_a.shape[0]]).half()
256
+ if use_bias:
257
+ diff = diff.detach().cpu().reshape(extract_b.size(0), -1)
258
+ sparse_diff = make_sparse(diff, sparsity).to_sparse().coalesce()
259
+
260
+ indices = sparse_diff.indices().to(torch.int16)
261
+ values = sparse_diff.values().half()
262
+ loras[f"{lora_name}.bias_indices"] = indices
263
+ loras[f"{lora_name}.bias_values"] = values
264
+ loras[f"{lora_name}.bias_size"] = torch.tensor(diff.shape).to(
265
+ torch.int16
266
+ )
267
+ del extract_a, extract_b, diff
268
+ elif decompose_mode == "full":
269
+ if "Norm" in layer:
270
+ w_key = "w_norm"
271
+ b_key = "b_norm"
371
272
  else:
372
- raise NotImplementedError
273
+ w_key = "diff"
274
+ b_key = "diff_b"
275
+ weight_diff = module.weight - weights.weight
276
+ loras[f"{lora_name}.{w_key}"] = (
277
+ weight_diff.detach().cpu().contiguous().half()
278
+ )
279
+ if weights.bias is not None:
280
+ bias_diff = module.bias - weights.bias
281
+ loras[f"{lora_name}.{b_key}"] = (
282
+ bias_diff.detach().cpu().contiguous().half()
283
+ )
284
+ else:
285
+ raise NotImplementedError
286
+ module = module.to("cpu")
287
+ weights = weights.to("cpu")
373
288
  return loras
374
289
 
375
290
  all_loras = {}
291
+
292
+ all_loras |= make_state_dict(
293
+ LORA_PREFIX_UNET,
294
+ base_unet,
295
+ db_unet,
296
+ UNET_TARGET_REPLACE_MODULE,
297
+ )
298
+ del base_unet, db_unet
299
+ if torch.cuda.is_available():
300
+ torch.cuda.empty_cache()
301
+
376
302
  for idx, (te1, te2) in enumerate(zip(base_tes, db_tes)):
377
303
  if len(base_tes) > 1:
378
304
  prefix = f"{LORA_PREFIX_TEXT_ENCODER}{idx+1}"
379
305
  else:
380
306
  prefix = LORA_PREFIX_TEXT_ENCODER
381
307
  all_loras |= make_state_dict(
382
- prefix, te1, te2, TEXT_ENCODER_TARGET_REPLACE_MODULE
308
+ prefix,
309
+ te1,
310
+ te2,
311
+ TEXT_ENCODER_TARGET_REPLACE_MODULE,
383
312
  )
313
+ del te1, te2
384
314
 
385
- all_loras |= make_state_dict(
386
- LORA_PREFIX_UNET,
387
- base_unet,
388
- db_unet,
389
- UNET_TARGET_REPLACE_MODULE,
390
- UNET_TARGET_REPLACE_NAME,
391
- )
392
315
  print(len(all_loras))
393
316
  return all_loras
394
317
 
@@ -685,7 +608,7 @@ def merge(tes, unet, lyco_state_dict, scale: float = 1.0, device="cpu"):
685
608
  )
686
609
 
687
610
  for idx, te in enumerate(tes):
688
- if len(tes)>1:
611
+ if len(tes) > 1:
689
612
  prefix = LORA_PREFIX_TEXT_ENCODER + str(idx + 1)
690
613
  else:
691
614
  prefix = LORA_PREFIX_TEXT_ENCODER
@@ -432,6 +432,9 @@ class LycorisNetwork(torch.nn.Module):
432
432
  info = self.load_state_dict(self.weights_sd, False)
433
433
  print(f"weights are loaded: {info}")
434
434
 
435
+ def is_mergeable(self):
436
+ return True
437
+
435
438
  def restore(self):
436
439
  for lora in self.loras:
437
440
  lora.restore()
@@ -479,13 +482,13 @@ class LycorisNetwork(torch.nn.Module):
479
482
  all_params.append(param_data)
480
483
  return all_params
481
484
 
482
- def prepare_grad_etc(self):
485
+ def prepare_grad_etc(self, *args):
483
486
  self.requires_grad_(True)
484
487
 
485
- def on_epoch_start(self):
488
+ def on_epoch_start(self, *args):
486
489
  self.train()
487
490
 
488
- def get_trainable_params(self):
491
+ def get_trainable_params(self, *args):
489
492
  return self.parameters()
490
493
 
491
494
  def save_weights(self, file, dtype, metadata):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lycoris-lora
3
- Version: 2.1.0.dev3
3
+ Version: 2.1.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
@@ -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="2.1.0.dev3",
7
+ version="2.1.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",