Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Overbill1683
Stable Diffusion Webui
提交
68f336bd
S
Stable Diffusion Webui
项目概览
Overbill1683
/
Stable Diffusion Webui
8 个月 前同步成功
通知
1701
Star
78
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
分析
仓库
DevOps
项目成员
Pages
S
Stable Diffusion Webui
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Pages
分析
分析
仓库分析
DevOps
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
提交
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
68f336bd
编写于
7月 27, 2023
作者:
A
AUTOMATIC1111
1
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'release_candidate'
上级
a3ddf464
50973ec7
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
140 addition
and
164 deletion
+140
-164
CHANGELOG.md
CHANGELOG.md
+25
-0
extensions-builtin/Lora/network.py
extensions-builtin/Lora/network.py
+1
-0
extensions-builtin/Lora/networks.py
extensions-builtin/Lora/networks.py
+5
-0
javascript/badScaleChecker.js
javascript/badScaleChecker.js
+0
-108
modules/api/api.py
modules/api/api.py
+22
-18
modules/api/models.py
modules/api/models.py
+2
-4
modules/extensions.py
modules/extensions.py
+6
-4
modules/launch_utils.py
modules/launch_utils.py
+4
-4
modules/processing.py
modules/processing.py
+26
-15
modules/prompt_parser.py
modules/prompt_parser.py
+1
-1
modules/scripts.py
modules/scripts.py
+33
-1
modules/sd_hijack.py
modules/sd_hijack.py
+1
-1
modules/sd_hijack_clip.py
modules/sd_hijack_clip.py
+7
-2
modules/ui_extra_networks.py
modules/ui_extra_networks.py
+1
-1
style.css
style.css
+4
-3
webui.py
webui.py
+2
-2
未找到文件。
CHANGELOG.md
浏览文件 @
68f336bd
## 1.5.1
### Minor:
*
support parsing text encoder blocks in some new LoRAs
*
delete scale checker script due to user demand
### Extensions and API:
*
add postprocess_batch_list script callback
### Bug Fixes:
*
fix TI training for SD1
*
fix reload altclip model error
*
prepend the pythonpath instead of overriding it
*
fix typo in SD_WEBUI_RESTARTING
*
if txt2img/img2img raises an exception, finally call state.end()
*
fix composable diffusion weight parsing
*
restyle Startup profile for black users
*
fix webui not launching with --nowebui
*
catch exception for non git extensions
*
fix some options missing from /sdapi/v1/options
*
fix for extension update status always saying "unknown"
*
fix display of extra network cards that have
`<>`
in the name
*
update lora extension to work with python 3.8
## 1.5.0
### Features:
...
...
extensions-builtin/Lora/network.py
浏览文件 @
68f336bd
from
__future__
import
annotations
import
os
from
collections
import
namedtuple
import
enum
...
...
extensions-builtin/Lora/networks.py
浏览文件 @
68f336bd
...
...
@@ -163,6 +163,11 @@ def load_network(name, network_on_disk):
key
=
key_network_without_network_parts
.
replace
(
"lora_te1_text_model"
,
"0_transformer_text_model"
)
sd_module
=
shared
.
sd_model
.
network_layer_mapping
.
get
(
key
,
None
)
# some SD1 Loras also have correct compvis keys
if
sd_module
is
None
:
key
=
key_network_without_network_parts
.
replace
(
"lora_te1_text_model"
,
"transformer_text_model"
)
sd_module
=
shared
.
sd_model
.
network_layer_mapping
.
get
(
key
,
None
)
if
sd_module
is
None
:
keys_failed_to_match
[
key_network
]
=
key
continue
...
...
javascript/badScaleChecker.js
已删除
100644 → 0
浏览文件 @
a3ddf464
(
function
()
{
var
ignore
=
localStorage
.
getItem
(
"
bad-scale-ignore-it
"
)
==
"
ignore-it
"
;
function
getScale
()
{
var
ratio
=
0
,
screen
=
window
.
screen
,
ua
=
navigator
.
userAgent
.
toLowerCase
();
if
(
window
.
devicePixelRatio
!==
undefined
)
{
ratio
=
window
.
devicePixelRatio
;
}
else
if
(
~
ua
.
indexOf
(
'
msie
'
))
{
if
(
screen
.
deviceXDPI
&&
screen
.
logicalXDPI
)
{
ratio
=
screen
.
deviceXDPI
/
screen
.
logicalXDPI
;
}
}
else
if
(
window
.
outerWidth
!==
undefined
&&
window
.
innerWidth
!==
undefined
)
{
ratio
=
window
.
outerWidth
/
window
.
innerWidth
;
}
return
ratio
==
0
?
0
:
Math
.
round
(
ratio
*
100
);
}
var
showing
=
false
;
var
div
=
document
.
createElement
(
"
div
"
);
div
.
style
.
position
=
"
fixed
"
;
div
.
style
.
top
=
"
0px
"
;
div
.
style
.
left
=
"
0px
"
;
div
.
style
.
width
=
"
100vw
"
;
div
.
style
.
backgroundColor
=
"
firebrick
"
;
div
.
style
.
textAlign
=
"
center
"
;
div
.
style
.
zIndex
=
99
;
var
b
=
document
.
createElement
(
"
b
"
);
b
.
innerHTML
=
'
Bad Scale: ??%
'
;
div
.
appendChild
(
b
);
var
note1
=
document
.
createElement
(
"
p
"
);
note1
.
innerHTML
=
"
Change your browser or your computer settings!
"
;
note1
.
title
=
'
Just make sure "computer-scale" * "browser-scale" = 100% ,
\n
'
+
"
you can keep your computer-scale and only change this page's scale,
\n
"
+
"
for example: your computer-scale is 125%, just use [
\"
CTRL
\"
+
\"
-
\"
] to make your browser-scale of this page to 80%.
"
;
div
.
appendChild
(
note1
);
var
note2
=
document
.
createElement
(
"
p
"
);
note2
.
innerHTML
=
"
Otherwise, it will cause this page to not function properly!
"
;
note2
.
title
=
"
When you click
\"
Copy image to: [inpaint sketch]
\"
in some img2img's tab,
\n
"
+
"
if scale<100% the canvas will be invisible,
\n
"
+
"
else if scale>100% this page will take large amount of memory and CPU performance.
"
;
div
.
appendChild
(
note2
);
var
btn
=
document
.
createElement
(
"
button
"
);
btn
.
innerHTML
=
"
Click here to ignore
"
;
div
.
appendChild
(
btn
);
function
tryShowTopBar
(
scale
)
{
if
(
showing
)
return
;
b
.
innerHTML
=
'
Bad Scale:
'
+
scale
+
'
%
'
;
var
updateScaleTimer
=
setInterval
(
function
()
{
var
newScale
=
getScale
();
b
.
innerHTML
=
'
Bad Scale:
'
+
newScale
+
'
%
'
;
if
(
newScale
==
100
)
{
var
p
=
div
.
parentNode
;
if
(
p
!=
null
)
p
.
removeChild
(
div
);
showing
=
false
;
clearInterval
(
updateScaleTimer
);
check
();
}
},
999
);
btn
.
onclick
=
function
()
{
clearInterval
(
updateScaleTimer
);
var
p
=
div
.
parentNode
;
if
(
p
!=
null
)
p
.
removeChild
(
div
);
ignore
=
true
;
showing
=
false
;
localStorage
.
setItem
(
"
bad-scale-ignore-it
"
,
"
ignore-it
"
);
};
document
.
body
.
appendChild
(
div
);
}
function
check
()
{
if
(
!
ignore
)
{
var
timer
=
setInterval
(
function
()
{
var
scale
=
getScale
();
if
(
scale
!=
100
&&
!
ignore
)
{
tryShowTopBar
(
scale
);
clearInterval
(
timer
);
}
if
(
ignore
)
{
clearInterval
(
timer
);
}
},
999
);
}
}
if
(
document
.
readyState
!=
"
complete
"
)
{
document
.
onreadystatechange
=
function
()
{
if
(
document
.
readyState
!=
"
complete
"
)
check
();
};
}
else
{
check
();
}
})();
modules/api/api.py
浏览文件 @
68f336bd
...
...
@@ -333,14 +333,16 @@ class Api:
p
.
outpath_grids
=
opts
.
outdir_txt2img_grids
p
.
outpath_samples
=
opts
.
outdir_txt2img_samples
shared
.
state
.
begin
(
job
=
"scripts_txt2img"
)
if
selectable_scripts
is
not
None
:
p
.
script_args
=
script_args
processed
=
scripts
.
scripts_txt2img
.
run
(
p
,
*
p
.
script_args
)
# Need to pass args as list here
else
:
p
.
script_args
=
tuple
(
script_args
)
# Need to pass args as tuple here
processed
=
process_images
(
p
)
shared
.
state
.
end
()
try
:
shared
.
state
.
begin
(
job
=
"scripts_txt2img"
)
if
selectable_scripts
is
not
None
:
p
.
script_args
=
script_args
processed
=
scripts
.
scripts_txt2img
.
run
(
p
,
*
p
.
script_args
)
# Need to pass args as list here
else
:
p
.
script_args
=
tuple
(
script_args
)
# Need to pass args as tuple here
processed
=
process_images
(
p
)
finally
:
shared
.
state
.
end
()
b64images
=
list
(
map
(
encode_pil_to_base64
,
processed
.
images
))
if
send_images
else
[]
...
...
@@ -390,14 +392,16 @@ class Api:
p
.
outpath_grids
=
opts
.
outdir_img2img_grids
p
.
outpath_samples
=
opts
.
outdir_img2img_samples
shared
.
state
.
begin
(
job
=
"scripts_img2img"
)
if
selectable_scripts
is
not
None
:
p
.
script_args
=
script_args
processed
=
scripts
.
scripts_img2img
.
run
(
p
,
*
p
.
script_args
)
# Need to pass args as list here
else
:
p
.
script_args
=
tuple
(
script_args
)
# Need to pass args as tuple here
processed
=
process_images
(
p
)
shared
.
state
.
end
()
try
:
shared
.
state
.
begin
(
job
=
"scripts_img2img"
)
if
selectable_scripts
is
not
None
:
p
.
script_args
=
script_args
processed
=
scripts
.
scripts_img2img
.
run
(
p
,
*
p
.
script_args
)
# Need to pass args as list here
else
:
p
.
script_args
=
tuple
(
script_args
)
# Need to pass args as tuple here
processed
=
process_images
(
p
)
finally
:
shared
.
state
.
end
()
b64images
=
list
(
map
(
encode_pil_to_base64
,
processed
.
images
))
if
send_images
else
[]
...
...
@@ -720,9 +724,9 @@ class Api:
cuda
=
{
'error'
:
f
'
{
err
}
'
}
return
models
.
MemoryResponse
(
ram
=
ram
,
cuda
=
cuda
)
def
launch
(
self
,
server_name
,
port
):
def
launch
(
self
,
server_name
,
port
,
root_path
):
self
.
app
.
include_router
(
self
.
router
)
uvicorn
.
run
(
self
.
app
,
host
=
server_name
,
port
=
port
,
timeout_keep_alive
=
shared
.
cmd_opts
.
timeout_keep_alive
)
uvicorn
.
run
(
self
.
app
,
host
=
server_name
,
port
=
port
,
timeout_keep_alive
=
shared
.
cmd_opts
.
timeout_keep_alive
,
root_path
=
root_path
)
def
kill_webui
(
self
):
restart
.
stop_program
()
...
...
modules/api/models.py
浏览文件 @
68f336bd
...
...
@@ -208,11 +208,9 @@ class PreprocessResponse(BaseModel):
fields
=
{}
for
key
,
metadata
in
opts
.
data_labels
.
items
():
value
=
opts
.
data
.
get
(
key
)
optType
=
opts
.
typemap
.
get
(
type
(
metadata
.
default
),
type
(
metadata
.
default
))
optType
=
opts
.
typemap
.
get
(
type
(
metadata
.
default
),
type
(
metadata
.
default
))
if
metadata
.
default
else
Any
if
metadata
.
default
is
None
:
pass
elif
metadata
is
not
None
:
if
metadata
is
not
None
:
fields
.
update
({
key
:
(
Optional
[
optType
],
Field
(
default
=
metadata
.
default
,
description
=
metadata
.
label
))})
else
:
fields
.
update
({
key
:
(
Optional
[
optType
],
Field
())})
...
...
modules/extensions.py
浏览文件 @
68f336bd
...
...
@@ -56,10 +56,12 @@ class Extension:
self
.
do_read_info_from_repo
()
return
self
.
to_dict
()
d
=
cache
.
cached_data_for_file
(
'extensions-git'
,
self
.
name
,
os
.
path
.
join
(
self
.
path
,
".git"
),
read_from_repo
)
self
.
from_dict
(
d
)
self
.
status
=
'unknown'
try
:
d
=
cache
.
cached_data_for_file
(
'extensions-git'
,
self
.
name
,
os
.
path
.
join
(
self
.
path
,
".git"
),
read_from_repo
)
self
.
from_dict
(
d
)
except
FileNotFoundError
:
pass
self
.
status
=
'unknown'
if
self
.
status
==
''
else
self
.
status
def
do_read_info_from_repo
(
self
):
repo
=
None
...
...
modules/launch_utils.py
浏览文件 @
68f336bd
...
...
@@ -196,7 +196,7 @@ def run_extension_installer(extension_dir):
try
:
env
=
os
.
environ
.
copy
()
env
[
'PYTHONPATH'
]
=
os
.
path
.
abspath
(
"."
)
env
[
'PYTHONPATH'
]
=
f
"
{
os
.
path
.
abspath
(
'.'
)
}{
os
.
pathsep
}{
env
.
get
(
'PYTHONPATH'
,
''
)
}
"
print
(
run
(
f
'"
{
python
}
" "
{
path_installer
}
"'
,
errdesc
=
f
"Error running install.py for extension
{
extension_dir
}
"
,
custom_env
=
env
))
except
Exception
as
e
:
...
...
@@ -233,7 +233,7 @@ def run_extensions_installers(settings_file):
re_requirement
=
re
.
compile
(
r
"\s*([-_a-zA-Z0-9]+)\s*(?:==\s*([-+_.a-zA-Z0-9]+))?\s*"
)
def
requrements_met
(
requirements_file
):
def
requ
i
rements_met
(
requirements_file
):
"""
Does a simple parse of a requirements.txt file to determine if all rerqirements in it
are already installed. Returns True if so, False if not installed or parsing fails.
...
...
@@ -293,7 +293,7 @@ def prepare_environment():
try
:
# the existance of this file is a signal to webui.sh/bat that webui needs to be restarted when it stops execution
os
.
remove
(
os
.
path
.
join
(
script_path
,
"tmp"
,
"restart"
))
os
.
environ
.
setdefault
(
'SD_WEBUI_RESTARTING
'
,
'1'
)
os
.
environ
.
setdefault
(
'SD_WEBUI_RESTARTING'
,
'1'
)
except
OSError
:
pass
...
...
@@ -354,7 +354,7 @@ def prepare_environment():
if
not
os
.
path
.
isfile
(
requirements_file
):
requirements_file
=
os
.
path
.
join
(
script_path
,
requirements_file
)
if
not
requrements_met
(
requirements_file
):
if
not
requ
i
rements_met
(
requirements_file
):
run_pip
(
f
"install -r
\"
{
requirements_file
}
\"
"
,
"requirements"
)
run_extensions_installers
(
settings_file
=
args
.
ui_settings_file
)
...
...
modules/processing.py
浏览文件 @
68f336bd
...
...
@@ -600,8 +600,12 @@ def program_version():
return
res
def
create_infotext
(
p
,
all_prompts
,
all_seeds
,
all_subseeds
,
comments
=
None
,
iteration
=
0
,
position_in_batch
=
0
,
use_main_prompt
=
False
):
index
=
position_in_batch
+
iteration
*
p
.
batch_size
def
create_infotext
(
p
,
all_prompts
,
all_seeds
,
all_subseeds
,
comments
=
None
,
iteration
=
0
,
position_in_batch
=
0
,
use_main_prompt
=
False
,
index
=
None
,
all_negative_prompts
=
None
):
if
index
is
None
:
index
=
position_in_batch
+
iteration
*
p
.
batch_size
if
all_negative_prompts
is
None
:
all_negative_prompts
=
p
.
all_negative_prompts
clip_skip
=
getattr
(
p
,
'clip_skip'
,
opts
.
CLIP_stop_at_last_layers
)
enable_hr
=
getattr
(
p
,
'enable_hr'
,
False
)
...
...
@@ -617,12 +621,12 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter
"Sampler"
:
p
.
sampler_name
,
"CFG scale"
:
p
.
cfg_scale
,
"Image CFG scale"
:
getattr
(
p
,
'image_cfg_scale'
,
None
),
"Seed"
:
all_seeds
[
index
],
"Seed"
:
p
.
all_seeds
[
0
]
if
use_main_prompt
else
all_seeds
[
index
],
"Face restoration"
:
(
opts
.
face_restoration_model
if
p
.
restore_faces
else
None
),
"Size"
:
f
"
{
p
.
width
}
x
{
p
.
height
}
"
,
"Model hash"
:
getattr
(
p
,
'sd_model_hash'
,
None
if
not
opts
.
add_model_hash_to_info
or
not
shared
.
sd_model
.
sd_model_hash
else
shared
.
sd_model
.
sd_model_hash
),
"Model"
:
(
None
if
not
opts
.
add_model_name_to_info
else
shared
.
sd_model
.
sd_checkpoint_info
.
name_for_extra
),
"Variation seed"
:
(
None
if
p
.
subseed_strength
==
0
else
all_subseeds
[
index
]
),
"Variation seed"
:
(
None
if
p
.
subseed_strength
==
0
else
(
p
.
all_subseeds
[
0
]
if
use_main_prompt
else
all_subseeds
[
index
])
),
"Variation seed strength"
:
(
None
if
p
.
subseed_strength
==
0
else
p
.
subseed_strength
),
"Seed resize from"
:
(
None
if
p
.
seed_resize_from_w
<=
0
or
p
.
seed_resize_from_h
<=
0
else
f
"
{
p
.
seed_resize_from_w
}
x
{
p
.
seed_resize_from_h
}
"
),
"Denoising strength"
:
getattr
(
p
,
'denoising_strength'
,
None
),
...
...
@@ -642,7 +646,7 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter
generation_params_text
=
", "
.
join
([
k
if
k
==
v
else
f
'
{
k
}
:
{
generation_parameters_copypaste
.
quote
(
v
)
}
'
for
k
,
v
in
generation_params
.
items
()
if
v
is
not
None
])
prompt_text
=
p
.
prompt
if
use_main_prompt
else
all_prompts
[
index
]
negative_prompt_text
=
f
"
\n
Negative prompt:
{
p
.
all_negative_prompts
[
index
]
}
"
if
p
.
all_negative_prompts
[
index
]
else
""
negative_prompt_text
=
f
"
\n
Negative prompt:
{
all_negative_prompts
[
index
]
}
"
if
all_negative_prompts
[
index
]
else
""
return
f
"
{
prompt_text
}{
negative_prompt_text
}
\n
{
generation_params_text
}
"
.
strip
()
...
...
@@ -716,9 +720,6 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
else
:
p
.
all_subseeds
=
[
int
(
subseed
)
+
x
for
x
in
range
(
len
(
p
.
all_prompts
))]
def
infotext
(
iteration
=
0
,
position_in_batch
=
0
,
use_main_prompt
=
False
):
return
create_infotext
(
p
,
p
.
all_prompts
,
p
.
all_seeds
,
p
.
all_subseeds
,
comments
,
iteration
,
position_in_batch
,
use_main_prompt
)
if
os
.
path
.
exists
(
cmd_opts
.
embeddings_dir
)
and
not
p
.
do_not_reload_embeddings
:
model_hijack
.
embedding_db
.
load_textual_inversion_embeddings
()
...
...
@@ -806,6 +807,16 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
if
p
.
scripts
is
not
None
:
p
.
scripts
.
postprocess_batch
(
p
,
x_samples_ddim
,
batch_number
=
n
)
p
.
prompts
=
p
.
all_prompts
[
n
*
p
.
batch_size
:(
n
+
1
)
*
p
.
batch_size
]
p
.
negative_prompts
=
p
.
all_negative_prompts
[
n
*
p
.
batch_size
:(
n
+
1
)
*
p
.
batch_size
]
batch_params
=
scripts
.
PostprocessBatchListArgs
(
list
(
x_samples_ddim
))
p
.
scripts
.
postprocess_batch_list
(
p
,
batch_params
,
batch_number
=
n
)
x_samples_ddim
=
batch_params
.
images
def
infotext
(
index
=
0
,
use_main_prompt
=
False
):
return
create_infotext
(
p
,
p
.
prompts
,
p
.
seeds
,
p
.
subseeds
,
use_main_prompt
=
use_main_prompt
,
index
=
index
,
all_negative_prompts
=
p
.
negative_prompts
)
for
i
,
x_sample
in
enumerate
(
x_samples_ddim
):
p
.
batch_index
=
i
...
...
@@ -814,7 +825,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
if
p
.
restore_faces
:
if
opts
.
save
and
not
p
.
do_not_save_samples
and
opts
.
save_images_before_face_restoration
:
images
.
save_image
(
Image
.
fromarray
(
x_sample
),
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
n
,
i
),
p
=
p
,
suffix
=
"-before-face-restoration"
)
images
.
save_image
(
Image
.
fromarray
(
x_sample
),
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
i
),
p
=
p
,
suffix
=
"-before-face-restoration"
)
devices
.
torch_gc
()
...
...
@@ -831,15 +842,15 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
if
p
.
color_corrections
is
not
None
and
i
<
len
(
p
.
color_corrections
):
if
opts
.
save
and
not
p
.
do_not_save_samples
and
opts
.
save_images_before_color_correction
:
image_without_cc
=
apply_overlay
(
image
,
p
.
paste_to
,
i
,
p
.
overlay_images
)
images
.
save_image
(
image_without_cc
,
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
n
,
i
),
p
=
p
,
suffix
=
"-before-color-correction"
)
images
.
save_image
(
image_without_cc
,
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
i
),
p
=
p
,
suffix
=
"-before-color-correction"
)
image
=
apply_color_correction
(
p
.
color_corrections
[
i
],
image
)
image
=
apply_overlay
(
image
,
p
.
paste_to
,
i
,
p
.
overlay_images
)
if
opts
.
samples_save
and
not
p
.
do_not_save_samples
:
images
.
save_image
(
image
,
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
n
,
i
),
p
=
p
)
images
.
save_image
(
image
,
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
i
),
p
=
p
)
text
=
infotext
(
n
,
i
)
text
=
infotext
(
i
)
infotexts
.
append
(
text
)
if
opts
.
enable_pnginfo
:
image
.
info
[
"parameters"
]
=
text
...
...
@@ -850,10 +861,10 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
image_mask_composite
=
Image
.
composite
(
image
.
convert
(
'RGBA'
).
convert
(
'RGBa'
),
Image
.
new
(
'RGBa'
,
image
.
size
),
images
.
resize_image
(
2
,
p
.
mask_for_overlay
,
image
.
width
,
image
.
height
).
convert
(
'L'
)).
convert
(
'RGBA'
)
if
opts
.
save_mask
:
images
.
save_image
(
image_mask
,
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
n
,
i
),
p
=
p
,
suffix
=
"-mask"
)
images
.
save_image
(
image_mask
,
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
i
),
p
=
p
,
suffix
=
"-mask"
)
if
opts
.
save_mask_composite
:
images
.
save_image
(
image_mask_composite
,
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
n
,
i
),
p
=
p
,
suffix
=
"-mask-composite"
)
images
.
save_image
(
image_mask_composite
,
p
.
outpath_samples
,
""
,
p
.
seeds
[
i
],
p
.
prompts
[
i
],
opts
.
samples_format
,
info
=
infotext
(
i
),
p
=
p
,
suffix
=
"-mask-composite"
)
if
opts
.
return_mask
:
output_images
.
append
(
image_mask
)
...
...
@@ -894,7 +905,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
p
,
images_list
=
output_images
,
seed
=
p
.
all_seeds
[
0
],
info
=
infotext
()
,
info
=
infotext
s
[
0
]
,
comments
=
""
.
join
(
f
"
{
comment
}
\n
"
for
comment
in
comments
),
subseed
=
p
.
all_subseeds
[
0
],
index_of_first_image
=
index_of_first_image
,
...
...
modules/prompt_parser.py
浏览文件 @
68f336bd
...
...
@@ -178,7 +178,7 @@ def get_learned_conditioning(model, prompts: SdConditioning | list[str], steps):
re_AND
=
re
.
compile
(
r
"\bAND\b"
)
re_weight
=
re
.
compile
(
r
"^(
.
*?)(?:\s*:\s*([-+]?(?:\d+\.?|\d*\.\d+)))?\s*$"
)
re_weight
=
re
.
compile
(
r
"^(
(?:\s|.)
*?)(?:\s*:\s*([-+]?(?:\d+\.?|\d*\.\d+)))?\s*$"
)
def
get_multicond_prompt_list
(
prompts
:
SdConditioning
|
list
[
str
]):
...
...
modules/scripts.py
浏览文件 @
68f336bd
...
...
@@ -16,6 +16,11 @@ class PostprocessImageArgs:
self
.
image
=
image
class
PostprocessBatchListArgs
:
def
__init__
(
self
,
images
):
self
.
images
=
images
class
Script
:
name
=
None
"""script's internal name derived from title"""
...
...
@@ -119,7 +124,7 @@ class Script:
def
after_extra_networks_activate
(
self
,
p
,
*
args
,
**
kwargs
):
"""
Calledafter extra networks activation, before conds calculation
Called
after extra networks activation, before conds calculation
allow modification of the network after extra networks activation been applied
won't be call if p.disable_extra_networks
...
...
@@ -156,6 +161,25 @@ class Script:
pass
def
postprocess_batch_list
(
self
,
p
,
pp
:
PostprocessBatchListArgs
,
*
args
,
**
kwargs
):
"""
Same as postprocess_batch(), but receives batch images as a list of 3D tensors instead of a 4D tensor.
This is useful when you want to update the entire batch instead of individual images.
You can modify the postprocessing object (pp) to update the images in the batch, remove images, add images, etc.
If the number of images is different from the batch size when returning,
then the script has the responsibility to also update the following attributes in the processing object (p):
- p.prompts
- p.negative_prompts
- p.seeds
- p.subseeds
**kwargs will have same items as process_batch, and also:
- batch_number - index of current batch, from 0 to number of batches-1
"""
pass
def
postprocess_image
(
self
,
p
,
pp
:
PostprocessImageArgs
,
*
args
):
"""
Called for every image after it has been generated.
...
...
@@ -536,6 +560,14 @@ class ScriptRunner:
except
Exception
:
errors
.
report
(
f
"Error running postprocess_batch:
{
script
.
filename
}
"
,
exc_info
=
True
)
def
postprocess_batch_list
(
self
,
p
,
pp
:
PostprocessBatchListArgs
,
**
kwargs
):
for
script
in
self
.
alwayson_scripts
:
try
:
script_args
=
p
.
script_args
[
script
.
args_from
:
script
.
args_to
]
script
.
postprocess_batch_list
(
p
,
pp
,
*
script_args
,
**
kwargs
)
except
Exception
:
errors
.
report
(
f
"Error running postprocess_batch_list:
{
script
.
filename
}
"
,
exc_info
=
True
)
def
postprocess_image
(
self
,
p
,
pp
:
PostprocessImageArgs
):
for
script
in
self
.
alwayson_scripts
:
try
:
...
...
modules/sd_hijack.py
浏览文件 @
68f336bd
...
...
@@ -243,7 +243,7 @@ class StableDiffusionModelHijack:
ldm
.
modules
.
diffusionmodules
.
openaimodel
.
UNetModel
.
forward
=
sd_unet
.
UNetModel_forward
def
undo_hijack
(
self
,
m
):
if
type
(
m
.
cond_stage_model
)
==
xlmr
.
BertSeriesModelWithTransformation
:
if
type
(
m
.
cond_stage_model
)
==
sd_hijack_xlmr
.
FrozenXLMREmbedderWithCustomWords
:
m
.
cond_stage_model
=
m
.
cond_stage_model
.
wrapped
elif
type
(
m
.
cond_stage_model
)
==
sd_hijack_clip
.
FrozenCLIPEmbedderWithCustomWords
:
...
...
modules/sd_hijack_clip.py
浏览文件 @
68f336bd
...
...
@@ -270,12 +270,17 @@ class FrozenCLIPEmbedderWithCustomWordsBase(torch.nn.Module):
z
=
self
.
encode_with_transformers
(
tokens
)
pooled
=
getattr
(
z
,
'pooled'
,
None
)
# restoring original mean is likely not correct, but it seems to work well to prevent artifacts that happen otherwise
batch_multipliers
=
torch
.
asarray
(
batch_multipliers
).
to
(
devices
.
device
)
original_mean
=
z
.
mean
()
z
*=
batch_multipliers
.
reshape
(
batch_multipliers
.
shape
+
(
1
,)).
expand
(
z
.
shape
)
z
=
z
*
batch_multipliers
.
reshape
(
batch_multipliers
.
shape
+
(
1
,)).
expand
(
z
.
shape
)
new_mean
=
z
.
mean
()
z
*=
(
original_mean
/
new_mean
)
z
=
z
*
(
original_mean
/
new_mean
)
if
pooled
is
not
None
:
z
.
pooled
=
pooled
return
z
...
...
modules/ui_extra_networks.py
浏览文件 @
68f336bd
...
...
@@ -253,7 +253,7 @@ class ExtraNetworksPage:
"prompt"
:
item
.
get
(
"prompt"
,
None
),
"tabname"
:
quote_js
(
tabname
),
"local_preview"
:
quote_js
(
item
[
"local_preview"
]),
"name"
:
item
[
"name"
]
,
"name"
:
html
.
escape
(
item
[
"name"
])
,
"description"
:
(
item
.
get
(
"description"
)
or
""
if
shared
.
opts
.
extra_networks_card_show_desc
else
""
),
"card_clicked"
:
onclick
,
"save_card_preview"
:
'"'
+
html
.
escape
(
f
"""return saveCardPreview(event,
{
quote_js
(
tabname
)
}
,
{
quote_js
(
item
[
"local_preview"
])
}
)"""
)
+
'"'
,
...
...
style.css
浏览文件 @
68f336bd
...
...
@@ -423,15 +423,16 @@ div#extras_scale_to_tab div.form{
}
table
.popup-table
{
background
:
white
;
background
:
var
(
--body-background-fill
);
color
:
var
(
--body-text-color
);
border-collapse
:
collapse
;
margin
:
1em
;
border
:
4px
solid
white
;
border
:
4px
solid
var
(
--body-background-fill
)
;
}
table
.popup-table
td
{
padding
:
0.4em
;
border
:
1px
solid
#ccc
;
border
:
1px
solid
rgba
(
128
,
128
,
128
,
0.5
)
;
max-width
:
36em
;
}
...
...
webui.py
浏览文件 @
68f336bd
...
...
@@ -374,7 +374,7 @@ def api_only():
api
.
launch
(
server_name
=
"0.0.0.0"
if
cmd_opts
.
listen
else
"127.0.0.1"
,
port
=
cmd_opts
.
port
if
cmd_opts
.
port
else
7861
,
root_path
=
f
"/
{
cmd_opts
.
subpath
}
"
root_path
=
f
"/
{
cmd_opts
.
subpath
}
"
if
cmd_opts
.
subpath
else
"
"
)
...
...
@@ -407,7 +407,7 @@ def webui():
ssl_verify
=
cmd_opts
.
disable_tls_verify
,
debug
=
cmd_opts
.
gradio_debug
,
auth
=
gradio_auth_creds
,
inbrowser
=
cmd_opts
.
autolaunch
and
os
.
getenv
(
'SD_WEBUI_RESTARTING
'
)
!=
'1'
,
inbrowser
=
cmd_opts
.
autolaunch
and
os
.
getenv
(
'SD_WEBUI_RESTARTING'
)
!=
'1'
,
prevent_thread_lock
=
True
,
allowed_paths
=
cmd_opts
.
gradio_allowed_path
,
app_kwargs
=
{
...
...
不蠢不蠢
@hyf81107
·
8月 15, 2023
还是没法使用lora block weight
还是没法使用lora block weight
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录