lycoris-lora 3.0.0.dev11__tar.gz → 3.0.0.dev13__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.dev11/lycoris_lora.egg-info → lycoris_lora-3.0.0.dev13}/PKG-INFO +1 -1
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/config.py +11 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/functional/__init__.py +7 -0
- lycoris_lora-3.0.0.dev13/lycoris/functional/boft.py +113 -0
- lycoris_lora-3.0.0.dev13/lycoris/functional/diag_oft.py +119 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/functional/lokr.py +2 -2
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/kohya.py +61 -314
- lycoris_lora-3.0.0.dev13/lycoris/modules/__init__.py +46 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/base.py +15 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/boft.py +61 -20
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/diag_oft.py +42 -9
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/full.py +23 -8
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/glora.py +62 -3
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/ia3.py +13 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/locon.py +30 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/loha.py +36 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/lokr.py +98 -2
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/norms.py +15 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/utils/__init__.py +0 -49
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/wrapper.py +40 -43
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13/lycoris_lora.egg-info}/PKG-INFO +1 -1
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris_lora.egg-info/SOURCES.txt +7 -1
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris_lora.egg-info/top_level.txt +1 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/setup.py +1 -1
- lycoris_lora-3.0.0.dev13/test/__init__.py +0 -0
- lycoris_lora-3.0.0.dev13/test/functional.py +71 -0
- lycoris_lora-3.0.0.dev13/test/module.py +181 -0
- lycoris_lora-3.0.0.dev13/test/wrapper.py +128 -0
- lycoris_lora-3.0.0.dev11/lycoris/modules/__init__.py +0 -147
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/LICENSE.md +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/README.md +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/functional/general.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/functional/locon.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/functional/loha.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/logging.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/modules/dylora.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/utils/bnb.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/utils/general.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/utils/logger.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/utils/preset.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris/utils/xformers_utils.py +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris_lora.egg-info/dependency_links.txt +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris_lora.egg-info/not-zip-safe +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/lycoris_lora.egg-info/requires.txt +0 -0
- {lycoris_lora-3.0.0.dev11 → lycoris_lora-3.0.0.dev13}/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.dev13
|
|
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
|
|
@@ -108,4 +108,15 @@ PRESET = {
|
|
|
108
108
|
"text_encoder_target_module": [],
|
|
109
109
|
"text_encoder_target_name": [],
|
|
110
110
|
},
|
|
111
|
+
"ia3": {
|
|
112
|
+
"enable_conv": False,
|
|
113
|
+
"unet_target_module": [],
|
|
114
|
+
"unet_target_name": ["to_k", "to_v", "ff.net.2"],
|
|
115
|
+
"text_encoder_target_module": [],
|
|
116
|
+
"text_encoder_target_name": ["k_proj", "v_proj", "mlp.fc2"],
|
|
117
|
+
"name_algo_map": {
|
|
118
|
+
"mlp.fc2": {"train_on_input": True},
|
|
119
|
+
"ff.net.2": {"train_on_input": True},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
111
122
|
}
|
|
@@ -4,10 +4,17 @@ from .general import (
|
|
|
4
4
|
power2factorization,
|
|
5
5
|
)
|
|
6
6
|
from .locon import (
|
|
7
|
+
lora_weight_gen,
|
|
7
8
|
lora_diff_weight,
|
|
8
9
|
lora_bypass_forward_diff,
|
|
9
10
|
)
|
|
10
11
|
from .loha import (
|
|
12
|
+
loha_weight_gen,
|
|
11
13
|
loha_diff_weight,
|
|
12
14
|
loha_bypass_forward_diff,
|
|
13
15
|
)
|
|
16
|
+
from .lokr import (
|
|
17
|
+
lokr_weight_gen,
|
|
18
|
+
lokr_diff_weight,
|
|
19
|
+
lokr_bypass_forward_diff,
|
|
20
|
+
)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import torch
|
|
4
|
+
import torch.nn as nn
|
|
5
|
+
import torch.nn.functional as F
|
|
6
|
+
|
|
7
|
+
from einops import rearrange
|
|
8
|
+
|
|
9
|
+
from .general import power2factorization, FUNC_LIST
|
|
10
|
+
from .diag_oft import get_r
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def boft_weight_gen(org_weight, max_block_size, boft_m=-1, rescale=False):
|
|
14
|
+
"""### boft_weight_gen
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
org_weight (torch.Tensor): the weight tensor
|
|
18
|
+
max_block_size (int): max block size
|
|
19
|
+
rescale (bool, optional): whether to rescale the weight. Defaults to False.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
torch.Tensor: oft_blocks[, rescale_weight]
|
|
23
|
+
"""
|
|
24
|
+
out_dim, *rest = org_weight.shape
|
|
25
|
+
block_size, block_num = power2factorization(out_dim, max_block_size)
|
|
26
|
+
max_boft_m = sum(int(i) for i in f"{block_num-1:b}") + 1
|
|
27
|
+
if boft_m == -1:
|
|
28
|
+
boft_m = max_boft_m
|
|
29
|
+
boft_m = min(boft_m, max_boft_m)
|
|
30
|
+
oft_blocks = torch.zeros(boft_m, block_num, block_size, block_size)
|
|
31
|
+
if rescale:
|
|
32
|
+
return oft_blocks, torch.ones(out_dim, *[1] * len(rest))
|
|
33
|
+
else:
|
|
34
|
+
return oft_blocks, None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def boft_diff_weight(org_weight, oft_blocks, rescale=None, constraint=None):
|
|
38
|
+
"""### boft_diff_weight
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
TODO
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
torch.Tensor: ΔW
|
|
45
|
+
"""
|
|
46
|
+
m, num, b, _ = oft_blocks.shape
|
|
47
|
+
r_b = b // 2
|
|
48
|
+
I = torch.eye(b, device=oft_blocks.device)
|
|
49
|
+
r = get_r(oft_blocks, I, constraint)
|
|
50
|
+
inp = org = org_weight.to(dtype=r.dtype)
|
|
51
|
+
|
|
52
|
+
for i in range(m):
|
|
53
|
+
bi = r[i] # b_num, b_size, b_size
|
|
54
|
+
inp = rearrange(inp, "(c g k) ... -> (c k g) ...", g=2, k=2**i * r_b)
|
|
55
|
+
inp = rearrange(inp, "(d b) ... -> d b ...", b=b)
|
|
56
|
+
inp = torch.einsum("b i j, b j ... -> b i ...", bi, inp)
|
|
57
|
+
inp = rearrange(inp, "d b ... -> (d b) ...")
|
|
58
|
+
inp = rearrange(inp, "(c k g) ... -> (c g k) ...", g=2, k=2**i * r_b)
|
|
59
|
+
|
|
60
|
+
return inp * rescale - org
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def boft_bypass_forward_diff(
|
|
64
|
+
org_out, need_transpose, oft_blocks, rescale=None, constraint=None
|
|
65
|
+
):
|
|
66
|
+
"""### boft_bypass_forward_diff
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
TODO
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
torch.Tensor: output tensor
|
|
73
|
+
"""
|
|
74
|
+
m, num, b, _ = oft_blocks.shape
|
|
75
|
+
r_b = b // 2
|
|
76
|
+
I = torch.eye(b, device=oft_blocks.device)
|
|
77
|
+
r = get_r(oft_blocks, I, constraint)
|
|
78
|
+
inp = org_out.to(dtype=r.dtype)
|
|
79
|
+
if need_transpose:
|
|
80
|
+
inp = org = inp.transpose(1, -1)
|
|
81
|
+
|
|
82
|
+
for i in range(m):
|
|
83
|
+
bi = r[i] # b_num, b_size, b_size
|
|
84
|
+
inp = rearrange(inp, "... (c g k) ->... (c k g)", g=2, k=2**i * r_b)
|
|
85
|
+
inp = rearrange(inp, "... (d b) -> ... d b", b=b)
|
|
86
|
+
inp = torch.einsum("b i j, ... b j -> ... b i", bi, inp)
|
|
87
|
+
inp = rearrange(inp, "... d b -> ... (d b)")
|
|
88
|
+
inp = rearrange(inp, "... (c k g) -> ... (c g k)", g=2, k=2**i * r_b)
|
|
89
|
+
|
|
90
|
+
inp = inp * rescale.transpose(0, -1) - org
|
|
91
|
+
if need_transpose:
|
|
92
|
+
inp = inp.transpose(1, -1)
|
|
93
|
+
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))
|
|
@@ -0,0 +1,119 @@
|
|
|
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 factorization, FUNC_LIST
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_r(oft_blocks, I=None, constraint=0):
|
|
11
|
+
if I is None:
|
|
12
|
+
I = torch.eye(oft_blocks.shape[-1], device=oft_blocks.device)
|
|
13
|
+
if I.ndim < oft_blocks.ndim:
|
|
14
|
+
for _ in range(oft_blocks.ndim - I.ndim):
|
|
15
|
+
I = I.unsqueeze(0)
|
|
16
|
+
# for Q = -Q^T
|
|
17
|
+
q = oft_blocks - oft_blocks.transpose(-1, -2)
|
|
18
|
+
normed_q = q
|
|
19
|
+
if constraint > 0:
|
|
20
|
+
q_norm = torch.norm(q) + 1e-8
|
|
21
|
+
if q_norm > constraint:
|
|
22
|
+
normed_q = q * constraint / q_norm
|
|
23
|
+
# use float() to prevent unsupported type
|
|
24
|
+
r = (I + normed_q) @ (I - normed_q).float().inverse()
|
|
25
|
+
return r
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def daig_oft_weight_gen(org_weight, max_block_size, rescale=False):
|
|
29
|
+
"""### daig_oft_weight_gen
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
org_weight (torch.Tensor): the weight tensor
|
|
33
|
+
max_block_size (int): max block size
|
|
34
|
+
rescale (bool, optional): whether to rescale the weight. Defaults to False.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
torch.Tensor: oft_blocks[, rescale_weight]
|
|
38
|
+
"""
|
|
39
|
+
out_dim, *rest = org_weight.shape
|
|
40
|
+
block_size, block_num = factorization(out_dim, max_block_size)
|
|
41
|
+
oft_blocks = torch.zeros(block_num, block_size, block_size)
|
|
42
|
+
if rescale:
|
|
43
|
+
return oft_blocks, torch.ones(out_dim, *[1] * len(rest))
|
|
44
|
+
else:
|
|
45
|
+
return oft_blocks, None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def daig_oft_diff_weight(org_weight, oft_blocks, rescale=None, constraint=None):
|
|
49
|
+
"""### daig_oft_diff_weight
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
TODO
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
torch.Tensor: ΔW
|
|
56
|
+
"""
|
|
57
|
+
I = torch.eye(oft_blocks.shape[1], device=oft_blocks.device)
|
|
58
|
+
r = get_r(oft_blocks, I, constraint)
|
|
59
|
+
|
|
60
|
+
block_num, block_size, _ = oft_blocks.shape
|
|
61
|
+
_, *shape = org_weight.shape
|
|
62
|
+
org_weight = org_weight.to(dtype=r.dtype)
|
|
63
|
+
org_weight = org_weight.view(block_num, block_size, *shape)
|
|
64
|
+
# Init R=0, so add I on it to ensure the output of step0 is original model output
|
|
65
|
+
weight = torch.einsum(
|
|
66
|
+
"k n m, k n ... -> k m ...",
|
|
67
|
+
r - I,
|
|
68
|
+
org_weight,
|
|
69
|
+
).view(-1, *shape)
|
|
70
|
+
if rescale is None:
|
|
71
|
+
weight = rescale * weight
|
|
72
|
+
weight = weight + (rescale - 1) * org_weight
|
|
73
|
+
return weight
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def daig_oft_bypass_forward_diff(
|
|
77
|
+
org_out, need_transpose, oft_blocks, rescale=None, constraint=None
|
|
78
|
+
):
|
|
79
|
+
"""### daig_oft_bypass_forward_diff
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
TODO
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
torch.Tensor: output tensor
|
|
86
|
+
"""
|
|
87
|
+
block_num, block_size, _ = oft_blocks.shape
|
|
88
|
+
I = torch.eye(block_size, device=oft_blocks.device)
|
|
89
|
+
r = get_r(oft_blocks, I, constraint)
|
|
90
|
+
if need_transpose:
|
|
91
|
+
org_out = org_out.transpose(1, -1)
|
|
92
|
+
*shape, _ = org_out.shape
|
|
93
|
+
oft_out = torch.einsum(
|
|
94
|
+
"k n m, ... k n -> ... k m", r - I, org_out.view(*shape, block_num, block_size)
|
|
95
|
+
)
|
|
96
|
+
out = oft_out.view(*shape, -1)
|
|
97
|
+
if rescale is not None:
|
|
98
|
+
out = rescale.transpose(-1, 0) * out
|
|
99
|
+
out = out + (rescale - 1).transpose(-1, 0) * org_out
|
|
100
|
+
if need_transpose:
|
|
101
|
+
out = out.transpose(1, -1)
|
|
102
|
+
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))
|
|
@@ -17,7 +17,7 @@ def make_kron(w1, w2, scale):
|
|
|
17
17
|
return rebuild * scale
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def
|
|
20
|
+
def lokr_weight_gen(
|
|
21
21
|
org_weight,
|
|
22
22
|
rank,
|
|
23
23
|
tucker=True,
|
|
@@ -245,7 +245,7 @@ def lokr_bypass_forward_diff(
|
|
|
245
245
|
|
|
246
246
|
if __name__ == "__main__":
|
|
247
247
|
w = torch.randn(32, 32, 3, 3, 3)
|
|
248
|
-
w1, w1a, w1b, w2, w2a, w2b, t =
|
|
248
|
+
w1, w1a, w1b, w2, w2a, w2b, t = lokr_weight_gen(w, 2, tucker=False)
|
|
249
249
|
extra_args = {"padding": 1}
|
|
250
250
|
|
|
251
251
|
x = torch.randn(1, 32, 8, 8, 8)
|