lycoris-lora 3.0.0.dev3__tar.gz → 3.0.0.dev4__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.
Files changed (38) hide show
  1. {lycoris_lora-3.0.0.dev3/lycoris_lora.egg-info → lycoris_lora-3.0.0.dev4}/PKG-INFO +1 -1
  2. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/glora.py +63 -28
  3. lycoris_lora-3.0.0.dev4/lycoris/modules/ia3.py +179 -0
  4. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/loha.py +1 -1
  5. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/lokr.py +2 -2
  6. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4/lycoris_lora.egg-info}/PKG-INFO +1 -1
  7. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/setup.py +1 -1
  8. lycoris_lora-3.0.0.dev3/lycoris/modules/ia3.py +0 -67
  9. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/LICENSE.md +0 -0
  10. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/README.md +0 -0
  11. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/__init__.py +0 -0
  12. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/config.py +0 -0
  13. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/functional/__init__.py +0 -0
  14. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/functional/general.py +0 -0
  15. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/functional/locon.py +0 -0
  16. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/functional/loha.py +0 -0
  17. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/kohya.py +0 -0
  18. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/logging.py +0 -0
  19. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/__init__.py +0 -0
  20. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/base.py +0 -0
  21. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/boft.py +0 -0
  22. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/diag_oft.py +0 -0
  23. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/dylora.py +0 -0
  24. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/full.py +0 -0
  25. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/locon.py +0 -0
  26. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/modules/norms.py +0 -0
  27. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/utils/__init__.py +0 -0
  28. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/utils/bnb.py +0 -0
  29. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/utils/logger.py +0 -0
  30. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/utils/preset.py +0 -0
  31. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/utils/xformers_utils.py +0 -0
  32. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris/wrapper.py +0 -0
  33. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/SOURCES.txt +0 -0
  34. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/dependency_links.txt +0 -0
  35. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/not-zip-safe +0 -0
  36. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/requires.txt +0 -0
  37. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/lycoris_lora.egg-info/top_level.txt +0 -0
  38. {lycoris_lora-3.0.0.dev3 → lycoris_lora-3.0.0.dev4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lycoris_lora
3
- Version: 3.0.0.dev3
3
+ Version: 3.0.0.dev4
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
@@ -5,6 +5,7 @@ import torch.nn as nn
5
5
  import torch.nn.functional as F
6
6
 
7
7
  from .base import LycorisBaseModule
8
+ from ..utils import tucker_weight_from_conv
8
9
  from ..utils.bnb import LinearNF4
9
10
 
10
11
 
@@ -52,7 +53,7 @@ class GLoRAModule(LycorisBaseModule):
52
53
  bypass_mode,
53
54
  )
54
55
  if self.module_type not in self.support_module:
55
- raise ValueError(f"{self.module_type} is not supported in LoRA/LoCon algo.")
56
+ raise ValueError(f"{self.module_type} is not supported in GLoRA algo.")
56
57
  self.lora_dim = lora_dim
57
58
  self.tucker = False
58
59
  self.rs_lora = rs_lora
@@ -68,17 +69,12 @@ class GLoRAModule(LycorisBaseModule):
68
69
  self.tucker = use_tucker and k_size != (1, 1)
69
70
  self.down_op = self.op
70
71
  self.up_op = self.op
71
- if use_tucker and k_size != (1, 1):
72
- self.a2 = self.module(in_dim, lora_dim, (1, 1), bias=False)
73
- self.am = self.module(
74
- lora_dim, lora_dim, k_size, stride, padding, bias=False
75
- )
76
- self.tucker = True
77
- else:
78
- self.a2 = self.module(
79
- in_dim, lora_dim, k_size, stride, padding, bias=False
80
- )
72
+
73
+ # A
74
+ self.a2 = self.module(in_dim, lora_dim, (1, 1), bias=False)
81
75
  self.a1 = self.module(lora_dim, in_dim, (1, 1), bias=False)
76
+
77
+ # B
82
78
  if use_tucker and k_size != (1, 1):
83
79
  self.b2 = self.module(in_dim, lora_dim, (1, 1), bias=False)
84
80
  self.bm = self.module(
@@ -90,7 +86,7 @@ class GLoRAModule(LycorisBaseModule):
90
86
  in_dim, lora_dim, k_size, stride, padding, bias=False
91
87
  )
92
88
  self.b1 = self.module(lora_dim, out_dim, (1, 1), bias=False)
93
- elif isinstance(org_module, nn.Linear):
89
+ else:
94
90
  self.isconv = False
95
91
  self.down_op = F.linear
96
92
  self.up_op = F.linear
@@ -100,8 +96,6 @@ class GLoRAModule(LycorisBaseModule):
100
96
  self.a1 = nn.Linear(lora_dim, in_dim, bias=False)
101
97
  self.b2 = nn.Linear(in_dim, lora_dim, bias=False)
102
98
  self.b1 = nn.Linear(lora_dim, out_dim, bias=False)
103
- else:
104
- raise NotImplementedError
105
99
 
106
100
  if type(alpha) == torch.Tensor:
107
101
  alpha = alpha.detach().float().numpy() # without casting, bf16 causes error
@@ -129,19 +123,35 @@ class GLoRAModule(LycorisBaseModule):
129
123
  def make_weight(self, device=None):
130
124
  wa1 = self.a1.weight.view(self.a1.weight.size(0), -1)
131
125
  wa2 = self.a2.weight.view(self.a2.weight.size(0), -1)
132
- wb1 = self.b1.weight.view(self.b1.weight.size(0), -1)
133
- wb2 = self.b2.weight.view(self.b2.weight.size(0), -1)
134
- orig = self.org_weight.view(self.org_module[0].weight.size(0), -1)
135
- return (wb2 @ wb1) + ((orig @ wa2) @ wa1)
136
126
 
137
- def forward(self, x):
138
- if self.module_dropout and self.training:
139
- if torch.rand(1) < self.module_dropout:
140
- return self.org_forward(x)
141
- scale = self.scale * self.multiplier
127
+ if self.tucker:
128
+ wb = tucker_weight_from_conv(self.b1.weight, self.b2.weight, self.bm.weight)
129
+ else:
130
+ wb1 = self.b1.weight.view(self.b1.weight.size(0), -1)
131
+ wb2 = self.b2.weight.view(self.b2.weight.size(0), -1)
132
+ wb = wb1 @ wb2
133
+ orig = self.org_weight
134
+ if orig.dim() > 2:
135
+ w_wa1 = torch.einsum("o i ..., i j -> o j ...", orig, wa1)
136
+ w_wa2 = torch.einsum("o i ..., i j -> o j ...", w_wa1, wa2)
137
+ else:
138
+ w_wa2 = (orig @ wa1) @ wa2
139
+ return (wb + w_wa2) * self.scale
140
+
141
+ def get_diff_weight(self, multiplier=1.0, shape=None, device=None):
142
+ weight = self.make_weight(device) * multiplier
143
+ if shape is not None:
144
+ weight = weight.view(shape)
145
+ return weight, None
142
146
 
143
- ax_mid = self.a1(x) * scale
144
- bx_mid = self.b1(x) * scale
147
+ def get_merged_weight(self, multiplier=1, shape=None, device=None):
148
+ diff_w, _ = self.get_diff_weight(multiplier, shape, device)
149
+ return self.org_weight + diff_w, None
150
+
151
+ def _bypass_forward(self, x, scale=1, diff=False):
152
+ scale = self.scale * scale
153
+ ax_mid = self.a2(x) * scale
154
+ bx_mid = self.b2(x) * scale
145
155
 
146
156
  if self.rank_dropout and self.training:
147
157
  drop_a = (
@@ -161,12 +171,37 @@ class GLoRAModule(LycorisBaseModule):
161
171
  drop_b = drop_b.view(*[1] * (dims - 1), -1)
162
172
  ax_mid = ax_mid * drop_a
163
173
  bx_mid = bx_mid * drop_b
164
-
165
174
  return (
166
- self.org_forward(x + self.dropout(self.a2(ax_mid)) * self.scale)
167
- + self.dropout(self.b2(bx_mid)) * self.scale
175
+ self.org_forward(
176
+ (0 if diff else x) + self.drop(self.a1(ax_mid)) * self.scale
177
+ )
178
+ + self.drop(self.b1(bx_mid)) * self.scale
168
179
  )
169
180
 
181
+ def bypass_forward_diff(self, x, scale=1):
182
+ return self._bypass_forward(x, scale=scale, diff=True)
183
+
184
+ def bypass_forward(self, x, scale=1):
185
+ return self._bypass_forward(x, scale=scale, diff=False)
186
+
187
+ def forward(self, x, *args, **kwargs):
188
+ if self.module_dropout and self.training:
189
+ if torch.rand(1) < self.module_dropout:
190
+ return self.org_forward(x)
191
+ if self.bypass_mode:
192
+ return self.bypass_forward(x, self.multiplier)
193
+ else:
194
+ weight = (
195
+ self.org_module[0].weight.data.to(self.dtype)
196
+ + self.get_diff_weight(multiplier=self.multiplier)[0]
197
+ )
198
+ bias = (
199
+ None
200
+ if self.org_module[0].bias is None
201
+ else self.org_module[0].bias.data
202
+ )
203
+ return self.op(x, weight, bias, **self.kw_dict)
204
+
170
205
 
171
206
  if __name__ == "__main__":
172
207
  device = torch.device("cuda")
@@ -0,0 +1,179 @@
1
+ import torch
2
+ import torch.nn as nn
3
+
4
+ from .base import LycorisBaseModule
5
+ from ..utils.bnb import LinearNF4
6
+
7
+
8
+ class IA3Module(LycorisBaseModule):
9
+ support_module = {
10
+ "linear",
11
+ "conv1d",
12
+ "conv2d",
13
+ "conv3d",
14
+ }
15
+
16
+ def __init__(
17
+ self,
18
+ lora_name,
19
+ org_module: nn.Module,
20
+ multiplier=1.0,
21
+ lora_dim=4,
22
+ alpha=1,
23
+ dropout=0.0,
24
+ rank_dropout=0.0,
25
+ module_dropout=0.0,
26
+ use_tucker=False,
27
+ use_scalar=False,
28
+ rank_dropout_scale=False,
29
+ weight_decompose=False,
30
+ bypass_mode=False,
31
+ rs_lora=False,
32
+ train_on_input=False,
33
+ **kwargs,
34
+ ):
35
+ """if alpha == 0 or None, alpha is rank (no scaling)."""
36
+ super().__init__(
37
+ lora_name,
38
+ org_module,
39
+ multiplier,
40
+ dropout,
41
+ rank_dropout,
42
+ module_dropout,
43
+ rank_dropout_scale,
44
+ bypass_mode,
45
+ )
46
+ if self.module_type not in self.support_module:
47
+ raise ValueError(f"{self.module_type} is not supported in IA^3 algo.")
48
+ self.lora_dim = lora_dim
49
+ self.tucker = False
50
+ self.rs_lora = rs_lora
51
+
52
+ self.shape = org_module.weight.shape
53
+ if self.module_type.startswith("conv"):
54
+ self.isconv = True
55
+ in_dim = org_module.in_channels
56
+ out_dim = org_module.out_channels
57
+ if train_on_input:
58
+ train_dim = in_dim
59
+ else:
60
+ train_dim = out_dim
61
+ self.weight = nn.Parameter(
62
+ torch.empty(1, train_dim, *(1 for _ in self.shape[2:]))
63
+ )
64
+ else:
65
+ in_dim = org_module.in_features
66
+ out_dim = org_module.out_features
67
+ if train_on_input:
68
+ train_dim = in_dim
69
+ else:
70
+ train_dim = out_dim
71
+
72
+ self.weight = nn.Parameter(torch.empty(train_dim))
73
+
74
+ # Need more experiences on init method
75
+ torch.nn.init.constant_(self.weight, 0)
76
+
77
+ self.multiplier = multiplier
78
+ self.train_input = train_on_input
79
+ self.register_buffer("on_input", torch.tensor(int(train_on_input)))
80
+
81
+ def apply_to(self):
82
+ self.org_forward = self.org_module[0].forward
83
+ self.org_module[0].forward = self.forward
84
+
85
+ def make_weight(self, multiplier=1, shape=None, device=None, diff=False):
86
+ weight = self.weight * multiplier + int(not diff)
87
+ if self.train_input:
88
+ diff = self.org_weight * weight
89
+ else:
90
+ diff = self.org_weight.transpose(0, 1) * weight
91
+ diff = diff.transpose(0, 1)
92
+ if shape is not None:
93
+ diff = diff.view(shape)
94
+ if device is not None:
95
+ diff = diff.to(device)
96
+ return diff
97
+
98
+ def get_diff_weight(self, multiplier=1, shape=None, device=None):
99
+ diff = self.make_weight(
100
+ multiplier=multiplier, shape=shape, device=device, diff=True
101
+ )
102
+ return diff, None
103
+
104
+ def get_merged_weight(self, multiplier=1, shape=None, device=None):
105
+ diff = self.make_weight(multiplier=multiplier, shape=shape, device=device)
106
+ return diff, None
107
+
108
+ def _bypass_forward(self, x, scale=1, diff=False):
109
+ weight = self.weight * scale + int(not diff)
110
+ if self.train_input:
111
+ x = x * weight
112
+ out = self.org_forward(x)
113
+ if not self.train_input:
114
+ out = out * weight
115
+ return out
116
+
117
+ def bypass_forward_diff(self, x, scale=1):
118
+ return self._bypass_forward(x, scale, diff=True)
119
+
120
+ def bypass_forward(self, x, scale=1):
121
+ return self._bypass_forward(x, scale, diff=False)
122
+
123
+ def forward(self, x, *args, **kwargs):
124
+ if self.module_dropout and self.training:
125
+ if torch.rand(1) < self.module_dropout:
126
+ return self.org_forward(x)
127
+ if self.bypass_mode:
128
+ return self.bypass_forward(x, self.multiplier)
129
+ else:
130
+ weight = self.get_merged_weight(multiplier=self.multiplier)[0]
131
+ bias = (
132
+ None
133
+ if self.org_module[0].bias is None
134
+ else self.org_module[0].bias.data
135
+ )
136
+ return self.op(x, weight, bias, **self.kw_dict)
137
+
138
+
139
+ if __name__ == "__main__":
140
+ device = torch.device("cuda")
141
+ module = IA3Module
142
+ with torch.autocast("cuda" if torch.cuda.is_available() else "cpu"):
143
+ base = nn.Linear(128, 128).to(device).half()
144
+ net = module("test", base, 1, 4, 1, weight_decompose=True).to(device)
145
+ print(net)
146
+ test_input = torch.randn(1, 128).to(device).half()
147
+ test_output = net(test_input)
148
+ torch.sum(test_output).backward()
149
+ print(test_output.shape)
150
+
151
+ base_4bit = LinearNF4(128, 128, device="cuda")
152
+ base_4bit.load_state_dict(base.state_dict())
153
+ base_4bit.to(device)
154
+ qnet = module("test", base_4bit, 1, 4, 1, weight_decompose=False).to(device)
155
+ print(qnet)
156
+ test_input = torch.randn(1, 128).to(device).half()
157
+ test_output = qnet(test_input)
158
+ torch.sum(test_output).backward()
159
+ print(test_output.shape)
160
+
161
+ base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
162
+ net = module("test", base, 1, 4, 1, weight_decompose=True, use_tucker=True).to(
163
+ device
164
+ )
165
+ print(net)
166
+ test_input = torch.randn(1, 128, 16, 16).to(device).half()
167
+ test_output = net(test_input)
168
+ torch.sum(test_output).backward()
169
+ print(test_output.shape)
170
+
171
+ base = nn.Conv2d(128, 128, 3, 1, 1).to(device).half()
172
+ net = module.parametrize(
173
+ base, "weight", 1, 4, 1, weight_decompose=True, use_tucker=True
174
+ ).to(device)
175
+ print(base)
176
+ test_input = torch.randn(1, 128, 16, 16).to(device).half()
177
+ test_output = base(test_input)
178
+ torch.sum(test_output).backward()
179
+ print(test_output.shape)
@@ -265,7 +265,7 @@ class LohaModule(LycorisBaseModule):
265
265
 
266
266
  if self.wd:
267
267
  weight = self.apply_weight_decompose(weight)
268
- return self.op(x, weight.view(self.shape), bias, **self.kw_dict)
268
+ return self.op(x, weight, bias, **self.kw_dict)
269
269
 
270
270
 
271
271
  if __name__ == "__main__":
@@ -72,7 +72,7 @@ class LokrModule(LycorisBaseModule):
72
72
  bypass_mode,
73
73
  )
74
74
  if self.module_type not in self.support_module:
75
- raise ValueError(f"{self.module_type} is not supported in LoRA/LoCon algo.")
75
+ raise ValueError(f"{self.module_type} is not supported in LoKr algo.")
76
76
 
77
77
  factor = int(factor)
78
78
  self.lora_dim = lora_dim
@@ -396,7 +396,7 @@ class LokrModule(LycorisBaseModule):
396
396
 
397
397
  if self.wd:
398
398
  weight = self.apply_weight_decompose(weight)
399
- return self.op(x, weight.view(self.shape), bias, **self.kw_dict)
399
+ return self.op(x, weight, bias, **self.kw_dict)
400
400
 
401
401
 
402
402
  if __name__ == "__main__":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lycoris_lora
3
- Version: 3.0.0.dev3
3
+ Version: 3.0.0.dev4
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.dev3",
7
+ version="3.0.0.dev4",
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",
@@ -1,67 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
-
4
- from .base import ModuleCustomSD
5
-
6
-
7
- class IA3Module(ModuleCustomSD):
8
- """
9
- Hadamard product Implementaion for Low Rank Adaptation
10
- """
11
-
12
- def __init__(
13
- self,
14
- lora_name,
15
- org_module: nn.Module,
16
- multiplier=1.0,
17
- train_on_input=False,
18
- **kwargs
19
- ):
20
- """if alpha == 0 or None, alpha is rank (no scaling)."""
21
- super().__init__()
22
- self.lora_name = lora_name
23
- self.tucker = False
24
-
25
- self.shape = org_module.weight.shape
26
- if org_module.__class__.__name__ == "Conv2d":
27
- in_dim = org_module.in_channels
28
- out_dim = org_module.out_channels
29
- if train_on_input:
30
- train_dim = in_dim
31
- else:
32
- train_dim = out_dim
33
- self.weight = nn.Parameter(torch.empty(1, train_dim, 1, 1))
34
- else:
35
- in_dim = org_module.in_features
36
- out_dim = org_module.out_features
37
- if train_on_input:
38
- train_dim = in_dim
39
- else:
40
- train_dim = out_dim
41
-
42
- self.weight = nn.Parameter(torch.empty(train_dim))
43
-
44
- # Need more experiences on init method
45
- torch.nn.init.constant_(self.weight, 0)
46
-
47
- self.multiplier = multiplier
48
- self.org_forward = None
49
- self.org_module = [org_module] # remove in applying
50
- self.grad_ckpt = False
51
- self.train_input = train_on_input
52
- self.register_buffer("on_input", torch.tensor(int(train_on_input)))
53
-
54
- def apply_to(self):
55
- self.org_forward = self.org_module[0].forward
56
- self.org_module[0].forward = self.forward
57
-
58
- @torch.enable_grad()
59
- def forward(self, x):
60
- if self.train_input:
61
- x = x * (1 + self.weight * self.multiplier)
62
- out = self.org_forward(x)
63
- dtype = out.dtype
64
- if not self.train_input:
65
- out = out * (1 + self.weight * self.multiplier)
66
- out = out.to(dtype)
67
- return out