Skip to content

Commit adadb4e

Browse files
committed
Merge branch 'release_candidate'
2 parents bef51ae + d282d24 commit adadb4e

File tree

109 files changed

+1957
-781
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+1957
-781
lines changed

.eslintrc.js

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ module.exports = {
7878
//extraNetworks.js
7979
requestGet: "readonly",
8080
popup: "readonly",
81+
// profilerVisualization.js
82+
createVisualizationTable: "readonly",
8183
// from python
8284
localization: "readonly",
8385
// progrssbar.js

.github/workflows/on_pull_request.yaml

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ jobs:
1111
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
1212
steps:
1313
- name: Checkout Code
14-
uses: actions/checkout@v3
15-
- uses: actions/setup-python@v4
14+
uses: actions/checkout@v4
15+
- uses: actions/setup-python@v5
1616
with:
1717
python-version: 3.11
1818
# NB: there's no cache: pip here since we're not installing anything
1919
# from the requirements.txt file(s) in the repository; it's faster
2020
# not to have GHA download an (at the time of writing) 4 GB cache
2121
# of PyTorch and other dependencies.
2222
- name: Install Ruff
23-
run: pip install ruff==0.1.6
23+
run: pip install ruff==0.3.3
2424
- name: Run Ruff
2525
run: ruff .
2626
lint-js:
@@ -29,9 +29,9 @@ jobs:
2929
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
3030
steps:
3131
- name: Checkout Code
32-
uses: actions/checkout@v3
32+
uses: actions/checkout@v4
3333
- name: Install Node.js
34-
uses: actions/setup-node@v3
34+
uses: actions/setup-node@v4
3535
with:
3636
node-version: 18
3737
- run: npm i --ci

.github/workflows/run_tests.yaml

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ jobs:
1111
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
1212
steps:
1313
- name: Checkout Code
14-
uses: actions/checkout@v3
14+
uses: actions/checkout@v4
1515
- name: Set up Python 3.10
16-
uses: actions/setup-python@v4
16+
uses: actions/setup-python@v5
1717
with:
1818
python-version: 3.10.6
1919
cache: pip
@@ -22,7 +22,7 @@ jobs:
2222
launch.py
2323
- name: Cache models
2424
id: cache-models
25-
uses: actions/cache@v3
25+
uses: actions/cache@v4
2626
with:
2727
path: models
2828
key: "2023-12-30"
@@ -68,13 +68,13 @@ jobs:
6868
python -m coverage report -i
6969
python -m coverage html -i
7070
- name: Upload main app output
71-
uses: actions/upload-artifact@v3
71+
uses: actions/upload-artifact@v4
7272
if: always()
7373
with:
7474
name: output
7575
path: output.txt
7676
- name: Upload coverage HTML
77-
uses: actions/upload-artifact@v3
77+
uses: actions/upload-artifact@v4
7878
if: always()
7979
with:
8080
name: htmlcov

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@ notification.mp3
3838
/package-lock.json
3939
/.coverage*
4040
/test/test_outputs
41+
/cache

CHANGELOG.md

+133-11
Large diffs are not rendered by default.

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ Make sure the required [dependencies](https://github.com/AUTOMATIC1111/stable-di
9898
- [NVidia](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-NVidia-GPUs) (recommended)
9999
- [AMD](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs) GPUs.
100100
- [Intel CPUs, Intel GPUs (both integrated and discrete)](https://github.com/openvinotoolkit/stable-diffusion-webui/wiki/Installation-on-Intel-Silicon) (external wiki page)
101+
- [Ascend NPUs](https://github.com/wangshuai09/stable-diffusion-webui/wiki/Install-and-run-on-Ascend-NPUs) (external wiki page)
101102

102103
Alternatively, use online services (like Google Colab):
103104

_typos.toml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[default.extend-words]
2+
# Part of "RGBa" (Pillow's pre-multiplied alpha RGB mode)
3+
Ba = "Ba"
4+
# HSA is something AMD uses for their GPUs
5+
HSA = "HSA"

extensions-builtin/LDSR/sd_hijack_ddpm_v1.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def p_losses(self, x_start, t, noise=None):
301301
elif self.parameterization == "x0":
302302
target = x_start
303303
else:
304-
raise NotImplementedError(f"Paramterization {self.parameterization} not yet supported")
304+
raise NotImplementedError(f"Parameterization {self.parameterization} not yet supported")
305305

306306
loss = self.get_loss(model_out, target, mean=False).mean(dim=[1, 2, 3])
307307

@@ -880,7 +880,7 @@ def forward(self, x, c, *args, **kwargs):
880880
def apply_model(self, x_noisy, t, cond, return_ids=False):
881881

882882
if isinstance(cond, dict):
883-
# hybrid case, cond is exptected to be a dict
883+
# hybrid case, cond is expected to be a dict
884884
pass
885885
else:
886886
if not isinstance(cond, list):
@@ -916,7 +916,7 @@ def apply_model(self, x_noisy, t, cond, return_ids=False):
916916
cond_list = [{c_key: [c[:, :, :, :, i]]} for i in range(c.shape[-1])]
917917

918918
elif self.cond_stage_key == 'coordinates_bbox':
919-
assert 'original_image_size' in self.split_input_params, 'BoudingBoxRescaling is missing original_image_size'
919+
assert 'original_image_size' in self.split_input_params, 'BoundingBoxRescaling is missing original_image_size'
920920

921921
# assuming padding of unfold is always 0 and its dilation is always 1
922922
n_patches_per_row = int((w - ks[0]) / stride[0] + 1)
@@ -926,7 +926,7 @@ def apply_model(self, x_noisy, t, cond, return_ids=False):
926926
num_downs = self.first_stage_model.encoder.num_resolutions - 1
927927
rescale_latent = 2 ** (num_downs)
928928

929-
# get top left postions of patches as conforming for the bbbox tokenizer, therefore we
929+
# get top left positions of patches as conforming for the bbbox tokenizer, therefore we
930930
# need to rescale the tl patch coordinates to be in between (0,1)
931931
tl_patch_coordinates = [(rescale_latent * stride[0] * (patch_nr % n_patches_per_row) / full_img_w,
932932
rescale_latent * stride[1] * (patch_nr // n_patches_per_row) / full_img_h)

extensions-builtin/Lora/lyco_helpers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def factorization(dimension: int, factor:int=-1) -> tuple[int, int]:
3030
In LoRA with Kroneckor Product, first value is a value for weight scale.
3131
secon value is a value for weight.
3232
33-
Becuase of non-commutative property, A⊗B ≠ B⊗A. Meaning of two matrices is slightly different.
33+
Because of non-commutative property, A⊗B ≠ B⊗A. Meaning of two matrices is slightly different.
3434
3535
examples)
3636
factor

extensions-builtin/Lora/network.py

+33-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ def __init__(self, name, filename):
2929

3030
def read_metadata():
3131
metadata = sd_models.read_metadata_from_safetensors(filename)
32-
metadata.pop('ssmd_cover_images', None) # those are cover images, and they are too big to display in UI as text
3332

3433
return metadata
3534

@@ -117,6 +116,12 @@ def __init__(self, net: Network, weights: NetworkWeights):
117116

118117
if hasattr(self.sd_module, 'weight'):
119118
self.shape = self.sd_module.weight.shape
119+
elif isinstance(self.sd_module, nn.MultiheadAttention):
120+
# For now, only self-attn use Pytorch's MHA
121+
# So assume all qkvo proj have same shape
122+
self.shape = self.sd_module.out_proj.weight.shape
123+
else:
124+
self.shape = None
120125

121126
self.ops = None
122127
self.extra_kwargs = {}
@@ -146,6 +151,9 @@ def __init__(self, net: Network, weights: NetworkWeights):
146151
self.alpha = weights.w["alpha"].item() if "alpha" in weights.w else None
147152
self.scale = weights.w["scale"].item() if "scale" in weights.w else None
148153

154+
self.dora_scale = weights.w.get("dora_scale", None)
155+
self.dora_norm_dims = len(self.shape) - 1
156+
149157
def multiplier(self):
150158
if 'transformer' in self.sd_key[:20]:
151159
return self.network.te_multiplier
@@ -160,6 +168,27 @@ def calc_scale(self):
160168

161169
return 1.0
162170

171+
def apply_weight_decompose(self, updown, orig_weight):
172+
# Match the device/dtype
173+
orig_weight = orig_weight.to(updown.dtype)
174+
dora_scale = self.dora_scale.to(device=orig_weight.device, dtype=updown.dtype)
175+
updown = updown.to(orig_weight.device)
176+
177+
merged_scale1 = updown + orig_weight
178+
merged_scale1_norm = (
179+
merged_scale1.transpose(0, 1)
180+
.reshape(merged_scale1.shape[1], -1)
181+
.norm(dim=1, keepdim=True)
182+
.reshape(merged_scale1.shape[1], *[1] * self.dora_norm_dims)
183+
.transpose(0, 1)
184+
)
185+
186+
dora_merged = (
187+
merged_scale1 * (dora_scale / merged_scale1_norm)
188+
)
189+
final_updown = dora_merged - orig_weight
190+
return final_updown
191+
163192
def finalize_updown(self, updown, orig_weight, output_shape, ex_bias=None):
164193
if self.bias is not None:
165194
updown = updown.reshape(self.bias.shape)
@@ -175,6 +204,9 @@ def finalize_updown(self, updown, orig_weight, output_shape, ex_bias=None):
175204
if ex_bias is not None:
176205
ex_bias = ex_bias * self.multiplier()
177206

207+
if self.dora_scale is not None:
208+
updown = self.apply_weight_decompose(updown, orig_weight)
209+
178210
return updown * self.calc_scale() * self.multiplier(), ex_bias
179211

180212
def calc_updown(self, target):

extensions-builtin/Lora/network_oft.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,6 @@ def __init__(self, net: network.Network, weights: network.NetworkWeights):
3636
# self.alpha is unused
3737
self.dim = self.oft_blocks.shape[1] # (num_blocks, block_size, block_size)
3838

39-
# LyCORIS BOFT
40-
if self.oft_blocks.dim() == 4:
41-
self.is_boft = True
42-
self.rescale = weights.w.get('rescale', None)
43-
if self.rescale is not None:
44-
self.rescale = self.rescale.reshape(-1, *[1]*(self.org_module[0].weight.dim() - 1))
45-
4639
is_linear = type(self.sd_module) in [torch.nn.Linear, torch.nn.modules.linear.NonDynamicallyQuantizableLinear]
4740
is_conv = type(self.sd_module) in [torch.nn.Conv2d]
4841
is_other_linear = type(self.sd_module) in [torch.nn.MultiheadAttention] # unsupported
@@ -54,6 +47,13 @@ def __init__(self, net: network.Network, weights: network.NetworkWeights):
5447
elif is_other_linear:
5548
self.out_dim = self.sd_module.embed_dim
5649

50+
# LyCORIS BOFT
51+
if self.oft_blocks.dim() == 4:
52+
self.is_boft = True
53+
self.rescale = weights.w.get('rescale', None)
54+
if self.rescale is not None and not is_other_linear:
55+
self.rescale = self.rescale.reshape(-1, *[1]*(self.org_module[0].weight.dim() - 1))
56+
5757
self.num_blocks = self.dim
5858
self.block_size = self.out_dim // self.dim
5959
self.constraint = (0 if self.alpha is None else self.alpha) * self.out_dim

extensions-builtin/Lora/networks.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ def network_apply_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn
355355
"""
356356
Applies the currently selected set of networks to the weights of torch layer self.
357357
If weights already have this particular set of networks applied, does nothing.
358-
If not, restores orginal weights from backup and alters weights according to networks.
358+
If not, restores original weights from backup and alters weights according to networks.
359359
"""
360360

361361
network_layer_name = getattr(self, 'network_layer_name', None)
@@ -429,9 +429,12 @@ def network_apply_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn
429429
if isinstance(self, torch.nn.MultiheadAttention) and module_q and module_k and module_v and module_out:
430430
try:
431431
with torch.no_grad():
432-
updown_q, _ = module_q.calc_updown(self.in_proj_weight)
433-
updown_k, _ = module_k.calc_updown(self.in_proj_weight)
434-
updown_v, _ = module_v.calc_updown(self.in_proj_weight)
432+
# Send "real" orig_weight into MHA's lora module
433+
qw, kw, vw = self.in_proj_weight.chunk(3, 0)
434+
updown_q, _ = module_q.calc_updown(qw)
435+
updown_k, _ = module_k.calc_updown(kw)
436+
updown_v, _ = module_v.calc_updown(vw)
437+
del qw, kw, vw
435438
updown_qkv = torch.vstack([updown_q, updown_k, updown_v])
436439
updown_out, ex_bias = module_out.calc_updown(self.out_proj.weight)
437440

extensions-builtin/Lora/ui_edit_user_metadata.py

+2
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ def generate_random_prompt_from_tags(self, tags):
149149

150150
v = random.random() * max_count
151151
if count > v:
152+
for x in "({[]})":
153+
tag = tag.replace(x, '\\' + x)
152154
res.append(tag)
153155

154156
return ", ".join(sorted(res))

extensions-builtin/Lora/ui_extra_networks_lora.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def create_item(self, name, index=None, enable_filter=True):
3131
"name": name,
3232
"filename": lora_on_disk.filename,
3333
"shorthash": lora_on_disk.shorthash,
34-
"preview": self.find_preview(path),
34+
"preview": self.find_preview(path) or self.find_embedded_preview(path, name, lora_on_disk.metadata),
3535
"description": self.find_description(path),
3636
"search_terms": search_terms,
3737
"local_preview": f"{path}.{shared.opts.samples_format}",

0 commit comments

Comments
 (0)