lycoris-lora 3.0.0.dev12__tar.gz → 3.0.0.dev14__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.dev12/lycoris_lora.egg-info → lycoris_lora-3.0.0.dev14}/PKG-INFO +1 -1
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/config.py +11 -0
- lycoris_lora-3.0.0.dev14/lycoris/functional/__init__.py +1 -0
- lycoris_lora-3.0.0.dev14/lycoris/functional/boft.py +99 -0
- lycoris_lora-3.0.0.dev14/lycoris/functional/diag_oft.py +103 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/functional/locon.py +6 -21
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/functional/loha.py +15 -34
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/functional/lokr.py +4 -23
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/kohya.py +61 -314
- lycoris_lora-3.0.0.dev14/lycoris/modules/__init__.py +46 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/base.py +15 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/boft.py +61 -20
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/diag_oft.py +42 -9
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/full.py +23 -8
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/glora.py +62 -3
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/ia3.py +13 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/locon.py +30 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/loha.py +37 -1
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/lokr.py +92 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/norms.py +15 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/utils/__init__.py +0 -49
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/wrapper.py +40 -43
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14/lycoris_lora.egg-info}/PKG-INFO +1 -1
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris_lora.egg-info/SOURCES.txt +7 -1
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris_lora.egg-info/top_level.txt +1 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/setup.py +1 -1
- lycoris_lora-3.0.0.dev14/test/__init__.py +0 -0
- lycoris_lora-3.0.0.dev14/test/functional.py +87 -0
- lycoris_lora-3.0.0.dev14/test/module.py +181 -0
- lycoris_lora-3.0.0.dev14/test/wrapper.py +128 -0
- lycoris_lora-3.0.0.dev12/lycoris/functional/__init__.py +0 -13
- lycoris_lora-3.0.0.dev12/lycoris/modules/__init__.py +0 -148
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/LICENSE.md +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/README.md +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/functional/general.py +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/logging.py +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/modules/dylora.py +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/utils/bnb.py +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/utils/general.py +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/utils/logger.py +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/utils/preset.py +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris/utils/xformers_utils.py +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris_lora.egg-info/dependency_links.txt +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris_lora.egg-info/not-zip-safe +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/lycoris_lora.egg-info/requires.txt +0 -0
- {lycoris_lora-3.0.0.dev12 → lycoris_lora-3.0.0.dev14}/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.dev14
|
|
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
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .general import rebuild_tucker, factorization, power2factorization, FUNC_LIST
|
|
@@ -0,0 +1,99 @@
|
|
|
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 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 is not None:
|
|
32
|
+
return oft_blocks, torch.ones(out_dim, *[1] * len(rest))
|
|
33
|
+
else:
|
|
34
|
+
return oft_blocks, None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def 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
|
+
if rescale is not None:
|
|
61
|
+
inp = inp * rescale
|
|
62
|
+
|
|
63
|
+
return inp - org
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def bypass_forward_diff(
|
|
67
|
+
org_out, oft_blocks, rescale=None, constraint=None, need_transpose=False
|
|
68
|
+
):
|
|
69
|
+
"""### boft_bypass_forward_diff
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
TODO
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
torch.Tensor: output tensor
|
|
76
|
+
"""
|
|
77
|
+
m, num, b, _ = oft_blocks.shape
|
|
78
|
+
r_b = b // 2
|
|
79
|
+
I = torch.eye(b, device=oft_blocks.device)
|
|
80
|
+
r = get_r(oft_blocks, I, constraint)
|
|
81
|
+
inp = org = org_out.to(dtype=r.dtype)
|
|
82
|
+
if need_transpose:
|
|
83
|
+
inp = org = inp.transpose(1, -1)
|
|
84
|
+
|
|
85
|
+
for i in range(m):
|
|
86
|
+
bi = r[i] # b_num, b_size, b_size
|
|
87
|
+
inp = rearrange(inp, "... (c g k) ->... (c k g)", g=2, k=2**i * r_b)
|
|
88
|
+
inp = rearrange(inp, "... (d b) -> ... d b", b=b)
|
|
89
|
+
inp = torch.einsum("b i j, ... b j -> ... b i", bi, inp)
|
|
90
|
+
inp = rearrange(inp, "... d b -> ... (d b)")
|
|
91
|
+
inp = rearrange(inp, "... (c k g) -> ... (c g k)", g=2, k=2**i * r_b)
|
|
92
|
+
|
|
93
|
+
if rescale is not None:
|
|
94
|
+
inp = inp * rescale.transpose(0, -1)
|
|
95
|
+
|
|
96
|
+
inp = inp - org
|
|
97
|
+
if need_transpose:
|
|
98
|
+
inp = inp.transpose(1, -1)
|
|
99
|
+
return inp
|
|
@@ -0,0 +1,103 @@
|
|
|
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 is not None and 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 weight_gen(org_weight, max_block_size, rescale=False):
|
|
29
|
+
"""### 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 diff_weight(org_weight, oft_blocks, rescale=None, constraint=None):
|
|
49
|
+
"""### 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 not None:
|
|
71
|
+
weight = rescale * weight
|
|
72
|
+
weight = weight + (rescale - 1) * org_weight
|
|
73
|
+
return weight
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def bypass_forward_diff(
|
|
77
|
+
org_out, oft_blocks, rescale=None, constraint=None, need_transpose=False
|
|
78
|
+
):
|
|
79
|
+
"""### 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
|
+
org_out = org_out.to(dtype=r.dtype)
|
|
93
|
+
*shape, _ = org_out.shape
|
|
94
|
+
oft_out = torch.einsum(
|
|
95
|
+
"k n m, ... k n -> ... k m", r - I, org_out.view(*shape, block_num, block_size)
|
|
96
|
+
)
|
|
97
|
+
out = oft_out.view(*shape, -1)
|
|
98
|
+
if rescale is not None:
|
|
99
|
+
out = rescale.transpose(-1, 0) * out
|
|
100
|
+
out = out + (rescale - 1).transpose(-1, 0) * org_out
|
|
101
|
+
if need_transpose:
|
|
102
|
+
out = out.transpose(1, -1)
|
|
103
|
+
return out
|
|
@@ -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))
|
|
@@ -118,8 +118,8 @@ def 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 = 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))
|