lycoris-lora 3.1.1.post1__tar.gz → 3.2.0.dev2__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 (48) hide show
  1. {lycoris_lora-3.1.1.post1/lycoris_lora.egg-info → lycoris_lora-3.2.0.dev2}/PKG-INFO +9 -2
  2. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/config.py +14 -4
  3. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/kohya.py +164 -56
  4. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/base.py +32 -0
  5. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/wrapper.py +8 -0
  6. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2/lycoris_lora.egg-info}/PKG-INFO +9 -2
  7. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris_lora.egg-info/SOURCES.txt +2 -0
  8. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/setup.py +1 -1
  9. lycoris_lora-3.2.0.dev2/test/compile.py +69 -0
  10. lycoris_lora-3.2.0.dev2/test/restore.py +56 -0
  11. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/LICENSE.md +0 -0
  12. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/README.md +0 -0
  13. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/__init__.py +0 -0
  14. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/functional/__init__.py +0 -0
  15. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/functional/boft.py +0 -0
  16. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/functional/diag_oft.py +0 -0
  17. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/functional/general.py +0 -0
  18. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/functional/locon.py +0 -0
  19. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/functional/loha.py +0 -0
  20. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/functional/lokr.py +0 -0
  21. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/logging.py +0 -0
  22. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/__init__.py +0 -0
  23. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/boft.py +0 -0
  24. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/diag_oft.py +0 -0
  25. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/dylora.py +0 -0
  26. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/full.py +0 -0
  27. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/glora.py +0 -0
  28. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/ia3.py +0 -0
  29. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/locon.py +0 -0
  30. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/loha.py +0 -0
  31. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/lokr.py +0 -0
  32. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/modules/norms.py +0 -0
  33. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/utils/__init__.py +0 -0
  34. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/utils/general.py +0 -0
  35. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/utils/logger.py +0 -0
  36. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/utils/preset.py +0 -0
  37. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/utils/quant.py +0 -0
  38. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris/utils/xformers_utils.py +0 -0
  39. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris_lora.egg-info/dependency_links.txt +0 -0
  40. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris_lora.egg-info/not-zip-safe +0 -0
  41. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris_lora.egg-info/requires.txt +0 -0
  42. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/lycoris_lora.egg-info/top_level.txt +0 -0
  43. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/setup.cfg +0 -0
  44. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/test/__init__.py +0 -0
  45. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/test/functional.py +0 -0
  46. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/test/kohya.py +0 -0
  47. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/test/module.py +0 -0
  48. {lycoris_lora-3.1.1.post1 → lycoris_lora-3.2.0.dev2}/test/wrapper.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: lycoris_lora
3
- Version: 3.1.1.post1
3
+ Version: 3.2.0.dev2
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
@@ -23,3 +23,10 @@ Requires-Dist: torch
23
23
  Requires-Dist: einops
24
24
  Requires-Dist: toml
25
25
  Requires-Dist: tqdm
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: home-page
30
+ Dynamic: requires-dist
31
+ Dynamic: requires-python
32
+ Dynamic: summary
@@ -6,10 +6,12 @@ PRESET = {
6
6
  "ResnetBlock2D",
7
7
  "Downsample2D",
8
8
  "Upsample2D",
9
- "HunYuanDiTBlock",
10
- "DoubleStreamBlock",
11
- "SingleStreamBlock",
12
- "SingleDiTBlock",
9
+ "HunYuanDiTBlock", # HunYuanDiT
10
+ "DoubleStreamBlock", # Flux
11
+ "SingleStreamBlock", # Flux
12
+ "SingleDiTBlock", # SD3.5
13
+ "MMDoubleStreamBlock", # HunYuanVideo
14
+ "MMSingleStreamBlock", # HunYuanVideo
13
15
  ],
14
16
  "unet_target_name": [
15
17
  "conv_in",
@@ -35,6 +37,8 @@ PRESET = {
35
37
  "DoubleStreamBlock",
36
38
  "SingleStreamBlock",
37
39
  "SingleDiTBlock",
40
+ "MMDoubleStreamBlock", # HunYuanVideo
41
+ "MMSingleStreamBlock", # HunYuanVideo
38
42
  ],
39
43
  "unet_target_name": [
40
44
  "time_embedding.linear_1",
@@ -57,6 +61,8 @@ PRESET = {
57
61
  "DoubleStreamBlock",
58
62
  "SingleStreamBlock",
59
63
  "SingleDiTBlock",
64
+ "MMDoubleStreamBlock", # HunYuanVideo
65
+ "MMSingleStreamBlock", # HunYuanVideo
60
66
  ],
61
67
  "unet_target_name": [],
62
68
  "text_encoder_target_module": [
@@ -94,6 +100,8 @@ PRESET = {
94
100
  "DoubleStreamBlock",
95
101
  "SingleStreamBlock",
96
102
  "SingleDiTBlock",
103
+ "MMDoubleStreamBlock", # HunYuanVideo
104
+ "MMSingleStreamBlock", # HunYuanVideo
97
105
  ],
98
106
  "unet_target_name": [
99
107
  "conv_in",
@@ -112,6 +120,8 @@ PRESET = {
112
120
  "DoubleStreamBlock",
113
121
  "SingleStreamBlock",
114
122
  "SingleDiTBlock",
123
+ "MMDoubleStreamBlock", # HunYuanVideo
124
+ "MMSingleStreamBlock", # HunYuanVideo
115
125
  ],
116
126
  "unet_target_name": [],
117
127
  "text_encoder_target_module": [],
@@ -63,6 +63,22 @@ def create_network(
63
63
  rs_lora = str_bool(kwargs.get("rs_lora", False))
64
64
  unbalanced_factorization = str_bool(kwargs.get("unbalanced_factorization", False))
65
65
  train_t5xxl = str_bool(kwargs.get("train_t5xxl", False))
66
+ # lora_plus
67
+ loraplus_lr_ratio = (
68
+ float(kwargs.get("loraplus_lr_ratio", None))
69
+ if kwargs.get("loraplus_lr_ratio", None) is not None
70
+ else None
71
+ )
72
+ loraplus_unet_lr_ratio = (
73
+ float(kwargs.get("loraplus_unet_lr_ratio", None))
74
+ if kwargs.get("loraplus_unet_lr_ratio", None) is not None
75
+ else None
76
+ )
77
+ loraplus_text_encoder_lr_ratio = (
78
+ float(kwargs.get("loraplus_text_encoder_lr_ratio", None))
79
+ if kwargs.get("loraplus_text_encoder_lr_ratio", None) is not None
80
+ else None
81
+ )
66
82
 
67
83
  if unbalanced_factorization:
68
84
  logger.info("Unbalanced factorization for LoKr is enabled")
@@ -117,6 +133,14 @@ def create_network(
117
133
  unbalanced_factorization=unbalanced_factorization,
118
134
  train_t5xxl=train_t5xxl,
119
135
  )
136
+ if (
137
+ loraplus_lr_ratio is not None
138
+ or loraplus_unet_lr_ratio is not None
139
+ or loraplus_text_encoder_lr_ratio is not None
140
+ ):
141
+ network.set_loraplus_lr_ratio(
142
+ loraplus_lr_ratio, loraplus_unet_lr_ratio, loraplus_text_encoder_lr_ratio
143
+ )
120
144
 
121
145
  return network
122
146
 
@@ -157,22 +181,23 @@ def create_network_from_weights(
157
181
  if lora_name in unet_loras:
158
182
  unet_loras[lora_name] = modules
159
183
 
160
- if isinstance(text_encoder, list):
161
- text_encoders = text_encoder
162
- use_index = True
163
- else:
164
- text_encoders = [text_encoder]
165
- use_index = False
166
-
167
- for idx, te in enumerate(text_encoders):
168
- if use_index:
169
- prefix = f"{LycorisNetworkKohya.LORA_PREFIX_TEXT_ENCODER}{idx+1}"
184
+ if text_encoder:
185
+ if isinstance(text_encoder, list):
186
+ text_encoders = text_encoder
187
+ use_index = True
170
188
  else:
171
- prefix = LycorisNetworkKohya.LORA_PREFIX_TEXT_ENCODER
172
- for name, modules in te.named_modules():
173
- lora_name = f"{prefix}_{name}".replace(".", "_")
174
- if lora_name in te_loras:
175
- te_loras[lora_name] = modules
189
+ text_encoders = [text_encoder]
190
+ use_index = False
191
+
192
+ for idx, te in enumerate(text_encoders):
193
+ if use_index:
194
+ prefix = f"{LycorisNetworkKohya.LORA_PREFIX_TEXT_ENCODER}{idx+1}"
195
+ else:
196
+ prefix = LycorisNetworkKohya.LORA_PREFIX_TEXT_ENCODER
197
+ for name, modules in te.named_modules():
198
+ lora_name = f"{prefix}_{name}".replace(".", "_")
199
+ if lora_name in te_loras:
200
+ te_loras[lora_name] = modules
176
201
 
177
202
  original_level = logger.level
178
203
  logger.setLevel(logging.ERROR)
@@ -192,14 +217,16 @@ def create_network_from_weights(
192
217
  logger.info(f"{len(network.unet_loras)} Modules Loaded")
193
218
 
194
219
  logger.info("Loading TE Modules from state dict...")
195
- for lora_name, orig_modules in te_loras.items():
196
- if orig_modules is None:
197
- continue
198
- lyco_type, params = get_module(weights_sd, lora_name)
199
- module = make_module(lyco_type, params, lora_name, orig_modules)
200
- if module is not None:
201
- network.text_encoder_loras.append(module)
202
- logger.info(f"{len(network.text_encoder_loras)} Modules Loaded")
220
+
221
+ if text_encoder:
222
+ for lora_name, orig_modules in te_loras.items():
223
+ if orig_modules is None:
224
+ continue
225
+ lyco_type, params = get_module(weights_sd, lora_name)
226
+ module = make_module(lyco_type, params, lora_name, orig_modules)
227
+ if module is not None:
228
+ network.text_encoder_loras.append(module)
229
+ logger.info(f"{len(network.text_encoder_loras)} Modules Loaded")
203
230
 
204
231
  for lora in network.unet_loras + network.text_encoder_loras:
205
232
  lora.multiplier = multiplier
@@ -223,6 +250,8 @@ class LycorisNetworkKohya(LycorisNetwork):
223
250
  "DoubleStreamBlock",
224
251
  "SingleStreamBlock",
225
252
  "SingleDiTBlock",
253
+ "MMDoubleStreamBlock", # HunYuanVideo
254
+ "MMSingleStreamBlock", # HunYuanVideo
226
255
  ]
227
256
  UNET_TARGET_REPLACE_NAME = [
228
257
  "conv_in",
@@ -291,6 +320,11 @@ class LycorisNetworkKohya(LycorisNetwork):
291
320
  self.lora_dim = lora_dim
292
321
  self.train_t5xxl = train_t5xxl
293
322
 
323
+ # 初始化LoRA+相关属性
324
+ self.loraplus_lr_ratio = None
325
+ self.loraplus_unet_lr_ratio = None
326
+ self.loraplus_text_encoder_lr_ratio = None
327
+
294
328
  if not self.ENABLE_CONV:
295
329
  conv_lora_dim = 0
296
330
 
@@ -460,27 +494,28 @@ class LycorisNetworkKohya(LycorisNetwork):
460
494
  ]
461
495
  LycorisNetworkKohya.UNET_TARGET_REPLACE_NAME = []
462
496
 
463
- if isinstance(text_encoder, list):
464
- text_encoders = text_encoder
465
- use_index = True
466
- else:
467
- text_encoders = [text_encoder]
468
- use_index = False
469
-
470
497
  self.text_encoder_loras = []
471
- for i, te in enumerate(text_encoders):
472
- self.text_encoder_loras.extend(
473
- create_modules(
474
- LycorisNetworkKohya.LORA_PREFIX_TEXT_ENCODER
475
- + (f"{i+1}" if use_index else ""),
476
- te,
477
- LycorisNetworkKohya.TEXT_ENCODER_TARGET_REPLACE_MODULE,
478
- LycorisNetworkKohya.TEXT_ENCODER_TARGET_REPLACE_NAME,
498
+ if text_encoder:
499
+ if isinstance(text_encoder, list):
500
+ text_encoders = text_encoder
501
+ use_index = True
502
+ else:
503
+ text_encoders = [text_encoder]
504
+ use_index = False
505
+
506
+ for i, te in enumerate(text_encoders):
507
+ self.text_encoder_loras.extend(
508
+ create_modules(
509
+ LycorisNetworkKohya.LORA_PREFIX_TEXT_ENCODER
510
+ + (f"{i+1}" if use_index else ""),
511
+ te,
512
+ LycorisNetworkKohya.TEXT_ENCODER_TARGET_REPLACE_MODULE,
513
+ LycorisNetworkKohya.TEXT_ENCODER_TARGET_REPLACE_NAME,
514
+ )
479
515
  )
516
+ logger.info(
517
+ f"create LyCORIS for Text Encoder: {len(self.text_encoder_loras)} modules."
480
518
  )
481
- logger.info(
482
- f"create LyCORIS for Text Encoder: {len(self.text_encoder_loras)} modules."
483
- )
484
519
 
485
520
  self.unet_loras = create_modules(
486
521
  LycorisNetworkKohya.LORA_PREFIX_UNET,
@@ -604,29 +639,102 @@ class LycorisNetworkKohya(LycorisNetwork):
604
639
 
605
640
  return key_scaled, sum(norms) / len(norms), max(norms)
606
641
 
607
- def prepare_optimizer_params(self, text_encoder_lr, unet_lr, learning_rate):
608
- def enumerate_params(loras):
609
- params = []
610
- for lora in loras:
611
- params.extend(lora.parameters())
612
- return params
642
+ def set_loraplus_lr_ratio(
643
+ self, loraplus_lr_ratio, loraplus_unet_lr_ratio, loraplus_text_encoder_lr_ratio
644
+ ):
645
+ self.loraplus_lr_ratio = loraplus_lr_ratio
646
+ self.loraplus_unet_lr_ratio = loraplus_unet_lr_ratio
647
+ self.loraplus_text_encoder_lr_ratio = loraplus_text_encoder_lr_ratio
648
+
649
+ logger.info(
650
+ f"LoRA+ UNet LR Ratio: {self.loraplus_unet_lr_ratio or self.loraplus_lr_ratio}"
651
+ )
652
+ logger.info(
653
+ f"LoRA+ Text Encoder LR Ratio: {self.loraplus_text_encoder_lr_ratio or self.loraplus_lr_ratio}"
654
+ )
613
655
 
656
+ def prepare_optimizer_params(
657
+ self, text_encoder_lr=None, unet_lr: float = 1e-4, learning_rate=None
658
+ ):
614
659
  self.requires_grad_(True)
660
+
615
661
  all_params = []
662
+ lr_descriptions = []
663
+
664
+ def assemble_params(loras, lr, ratio):
665
+ param_groups = {"lora": {}, "plus": {}}
666
+ for lora in loras:
667
+ for name, param in lora.named_parameters():
668
+ if ratio is not None and "lora_up" in name:
669
+ param_groups["plus"][f"{lora.lora_name}.{name}"] = param
670
+ else:
671
+ param_groups["lora"][f"{lora.lora_name}.{name}"] = param
672
+
673
+ params = []
674
+ descriptions = []
675
+ for key in param_groups.keys():
676
+ param_data = {"params": param_groups[key].values()}
677
+
678
+ if len(param_data["params"]) == 0:
679
+ continue
680
+
681
+ if lr is not None:
682
+ if key == "plus":
683
+ param_data["lr"] = lr * ratio
684
+ else:
685
+ param_data["lr"] = lr
686
+
687
+ if (
688
+ param_data.get("lr", None) == 0
689
+ or param_data.get("lr", None) is None
690
+ ):
691
+ logger.info("NO LR skipping!")
692
+ continue
693
+
694
+ params.append(param_data)
695
+ descriptions.append("plus" if key == "plus" else "")
696
+
697
+ return params, descriptions
616
698
 
617
699
  if self.text_encoder_loras:
618
- param_data = {"params": enumerate_params(self.text_encoder_loras)}
619
- if text_encoder_lr is not None:
620
- param_data["lr"] = text_encoder_lr
621
- all_params.append(param_data)
700
+ params, descriptions = assemble_params(
701
+ self.text_encoder_loras,
702
+ text_encoder_lr if text_encoder_lr is not None else default_lr,
703
+ self.loraplus_text_encoder_lr_ratio or self.loraplus_lr_ratio,
704
+ )
705
+ all_params.extend(params)
706
+ lr_descriptions.extend(
707
+ ["textencoder" + (" " + d if d else "") for d in descriptions]
708
+ )
622
709
 
623
710
  if self.unet_loras:
624
- param_data = {"params": enumerate_params(self.unet_loras)}
625
- if unet_lr is not None:
626
- param_data["lr"] = unet_lr
627
- all_params.append(param_data)
711
+ params, descriptions = assemble_params(
712
+ self.unet_loras,
713
+ unet_lr if unet_lr is not None else default_lr,
714
+ self.loraplus_unet_lr_ratio or self.loraplus_lr_ratio,
715
+ )
716
+ all_params.extend(params)
717
+ lr_descriptions.extend(
718
+ ["unet" + (" " + d if d else "") for d in descriptions]
719
+ )
720
+
721
+ return all_params, lr_descriptions
722
+
723
+ def enable_gradient_checkpointing(self):
724
+ # not supported
725
+ pass
726
+
727
+ def prepare_grad_etc(self, *args):
728
+ self.requires_grad_(True)
729
+
730
+ def on_epoch_start(self, unet):
731
+ self.train()
732
+
733
+ def on_step_start(self):
734
+ pass
628
735
 
629
- return all_params
736
+ def get_trainable_params(self):
737
+ return self.parameters()
630
738
 
631
739
  def save_weights(self, file, dtype, metadata):
632
740
  if metadata is not None and len(metadata) == 0:
@@ -290,6 +290,38 @@ class LycorisBaseModule(ModuleCustomSD):
290
290
  self.org_module[0].bias = nn.Parameter(bias)
291
291
  self.to(self_device, self_dtype)
292
292
 
293
+ def onfly_merge(self, multiplier=1.0):
294
+ if self.not_supported:
295
+ return
296
+ self_device = next(self.parameters()).device
297
+ self_dtype = next(self.parameters()).dtype
298
+ self.to(self.org_weight)
299
+ self.cached_org_weight = self.org_weight.data.cpu()
300
+ self.cached_org_bias = None
301
+ weight, bias = self.get_merged_weight(
302
+ multiplier, self.org_weight.shape, self.org_weight.device
303
+ )
304
+ self.org_weight = weight
305
+ if bias is not None:
306
+ bias = bias.to(self.org_weight)
307
+ if self.org_module[0].bias is not None:
308
+ self.org_module[0].bias.data.copy_(bias)
309
+ self.cached_org_bias = self.org_module[0].bias.data.cpu()
310
+ else:
311
+ self.org_module[0].bias = nn.Parameter(bias)
312
+ if self.org_module[0].bias is not None:
313
+ self.org_module[0].bias = self.org_module[0].bias.to(self.org_weight)
314
+ self.to(self_device, self_dtype)
315
+
316
+ def onfly_restore(self):
317
+ if self.not_supported:
318
+ return
319
+ self.org_weight = self.cached_org_weight.to(self.org_weight)
320
+ if self.cached_org_bias is not None:
321
+ self.org_module[0].bias.data.copy_(self.cached_org_bias.to(self.org_weight))
322
+ del self.cached_org_weight
323
+ del self.cached_org_bias
324
+
293
325
  def get_diff_weight(self, multiplier=1.0, shape=None, device=None):
294
326
  raise NotImplementedError
295
327
 
@@ -568,6 +568,14 @@ class LycorisNetwork(torch.nn.Module):
568
568
  for lora in self.loras:
569
569
  lora.merge_to(weight)
570
570
 
571
+ def onfly_merge(self, weight=1.0):
572
+ for lora in self.loras:
573
+ lora.onfly_merge(weight)
574
+
575
+ def onfly_restore(self):
576
+ for lora in self.loras:
577
+ lora.onfly_restore()
578
+
571
579
  def apply_max_norm_regularization(self, max_norm_value, device):
572
580
  key_scaled = 0
573
581
  norms = []
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: lycoris_lora
3
- Version: 3.1.1.post1
3
+ Version: 3.2.0.dev2
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
@@ -23,3 +23,10 @@ Requires-Dist: torch
23
23
  Requires-Dist: einops
24
24
  Requires-Dist: toml
25
25
  Requires-Dist: tqdm
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: home-page
30
+ Dynamic: requires-dist
31
+ Dynamic: requires-python
32
+ Dynamic: summary
@@ -38,7 +38,9 @@ lycoris_lora.egg-info/not-zip-safe
38
38
  lycoris_lora.egg-info/requires.txt
39
39
  lycoris_lora.egg-info/top_level.txt
40
40
  test/__init__.py
41
+ test/compile.py
41
42
  test/functional.py
42
43
  test/kohya.py
43
44
  test/module.py
45
+ test/restore.py
44
46
  test/wrapper.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.1.1.post1",
7
+ version="3.2.0.dev2",
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",
@@ -0,0 +1,69 @@
1
+ import sys
2
+
3
+ sys.setrecursionlimit(10000000)
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+ import torch.nn.functional as F
8
+
9
+ from torchao.quantization.quant_api import int8_weight_only, quantize_
10
+
11
+ from lycoris import create_lycoris
12
+
13
+
14
+ class TestNet(nn.Module):
15
+ def __init__(self):
16
+ super(TestNet, self).__init__()
17
+ self.fc1 = nn.Linear(8, 1024)
18
+ self.fc2 = nn.Linear(1024, 8)
19
+
20
+ def forward(self, x):
21
+ x = self.fc1(x)
22
+ x = F.relu(x)
23
+ x = self.fc2(x)
24
+ return x
25
+
26
+
27
+ def test_lycoris_compile():
28
+ net = TestNet().cuda()
29
+
30
+ test_x = torch.randn(1, 8).cuda()
31
+ out = net(test_x)
32
+ print("\nOriginal\n", out)
33
+
34
+ quantize_(net, int8_weight_only())
35
+ out = net(test_x)
36
+ print("\nQuantized\n", out)
37
+ compiled_net = torch.compile(net)
38
+ out = compiled_net(test_x)
39
+ print("\nQuantized compiled\n", out)
40
+
41
+ compiled_net._orig_mod.cpu()
42
+ compiled_net._orig_mod.cuda()
43
+
44
+ compiled_net.cpu()
45
+ compiled_net.cuda()
46
+
47
+ lycoris = create_lycoris(
48
+ net, algo="lokr", factor=2, bypass_mode=True, full_matrix=True
49
+ )
50
+ lycoris.apply_to()
51
+ lycoris.cuda()
52
+ out = net(test_x)
53
+ print("\nBypass Lokr Applied\n", out)
54
+
55
+ compiled_net = torch.compile(net)
56
+ compiled_out = compiled_net(test_x)
57
+ print("\nLyCORIS+torchao quantize_ compiled\n", compiled_out)
58
+ torch.sum(compiled_out).backward()
59
+
60
+ diff = torch.sum(torch.abs(out - compiled_out))
61
+ print("\nDiff: ", diff)
62
+ net.cpu()
63
+ lycoris.cpu()
64
+
65
+ assert torch.allclose(out, compiled_out, atol=1e-6)
66
+
67
+
68
+ if __name__ == "__main__":
69
+ test_lycoris_compile()
@@ -0,0 +1,56 @@
1
+ import sys
2
+
3
+ sys.setrecursionlimit(10000000)
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+ import torch.nn.functional as F
8
+
9
+ from lycoris import create_lycoris
10
+
11
+
12
+ class TestNet(nn.Module):
13
+ def __init__(self):
14
+ super(TestNet, self).__init__()
15
+ self.fc1 = nn.Linear(8, 1024)
16
+ self.fc2 = nn.Linear(1024, 8)
17
+
18
+ def forward(self, x):
19
+ x = self.fc1(x)
20
+ x = F.relu(x)
21
+ x = self.fc2(x)
22
+ return x
23
+
24
+
25
+ def test_lycoris_restore():
26
+ net = TestNet().cuda()
27
+ compiled_net = torch.compile(net)
28
+
29
+ test_x = torch.randn(1, 8).cuda()
30
+ out = compiled_net(test_x)
31
+ print("\nOriginal\n", out)
32
+
33
+ lycoris = create_lycoris(
34
+ net, algo="lokr", factor=2, bypass_mode=True, full_matrix=True
35
+ )
36
+ lycoris.apply_to()
37
+ lycoris.cuda()
38
+ for parameter in lycoris.parameters():
39
+ parameter.data = torch.randn_like(parameter) * 0.1
40
+ net = torch.compile(net)
41
+ out = net(test_x)
42
+ print("\nBypass Lokr Applied\n", out)
43
+
44
+ lycoris.restore()
45
+ # lycoris.set_multiplier(0.0)
46
+ out = net(test_x)
47
+ print("\nRestored\n", out)
48
+
49
+ lycoris.apply_to()
50
+ # lycoris.set_multiplier(1.0)
51
+ out = net(test_x)
52
+ print("\nBypass Lokr Applied\n", out)
53
+
54
+
55
+ if __name__ == "__main__":
56
+ test_lycoris_restore()