lycoris-lora 3.0.0.dev14__tar.gz → 3.0.0.dev16__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 (49) hide show
  1. lycoris_lora-3.0.0.dev16/PKG-INFO +25 -0
  2. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/README.md +64 -41
  3. lycoris_lora-3.0.0.dev16/lycoris/functional/__init__.py +9 -0
  4. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/functional/general.py +27 -0
  5. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/base.py +2 -1
  6. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/boft.py +1 -1
  7. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/diag_oft.py +1 -1
  8. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/glora.py +1 -1
  9. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/utils/__init__.py +21 -158
  10. lycoris_lora-3.0.0.dev16/lycoris_lora.egg-info/PKG-INFO +25 -0
  11. lycoris_lora-3.0.0.dev16/setup.py +29 -0
  12. lycoris_lora-3.0.0.dev14/PKG-INFO +0 -13
  13. lycoris_lora-3.0.0.dev14/lycoris/functional/__init__.py +0 -1
  14. lycoris_lora-3.0.0.dev14/lycoris_lora.egg-info/PKG-INFO +0 -13
  15. lycoris_lora-3.0.0.dev14/setup.py +0 -15
  16. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/LICENSE.md +0 -0
  17. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/__init__.py +0 -0
  18. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/config.py +0 -0
  19. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/functional/boft.py +0 -0
  20. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/functional/diag_oft.py +0 -0
  21. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/functional/locon.py +0 -0
  22. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/functional/loha.py +0 -0
  23. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/functional/lokr.py +0 -0
  24. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/kohya.py +0 -0
  25. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/logging.py +0 -0
  26. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/__init__.py +0 -0
  27. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/dylora.py +0 -0
  28. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/full.py +0 -0
  29. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/ia3.py +0 -0
  30. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/locon.py +0 -0
  31. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/loha.py +0 -0
  32. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/lokr.py +0 -0
  33. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/modules/norms.py +0 -0
  34. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/utils/bnb.py +0 -0
  35. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/utils/general.py +0 -0
  36. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/utils/logger.py +0 -0
  37. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/utils/preset.py +0 -0
  38. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/utils/xformers_utils.py +0 -0
  39. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris/wrapper.py +0 -0
  40. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris_lora.egg-info/SOURCES.txt +0 -0
  41. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris_lora.egg-info/dependency_links.txt +0 -0
  42. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris_lora.egg-info/not-zip-safe +0 -0
  43. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris_lora.egg-info/requires.txt +0 -0
  44. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/lycoris_lora.egg-info/top_level.txt +0 -0
  45. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/setup.cfg +0 -0
  46. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/test/__init__.py +0 -0
  47. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/test/functional.py +0 -0
  48. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/test/module.py +0 -0
  49. {lycoris_lora-3.0.0.dev14 → lycoris_lora-3.0.0.dev16}/test/wrapper.py +0 -0
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.1
2
+ Name: lycoris_lora
3
+ Version: 3.0.0.dev16
4
+ Summary: Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion
5
+ Home-page: https://github.com/KohakuBlueleaf/LyCORIS
6
+ Author: Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao
7
+ Author-email: apolloyeh0123@gmail.com
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: GPU :: NVIDIA CUDA :: 11.8
10
+ Classifier: Environment :: GPU :: NVIDIA CUDA :: 12
11
+ Classifier: Environment :: GPU :: NVIDIA CUDA :: 12 :: 12.1
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: End Users/Desktop
14
+ Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Operating System :: OS Independent
20
+ Requires-Python: >=3.10
21
+ License-File: LICENSE.md
22
+ Requires-Dist: torch
23
+ Requires-Dist: einops
24
+ Requires-Dist: toml
25
+ Requires-Dist: tqdm
@@ -1,6 +1,10 @@
1
+
2
+ ![pypi](https://img.shields.io/pypi/v/lycoris-lora.svg)
3
+ ![versions](https://img.shields.io/pypi/pyversions/lycoris-lora.svg)
4
+
1
5
  # LyCORIS - Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion. (ICLR'24)
2
6
 
3
- ![banner image](docs/images/banner.png)
7
+ ![banner image](docs/images/banner2.png)
4
8
 
5
9
  A project that implements different parameter-efficient fine-tuning algorithms for Stable Diffusion.
6
10
 
@@ -20,21 +24,21 @@ Please check [List of Implemented Algorithms](docs/Algo-List.md) and [Guidelines
20
24
 
21
25
  A simple comparison of some of these methods are provided below (to be taken with a grain of salt)
22
26
 
23
- | | Full | LoRA | LoHa | LoKr low factor | LoKr high factor $^+$ |
24
- | --------------------- | ---- | ---- | ---- | --------------- | ---------------- |
25
- | Fidelity | ★ | ● | ▲ | ◉ | ▲ |
26
- | Flexibility $^*$ | ★ | ● | ◉ | ▲ | ● $^†$ |
27
- | Diversity | ▲ | ◉ | ★ | ● | ★ |
28
- | Size | ▲ | ● | ● | ● | ★ |
29
- | Training Speed Linear | ★ | ● | ● | ★ | ★ |
30
- | Training Speed Conv | ● | ★ | ▲ | ● | ● |
27
+ | | Full | LoRA | LoHa | LoKr low factor | LoKr high factor$^+$ |
28
+ | --------------------- | ---- | ---- | ---- | --------------- | ---------------------- |
29
+ | Fidelity | ★ | ● | ▲ | ◉ | ▲ |
30
+ | Flexibility$^*$ | ★ | ● | ◉ | ▲ | ●$^†$ |
31
+ | Diversity | ▲ | ◉ | ★ | ● | ★ |
32
+ | Size | ▲ | ● | ● | ● | ★ |
33
+ | Training Speed Linear | ★ | ● | ● | ★ | ★ |
34
+ | Training Speed Conv | ● | ★ | ▲ | ● | ● |
31
35
 
32
36
  ★ > ◉ > ● > ▲
33
37
  [> means better and smaller size is better]
34
38
 
35
- $^+$ Usually we take `factor <= 0.5 * sqrt(dim)` as low factor and `factor >= sqrt(dim` as high factor. For example, factor<=8 for SD1.x/SD2.x/SDXL can be seen as low factor, and, factor>=16 can be seen as high factor. <br>
36
- $^*$ Flexibility means anything related to generating images not similar to those in the training set, and combination of multiple concepts, whether they are trained together or not <br>
37
- $^†$ It may become more difficult to switch base model or combine multiple concepts in this situation <br>
39
+ $^+$ Usually we take `factor <= 0.5 * sqrt(dim)` as low factor and `factor >= sqrt(dim` as high factor. For example, factor<=8 for SD1.x/SD2.x/SDXL can be seen as low factor, and, factor>=16 can be seen as high factor. `<br>`
40
+ $^*$ Flexibility means anything related to generating images not similar to those in the training set, and combination of multiple concepts, whether they are trained together or not `<br>`
41
+ $^†$ It may become more difficult to switch base model or combine multiple concepts in this situation `<br>`
38
42
 
39
43
  **The actual performance may vary depending on the datasets, tasks, and hyperparameters used. It is recommended to experiment with different settings to achieve optimal results.**
40
44
 
@@ -66,7 +70,7 @@ However, newer model types may not always be supported. If you encounter this is
66
70
  There are three different ways to train LyCORIS models.
67
71
 
68
72
  - With [kohya-ss/sd-scripts](https://github.com/kohya-ss/sd-scripts) (see a list of compatible graphical interfaces and colabs at the end of the section)
69
- - With [HCP-Diffusion](https://github.com/IrisRainbowNeko/HCP-Diffusion)
73
+ - With [Naifu-Diffusion](https://github.com/Mikubill/naifu)
70
74
  - With your own script by using LyCORIS as standalone wrappers for **ANY** pytorch modules.
71
75
 
72
76
  In any case, please install this package in the corresponding virtual environment. You can either install it
@@ -159,9 +163,11 @@ forward_with_lyco = your_model(x)
159
163
  You can check my [HakuPhi](https://github.com/KohakuBlueleaf/HakuPhi) project to see how I utilize LyCORIS to finetune the Phi-1.5 models.
160
164
 
161
165
  #### Other method
166
+
162
167
  After LyCORIS3.0.0, Parametrize API and Functional API have been added, which provide more different ways on utilizing LyCORIS library.
163
168
 
164
- Check [xxx] for more informations.
169
+ Check API reference for more informations.
170
+ You can also take the [test suites](test/) as a kind of examples.
165
171
 
166
172
  #### Bitsandbytes support
167
173
 
@@ -250,44 +256,61 @@ See [docs/Conversion-scripts.md](docs/Conversion-scripts.md) for more informatio
250
256
 
251
257
  For full log, please see [Change.md](Change.md)
252
258
 
253
- ## 2024/03/15 update to 2.2.0 - QLyCORIS and DoRA
259
+ ### 2024/06/xx update to 3.0.0 - Brand New Functional API, Parametrize API and Module API
260
+
261
+ #### The reasons of 3.0.0
262
+
263
+ We reconstruct the whole library with new Class definition and brand new Functional API system.
254
264
 
255
- #### New Algo
265
+ We also removed lot of redundant/unused modules.
256
266
 
257
- * DoRA
258
- * Ref: [DoRA: Weight-Decomposed Low-Rank Adaptation](https://github.com/KohakuBlueleaf/LyCORIS)
259
- * Weight decompose for LoHa and LoKr. (A.K.A DoHa/DoKr)
260
- * DoRA/DoHa/DoKr will require smaller Learning rate!
267
+ Since the whole library are changed significantly. We decide to call it 3.0.0 as a new major version.
261
268
 
262
- #### New Features
269
+ #### Major Changes
263
270
 
264
- * Support "bypass" (a.k.a. adapter) mode for LoHa/LoKr/OFT/BOFT
265
- * LoHa will require 2xFLOPs since we rebuild full diff weight and then do one more forward.
266
- * LoKr, OFT, BOFT should be more efficient than LoHa in bypass mode.
267
- * Support [bnb 8bit/4bit Linear layer](https://github.com/TimDettmers/bitsandbytes) (a.k.a. QLyCORIS) with LoHa/LoKr/OFT/BOFT.
268
- * This will force module to enable bypass mode.
271
+ * New Module API
272
+ * Add Parametrize API
273
+ * Add Functional API
274
+ * LoCon/LoHa/LoKr/Diag-OFT/BOFT only.
275
+ * Remove optional deps from install_requires
276
+ * Remove lot of redundant/deprecated modules
277
+ * Better testing
278
+ * HunYuan DiT Support ([PR](https://github.com/kohya-ss/sd-scripts/pull/1378) in kohya-ss/sd-scripts)
269
279
 
270
- #### Fixes, slight changes
280
+ #### Full change log
271
281
 
272
- * Refine some details about code quality. Based on the report from GitRoll. (Thx you gitroll!)
273
- * Remove redundant calculation in BOFT
274
- * rank_dropout has been removed from OFT/BOFT temporarily untill we ensure how to apply it.
275
- * Fix bugs in lokr when `lokr_w1_a` not exist.
276
- * Fix bugs in conversion scritps.
282
+ ##### New Features
283
+
284
+ * LyCORIS now have consistent API for different algorithm like `bypass_forward_diff` or `get_diff_weight` method. Developers of other project can utilize these API to do more tricks or integrate LyCORIS into their framework more easily.
285
+ * LyCORIS now have parametrize API which utilize `torch.nn.utils.parametrize.register_parametrization` to directly patch individual parameters. Which can be useful for MHA layer or other tricky modules.
286
+ * Currently only support 2~5D tensors. And LyCORIS will pretend these weights are weight of Linear/Conv1,2,3D then send it into LyCORIS modules
287
+ * More native implementation or more detailed control will be added in the future.
288
+ * LyCORIS now have functional API. Developers who prefer functional more than Module things can utilize this feature.
289
+ * Functional API also allow developers who don't want to introduce new dependencies. Just copy-paste the source code and utilizing it. (with Apache-2 License, directly copy-paste is totally allowed)
290
+ * Add support for Conv1d and Conv3d module on LoCon/LoHa/LoKr/Full/OFT/BOFT/GLoRA (not All algo in LyCORIS support them, you may receive error when apply unsopported algo), support inherited module (for example: `LoRACompatibleConv` or `LoRACompatibleLinear` from [`huggingface/diffusers`](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/lora.py))
291
+ * HunYuan DiT support.
292
+
293
+ ##### Improvements, Fixes, Slight Changes
294
+
295
+ * Drop dependencies related to kohya-ss/sd-scripts:
296
+ * We now take kohya-ss/sd-scripts as optional dependency
297
+ * Which means `transformers`, `diffusers` and anything related to kohya are all optional deps now.
298
+ * The definition of dropout and rank_dropout in each algorithm are changed. Since some concept of original rank_dropout in the lora of kohya-ss/sd-script is hard to applied to other algorithm. We can only design the dropout for each module seperatedly.
299
+ * `apply_max_norm` issue are all fixed.
300
+ * DyLoRA, (IA)^3, GLoRA are all rewritten and support Linear/Conv1,2,3d.
301
+ * (IA)^3, GLoRA, Diag-OFT, BOFT are supported in `create_lycoris_from_weights`
302
+ * `lycoris.kohya.create_network_from_weights` also support them as well.
303
+ * Fix wrong implementation of BOFT.
304
+ * `create_lycoris_from_weights` and `create_network_from_weights` now have correct logging infos.
305
+ * `get_module` and `make_module` are moved into modules' API.
277
306
 
278
307
  ## Todo list
279
308
 
280
- - [X] Module and Document for using LyCORIS in any other model, Not only SD.
281
- - [X] Proposition3 in [FedPara](https://arxiv.org/abs/2108.06098)
282
- * also need custom backward to save the vram
283
- - [ ] Low rank + sparse representation
284
- - [X] For extraction
285
- - [ ] For training
286
- - [ ] Support more operation, not only linear and conv2d.
287
- - [X] Configure varying ranks or dimensions for specific modules as needed.
288
309
  - [ ] Automatically selecting an algorithm based on the specific rank requirement.
289
- - [ ] Explore other low-rank representations or parameter-efficient methods to fine-tune either the entire model or specific parts of it.
290
310
  - [ ] More experiments for different task, not only diffusion models.
311
+ - [X] LoKr and LoHa have been proven to be useful for Large Language Model.
312
+ - [ ] Explore other low-rank representations or parameter-efficient methods to fine-tune either the entire model or specific parts of it.
313
+ - [ ] Documentation for whole library.
291
314
 
292
315
  ## Citation
293
316
 
@@ -0,0 +1,9 @@
1
+ from .general import (
2
+ rebuild_tucker,
3
+ factorization,
4
+ power2factorization,
5
+ FUNC_LIST,
6
+ tucker_weight,
7
+ tucker_weight_from_conv,
8
+ apply_dora_scale,
9
+ )
@@ -77,3 +77,30 @@ def power2factorization(dimension: int, factor: int = -1) -> tuple[int, int]:
77
77
  n = dimension // m
78
78
 
79
79
  return dimension // n, n
80
+
81
+
82
+ def tucker_weight_from_conv(up, down, mid):
83
+ up = up.reshape(up.size(0), up.size(1))
84
+ down = down.reshape(down.size(0), down.size(1))
85
+ return torch.einsum("m n ..., i m, n j -> i j ...", mid, up, down)
86
+
87
+
88
+ def tucker_weight(wa, wb, t):
89
+ temp = torch.einsum("i j ..., j r -> i r ...", t, wb)
90
+ return torch.einsum("i j ..., i r -> r j ...", temp, wa)
91
+
92
+
93
+ def apply_dora_scale(org_weight, rebuild, dora_scale, scale):
94
+ dora_norm_dims = org_weight.dim() - 1
95
+ weight = org_weight + rebuild
96
+ weight = weight.to(dora_scale.dtype)
97
+ weight_norm = (
98
+ weight.transpose(0, 1)
99
+ .reshape(weight.shape[1], -1)
100
+ .norm(dim=1, keepdim=True)
101
+ .reshape(weight.shape[1], *[1] * dora_norm_dims)
102
+ .transpose(0, 1)
103
+ )
104
+ merged_scale1 = weight / weight_norm * dora_scale
105
+ diff_weight = merged_scale1 - org_weight
106
+ return org_weight + diff_weight * scale
@@ -269,8 +269,9 @@ class LycorisBaseModule(ModuleCustomSD):
269
269
  weight, bias = self.get_merged_weight(
270
270
  multiplier, self.org_weight.shape, self.org_weight.device
271
271
  )
272
- self.org_weight = weight
272
+ self.org_weight = weight.to(self.org_weight)
273
273
  if bias is not None:
274
+ bias = bias.to(self.org_weight)
274
275
  if self.org_module[0].bias is not None:
275
276
  self.org_module[0].bias.data.copy_(bias)
276
277
  else:
@@ -197,7 +197,7 @@ class ButterflyOFTModule(LycorisBaseModule):
197
197
  r = self.get_r()
198
198
  inp = org = self.org_forward(x)
199
199
  if self.op in {F.conv2d, F.conv1d, F.conv3d}:
200
- org_out = org_out.transpose(1, -1)
200
+ inp = inp.transpose(1, -1)
201
201
 
202
202
  for i in range(m):
203
203
  bi = r[i] # b_num, b_size, b_size
@@ -188,7 +188,7 @@ class DiagOFTModule(LycorisBaseModule):
188
188
  if diff:
189
189
  out = out - org_out
190
190
  out = oft_out.view(*shape, -1)
191
- if self.rescale is not None:
191
+ if self.rescaled:
192
192
  out = self.rescale.transpose(-1, 0) * out
193
193
  out = out + (self.rescale.transpose(-1, 0) - 1) * org_out
194
194
  if self.op in {F.conv2d, F.conv1d, F.conv3d}:
@@ -5,7 +5,7 @@ import torch.nn as nn
5
5
  import torch.nn.functional as F
6
6
 
7
7
  from .base import LycorisBaseModule
8
- from ..utils import tucker_weight_from_conv
8
+ from ..functional import tucker_weight_from_conv
9
9
  from ..utils.bnb import LinearNF4
10
10
 
11
11
 
@@ -417,138 +417,10 @@ def convert_diffusers_name_to_compvis(key):
417
417
  return key
418
418
 
419
419
 
420
- def tucker_weight_from_conv(up, down, mid):
421
- up = up.reshape(up.size(0), up.size(1))
422
- down = down.reshape(down.size(0), down.size(1))
423
- return torch.einsum("m n ..., i m, n j -> i j ...", mid, up, down)
424
-
425
-
426
- def tucker_weight(wa, wb, t):
427
- temp = torch.einsum("i j ..., j r -> i r ...", t, wb)
428
- return torch.einsum("i j ..., i r -> r j ...", temp, wa)
429
-
430
-
431
- def apply_dora_scale(org_weight, rebuild, dora_scale, scale):
432
- dora_norm_dims = org_weight.dim() - 1
433
- weight = org_weight + rebuild
434
- weight = weight.to(dora_scale.dtype)
435
- weight_norm = (
436
- weight.transpose(0, 1)
437
- .reshape(weight.shape[1], -1)
438
- .norm(dim=1, keepdim=True)
439
- .reshape(weight.shape[1], *[1] * dora_norm_dims)
440
- .transpose(0, 1)
441
- )
442
- merged_scale1 = weight / weight_norm * dora_scale
443
- diff_weight = merged_scale1 - org_weight
444
- return org_weight + diff_weight * scale
445
-
446
-
447
- @torch.no_grad()
448
- def rebuild_weight(module_type, params, orig_weight, orig_bias, scale=1):
449
- if orig_weight is None:
450
- return None, None
451
- merged = orig_weight
452
- merged_bias = orig_bias
453
- if module_type == "locon":
454
- up, down, mid, alpha, dora_scale = params
455
- if alpha is not None:
456
- scale *= alpha / up.size(1)
457
- if mid is not None:
458
- rebuild = tucker_weight_from_conv(up, down, mid)
459
- else:
460
- rebuild = up.reshape(up.size(0), -1) @ down.reshape(down.size(0), -1)
461
- rebuild = rebuild.reshape(orig_weight.shape)
462
- if dora_scale is None:
463
- merged = orig_weight + rebuild * scale
464
- else:
465
- merged = apply_dora_scale(orig_weight, rebuild, dora_scale, scale)
466
- del up, down, mid, alpha, params, rebuild
467
- elif module_type == "hada":
468
- w1a, w1b, w2a, w2b, t1, t2, alpha, dora_scale = params
469
- if alpha is not None:
470
- scale *= alpha / w1b.size(0)
471
- if t1 is not None:
472
- rebuild1 = tucker_weight(w1a, w1b, t1)
473
- else:
474
- rebuild1 = w1a @ w1b
475
- if t2 is not None:
476
- rebuild2 = tucker_weight(w2a, w2b, t2)
477
- else:
478
- rebuild2 = w2a @ w2b
479
- rebuild = (rebuild1 * rebuild2).reshape(orig_weight.shape)
480
- if dora_scale is None:
481
- merged = orig_weight + rebuild * scale
482
- else:
483
- merged = apply_dora_scale(orig_weight, rebuild, dora_scale, scale)
484
- del w1a, w1b, w2a, w2b, t1, t2, alpha, params, rebuild, rebuild1, rebuild2
485
- elif module_type == "ia3":
486
- weight, on_input = params
487
- if not on_input:
488
- weight = weight.reshape(-1, 1)
489
- merged = orig_weight + weight * orig_weight * scale
490
- del weight, on_input, params
491
- elif module_type == "kron":
492
- w1, w1a, w1b, w2, w2a, w2b, t1, t2, alpha, dora_scale = params
493
- if alpha is not None and (w1b is not None or w2b is not None):
494
- scale *= alpha / (w1b.size(0) if w1b else w2b.size(0))
495
- if w1a is not None and w1b is not None:
496
- if t1 is not None:
497
- w1 = tucker_weight(w1a, w1b, t1)
498
- else:
499
- w1 = w1a @ w1b
500
- if w2a is not None and w2b is not None:
501
- if t2 is not None:
502
- w2 = tucker_weight(w2a, w2b, t2)
503
- else:
504
- w2 = w2a @ w2b
505
- if len(w2.shape) == 4:
506
- w1 = w1.unsqueeze(2).unsqueeze(2)
507
- w2 = w2.contiguous()
508
- rebuild = torch.kron(w1, w2).reshape(orig_weight.shape)
509
- if dora_scale is None:
510
- merged = orig_weight + rebuild * scale
511
- else:
512
- merged = apply_dora_scale(orig_weight, rebuild, dora_scale, scale)
513
- del w1, w1a, w1b, w2, w2a, w2b, t1, t2, alpha, params, rebuild
514
- elif module_type == "full":
515
- rebuild = params[0].reshape(orig_weight.shape)
516
- rebuild_b = (
517
- params[1].reshape(orig_bias.shape) if orig_bias is not None else None
518
- )
519
- merged = orig_weight + rebuild * scale
520
- if rebuild_b is not None:
521
- merged_bias = orig_bias + rebuild_b * scale
522
- del params, rebuild, rebuild_b
523
- elif module_type == "norm":
524
- rebuild = params[0].reshape(orig_weight.shape)
525
- rebuild_b = params[1].reshape(orig_bias.shape)
526
- merged = orig_weight + rebuild * scale
527
- merged_bias = orig_bias + rebuild_b * scale
528
- else:
529
- return None, None
530
-
531
- return merged, merged_bias
532
-
533
-
534
420
  @torch.no_grad()
535
421
  def merge(tes, unet, lyco_state_dict, scale: float = 1.0, device="cpu"):
536
- UNET_TARGET_REPLACE_MODULE = [
537
- "Linear",
538
- "Conv2d",
539
- "LayerNorm",
540
- "GroupNorm",
541
- "GroupNorm32",
542
- ]
543
- TEXT_ENCODER_TARGET_REPLACE_MODULE = [
544
- "Embedding",
545
- "Linear",
546
- "Conv2d",
547
- "LayerNorm",
548
- "GroupNorm",
549
- "GroupNorm32",
550
- "Embedding",
551
- ]
422
+ from ..modules import make_module, get_module
423
+
552
424
  LORA_PREFIX_UNET = "lora_unet"
553
425
  LORA_PREFIX_TEXT_ENCODER = "lora_te"
554
426
  merged = 0
@@ -557,29 +429,25 @@ def merge(tes, unet, lyco_state_dict, scale: float = 1.0, device="cpu"):
557
429
  prefix,
558
430
  root_module: torch.nn.Module,
559
431
  lyco_state_dict: Dict[str, torch.Tensor],
560
- target_replace_modules,
561
432
  ):
562
433
  nonlocal merged
563
434
  for child_name, child_module in tqdm(
564
435
  list(root_module.named_modules()), desc=f"Merging {prefix}"
565
436
  ):
566
- if child_module.__class__.__name__ in target_replace_modules:
567
- lora_name = prefix + "." + child_name
568
- lora_name = lora_name.replace(".", "_")
569
-
570
- result, result_b = rebuild_weight(
571
- *get_module(lyco_state_dict, lora_name),
572
- getattr(child_module, "weight"),
573
- getattr(child_module, "bias", None),
574
- scale,
575
- )
576
- if result is not None:
577
- key_dict.pop(lora_name)
578
- merged += 1
579
- child_module.requires_grad_(False)
580
- child_module.weight.copy_(result)
581
- if result_b is not None:
582
- child_module.bias.copy_(result_b)
437
+ lora_name = prefix + "." + child_name
438
+ lora_name = lora_name.replace(".", "_")
439
+
440
+ lyco_type, params = get_module(lyco_state_dict, lora_name)
441
+ if lyco_type is None:
442
+ continue
443
+ module = make_module(lyco_type, params, lora_name, child_module)
444
+ if module is None:
445
+ continue
446
+ module.to(device)
447
+ module.merge_to(scale)
448
+ key_dict.pop(convert_diffusers_name_to_compvis(lora_name), None)
449
+ key_dict.pop(lora_name, None)
450
+ merged += 1
583
451
 
584
452
  key_dict = {}
585
453
  for k, v in tqdm(list(lyco_state_dict.items()), desc="Converting Dtype and Device"):
@@ -592,12 +460,7 @@ def merge(tes, unet, lyco_state_dict, scale: float = 1.0, device="cpu"):
592
460
  k = f"{convert_key}.{weight_key}"
593
461
  else:
594
462
  key_dict[module] = key_dict.get(module, []) + [k]
595
- if device == "cpu":
596
- lyco_state_dict[k] = v.float().cpu()
597
- else:
598
- lyco_state_dict[k] = v.to(
599
- device, dtype=tes[0].parameters().__next__().dtype
600
- )
463
+ lyco_state_dict[k] = v.float().cpu()
601
464
 
602
465
  for idx, te in enumerate(tes):
603
466
  if len(tes) > 1:
@@ -606,15 +469,15 @@ def merge(tes, unet, lyco_state_dict, scale: float = 1.0, device="cpu"):
606
469
  prefix = LORA_PREFIX_TEXT_ENCODER
607
470
  merge_state_dict(
608
471
  prefix,
609
- te.to(device),
472
+ te,
610
473
  lyco_state_dict,
611
- TEXT_ENCODER_TARGET_REPLACE_MODULE,
612
474
  )
475
+ torch.cuda.empty_cache()
613
476
  merge_state_dict(
614
477
  LORA_PREFIX_UNET,
615
- unet.to(device),
478
+ unet,
616
479
  lyco_state_dict,
617
- UNET_TARGET_REPLACE_MODULE,
618
480
  )
481
+ torch.cuda.empty_cache()
619
482
  print(f"Unused state dict key: {key_dict}")
620
483
  print(f"{merged} Modules been merged")
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.1
2
+ Name: lycoris_lora
3
+ Version: 3.0.0.dev16
4
+ Summary: Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion
5
+ Home-page: https://github.com/KohakuBlueleaf/LyCORIS
6
+ Author: Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao
7
+ Author-email: apolloyeh0123@gmail.com
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: GPU :: NVIDIA CUDA :: 11.8
10
+ Classifier: Environment :: GPU :: NVIDIA CUDA :: 12
11
+ Classifier: Environment :: GPU :: NVIDIA CUDA :: 12 :: 12.1
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: End Users/Desktop
14
+ Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Operating System :: OS Independent
20
+ Requires-Python: >=3.10
21
+ License-File: LICENSE.md
22
+ Requires-Dist: torch
23
+ Requires-Dist: einops
24
+ Requires-Dist: toml
25
+ Requires-Dist: tqdm
@@ -0,0 +1,29 @@
1
+ from setuptools import setup, find_packages
2
+
3
+
4
+ setup(
5
+ name="lycoris_lora",
6
+ packages=find_packages(),
7
+ version="3.0.0.dev16",
8
+ url="https://github.com/KohakuBlueleaf/LyCORIS",
9
+ description="Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion",
10
+ author="Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao",
11
+ author_email="apolloyeh0123@gmail.com",
12
+ zip_safe=False,
13
+ install_requires=["torch", "einops", "toml", "tqdm"],
14
+ python_requires=">=3.10",
15
+ classifiers=[
16
+ 'Development Status :: 4 - Beta',
17
+ 'Environment :: GPU :: NVIDIA CUDA :: 11.8',
18
+ 'Environment :: GPU :: NVIDIA CUDA :: 12',
19
+ 'Environment :: GPU :: NVIDIA CUDA :: 12 :: 12.1',
20
+ 'Intended Audience :: Developers',
21
+ 'Intended Audience :: End Users/Desktop',
22
+ 'License :: OSI Approved :: Apache Software License',
23
+ 'Programming Language :: Python',
24
+ 'Programming Language :: Python :: 3.10',
25
+ 'Programming Language :: Python :: 3.11',
26
+ 'Programming Language :: Python :: 3.12',
27
+ 'Operating System :: OS Independent',
28
+ ],
29
+ )
@@ -1,13 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: lycoris_lora
3
- Version: 3.0.0.dev14
4
- Summary: Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion
5
- Home-page: https://github.com/KohakuBlueleaf/LyCORIS
6
- Author: Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao
7
- Author-email: apolloyeh0123@gmail.com
8
- Requires-Python: >=3.10
9
- License-File: LICENSE.md
10
- Requires-Dist: torch
11
- Requires-Dist: einops
12
- Requires-Dist: toml
13
- Requires-Dist: tqdm
@@ -1 +0,0 @@
1
- from .general import rebuild_tucker, factorization, power2factorization, FUNC_LIST
@@ -1,13 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: lycoris_lora
3
- Version: 3.0.0.dev14
4
- Summary: Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion
5
- Home-page: https://github.com/KohakuBlueleaf/LyCORIS
6
- Author: Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao
7
- Author-email: apolloyeh0123@gmail.com
8
- Requires-Python: >=3.10
9
- License-File: LICENSE.md
10
- Requires-Dist: torch
11
- Requires-Dist: einops
12
- Requires-Dist: toml
13
- Requires-Dist: tqdm
@@ -1,15 +0,0 @@
1
- from setuptools import setup, find_packages
2
-
3
-
4
- setup(
5
- name="lycoris_lora",
6
- packages=find_packages(),
7
- version="3.0.0.dev14",
8
- url="https://github.com/KohakuBlueleaf/LyCORIS",
9
- description="Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion",
10
- author="Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao",
11
- author_email="apolloyeh0123@gmail.com",
12
- zip_safe=False,
13
- install_requires=["torch", "einops", "toml", "tqdm"],
14
- python_requires=">=3.10",
15
- )