lycoris-lora 3.0.0.dev13__tar.gz → 3.0.0.dev15__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.dev13/lycoris_lora.egg-info → lycoris_lora-3.0.0.dev15}/PKG-INFO +1 -1
- lycoris_lora-3.0.0.dev15/lycoris/functional/__init__.py +9 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/functional/boft.py +14 -28
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/functional/diag_oft.py +10 -26
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/functional/general.py +27 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/functional/locon.py +6 -21
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/functional/loha.py +15 -34
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/functional/lokr.py +5 -24
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/base.py +2 -1
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/boft.py +1 -1
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/diag_oft.py +1 -1
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/glora.py +1 -1
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/loha.py +1 -1
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/utils/__init__.py +21 -158
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15/lycoris_lora.egg-info}/PKG-INFO +1 -1
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/setup.py +1 -1
- lycoris_lora-3.0.0.dev15/test/functional.py +87 -0
- lycoris_lora-3.0.0.dev13/lycoris/functional/__init__.py +0 -20
- lycoris_lora-3.0.0.dev13/test/functional.py +0 -71
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/LICENSE.md +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/README.md +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/config.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/kohya.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/logging.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/dylora.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/full.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/ia3.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/locon.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/lokr.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/modules/norms.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/utils/bnb.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/utils/general.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/utils/logger.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/utils/preset.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/utils/xformers_utils.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris/wrapper.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris_lora.egg-info/SOURCES.txt +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris_lora.egg-info/dependency_links.txt +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris_lora.egg-info/not-zip-safe +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris_lora.egg-info/requires.txt +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris_lora.egg-info/top_level.txt +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/setup.cfg +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/test/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/test/module.py +0 -0
- {lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/test/wrapper.py +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.dev15
|
|
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
|
|
@@ -10,7 +10,7 @@ from .general import power2factorization, FUNC_LIST
|
|
|
10
10
|
from .diag_oft import get_r
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def
|
|
13
|
+
def weight_gen(org_weight, max_block_size, boft_m=-1, rescale=False):
|
|
14
14
|
"""### boft_weight_gen
|
|
15
15
|
|
|
16
16
|
Args:
|
|
@@ -28,13 +28,13 @@ def boft_weight_gen(org_weight, max_block_size, boft_m=-1, rescale=False):
|
|
|
28
28
|
boft_m = max_boft_m
|
|
29
29
|
boft_m = min(boft_m, max_boft_m)
|
|
30
30
|
oft_blocks = torch.zeros(boft_m, block_num, block_size, block_size)
|
|
31
|
-
if rescale:
|
|
31
|
+
if rescale is not None:
|
|
32
32
|
return oft_blocks, torch.ones(out_dim, *[1] * len(rest))
|
|
33
33
|
else:
|
|
34
34
|
return oft_blocks, None
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def
|
|
37
|
+
def diff_weight(org_weight, oft_blocks, rescale=None, constraint=None):
|
|
38
38
|
"""### boft_diff_weight
|
|
39
39
|
|
|
40
40
|
Args:
|
|
@@ -57,11 +57,14 @@ def boft_diff_weight(org_weight, oft_blocks, rescale=None, constraint=None):
|
|
|
57
57
|
inp = rearrange(inp, "d b ... -> (d b) ...")
|
|
58
58
|
inp = rearrange(inp, "(c k g) ... -> (c g k) ...", g=2, k=2**i * r_b)
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
if rescale is not None:
|
|
61
|
+
inp = inp * rescale
|
|
61
62
|
|
|
63
|
+
return inp - org
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
|
|
66
|
+
def bypass_forward_diff(
|
|
67
|
+
org_out, oft_blocks, rescale=None, constraint=None, need_transpose=False
|
|
65
68
|
):
|
|
66
69
|
"""### boft_bypass_forward_diff
|
|
67
70
|
|
|
@@ -75,7 +78,7 @@ def boft_bypass_forward_diff(
|
|
|
75
78
|
r_b = b // 2
|
|
76
79
|
I = torch.eye(b, device=oft_blocks.device)
|
|
77
80
|
r = get_r(oft_blocks, I, constraint)
|
|
78
|
-
inp = org_out.to(dtype=r.dtype)
|
|
81
|
+
inp = org = org_out.to(dtype=r.dtype)
|
|
79
82
|
if need_transpose:
|
|
80
83
|
inp = org = inp.transpose(1, -1)
|
|
81
84
|
|
|
@@ -87,27 +90,10 @@ def boft_bypass_forward_diff(
|
|
|
87
90
|
inp = rearrange(inp, "... d b -> ... (d b)")
|
|
88
91
|
inp = rearrange(inp, "... (c k g) -> ... (c g k)", g=2, k=2**i * r_b)
|
|
89
92
|
|
|
90
|
-
|
|
93
|
+
if rescale is not None:
|
|
94
|
+
inp = inp * rescale.transpose(0, -1)
|
|
95
|
+
|
|
96
|
+
inp = inp - org
|
|
91
97
|
if need_transpose:
|
|
92
98
|
inp = inp.transpose(1, -1)
|
|
93
99
|
return inp
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if __name__ == "__main__":
|
|
97
|
-
w = torch.randn(32, 32, 3, 3, 3)
|
|
98
|
-
blocks, rescale = boft_weight_gen(w, 4, -1, True)
|
|
99
|
-
blocks = blocks + torch.randn_like(blocks) * 0.01
|
|
100
|
-
extra_args = {"padding": 1}
|
|
101
|
-
|
|
102
|
-
x = torch.randn(1, 32, 8, 8, 8)
|
|
103
|
-
y = FUNC_LIST[x.dim()](x, w, **extra_args)
|
|
104
|
-
diff_w = boft_diff_weight(w, blocks, rescale, 0.1)
|
|
105
|
-
diff_y_rebuild = FUNC_LIST[x.dim()](x, diff_w, **extra_args)
|
|
106
|
-
diff_y = boft_bypass_forward_diff(y, w.dim() > 2, blocks, rescale, 0.1)
|
|
107
|
-
|
|
108
|
-
print(y.shape, diff_y.shape, diff_y_rebuild.shape)
|
|
109
|
-
print(w.shape, diff_w.shape)
|
|
110
|
-
|
|
111
|
-
print(F.mse_loss(y, y + diff_y))
|
|
112
|
-
print(F.mse_loss(w, w + diff_w))
|
|
113
|
-
print(F.mse_loss(diff_y, diff_y_rebuild))
|
|
@@ -16,7 +16,7 @@ def get_r(oft_blocks, I=None, constraint=0):
|
|
|
16
16
|
# for Q = -Q^T
|
|
17
17
|
q = oft_blocks - oft_blocks.transpose(-1, -2)
|
|
18
18
|
normed_q = q
|
|
19
|
-
if constraint > 0:
|
|
19
|
+
if constraint is not None and constraint > 0:
|
|
20
20
|
q_norm = torch.norm(q) + 1e-8
|
|
21
21
|
if q_norm > constraint:
|
|
22
22
|
normed_q = q * constraint / q_norm
|
|
@@ -25,8 +25,8 @@ def get_r(oft_blocks, I=None, constraint=0):
|
|
|
25
25
|
return r
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def
|
|
29
|
-
"""###
|
|
28
|
+
def weight_gen(org_weight, max_block_size, rescale=False):
|
|
29
|
+
"""### weight_gen
|
|
30
30
|
|
|
31
31
|
Args:
|
|
32
32
|
org_weight (torch.Tensor): the weight tensor
|
|
@@ -45,8 +45,8 @@ def daig_oft_weight_gen(org_weight, max_block_size, rescale=False):
|
|
|
45
45
|
return oft_blocks, None
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
def
|
|
49
|
-
"""###
|
|
48
|
+
def diff_weight(org_weight, oft_blocks, rescale=None, constraint=None):
|
|
49
|
+
"""### diff_weight
|
|
50
50
|
|
|
51
51
|
Args:
|
|
52
52
|
TODO
|
|
@@ -67,16 +67,16 @@ def daig_oft_diff_weight(org_weight, oft_blocks, rescale=None, constraint=None):
|
|
|
67
67
|
r - I,
|
|
68
68
|
org_weight,
|
|
69
69
|
).view(-1, *shape)
|
|
70
|
-
if rescale is None:
|
|
70
|
+
if rescale is not None:
|
|
71
71
|
weight = rescale * weight
|
|
72
72
|
weight = weight + (rescale - 1) * org_weight
|
|
73
73
|
return weight
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
def
|
|
77
|
-
org_out,
|
|
76
|
+
def bypass_forward_diff(
|
|
77
|
+
org_out, oft_blocks, rescale=None, constraint=None, need_transpose=False
|
|
78
78
|
):
|
|
79
|
-
"""###
|
|
79
|
+
"""### bypass_forward_diff
|
|
80
80
|
|
|
81
81
|
Args:
|
|
82
82
|
TODO
|
|
@@ -89,6 +89,7 @@ def daig_oft_bypass_forward_diff(
|
|
|
89
89
|
r = get_r(oft_blocks, I, constraint)
|
|
90
90
|
if need_transpose:
|
|
91
91
|
org_out = org_out.transpose(1, -1)
|
|
92
|
+
org_out = org_out.to(dtype=r.dtype)
|
|
92
93
|
*shape, _ = org_out.shape
|
|
93
94
|
oft_out = torch.einsum(
|
|
94
95
|
"k n m, ... k n -> ... k m", r - I, org_out.view(*shape, block_num, block_size)
|
|
@@ -100,20 +101,3 @@ def daig_oft_bypass_forward_diff(
|
|
|
100
101
|
if need_transpose:
|
|
101
102
|
out = out.transpose(1, -1)
|
|
102
103
|
return out
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if __name__ == "__main__":
|
|
106
|
-
w = torch.randn(32, 32, 3, 3, 3)
|
|
107
|
-
blocks, rescale = daig_oft_weight_gen(w, 4, True)
|
|
108
|
-
blocks = blocks + torch.randn_like(blocks) * 0.01
|
|
109
|
-
extra_args = {"padding": 1}
|
|
110
|
-
|
|
111
|
-
x = torch.randn(1, 32, 8, 8, 8)
|
|
112
|
-
y = FUNC_LIST[x.dim()](x, w, **extra_args)
|
|
113
|
-
diff_w = daig_oft_diff_weight(w, blocks, rescale, 0.1)
|
|
114
|
-
diff_y_rebuild = FUNC_LIST[x.dim()](x, diff_w, **extra_args)
|
|
115
|
-
diff_y = daig_oft_bypass_forward_diff(y, w.dim() > 2, blocks, rescale, 0.1)
|
|
116
|
-
|
|
117
|
-
print(F.mse_loss(y, y + diff_y))
|
|
118
|
-
print(F.mse_loss(w, w + diff_w))
|
|
119
|
-
print(F.mse_loss(diff_y, diff_y_rebuild))
|
|
@@ -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
|
|
@@ -7,8 +7,8 @@ import torch.nn.functional as F
|
|
|
7
7
|
from .general import rebuild_tucker, FUNC_LIST
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
def
|
|
11
|
-
"""###
|
|
10
|
+
def weight_gen(org_weight, rank, tucker=True):
|
|
11
|
+
"""### weight_gen
|
|
12
12
|
|
|
13
13
|
Args:
|
|
14
14
|
org_weight (torch.Tensor): the weight tensor
|
|
@@ -34,8 +34,8 @@ def lora_weight_gen(org_weight, rank, tucker=True):
|
|
|
34
34
|
return down, up
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def
|
|
38
|
-
"""###
|
|
37
|
+
def diff_weight(d, u, m=None, gamma=1.0):
|
|
38
|
+
"""### diff_weight
|
|
39
39
|
|
|
40
40
|
Get ΔW = BA, where BA is low rank decomposition
|
|
41
41
|
|
|
@@ -62,8 +62,8 @@ def lora_diff_weight(d, u, m=None, gamma=1.0):
|
|
|
62
62
|
return result.reshape(O, I, *k)
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
def
|
|
66
|
-
"""###
|
|
65
|
+
def bypass_forward_diff(x, d, u, m=None, gamma=1.0, extra_args={}):
|
|
66
|
+
"""### bypass_forward_diff
|
|
67
67
|
|
|
68
68
|
Args:
|
|
69
69
|
x (torch.Tensor): input tensor
|
|
@@ -85,18 +85,3 @@ def lora_bypass_forward_diff(x, d, u, m=None, gamma=1.0, extra_args={}):
|
|
|
85
85
|
down = FUNC_LIST[d.dim()](x, d, **extra_args)
|
|
86
86
|
up = FUNC_LIST[d.dim()](down, u)
|
|
87
87
|
return up * gamma
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if __name__ == "__main__":
|
|
91
|
-
w = torch.randn(32, 32, 3, 3, 3)
|
|
92
|
-
d, u, m = lora_weight_gen(w, 4)
|
|
93
|
-
u = u + 0.01
|
|
94
|
-
extra_args = {"padding": 1}
|
|
95
|
-
|
|
96
|
-
x = torch.randn(1, 32, 8, 8, 8)
|
|
97
|
-
y = FUNC_LIST[d.dim()](x, w, **extra_args)
|
|
98
|
-
diff_w = lora_diff_weight(d, u, m, 1)
|
|
99
|
-
diff_y = lora_bypass_forward_diff(x, d, u, m, 1, extra_args)
|
|
100
|
-
|
|
101
|
-
print(F.mse_loss(y, y + diff_y))
|
|
102
|
-
print(F.mse_loss(w, w + diff_w))
|
|
@@ -83,8 +83,8 @@ def make_weight_tucker(t1, w1d, w1u, t2, w2d, w2u, scale):
|
|
|
83
83
|
return HadaWeightTucker.apply(t1, w1d, w1u, t2, w2d, w2u, scale)
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
def
|
|
87
|
-
"""###
|
|
86
|
+
def weight_gen(org_weight, rank, tucker=True):
|
|
87
|
+
"""### weight_gen
|
|
88
88
|
|
|
89
89
|
Args:
|
|
90
90
|
org_weight (torch.Tensor): the weight tensor
|
|
@@ -101,27 +101,23 @@ def loha_weight_gen(org_weight, rank, tucker=True):
|
|
|
101
101
|
w2d = torch.empty(rank, in_dim)
|
|
102
102
|
w2u = torch.empty(rank, out_dim)
|
|
103
103
|
t2 = torch.empty(rank, rank, *k)
|
|
104
|
-
nn.init.normal_(w1d, std=1)
|
|
105
|
-
nn.init.constant_(w1u, 0)
|
|
106
|
-
nn.init.normal_(w2d, std=1)
|
|
107
|
-
nn.init.normal_(w2u, std=0.1)
|
|
108
104
|
nn.init.normal_(t1, std=0.1)
|
|
109
105
|
nn.init.normal_(t2, std=0.1)
|
|
110
|
-
return w1d, w2d, w1u, w2u, t1, t2
|
|
111
106
|
else:
|
|
112
107
|
w1d = torch.empty(rank, in_dim)
|
|
113
|
-
w1u = torch.empty(
|
|
108
|
+
w1u = torch.empty(out_dim, rank)
|
|
114
109
|
w2d = torch.empty(rank, in_dim)
|
|
115
|
-
w2u = torch.empty(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
110
|
+
w2u = torch.empty(out_dim, rank)
|
|
111
|
+
t1 = t2 = None
|
|
112
|
+
nn.init.normal_(w1d, std=1)
|
|
113
|
+
nn.init.constant_(w1u, 0)
|
|
114
|
+
nn.init.normal_(w2d, std=1)
|
|
115
|
+
nn.init.normal_(w2u, std=0.1)
|
|
116
|
+
return w1d, w1u, w2d, w2u, t1, t2
|
|
121
117
|
|
|
122
118
|
|
|
123
|
-
def
|
|
124
|
-
"""###
|
|
119
|
+
def diff_weight(w1d, w1u, w2d, w2u, t1=None, t2=None, gamma=1.0):
|
|
120
|
+
"""### diff_weight
|
|
125
121
|
|
|
126
122
|
Get ΔW = BA, where BA is low rank decomposition
|
|
127
123
|
|
|
@@ -152,10 +148,10 @@ def loha_diff_weight(w1d, w1u, w2d, w2u, t1=None, t2=None, gamma=1.0):
|
|
|
152
148
|
return result
|
|
153
149
|
|
|
154
150
|
|
|
155
|
-
def
|
|
151
|
+
def bypass_forward_diff(
|
|
156
152
|
x, w1d, w1u, w2d, w2u, t1=None, t2=None, gamma=1.0, extra_args={}
|
|
157
153
|
):
|
|
158
|
-
"""###
|
|
154
|
+
"""### bypass_forward_diff
|
|
159
155
|
|
|
160
156
|
Args:
|
|
161
157
|
x (torch.Tensor): input tensor
|
|
@@ -168,20 +164,5 @@ def loha_bypass_forward_diff(
|
|
|
168
164
|
Returns:
|
|
169
165
|
torch.Tensor: output tensor
|
|
170
166
|
"""
|
|
171
|
-
diff_w =
|
|
167
|
+
diff_w = diff_weight(w1d, w1u, w2d, w2u, t1, t2, gamma)
|
|
172
168
|
return FUNC_LIST[w1d.dim() if t1 is None else t1.dim()](x, diff_w, **extra_args)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if __name__ == "__main__":
|
|
176
|
-
w = torch.randn(128, 128, 3, 3, 3)
|
|
177
|
-
w1d, w2d, w1u, w2u, t1, t2 = loha_weight_gen(w, 4, tucker=True)
|
|
178
|
-
w1u += 0.01
|
|
179
|
-
extra_args = {"padding": 1}
|
|
180
|
-
|
|
181
|
-
x = torch.randn(1, 128, 8, 8, 8)
|
|
182
|
-
y = FUNC_LIST[w.dim()](x, w, **extra_args)
|
|
183
|
-
diff_w = loha_diff_weight(w1d, w2d, w1u, w2u, t1, t2, 1)
|
|
184
|
-
diff_y = loha_bypass_forward_diff(x, w1d, w2d, w1u, w2u, t1, t2, 1, extra_args)
|
|
185
|
-
|
|
186
|
-
print(F.mse_loss(y, y + diff_y))
|
|
187
|
-
print(F.mse_loss(w, w + diff_w))
|
|
@@ -17,7 +17,7 @@ def make_kron(w1, w2, scale):
|
|
|
17
17
|
return rebuild * scale
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def
|
|
20
|
+
def weight_gen(
|
|
21
21
|
org_weight,
|
|
22
22
|
rank,
|
|
23
23
|
tucker=True,
|
|
@@ -118,8 +118,8 @@ def lokr_weight_gen(
|
|
|
118
118
|
return w1, w1a, w1b, w2, w2a, w2b, t2
|
|
119
119
|
|
|
120
120
|
|
|
121
|
-
def
|
|
122
|
-
"""###
|
|
121
|
+
def diff_weight(w1, w1a, w1b, w2, w2a, w2b, t, gamma=1.0):
|
|
122
|
+
"""### diff_weight
|
|
123
123
|
|
|
124
124
|
Args:
|
|
125
125
|
gamma (float, optional): scale factor, normally alpha/rank here
|
|
@@ -146,10 +146,8 @@ def lokr_diff_weight(w1, w1a, w1b, w2, w2a, w2b, t, gamma=1.0):
|
|
|
146
146
|
return make_kron(w1, w2, scale)
|
|
147
147
|
|
|
148
148
|
|
|
149
|
-
def
|
|
150
|
-
|
|
151
|
-
):
|
|
152
|
-
"""### lokr_bypass_forward_diff
|
|
149
|
+
def bypass_forward_diff(h, w1, w1a, w1b, w2, w2a, w2b, t, gamma=1.0, extra_args={}):
|
|
150
|
+
"""### bypass_forward_diff
|
|
153
151
|
|
|
154
152
|
Args:
|
|
155
153
|
gamma (float, optional): scale factor, normally alpha/rank here
|
|
@@ -163,7 +161,6 @@ def lokr_bypass_forward_diff(
|
|
|
163
161
|
use_w2 = w2 is not None
|
|
164
162
|
tucker = t is not None
|
|
165
163
|
dim = t.dim() if tucker else w2.dim() if w2 is not None else w2b.dim()
|
|
166
|
-
print(dim)
|
|
167
164
|
rank = w1b.size(0) if not use_w1 else w2b.size(0) if not use_w2 else gamma
|
|
168
165
|
scale = gamma / rank
|
|
169
166
|
is_conv = dim > 2
|
|
@@ -241,19 +238,3 @@ def lokr_bypass_forward_diff(
|
|
|
241
238
|
h = hc.reshape(*hc.shape[:-2], -1)
|
|
242
239
|
|
|
243
240
|
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 = lokr_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))
|
|
@@ -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
|
-
|
|
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.
|
|
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}:
|
|
@@ -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
|
-
|
|
537
|
-
|
|
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
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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")
|
|
@@ -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.dev15
|
|
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.dev15",
|
|
8
8
|
url="https://github.com/KohakuBlueleaf/LyCORIS",
|
|
9
9
|
description="Lora beYond Conventional methods, Other Rank adaptation Implementations for Stable diffusion",
|
|
10
10
|
author="Shih-Ying Yeh(KohakuBlueLeaf), Yu-Guan Hsieh, Zhidong Gao",
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from itertools import product
|
|
3
|
+
from parameterized import parameterized
|
|
4
|
+
|
|
5
|
+
import torch
|
|
6
|
+
import torch.nn as nn
|
|
7
|
+
import torch.nn.functional as F
|
|
8
|
+
|
|
9
|
+
from lycoris.functional import locon, loha, lokr, diag_oft, boft
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
EPS_DTYPE = {
|
|
13
|
+
torch.float32: 5e-6,
|
|
14
|
+
torch.float16: 5e-5,
|
|
15
|
+
torch.bfloat16: 5e-4,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
modules = [locon, loha, lokr, diag_oft, boft]
|
|
20
|
+
base_module_and_input_adn_weight = [
|
|
21
|
+
lambda dim: (F.linear, torch.randn(dim, dim), torch.randn(1, dim)),
|
|
22
|
+
lambda dim: (F.conv1d, torch.randn(dim, dim, 3), torch.randn(1, dim, 16)),
|
|
23
|
+
lambda dim: (F.conv2d, torch.randn(dim, dim, 3, 3), torch.randn(1, dim, 16, 16)),
|
|
24
|
+
lambda dim: (
|
|
25
|
+
F.conv3d,
|
|
26
|
+
torch.randn(dim, dim, 3, 3, 3),
|
|
27
|
+
torch.randn(1, dim, 16, 16, 16),
|
|
28
|
+
),
|
|
29
|
+
]
|
|
30
|
+
device_and_dtype = [
|
|
31
|
+
(torch.device("cpu"), torch.float32),
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
if torch.cuda.is_available():
|
|
35
|
+
device_and_dtype.append((torch.device("cuda"), torch.float32))
|
|
36
|
+
device_and_dtype.append((torch.device("cuda"), torch.float16))
|
|
37
|
+
device_and_dtype.append((torch.device("cuda"), torch.bfloat16))
|
|
38
|
+
|
|
39
|
+
if torch.backends.mps.is_available():
|
|
40
|
+
device_and_dtype.append((torch.device("mps"), torch.float32))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
patch_forward_param_list = list(
|
|
44
|
+
product(
|
|
45
|
+
modules,
|
|
46
|
+
base_module_and_input_adn_weight,
|
|
47
|
+
device_and_dtype,
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class LycorisFunctionalTests(unittest.TestCase):
|
|
53
|
+
@parameterized.expand(patch_forward_param_list)
|
|
54
|
+
def test_lycoris_functional(self, module, base, device_dtype):
|
|
55
|
+
func, test_weight, test_input = base(16)
|
|
56
|
+
device, dtype = device_dtype
|
|
57
|
+
print(
|
|
58
|
+
f"{module.__name__: <27}",
|
|
59
|
+
f"{func.__name__: <7}",
|
|
60
|
+
f"device={str(device): <5}",
|
|
61
|
+
f"dtype={str(dtype): <15}",
|
|
62
|
+
sep="||",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
w = test_weight.to(device, dtype)
|
|
66
|
+
x = test_input.to(device, dtype)
|
|
67
|
+
y = func(x, w)
|
|
68
|
+
|
|
69
|
+
params = list(module.weight_gen(w, 4))
|
|
70
|
+
for idx, param in enumerate(params):
|
|
71
|
+
if param is not None:
|
|
72
|
+
param = param.to(device, dtype)
|
|
73
|
+
params[idx] = param + torch.randn_like(param) * 0.01
|
|
74
|
+
|
|
75
|
+
if module in {boft, diag_oft}:
|
|
76
|
+
diff_w = module.diff_weight(w, *params)
|
|
77
|
+
diff_y = module.bypass_forward_diff(y, *params, need_transpose=w.ndim > 2)
|
|
78
|
+
else:
|
|
79
|
+
diff_w = module.diff_weight(*params)
|
|
80
|
+
diff_y = module.bypass_forward_diff(x, *params)
|
|
81
|
+
|
|
82
|
+
diff_y_from_diff_w = func(x, diff_w.to(x))
|
|
83
|
+
self.assertTrue(
|
|
84
|
+
F.mse_loss(diff_y, diff_y_from_diff_w).item() < EPS_DTYPE[dtype],
|
|
85
|
+
f"Error: {module.__name__} {base.__name__} {device} {dtype} ||"
|
|
86
|
+
f"{F.mse_loss(diff_y, diff_y_from_diff_w).item()}",
|
|
87
|
+
)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from .general import (
|
|
2
|
-
rebuild_tucker,
|
|
3
|
-
factorization,
|
|
4
|
-
power2factorization,
|
|
5
|
-
)
|
|
6
|
-
from .locon import (
|
|
7
|
-
lora_weight_gen,
|
|
8
|
-
lora_diff_weight,
|
|
9
|
-
lora_bypass_forward_diff,
|
|
10
|
-
)
|
|
11
|
-
from .loha import (
|
|
12
|
-
loha_weight_gen,
|
|
13
|
-
loha_diff_weight,
|
|
14
|
-
loha_bypass_forward_diff,
|
|
15
|
-
)
|
|
16
|
-
from .lokr import (
|
|
17
|
-
lokr_weight_gen,
|
|
18
|
-
lokr_diff_weight,
|
|
19
|
-
lokr_bypass_forward_diff,
|
|
20
|
-
)
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
from itertools import product
|
|
3
|
-
from parameterized import parameterized
|
|
4
|
-
|
|
5
|
-
import torch
|
|
6
|
-
import torch.nn as nn
|
|
7
|
-
|
|
8
|
-
from lycoris.modules import (
|
|
9
|
-
LycorisBaseModule,
|
|
10
|
-
LoConModule,
|
|
11
|
-
LohaModule,
|
|
12
|
-
LokrModule,
|
|
13
|
-
FullModule,
|
|
14
|
-
DiagOFTModule,
|
|
15
|
-
ButterflyOFTModule,
|
|
16
|
-
GLoRAModule,
|
|
17
|
-
DyLoraModule,
|
|
18
|
-
IA3Module,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
modules: list[LycorisBaseModule] = [
|
|
23
|
-
LoConModule,
|
|
24
|
-
LohaModule,
|
|
25
|
-
LokrModule,
|
|
26
|
-
FullModule,
|
|
27
|
-
DiagOFTModule,
|
|
28
|
-
ButterflyOFTModule,
|
|
29
|
-
GLoRAModule,
|
|
30
|
-
DyLoraModule,
|
|
31
|
-
IA3Module,
|
|
32
|
-
]
|
|
33
|
-
base_module_and_input = [
|
|
34
|
-
lambda dim: (nn.Linear(dim, dim), torch.randn(1, dim)),
|
|
35
|
-
lambda dim: (nn.Conv1d(dim, dim, 3, 1, 1), torch.randn(1, dim, 16)),
|
|
36
|
-
lambda dim: (nn.Conv2d(dim, dim, (3, 3), 1, 1), torch.randn(1, dim, 16, 16)),
|
|
37
|
-
# lambda dim: (nn.Conv3d(dim, dim, (3, 3, 3), 1, 1), torch.randn(1, dim, 16, 16, 16)),
|
|
38
|
-
]
|
|
39
|
-
device_and_dtype = [
|
|
40
|
-
(torch.device("cpu"), torch.float32),
|
|
41
|
-
]
|
|
42
|
-
weight_decompose = [False, True]
|
|
43
|
-
use_tucker = [False, True]
|
|
44
|
-
use_scalar = [False, True]
|
|
45
|
-
|
|
46
|
-
if torch.cuda.is_available():
|
|
47
|
-
device_and_dtype.append((torch.device("cuda"), torch.float32))
|
|
48
|
-
device_and_dtype.append((torch.device("cuda"), torch.float16))
|
|
49
|
-
device_and_dtype.append((torch.device("cuda"), torch.bfloat16))
|
|
50
|
-
|
|
51
|
-
if torch.backends.mps.is_available():
|
|
52
|
-
device_and_dtype.append((torch.device("mps"), torch.float32))
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
patch_forward_param_list = list(
|
|
56
|
-
product(
|
|
57
|
-
modules,
|
|
58
|
-
base_module_and_input,
|
|
59
|
-
device_and_dtype,
|
|
60
|
-
weight_decompose,
|
|
61
|
-
use_tucker,
|
|
62
|
-
use_scalar,
|
|
63
|
-
)
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class LycorisModuleTests(unittest.TestCase):
|
|
68
|
-
@parameterized.expand(patch_forward_param_list)
|
|
69
|
-
def test_lycoris_functional(self, module, base, device_dtype, wd, tucker, scalar):
|
|
70
|
-
base, test_input = base(16)
|
|
71
|
-
device, dtype = device_dtype
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lycoris_lora-3.0.0.dev13 → lycoris_lora-3.0.0.dev15}/lycoris_lora.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|