lycoris-lora 2.0.0.dev7__tar.gz → 2.1.0__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 (58) hide show
  1. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/PKG-INFO +1 -1
  2. lycoris_lora-2.1.0/README.md +289 -0
  3. lycoris_lora-2.1.0/lycoris/__init__.py +23 -0
  4. lycoris_lora-2.1.0/lycoris/config.py +86 -0
  5. lycoris_lora-2.1.0/lycoris/hcp/__init__.py +4 -0
  6. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/hcp/base.py +57 -32
  7. lycoris_lora-2.1.0/lycoris/hcp/diag_oft.py +62 -0
  8. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/hcp/loha.py +40 -22
  9. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/hcp/lokr.py +60 -35
  10. lycoris_lora-2.1.0/lycoris/kohya/__init__.py +1327 -0
  11. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/kohya/model_utils.py +409 -110
  12. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/kohya/original_unet.py +220 -67
  13. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/kohya/sdxl_model_util.py +64 -20
  14. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/kohya/sdxl_original_unet.py +150 -48
  15. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/kohya/utils.py +1 -1
  16. lycoris_lora-2.1.0/lycoris/logging.py +36 -0
  17. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/__init__.py +40 -29
  18. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/attention.py +85 -72
  19. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/base.py +27 -6
  20. lycoris_lora-2.1.0/lycoris/modules/boft.py +210 -0
  21. lycoris_lora-2.1.0/lycoris/modules/diag_oft.py +168 -0
  22. lycoris_lora-2.1.0/lycoris/modules/dylora.py +132 -0
  23. lycoris_lora-2.1.0/lycoris/modules/full.py +134 -0
  24. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/glokr.py +112 -84
  25. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/glora.py +39 -20
  26. lycoris_lora-2.1.0/lycoris/modules/hypernet/__init__.py +1 -0
  27. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/hypernet/generater.py +71 -50
  28. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/hypernet/text_encoder.py +79 -52
  29. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/ia3.py +13 -13
  30. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/locon.py +92 -54
  31. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/loha.py +120 -88
  32. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/lokr.py +136 -97
  33. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/modules/norms.py +29 -12
  34. lycoris_lora-2.1.0/lycoris/utils/__init__.py +611 -0
  35. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/utils/logger.py +2 -4
  36. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/utils/preset.py +2 -2
  37. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris/utils/xformers_utils.py +1 -0
  38. lycoris_lora-2.1.0/lycoris/wrapper.py +514 -0
  39. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris_lora.egg-info/PKG-INFO +1 -1
  40. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris_lora.egg-info/SOURCES.txt +4 -0
  41. lycoris_lora-2.1.0/setup.py +14 -0
  42. lycoris_lora-2.0.0.dev7/README.md +0 -194
  43. lycoris_lora-2.0.0.dev7/lycoris/__init__.py +0 -5
  44. lycoris_lora-2.0.0.dev7/lycoris/config.py +0 -98
  45. lycoris_lora-2.0.0.dev7/lycoris/hcp/__init__.py +0 -6
  46. lycoris_lora-2.0.0.dev7/lycoris/kohya/__init__.py +0 -1135
  47. lycoris_lora-2.0.0.dev7/lycoris/modules/diag_oft.py +0 -127
  48. lycoris_lora-2.0.0.dev7/lycoris/modules/dylora.py +0 -120
  49. lycoris_lora-2.0.0.dev7/lycoris/modules/full.py +0 -36
  50. lycoris_lora-2.0.0.dev7/lycoris/modules/hypernet/__init__.py +0 -5
  51. lycoris_lora-2.0.0.dev7/lycoris/utils/__init__.py +0 -535
  52. lycoris_lora-2.0.0.dev7/setup.py +0 -18
  53. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/LICENSE.md +0 -0
  54. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris_lora.egg-info/dependency_links.txt +0 -0
  55. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris_lora.egg-info/not-zip-safe +0 -0
  56. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris_lora.egg-info/requires.txt +0 -0
  57. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/lycoris_lora.egg-info/top_level.txt +0 -0
  58. {lycoris_lora-2.0.0.dev7 → lycoris_lora-2.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lycoris_lora
3
- Version: 2.0.0.dev7
3
+ Version: 2.1.0
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
@@ -0,0 +1,289 @@
1
+ # LyCORIS - Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion.
2
+
3
+ ![banner image](docs/images/banner.png)
4
+
5
+ A project that implements different parameter-efficient fine-tuning algorithms for Stable Diffusion.
6
+
7
+ This project originated from LoCon (see archive branch).
8
+
9
+ **If you are interested in discussing more details, you can join [our Discord server](https://discord.gg/VtTFKrj9gJ)**
10
+
11
+ [![Discord!](https://i.imgur.com/A8tOvFS.jpg)](https://discord.gg/VtTFKrj9gJ)
12
+
13
+ **If you want to check more in-depth experiment results and discussions for LyCORIS, you can check our [paper](https://arxiv.org/abs/2309.14859)**
14
+
15
+ ## Algorithm Overview
16
+
17
+ LyCORIS currently contains LoRA (LoCon), LoHa, LoKr, (IA)^3, DyLoRA, Native fine-tuning (aka dreambooth).
18
+ GLoRA and GLoKr are coming soon.
19
+ Please check [List of Implemented Algorithms](docs/Algo-List.md) and [Guidelines](docs/Guidelines.md) for more details.
20
+
21
+ A simple comparison of some of these methods are provided below (to be taken with a grain of salt)
22
+
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 | ● | ★ | ▲ | ● | ● |
31
+
32
+ ★ > ◉ > ● > ▲
33
+ [> means better and smaller size is better]
34
+
35
+ $^*$ 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
36
+ $^†$ It may become more difficult to switch base model or combine multiple concepts in this situation
37
+
38
+ ## Usage
39
+
40
+ ### Image Generation
41
+
42
+ #### [a1111/sd-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui)
43
+
44
+ After sd-webui 1.5.0, LyCORIS models are officially supported by the built-in LoRA system. You can put them in either `models/Lora` or `models/LyCORIS` and use the default syntax `<lora:filename:multiplier>` to trigger it.
45
+
46
+ When we add new model types, we will always make sure they can be used with the newest version of sd-webui.
47
+
48
+ As for sd-webui with version < 1.5.0, please check this [extension](https://github.com/KohakuBlueleaf/a1111-sd-webui-lycoris).
49
+
50
+ #### Others
51
+
52
+ As far as we are aware, LyCORIS models are also supported in the following interfaces / online generation services (please help us complete the list!)
53
+
54
+ - [ComfyUI](https://github.com/comfyanonymous/ComfyUI)
55
+ - [InvokeAI](https://github.com/invoke-ai/InvokeAI)
56
+ - [CivitAI](https://civitai.com/)
57
+ - [Tensor.Art](https://tensor.art/)
58
+
59
+ However, newer model types may not always be supported. If you encounter this issue, consider requesting the developers of the corresponding interface or website to include support for the new type.
60
+
61
+ ### Training
62
+
63
+ There are three different ways to train LyCORIS models.
64
+
65
+ - 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)
66
+ - With [HCP-Diffusion](https://github.com/IrisRainbowNeko/HCP-Diffusion)
67
+ - With your own script by using LyCORIS as standalone wrappers for any pytorch modules.
68
+
69
+ In any case, please install this package in the corresponding virtual environment. You can either install it
70
+
71
+ - through pip
72
+
73
+ ```bash
74
+ pip install lycoris_lora
75
+ ```
76
+ - or from source
77
+
78
+ ```bash
79
+ git clone https://github.com/KohakuBlueleaf/LyCORIS
80
+ cd LyCORIS
81
+ pip install .
82
+ ```
83
+
84
+ A detilaed description of the network arguments is provided in [docs/Network-Args.md](docs/Network-Args.md).
85
+
86
+ #### kohya script
87
+
88
+ You can use this package's kohya module to run kohya's training script to train lycoris module for SD models
89
+
90
+ - with command line arguments
91
+
92
+ ```bash
93
+ accelerate launch train_network.py \
94
+ --network_module lycoris.kohya \
95
+ --network_dim "DIM_FOR_LINEAR" --network_alpha "ALPHA_FOR_LINEAR"\
96
+ --network_args "conv_dim=DIM_FOR_CONV" "conv_alpha=ALPHA_FOR_CONV" \
97
+ "dropout=DROPOUT_RATE" "algo=locon" \
98
+ ```
99
+ - with `toml` files
100
+
101
+ ```bash
102
+ accelerate launch train_network.py \
103
+ --config_file example_configs/training_configs/kohya/loha_config.toml \
104
+ --dataset_config example_configs/training_configs/kohya/dataset_config.toml
105
+ ```
106
+
107
+ For your convenience, some example `toml` files for kohya LyCORIS training are provided in [example/training_configs/kohya](example_configs/training_configs/kohya).
108
+
109
+ #### HCP-Diffusion
110
+
111
+ You can use this package's hcp module to run HCP-Diffusion's training script to train lycoris module for SD models
112
+
113
+ ```bash
114
+ accelerate launch -m hcpdiff.train_ac_single \
115
+ --cfg example_configs/training_configs/hcp/hcp_diag_oft.yaml
116
+ ```
117
+
118
+ For your convenience, some example `yaml` files for HCP LyCORIS training are provided in [example/training_configs/hcp](example_configs/training_configs/hcp).
119
+
120
+ For the moment being the outputs of HCP-Diffusion are not directly compatible with a1111/sdwebui.
121
+ You can perform conversion with [tools/batch_hcp_convert.py](tools/batch_hcp_convert.py).
122
+
123
+ In the case of pivotal tuning, [tools/batch_bundle_convert.py](tools/batch_bundle_convert.py) can be further used to convert to and from bundle formats.
124
+ Check [docs/Conversion-scripts.md](docs/Conversion-scripts.md) for more information.
125
+
126
+ #### As standalone wrappers
127
+
128
+ See [standalone_example.py](standalone_example.py) for full example.
129
+
130
+ Import `create_lycoris` and `LycorisNetwork` from `lycoris` library, put your preset to `LycorisNetwork` and then use `create_lycoris` to create LyCORIS module for your pytorch module.
131
+
132
+ For example:
133
+
134
+ ```py
135
+ from lycoris import create_lycoris, LycorisNetwork
136
+
137
+ LycorisNetwork.apply_preset(
138
+ {"target_name": [".*attn.*"]}
139
+ )
140
+ lycoris_net = create_lycoris(
141
+ your_model,
142
+ 1.0,
143
+ linear_dim=16,
144
+ linear_alpha=2.0,
145
+ algo="lokr"
146
+ )
147
+ lycoris_net.apply_to()
148
+
149
+ # after apply_to(), your_model() will run with LyCORIS net
150
+ lycoris_param = lycoris_net.parameters()
151
+ forward_with_lyco = your_model(x)
152
+ ```
153
+
154
+ You can check my [HakuPhi](https://github.com/KohakuBlueleaf/HakuPhi) project to see how I utilize LyCORIS to finetune the Phi-1.5 models.
155
+
156
+ #### Graphical interfaces and Colabs (via kohya trainer)
157
+
158
+ You can also train LyCORIS with the following graphical interfaces
159
+
160
+ * [bmaltais/kohya_ss](https://github.com/bmaltais/kohya_ss)
161
+ * [derrian-distro/LoRA_Easy_Training_Scripts](https://github.com/derrian-distro/LoRA_Easy_Training_Scripts)
162
+ * [Akegarasu/lora-scripts](https://github.com/Akegarasu/lora-scripts)
163
+
164
+ and colabs (please help us complete the list!)
165
+
166
+ * [hollowstrawberry/kohya-colab](https://github.com/hollowstrawberry/kohya-colab)
167
+ * [Linaqruf/kohya-trainer](https://github.com/Linaqruf/kohya-trainer)
168
+
169
+ However, they are not guaranteed to be up-to-date. In particular, newer types may not be supported. Consider requesting the developers for support or simply use the original kohya script in this case.
170
+
171
+ ## Utilities
172
+
173
+ ### Extract LoCon
174
+
175
+ You can extract LoCon from a dreambooth model with its base model.
176
+
177
+ ```bash
178
+ python3 extract_locon.py <settings> <base_model> <db_model> <output>
179
+ ```
180
+
181
+ Use --help to get more info
182
+
183
+ ```
184
+ $ python3 extract_locon.py --help
185
+ usage: extract_locon.py [-h] [--is_v2] [--is_sdxl] [--device DEVICE] [--mode MODE] [--safetensors] [--linear_dim LINEAR_DIM]
186
+ [--conv_dim CONV_DIM] [--linear_threshold LINEAR_THRESHOLD] [--conv_threshold CONV_THRESHOLD]
187
+ [--linear_ratio LINEAR_RATIO] [--conv_ratio CONV_RATIO] [--linear_quantile LINEAR_QUANTILE]
188
+ [--conv_quantile CONV_QUANTILE] [--use_sparse_bias] [--sparsity SPARSITY] [--disable_cp]
189
+ base_model db_model output_name
190
+ ```
191
+
192
+ ### Merge LyCORIS back to model
193
+
194
+ You can merge your LyCORIS model back to your checkpoint (base model).
195
+
196
+ ```bash
197
+ python3 merge.py <settings> <base_model> <lycoris_model> <output>
198
+ ```
199
+
200
+ Use --help to get more info
201
+
202
+ ```
203
+ $ python3 merge.py --help
204
+ usage: merge.py [-h] [--is_v2] [--is_sdxl] [--device DEVICE] [--dtype DTYPE] [--weight WEIGHT] base_model lycoris_model output_name
205
+ ```
206
+
207
+ ### Conversion of LoRA, LyCORIS and full models between HCP and sd-webui format
208
+
209
+ This script allows you to use the LyCORIS models trained with HCP-Diffusion in sd-webui.
210
+
211
+ ```bash
212
+ python3 batch_hcp_convert.py \
213
+ --network_path /path/to/ckpts \
214
+ --dst_dir /path/to/stable-diffusion-webui/models/Lora \
215
+ --output_prefix something \
216
+ --auto_scale_alpha --to_webui
217
+ ```
218
+
219
+ See [docs/Conversion-scripts.md](docs/Conversion-scripts.md) for more information.
220
+
221
+ ### Conversion from and to bundle format
222
+
223
+ This script is particularly useful in the case of pivotal tuning.
224
+
225
+ ```bash
226
+ python3 batch_bundle_convert.py \
227
+ --network_path /path/to/sd-webui-ssd/models/Lora \
228
+ --emb_path /path/to/ckpts \
229
+ --dst_dir /path/to/sd-webui-ssd/models/Lora/bundle \
230
+ --to_bundle --verbose 2
231
+ ```
232
+
233
+ See [docs/Conversion-scripts.md](docs/Conversion-scripts.md) for more information.
234
+
235
+ ## Change Log
236
+
237
+ For full log, please see [Change.md](Change.md)
238
+
239
+ ## 2024/02/18 update to 2.1.0
240
+
241
+ #### New Algo
242
+
243
+ * [BOFT (Butterfly OFT)](https://arxiv.org/abs/2311.06243)
244
+
245
+ #### Improvements
246
+
247
+ * Faster, better extract script
248
+ * support kohya-ss/sd-scripts image gen
249
+ * support regex name in kohya-ss/sd-scripts
250
+ * support resume on:
251
+ * full
252
+ * loha
253
+ * oft
254
+ * boft
255
+ * Add logger into LyCORIS
256
+
257
+ #### Fixes, slight changes
258
+
259
+ * Update HCP convert for the case where only UNet or TE is trained.
260
+ * Change arg names for conversion scripts.
261
+ * Fix wrong TE prefix in merge scripts.
262
+ * Fix warnings and confusing logging.
263
+
264
+ ## Todo list
265
+
266
+ - [X] Module and Document for using LyCORIS in any other model, Not only SD.
267
+ - [X] Proposition3 in [FedPara](https://arxiv.org/abs/2108.06098)
268
+ * also need custom backward to save the vram
269
+ - [ ] Low rank + sparse representation
270
+ - [X] For extraction
271
+ - [ ] For training
272
+ - [ ] Support more operation, not only linear and conv2d.
273
+ - [X] Configure varying ranks or dimensions for specific modules as needed.
274
+ - [ ] Automatically selecting an algorithm based on the specific rank requirement.
275
+ - [ ] Explore other low-rank representations or parameter-efficient methods to fine-tune either the entire model or specific parts of it.
276
+ - [ ] More experiments for different task, not only diffusion models.
277
+
278
+ ## Citation
279
+
280
+ ```bibtex
281
+ @inproceedings{
282
+ yeh2024navigating,
283
+ title={Navigating Text-To-Image Customization: From Ly{CORIS} Fine-Tuning to Model Evaluation},
284
+ author={SHIH-YING YEH and Yu-Guan Hsieh and Zhidong Gao and Bernard B W Yang and Giyeong Oh and Yanmin Gong},
285
+ booktitle={The Twelfth International Conference on Learning Representations},
286
+ year={2024},
287
+ url={https://openreview.net/forum?id=wfzXa8e783}
288
+ }
289
+ ```
@@ -0,0 +1,23 @@
1
+ from . import (
2
+ kohya,
3
+ modules,
4
+ utils,
5
+ )
6
+
7
+ from .modules.locon import LoConModule
8
+ from .modules.loha import LohaModule
9
+ from .modules.lokr import LokrModule
10
+ from .modules.dylora import DyLoraModule
11
+ from .modules.glora import GLoRAModule
12
+ from .modules.norms import NormModule
13
+ from .modules.full import FullModule
14
+ from .modules.diag_oft import DiagOFTModule
15
+ from .modules import make_module
16
+
17
+ from .wrapper import (
18
+ LycorisNetwork,
19
+ create_lycoris,
20
+ create_lycoris_from_weights,
21
+ )
22
+
23
+ from .logging import logger
@@ -0,0 +1,86 @@
1
+ PRESET = {
2
+ "full": {
3
+ "enable_conv": True,
4
+ "unet_target_module": [
5
+ "Transformer2DModel",
6
+ "ResnetBlock2D",
7
+ "Downsample2D",
8
+ "Upsample2D",
9
+ ],
10
+ "unet_target_name": [
11
+ "conv_in",
12
+ "conv_out",
13
+ "time_embedding.linear_1",
14
+ "time_embedding.linear_2",
15
+ ],
16
+ "text_encoder_target_module": ["CLIPAttention", "CLIPMLP"],
17
+ "text_encoder_target_name": [],
18
+ },
19
+ "full-lin": {
20
+ "enable_conv": False,
21
+ "unet_target_module": [
22
+ "Transformer2DModel",
23
+ "ResnetBlock2D",
24
+ ],
25
+ "unet_target_name": [
26
+ "time_embedding.linear_1",
27
+ "time_embedding.linear_2",
28
+ ],
29
+ "text_encoder_target_module": ["CLIPAttention", "CLIPMLP"],
30
+ "text_encoder_target_name": [],
31
+ },
32
+ "attn-mlp": {
33
+ "enable_conv": False,
34
+ "unet_target_module": [
35
+ "Transformer2DModel",
36
+ ],
37
+ "unet_target_name": [],
38
+ "text_encoder_target_module": ["CLIPAttention", "CLIPMLP"],
39
+ "text_encoder_target_name": [],
40
+ },
41
+ "attn-only": {
42
+ "enable_conv": False,
43
+ "unet_target_module": [
44
+ "CrossAttention",
45
+ ],
46
+ "unet_target_name": [],
47
+ "text_encoder_target_module": ["CLIPAttention"],
48
+ "text_encoder_target_name": [],
49
+ },
50
+ "unet-only": {
51
+ "enable_conv": True,
52
+ "unet_target_module": [
53
+ "Transformer2DModel",
54
+ "ResnetBlock2D",
55
+ "Downsample2D",
56
+ "Upsample2D",
57
+ ],
58
+ "unet_target_name": [
59
+ "conv_in",
60
+ "conv_out",
61
+ "time_embedding.linear_1",
62
+ "time_embedding.linear_2",
63
+ ],
64
+ "text_encoder_target_module": [],
65
+ "text_encoder_target_name": [],
66
+ },
67
+ "unet-transformer-only": {
68
+ "enable_conv": False,
69
+ "unet_target_module": [
70
+ "Transformer2DModel",
71
+ ],
72
+ "unet_target_name": [],
73
+ "text_encoder_target_module": [],
74
+ "text_encoder_target_name": [],
75
+ },
76
+ "unet-convblock-only": {
77
+ "enable_conv": True,
78
+ "unet_target_module": ["ResnetBlock2D", "Downsample2D", "Upsample2D"],
79
+ "unet_target_name": [
80
+ "conv_in",
81
+ "conv_out",
82
+ ],
83
+ "text_encoder_target_module": [],
84
+ "text_encoder_target_name": [],
85
+ },
86
+ }
@@ -0,0 +1,4 @@
1
+ from .base import LycorisPluginContainer, LycorisPluginBlock
2
+ from .loha import LohaBlock
3
+ from .lokr import LokrBlock
4
+ from .diag_oft import DiagOFTBlock
@@ -11,8 +11,8 @@ try:
11
11
  from hcpdiff.utils.utils import isinstance_list
12
12
  except ImportError:
13
13
  print(
14
- 'HCP-Diffusion is not installed, hcp feature will be disabled. '
15
- 'Use `pip install hcpdiff` to install hcpdiff.'
14
+ "HCP-Diffusion is not installed, hcp feature will be disabled. "
15
+ "Use `pip install hcpdiff` to install hcpdiff."
16
16
  )
17
17
 
18
18
  from ..utils.logger import logger
@@ -21,70 +21,88 @@ from ..utils.logger import logger
21
21
  class LycorisPluginContainer(PatchPluginContainer):
22
22
  def __init__(self, host_name: str, host: nn.Module, parent_block: nn.Module):
23
23
  super(LycorisPluginContainer, self).__init__(host_name, host, parent_block)
24
-
24
+
25
25
  self.op = None
26
- self.module_type = ''
26
+ self.module_type = ""
27
27
  self.extra_args = {}
28
28
  if isinstance(host, nn.Conv2d):
29
29
  self.op = F.conv2d
30
- self.module_type = 'conv'
30
+ self.module_type = "conv"
31
31
  self.extra_args = {
32
32
  "stride": host.stride,
33
33
  "padding": host.padding,
34
34
  "dilation": host.dilation,
35
- "groups": host.groups
35
+ "groups": host.groups,
36
36
  }
37
37
  elif isinstance(host, nn.Linear):
38
38
  self.op = F.linear
39
- self.module_type = 'linear'
39
+ self.module_type = "linear"
40
40
  self.extra_args = {}
41
41
  elif isinstance(host, nn.LayerNorm):
42
42
  self.op = F.layer_norm
43
- self.module_type = 'norm'
43
+ self.module_type = "norm"
44
44
  self.extra_args = {
45
45
  "normalized_shape": host.normalized_shape,
46
- "eps": host.eps
46
+ "eps": host.eps,
47
47
  }
48
48
  elif isinstance(host, nn.GroupNorm):
49
49
  self.op = F.group_norm
50
- self.module_type = 'norm'
51
- self.extra_args = {
52
- "num_groups": host.num_groups,
53
- "eps": host.eps
54
- }
50
+ self.module_type = "norm"
51
+ self.extra_args = {"num_groups": host.num_groups, "eps": host.eps}
55
52
  else:
56
53
  logger.warning(
57
54
  f"Unsupported host type: '{type(host)}' for LyCORIS plugin. "
58
55
  "Will ignore this block."
59
56
  )
60
-
57
+
61
58
  def forward(self, *args, **kwargs):
62
59
  if self.op is None:
63
60
  return self._host(*args, **kwargs)
64
-
65
- if isinstance(self._host, (LoRACompatibleLinear, LoRACompatibleConv)) and len(args)==2:
61
+
62
+ if (
63
+ isinstance(self._host, (LoRACompatibleLinear, LoRACompatibleConv))
64
+ and len(args) == 2
65
+ ):
66
66
  scale = args[1]
67
67
  args = [args[0]]
68
68
  else:
69
69
  scale = 1
70
-
70
+
71
71
  org_weight = self._host.weight
72
72
  org_bias = getattr(self._host, "bias", None)
73
73
  new_weight = org_weight
74
74
  new_bias = org_bias
75
75
  total_diff_output = 0
76
-
76
+
77
77
  for name in self.plugin_names:
78
78
  lyco_plugin_block = getattr(self, name)
79
- diff_weight, diff_bias, diff_output = lyco_plugin_block(org_weight, org_bias, new_weight, new_bias, *args, **kwargs)
79
+ (
80
+ diff_weight,
81
+ diff_bias,
82
+ diff_output,
83
+ update_weight,
84
+ update_bias,
85
+ ) = lyco_plugin_block(
86
+ org_weight, org_bias, new_weight, new_bias, *args, **kwargs
87
+ )
80
88
  # logger.debug(f'diff weight norm: {torch.norm(diff_weight).detach().cpu().item()}')
81
89
  if diff_weight is not None:
82
- new_weight = new_weight + diff_weight * scale
90
+ if update_weight:
91
+ new_weight = new_weight + diff_weight * scale
92
+ else:
93
+ new_weight = diff_weight
83
94
  if diff_bias is not None:
84
- new_bias = diff_bias * scale if new_bias is None else new_bias + diff_bias * scale
95
+ if update_bias:
96
+ new_bias = (
97
+ diff_bias * scale
98
+ if new_bias is None
99
+ else new_bias + diff_bias * scale
100
+ )
101
+ else:
102
+ new_bias = diff_bias
85
103
  if diff_output is not None:
86
104
  total_diff_output = total_diff_output + diff_output * scale
87
-
105
+
88
106
  weight_dict = {
89
107
  "weight": new_weight,
90
108
  "bias": new_bias,
@@ -95,10 +113,17 @@ class LycorisPluginContainer(PatchPluginContainer):
95
113
 
96
114
  class LycorisPluginBlock(PatchPluginBlock):
97
115
  container_cls = LycorisPluginContainer
116
+
98
117
  def __init__(
99
- self, *args, dim=4, alpha=1.0,
100
- dropout=0., rank_dropout=0., module_dropout=0.,
101
- use_tucker=False, **kwargs
118
+ self,
119
+ *args,
120
+ dim=4,
121
+ alpha=1.0,
122
+ dropout=0.0,
123
+ rank_dropout=0.0,
124
+ module_dropout=0.0,
125
+ use_tucker=False,
126
+ **kwargs,
102
127
  ):
103
128
  super(LycorisPluginBlock, self).__init__(*args, **kwargs)
104
129
  self.module_type = self.container().module_type
@@ -108,21 +133,21 @@ class LycorisPluginBlock(PatchPluginBlock):
108
133
  self.rank_dropout = rank_dropout
109
134
  self.module_dropout = module_dropout
110
135
  self.tucker = False
111
-
112
- if self.module_type == 'conv':
136
+
137
+ if self.module_type == "conv":
113
138
  self.out_dim = self.host().out_channels
114
139
  self.in_dim = self.host().in_channels
115
140
  self.k_size = self.host().kernel_size
116
141
  self.tucker = use_tucker
117
142
  self.shape = [self.out_dim, self.in_dim, *self.k_size]
118
- elif self.module_type == 'linear':
143
+ elif self.module_type == "linear":
119
144
  self.out_dim = self.host().out_features
120
145
  self.in_dim = self.host().in_features
121
146
  self.shape = [self.out_dim, self.in_dim]
122
- elif self.module_type == 'norm':
147
+ elif self.module_type == "norm":
123
148
  self.dim = self.host().weight.shape[0]
124
149
  else:
125
150
  raise NotImplementedError
126
-
151
+
127
152
  def forward(self, org_weight, org_bias, new_weight, new_bias, *args, **kwargs):
128
- raise NotImplementedError
153
+ raise NotImplementedError
@@ -0,0 +1,62 @@
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+
5
+ from einops import rearrange
6
+
7
+ from .base import LycorisPluginBlock
8
+ from ..modules.lokr import factorization
9
+ from ..modules.diag_oft import DiagOFTModule, log_oft_factorize
10
+
11
+
12
+ class DiagOFTBlock(DiagOFTModule, LycorisPluginBlock):
13
+ wrapable_classes = (nn.Conv2d, nn.Linear)
14
+
15
+ def __init__(self, *args, constrain=0, rescaled=False, **kwargs):
16
+ LycorisPluginBlock.__init__(self, *args, **kwargs)
17
+
18
+ out_dim = self.shape[0]
19
+ self.block_size, self.block_num = factorization(out_dim, self.dim)
20
+ self.scale = 1.0
21
+ # block_num > block_size
22
+ self.rescaled = rescaled
23
+ self.constrain = constrain * out_dim
24
+ self.oft_blocks = nn.Parameter(
25
+ torch.zeros(self.block_num, self.block_size, self.block_size)
26
+ )
27
+ if rescaled:
28
+ self.rescale = nn.Parameter(torch.ones(out_dim))
29
+ log_oft_factorize(
30
+ dim=out_dim,
31
+ factor=self.dim,
32
+ num=self.block_num,
33
+ bdim=self.block_size,
34
+ )
35
+
36
+ def forward(self, orig_weight, org_bias, new_weight, new_bias, *args, **kwargs):
37
+ device = self.oft_blocks.device
38
+ if self.rank_dropout and self.training:
39
+ drop = (torch.rand(self.oft_blocks, device=device) < self.rank_dropout).to(
40
+ self.oft_blocks.dtype
41
+ )
42
+ if self.rank_dropout_scale:
43
+ drop /= drop.mean()
44
+ else:
45
+ drop = 1
46
+
47
+ r = self.get_r()
48
+ org_weight = orig_weight.to(device, dtype=r.dtype)
49
+ org_weight = rearrange(
50
+ org_weight, "(k n) ... -> k n ...", k=self.block_num, n=self.block_size
51
+ )
52
+ # Init R=0, so add I on it to ensure the output of step0 is original model output
53
+ weight = torch.einsum(
54
+ "k n m, k n ... -> k m ...",
55
+ r * self.scale + (1 - self.scale) * self.I,
56
+ org_weight,
57
+ )
58
+ weight = rearrange(weight, "k m ... -> (k m) ...")
59
+ if self.rescaled:
60
+ weight = self.rescale.to(weight) * weight
61
+ # disable update weight for replace the weight directly
62
+ return weight, None, None, False, False