lycoris-lora 3.0.0.dev7__tar.gz → 3.0.0.dev9__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.dev7/lycoris_lora.egg-info → lycoris_lora-3.0.0.dev9}/PKG-INFO +1 -1
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/README.md +8 -1
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/functional/loha.py +1 -3
- lycoris_lora-3.0.0.dev9/lycoris/functional/lokr.py +259 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/kohya.py +2 -8
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/__init__.py +2 -1
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/base.py +6 -1
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/boft.py +0 -44
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/diag_oft.py +0 -45
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/dylora.py +3 -44
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/full.py +10 -34
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/glora.py +8 -50
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/ia3.py +0 -43
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/locon.py +7 -48
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/loha.py +4 -47
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/lokr.py +100 -73
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/__init__.py +3 -3
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/bnb.py +3 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9/lycoris_lora.egg-info}/PKG-INFO +1 -1
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/SOURCES.txt +1 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/setup.py +1 -1
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/LICENSE.md +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/config.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/functional/__init__.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/functional/general.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/functional/locon.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/logging.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/modules/norms.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/general.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/logger.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/preset.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/utils/xformers_utils.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris/wrapper.py +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/dependency_links.txt +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/not-zip-safe +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/requires.txt +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/top_level.txt +0 -0
- {lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/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.dev9
|
|
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.
|
|
@@ -174,9 +174,7 @@ def loha_bypass_forward_diff(
|
|
|
174
174
|
|
|
175
175
|
if __name__ == "__main__":
|
|
176
176
|
w = torch.randn(128, 128, 3, 3, 3)
|
|
177
|
-
w1d, w2d, w1u, w2u, t1, t2 = loha_weight_gen(
|
|
178
|
-
w, 4, tucker=True
|
|
179
|
-
)
|
|
177
|
+
w1d, w2d, w1u, w2u, t1, t2 = loha_weight_gen(w, 4, tucker=True)
|
|
180
178
|
w1u += 0.01
|
|
181
179
|
extra_args = {"padding": 1}
|
|
182
180
|
|
|
@@ -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))
|
|
@@ -611,11 +611,8 @@ class LycorisNetworkKohya(LycorisNetwork):
|
|
|
611
611
|
# Precalculate model hashes to save time on indexing
|
|
612
612
|
if metadata is None:
|
|
613
613
|
metadata = {}
|
|
614
|
-
model_hash
|
|
615
|
-
state_dict
|
|
616
|
-
)
|
|
614
|
+
model_hash = precalculate_safetensors_hashes(state_dict)
|
|
617
615
|
metadata["sshs_model_hash"] = model_hash
|
|
618
|
-
metadata["sshs_legacy_hash"] = legacy_hash
|
|
619
616
|
|
|
620
617
|
save_file(state_dict, file, metadata)
|
|
621
618
|
else:
|
|
@@ -845,11 +842,8 @@ class IA3Network(torch.nn.Module):
|
|
|
845
842
|
# Precalculate model hashes to save time on indexing
|
|
846
843
|
if metadata is None:
|
|
847
844
|
metadata = {}
|
|
848
|
-
model_hash
|
|
849
|
-
state_dict
|
|
850
|
-
)
|
|
845
|
+
model_hash = precalculate_safetensors_hashes(state_dict)
|
|
851
846
|
metadata["sshs_model_hash"] = model_hash
|
|
852
|
-
metadata["sshs_legacy_hash"] = legacy_hash
|
|
853
847
|
|
|
854
848
|
save_file(state_dict, file, metadata)
|
|
855
849
|
else:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import torch
|
|
2
2
|
import torch.nn as nn
|
|
3
3
|
|
|
4
|
+
from .base import LycorisBaseModule
|
|
4
5
|
from .locon import LoConModule
|
|
5
6
|
from .loha import LohaModule
|
|
6
7
|
from .lokr import LokrModule
|
|
@@ -57,7 +58,7 @@ def make_module(lyco_type, params, lora_name, orig_module):
|
|
|
57
58
|
module.dora_scale.copy_(dora_scale)
|
|
58
59
|
elif lyco_type == "kron":
|
|
59
60
|
w1, w1a, w1b, w2, w2a, w2b, _, t2, alpha, dora_scale = params
|
|
60
|
-
full_matrix=False
|
|
61
|
+
full_matrix = False
|
|
61
62
|
if w1a is not None:
|
|
62
63
|
lora_dim = w1a.size(1)
|
|
63
64
|
elif w2a is not None:
|
|
@@ -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
|
|
@@ -80,6 +79,9 @@ class DyLoraModule(LycorisBaseModule):
|
|
|
80
79
|
for v in self.up_list:
|
|
81
80
|
torch.nn.init.zeros_(v)
|
|
82
81
|
|
|
82
|
+
def load_state_dict(self, state_dict, strict: bool = True, assign: bool = False):
|
|
83
|
+
return
|
|
84
|
+
|
|
83
85
|
def custom_state_dict(self):
|
|
84
86
|
destination = {}
|
|
85
87
|
destination["alpha"] = self.alpha
|
|
@@ -153,46 +155,3 @@ class DyLoraModule(LycorisBaseModule):
|
|
|
153
155
|
else self.org_module[0].bias.data
|
|
154
156
|
)
|
|
155
157
|
return self.op(x, weight, bias, **self.kw_dict)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if __name__ == "__main__":
|
|
159
|
-
device = torch.device("cuda")
|
|
160
|
-
module = DyLoraModule
|
|
161
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
162
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
163
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
164
|
-
print(net)
|
|
165
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
166
|
-
test_output = net(test_input)
|
|
167
|
-
torch.sum(test_output).backward()
|
|
168
|
-
print(test_output.shape)
|
|
169
|
-
|
|
170
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
171
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
172
|
-
base_4bit.to(device)
|
|
173
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
174
|
-
print(qnet)
|
|
175
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
176
|
-
test_output = qnet(test_input)
|
|
177
|
-
torch.sum(test_output).backward()
|
|
178
|
-
print(test_output.shape)
|
|
179
|
-
|
|
180
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
181
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
182
|
-
device
|
|
183
|
-
)
|
|
184
|
-
print(net)
|
|
185
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
186
|
-
test_output = net(test_input)
|
|
187
|
-
torch.sum(test_output).backward()
|
|
188
|
-
print(test_output.shape)
|
|
189
|
-
|
|
190
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
191
|
-
net = module.parametrize(
|
|
192
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
193
|
-
).to(device)
|
|
194
|
-
print(base)
|
|
195
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
196
|
-
test_output = base(test_input)
|
|
197
|
-
torch.sum(test_output).backward()
|
|
198
|
-
print(test_output.shape)
|
|
@@ -76,6 +76,15 @@ class FullModule(LycorisBaseModule):
|
|
|
76
76
|
else:
|
|
77
77
|
self.org_bias = None
|
|
78
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
|
+
|
|
85
|
+
def load_state_dict(self, state_dict, strict: bool = True, assign: bool = False):
|
|
86
|
+
return
|
|
87
|
+
|
|
79
88
|
def custom_state_dict(self):
|
|
80
89
|
sd = {"diff": self.weight.data.cpu() - self._org_weight[0]}
|
|
81
90
|
if self.bias is not None:
|
|
@@ -137,7 +146,7 @@ class FullModule(LycorisBaseModule):
|
|
|
137
146
|
if shape is not None:
|
|
138
147
|
weight = weight.view(shape)
|
|
139
148
|
if bias is not None:
|
|
140
|
-
bias = bias.view(shape[0]
|
|
149
|
+
bias = bias.view(shape[0])
|
|
141
150
|
return weight, bias
|
|
142
151
|
|
|
143
152
|
def forward(self, x: torch.Tensor, *args, **kwargs):
|
|
@@ -155,36 +164,3 @@ class FullModule(LycorisBaseModule):
|
|
|
155
164
|
weight, bias = self.make_weight(scale, x.device)
|
|
156
165
|
kw_dict = self.kw_dict | {"weight": weight, "bias": bias}
|
|
157
166
|
return self.op(x, **kw_dict)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if __name__ == "__main__":
|
|
161
|
-
device = torch.device("cuda")
|
|
162
|
-
module = FullModule
|
|
163
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
164
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
165
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
166
|
-
print(net)
|
|
167
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
168
|
-
test_output = net(test_input)
|
|
169
|
-
torch.sum(test_output).backward()
|
|
170
|
-
print(test_output.shape)
|
|
171
|
-
|
|
172
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
173
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
174
|
-
device
|
|
175
|
-
)
|
|
176
|
-
print(net)
|
|
177
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
178
|
-
test_output = net(test_input)
|
|
179
|
-
torch.sum(test_output).backward()
|
|
180
|
-
print(test_output.shape)
|
|
181
|
-
|
|
182
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
183
|
-
net = module.parametrize(
|
|
184
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
185
|
-
).to(device)
|
|
186
|
-
print(base)
|
|
187
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
188
|
-
test_output = base(test_input)
|
|
189
|
-
torch.sum(test_output).backward()
|
|
190
|
-
print(test_output.shape)
|
|
@@ -66,17 +66,17 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
66
66
|
stride = org_module.stride
|
|
67
67
|
padding = org_module.padding
|
|
68
68
|
out_dim = org_module.out_channels
|
|
69
|
-
self.tucker = use_tucker and
|
|
69
|
+
self.tucker = use_tucker and all(i == 1 for i in k_size)
|
|
70
70
|
self.down_op = self.op
|
|
71
71
|
self.up_op = self.op
|
|
72
72
|
|
|
73
73
|
# A
|
|
74
|
-
self.a2 = self.module(in_dim, lora_dim,
|
|
75
|
-
self.a1 = self.module(lora_dim, in_dim,
|
|
74
|
+
self.a2 = self.module(in_dim, lora_dim, 1, bias=False)
|
|
75
|
+
self.a1 = self.module(lora_dim, in_dim, 1, bias=False)
|
|
76
76
|
|
|
77
77
|
# B
|
|
78
|
-
if use_tucker and
|
|
79
|
-
self.b2 = self.module(in_dim, lora_dim,
|
|
78
|
+
if use_tucker and any(i != 1 for i in k_size):
|
|
79
|
+
self.b2 = self.module(in_dim, lora_dim, 1, bias=False)
|
|
80
80
|
self.bm = self.module(
|
|
81
81
|
lora_dim, lora_dim, k_size, stride, padding, bias=False
|
|
82
82
|
)
|
|
@@ -85,7 +85,7 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
85
85
|
self.b2 = self.module(
|
|
86
86
|
in_dim, lora_dim, k_size, stride, padding, bias=False
|
|
87
87
|
)
|
|
88
|
-
self.b1 = self.module(lora_dim, out_dim,
|
|
88
|
+
self.b1 = self.module(lora_dim, out_dim, 1, bias=False)
|
|
89
89
|
else:
|
|
90
90
|
self.isconv = False
|
|
91
91
|
self.down_op = F.linear
|
|
@@ -123,6 +123,7 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
123
123
|
def make_weight(self, device=None):
|
|
124
124
|
wa1 = self.a1.weight.view(self.a1.weight.size(0), -1)
|
|
125
125
|
wa2 = self.a2.weight.view(self.a2.weight.size(0), -1)
|
|
126
|
+
orig = self.org_weight
|
|
126
127
|
|
|
127
128
|
if self.tucker:
|
|
128
129
|
wb = tucker_weight_from_conv(self.b1.weight, self.b2.weight, self.bm.weight)
|
|
@@ -130,7 +131,7 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
130
131
|
wb1 = self.b1.weight.view(self.b1.weight.size(0), -1)
|
|
131
132
|
wb2 = self.b2.weight.view(self.b2.weight.size(0), -1)
|
|
132
133
|
wb = wb1 @ wb2
|
|
133
|
-
|
|
134
|
+
wb = wb.view(*orig.shape)
|
|
134
135
|
if orig.dim() > 2:
|
|
135
136
|
w_wa1 = torch.einsum("o i ..., i j -> o j ...", orig, wa1)
|
|
136
137
|
w_wa2 = torch.einsum("o i ..., i j -> o j ...", w_wa1, wa2)
|
|
@@ -201,46 +202,3 @@ class GLoRAModule(LycorisBaseModule):
|
|
|
201
202
|
else self.org_module[0].bias.data
|
|
202
203
|
)
|
|
203
204
|
return self.op(x, weight, bias, **self.kw_dict)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if __name__ == "__main__":
|
|
207
|
-
device = torch.device("cuda")
|
|
208
|
-
module = GLoRAModule
|
|
209
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
210
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
211
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
212
|
-
print(net)
|
|
213
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
214
|
-
test_output = net(test_input)
|
|
215
|
-
torch.sum(test_output).backward()
|
|
216
|
-
print(test_output.shape)
|
|
217
|
-
|
|
218
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
219
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
220
|
-
base_4bit.to(device)
|
|
221
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
222
|
-
print(qnet)
|
|
223
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
224
|
-
test_output = qnet(test_input)
|
|
225
|
-
torch.sum(test_output).backward()
|
|
226
|
-
print(test_output.shape)
|
|
227
|
-
|
|
228
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
229
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
230
|
-
device
|
|
231
|
-
)
|
|
232
|
-
print(net)
|
|
233
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
234
|
-
test_output = net(test_input)
|
|
235
|
-
torch.sum(test_output).backward()
|
|
236
|
-
print(test_output.shape)
|
|
237
|
-
|
|
238
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
239
|
-
net = module.parametrize(
|
|
240
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
241
|
-
).to(device)
|
|
242
|
-
print(base)
|
|
243
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
244
|
-
test_output = base(test_input)
|
|
245
|
-
torch.sum(test_output).backward()
|
|
246
|
-
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)
|
|
@@ -70,11 +70,11 @@ class LoConModule(LycorisBaseModule):
|
|
|
70
70
|
stride = org_module.stride
|
|
71
71
|
padding = org_module.padding
|
|
72
72
|
out_dim = org_module.out_channels
|
|
73
|
-
self.tucker = use_tucker and
|
|
73
|
+
self.tucker = use_tucker and any(i != 1 for i in k_size)
|
|
74
74
|
self.down_op = self.op
|
|
75
75
|
self.up_op = self.op
|
|
76
|
-
if use_tucker and
|
|
77
|
-
self.lora_down = self.module(in_dim, lora_dim,
|
|
76
|
+
if use_tucker and any(i != 1 for i in k_size):
|
|
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
|
|
@@ -97,7 +97,7 @@ class LoConModule(LycorisBaseModule):
|
|
|
97
97
|
|
|
98
98
|
self.wd = weight_decompose
|
|
99
99
|
if self.wd:
|
|
100
|
-
org_weight
|
|
100
|
+
org_weight = org_module.weight.cpu().clone().float()
|
|
101
101
|
self.dora_norm_dims = org_weight.dim() - 1
|
|
102
102
|
self.dora_scale = nn.Parameter(
|
|
103
103
|
torch.norm(
|
|
@@ -148,6 +148,8 @@ class LoConModule(LycorisBaseModule):
|
|
|
148
148
|
del missing_keys[missing_keys.index(key)]
|
|
149
149
|
if isinstance(self.scalar, nn.Parameter):
|
|
150
150
|
self.scalar.data.copy_(torch.ones_like(self.scalar))
|
|
151
|
+
elif getattr(self, "scalar", None) is not None:
|
|
152
|
+
self.scalar.copy_(torch.ones_like(self.scalar))
|
|
151
153
|
else:
|
|
152
154
|
self.register_buffer(
|
|
153
155
|
"scalar", torch.ones_like(self.scalar), persistent=False
|
|
@@ -275,46 +277,3 @@ class LoConModule(LycorisBaseModule):
|
|
|
275
277
|
return self.op(x, weight, bias, **self.kw_dict)
|
|
276
278
|
else:
|
|
277
279
|
return self.bypass_forward(x, scale=self.multiplier)
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if __name__ == "__main__":
|
|
281
|
-
device = torch.device("cuda")
|
|
282
|
-
module = LoConModule
|
|
283
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
284
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
285
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
286
|
-
print(net)
|
|
287
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
288
|
-
test_output = net(test_input)
|
|
289
|
-
torch.sum(test_output).backward()
|
|
290
|
-
print(test_output.shape)
|
|
291
|
-
|
|
292
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
293
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
294
|
-
base_4bit.to(device)
|
|
295
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
296
|
-
print(qnet)
|
|
297
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
298
|
-
test_output = qnet(test_input)
|
|
299
|
-
torch.sum(test_output).backward()
|
|
300
|
-
print(test_output.shape)
|
|
301
|
-
|
|
302
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
303
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
304
|
-
device
|
|
305
|
-
)
|
|
306
|
-
print(net)
|
|
307
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
308
|
-
test_output = net(test_input)
|
|
309
|
-
torch.sum(test_output).backward()
|
|
310
|
-
print(test_output.shape)
|
|
311
|
-
|
|
312
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
313
|
-
net = module.parametrize(
|
|
314
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
315
|
-
)
|
|
316
|
-
print(base)
|
|
317
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
318
|
-
test_output = base(test_input)
|
|
319
|
-
torch.sum(test_output).backward()
|
|
320
|
-
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
|
|
@@ -58,12 +57,11 @@ class LohaModule(LycorisBaseModule):
|
|
|
58
57
|
k_size = org_module.kernel_size
|
|
59
58
|
out_dim = org_module.out_channels
|
|
60
59
|
self.shape = (out_dim, in_dim, *k_size)
|
|
61
|
-
self.tucker = use_tucker and
|
|
60
|
+
self.tucker = use_tucker and any(i != 1 for i in k_size)
|
|
62
61
|
if self.tucker:
|
|
63
62
|
w_shape = (out_dim, in_dim, *k_size)
|
|
64
63
|
else:
|
|
65
64
|
w_shape = (out_dim, in_dim * torch.tensor(k_size).prod().item())
|
|
66
|
-
self.op = F.conv2d
|
|
67
65
|
|
|
68
66
|
if self.tucker:
|
|
69
67
|
self.hada_t1 = nn.Parameter(torch.empty(lora_dim, lora_dim, *w_shape[2:]))
|
|
@@ -90,7 +88,7 @@ class LohaModule(LycorisBaseModule):
|
|
|
90
88
|
|
|
91
89
|
self.wd = weight_decompose
|
|
92
90
|
if self.wd:
|
|
93
|
-
org_weight
|
|
91
|
+
org_weight = org_module.weight.cpu().clone().float()
|
|
94
92
|
self.dora_norm_dims = org_weight.dim() - 1
|
|
95
93
|
self.dora_scale = nn.Parameter(
|
|
96
94
|
torch.norm(
|
|
@@ -140,6 +138,8 @@ class LohaModule(LycorisBaseModule):
|
|
|
140
138
|
del missing_keys[missing_keys.index(key)]
|
|
141
139
|
if isinstance(self.scalar, nn.Parameter):
|
|
142
140
|
self.scalar.data.copy_(torch.ones_like(self.scalar))
|
|
141
|
+
elif getattr(self, "scalar", None) is not None:
|
|
142
|
+
self.scalar.copy_(torch.ones_like(self.scalar))
|
|
143
143
|
else:
|
|
144
144
|
self.register_buffer(
|
|
145
145
|
"scalar", torch.ones_like(self.scalar), persistent=False
|
|
@@ -266,46 +266,3 @@ class LohaModule(LycorisBaseModule):
|
|
|
266
266
|
if self.wd:
|
|
267
267
|
weight = self.apply_weight_decompose(weight)
|
|
268
268
|
return self.op(x, weight, bias, **self.kw_dict)
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if __name__ == "__main__":
|
|
272
|
-
device = torch.device("cuda")
|
|
273
|
-
module = LohaModule
|
|
274
|
-
with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
|
|
275
|
-
base = nn.Linear(128, 128).to(device).half()
|
|
276
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
|
|
277
|
-
print(net)
|
|
278
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
279
|
-
test_output = net(test_input)
|
|
280
|
-
torch.sum(test_output).backward()
|
|
281
|
-
print(test_output.shape)
|
|
282
|
-
|
|
283
|
-
base_4bit = LinearNF4(128, 128, device="cuda")
|
|
284
|
-
base_4bit.load_state_dict(base.state_dict())
|
|
285
|
-
base_4bit.to(device)
|
|
286
|
-
qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
|
|
287
|
-
print(qnet)
|
|
288
|
-
test_input = torch.randn(1, 128).to(device).half()
|
|
289
|
-
test_output = qnet(test_input)
|
|
290
|
-
torch.sum(test_output).backward()
|
|
291
|
-
print(test_output.shape)
|
|
292
|
-
|
|
293
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
294
|
-
net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
|
|
295
|
-
device
|
|
296
|
-
)
|
|
297
|
-
print(net)
|
|
298
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
299
|
-
test_output = net(test_input)
|
|
300
|
-
torch.sum(test_output).backward()
|
|
301
|
-
print(test_output.shape)
|
|
302
|
-
|
|
303
|
-
base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
|
|
304
|
-
net = module.parametrize(
|
|
305
|
-
base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
|
|
306
|
-
)
|
|
307
|
-
print(base)
|
|
308
|
-
test_input = torch.randn(1, 128, 16, 16).to(device).half()
|
|
309
|
-
test_output = base(test_input)
|
|
310
|
-
torch.sum(test_output).backward()
|
|
311
|
-
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",
|
|
@@ -93,7 +85,7 @@ class LokrModule(LycorisBaseModule):
|
|
|
93
85
|
if unbalanced_factorization:
|
|
94
86
|
out_l, out_k = out_k, out_l
|
|
95
87
|
shape = ((out_l, out_k), (in_m, in_n), *k_size) # ((a, b), (c, d), *k_size)
|
|
96
|
-
self.tucker = use_tucker and
|
|
88
|
+
self.tucker = use_tucker and any(i != 1 for i in k_size)
|
|
97
89
|
if (
|
|
98
90
|
decompose_both
|
|
99
91
|
and lora_dim < max(shape[0][0], shape[1][0]) / 2
|
|
@@ -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
|
|
@@ -166,7 +156,7 @@ class LokrModule(LycorisBaseModule):
|
|
|
166
156
|
|
|
167
157
|
self.wd = weight_decompose
|
|
168
158
|
if self.wd:
|
|
169
|
-
org_weight
|
|
159
|
+
org_weight = org_module.weight.cpu().clone().float()
|
|
170
160
|
self.dora_norm_dims = org_weight.dim() - 1
|
|
171
161
|
self.dora_scale = nn.Parameter(
|
|
172
162
|
torch.norm(
|
|
@@ -232,6 +222,8 @@ class LokrModule(LycorisBaseModule):
|
|
|
232
222
|
del missing_keys[missing_keys.index(key)]
|
|
233
223
|
if isinstance(self.scalar, nn.Parameter):
|
|
234
224
|
self.scalar.data.copy_(torch.ones_like(self.scalar))
|
|
225
|
+
elif getattr(self, "scalar", None) is not None:
|
|
226
|
+
self.scalar.copy_(torch.ones_like(self.scalar))
|
|
235
227
|
else:
|
|
236
228
|
self.register_buffer(
|
|
237
229
|
"scalar", torch.ones_like(self.scalar), persistent=False
|
|
@@ -337,40 +329,74 @@ class LokrModule(LycorisBaseModule):
|
|
|
337
329
|
return scaled, orig_norm * ratio
|
|
338
330
|
|
|
339
331
|
def bypass_forward_diff(self, h, scale=1):
|
|
340
|
-
|
|
341
|
-
return (
|
|
342
|
-
self.op(h, self.get_weight(self.shape), **self.kw_dict)
|
|
343
|
-
* self.multiplier
|
|
344
|
-
)
|
|
345
|
-
if self.module_type.startswith("conv"):
|
|
346
|
-
h = h.transpose(1, -1)
|
|
332
|
+
is_conv = self.module_type.startswith("conv")
|
|
347
333
|
if self.use_w2:
|
|
348
334
|
ba = self.lokr_w2
|
|
349
335
|
else:
|
|
350
336
|
a = self.lokr_w2_b
|
|
351
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
|
+
|
|
352
347
|
if self.use_w1:
|
|
353
348
|
c = self.lokr_w1
|
|
354
349
|
else:
|
|
355
350
|
c = self.lokr_w1_a @ self.lokr_w1_b
|
|
356
351
|
uq = c.size(1)
|
|
357
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
|
+
|
|
358
361
|
if self.use_w2:
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
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)
|
|
362
382
|
else:
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
hb = F.linear(ha, b)
|
|
383
|
+
# b, ..., uq, vq
|
|
384
|
+
# -> b, ..., vq, uq
|
|
385
|
+
h_cross_group = hb.transpose(-1, -2)
|
|
367
386
|
|
|
368
|
-
h_cross_group = hb.transpose(-1, -2)
|
|
369
387
|
hc = F.linear(h_cross_group, c)
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
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)
|
|
374
400
|
|
|
375
401
|
return self.drop(h * scale)
|
|
376
402
|
|
|
@@ -400,43 +426,44 @@ class LokrModule(LycorisBaseModule):
|
|
|
400
426
|
|
|
401
427
|
|
|
402
428
|
if __name__ == "__main__":
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
base
|
|
407
|
-
|
|
408
|
-
|
|
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
|
-
|
|
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))
|
|
@@ -469,12 +469,12 @@ def get_module(lyco_state_dict: Dict, lora_name):
|
|
|
469
469
|
def tucker_weight_from_conv(up, down, mid):
|
|
470
470
|
up = up.reshape(up.size(0), up.size(1))
|
|
471
471
|
down = down.reshape(down.size(0), down.size(1))
|
|
472
|
-
return torch.einsum("m n
|
|
472
|
+
return torch.einsum("m n ..., i m, n j -> i j ...", mid, up, down)
|
|
473
473
|
|
|
474
474
|
|
|
475
475
|
def tucker_weight(wa, wb, t):
|
|
476
|
-
temp = torch.einsum("i j
|
|
477
|
-
return torch.einsum("i j
|
|
476
|
+
temp = torch.einsum("i j ..., j r -> i r ...", t, wb)
|
|
477
|
+
return torch.einsum("i j ..., i r -> r j ...", temp, wa)
|
|
478
478
|
|
|
479
479
|
|
|
480
480
|
def apply_dora_scale(org_weight, rebuild, dora_scale, scale):
|
|
@@ -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.dev9
|
|
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.dev9",
|
|
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
|
{lycoris_lora-3.0.0.dev7 → lycoris_lora-3.0.0.dev9}/lycoris_lora.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|