lycoris-lora 3.0.0.dev8__tar.gz → 3.0.0.dev10__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.
- {lycoris_lora-3.0.0.dev8/lycoris_lora.egg-info → lycoris_lora-3.0.0.dev10}/PKG-INFO +1 -1
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/README.md +8 -1
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/config.py +25 -4
- lycoris_lora-3.0.0.dev10/lycoris/functional/lokr.py +259 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/kohya.py +7 -1
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/base.py +6 -1
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/boft.py +0 -44
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/diag_oft.py +0 -45
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/dylora.py +0 -44
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/full.py +7 -35
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/glora.py +0 -43
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/ia3.py +0 -43
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/locon.py +2 -45
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/loha.py +0 -44
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/lokr.py +96 -71
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/utils/bnb.py +3 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10/lycoris_lora.egg-info}/PKG-INFO +1 -1
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris_lora.egg-info/SOURCES.txt +1 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/setup.py +1 -1
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/LICENSE.md +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/functional/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/functional/general.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/functional/locon.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/functional/loha.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/logging.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/modules/norms.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/utils/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/utils/general.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/utils/logger.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/utils/preset.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/utils/xformers_utils.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris/wrapper.py +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris_lora.egg-info/dependency_links.txt +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris_lora.egg-info/not-zip-safe +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris_lora.egg-info/requires.txt +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris_lora.egg-info/top_level.txt +0 -0
- {lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lycoris_lora
|
|
3
|
-
Version: 3.0.0.
|
|
3
|
+
Version: 3.0.0.dev10
|
|
4
4
|
Summary: Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion
|
|
5
5
|
Home-page: https://github.com/KohakuBlueleaf/LyCORIS
|
|
6
6
|
Author: Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao
|
|
@@ -74,7 +74,7 @@ In any case, please install this package in the corresponding virtual environmen
|
|
|
74
74
|
- through pip
|
|
75
75
|
|
|
76
76
|
```bash
|
|
77
|
-
pip install
|
|
77
|
+
pip install lycoris-lora
|
|
78
78
|
```
|
|
79
79
|
- or from source
|
|
80
80
|
|
|
@@ -111,6 +111,8 @@ You can use this package's kohya module to run kohya's training script to train
|
|
|
111
111
|
|
|
112
112
|
#### HCP-Diffusion
|
|
113
113
|
|
|
114
|
+
**The support for HCP-Diffusion has been dropped on LyCORIS3.0.0, we will wait until HCP side finish the implementation of new wrapper**
|
|
115
|
+
|
|
114
116
|
You can use this package's hcp module to run HCP-Diffusion's training script to train lycoris module for SD models
|
|
115
117
|
|
|
116
118
|
```bash
|
|
@@ -156,6 +158,11 @@ forward_with_lyco = your_model(x)
|
|
|
156
158
|
|
|
157
159
|
You can check my [HakuPhi](https://github.com/KohakuBlueleaf/HakuPhi) project to see how I utilize LyCORIS to finetune the Phi-1.5 models.
|
|
158
160
|
|
|
161
|
+
#### Other method
|
|
162
|
+
After LyCORIS3.0.0, Parametrize API and Functional API have been added, which provide more different ways on utilizing LyCORIS library.
|
|
163
|
+
|
|
164
|
+
Check [xxx] for more informations.
|
|
165
|
+
|
|
159
166
|
#### Bitsandbytes support
|
|
160
167
|
|
|
161
168
|
See [bnb_example.py](bnb_example.py) for example. Basically as same as standalone wrapper.
|
|
@@ -6,6 +6,7 @@ PRESET = {
|
|
|
6
6
|
"ResnetBlock2D",
|
|
7
7
|
"Downsample2D",
|
|
8
8
|
"Upsample2D",
|
|
9
|
+
"HunYuanDiTBlock",
|
|
9
10
|
],
|
|
10
11
|
"unet_target_name": [
|
|
11
12
|
"conv_in",
|
|
@@ -13,7 +14,12 @@ PRESET = {
|
|
|
13
14
|
"time_embedding.linear_1",
|
|
14
15
|
"time_embedding.linear_2",
|
|
15
16
|
],
|
|
16
|
-
"text_encoder_target_module": [
|
|
17
|
+
"text_encoder_target_module": [
|
|
18
|
+
"CLIPAttention",
|
|
19
|
+
"CLIPMLP",
|
|
20
|
+
"MT5Block",
|
|
21
|
+
"BertLayer",
|
|
22
|
+
],
|
|
17
23
|
"text_encoder_target_name": [],
|
|
18
24
|
},
|
|
19
25
|
"full-lin": {
|
|
@@ -21,30 +27,43 @@ PRESET = {
|
|
|
21
27
|
"unet_target_module": [
|
|
22
28
|
"Transformer2DModel",
|
|
23
29
|
"ResnetBlock2D",
|
|
30
|
+
"HunYuanDiTBlock",
|
|
24
31
|
],
|
|
25
32
|
"unet_target_name": [
|
|
26
33
|
"time_embedding.linear_1",
|
|
27
34
|
"time_embedding.linear_2",
|
|
28
35
|
],
|
|
29
|
-
"text_encoder_target_module": [
|
|
36
|
+
"text_encoder_target_module": [
|
|
37
|
+
"CLIPAttention",
|
|
38
|
+
"CLIPMLP",
|
|
39
|
+
"MT5Block",
|
|
40
|
+
"BertLayer",
|
|
41
|
+
],
|
|
30
42
|
"text_encoder_target_name": [],
|
|
31
43
|
},
|
|
32
44
|
"attn-mlp": {
|
|
33
45
|
"enable_conv": False,
|
|
34
46
|
"unet_target_module": [
|
|
35
47
|
"Transformer2DModel",
|
|
48
|
+
"HunYuanDiTBlock",
|
|
36
49
|
],
|
|
37
50
|
"unet_target_name": [],
|
|
38
|
-
"text_encoder_target_module": [
|
|
51
|
+
"text_encoder_target_module": [
|
|
52
|
+
"CLIPAttention",
|
|
53
|
+
"CLIPMLP",
|
|
54
|
+
"MT5Block",
|
|
55
|
+
"BertLayer",
|
|
56
|
+
],
|
|
39
57
|
"text_encoder_target_name": [],
|
|
40
58
|
},
|
|
41
59
|
"attn-only": {
|
|
42
60
|
"enable_conv": False,
|
|
43
61
|
"unet_target_module": [
|
|
44
62
|
"CrossAttention",
|
|
63
|
+
"SelfAttention",
|
|
45
64
|
],
|
|
46
65
|
"unet_target_name": [],
|
|
47
|
-
"text_encoder_target_module": ["CLIPAttention"],
|
|
66
|
+
"text_encoder_target_module": ["CLIPAttention", "BertAttention", "MT5LayerSelfAttention"],
|
|
48
67
|
"text_encoder_target_name": [],
|
|
49
68
|
},
|
|
50
69
|
"unet-only": {
|
|
@@ -54,6 +73,7 @@ PRESET = {
|
|
|
54
73
|
"ResnetBlock2D",
|
|
55
74
|
"Downsample2D",
|
|
56
75
|
"Upsample2D",
|
|
76
|
+
"HunYuanDiTBlock",
|
|
57
77
|
],
|
|
58
78
|
"unet_target_name": [
|
|
59
79
|
"conv_in",
|
|
@@ -68,6 +88,7 @@ PRESET = {
|
|
|
68
88
|
"enable_conv": False,
|
|
69
89
|
"unet_target_module": [
|
|
70
90
|
"Transformer2DModel",
|
|
91
|
+
"HunYuanDiTBlock",
|
|
71
92
|
],
|
|
72
93
|
"unet_target_name": [],
|
|
73
94
|
"text_encoder_target_module": [],
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import torch
|
|
4
|
+
import torch.nn as nn
|
|
5
|
+
import torch.nn.functional as F
|
|
6
|
+
|
|
7
|
+
from .general import rebuild_tucker, FUNC_LIST
|
|
8
|
+
from .general import factorization
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def make_kron(w1, w2, scale):
|
|
12
|
+
for _ in range(w2.dim() - w1.dim()):
|
|
13
|
+
w1 = w1.unsqueeze(-1)
|
|
14
|
+
w2 = w2.contiguous()
|
|
15
|
+
rebuild = torch.kron(w1, w2)
|
|
16
|
+
|
|
17
|
+
return rebuild * scale
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def weight_gen(
|
|
21
|
+
org_weight,
|
|
22
|
+
rank,
|
|
23
|
+
tucker=True,
|
|
24
|
+
factor=-1,
|
|
25
|
+
decompose_both=False,
|
|
26
|
+
full_matrix=False,
|
|
27
|
+
unbalanced_factorization=False,
|
|
28
|
+
):
|
|
29
|
+
"""### weight_gen
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
org_weight (torch.Tensor): the weight tensor
|
|
33
|
+
rank (int): low rank
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
torch.Tensor | None: w1, w1a, w1b, w2, w2a, w2b, t2
|
|
37
|
+
"""
|
|
38
|
+
out_dim, in_dim, *k = org_weight.shape
|
|
39
|
+
w1 = w1a = w1b = None
|
|
40
|
+
w2 = w2a = w2b = None
|
|
41
|
+
t2 = None
|
|
42
|
+
use_w1 = use_w2 = False
|
|
43
|
+
|
|
44
|
+
if k:
|
|
45
|
+
k_size = k
|
|
46
|
+
shape = (out_dim, in_dim, *k_size)
|
|
47
|
+
|
|
48
|
+
in_m, in_n = factorization(in_dim, factor)
|
|
49
|
+
out_l, out_k = factorization(out_dim, factor)
|
|
50
|
+
if unbalanced_factorization:
|
|
51
|
+
out_l, out_k = out_k, out_l
|
|
52
|
+
shape = ((out_l, out_k), (in_m, in_n), *k_size) # ((a, b), (c, d), *k_size)
|
|
53
|
+
tucker = tucker and any(i != 1 for i in k_size)
|
|
54
|
+
if (
|
|
55
|
+
decompose_both
|
|
56
|
+
and rank < max(shape[0][0], shape[1][0]) / 2
|
|
57
|
+
and not full_matrix
|
|
58
|
+
):
|
|
59
|
+
w1a = torch.empty(shape[0][0], rank)
|
|
60
|
+
w1b = torch.empty(rank, shape[1][0])
|
|
61
|
+
else:
|
|
62
|
+
use_w1 = True
|
|
63
|
+
w1 = torch.empty(shape[0][0], shape[1][0]) # a*c, 1-mode
|
|
64
|
+
|
|
65
|
+
if rank >= max(shape[0][1], shape[1][1]) / 2 or full_matrix:
|
|
66
|
+
use_w2 = True
|
|
67
|
+
w2 = torch.empty(shape[0][1], shape[1][1], *k_size)
|
|
68
|
+
elif tucker:
|
|
69
|
+
t2 = torch.empty(rank, rank, *shape[2:])
|
|
70
|
+
w2a = torch.empty(rank, shape[0][1]) # b, 1-mode
|
|
71
|
+
w2b = torch.empty(rank, shape[1][1]) # d, 2-mode
|
|
72
|
+
else: # Conv2d not tucker
|
|
73
|
+
# bigger part. weight and LoRA. [b, dim] x [dim, d*k1*k2]
|
|
74
|
+
w2a = torch.empty(shape[0][1], rank)
|
|
75
|
+
w2b = torch.empty(rank, shape[1][1], *shape[2:])
|
|
76
|
+
# w1 ⊗ (w2a x w2b) = (a, b)⊗((c, dim)x(dim, d*k1*k2)) = (a, b)⊗(c, d*k1*k2) = (ac, bd*k1*k2)
|
|
77
|
+
else: # Linear
|
|
78
|
+
shape = (out_dim, in_dim)
|
|
79
|
+
|
|
80
|
+
in_m, in_n = factorization(in_dim, factor)
|
|
81
|
+
out_l, out_k = factorization(out_dim, factor)
|
|
82
|
+
if unbalanced_factorization:
|
|
83
|
+
out_l, out_k = out_k, out_l
|
|
84
|
+
shape = (
|
|
85
|
+
(out_l, out_k),
|
|
86
|
+
(in_m, in_n),
|
|
87
|
+
) # ((a, b), (c, d)), out_dim = a*c, in_dim = b*d
|
|
88
|
+
# smaller part. weight scale
|
|
89
|
+
if decompose_both and rank < max(shape[0][0], shape[1][0]) / 2:
|
|
90
|
+
w1a = torch.empty(shape[0][0], rank)
|
|
91
|
+
w1b = torch.empty(rank, shape[1][0])
|
|
92
|
+
else:
|
|
93
|
+
use_w1 = True
|
|
94
|
+
w1 = torch.empty(shape[0][0], shape[1][0]) # a*c, 1-mode
|
|
95
|
+
if rank < max(shape[0][1], shape[1][1]) / 2:
|
|
96
|
+
# bigger part. weight and LoRA. [b, dim] x [dim, d]
|
|
97
|
+
w2a = torch.empty(shape[0][1], rank)
|
|
98
|
+
w2b = torch.empty(rank, shape[1][1])
|
|
99
|
+
# w1 ⊗ (w2a x w2b) = (a, b)⊗((c, dim)x(dim, d)) = (a, b)⊗(c, d) = (ac, bd)
|
|
100
|
+
else:
|
|
101
|
+
use_w2 = True
|
|
102
|
+
w2 = torch.empty(shape[0][1], shape[1][1])
|
|
103
|
+
|
|
104
|
+
if use_w2:
|
|
105
|
+
torch.nn.init.constant_(w2, 1)
|
|
106
|
+
else:
|
|
107
|
+
if tucker:
|
|
108
|
+
torch.nn.init.kaiming_uniform_(t2, a=math.sqrt(5))
|
|
109
|
+
torch.nn.init.kaiming_uniform_(w2a, a=math.sqrt(5))
|
|
110
|
+
torch.nn.init.constant_(w2b, 1)
|
|
111
|
+
|
|
112
|
+
if use_w1:
|
|
113
|
+
torch.nn.init.kaiming_uniform_(w1, a=math.sqrt(5))
|
|
114
|
+
else:
|
|
115
|
+
torch.nn.init.kaiming_uniform_(w1a, a=math.sqrt(5))
|
|
116
|
+
torch.nn.init.kaiming_uniform_(w1b, a=math.sqrt(5))
|
|
117
|
+
|
|
118
|
+
return w1, w1a, w1b, w2, w2a, w2b, t2
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def lokr_diff_weight(w1, w1a, w1b, w2, w2a, w2b, t, gamma=1.0):
|
|
122
|
+
"""### lokr_diff_weight
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
gamma (float, optional): scale factor, normally alpha/rank here
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
torch.Tensor: ΔW
|
|
129
|
+
"""
|
|
130
|
+
if w1a is not None:
|
|
131
|
+
rank = w1a.shape[1]
|
|
132
|
+
elif w2a is not None:
|
|
133
|
+
rank = w2a.shape[1]
|
|
134
|
+
else:
|
|
135
|
+
rank = gamma
|
|
136
|
+
scale = gamma / rank
|
|
137
|
+
if w1 is None:
|
|
138
|
+
w1 = w1a @ w1b
|
|
139
|
+
if w2 is None:
|
|
140
|
+
if t is None:
|
|
141
|
+
r, o, *k = w2b.shape
|
|
142
|
+
w2 = w2a @ w2b.view(r, -1)
|
|
143
|
+
w2 = w2.view(-1, o, *k)
|
|
144
|
+
else:
|
|
145
|
+
w2 = rebuild_tucker(t, w2a, w2b)
|
|
146
|
+
return make_kron(w1, w2, scale)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def lokr_bypass_forward_diff(
|
|
150
|
+
h, w1, w1a, w1b, w2, w2a, w2b, t, gamma=1.0, extra_args={}
|
|
151
|
+
):
|
|
152
|
+
"""### lokr_bypass_forward_diff
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
gamma (float, optional): scale factor, normally alpha/rank here
|
|
156
|
+
extra_args (dict, optional): extra args for forward func, \
|
|
157
|
+
e.g. padding, stride for Conv1/2/3d
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
torch.Tensor: output tensor
|
|
161
|
+
"""
|
|
162
|
+
use_w1 = w1 is not None
|
|
163
|
+
use_w2 = w2 is not None
|
|
164
|
+
tucker = t is not None
|
|
165
|
+
dim = t.dim() if tucker else w2.dim() if w2 is not None else w2b.dim()
|
|
166
|
+
print(dim)
|
|
167
|
+
rank = w1b.size(0) if not use_w1 else w2b.size(0) if not use_w2 else gamma
|
|
168
|
+
scale = gamma / rank
|
|
169
|
+
is_conv = dim > 2
|
|
170
|
+
op = FUNC_LIST[dim]
|
|
171
|
+
|
|
172
|
+
if is_conv:
|
|
173
|
+
kw_dict = extra_args
|
|
174
|
+
else:
|
|
175
|
+
kw_dict = {}
|
|
176
|
+
|
|
177
|
+
if use_w2:
|
|
178
|
+
ba = w2
|
|
179
|
+
else:
|
|
180
|
+
a = w2b
|
|
181
|
+
b = w2a
|
|
182
|
+
|
|
183
|
+
if t is not None:
|
|
184
|
+
a = a.view(*a.shape, *[1] * (dim - 2))
|
|
185
|
+
b = b.view(*b.shape, *[1] * (dim - 2))
|
|
186
|
+
elif is_conv:
|
|
187
|
+
b = b.view(*b.shape, *[1] * (dim - 2))
|
|
188
|
+
|
|
189
|
+
if use_w1:
|
|
190
|
+
c = w1
|
|
191
|
+
else:
|
|
192
|
+
c = w1a @ w1b
|
|
193
|
+
uq = c.size(1)
|
|
194
|
+
|
|
195
|
+
if is_conv:
|
|
196
|
+
# (b, uq), vq, ...
|
|
197
|
+
B, _, *rest = h.shape
|
|
198
|
+
h_in_group = h.reshape(B * uq, -1, *rest)
|
|
199
|
+
else:
|
|
200
|
+
# b, ..., uq, vq
|
|
201
|
+
h_in_group = h.reshape(*h.shape[:-1], uq, -1)
|
|
202
|
+
|
|
203
|
+
if use_w2:
|
|
204
|
+
hb = op(h_in_group, ba, **kw_dict)
|
|
205
|
+
else:
|
|
206
|
+
if is_conv:
|
|
207
|
+
if tucker:
|
|
208
|
+
ha = op(h_in_group, a)
|
|
209
|
+
ht = op(ha, t, **kw_dict)
|
|
210
|
+
hb = op(ht, b)
|
|
211
|
+
else:
|
|
212
|
+
ha = op(h_in_group, a, **kw_dict)
|
|
213
|
+
hb = op(ha, b)
|
|
214
|
+
else:
|
|
215
|
+
ha = op(h_in_group, a, **kw_dict)
|
|
216
|
+
hb = op(ha, b)
|
|
217
|
+
|
|
218
|
+
if is_conv:
|
|
219
|
+
# (b, uq), vp, ..., f
|
|
220
|
+
# -> b, uq, vp, ..., f
|
|
221
|
+
# -> b, f, vp, ..., uq
|
|
222
|
+
hb = hb.view(B, -1, *hb.shape[1:])
|
|
223
|
+
h_cross_group = hb.transpose(1, -1)
|
|
224
|
+
else:
|
|
225
|
+
# b, ..., uq, vq
|
|
226
|
+
# -> b, ..., vq, uq
|
|
227
|
+
h_cross_group = hb.transpose(-1, -2)
|
|
228
|
+
|
|
229
|
+
hc = F.linear(h_cross_group, c)
|
|
230
|
+
if is_conv:
|
|
231
|
+
# b, f, vp, ..., up
|
|
232
|
+
# -> b, up, vp, ... ,f
|
|
233
|
+
# -> b, c, ..., f
|
|
234
|
+
hc = hc.transpose(1, -1)
|
|
235
|
+
h = hc.reshape(B, -1, *hc.shape[3:])
|
|
236
|
+
else:
|
|
237
|
+
# b, ..., vp, up
|
|
238
|
+
# -> b, ..., up, vp
|
|
239
|
+
# -> b, ..., c
|
|
240
|
+
hc = hc.transpose(-1, -2)
|
|
241
|
+
h = hc.reshape(*hc.shape[:-2], -1)
|
|
242
|
+
|
|
243
|
+
return h * scale
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
if __name__ == "__main__":
|
|
247
|
+
w = torch.randn(32, 32, 3, 3, 3)
|
|
248
|
+
w1, w1a, w1b, w2, w2a, w2b, t = weight_gen(w, 2, tucker=False)
|
|
249
|
+
extra_args = {"padding": 1}
|
|
250
|
+
|
|
251
|
+
x = torch.randn(1, 32, 8, 8, 8)
|
|
252
|
+
y = FUNC_LIST[w.dim()](x, w, **extra_args)
|
|
253
|
+
diff_w = lokr_diff_weight(w1, w1a, w1b, w2, w2a, w2b, t, 1)
|
|
254
|
+
diff_y_w = FUNC_LIST[w.dim()](x, diff_w, **extra_args)
|
|
255
|
+
diff_y = lokr_bypass_forward_diff(x, w1, w1a, w1b, w2, w2a, w2b, t, 1, extra_args)
|
|
256
|
+
|
|
257
|
+
print(F.mse_loss(y, y + diff_y))
|
|
258
|
+
print(F.mse_loss(w, w + diff_w))
|
|
259
|
+
print(F.mse_loss(diff_y, diff_y_w))
|
|
@@ -238,6 +238,7 @@ class LycorisNetworkKohya(LycorisNetwork):
|
|
|
238
238
|
"ResnetBlock2D",
|
|
239
239
|
"Downsample2D",
|
|
240
240
|
"Upsample2D",
|
|
241
|
+
"HunYuanDiTBlock",
|
|
241
242
|
]
|
|
242
243
|
UNET_TARGET_REPLACE_NAME = [
|
|
243
244
|
"conv_in",
|
|
@@ -245,7 +246,12 @@ class LycorisNetworkKohya(LycorisNetwork):
|
|
|
245
246
|
"time_embedding.linear_1",
|
|
246
247
|
"time_embedding.linear_2",
|
|
247
248
|
]
|
|
248
|
-
TEXT_ENCODER_TARGET_REPLACE_MODULE = [
|
|
249
|
+
TEXT_ENCODER_TARGET_REPLACE_MODULE = [
|
|
250
|
+
"CLIPAttention",
|
|
251
|
+
"CLIPMLP",
|
|
252
|
+
"MT5Block",
|
|
253
|
+
"BertLayer",
|
|
254
|
+
]
|
|
249
255
|
TEXT_ENCODER_TARGET_REPLACE_NAME = []
|
|
250
256
|
LORA_PREFIX_UNET = "lora_unet"
|
|
251
257
|
LORA_PREFIX_TEXT_ENCODER = "lora_te"
|
|
@@ -184,6 +184,10 @@ class LycorisBaseModule(ModuleCustomSD):
|
|
|
184
184
|
|
|
185
185
|
@classmethod
|
|
186
186
|
def parametrize(cls, org_module, attr, *args, **kwargs):
|
|
187
|
+
from .full import FullModule
|
|
188
|
+
|
|
189
|
+
if cls is FullModule:
|
|
190
|
+
raise RuntimeError("FullModule cannot be used for parametrize.")
|
|
187
191
|
target_param = getattr(org_module, attr)
|
|
188
192
|
kwargs["bypass_mode"] = False
|
|
189
193
|
if target_param.dim() == 2:
|
|
@@ -206,11 +210,12 @@ class LycorisBaseModule(ModuleCustomSD):
|
|
|
206
210
|
target_param.shape[0],
|
|
207
211
|
target_param.shape[1],
|
|
208
212
|
*target_param.shape[2:],
|
|
213
|
+
bias=False,
|
|
209
214
|
)
|
|
210
215
|
proxy_module.weight = target_param
|
|
211
216
|
module_obj = cls("", proxy_module, *args, **kwargs)
|
|
212
217
|
module_obj.forward = module_obj.parametrize_forward
|
|
213
|
-
module_obj.to(target_param
|
|
218
|
+
module_obj.to(target_param)
|
|
214
219
|
parametrize.register_parametrization(org_module, attr, module_obj)
|
|
215
220
|
return module_obj
|
|
216
221
|
|
|
@@ -3,7 +3,6 @@ from math import log2
|
|
|
3
3
|
|
|
4
4
|
import torch
|
|
5
5
|
import torch.nn as nn
|
|
6
|
-
import torch.nn.functional as F
|
|
7
6
|
|
|
8
7
|
from einops import rearrange
|
|
9
8
|
|
|
@@ -197,46 +196,3 @@ class ButterflyOFTModule(LycorisBaseModule):
|
|
|
197
196
|
w = self.make_weight(scale, x.device)
|
|
198
197
|
kw_dict = self.kw_dict | {"weight": w, "bias": self.org_module[0].bias}
|
|
199
198
|
return self.op(x, **kw_dict)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if __name__ == "__main__":
|
|
203
|
-
device = torch.device("cuda")
|
|
204
|
-
module = ButterflyOFTModule
|
|
205
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
206
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
207
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
208
|
-
print(net)
|
|
209
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
210
|
-
test_output = net(test_input)
|
|
211
|
-
torch.sum(test_output).backward()
|
|
212
|
-
print(test_output.shape)
|
|
213
|
-
|
|
214
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
215
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
216
|
-
base_4bit.to(device)
|
|
217
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
218
|
-
print(qnet)
|
|
219
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
220
|
-
test_output = qnet(test_input)
|
|
221
|
-
torch.sum(test_output).backward()
|
|
222
|
-
print(test_output.shape)
|
|
223
|
-
|
|
224
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
225
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
226
|
-
device
|
|
227
|
-
)
|
|
228
|
-
print(net)
|
|
229
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
230
|
-
test_output = net(test_input)
|
|
231
|
-
torch.sum(test_output).backward()
|
|
232
|
-
print(test_output.shape)
|
|
233
|
-
|
|
234
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
235
|
-
net = module.parametrize(
|
|
236
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
237
|
-
).to(device)
|
|
238
|
-
print(base)
|
|
239
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
240
|
-
test_output = base(test_input)
|
|
241
|
-
torch.sum(test_output).backward()
|
|
242
|
-
print(test_output.shape)
|
|
@@ -4,8 +4,6 @@ import torch
|
|
|
4
4
|
import torch.nn as nn
|
|
5
5
|
import torch.nn.functional as F
|
|
6
6
|
|
|
7
|
-
from einops import rearrange
|
|
8
|
-
|
|
9
7
|
from .base import LycorisBaseModule
|
|
10
8
|
from ..functional import factorization
|
|
11
9
|
from ..logging import logger
|
|
@@ -182,46 +180,3 @@ class DiagOFTModule(LycorisBaseModule):
|
|
|
182
180
|
w = self.make_weight(scale, x.device)
|
|
183
181
|
kw_dict = self.kw_dict | {"weight": w, "bias": self.org_module[0].bias}
|
|
184
182
|
return self.op(x, **kw_dict)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if __name__ == "__main__":
|
|
188
|
-
device = torch.device("cuda")
|
|
189
|
-
module = DiagOFTModule
|
|
190
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
191
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
192
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
193
|
-
print(net)
|
|
194
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
195
|
-
test_output = net(test_input)
|
|
196
|
-
torch.sum(test_output).backward()
|
|
197
|
-
print(test_output.shape)
|
|
198
|
-
|
|
199
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
200
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
201
|
-
base_4bit.to(device)
|
|
202
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
203
|
-
print(qnet)
|
|
204
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
205
|
-
test_output = qnet(test_input)
|
|
206
|
-
torch.sum(test_output).backward()
|
|
207
|
-
print(test_output.shape)
|
|
208
|
-
|
|
209
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
210
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
211
|
-
device
|
|
212
|
-
)
|
|
213
|
-
print(net)
|
|
214
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
215
|
-
test_output = net(test_input)
|
|
216
|
-
torch.sum(test_output).backward()
|
|
217
|
-
print(test_output.shape)
|
|
218
|
-
|
|
219
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
220
|
-
net = module.parametrize(
|
|
221
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
222
|
-
).to(device)
|
|
223
|
-
print(base)
|
|
224
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
225
|
-
test_output = base(test_input)
|
|
226
|
-
torch.sum(test_output).backward()
|
|
227
|
-
print(test_output.shape)
|
|
@@ -3,7 +3,6 @@ import random
|
|
|
3
3
|
|
|
4
4
|
import torch
|
|
5
5
|
import torch.nn as nn
|
|
6
|
-
import torch.nn.functional as F
|
|
7
6
|
|
|
8
7
|
from .base import LycorisBaseModule
|
|
9
8
|
from ..utils import product
|
|
@@ -156,46 +155,3 @@ class DyLoraModule(LycorisBaseModule):
|
|
|
156
155
|
else self.org_module[0].bias.data
|
|
157
156
|
)
|
|
158
157
|
return self.op(x, weight, bias, **self.kw_dict)
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if __name__ == "__main__":
|
|
162
|
-
device = torch.device("cuda")
|
|
163
|
-
module = DyLoraModule
|
|
164
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
165
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
166
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
167
|
-
print(net)
|
|
168
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
169
|
-
test_output = net(test_input)
|
|
170
|
-
torch.sum(test_output).backward()
|
|
171
|
-
print(test_output.shape)
|
|
172
|
-
|
|
173
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
174
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
175
|
-
base_4bit.to(device)
|
|
176
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
177
|
-
print(qnet)
|
|
178
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
179
|
-
test_output = qnet(test_input)
|
|
180
|
-
torch.sum(test_output).backward()
|
|
181
|
-
print(test_output.shape)
|
|
182
|
-
|
|
183
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
184
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
185
|
-
device
|
|
186
|
-
)
|
|
187
|
-
print(net)
|
|
188
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
189
|
-
test_output = net(test_input)
|
|
190
|
-
torch.sum(test_output).backward()
|
|
191
|
-
print(test_output.shape)
|
|
192
|
-
|
|
193
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
194
|
-
net = module.parametrize(
|
|
195
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
196
|
-
).to(device)
|
|
197
|
-
print(base)
|
|
198
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
199
|
-
test_output = base(test_input)
|
|
200
|
-
torch.sum(test_output).backward()
|
|
201
|
-
print(test_output.shape)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from typing import Mapping
|
|
2
1
|
import torch
|
|
3
2
|
import torch.nn as nn
|
|
4
3
|
|
|
@@ -77,6 +76,12 @@ class FullModule(LycorisBaseModule):
|
|
|
77
76
|
else:
|
|
78
77
|
self.org_bias = None
|
|
79
78
|
|
|
79
|
+
def restore(self):
|
|
80
|
+
self.org_module[0].forward = self.org_forward
|
|
81
|
+
self.org_module[0].weight = nn.Parameter(self._org_weight[0])
|
|
82
|
+
if self.org_bias is not None:
|
|
83
|
+
self.org_module[0].bias = nn.Parameter(self.org_bias[0])
|
|
84
|
+
|
|
80
85
|
def load_state_dict(self, state_dict, strict: bool = True, assign: bool = False):
|
|
81
86
|
return
|
|
82
87
|
|
|
@@ -141,7 +146,7 @@ class FullModule(LycorisBaseModule):
|
|
|
141
146
|
if shape is not None:
|
|
142
147
|
weight = weight.view(shape)
|
|
143
148
|
if bias is not None:
|
|
144
|
-
bias = bias.view(shape[0]
|
|
149
|
+
bias = bias.view(shape[0])
|
|
145
150
|
return weight, bias
|
|
146
151
|
|
|
147
152
|
def forward(self, x: torch.Tensor, *args, **kwargs):
|
|
@@ -159,36 +164,3 @@ class FullModule(LycorisBaseModule):
|
|
|
159
164
|
weight, bias = self.make_weight(scale, x.device)
|
|
160
165
|
kw_dict = self.kw_dict | {"weight": weight, "bias": bias}
|
|
161
166
|
return self.op(x, **kw_dict)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if __name__ == "__main__":
|
|
165
|
-
device = torch.device("cuda")
|
|
166
|
-
module = FullModule
|
|
167
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
168
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
169
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
170
|
-
print(net)
|
|
171
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
172
|
-
test_output = net(test_input)
|
|
173
|
-
torch.sum(test_output).backward()
|
|
174
|
-
print(test_output.shape)
|
|
175
|
-
|
|
176
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
177
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
178
|
-
device
|
|
179
|
-
)
|
|
180
|
-
print(net)
|
|
181
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
182
|
-
test_output = net(test_input)
|
|
183
|
-
torch.sum(test_output).backward()
|
|
184
|
-
print(test_output.shape)
|
|
185
|
-
|
|
186
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
187
|
-
net = module.parametrize(
|
|
188
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
189
|
-
).to(device)
|
|
190
|
-
print(base)
|
|
191
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
192
|
-
test_output = base(test_input)
|
|
193
|
-
torch.sum(test_output).backward()
|
|
194
|
-
print(test_output.shape)
|
|
@@ -202,46 +202,3 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
202
202
|
else self.org_module[0].bias.data
|
|
203
203
|
)
|
|
204
204
|
return self.op(x, weight, bias, **self.kw_dict)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if __name__ == "__main__":
|
|
208
|
-
device = torch.device("cuda")
|
|
209
|
-
module = GLoRAModule
|
|
210
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
211
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
212
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
213
|
-
print(net)
|
|
214
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
215
|
-
test_output = net(test_input)
|
|
216
|
-
torch.sum(test_output).backward()
|
|
217
|
-
print(test_output.shape)
|
|
218
|
-
|
|
219
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
220
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
221
|
-
base_4bit.to(device)
|
|
222
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
223
|
-
print(qnet)
|
|
224
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
225
|
-
test_output = qnet(test_input)
|
|
226
|
-
torch.sum(test_output).backward()
|
|
227
|
-
print(test_output.shape)
|
|
228
|
-
|
|
229
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
230
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
231
|
-
device
|
|
232
|
-
)
|
|
233
|
-
print(net)
|
|
234
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
235
|
-
test_output = net(test_input)
|
|
236
|
-
torch.sum(test_output).backward()
|
|
237
|
-
print(test_output.shape)
|
|
238
|
-
|
|
239
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
240
|
-
net = module.parametrize(
|
|
241
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
242
|
-
).to(device)
|
|
243
|
-
print(base)
|
|
244
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
245
|
-
test_output = base(test_input)
|
|
246
|
-
torch.sum(test_output).backward()
|
|
247
|
-
print(test_output.shape)
|
|
@@ -128,46 +128,3 @@ class IA3Module(LycorisBaseModule):
|
|
|
128
128
|
else self.org_module[0].bias.data
|
|
129
129
|
)
|
|
130
130
|
return self.op(x, weight, bias, **self.kw_dict)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if __name__ == "__main__":
|
|
134
|
-
device = torch.device("cuda")
|
|
135
|
-
module = IA3Module
|
|
136
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
137
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
138
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
139
|
-
print(net)
|
|
140
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
141
|
-
test_output = net(test_input)
|
|
142
|
-
torch.sum(test_output).backward()
|
|
143
|
-
print(test_output.shape)
|
|
144
|
-
|
|
145
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
146
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
147
|
-
base_4bit.to(device)
|
|
148
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
149
|
-
print(qnet)
|
|
150
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
151
|
-
test_output = qnet(test_input)
|
|
152
|
-
torch.sum(test_output).backward()
|
|
153
|
-
print(test_output.shape)
|
|
154
|
-
|
|
155
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
156
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
157
|
-
device
|
|
158
|
-
)
|
|
159
|
-
print(net)
|
|
160
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
161
|
-
test_output = net(test_input)
|
|
162
|
-
torch.sum(test_output).backward()
|
|
163
|
-
print(test_output.shape)
|
|
164
|
-
|
|
165
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
166
|
-
net = module.parametrize(
|
|
167
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
168
|
-
).to(device)
|
|
169
|
-
print(base)
|
|
170
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
171
|
-
test_output = base(test_input)
|
|
172
|
-
torch.sum(test_output).backward()
|
|
173
|
-
print(test_output.shape)
|
|
@@ -74,7 +74,7 @@ class LoConModule(LycorisBaseModule):
|
|
|
74
74
|
self.down_op = self.op
|
|
75
75
|
self.up_op = self.op
|
|
76
76
|
if use_tucker and any(i != 1 for i in k_size):
|
|
77
|
-
self.lora_down = self.module(in_dim, lora_dim,
|
|
77
|
+
self.lora_down = self.module(in_dim, lora_dim, 1, bias=False)
|
|
78
78
|
self.lora_mid = self.module(
|
|
79
79
|
lora_dim, lora_dim, k_size, stride, padding, bias=False
|
|
80
80
|
)
|
|
@@ -83,7 +83,7 @@ class LoConModule(LycorisBaseModule):
|
|
|
83
83
|
self.lora_down = self.module(
|
|
84
84
|
in_dim, lora_dim, k_size, stride, padding, bias=False
|
|
85
85
|
)
|
|
86
|
-
self.lora_up = self.module(lora_dim, out_dim,
|
|
86
|
+
self.lora_up = self.module(lora_dim, out_dim, 1, bias=False)
|
|
87
87
|
elif isinstance(org_module, nn.Linear):
|
|
88
88
|
self.isconv = False
|
|
89
89
|
self.down_op = F.linear
|
|
@@ -277,46 +277,3 @@ class LoConModule(LycorisBaseModule):
|
|
|
277
277
|
return self.op(x, weight, bias, **self.kw_dict)
|
|
278
278
|
else:
|
|
279
279
|
return self.bypass_forward(x, scale=self.multiplier)
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if __name__ == "__main__":
|
|
283
|
-
device = torch.device("cuda")
|
|
284
|
-
module = LoConModule
|
|
285
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
286
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
287
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
288
|
-
print(net)
|
|
289
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
290
|
-
test_output = net(test_input)
|
|
291
|
-
torch.sum(test_output).backward()
|
|
292
|
-
print(test_output.shape)
|
|
293
|
-
|
|
294
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
295
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
296
|
-
base_4bit.to(device)
|
|
297
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
298
|
-
print(qnet)
|
|
299
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
300
|
-
test_output = qnet(test_input)
|
|
301
|
-
torch.sum(test_output).backward()
|
|
302
|
-
print(test_output.shape)
|
|
303
|
-
|
|
304
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
305
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
306
|
-
device
|
|
307
|
-
)
|
|
308
|
-
print(net)
|
|
309
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
310
|
-
test_output = net(test_input)
|
|
311
|
-
torch.sum(test_output).backward()
|
|
312
|
-
print(test_output.shape)
|
|
313
|
-
|
|
314
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
315
|
-
net = module.parametrize(
|
|
316
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
317
|
-
)
|
|
318
|
-
print(base)
|
|
319
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
320
|
-
test_output = base(test_input)
|
|
321
|
-
torch.sum(test_output).backward()
|
|
322
|
-
print(test_output.shape)
|
|
@@ -2,7 +2,6 @@ import math
|
|
|
2
2
|
|
|
3
3
|
import torch
|
|
4
4
|
import torch.nn as nn
|
|
5
|
-
import torch.nn.functional as F
|
|
6
5
|
|
|
7
6
|
from .base import LycorisBaseModule
|
|
8
7
|
from ..functional.loha import loha_diff_weight
|
|
@@ -267,46 +266,3 @@ class LohaModule(LycorisBaseModule):
|
|
|
267
266
|
if self.wd:
|
|
268
267
|
weight = self.apply_weight_decompose(weight)
|
|
269
268
|
return self.op(x, weight, bias, **self.kw_dict)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
if __name__ == "__main__":
|
|
273
|
-
device = torch.device("cuda")
|
|
274
|
-
module = LohaModule
|
|
275
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
276
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
277
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
278
|
-
print(net)
|
|
279
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
280
|
-
test_output = net(test_input)
|
|
281
|
-
torch.sum(test_output).backward()
|
|
282
|
-
print(test_output.shape)
|
|
283
|
-
|
|
284
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
285
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
286
|
-
base_4bit.to(device)
|
|
287
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
288
|
-
print(qnet)
|
|
289
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
290
|
-
test_output = qnet(test_input)
|
|
291
|
-
torch.sum(test_output).backward()
|
|
292
|
-
print(test_output.shape)
|
|
293
|
-
|
|
294
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
295
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
296
|
-
device
|
|
297
|
-
)
|
|
298
|
-
print(net)
|
|
299
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
300
|
-
test_output = net(test_input)
|
|
301
|
-
torch.sum(test_output).backward()
|
|
302
|
-
print(test_output.shape)
|
|
303
|
-
|
|
304
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
305
|
-
net = module.parametrize(
|
|
306
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
307
|
-
)
|
|
308
|
-
print(base)
|
|
309
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
310
|
-
test_output = base(test_input)
|
|
311
|
-
torch.sum(test_output).backward()
|
|
312
|
-
print(test_output.shape)
|
|
@@ -9,6 +9,7 @@ from einops import rearrange
|
|
|
9
9
|
|
|
10
10
|
from .base import LycorisBaseModule
|
|
11
11
|
from ..functional import factorization, rebuild_tucker
|
|
12
|
+
from ..functional.lokr import make_kron
|
|
12
13
|
from ..logging import logger
|
|
13
14
|
from ..utils.bnb import LinearNF4
|
|
14
15
|
|
|
@@ -22,15 +23,6 @@ def logging_force_full_matrix(lora_dim, dim, factor):
|
|
|
22
23
|
)
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
def make_kron(w1, w2, scale):
|
|
26
|
-
if len(w2.shape) == 4:
|
|
27
|
-
w1 = w1.unsqueeze(2).unsqueeze(2)
|
|
28
|
-
w2 = w2.contiguous()
|
|
29
|
-
rebuild = torch.kron(w1, w2)
|
|
30
|
-
|
|
31
|
-
return rebuild * scale
|
|
32
|
-
|
|
33
|
-
|
|
34
26
|
class LokrModule(LycorisBaseModule):
|
|
35
27
|
support_module = {
|
|
36
28
|
"linear",
|
|
@@ -115,9 +107,7 @@ class LokrModule(LycorisBaseModule):
|
|
|
115
107
|
torch.empty(shape[0][1], shape[1][1], *k_size)
|
|
116
108
|
)
|
|
117
109
|
elif self.tucker:
|
|
118
|
-
self.lokr_t2 = nn.Parameter(
|
|
119
|
-
torch.empty(lora_dim, lora_dim, shape[2], shape[3])
|
|
120
|
-
)
|
|
110
|
+
self.lokr_t2 = nn.Parameter(torch.empty(lora_dim, lora_dim, *shape[2:]))
|
|
121
111
|
self.lokr_w2_a = nn.Parameter(
|
|
122
112
|
torch.empty(lora_dim, shape[0][1])
|
|
123
113
|
) # b, 1-mode
|
|
@@ -339,40 +329,74 @@ class LokrModule(LycorisBaseModule):
|
|
|
339
329
|
return scaled, orig_norm * ratio
|
|
340
330
|
|
|
341
331
|
def bypass_forward_diff(self, h, scale=1):
|
|
342
|
-
|
|
343
|
-
return (
|
|
344
|
-
self.op(h, self.get_weight(self.shape), **self.kw_dict)
|
|
345
|
-
* self.multiplier
|
|
346
|
-
)
|
|
347
|
-
if self.module_type.startswith("conv"):
|
|
348
|
-
h = h.transpose(1, -1)
|
|
332
|
+
is_conv = self.module_type.startswith("conv")
|
|
349
333
|
if self.use_w2:
|
|
350
334
|
ba = self.lokr_w2
|
|
351
335
|
else:
|
|
352
336
|
a = self.lokr_w2_b
|
|
353
337
|
b = self.lokr_w2_a
|
|
338
|
+
|
|
339
|
+
if self.tucker:
|
|
340
|
+
t = self.lokr_t2
|
|
341
|
+
a = a.view(*a.shape, *[1] * (len(t.shape) - 2))
|
|
342
|
+
b = b.view(*b.shape, *[1] * (len(t.shape) - 2))
|
|
343
|
+
elif is_conv:
|
|
344
|
+
a = a.view(*a.shape, *self.shape[2:])
|
|
345
|
+
b = b.view(*b.shape, *[1] * (len(self.shape) - 2))
|
|
346
|
+
|
|
354
347
|
if self.use_w1:
|
|
355
348
|
c = self.lokr_w1
|
|
356
349
|
else:
|
|
357
350
|
c = self.lokr_w1_a @ self.lokr_w1_b
|
|
358
351
|
uq = c.size(1)
|
|
359
352
|
|
|
353
|
+
if is_conv:
|
|
354
|
+
# (b, uq), vq, ...
|
|
355
|
+
b, _, *rest = h.shape
|
|
356
|
+
h_in_group = h.reshape(b * uq, -1, *rest)
|
|
357
|
+
else:
|
|
358
|
+
# b, ..., uq, vq
|
|
359
|
+
h_in_group = h.reshape(*h.shape[:-1], uq, -1)
|
|
360
|
+
|
|
360
361
|
if self.use_w2:
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
362
|
+
hb = self.op(h_in_group, ba, **self.kw_dict)
|
|
363
|
+
else:
|
|
364
|
+
if is_conv:
|
|
365
|
+
if self.tucker:
|
|
366
|
+
ha = self.op(h_in_group, a)
|
|
367
|
+
ht = self.op(ha, t, **self.kw_dict)
|
|
368
|
+
hb = self.op(ht, b)
|
|
369
|
+
else:
|
|
370
|
+
ha = self.op(h_in_group, a, **self.kw_dict)
|
|
371
|
+
hb = self.op(ha, b)
|
|
372
|
+
else:
|
|
373
|
+
ha = self.op(h_in_group, a, **self.kw_dict)
|
|
374
|
+
hb = self.op(ha, b)
|
|
375
|
+
|
|
376
|
+
if is_conv:
|
|
377
|
+
# (b, uq), vp, ..., f
|
|
378
|
+
# -> b, uq, vp, ..., f
|
|
379
|
+
# -> b, f, vp, ..., uq
|
|
380
|
+
hb = hb.view(b, -1, *hb.shape[1:])
|
|
381
|
+
h_cross_group = hb.transpose(1, -1)
|
|
364
382
|
else:
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
hb = F.linear(ha, b)
|
|
383
|
+
# b, ..., uq, vq
|
|
384
|
+
# -> b, ..., vq, uq
|
|
385
|
+
h_cross_group = hb.transpose(-1, -2)
|
|
369
386
|
|
|
370
|
-
h_cross_group = hb.transpose(-1, -2)
|
|
371
387
|
hc = F.linear(h_cross_group, c)
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
388
|
+
if is_conv:
|
|
389
|
+
# b, f, vp, ..., up
|
|
390
|
+
# -> b, up, vp, ... ,f
|
|
391
|
+
# -> b, c, ..., f
|
|
392
|
+
hc = hc.transpose(1, -1)
|
|
393
|
+
h = hc.reshape(b, -1, *hc.shape[3:])
|
|
394
|
+
else:
|
|
395
|
+
# b, ..., vp, up
|
|
396
|
+
# -> b, ..., up, vp
|
|
397
|
+
# -> b, ..., c
|
|
398
|
+
hc = hc.transpose(-1, -2)
|
|
399
|
+
h = hc.reshape(*hc.shape[:-2], -1)
|
|
376
400
|
|
|
377
401
|
return self.drop(h * scale)
|
|
378
402
|
|
|
@@ -402,43 +426,44 @@ class LokrModule(LycorisBaseModule):
|
|
|
402
426
|
|
|
403
427
|
|
|
404
428
|
if __name__ == "__main__":
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
base
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
429
|
+
base = nn.Conv2d(128, 128, 3, 1, 1)
|
|
430
|
+
net = LokrModule(
|
|
431
|
+
"",
|
|
432
|
+
base,
|
|
433
|
+
multiplier=1,
|
|
434
|
+
lora_dim=4,
|
|
435
|
+
alpha=1,
|
|
436
|
+
weight_decompose=False,
|
|
437
|
+
use_tucker=False,
|
|
438
|
+
use_scalar=False,
|
|
439
|
+
decompose_both=True,
|
|
440
|
+
)
|
|
441
|
+
net.apply_to()
|
|
442
|
+
sd = net.state_dict()
|
|
443
|
+
for key in sd:
|
|
444
|
+
if key != "alpha":
|
|
445
|
+
sd[key] = torch.randn_like(sd[key])
|
|
446
|
+
net.load_state_dict(sd)
|
|
447
|
+
|
|
448
|
+
test_input = torch.randn(1, 128, 16, 16)
|
|
449
|
+
test_output = net(test_input)
|
|
450
|
+
print(test_output.shape)
|
|
451
|
+
|
|
452
|
+
net2 = LokrModule(
|
|
453
|
+
"",
|
|
454
|
+
base,
|
|
455
|
+
multiplier=1,
|
|
456
|
+
lora_dim=4,
|
|
457
|
+
alpha=1,
|
|
458
|
+
weight_decompose=False,
|
|
459
|
+
use_tucker=False,
|
|
460
|
+
use_scalar=False,
|
|
461
|
+
bypass_mode=True,
|
|
462
|
+
decompose_both=True,
|
|
463
|
+
)
|
|
464
|
+
net2.apply_to()
|
|
465
|
+
net2.load_state_dict(sd)
|
|
466
|
+
print(net2)
|
|
467
|
+
|
|
468
|
+
test_output2 = net(test_input)
|
|
469
|
+
print(F.mse_loss(test_output, test_output2))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lycoris_lora
|
|
3
|
-
Version: 3.0.0.
|
|
3
|
+
Version: 3.0.0.dev10
|
|
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="3.0.0.
|
|
7
|
+
version="3.0.0.dev10",
|
|
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",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lycoris_lora-3.0.0.dev8 → lycoris_lora-3.0.0.dev10}/lycoris_lora.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|