Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
S
Stable Diffusion Webui
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
novelai-storage
Stable Diffusion Webui
Commits
a2fad6ee
Commit
a2fad6ee
authored
Nov 01, 2023
by
v0xie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
test implementation based on kohaku diag-oft implementation
parent
6523edb8
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
38 additions
and
21 deletions
+38
-21
extensions-builtin/Lora/network_oft.py
extensions-builtin/Lora/network_oft.py
+38
-21
No files found.
extensions-builtin/Lora/network_oft.py
View file @
a2fad6ee
import
torch
import
torch
import
network
import
network
from
einops
import
rearrange
class
ModuleTypeOFT
(
network
.
ModuleType
):
class
ModuleTypeOFT
(
network
.
ModuleType
):
...
@@ -30,35 +31,51 @@ class NetworkModuleOFT(network.NetworkModule):
...
@@ -30,35 +31,51 @@ class NetworkModuleOFT(network.NetworkModule):
self
.
org_module
:
list
[
torch
.
Module
]
=
[
self
.
sd_module
]
self
.
org_module
:
list
[
torch
.
Module
]
=
[
self
.
sd_module
]
def
merge_weight
(
self
,
R_weight
,
org_weight
):
# def merge_weight(self, R_weight, org_weight):
R_weight
=
R_weight
.
to
(
org_weight
.
device
,
dtype
=
org_weight
.
dtype
)
# R_weight = R_weight.to(org_weight.device, dtype=org_weight.dtype)
if
org_weight
.
dim
()
==
4
:
# if org_weight.dim() == 4:
weight
=
torch
.
einsum
(
"oihw, op -> pihw"
,
org_weight
,
R_weight
)
# weight = torch.einsum("oihw, op -> pihw", org_weight, R_weight)
else
:
# else:
weight
=
torch
.
einsum
(
"oi, op -> pi"
,
org_weight
,
R_weight
)
# weight = torch.einsum("oi, op -> pi", org_weight, R_weight)
return
weight
# weight = torch.einsum(
# "k n m, k n ... -> k m ...",
# self.oft_diag * scale + torch.eye(self.block_size, device=device),
# org_weight
# )
# return weight
def
get_weight
(
self
,
oft_blocks
,
multiplier
=
None
):
def
get_weight
(
self
,
oft_blocks
,
multiplier
=
None
):
constraint
=
self
.
constraint
.
to
(
oft_blocks
.
device
,
dtype
=
oft_blocks
.
dtype
)
#
constraint = self.constraint.to(oft_blocks.device, dtype=oft_blocks.dtype)
block_Q
=
oft_blocks
-
oft_blocks
.
transpose
(
1
,
2
)
#
block_Q = oft_blocks - oft_blocks.transpose(1, 2)
norm_Q
=
torch
.
norm
(
block_Q
.
flatten
())
#
norm_Q = torch.norm(block_Q.flatten())
new_norm_Q
=
torch
.
clamp
(
norm_Q
,
max
=
constraint
)
#
new_norm_Q = torch.clamp(norm_Q, max=constraint)
block_Q
=
block_Q
*
((
new_norm_Q
+
1e-8
)
/
(
norm_Q
+
1e-8
))
#
block_Q = block_Q * ((new_norm_Q + 1e-8) / (norm_Q + 1e-8))
m_I
=
torch
.
eye
(
self
.
block_size
,
device
=
oft_blocks
.
device
)
.
unsqueeze
(
0
)
.
repeat
(
self
.
num_blocks
,
1
,
1
)
#
m_I = torch.eye(self.block_size, device=oft_blocks.device).unsqueeze(0).repeat(self.num_blocks, 1, 1)
block_R
=
torch
.
matmul
(
m_I
+
block_Q
,
(
m_I
-
block_Q
)
.
inverse
())
#
block_R = torch.matmul(m_I + block_Q, (m_I - block_Q).inverse())
block_R_weighted
=
multiplier
*
block_R
+
(
1
-
multiplier
)
*
m_I
# block_R_weighted = multiplier * block_R + (1 - multiplier) * m_I
R
=
torch
.
block_diag
(
*
block_R_weighted
)
# R = torch.block_diag(*block_R_weighted)
#return R
return
self
.
oft_blocks
return
R
def
calc_updown
(
self
,
orig_weight
):
def
calc_updown
(
self
,
orig_weight
):
multiplier
=
self
.
multiplier
()
*
self
.
calc_scale
()
multiplier
=
self
.
multiplier
()
*
self
.
calc_scale
()
R
=
self
.
get_weight
(
self
.
oft_blocks
,
multiplier
)
#R = self.get_weight(self.oft_blocks, multiplier)
merged_weight
=
self
.
merge_weight
(
R
,
orig_weight
)
R
=
self
.
oft_blocks
.
to
(
orig_weight
.
device
,
dtype
=
orig_weight
.
dtype
)
#merged_weight = self.merge_weight(R, orig_weight)
updown
=
merged_weight
.
to
(
orig_weight
.
device
,
dtype
=
orig_weight
.
dtype
)
-
orig_weight
orig_weight
=
rearrange
(
orig_weight
,
'(k n) ... -> k n ...'
,
k
=
self
.
num_blocks
,
n
=
self
.
block_size
)
weight
=
torch
.
einsum
(
'k n m, k n ... -> k m ...'
,
R
*
multiplier
+
torch
.
eye
(
self
.
block_size
,
device
=
orig_weight
.
device
),
orig_weight
)
weight
=
rearrange
(
weight
,
'k m ... -> (k m) ...'
)
#updown = merged_weight.to(orig_weight.device, dtype=orig_weight.dtype) - orig_weight
updown
=
weight
.
to
(
orig_weight
.
device
,
dtype
=
orig_weight
.
dtype
)
-
orig_weight
output_shape
=
orig_weight
.
shape
output_shape
=
orig_weight
.
shape
orig_weight
=
orig_weight
orig_weight
=
orig_weight
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment