Compare commits

...

2382 Commits

Author SHA1 Message Date
AUTOMATIC1111
82a973c043 changelog 2024-07-27 15:49:39 +03:00
AUTOMATIC1111
1d7e9eca09 Merge pull request #16275 from AUTOMATIC1111/fix-image-upscale-on-cpu
fix image upscale on cpu
2024-07-27 15:48:22 +03:00
AUTOMATIC1111
c19d044364 Merge branch 'release_candidate' 2024-07-27 06:53:05 +03:00
AUTOMATIC1111
8b3d98c5a5 update CHANGELOG 2024-07-20 11:54:14 +03:00
AUTOMATIC1111
5bbbda473f Merge branch 'dev' into release_candidate 2024-07-20 11:51:12 +03:00
AUTOMATIC1111
9f5a98d576
Merge pull request #16166 from richardtallent/dev
Fix noisy DS_Store files for MacOS
2024-07-20 11:47:50 +03:00
AUTOMATIC1111
986c31dcfe
Merge pull request #16180 from light-and-ray/do_not_send_image_size_on_paste_inpaint
do not send image size on paste inpaint
2024-07-20 11:47:27 +03:00
AUTOMATIC1111
5096c163c1
Merge pull request #16173 from AUTOMATIC1111/robust-sysinfo
Robust sysinfo
2024-07-20 11:46:45 +03:00
AUTOMATIC1111
7b99e14ab1
Merge pull request #16194 from light-and-ray/fix_cannot_write_mode_P_as_jpeg
fix OSError: cannot write mode P as JPEG
2024-07-20 11:46:24 +03:00
AUTOMATIC1111
7c8a4ccecb
Merge pull request #16202 from light-and-ray/do_not_break_progressbar_on_non-job_actions
[bug] do not break progressbar on non-job actions (add wrap_gradio_call_no_job)
2024-07-20 11:45:57 +03:00
AUTOMATIC1111
5d26c6ae89
Merge pull request #16178 from light-and-ray/update_installation_guide_linux
update installation guide linux
2024-07-20 11:44:59 +03:00
AUTOMATIC1111
5a10bb9aa6
Merge pull request #16235 from v0xie/beta-sampling
Feature: Beta scheduler
2024-07-20 11:43:39 +03:00
AUTOMATIC1111
fa0ba939a7
Merge pull request #16218 from Haoming02/resize-tabs-id
add ids to the resize tabs in img2img
2024-07-20 11:43:03 +03:00
AUTOMATIC1111
fc7b25ac67
Merge pull request #16231 from AUTOMATIC1111/bat-activate-venv
activate venv .bat
2024-07-20 11:42:29 +03:00
AUTOMATIC1111
e09104a126
Merge pull request #16239 from AUTOMATIC1111/fix-upscale-logic
fix upscale logic
2024-07-20 11:41:34 +03:00
AUTOMATIC1111
141d4b71b1
Merge pull request #16242 from AUTOMATIC1111/option-to-disable-save-button-log.csv-
option to disable save button log.csv
2024-07-20 11:40:39 +03:00
AUTOMATIC1111
ea903819cb
Merge pull request #16212 from AUTOMATIC1111/sd3_lora
SD3 Lora support
2024-07-20 11:39:53 +03:00
w-e-w
24a23e1225 option to disable save button log.csv 2024-07-20 15:59:44 +09:00
v0xie
8749540602 fix lint 2024-07-19 15:33:07 -07:00
v0xie
9de7084884 always add alpha/beta to extra_generation_params when schedule is Beta 2024-07-19 14:54:24 -07:00
v0xie
94275b115c enforce beta_dist_alpha / beta_dist_beta > 0 to avoid nan 2024-07-19 14:15:55 -07:00
v0xie
e285af6e48 add beta schedule opts to xyz options 2024-07-19 14:15:10 -07:00
v0xie
f6f055a93d use configured alpha/beta values in Beta scheduling 2024-07-19 14:08:44 -07:00
v0xie
3a5a66775c add new options 'beta_dist_alpha', 'beta_dist_beta' 2024-07-19 14:08:08 -07:00
v0xie
7e1bd3e3c3 refactor: syntax and add 0.0 on new line 2024-07-19 13:44:22 -07:00
w-e-w
964fc13a99 fix upscale logic 2024-07-20 04:01:13 +09:00
v0xie
a5f66b5003 feature: beta scheduler 2024-07-18 15:53:54 -07:00
w-e-w
2abc628899 bat activate venv 2024-07-18 23:51:46 +09:00
AUTOMATIC1111
2b50233f3f fix bugs in lora support 2024-07-16 20:50:25 +03:00
Haoming
f5866199c4 add ids 2024-07-16 11:07:22 +08:00
AUTOMATIC1111
7e5cdaab4b SD3 lora support 2024-07-15 08:31:55 +03:00
AUTOMATIC1111
b2453d280a
Merge pull request #16192 from AUTOMATIC1111/patch-#16169
fix #16169 Py 3.9 compatibility
2024-07-13 09:29:47 +03:00
AUTOMATIC1111
b4d62a05af
Merge pull request #16164 from AUTOMATIC1111/sd3_textual_inversion
sd3 TI support
2024-07-13 09:27:46 +03:00
Andray
589dda3cf2 do not break progressbar on non-job actions 2024-07-12 16:08:36 +04:00
Andray
3d2dbefcde fix OSError: cannot write mode P as JPEG 2024-07-11 23:54:25 +04:00
w-e-w
b1695c1b68 fix #16169 Py 3.9 compatibility
Co-Authored-By: SLAPaper Pang <slapaper.pku@gmail.com>
2024-07-11 18:46:54 +09:00
Andray
d57ff884ed do not send image size on paste inpaint 2024-07-09 16:12:39 +04:00
Andray
26cccd8faa update 2024-07-09 14:22:08 +04:00
Andray
9cc7142dd7 update installation guide linux 2024-07-09 14:07:12 +04:00
w-e-w
5a5fe7494a .gitignore sysinfo.json 2024-07-09 02:27:22 +09:00
w-e-w
6a7042fe2f move git_status to sysinfo 2024-07-09 02:27:22 +09:00
w-e-w
72cfa2829d safer Imports 2024-07-09 02:27:22 +09:00
w-e-w
4debd4d3ef compact get_info_from_repo_path 2024-07-09 02:27:22 +09:00
w-e-w
3f6dcda3e5 Extensions info full commit hash 2024-07-09 02:23:23 +09:00
w-e-w
27d96fa608 fallback Extensions info 2024-07-09 02:23:23 +09:00
w-e-w
dd4f798b97 fallback get_config() 2024-07-09 02:23:23 +09:00
w-e-w
27947a79d6 git status 2024-07-09 02:23:23 +09:00
w-e-w
11f827c58b use pip freeze --all to get packages 2024-07-09 02:23:23 +09:00
AUTOMATIC1111
48dd4d9eae Merge pull request #16170 from AUTOMATIC1111/shlex.quote-launch-args-in-console-log
shlex.join launch args in console log
2024-07-08 18:36:56 +03:00
AUTOMATIC1111
93c00b2af7
Merge pull request #16170 from AUTOMATIC1111/shlex.quote-launch-args-in-console-log
shlex.join launch args in console log
2024-07-08 18:36:28 +03:00
w-e-w
7d7f7f4b49 sysinfo handle psutil not working 2024-07-08 16:40:20 +09:00
w-e-w
1b0823db94 shlex.join launch args in console log 2024-07-08 15:32:45 +09:00
AUTOMATIC1111
6ca7a453d4 Merge pull request #16169 from AUTOMATIC1111/py-3.9-compatibility
Py 3.9 compatibility
2024-07-08 08:27:40 +03:00
AUTOMATIC1111
bad47dcfeb
Merge pull request #16169 from AUTOMATIC1111/py-3.9-compatibility
Py 3.9 compatibility
2024-07-08 08:27:07 +03:00
w-e-w
c3d8b78b47 py 3.9 compatibility 2024-07-08 14:17:51 +09:00
w-e-w
21e72d1a5e py 3.9 find_vae() 2024-07-08 14:07:26 +09:00
Richard Tallent
7b2917255a Fix noisy DS_Store files for MacOS 2024-07-07 11:18:17 -05:00
AUTOMATIC1111
11cfe0dd05 sd3 TI support 2024-07-07 16:36:53 +03:00
AUTOMATIC1111
780c70f6ea update changelog 2024-07-07 08:40:19 +03:00
AUTOMATIC1111
b5481c6195 Merge pull request #16153 from light-and-ray/fix_ui_flashing_on_reload_and_fast_scrollong
fix ui flashing on reloading and fast scrollong
2024-07-07 08:38:26 +03:00
AUTOMATIC1111
1da4907927
Merge pull request #16153 from light-and-ray/fix_ui_flashing_on_reload_and_fast_scrollong
fix ui flashing on reloading and fast scrollong
2024-07-07 08:37:58 +03:00
w-e-w
ec580374e5 background-color: background_fill_primary 2024-07-07 00:22:27 +09:00
AUTOMATIC1111
340a9108ca update changelog 2024-07-06 11:26:14 +03:00
AUTOMATIC1111
74069addc3 SD2 v autodetection fix 2024-07-06 11:00:22 +03:00
AUTOMATIC1111
477869c044
Merge pull request #16079 from light-and-ray/fix_sd2_switching
fix sd2 switching
2024-07-06 10:41:16 +03:00
AUTOMATIC1111
ffead92d4e Revert "Merge pull request #16078 from huchenlei/fix_sd2"
This reverts commit 4cc3add770b10cb8e8f7aa980c0d50e5b637ab2b, reversing
changes made to 50514ce414ee4fad9aa4780ef0b97116c7d7c970.
2024-07-06 10:40:48 +03:00
AUTOMATIC1111
0a6628bad0 remove mentions of specific samplers from CFG denoiser code 2024-07-06 10:31:08 +03:00
AUTOMATIC1111
eb112c6f88
Merge pull request #16035 from v0xie/cfgpp
Add new sampler DDIM CFG++
2024-07-06 10:18:49 +03:00
AUTOMATIC1111
ace00a1fe8
Merge pull request #16054 from AUTOMATIC1111/fix-Sampler-Scheduler-autocorrection-warning
Fix sampler scheduler autocorrection warning
2024-07-06 10:11:33 +03:00
AUTOMATIC1111
2fec94710b
Merge pull request #16060 from xiaoxianBoy/fix-typos
chore: fix typos
2024-07-06 10:06:35 +03:00
AUTOMATIC1111
74b56fef3d
Merge pull request #16061 from AUTOMATIC1111/remove-dont_fix_second_order_samplers_schedule
remove deprecated setting dont_fix_second_order_samplers_schedule
2024-07-06 10:06:01 +03:00
AUTOMATIC1111
8058eed6a5
Merge pull request #16059 from viking1304/mac-torch-231
Update torch for ARM Macs to 2.3.1
2024-07-06 10:04:26 +03:00
AUTOMATIC1111
3bd4a08119
Merge pull request #16062 from AUTOMATIC1111/fix-infotext-Lora-hashes-fro-hires-fix-different-lora
fix infotext Lora hashes fro hires fix different lora
2024-07-06 10:04:06 +03:00
AUTOMATIC1111
68df28176c
Merge pull request #16065 from AUTOMATIC1111/ToggleLivePriview-in-image-viewer
ToggleLivePriview button in image viewer
2024-07-06 10:02:01 +03:00
AUTOMATIC1111
4cc3add770
Merge pull request #16078 from huchenlei/fix_sd2
Fix SD2 loading
2024-07-06 09:59:29 +03:00
AUTOMATIC1111
50514ce414
Merge pull request #16085 from light-and-ray/stoping_generation_extras
stoping generation extras
2024-07-06 09:53:03 +03:00
AUTOMATIC1111
edebe4d4de
Merge pull request #16088 from cuba3/dev_cuba3
Maintaining Project Compatibility for Python 3.9 Users Without Upgrade Requirements.
2024-07-06 09:52:40 +03:00
AUTOMATIC1111
b9c3f4ec2c
Merge pull request #16092 from viking1304/bash-python-version
Prioritize python3.10 over python3 if both are available on Linux and Mac (with fallback)
2024-07-06 09:52:14 +03:00
AUTOMATIC1111
41ac13996e
Merge pull request #16102 from eltociear/patch-4
docs: update bug_report.yml
2024-07-06 09:51:44 +03:00
AUTOMATIC1111
76a19c089a
Merge pull request #16116 from viking1304/ensure-venv-use
Ensure use of python from venv on Mac and Linux
2024-07-06 09:49:34 +03:00
AUTOMATIC1111
372a8e0658
Merge pull request #16151 from AUTOMATIC1111/dora-fix
Possible fix of wrong scale in weight decomposition
2024-07-06 09:48:53 +03:00
AUTOMATIC1111
b8c3664934
Merge pull request #16142 from AndreyRGW/dev
Add Simple Scheduler
2024-07-06 09:47:15 +03:00
AUTOMATIC1111
9414309f15
Merge branch 'dev' into dev 2024-07-06 09:46:57 +03:00
AUTOMATIC1111
9cbde7938a
Merge pull request #16118 from AUTOMATIC1111/fix-Replace-preview
fix Replace preview
2024-07-06 09:44:17 +03:00
AUTOMATIC1111
019df53a31
Merge pull request #16119 from AUTOMATIC1111/defunct---max-batch-count
Defunct --max-batch-count
2024-07-06 09:43:09 +03:00
AUTOMATIC1111
af3ccee5c8
Merge pull request #16140 from ibrahimsn98/master
Return HTTP 400 instead of 404 on invalid sampler error
2024-07-06 09:42:44 +03:00
AUTOMATIC1111
a6c384b9f7
Merge pull request #16144 from akx/bump-spandrel
Bump spandrel to 0.3.4
2024-07-06 09:42:14 +03:00
AUTOMATIC1111
b282b47b85
Merge pull request #16149 from AndreyRGW/devpatch1
Add Normal and DDIM Schedulers
2024-07-06 09:41:21 +03:00
AUTOMATIC1111
c02e3a5549
Merge pull request #16030 from AUTOMATIC1111/sd3
Stable Diffusion 3 support
2024-07-06 09:39:01 +03:00
Andray
b82caf1322 fix ui flashing on reloading and fast scrollong 2024-07-05 19:28:16 +04:00
Kohaku-Blueleaf
bfbca31074 possible fix of wrong scale
https://github.com/comfyanonymous/ComfyUI/pull/3922
2024-07-05 18:56:39 +08:00
Andrey Efremov
f8640662c5
Add Normal and DDIM Schedulers 2024-07-04 19:27:08 +03:00
Aarni Koskela
f8fb74b93a Bump Spandrel to 0.3.4; add spandrel-extra-arches for CodeFormer 2024-07-04 09:14:04 +03:00
Andrey Efremov
32fdf18203
Add Simple Scheduler 2024-07-04 00:56:18 +03:00
İbrahim Süren
3971c01562 Return http 400 instead of 404 on invalid sampler 2024-07-03 17:33:25 +03:00
w-e-w
fd16393465 defunct --max-batch-count 2024-06-30 21:19:25 +09:00
w-e-w
957185f7eb fix Replace preview
fix broken Replace preview for extra networks tabs edit metadata
caused by #11808
2024-06-30 20:20:29 +09:00
viking1304
6ddcd8914b ensure use of python from venv 2024-06-30 11:44:06 +02:00
AUTOMATIC1111
9e404c3154 fix --medvram 2024-06-30 07:06:28 +03:00
AUTOMATIC1111
ebe8be9028 remove AutocastLinear from SD3's MLP 2024-06-29 08:05:55 +03:00
AUTOMATIC1111
1394ecaf36 do sampler calculations on CPU 2024-06-29 08:05:35 +03:00
AUTOMATIC1111
7e4b06fcd0 support loading clip/t5 from the main model checkpoint 2024-06-29 00:38:52 +03:00
AUTOMATIC1111
d67348a0a5 allow generation to be started with any dimensions specified 2024-06-28 18:06:49 +03:00
AUTOMATIC1111
179ae47d64 fix the problem with infinite prompts where empty cond would be calculated incorrectly 2024-06-28 11:15:34 +03:00
AUTOMATIC1111
0b64633584 fix img2img 2024-06-28 09:23:41 +03:00
AUTOMATIC1111
0c7bdcc1b1 add the missing get_first_stage_encoding function 2024-06-28 08:10:32 +03:00
AUTOMATIC1111
fc8b126673 get T5 to work both with and without --precision half 2024-06-28 08:10:19 +03:00
AUTOMATIC1111
06fe174c74 get deepbooru to run with --precision-half 2024-06-28 07:51:30 +03:00
Ikko Eltociear Ashimine
afaf120bc2
docs: update bug_report.yml
occured -> occurred
2024-06-27 17:44:12 +09:00
AUTOMATIC1111
42ca30d6c1 fix mdevram for SD1/SDXL 2024-06-27 07:35:53 +03:00
AUTOMATIC1111
d686e73daa support for SD3: infinite prompt length, token counting 2024-06-26 23:22:00 +03:00
viking1304
ec3c31e7a1 Try to use specified python version on linux and mac, with fallback 2024-06-25 21:01:33 +02:00
cuba3
9e60cdbc3f Maintaining Project Compatibility for Python 3.9 Users Without Upgrade Requirements.
Sole usage of Python 3.10's match-case in the project hinders quick-start for beginners; consider replacing with if-else for improved accessibility.
2024-06-25 15:24:46 +08:00
Andray
5d9f1e6a43 stoping generation extras 2024-06-25 05:33:07 +04:00
AUTOMATIC1111
a8fba9af35 medvram support for SD3 2024-06-24 10:15:46 +03:00
AUTOMATIC1111
a65dd315ad fix T5 2024-06-24 09:06:10 +03:00
Andray
731eb72774 fix sd2 switching 2024-06-23 21:16:48 +04:00
huchenlei
c3ef381cd8 Fix SD2 loading 2024-06-23 11:19:04 -04:00
w-e-w
775fa7696b ToggleLivePriview in image viewer 2024-06-21 20:38:40 +09:00
w-e-w
109bbda709 fix infotext Lora hashes fro hires fix different lora 2024-06-21 15:11:41 +09:00
w-e-w
0f40c4b9b1 fix Sampler Scheduler autocorrection warning 2024-06-21 12:14:33 +09:00
w-e-w
bd85b3f19b remove dont_fix_second_order_samplers_schedule 2024-06-21 10:53:44 +09:00
snoppy
13f22974a4
chore: fix typos
Signed-off-by: snoppy <michaleli@foxmail.com>
2024-06-21 09:52:02 +08:00
viking1304
a772fd9804 Update torch for ARM Macs to 2.3.1 2024-06-20 23:57:59 +02:00
v0xie
663a4d80df add new sampler DDIM CFG++ 2024-06-16 17:47:21 -07:00
AUTOMATIC1111
34b4443cc3 add an option (on by default) to disable T5
revert t5xxl back to fp16
2024-06-16 21:57:17 +03:00
AUTOMATIC1111
d4b814aed6 change t5xxl checkpoint to fp8 2024-06-16 14:39:58 +03:00
AUTOMATIC1111
58dc35a64a change CLIP links to allow anonymous downloading 2024-06-16 14:31:43 +03:00
AUTOMATIC1111
06d0a5ab4d fix NaN issue when running without --precision half 2024-06-16 14:09:32 +03:00
AUTOMATIC1111
80f618ea95 add protobuf==3.20.0 to requirements 2024-06-16 12:52:03 +03:00
AUTOMATIC1111
b443fdcf76 prevent accidental creation of CLIP models in float32 type when user wants float16 2024-06-16 11:04:19 +03:00
AUTOMATIC1111
7ee2114cd9 typo 2024-06-16 08:18:05 +03:00
AUTOMATIC1111
79de09c3df linter 2024-06-16 08:13:23 +03:00
AUTOMATIC1111
5b2a60b8e2 initial SD3 support 2024-06-16 08:04:31 +03:00
Alex "mcmonkey" Goodwin
a7116aa9a1 add SD3 reference implementation from https://github.com/mcmonkey4eva/sd3-ref/ 2024-06-16 07:13:57 +03:00
w-e-w
9e0f6d2012 remove commented code 2024-06-13 09:31:37 +09:00
AUTOMATIC1111
a30b19dd55
Merge pull request #16001 from zero41120/feat-prevent-screen-lock
feat: Prevent screen sleep during generation
2024-06-12 08:33:28 +03:00
YSH
f1e0bfebfc ci: remove comments and console logs 2024-06-11 22:33:11 -07:00
YSH
c803e11505 fix: prevent create multiple wake lock 2024-06-11 18:14:32 -07:00
YSH
1f8f3a6e8b feat: prevent screen sleep during generation 2024-06-11 16:50:00 -07:00
AUTOMATIC1111
d5e26274c8
Merge pull request #15992 from silveroxides/dev
Add option to enable clip skip for clip L on SDXL
2024-06-11 07:25:47 +03:00
Silver
91ecc750be
Update sd_hijack_clip.py 2024-06-11 00:40:26 +02:00
Silver
00e09382cd Add option to enable clip skip for clip L on SDXL 2024-06-10 22:11:11 +02:00
AUTOMATIC1111
123582b00f
Merge pull request #15988 from AUTOMATIC1111/multi-size-grid
multi size grid
2024-06-10 16:44:11 +03:00
w-e-w
abacb735f4 multi size grid 2024-06-10 20:47:12 +09:00
AUTOMATIC1111
e33bb8febe
Merge pull request #15984 from huchenlei/before_every_sampling
Add process_before_every_sampling hook
2024-06-10 07:25:17 +03:00
huchenlei
17e846150c Add process_before_every_sampling hook 2024-06-09 23:06:28 -04:00
AUTOMATIC1111
a84000c285
Merge pull request #15980 from AUTOMATIC1111/git-ignore-trace.json
.gitignore trace.json
2024-06-09 23:23:23 +03:00
w-e-w
74ee8fd1e3 .gitignore trace.json 2024-06-10 04:36:58 +09:00
AUTOMATIC1111
d2097dbdd9 added onOptionsAvailable callback for javascript for 2024-06-09 21:33:32 +03:00
AUTOMATIC1111
99e65ec618 undo some changes from #15823 and fix whitespace 2024-06-09 21:23:53 +03:00
AUTOMATIC1111
1d0bb39797
Merge pull request #15823 from drhead/patch-3
[Performance] Keep sigmas on CPU
2024-06-09 21:18:48 +03:00
AUTOMATIC1111
57e6d05a43 added tool for profiling code 2024-06-09 21:18:36 +03:00
AUTOMATIC1111
aafbb5b403 lint 2024-06-09 16:47:08 +03:00
AUTOMATIC1111
e368cd2810 stylistic changes for #15978 2024-06-09 16:46:08 +03:00
AUTOMATIC1111
981abbb1f2
Merge pull request #15978 from bluelovers/pr/pattern-001
feat: save pattern add `basename`
2024-06-09 16:45:06 +03:00
AUTOMATIC1111
6214aa7d2a performance: check for nans in unet only once, after all steps have been completed 2024-06-09 16:24:04 +03:00
bluelovers
6447ff49d3 feat: save pattern add basename
`grid` or `xyz_grid` or `img`

```py
'basename': lambda self: 'img' if self.basename == '' else self.basename,
```
2024-06-09 19:07:32 +08:00
AUTOMATIC1111
41ee2db5a8
Merge pull request #15976 from huchenlei/fix_sdxl_inpaint
Fix SDXL Inpaint
2024-06-09 07:44:46 +03:00
huchenlei
f89b5dbbd2 nit 2024-06-08 22:15:37 -04:00
huchenlei
d875cda565 Fix sdxl inpaint 2024-06-08 22:11:11 -04:00
drhead
d52a1e1a22
lint 2024-06-08 18:56:23 -04:00
drhead
39a6d5655f
patch k_diffusion to_d and strip device from schedulers 2024-06-08 18:55:07 -04:00
drhead
428975e1d3
Merge pull request #1 from AUTOMATIC1111/dev
Dev
2024-06-08 18:49:44 -04:00
drhead
58b24eae30
Merge branch 'AUTOMATIC1111:master' into patch-3 2024-06-08 18:44:46 -04:00
AUTOMATIC1111
547778b10f possibly make NaN check cheaper 2024-06-08 12:41:38 +03:00
AUTOMATIC1111
194c2620d6
Merge pull request #15968 from AUTOMATIC1111/wsl-open
replace wsl-open with wslpath and explorer.exe
2024-06-08 12:30:11 +03:00
AUTOMATIC1111
5ecfc20d97
Merge pull request #15610 from pinanew/pinanew-patch-1
AVIF has quality setting too
2024-06-08 12:27:54 +03:00
AUTOMATIC1111
2dbc7aa688
Merge pull request #15627 from light-and-ray/more_extension_tag_filtering_options
more extension tag filtering options
2024-06-08 12:24:17 +03:00
AUTOMATIC1111
6d8d2723a0
Merge pull request #15632 from brendanhoar/bgh-handle-metadata-issues-more-cleanly
QOL Items - handle metadata issues more cleanly for SD models, Loras and embeddings
2024-06-08 12:17:01 +03:00
AUTOMATIC1111
3ef9f2748d
Merge branch 'dev' into bgh-handle-metadata-issues-more-cleanly 2024-06-08 12:16:55 +03:00
AUTOMATIC1111
30461bef98
Merge pull request #15602 from AUTOMATIC1111/initial-model-download-integrity
Initial model download integrity
2024-06-08 12:13:24 +03:00
AUTOMATIC1111
569f17c6c6
Merge pull request #15654 from huchenlei/mime
Add correct mimetype for .mjs files
2024-06-08 12:10:42 +03:00
AUTOMATIC1111
a184e5dd87
Merge pull request #15657 from AUTOMATIC1111/drag-text-fix
Fix dragging text within prompt input
2024-06-08 11:58:05 +03:00
AUTOMATIC1111
9e5103124a
Merge pull request #15641 from AUTOMATIC1111/no-referrer
no-referrer
2024-06-08 11:56:53 +03:00
AUTOMATIC1111
41b24d350f
Merge pull request #15680 from light-and-ray/use_gradio_theme_colors_in_css
use gradio theme colors in css
2024-06-08 11:54:55 +03:00
AUTOMATIC1111
742bfbe0ec
Merge pull request #15679 from AUTOMATIC1111/lora-bundled-TI-infotext
LoRA bundled TI infotext
2024-06-08 11:54:29 +03:00
AUTOMATIC1111
a1130c26e5
Merge pull request #15664 from AUTOMATIC1111/fix-extra-batch-mode-P-Transparency
fix extra batch mode P Transparency
2024-06-08 11:53:08 +03:00
AUTOMATIC1111
b9dfc50a1b
Merge pull request #15705 from AUTOMATIC1111/use-script_path-for-webui-root-in-launch_utils
use script_path for webui root in launch_utils
2024-06-08 11:51:48 +03:00
AUTOMATIC1111
74b1fc6256
Merge pull request #15682 from light-and-ray/two_fingers_press_to_open_context_menu
two fingers press to open context menu
2024-06-08 11:43:06 +03:00
AUTOMATIC1111
4aebfe9844
Merge pull request #15730 from bluelovers/patch-2
Update imageviewer.js
2024-06-08 11:42:27 +03:00
AUTOMATIC1111
debc6dddeb
Merge pull request #15739 from LoganBooker/LoganBooker-AVIF-mimetype-patch
Add AVIF MIME type support to mimetype definitions
2024-06-08 11:36:21 +03:00
AUTOMATIC1111
1a7ffa2c76 remove extra local variable 2024-06-08 11:35:45 +03:00
AUTOMATIC1111
64783dd9cc
Merge pull request #15742 from MarcusNyne/m9-240508-model-dir
Added --models-dir option
2024-06-08 11:35:03 +03:00
AUTOMATIC1111
c1c4b3fb34
Merge pull request #15738 from JLipnerPitt/JLipnerPitt-patch-1
Fix AttributeError
2024-06-08 11:32:38 +03:00
AUTOMATIC1111
5abdf5191d
Merge pull request #15750 from MarcusNyne/m9-240509-pip-upgrade
When creating a virtual environment, upgrade pip in webui.bat/webui.sh
2024-06-08 11:31:26 +03:00
AUTOMATIC1111
64ebb245ad
Merge pull request #15757 from AUTOMATIC1111/fix-fonts-with-subpath-
use relative path for webui-assets css
2024-06-08 11:28:06 +03:00
AUTOMATIC1111
07cf95c76e update pickle safe filenames 2024-06-08 11:26:41 +03:00
AUTOMATIC1111
9905341602
Merge pull request #15783 from elf-mouse/dev
chore: sync v1.8.0 packages according to changelog
2024-06-08 11:20:43 +03:00
AUTOMATIC1111
88a5001e06
Merge branch 'dev' into dev 2024-06-08 11:20:35 +03:00
AUTOMATIC1111
7b940e3879
Merge pull request #15797 from AUTOMATIC1111/fix-extention-update-when-not-on-main-branch
fix extention update when not on main branch
2024-06-08 11:19:26 +03:00
AUTOMATIC1111
b4723bb8c1
Merge pull request #15815 from AUTOMATIC1111/torch-float64-or-float32
fix soft inpainting on mps and xpu, torch_utils.float64
2024-06-08 11:07:29 +03:00
AUTOMATIC1111
6450d24afe
Merge pull request #15806 from huchenlei/inpaint_fix
[Performance 4/6] Precompute is_sdxl_inpaint flag
2024-06-08 11:06:39 +03:00
AUTOMATIC1111
64bf57b5ea
Merge pull request #15817 from light-and-ray/img2img_batch_upload
img2img batch upload method
2024-06-08 11:00:21 +03:00
AUTOMATIC1111
816bc424c4
Merge pull request #15816 from huchenlei/bias_backup
[Performance 5/6] Prevent unnecessary extra networks bias backup
2024-06-08 10:56:40 +03:00
AUTOMATIC1111
371cb60945
Merge pull request #15830 from light-and-ray/scroll_extensions_table_on_overflow
scroll extensions table on overflow
2024-06-08 10:55:18 +03:00
AUTOMATIC1111
603509ec90 as per wfjsw's suggestion, revert changes for sd_hijack_checkpoint.py 2024-06-08 10:54:41 +03:00
AUTOMATIC1111
ad229fae43
Merge pull request #15803 from huchenlei/checkpoint_false
[Performance 1/6] use_checkpoint = False
2024-06-08 10:52:40 +03:00
w-e-w
510f025a01 replace wsl-open with wslpath and explorer.exe 2024-06-08 16:52:12 +09:00
AUTOMATIC1111
5977cb0946
Merge pull request #15832 from AUTOMATIC1111/xyz-csv-skipinitialspace
XYZ CSV skipinitialspace
2024-06-08 10:46:26 +03:00
AUTOMATIC1111
04164a83c4
Merge pull request #15831 from AUTOMATIC1111/fix-Hypertile-xyz
Fix Hypertile xyz
2024-06-08 10:45:49 +03:00
AUTOMATIC1111
96f907ee09
Merge branch 'dev' into fix-Hypertile-xyz 2024-06-08 10:45:36 +03:00
AUTOMATIC1111
c3c90deec0
Merge pull request #15681 from AUTOMATIC1111/fix_p_invalid_sampler_and_scheduler
more old sampler scheduler compatibility
2024-06-08 10:42:42 +03:00
AUTOMATIC1111
cbac72d8ee
Merge pull request #15836 from AUTOMATIC1111/xyz-override-rework
XYZ override rework
2024-06-08 10:40:14 +03:00
AUTOMATIC1111
616013fd7a
Merge pull request #15851 from viking1304/torch-on-mac
Use different torch versions for Intel and ARM Macs
2024-06-08 10:39:33 +03:00
AUTOMATIC1111
93b53dc116
Merge pull request #15824 from drhead/patch-4
[Performance] LDM optimization patches
2024-06-08 10:35:39 +03:00
AUTOMATIC1111
ebfc9f6d09
Merge branch 'dev' into patch-4 2024-06-08 10:35:09 +03:00
AUTOMATIC1111
33b73c473c
Merge pull request #15820 from huchenlei/force_half
[Performance 6/6] Add --precision half option to avoid casting during inference
2024-06-08 10:26:23 +03:00
AUTOMATIC1111
ba54c747e2
Merge pull request #15656 from AUTOMATIC1111/api-old-sampler-names
Allow old sampler names in API
2024-06-08 10:18:20 +03:00
AUTOMATIC1111
cd9e9e4049 remove unneeded tabulation 2024-06-08 10:13:38 +03:00
AUTOMATIC1111
15245d9d5e
Merge pull request #15600 from AUTOMATIC1111/fix-corrupt-model-loop
Fix corrupt model initial load loop
2024-06-08 10:12:45 +03:00
AUTOMATIC1111
5429e4cff5 add proper infotext support for #15607
fix settings override not working for NGMI, s_churn, etc...
2024-06-08 09:56:09 +03:00
AUTOMATIC1111
b150b3a3a4
Merge pull request #15607 from drhead/patch-1
add code for skipping CFG on early steps
2024-06-08 09:20:08 +03:00
AUTOMATIC1111
9e1fc80c48
Merge pull request #15608 from drhead/patch-2
Add KL Optimal scheduler
2024-06-08 09:10:57 +03:00
AUTOMATIC1111
0edc04d126
Merge branch 'dev' into patch-2 2024-06-08 09:10:51 +03:00
AUTOMATIC1111
e21b1e3716
Merge pull request #15864 from AUTOMATIC1111/ReloadUI-backgroundColor---background-fill-primary
ReloadUI backgroundColor --background-fill-primary
2024-06-08 09:06:39 +03:00
AUTOMATIC1111
00f37ad73f
Merge pull request #15893 from alcacode/dev
Fix bug where file extension had an extra '.' under some circumstances
2024-06-08 09:06:03 +03:00
AUTOMATIC1111
0769aa318a integrated edits as recommended in the PR #15804 2024-06-08 09:05:35 +03:00
AUTOMATIC1111
de7f5cdc62
Merge pull request #15804 from huchenlei/rearrange_fix
[Performance 2/6] Replace einops.rearrange with torch native ops
2024-06-08 08:55:51 +03:00
AUTOMATIC1111
0c0d71a4e4
Merge pull request #15907 from AUTOMATIC1111/fix-change-log
fix changelog #15883 -> #15882
2024-06-08 08:53:56 +03:00
AUTOMATIC1111
6de733c91e
Merge pull request #15943 from eatmoreapple/update-lora-load
feat: lora partial update precede full update
2024-06-08 08:51:42 +03:00
AUTOMATIC1111
46bcfbe37c
Merge pull request #15751 from LoganBooker/LoganBooker-Add-AlignYourSteps-Scheduler
Add Align Your Steps to available schedulers
2024-06-08 08:43:02 +03:00
AUTOMATIC1111
3c7384ab60
Merge pull request #15958 from NouberNou/Fix-Grids-Without-Infotexts
Fix for grids without comprehensive infotexts
2024-06-08 08:10:18 +03:00
NouberNou
53f62674ae
Typo on edit
Edited in fix in Github editor and mistyped from local copy
2024-06-06 16:30:01 -07:00
NouberNou
25bbf31f57
Fix for grids without comprehensive infotexts
When generating grids, some scripts such as img2img loopback and ultimate SD upscale do not pass infotexts for each image since they are the same prompt.

If you attempt to save those images using the saved button in the UI it will fail because it will look for the selected image info text. This fixes those errors by replicating the infotext for as many images are passed into the image list if the infotext parameter is none.
2024-06-06 16:22:49 -07:00
eatmoreapple
10f8d0f842 feat: lora partial update precede full update. 2024-06-04 15:02:13 +08:00
w-e-w
8d6f741738 #15883 -> #15882 2024-05-29 03:41:57 +09:00
AUTOMATIC1111
feee37d75f Merge branch 'dev' 2024-05-28 21:20:40 +03:00
AUTOMATIC1111
801b72b92b update changelog 2024-05-28 21:20:23 +03:00
AUTOMATIC1111
759f396a2e
Merge pull request #15882 from AUTOMATIC1111/setuptools==69.5.1
Fix method 1 : pin Setuptools==69.5.1
2024-05-28 21:16:28 +03:00
alcacode
6dd53ce63d
Fix bug where file extension had an extra '.' under some circumstances
Fix bug where under some circumstances an extra "." was inserted between the file base name and the file extension.
The bug is triggered when the extension argument is one of "jpg", "jpeg", or "webp", and the image exceeds the format's dimension limit. Then the extension variable is set to ".png", resulting in the fullfn variable to evaluate to a string ending with "..png".
2024-05-26 15:36:55 +02:00
w-e-w
a63946233b setuptools==69.5.1 2024-05-25 14:19:19 +09:00
w-e-w
344eda55d4 ReloadUI backgroundColor --background-fill-primary 2024-05-22 23:06:07 +09:00
viking1304
5867be2914
Use different torch versions for Intel and ARM Macs 2024-05-20 23:44:17 +02:00
w-e-w
51e7122f25 remove unused code 2024-05-19 15:39:29 +09:00
w-e-w
1e696b028a use override of sd_vae 2024-05-19 15:39:29 +09:00
w-e-w
1f392517f8 use override for uni_pc_order 2024-05-19 05:54:42 +09:00
w-e-w
82884da18c use apply_override for Clip skip 2024-05-19 05:54:42 +09:00
w-e-w
24a59ad3d2 fix Hypertile xyz grid 2024-05-18 18:38:24 +09:00
w-e-w
969a462ac9 xyz util confirm_range 2024-05-18 18:38:24 +09:00
w-e-w
501ac016da Reformat 2024-05-18 18:38:24 +09:00
drhead
feeb6802aa
fix case where first step skilled if skip early cond is 0 2024-05-18 01:22:31 -04:00
Andray
281e0a007b scroll extensions table on overflow 2024-05-18 09:13:16 +04:00
Logan
1d74482817 Default device for sigma tensor to CPU
* Consistent with implementations in k-diffusion.
* Makes this compatible with https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15823
2024-05-18 09:09:57 +10:00
huchenlei
b57a70f373 Proper fix of SD15 dtype 2024-05-17 13:34:04 -04:00
huchenlei
dca9007ac7 Fix SD15 dtype 2024-05-17 13:23:12 -04:00
drhead
cc9ca67664
Add transformer forward patch 2024-05-17 13:14:26 -04:00
drhead
53d67088ee
Patch timestep embedding to create tensor on-device 2024-05-17 12:12:57 -04:00
w-e-w
10f2407f48 xyz csv skipinitialspace 2024-05-18 01:00:48 +09:00
drhead
01491d303c
Keep sigmas on CPU 2024-05-17 10:36:08 -04:00
huchenlei
47f1d42a7e Fix for SD15 models 2024-05-16 20:06:04 -04:00
huchenlei
2a8a60c2c5 Add --precision half cmd option 2024-05-16 19:50:06 -04:00
huchenlei
58eec83a54 Fully prevent use_checkpoint 2024-05-16 16:39:02 -04:00
Andray
221ac0b9ab img2img batch upload method 2024-05-16 23:08:24 +04:00
huchenlei
b2ae4490b9 Fix LoRA bias error 2024-05-16 14:45:00 -04:00
huchenlei
51b13a8c54 Prevent uncessary bias backup 2024-05-16 11:39:01 -04:00
w-e-w
f015b94176 use torch_utils.float64 2024-05-16 23:19:06 +09:00
w-e-w
41f66849c7 mps, xpu compatibility 2024-05-16 23:18:20 +09:00
w-e-w
9c8075ba8e torch_utils.float64
return torch.float64 if device is not mps or xpu, else return torch.float32
2024-05-16 23:16:50 +09:00
huchenlei
3e20b36e8f Fix attr access 2024-05-15 17:27:01 -04:00
huchenlei
6a48476502 Fix flag check for SD15 2024-05-15 16:54:26 -04:00
huchenlei
9eb2f78631 Precompute is_sdxl_inpaint flag 2024-05-15 16:32:29 -04:00
huchenlei
0e98529365 Replace einops.rearrange with torch native 2024-05-15 15:46:53 -04:00
huchenlei
022d835565 use_checkpoint = False 2024-05-15 15:20:40 -04:00
w-e-w
5ab7d08a0a fix extention update when not on main branch 2024-05-15 17:27:05 +09:00
elf-mouse
ef7713fbb2 chore: sync v1.8.0 packages according to changelog, fix warning 2024-05-14 15:39:05 +08:00
w-e-w
d44f241317 use relative path for webui-assets css 2024-05-11 13:13:39 +09:00
Logan
d6b4444069 Use shared.sd_model.is_sdxl to determine base AYS sigmas 2024-05-10 18:05:45 +10:00
Logan
73d1caf8f2 Add Align Your Steps to available schedulers
* Include both SDXL and SD 1.5 variants (https://research.nvidia.com/labs/toronto-ai/AlignYourSteps/howto.html)
2024-05-10 12:38:10 +10:00
MarcusNyne
d2cc8ccb11 When creating a virtual environment, upgrade pip
Pip will be upgraded upon immediately creating the virtual environment.  If the pip upgrade fails, this should not cause the script to fail (treat as a warning).  After the environment is created, it will not attempt further updates to pip.
2024-05-09 17:16:53 -04:00
MarcusNyne
5fbac49791 Added --models-dir option
The --model-dir option overrides the location of the models directory for stable diffusion, so that models can be shared across multiple installations.  When --data-dir is specified alone, both the extensions and models folders are present in this folder.  --models-dir can be used independently, but when used with --data-dir, then the models folder is specified by --models-dir, and extensions are found in the --data-dir.
2024-05-08 16:48:10 -04:00
LoganBooker
f7e349cea4
Add AVIF MIME type support to mimetype definitions
AVIF images will open, rather than download, as the default behaviour.
2024-05-08 21:23:18 +10:00
JLipnerPitt
e736c3b36b
Add files via upload
Fixed an error (AttributeError: 'str' object has no attribute 'decode') coming from line 792 in images.py when trying to upscale certain images.
2024-05-08 05:22:12 -04:00
Andray
dbda59e58a fix context menu position 2024-05-07 19:26:16 +04:00
bluelovers
dd93c47abf
Update imageviewer.js 2024-05-07 19:53:18 +08:00
w-e-w
f12886aefa use script_path for webui root in launch_utils 2024-05-04 23:42:37 +09:00
Andray
7195c4d42c two fingers press to open context menu 2024-05-01 22:50:46 +04:00
w-e-w
5d5224b322 fix_p_invalid_sampler_and_scheduler 2024-05-02 02:25:16 +09:00
Andray
0e0e41eabc use gradio theme colors in css 2024-05-01 16:54:47 +04:00
w-e-w
89103b4747 lora bundled TI infotext
Co-Authored-By: Morgon Kanter <9632805+mx@users.noreply.github.com>
2024-05-01 19:41:02 +09:00
w-e-w
9d39380705 fix extra batch mode P Transparency
red, green, blue = transparency TypeError: cannot unpack non-iterable int object
2024-04-30 19:17:53 +09:00
missionfloyd
c8336c45b9 Use existing function for old sampler names 2024-04-30 01:53:41 -06:00
missionfloyd
4c7b22d37d Fix dragging text within prompt input 2024-04-28 22:46:11 -06:00
missionfloyd
579f1ef278 Allow old sampler names in API 2024-04-28 22:36:43 -06:00
huchenlei
3d3fc81f48 Add correct mimetype for .mjs files 2024-04-28 16:14:12 -04:00
drhead
3a215deff2
vectorize kl-optimal sigma calculation
Co-authored-by: mamei16 <marcel.1710@live.de>
2024-04-28 00:15:58 -04:00
w-e-w
9d964d3fc3 no-referrer 2024-04-27 19:21:34 +09:00
Brendan Hoar
60c0799958
Linter - except must not be bare. 2024-04-26 08:21:12 -04:00
Brendan Hoar
44afb48447
Linter fix - extraneous whitespace 2024-04-26 08:17:37 -04:00
Brendan Hoar
c5ae225418
Better handling of embeddings with two rare, but not unusual, files in them
I have encountered pickled embeddings with a short byteorder file at the top-level, as well as a .data/serialization_id file.

Both load fine after allowing these files in the dataset.

I do not think it is likely adding them to the safe unpickle regular expression would be a security risk, but that's for the maintainers to decide.
2024-04-26 07:55:39 -04:00
Brendan Hoar
c5b7559856
Better error handling when unable to extract contents of embedding/TI file 2024-04-26 06:57:32 -04:00
Brendan Hoar
8dc920228e
Better error handling when unable to read metadata from safetensors file 2024-04-26 06:52:21 -04:00
Brendan Hoar
3902aa222b
Better error handling to skip non-standard ss_tag_frequency content 2024-04-26 06:44:41 -04:00
w-e-w
d5f6fdb3c4 compact-checkbox-group 2024-04-26 18:47:04 +09:00
Andray
e85e327ae0 more extension tag filtering options 2024-04-25 13:26:26 +04:00
w-e-w
1091e3a37e update jpeg_quality description 2024-04-24 02:54:26 +09:00
w-e-w
8fa3fa76c3 fix exif_bytes referenced before assignment 2024-04-24 02:41:31 +09:00
pinanew
50bb6e1179
AVIF has quality setting too 2024-04-23 18:45:42 +03:00
drhead
029adbe531
implement option to skip uncond on all steps below ngms 2024-04-23 03:15:56 -04:00
drhead
33cbbf9f8b
add s_min_uncond_all option 2024-04-23 03:15:00 -04:00
drhead
6e9b69a338
change skip_early_cond code to use float 2024-04-23 03:08:28 -04:00
drhead
83182d2799
change skip early cond option name and to float 2024-04-23 03:07:25 -04:00
drhead
83266205d0
Add KL Optimal scheduler 2024-04-23 00:09:43 -04:00
drhead
8016d78a4b
add option for early cfg skip 2024-04-22 23:42:24 -04:00
drhead
a1aa0af8a4
add code for skipping CFG on early steps 2024-04-22 23:38:44 -04:00
w-e-w
c69773d7e8 ensure integrity for initial sd model download 2024-04-23 03:09:45 +09:00
w-e-w
246c269af8 add option to check file hash after download
if the sha256 hash does not match it will be automatically deleted
2024-04-23 03:09:45 +09:00
w-e-w
4bc39d234d Show LoRA if model is None 2024-04-23 02:39:45 +09:00
w-e-w
2b717bb195 fix initial corrupt model loop
if for some reason the initial loading model at loading phase of webui  is corrupted
after entering this state the user will not be able to load even a good model is selected, due the the unload_model_weights  > send_model_to_cpu > m.lowvram attribute check will fail becaules m is None
webui will be stuck in the loop unable to recover without manual intervention
2024-04-23 02:35:25 +09:00
AUTOMATIC1111
ddb28b33a3 Merge branch 'master' into dev 2024-04-22 18:01:16 +03:00
AUTOMATIC1111
1c0a0c4c26 Merge branch 'dev' 2024-04-22 18:00:36 +03:00
AUTOMATIC1111
7dfe959f4b update changelog 2024-04-22 18:00:23 +03:00
AUTOMATIC1111
8f64dad282
Merge pull request #15594 from AUTOMATIC1111/fix-get_crop_region_v2
fix get_crop_region_v2
2024-04-22 17:57:39 +03:00
w-e-w
821adc3041 fix get_crop_region_v2
Co-Authored-By: Dowon <ks2515@naver.com>
2024-04-22 23:10:19 +09:00
AUTOMATIC1111
e2b177c508 Merge branch 'dev' 2024-04-22 12:26:24 +03:00
AUTOMATIC1111
e837124f4b changelog 2024-04-22 12:26:05 +03:00
AUTOMATIC1111
3fdc3cfbbf
Merge pull request #15591 from AUTOMATIC1111/restore-1.8.0-style-naming-of-scripts
Restore 1.8.0 style naming of scripts
2024-04-22 12:24:06 +03:00
w-e-w
e9809de651 restore 1.8.0-style naming of scripts 2024-04-22 18:23:58 +09:00
AUTOMATIC1111
61f6479ea9 restore 1.8.0-style naming of scripts 2024-04-22 12:19:30 +03:00
AUTOMATIC1111
e84703b253 update changelog 2024-04-22 11:59:54 +03:00
AUTOMATIC1111
e4aa0c362e
Merge pull request #15587 from AUTOMATIC1111/fix-mistake-in-#15583
fix mistake in #15583
2024-04-22 11:50:34 +03:00
AUTOMATIC1111
a183ea4ba7 undo adding scripts to sys.modules 2024-04-22 11:49:55 +03:00
w-e-w
6c7c176dc9 fix mistake in #15583 2024-04-22 00:10:49 +09:00
AUTOMATIC1111
e6a8d0b4e6
Merge pull request #15583 from AUTOMATIC1111/get_crop_region_v2
get_crop_region_v2
2024-04-21 18:06:40 +03:00
w-e-w
db263df5d5 get_crop_region_v2 2024-04-21 19:34:11 +09:00
AUTOMATIC1111
d1998d747d
Merge pull request #15531 from thatfuckingbird/fix-mistyped-function-name
fix typo in function call (eror -> error)
2024-04-21 07:43:19 +03:00
AUTOMATIC1111
c0eaeb15af
Merge pull request #15532 from huchenlei/fix_module
Fix cls.__module__ value in extension script
2024-04-21 07:42:57 +03:00
AUTOMATIC1111
9bcfb92a00 rename logging from textual inversion to not confuse it with global logging module 2024-04-21 07:41:28 +03:00
AUTOMATIC1111
d74fc56fa5
Merge pull request #15547 from AUTOMATIC1111/numpy-DeprecationWarning-product---prod
numpy DeprecationWarning product -> prod
2024-04-21 07:23:38 +03:00
AUTOMATIC1111
a44ed231c2
Merge pull request #15555 from light-and-ray/fix_x1_upscalers
fix x1 upscalers
2024-04-21 07:22:58 +03:00
AUTOMATIC1111
daae17851a
Merge pull request #15560 from AUTOMATIC1111/api-downscale
Remove API upscaling factor limits
2024-04-21 07:22:30 +03:00
AUTOMATIC1111
ce19a7baef
Merge pull request #15544 from cabelo/master
Compatibility with Debian 11, Fedora 34+ and openSUSE 15.4+
2024-04-21 07:22:04 +03:00
AUTOMATIC1111
8d6e72dbfa
Merge pull request #15561 from speculativemoonstone/fix-launch-git-directories
Allow webui.sh to be runnable from arbitrary directories containing a .git file
2024-04-21 07:21:21 +03:00
AUTOMATIC1111
6f4f6bff6b add more info to the error message for #15567 2024-04-21 07:18:58 +03:00
AUTOMATIC1111
367b823466
Merge pull request #15567 from AUTOMATIC1111/no-image-data-blocks-debug
Hide 'No Image data blocks found.' message
2024-04-21 07:09:27 +03:00
AUTOMATIC1111
c8ac42aad1
Merge pull request #15533 from travisg/callback-fix
fix: remove_callbacks_for_function should also remove from the ordered map
2024-04-21 07:07:58 +03:00
AUTOMATIC1111
449bc7bcf3
Merge pull request #15534 from storyicon/fix-masking
Fix images do not match / Coordinate 'right' is less than 'left'
2024-04-21 07:06:45 +03:00
AUTOMATIC1111
3810413c00
Merge pull request #15581 from AUTOMATIC1111/FilenameGenerator-sampler-scheduler
FilenameGenerator Sampler Scheduler
2024-04-21 07:00:28 +03:00
AUTOMATIC1111
f8f5d6cea2
Merge pull request #15577 from AUTOMATIC1111/api-get-schedulers
Add schedulers API endpoint
2024-04-21 06:59:56 +03:00
AUTOMATIC1111
cde35bebe9
Merge pull request #15582 from kaanyalova/avif-support
Add avif support
2024-04-21 06:59:38 +03:00
kaanyalova
49fee7c8db Add avif support 2024-04-20 23:26:04 +03:00
w-e-w
b5b1487f6a FilenameGenerator Sampler Scheduler 2024-04-21 04:52:03 +09:00
missionfloyd
5cb567c138 Add schedulers API endpoint 2024-04-19 20:32:09 -06:00
missionfloyd
d212fb59fe Hide 'No Image data blocks found.' message 2024-04-18 20:56:51 -06:00
storyicon
71314e47b1 feat:compatible with inconsistent/empty mask
Signed-off-by: storyicon <storyicon@foxmail.com>
2024-04-18 11:59:25 +00:00
Speculative Moonstone
ba2a737cce
Allow webui.sh to be runnable from directories containing a .git file 2024-04-18 04:25:32 +00:00
missionfloyd
909c3dfe83 Remove API upscaling factor limits 2024-04-17 21:20:03 -06:00
Andray
9d4fdc45d3 fix x1 upscalers 2024-04-18 01:53:23 +04:00
w-e-w
63fd38a04f numpy DeprecationWarning product -> prod 2024-04-17 15:54:45 +09:00
Alessandro de Oliveira Faria (A.K.A. CABELO)
50190ca669 Compatibility with Debian 11, Fedora 34+ and openSUSE 15.4+ 2024-04-17 00:01:56 -03:00
storyicon
0980fdfe8c fix: images do not match
Signed-off-by: storyicon <storyicon@foxmail.com>
2024-04-16 07:35:33 +00:00
Travis Geiselbrecht
bba306d414 fix: remove callbacks properly in remove_callbacks_for_function()
Like remove_current_script_callback just before, also remove from the
ordered_callbacks_map to keep the callback map and ordered callback map
in sync.
2024-04-15 21:10:11 -07:00
huchenlei
a95326bec4 nit 2024-04-15 22:34:01 -04:00
huchenlei
0f82948e4f Fix cls.__module__ 2024-04-15 22:14:19 -04:00
thatfuckingbird
8e1c3561be
fix typo in function call (eror -> error) 2024-04-15 21:17:24 +02:00
AUTOMATIC1111
ff6f4680c4 Merge branch 'master' into dev 2024-04-13 06:38:58 +03:00
AUTOMATIC1111
adadb4e3c7 Merge branch 'release_candidate' 2024-04-13 06:37:28 +03:00
AUTOMATIC1111
d282d24800 update changelog 2024-04-13 06:37:03 +03:00
AUTOMATIC1111
a196319edf Merge pull request #15492 from w-e-w/update-restricted_opts
update restricted_opts
2024-04-11 19:34:10 +03:00
AUTOMATIC1111
3fadb4fc85
Merge pull request #15492 from w-e-w/update-restricted_opts
update restricted_opts
2024-04-11 19:33:55 +03:00
w-e-w
592e40ebe9 update restricted_opts 2024-04-11 23:10:25 +09:00
storyicon
4068429ac7 fix: Coordinate 'right' is less than 'left'
Signed-off-by: storyicon <storyicon@foxmail.com>
2024-04-10 10:53:25 +00:00
AUTOMATIC1111
88f70ce63c Merge pull request #15470 from AUTOMATIC1111/read-infotext-Script-not-found
error handling paste_field callables
2024-04-09 16:01:13 +03:00
AUTOMATIC1111
ac8ffb34e3
Merge pull request #15470 from AUTOMATIC1111/read-infotext-Script-not-found
error handling paste_field callables
2024-04-09 16:00:56 +03:00
w-e-w
ef83f6831f catch exception for all paste_fields callable 2024-04-09 21:32:58 +09:00
w-e-w
600f339c4c Warning when Script is not found 2024-04-09 21:32:41 +09:00
AUTOMATIC1111
7f691612ca Merge pull request #15460 from AUTOMATIC1111/create_infotext-index-and-callable
create_infotext allow index and callable, re-work Hires prompt infotext
2024-04-09 12:05:15 +03:00
AUTOMATIC1111
a976f4dff9
Merge pull request #15460 from AUTOMATIC1111/create_infotext-index-and-callable
create_infotext allow index and callable, re-work Hires prompt infotext
2024-04-09 12:05:02 +03:00
AUTOMATIC1111
696d6813e0 Merge pull request #15465 from jordenyt/fix-extras-api-upscale-enabled
Fix extra-single-image API not doing upscale failed
2024-04-09 11:00:49 +03:00
AUTOMATIC1111
c48b6bf6bd
Merge pull request #15465 from jordenyt/fix-extras-api-upscale-enabled
Fix extra-single-image API not doing upscale failed
2024-04-09 11:00:30 +03:00
Jorden Tse
2580235c72 Fix extra-single-image API not doing upscale failed 2024-04-09 11:13:47 +08:00
AUTOMATIC1111
3786f3742f fix limited file write (thanks, Sylwia) 2024-04-08 16:15:55 +03:00
AUTOMATIC1111
d9708c92b4 fix limited file write (thanks, Sylwia) 2024-04-08 16:15:25 +03:00
w-e-w
e3aabe6959 add documentation for create_infotext 2024-04-08 20:14:02 +09:00
w-e-w
1e1176b6eb non-serializable as None 2024-04-08 18:18:33 +09:00
w-e-w
219e64489c re-work extra_generation_params for Hires prompt 2024-04-08 18:18:13 +09:00
w-e-w
47ed9b2d39 allow list or callables in generation_params 2024-04-08 01:39:31 +09:00
w-e-w
6efdfe3234 if use use_main_prompt index = 0 2024-04-07 22:58:12 +09:00
AUTOMATIC1111
e1640314df 1.9.0 changelog 2024-04-06 21:46:56 +03:00
AUTOMATIC1111
c16a27caa9
Merge pull request #15446 from AUTOMATIC1111/re-add-update_file_entry
re-add update_file_entry
2024-04-06 10:02:45 +03:00
w-e-w
2ad17a6100 re-add update_file_entry
MassFileLister.update_file_entry was accidentally removed in https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15205/files#diff-c39b942d8f8620d46d314db8301189b8d6195fc97aedbeb124a33694b738d69cL151-R173
2024-04-06 15:56:57 +09:00
AUTOMATIC1111
23c06a51cc use 'scripts.' prefix for names of dynamically loaded modules 2024-04-06 09:05:04 +03:00
AUTOMATIC1111
badb70da48
Merge pull request #15423 from storyicon/master
feat: ensure the indexability of dynamically imported packages
2024-04-06 09:00:35 +03:00
AUTOMATIC1111
447198f21b
Merge pull request #15442 from AUTOMATIC1111/open_folder-as-util
open_folder as util
2024-04-06 08:54:20 +03:00
AUTOMATIC1111
acb20338b1 put HF_ENDPOINT into shared for #15443 2024-04-06 08:53:21 +03:00
AUTOMATIC1111
73f7812045
Merge pull request #15443 from Satariall/add-hf_endpoint-variable
Use HF_ENDPOINT variable for HuggingFace domain with default
2024-04-06 08:48:55 +03:00
Marsel Markhabulin
989b89b12a
Use HF_ENDPOINT variable for HuggingFace domain with default
Modified the list_models function to dynamically construct the model URL
by using an environment variable for the HuggingFace domain. This allows
for greater flexibility in specifying the domain and ensures that the
modification is also compatible with the Hub client library. By
supporting different environments or requirements without hardcoding the
domain name, this change facilitates the use of custom HuggingFace
domains not only within our code but also when interacting with the Hub
client library.
2024-04-05 13:02:49 +03:00
w-e-w
20123d427b open_folder docstring 2024-04-05 16:19:20 +09:00
w-e-w
a05d89b1e5
Merge branch 'dev' into open_folder-as-util 2024-04-05 15:14:38 +08:00
w-e-w
92e6aa3653 open_folder as util 2024-04-05 16:08:45 +09:00
AUTOMATIC1111
b372fb6165 fix API upscale 2024-04-01 23:33:45 +03:00
AUTOMATIC1111
0cb2bbd01a
Merge pull request #15428 from v0xie/fix/remove-callbacks
Fix: Remove script callbacks in ordered_callbacks_map
2024-04-01 23:25:03 +03:00
v0xie
a669b8a6bc fix: remove script callbacks in ordered_callbacks_map 2024-04-01 12:51:09 -07:00
AUTOMATIC1111
719296133d
Merge pull request #15425 from light-and-ray/fix_upscaler_2_images_do_not_match
fix upscaler 2 images do not match
2024-04-01 13:40:09 +03:00
Andray
86861f8379 fix upscaler 2 images do not match 2024-04-01 13:58:45 +04:00
storyicon
e73a7e4006 feat: ensure the indexability of dynamically imported packages
Signed-off-by: storyicon <storyicon@foxmail.com>
2024-04-01 09:13:07 +00:00
AUTOMATIC1111
aa4a45187e
Merge pull request #15417 from light-and-ray/fix_upscaler_2
Fix upscaler 2: add missed max_side_length
2024-03-31 18:49:21 +03:00
Andray
0a7d1e756f fix upscaler 2 2024-03-31 19:34:58 +04:00
AUTOMATIC1111
859f0f6b19
Merge pull request #15415 from light-and-ray/fix_dcd4f880a86e500ec88ddf7eafe65894a24b85a3
fix dcd4f880a86e500ec88ddf7eafe65894a24b85a3
2024-03-31 16:55:47 +03:00
AUTOMATIC1111
23ef5027c6
Merge pull request #15414 from DrBiggusDickus/dev2
Fix CodeFormer weight
2024-03-31 16:53:23 +03:00
Andray
4ccbae320e fix dcd4f880a86e500ec88ddf7eafe65894a24b85a3 2024-03-31 17:05:15 +04:00
DrBiggusDickus
ea83180761 fix CodeFormer weight 2024-03-31 14:41:06 +02:00
AUTOMATIC1111
f1a6c5fe17 add an option to hide postprocessing options in Extras tab 2024-03-31 08:30:00 +03:00
AUTOMATIC1111
bfa20d2758 resize Max side length field 2024-03-31 08:20:19 +03:00
AUTOMATIC1111
dcd4f880a8 rework code/UI for #15293 2024-03-31 08:17:22 +03:00
AUTOMATIC1111
7f3ce06de9
Merge pull request #15293 from light-and-ray/extras_upscaler_limit_target_resolution
Extras upscaler: option limit target resolution
2024-03-31 08:02:35 +03:00
AUTOMATIC1111
8bebfde701
Merge pull request #15350 from baseco/memory-bug-fix
minor bug fix of sd model memory management
2024-03-30 07:37:10 +03:00
AUTOMATIC1111
98096195dd
Merge pull request #15382 from huaizong/fix/whz/model-loaded-remove-v3
fix: when find already_loaded model, remove loaded by array index
2024-03-30 07:36:33 +03:00
AUTOMATIC1111
642bca4c3d
Merge pull request #15380 from light-and-ray/interrupt_upscale
interrupt upscale
2024-03-30 07:34:34 +03:00
AUTOMATIC1111
80b87107de
Merge pull request #15386 from eltociear/patch-3
fix typo in call_queue.py
2024-03-30 07:34:10 +03:00
AUTOMATIC1111
c4c8a64111 restore the line lost in the merge 2024-03-30 07:33:39 +03:00
AUTOMATIC1111
470d402b17
Merge pull request #15390 from ochen1/patch-1
fix: Python version check for PyTorch installation compatibility
2024-03-30 07:32:29 +03:00
AUTOMATIC1111
1dc8cc1bce
Merge branch 'dev' into patch-1 2024-03-30 07:31:08 +03:00
AUTOMATIC1111
8687163f7f
Merge pull request #15394 from light-and-ray/fix_ui_config_for_hires_sampler_and_scheduler
fix ui_config for hires sampler and scheduler
2024-03-27 16:42:09 +03:00
Andray
4e2bb7250f fix_ui_config_for_hires_sampler_and_scheduler 2024-03-27 15:35:06 +04:00
ochen1
5461b00e89
fix: Python version check for PyTorch installation compatibility 2024-03-26 21:22:09 -06:00
Ikko Eltociear Ashimine
16522cb0e3
fix typo in call_queue.py
amout -> amount
2024-03-27 03:01:06 +09:00
Andray
c321680b3d interrupt upscale 2024-03-26 14:53:38 +04:00
王怀宗
f4633cb9c0 fix: when find already_loaded model, remove loaded by array index 2024-03-26 18:29:51 +08:00
Boning
f62217b65d minor bug fix of sd model memory management 2024-03-25 10:38:15 -07:00
AUTOMATIC1111
dfbdb5a135 put request: gr.Request at start of img2img function similar to txt2img 2024-03-25 18:00:58 +03:00
AUTOMATIC1111
b0b90dc0d7
Merge pull request #15319 from catboxanon/feat/ssmd_cover_images
Support cover images embedded in safetensors metadata
2024-03-24 13:43:37 +03:00
AUTOMATIC1111
9aa9e980a9 support scheduler selection in hires fix 2024-03-24 11:00:16 +03:00
catboxanon
c4402500c7 Support ssmd_cover_images 2024-03-24 02:33:10 -04:00
AUTOMATIC1111
755d2cb2e5
Merge pull request #15343 from light-and-ray/escape_brackets_in_lora_random_prompt
escape brackets in lora random prompt generator
2024-03-24 05:31:33 +03:00
AUTOMATIC1111
0affa24ce2
Merge pull request #15354 from akx/xyz-script-size
Add Size as an XYZ Grid option
2024-03-24 05:27:00 +03:00
AUTOMATIC1111
bf2f7b3af4
Merge pull request #15333 from AUTOMATIC1111/scheduler_selection
Scheduler selection in main UI
2024-03-24 05:21:56 +03:00
AUTOMATIC1111
db61b876d6
Merge pull request #15361 from kaalibro/fix/scheduler_selection
Fix for "Scheduler selection" #15333
2024-03-24 05:21:40 +03:00
kaalibro
f3ca6a92ad
Fix for #15333
- Fix "X/Y/Z plot" not working with "Schedule type"
- Fix "Schedule type" not being saved to "params.txt"
2024-03-23 00:50:37 +05:00
Aarni Koskela
2941e1f1f3 Add Size as an XYZ Grid option 2024-03-22 12:04:03 +02:00
Andray
721c4309c2 escape brackets in lora random prompt generator 2024-03-21 16:29:51 +04:00
AUTOMATIC1111
57727e554d make #15334 work without making copies of images 2024-03-21 07:22:27 +03:00
AUTOMATIC1111
b80b1cf92c
Merge pull request #15334 from Gourieff/extras--allow-png-rgba--dev
Allow PNG-RGBA for Extras Tab
2024-03-21 07:21:15 +03:00
AUTOMATIC1111
5c5594ff16 linter 2024-03-21 07:09:40 +03:00
AUTOMATIC1111
65075896f2
Merge pull request #15310 from Dalton-Murray/update-pytorch-lightning-utilities
Update pytorch lightning utilities
2024-03-21 07:08:43 +03:00
Dalton
32ba757501
Re-add import but after if check 2024-03-20 23:55:04 -04:00
Dalton
4e6e2574ab
Cleanup ddpm_edit.py
Fully reverts this time
2024-03-20 23:36:35 -04:00
Dalton
41907b25f0
Cleanup sd_hijack_ddpm_v1.py
Forgot some things to revert
2024-03-20 23:35:32 -04:00
Dalton
4bc2963320
Remove unnecessary import 2024-03-20 23:33:15 -04:00
Dalton
4eb5e09873
Update initialize_util.py 2024-03-20 23:28:40 -04:00
Dalton
b5b04912b5
Include running pytorch lightning check 2024-03-20 23:06:00 -04:00
Dalton
f010dfffb9
Revert ddpm_edit.py 2024-03-20 23:02:30 -04:00
Dalton
5fd9a40b92
Revert sd_hijack_ddpm_v1.py 2024-03-20 23:01:50 -04:00
Art Gourieff
e0cad0f87a Merge remote-tracking branch 'upstream/dev' into extras--allow-png-rgba--dev 2024-03-20 15:28:17 +07:00
Art Gourieff
8ec8901921 FIX: No specific type for 'image' arg
Roll back
2024-03-20 15:20:29 +07:00
Art Gourieff
702edb288e FIX: initial_pp RGBA right way 2024-03-20 15:14:28 +07:00
AUTOMATIC1111
31306ce672 change the behavior of discard_next_to_last_sigma for sgm_uniform to match other schedulers 2024-03-20 10:29:52 +03:00
AUTOMATIC1111
ac9aa44cb8 do not add 'Automatic' to infotext 2024-03-20 10:27:53 +03:00
AUTOMATIC1111
76f8436bfa add Uniform scheduler 2024-03-20 10:27:32 +03:00
Art Gourieff
61f488302f FIX: Allow PNG-RGBA for Extras Tab 2024-03-20 13:28:32 +07:00
AUTOMATIC1111
25cd53d775 scheduler selection in main UI 2024-03-20 09:17:11 +03:00
AUTOMATIC1111
060e55dfe3
Merge pull request #15331 from AUTOMATIC1111/extra-networks-buttons
Fix extra networks buttons when filename contains an apostrophe
2024-03-20 06:53:55 +03:00
missionfloyd
b5c33341a1
Don't use quote_js on filename 2024-03-19 19:06:56 -06:00
missionfloyd
6e420c7be2
Merge branch 'dev' into extra-networks-buttons 2024-03-19 19:03:53 -06:00
missionfloyd
d7f48472cc Fix extra networks buttons when filename contains an apostrophe 2024-03-19 18:50:25 -06:00
Dalton
49779413aa
Formatting sd_hijack_ddpm_v1.py 2024-03-19 14:54:06 -04:00
Dalton
8f450321fe
Formatting ddpm_edit 2024-03-19 14:53:30 -04:00
Dalton
86276832e0
Update sd_hijack_ddpm_v1.py 2024-03-19 14:45:07 -04:00
Dalton
61f321756f
Update ddpm_edit.py 2024-03-19 14:44:31 -04:00
AUTOMATIC1111
d44b8aa8c1
Merge pull request #15325 from AUTOMATIC1111/sgm_uniform
Sgm uniform scheduler for SDXL-Lightning models
2024-03-19 21:37:16 +03:00
Kohaku-Blueleaf
a6b5a513f9 Implementation for sgm_uniform branch 2024-03-19 20:05:54 +08:00
AUTOMATIC1111
c4a00affc5 use existing quote_js function for #15316 2024-03-19 08:10:27 +03:00
AUTOMATIC1111
522121be7e
Merge pull request #15316 from AUTOMATIC1111/escape-filename
Escape btn_copy_path filename
2024-03-19 08:02:36 +03:00
missionfloyd
3fa1ebed62 Escape btn_copy_path filename 2024-03-18 21:47:52 -06:00
AUTOMATIC1111
7ac7600dc3
Merge pull request #15307 from AUTOMATIC1111/restore-outputs-path
restore outputs path
2024-03-18 19:33:48 +03:00
w-e-w
e9d4da7b56 restore outputs path
output -> outputs
2024-03-19 00:54:56 +09:00
AUTOMATIC1111
c4664b5a9c fix for listing wrong requirements for extensions 2024-03-18 08:00:42 +03:00
Andray
203afa39c4 update tooltip 2024-03-18 06:52:46 +04:00
Dalton
51cb20ec39
Update ddpm_edit.py 2024-03-17 22:45:31 -04:00
Dalton
2a6054f836
Update sd_hijack_ddpm_v1.py 2024-03-17 22:37:19 -04:00
AUTOMATIC1111
8ac4a207f3
Merge pull request #15299 from AUTOMATIC1111/diskcache-bett
Tweak diskcache limits
2024-03-17 23:59:12 +03:00
Aarni Koskela
df4da02ab0 Tweak diskcache limits 2024-03-17 20:25:25 +00:00
AUTOMATIC1111
f1b090e9e0
Merge pull request #15287 from AUTOMATIC1111/diskcache
use diskcache library for caching
2024-03-17 23:20:00 +03:00
AUTOMATIC1111
611faaddef change the default name for callback from None to "unnamed" 2024-03-17 23:19:24 +03:00
AUTOMATIC1111
daa1b33247 make reloading UI scripts optional when doing Reload UI, and off by default 2024-03-17 18:16:12 +03:00
Andray
fd83d4eec3 add .needs_reload_ui() 2024-03-17 18:19:13 +04:00
Andray
81be357925 hide limit target resolution under option 2024-03-17 14:51:19 +04:00
AUTOMATIC1111
79cbc92abf change code for variant requirements in metadata.ini 2024-03-17 13:30:20 +03:00
Andray
06c5dd0907 maybe fix tests 2024-03-17 14:28:26 +04:00
AUTOMATIC1111
908d522057 update ruff to 0.3.3 2024-03-17 13:19:44 +03:00
AUTOMATIC1111
4ce2e25c0b
Merge pull request #15290 from light-and-ray/allow_variants_for_extension_name_in_metadata.ini
allow variants for extension name in metadata.ini
2024-03-17 13:19:23 +03:00
Andray
ef35619325 Extras upscaler: option limit target resolution 2024-03-17 14:14:12 +04:00
Andray
b1cd0189bc allow variants for extension name in metadata.ini 2024-03-17 13:05:35 +04:00
AUTOMATIC1111
c95c46004a
Merge pull request #15288 from light-and-ray/allow_use_zoom.js_outside_webui_context
little fixes zoom.js
2024-03-17 09:48:33 +03:00
Andray
c3f75d1d85 little fixes zoom.js 2024-03-17 10:30:11 +04:00
AUTOMATIC1111
c12ba58433
Merge pull request #15286 from light-and-ray/allow_use_zoom.js_outside_webui_context
allow use zoom.js outside webui context [for extensions]
2024-03-17 09:20:51 +03:00
AUTOMATIC1111
66355b4775 use diskcache library for caching 2024-03-17 09:18:32 +03:00
Andray
e9b8a89b3c allow use zoom.js outside webui context 2024-03-17 09:29:11 +04:00
AUTOMATIC1111
93c7b9d7fc linter for #15262 2024-03-17 07:02:31 +03:00
AUTOMATIC1111
6d8b7ec188
Merge pull request #15262 from catboxanon/feat/dragdrop-urls
Support dragdrop for URLs to read infotext
2024-03-17 07:02:08 +03:00
catboxanon
446cd5a58b
dragdrop: add error handling for URLs 2024-03-16 20:19:12 -04:00
missionfloyd
83a9dd82db Download image client-side 2024-03-16 17:10:26 -06:00
missionfloyd
3da13f0cc9 Fix dragging to/from firefox 2024-03-16 15:46:29 -06:00
AUTOMATIC1111
df8c09bcb3
Merge pull request #15283 from AUTOMATIC1111/dora-weight-decompose
Use correct DoRA implementation
2024-03-16 20:20:08 +03:00
AUTOMATIC1111
8dcb8faf5d
Merge branch 'dev' into dora-weight-decompose 2024-03-16 20:20:02 +03:00
Kohaku-Blueleaf
199c51d688 linter 2024-03-17 00:00:07 +08:00
Kohaku-Blueleaf
1792e193b1 Use correct implementation, fix device error 2024-03-16 23:52:29 +08:00
AUTOMATIC1111
bf35c66183 fix for #15179 2024-03-16 18:45:19 +03:00
AUTOMATIC1111
cb09e1ef7d
Merge pull request #15179 from llnancy/master
fix: fix syntax errors
2024-03-16 18:45:01 +03:00
AUTOMATIC1111
0283826179 prevent make alt key from opening main menu if it's used for brush size also 2024-03-16 18:44:36 +03:00
AUTOMATIC1111
2f9d1c33e2
Merge pull request #15267 from light-and-ray/prevent_alt_menu_on_firefox
prevent alt menu for firefox
2024-03-16 18:31:55 +03:00
AUTOMATIC1111
874809e0ca
Merge pull request #15268 from light-and-ray/handle_0_wheel_deltaX
handle 0 wheel deltaY
2024-03-16 18:25:00 +03:00
Andray
c364b60776 handle 0 wheel deltaX 2024-03-16 18:08:02 +04:00
Andray
7598a92436 use e.key instead of e.code 2024-03-16 17:49:05 +04:00
Andray
eb2ea8df1d check e.key in up event 2024-03-16 17:42:25 +04:00
Andray
9142ce8188 fix linter and do not require reload page if option was changed 2024-03-16 16:14:57 +04:00
Andray
79514e5b8e prevent defaults for alt only if mouse inside image 2024-03-16 16:06:21 +04:00
AUTOMATIC1111
bb9df5cdc9
Merge pull request #15276 from AUTOMATIC1111/v180_hr_styles-actual-version-number
v180_hr_styles actual version number
2024-03-16 12:40:24 +03:00
AUTOMATIC1111
e8613dbc93
Merge pull request #15231 from light-and-ray/fix_ui-config_for_InputAccordion
fix ui-config for InputAccordion [custom_script_source]
2024-03-16 12:35:43 +03:00
Andray
cc8ea32501 fix ui-config for InputAccordion 2024-03-16 12:32:39 +04:00
w-e-w
38a7dc5488 v180_hr_styles actual version number 2024-03-16 17:19:38 +09:00
AUTOMATIC1111
5bd2724765
Merge pull request #15205 from AUTOMATIC1111/callback_order
Callback order
2024-03-16 09:45:41 +03:00
AUTOMATIC1111
9fd693272f
Merge pull request #15211 from light-and-ray/type_hintinh_in_shared.py
type hinting in shared.py
2024-03-16 09:45:30 +03:00
AUTOMATIC1111
f7bad19e00
Merge pull request #15221 from AUTOMATIC1111/fix-Restore-progress
fix "Restore progress" button
2024-03-16 09:44:50 +03:00
AUTOMATIC1111
03ea0f3bfc
Merge pull request #15222 from light-and-ray/move_postprocessing-for-training_into_builtin_extensions
move postprocessing-for-training into builtin extensions
2024-03-16 09:43:01 +03:00
AUTOMATIC1111
2fc47b44c2
Merge pull request #15223 from light-and-ray/move_upscale_postprocessing_under_input_accordion
move upscale postprocessing under input accordion
2024-03-16 09:41:40 +03:00
AUTOMATIC1111
446e49d6db
Merge branch 'dev' into move_upscale_postprocessing_under_input_accordion 2024-03-16 09:41:16 +03:00
AUTOMATIC1111
8bc9978909
Merge pull request #15228 from wangshuai09/ascend_npu_readme
Ascend NPU wiki page
2024-03-16 09:39:34 +03:00
AUTOMATIC1111
1282bceeba
Merge pull request #15233 from light-and-ray/featch_only_active_branch_updates_for_extensions
featch only active branch updates for extensions
2024-03-16 09:06:33 +03:00
AUTOMATIC1111
d38b390ed4
Merge pull request #15239 from AUTOMATIC1111/Fix-lora-bugs
Add missing .mean() back
2024-03-16 09:06:05 +03:00
AUTOMATIC1111
63c3c4dbc3 simplify code for #15244 2024-03-16 09:04:08 +03:00
AUTOMATIC1111
afb9296e0d
Merge pull request #15244 from Haoming02/auto-scale-by
Automatically Set the Scale by value when user selects an Upscale Model
2024-03-16 08:49:32 +03:00
AUTOMATIC1111
c9244ef83a
Merge pull request #15224 from DGdev91/dev
Better workaround for Navi1, removing --pre for Navi3
2024-03-16 08:45:02 +03:00
AUTOMATIC1111
a072c1997d
Merge pull request #15259 from AUTOMATIC1111/PEP-604-annotations
PEP 604 annotations
2024-03-16 08:43:02 +03:00
AUTOMATIC1111
3cb698ac15
Merge pull request #15260 from v0xie/fix-OFT-MhA-AttributeError
Fix AttributeError in OFT when trying to get MultiheadAttention weight
2024-03-16 08:42:45 +03:00
AUTOMATIC1111
0cc3647c1c
Merge pull request #15261 from catboxanon/fix/imageviewer-click
Make imageviewer event listeners browser consistent
2024-03-16 08:41:11 +03:00
AUTOMATIC1111
3ffe47c6b7
Merge pull request #15263 from AUTOMATIC1111/fix-hr-comments
Strip comments from hires fix prompt
2024-03-16 08:30:16 +03:00
AUTOMATIC1111
c5aa7b65f7
Merge pull request #15269 from AUTOMATIC1111/fix-Hires-prompt-Styles
fix issue with Styles when Hires prompt is used
2024-03-16 08:25:39 +03:00
AUTOMATIC1111
01ba5ad213
Merge pull request #15272 from AUTOMATIC1111/bump-action-version
bump action version
2024-03-16 08:22:48 +03:00
w-e-w
a3a648bf6b bump action version 2024-03-16 05:57:23 +09:00
w-e-w
887a512208 fix issue with Styles when Hires prompt is used 2024-03-15 21:06:54 +09:00
Andray
6f51e05553 prevent alt menu for firefox 2024-03-15 12:12:37 +04:00
missionfloyd
5f4203bf9b Strip comments from hires fix prompt 2024-03-14 22:23:06 -06:00
catboxanon
8eaa7e9f04 Support dragdrop for URLs 2024-03-15 04:06:17 +00:00
catboxanon
76fd487818
Make imageviewer event listeners browser consistent 2024-03-14 21:59:53 -04:00
v0xie
07805cbeee fix: AttributeError when attempting to reshape rescale by org_module weight 2024-03-14 17:05:14 -07:00
w-e-w
c40f33ca04 PEP 604 annotations 2024-03-15 08:22:36 +09:00
Haoming
4e17fc36d8 add user setting
Now this is disabled by default
2024-03-14 10:04:09 +08:00
Haoming
fd71b761ff use re instead of hardcoding
Now supports all natively provided upscaler as well
2024-03-14 09:55:14 +08:00
Haoming
d18eb10ecd add hook 2024-03-13 21:15:52 +08:00
KohakuBlueleaf
9f2ae1cb85 Add missing .mean 2024-03-13 11:47:33 +08:00
DGdev91
32f0b5dbaf Merge branch 'dev' of https://github.com/DGdev91/stable-diffusion-webui into dev 2024-03-13 00:56:42 +01:00
DGdev91
2efc7c1b05 Better workaround for Navi1, removing --pre for Navi3 2024-03-13 00:54:32 +01:00
DGdev91
9fbfb8ad32 Better workaround for Navi1 - fix if 2024-03-13 00:43:01 +01:00
DGdev91
74e2e5279c Workaround for Navi1: pytorch nightly whl for 3.8 and 3.9 2024-03-13 00:17:24 +01:00
Andray
b980c8140b featch only active branch updates for extensions 2024-03-12 22:21:59 +04:00
wangshuai09
994e08aac1 ascend npu readme 2024-03-12 18:45:26 +08:00
DGdev91
8262cd71c4 Better workaround for Navi1, removing --pre for Navi3 2024-03-12 00:09:07 +01:00
Andray
2e3a0f39f6 move upscale postprocessing under input accordion 2024-03-12 02:28:15 +04:00
Andray
4079b17dd9 move postprocessing-for-training into builtin extensions 2024-03-12 01:50:57 +04:00
w-e-w
1a1205f601 fix Restore progress 2024-03-12 03:26:50 +09:00
Andray
2d57a2df66
Update modules/shared.py
Co-authored-by: catboxanon <122327233+catboxanon@users.noreply.github.com>
2024-03-11 07:40:15 +04:00
Andray
eb10da8bb7 type hinting in shared.py 2024-03-11 05:15:09 +04:00
AUTOMATIC1111
3e0146f9bd restore the lost Uncategorized options section 2024-03-10 22:40:35 +03:00
AUTOMATIC1111
1bbc8a153b Merge branch 'dev' into callback_order 2024-03-10 16:15:09 +03:00
AUTOMATIC1111
3670b4f49e lint 2024-03-10 15:16:12 +03:00
AUTOMATIC1111
2f55d669a2 add support for specifying callback order in metadata 2024-03-10 15:14:04 +03:00
AUTOMATIC1111
edc56202c1
Merge pull request #15201 from AUTOMATIC1111/update-preview-on-Replace-Preview
update preview on Replace Preview
2024-03-10 14:11:26 +03:00
AUTOMATIC1111
7e5e67330b add UI for reordering callbacks 2024-03-10 14:09:48 +03:00
w-e-w
9fd0cd6a80 update preview on Replace Preview 2024-03-10 18:24:52 +09:00
SunChaser
9b842e9ec7
fix: resolve type annotation warnings 2024-03-10 16:19:59 +08:00
AUTOMATIC1111
0411eced89 add names to callbacks 2024-03-10 07:52:57 +03:00
AUTOMATIC1111
2e93bdce0c
Merge pull request #15198 from zopieux/search-desc
Add model description to searched terms
2024-03-10 07:03:16 +03:00
AUTOMATIC1111
8076100e14
Merge pull request #15199 from AUTOMATIC1111/add-entry-to-MassFileLister-after-writing-metadata
Add entry to MassFileLister  after writing metadata
2024-03-10 07:01:46 +03:00
w-e-w
fb62f1fb40 add entry to MassFileLister after writing metadata
fix #15184
2024-03-10 06:07:16 +09:00
Alexandre Macabies
0085e719a9 Add model description to searched terms.
This adds the model description to the searchable terms.
This is particularly useful since the description can be used to store
arbitrary tags, independently from the filename, which is imposed by the
model publisher.
2024-03-09 21:53:38 +01:00
AUTOMATIC1111
6136db1409 linter 2024-03-09 12:21:46 +03:00
AUTOMATIC1111
110e3d7033
Merge pull request #15191 from AUTOMATIC1111/fix-default-in-get_learned_conditioning
Avoid error from None in get_learned_conditioning
2024-03-09 12:21:23 +03:00
Kohaku-Blueleaf
0dc179ee72 Avoid error from None 2024-03-09 17:12:54 +08:00
AUTOMATIC1111
4c9a7b8a75
Merge pull request #15190 from AUTOMATIC1111/dora-weight-decompose
Fix built-in lora system bugs caused by torch.nn.MultiheadAttention
2024-03-09 08:29:51 +03:00
AUTOMATIC1111
1770b887ec
Merge pull request #15189 from 10sa/dev
Add '--no-prompt-history' cmd args for disable last generation prompt history
2024-03-09 08:28:56 +03:00
AUTOMATIC1111
18d801a13d stylistic changes for extra network sorting/search controls 2024-03-09 08:25:01 +03:00
Kohaku-Blueleaf
851c3d51ed Fix bugs for torch.nn.MultiheadAttention 2024-03-09 12:31:32 +08:00
AUTOMATIC1111
5251733c0d use natural sort in extra networks when ordering by path 2024-03-09 07:24:51 +03:00
10sa
c50b7e4eff Add '--no-prompt-history' cmd args for disable last generation prompt history 2024-03-09 11:43:49 +09:00
AUTOMATIC1111
d318f1b5e1
Merge pull request #15183 from jim60105/master
chore: fix font not loaded
2024-03-08 21:58:41 +03:00
陳鈞
02a4ceabdd
chore: fix font not loaded
fix #15182
2024-03-09 02:13:35 +08:00
AUTOMATIC1111
7d1368c51c lint 2024-03-08 17:11:56 +03:00
AUTOMATIC1111
758e8d7b41 undo unwanted change for extra networks 2024-03-08 17:11:42 +03:00
AUTOMATIC1111
530fea2bc4 optimization for extra networks sorting 2024-03-08 17:09:11 +03:00
AUTOMATIC1111
3bd75adb1c optimization for extra networks filtering 2024-03-08 16:54:39 +03:00
SunChaser
01f531e9b1
fix: fix syntax errors 2024-03-08 17:25:28 +08:00
AUTOMATIC1111
a551a43164 add an option to have old-style directory view instead of tree view 2024-03-08 09:52:25 +03:00
AUTOMATIC1111
a43ce7eabb fix broken resize handle on the train tab 2024-03-08 08:13:08 +03:00
AUTOMATIC1111
9409419afb
Merge pull request #15160 from AUTOMATIC1111/dora-weight-decompose
Add DoRA (weight-decompose) support for LoRA/LoHa/LoKr
2024-03-08 08:02:17 +03:00
AUTOMATIC1111
e0c9361b7d performance optimization for extra networks 2024-03-08 07:51:31 +03:00
AUTOMATIC1111
8b96f3d036
Merge pull request #15178 from catboxanon/feat/edit-attention-whitespace-trim
edit-attention: deselect surrounding whitespace
2024-03-08 06:21:24 +03:00
catboxanon
5ab5405b6f
Simpler comparison
Co-authored-by: missionfloyd <missionfloyd@users.noreply.github.com>
2024-03-07 21:30:05 -05:00
catboxanon
766f6e3eca
edit-attention: deselect surrounding whitespace 2024-03-07 18:30:36 -05:00
Kohaku-Blueleaf
12bcacf413 Initial implementation 2024-03-07 13:29:40 +08:00
AUTOMATIC1111
58f7410c9d
Merge pull request #14820 from alexhegit/master
Update to ROCm5.7 and PyTorch
2024-03-06 15:45:39 +03:00
AUTOMATIC1111
ea3aae9c39
Merge branch 'dev' into master 2024-03-06 15:44:55 +03:00
AUTOMATIC1111
8904e00842
Merge pull request #15148 from continue-revolution/conrevo/fix-soft-inpaint
Fix Soft Inpaint for AnimateDiff
2024-03-06 15:36:01 +03:00
continue-revolution
7d59b3b564 rm comment 2024-03-06 05:39:17 -06:00
continue-revolution
7f766cd762 Merge branch 'dev' into conrevo/fix-soft-inpaint 2024-03-06 05:33:30 -06:00
continue-revolution
73e635ce6e fix 2024-03-06 05:32:59 -06:00
AUTOMATIC1111
ecd5fa9c42
Merge pull request #15131 from catboxanon/feat/extra-network-metadata
Re-use profiler visualization for extra networks
2024-03-06 13:08:43 +03:00
AUTOMATIC1111
14215beb48
Merge pull request #15135 from AUTOMATIC1111/fix-extract_style_text_from_prompt
fix extract_style_text_from_prompt #15132
2024-03-06 13:07:43 +03:00
AUTOMATIC1111
11ef1a9302
Merge pull request #15142 from catboxanon/fix/emphasis-prompt-txt-write-order
Fix emphasis infotext missing from `params.txt`
2024-03-06 13:07:02 +03:00
AUTOMATIC1111
c1deec64cb lint 2024-03-06 13:06:13 +03:00
AUTOMATIC1111
2bb296531d
Merge pull request #15141 from catboxanon/feat/emphasis-infotext-parse
Only override emphasis if actually used in prompt
2024-03-06 13:05:56 +03:00
catboxanon
ed386c84b6
Fix emphasis infotext missing from params.txt 2024-03-05 11:53:36 -05:00
catboxanon
7785d484ae
Only override emphasis if actually used in prompt 2024-03-05 11:50:53 -05:00
w-e-w
706f63adfa fix extract_style_text_from_prompt #15132 2024-03-05 12:35:46 +09:00
catboxanon
ecffe8513e
Lint 2024-03-04 18:46:25 -05:00
catboxanon
801461eea2 Re-use profiler visualization for extra networks 2024-03-04 18:33:22 -05:00
AUTOMATIC1111
eee46a5094
Merge pull request #14981 from wangshuai09/gpu_info_for_ascend
Add training support and change lspci for Ascend NPU
2024-03-04 20:06:54 +03:00
AUTOMATIC1111
09b5ce68a9 add images.read to automatically fix all jpeg/png weirdness 2024-03-04 19:14:53 +03:00
AUTOMATIC1111
5625ce1b1a
Merge pull request #14958 from HTYISABUG/dev
Error handling for unsupported transparency
2024-03-04 18:40:16 +03:00
AUTOMATIC1111
58278aa71c
Merge pull request #15121 from AUTOMATIC1111/fix-settings-in-ui
[alternative fix] can't load webui if selected wrong extra option in ui
2024-03-04 18:24:09 +03:00
AUTOMATIC1111
33fbe943e2
Merge pull request #15062 from astriaai/fix-exif-orientation-api
Fix EXIF orientation in API image loading
2024-03-04 16:26:53 +03:00
AUTOMATIC1111
0dc12861ef call script_callbacks.ui_settings_callback earlier; fix extra-options-section built-in extension killing the ui if using a setting that doesn't exist 2024-03-04 15:30:46 +03:00
Alon Burg
67d8dafe44 Fix EXIF orientation in API image loading 2024-03-04 12:23:14 +02:00
wangshuai09
3fb1c2e58d fix npu-smi command 2024-03-04 17:19:37 +08:00
AUTOMATIC1111
92d77e3fa8
Merge pull request #15102 from light-and-ray/fix_jpeg_live_preview
fix_jpeg_live_preview
2024-03-04 10:30:24 +03:00
AUTOMATIC1111
48a677c4ac
Merge pull request #15116 from akx/typos
Fix various typos with crate-ci/typos
2024-03-04 10:28:42 +03:00
Aarni Koskela
e3fa46f26f Fix various typos with crate-ci/typos 2024-03-04 08:42:07 +02:00
AUTOMATIC1111
e2a8745abc
Merge pull request #15084 from clayne/1709395892-upscale-logging-reduce
upscaler_utils: Reduce logging
2024-03-04 06:50:03 +03:00
Christopher Layne
3c0177a24b upscaler_utils: Reduce logging
* upscale_with_model: Remove debugging logging occurring in loop as
  it's an excessive amount of noise when running w/ DEBUG log levels.
2024-03-03 11:41:32 -08:00
Andray
0103365697 fix_jpeg_live_preview 2024-03-03 16:54:58 +04:00
AUTOMATIC1111
45b8a499a7 fix wrong condition 2024-03-02 10:36:48 +03:00
AUTOMATIC1111
bb24c13ed7 infotext support for #14978 2024-03-02 07:39:59 +03:00
AUTOMATIC1111
aabedcbcc7
Merge pull request #14978 from drhead/refiner_fix
Make refiner switchover based on model timesteps instead of sampling steps
2024-03-02 07:24:44 +03:00
AUTOMATIC1111
f4cb21bb8a
Merge pull request #15031 from light-and-ray/unix_filenames
cmd args: `--unix-filenames-sanitization` and `--filenames-max-length`
2024-03-02 07:16:06 +03:00
AUTOMATIC1111
6044a9723a
Merge pull request #15059 from Dalton-Murray/direct-binary-release-link
Add a direct link to the binary release
2024-03-02 07:15:32 +03:00
AUTOMATIC1111
9189ea20b0
Merge pull request #15041 from light-and-ray/resize_handle_for_extra_networks
resize handle for extra networks
2024-03-02 07:13:00 +03:00
AUTOMATIC1111
95d143eafe Merge branch 'master' into dev 2024-03-02 07:04:33 +03:00
AUTOMATIC1111
bef51aed03 Merge branch 'release_candidate' 2024-03-02 07:03:13 +03:00
AUTOMATIC1111
1398485789 update changelog 2024-03-02 07:00:08 +03:00
AUTOMATIC1111
141a17e969 style changes for #14979 2024-03-02 06:55:03 +03:00
AUTOMATIC1111
da67afe5f6 call apply_alpha_schedule_override in load_model_weights for #14979 2024-03-02 06:54:58 +03:00
AUTOMATIC1111
28bc85a20a Merge pull request #14979 from drhead/refiner_cumprod_fix
Protect alphas_cumprod during refiner switchover
2024-03-02 06:54:55 +03:00
AUTOMATIC1111
978c7fadb3 Merge pull request #15039 from light-and-ray/dat_cmd_flag
dat cmd flag
2024-03-02 06:54:52 +03:00
AUTOMATIC1111
d558cb69b0 Merge pull request #15065 from light-and-ray/resizeHandle_handle_double_tap
resizeHandle handle double tap
2024-03-02 06:54:49 +03:00
AUTOMATIC1111
0b07a6cf26 Merge pull request #15035 from AUTOMATIC1111/fix/normalized-filepath-absolute
Use `absolute` path for normalized filepath
2024-03-02 06:54:48 +03:00
AUTOMATIC1111
024a32a09b Merge pull request #15012 from light-and-ray/register_tmp_file-also-with-mtime
register_tmp_file also for mtime
2024-03-02 06:54:46 +03:00
AUTOMATIC1111
b47756385d Merge pull request #15010 from light-and-ray/fix_resize-handle_for_vertical_layout
Fix resize-handle visability for vertical layout (mobile)
2024-03-02 06:54:44 +03:00
AUTOMATIC1111
ee470cc6a3 style changes for #14979 2024-03-02 06:54:11 +03:00
AUTOMATIC1111
1a51b166a0 call apply_alpha_schedule_override in load_model_weights for #14979 2024-03-02 06:53:53 +03:00
AUTOMATIC1111
06b9200e91
Merge pull request #14979 from drhead/refiner_cumprod_fix
Protect alphas_cumprod during refiner switchover
2024-03-02 06:40:32 +03:00
AUTOMATIC1111
f04e76811a
Merge pull request #15039 from light-and-ray/dat_cmd_flag
dat cmd flag
2024-03-02 06:38:50 +03:00
AUTOMATIC1111
817d9b15f7
Merge pull request #15065 from light-and-ray/resizeHandle_handle_double_tap
resizeHandle handle double tap
2024-03-02 06:37:19 +03:00
AUTOMATIC1111
150b603770
Merge pull request #15035 from AUTOMATIC1111/fix/normalized-filepath-absolute
Use `absolute` path for normalized filepath
2024-03-02 06:35:46 +03:00
Andray
eb0b84c564 make minimal width 2 times smaller then default 2024-02-29 16:02:21 +04:00
Andray
bb99f52712 resizeHandle handle double tap 2024-02-29 15:40:15 +04:00
Dalton
bce09eb987
Add a direct link to the binary release 2024-02-29 01:04:46 -05:00
Andray
51cc1ff2c9 fix for mobile and allow collapse right column 2024-02-27 23:31:47 +04:00
Andray
b4c44e659b fix on reload with changed show all loras setting 2024-02-27 23:17:52 +04:00
Andray
de7604fa77 lint 2024-02-27 18:38:38 +04:00
Andray
44bce3c74e resize handle for extra networks 2024-02-27 18:31:36 +04:00
Andray
3ba575216a dat cmd flag 2024-02-27 15:10:51 +04:00
drhead
4dae91a1fe
remove alphas cumprod fix from samplers_common 2024-02-26 23:46:10 -05:00
drhead
94f23d00a7
move alphas cumprod override out of processing 2024-02-26 23:44:58 -05:00
drhead
e2cd92ea23
move refiner fix to sd_models.py 2024-02-26 23:43:27 -05:00
catboxanon
3a618e3d24
Fix normalized filepath, resolve -> absolute
https://github.com/lllyasviel/stable-diffusion-webui-forge/issues/313
https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/14942#discussioncomment-8550050
2024-02-26 12:44:57 -05:00
Andray
dd4b0b95d5 cmd args: allow unix filenames and filenames max length 2024-02-26 16:30:15 +04:00
AUTOMATIC1111
c8a5322d1f
Merge pull request #15012 from light-and-ray/register_tmp_file-also-with-mtime
register_tmp_file also for mtime
2024-02-26 12:53:21 +03:00
AUTOMATIC1111
ca0308b60d
Merge pull request #15010 from light-and-ray/fix_resize-handle_for_vertical_layout
Fix resize-handle visability for vertical layout (mobile)
2024-02-26 12:52:34 +03:00
Andray
6e6cc2922d fix resize handle 2024-02-26 13:37:29 +04:00
AUTOMATIC1111
eaf5e0289a update cahngelog 2024-02-26 07:37:26 +03:00
AUTOMATIC1111
f97e3548e5 Merge pull request #15006 from imnodb/master
fix: the `split_threshold` parameter does not work when running Split oversized images
2024-02-26 07:35:42 +03:00
AUTOMATIC1111
e651ca8adb Merge pull request #15004 from light-and-ray/ResizeHandleRow_-_allow_overriden_column_scale_parametr
ResizeHandleRow - allow overriden column scale parametr
2024-02-26 07:35:36 +03:00
AUTOMATIC1111
78e421e4ea Merge pull request #14995 from dtlnor/14591-bug-the-categories-layout-is-different-when-localization-is-on
Fix #14591 using translated content to do categories mapping
2024-02-26 07:35:32 +03:00
AUTOMATIC1111
a10c8df876 Merge pull request #14973 from AUTOMATIC1111/Fix-new-oft-boft
Fix the OFT/BOFT bugs when using new LyCORIS implementation
2024-02-26 07:35:28 +03:00
drhead
648f6a8e0c
dont need to preserve alphas_cumprod_original 2024-02-25 23:28:36 -05:00
AUTOMATIC1111
2b7ddcbb5c
Merge pull request #15006 from imnodb/master
fix: the `split_threshold` parameter does not work when running Split oversized images
2024-02-26 07:16:42 +03:00
AUTOMATIC1111
e3a8dc6e23
Merge pull request #15004 from light-and-ray/ResizeHandleRow_-_allow_overriden_column_scale_parametr
ResizeHandleRow - allow overriden column scale parametr
2024-02-26 07:16:24 +03:00
AUTOMATIC1111
ca8dc2bde2
Merge pull request #14995 from dtlnor/14591-bug-the-categories-layout-is-different-when-localization-is-on
Fix #14591 using translated content to do categories mapping
2024-02-26 07:12:31 +03:00
AUTOMATIC1111
900419e85e
Merge pull request #14973 from AUTOMATIC1111/Fix-new-oft-boft
Fix the OFT/BOFT bugs when using new LyCORIS implementation
2024-02-26 07:12:12 +03:00
Andray
3a99824638 register_tmp_file also with mtime 2024-02-23 20:26:56 +04:00
Andray
bab918f049 fix resize-handle for vertical layout 2024-02-23 18:34:24 +04:00
DB Eriospermum
ed594d7ba6
fix: the split_threshold parameter does not work when running Split oversized images 2024-02-23 13:37:37 +08:00
Andray
9211febbfc ResizeHandleRow - allow overriden column scale parametr 2024-02-23 02:32:12 +04:00
AUTOMATIC1111
3069716510 update changelog 2024-02-22 23:00:14 +03:00
AUTOMATIC1111
dfab42c949 Merge pull request #15002 from light-and-ray/support_resizable_columns_for_touch_(tablets)
support resizable columns for touch (tablets)
2024-02-22 22:59:44 +03:00
AUTOMATIC1111
18819723c1
Merge pull request #15002 from light-and-ray/support_resizable_columns_for_touch_(tablets)
support resizable columns for touch (tablets)
2024-02-22 22:59:26 +03:00
AUTOMATIC1111
6bc35be10a update changelog 2024-02-22 21:29:58 +03:00
AUTOMATIC1111
b53989b195 update changelog 2024-02-22 21:29:10 +03:00
AUTOMATIC1111
726aaea0fe make extra network card description plaintext by default, with an option to re-enable HTML as it was 2024-02-22 21:27:28 +03:00
AUTOMATIC1111
3f18a09c86 make extra network card description plaintext by default, with an option to re-enable HTML as it was 2024-02-22 21:27:10 +03:00
Andray
58985e6b37 fix lint 2 2024-02-22 17:22:00 +04:00
Andray
ab1e0fa9bf fix lint and console warning 2024-02-22 17:16:16 +04:00
Andray
85abbbb8fa support resizable columns for touch (tablets) 2024-02-22 17:04:56 +04:00
wangshuai09
ba66cf8d69 update 2024-02-22 20:17:10 +08:00
AUTOMATIC1111
052fbde3ac possible fix for reload button not appearing in some cases for extra networks. 2024-02-22 10:48:30 +03:00
AUTOMATIC1111
1da05297ea possible fix for reload button not appearing in some cases for extra networks. 2024-02-22 10:28:03 +03:00
dtlnor
f537e5a519 fix #14591 - using translated content to do categories mapping 2024-02-22 12:26:57 +09:00
Kohaku-Blueleaf
c4afdb7895
For no constraint 2024-02-22 00:43:32 +08:00
Kohaku-Blueleaf
64179c3221
Update network_oft.py 2024-02-21 22:50:43 +08:00
wangshuai09
b7aa425344 del gpu_info for npu 2024-02-21 11:49:06 +08:00
drhead
9c1ece8978
Protect alphas_cumprod during refiner switchover 2024-02-20 19:23:21 -05:00
drhead
bf348032bc
fix missing arg 2024-02-20 16:59:28 -05:00
drhead
25eeeaa65f
Allow refiner to be triggered by model timestep instead of sampling 2024-02-20 16:37:29 -05:00
drhead
09d2e58811
Pass sigma to apply_refiner 2024-02-20 16:22:40 -05:00
drhead
f4869f8de3
Add compatibility option for refiner switching 2024-02-20 16:18:13 -05:00
Kohaku-Blueleaf
591470d86d linting 2024-02-20 17:21:34 +08:00
Kohaku-Blueleaf
a5436a3ac0 Update network_oft.py 2024-02-20 17:20:14 +08:00
AUTOMATIC1111
140d58b512 Merge pull request #14966 from light-and-ray/avoid_doble_upscaling_in_inpaint
[bug] avoid doble upscaling in inpaint
2024-02-19 18:06:16 +03:00
AUTOMATIC1111
0a271938d8
Merge pull request #14966 from light-and-ray/avoid_doble_upscaling_in_inpaint
[bug] avoid doble upscaling in inpaint
2024-02-19 18:06:05 +03:00
Andray
33c8fe1221 avoid doble upscaling in inpaint 2024-02-19 16:57:49 +04:00
AUTOMATIC1111
532c340829 update changelog 2024-02-19 10:07:57 +03:00
AUTOMATIC1111
92ab0ef7d6 Merge pull request #14871 from v0xie/boft
Support inference with LyCORIS BOFT networks
2024-02-19 10:05:44 +03:00
AUTOMATIC1111
6e4fc5e1a8
Merge pull request #14871 from v0xie/boft
Support inference with LyCORIS BOFT networks
2024-02-19 10:05:30 +03:00
Kohaku-Blueleaf
4eb949625c
prevent undefined variable 2024-02-19 14:43:07 +08:00
HSIEH TSUNGYU
9d5dc582be Error handling for unsupported transparency
When input images (palette mode) have transparency (bytes) in info,
the output images (RGB mode) will inherit it,
causing ValueError in Pillow:PIL/PngImagePlugin.py#1364
when trying to unpack this bytes.

This commit check the PNG mode and transparency info,
removing transparency if it's RGB mode and transparency is bytes
2024-02-18 19:27:33 +08:00
Kohaku-Blueleaf
5a8dd0c549
Fix rescale 2024-02-18 14:58:41 +08:00
AUTOMATIC1111
c7808825b1 update changelog 2024-02-17 21:38:19 +03:00
AUTOMATIC1111
cb52279c3e Merge pull request #14947 from AUTOMATIC1111/open-button
option "open image button" open the actual dir
2024-02-17 21:31:22 +03:00
AUTOMATIC1111
9d5becb4de
Merge pull request #14947 from AUTOMATIC1111/open-button
option "open image button" open the actual dir
2024-02-17 21:30:21 +03:00
w-e-w
71072f5620 re-work open image button settings 2024-02-18 02:47:44 +09:00
w-e-w
a18e54ecd7 option "open image button" open the actual dir 2024-02-18 00:38:05 +09:00
AUTOMATIC1111
3345218439 Update comment for Pad prompt/negative prompt v0 to add a warning about truncation, make it override the v1 implementation 2024-02-17 13:21:37 +03:00
AUTOMATIC1111
4ff1fabc86 Update comment for Pad prompt/negative prompt v0 to add a warning about truncation, make it override the v1 implementation 2024-02-17 13:21:08 +03:00
AUTOMATIC1111
4652fc5ac3 prevent escape button causing an interrupt when no generation has been made yet 2024-02-17 11:41:30 +03:00
AUTOMATIC1111
4573195894 prevent escape button causing an interrupt when no generation has been made yet 2024-02-17 11:40:53 +03:00
AUTOMATIC1111
310d6b9075 update changelog 2024-02-17 11:35:36 +03:00
AUTOMATIC1111
db19c46d6d lint 2024-02-17 10:32:10 +03:00
AUTOMATIC1111
1466daeafc Disable prompt token counters option actually disables token counting rather than just hiding results.
Disable prompt token counters option does not require reload UI.
token counters do not become visible until they are positioned correctly.
2024-02-17 10:31:16 +03:00
AUTOMATIC1111
dd1641ecc4 fix an exception when filtering extra networks very early 2024-02-17 09:46:04 +03:00
AUTOMATIC1111
7dae6bb3b5 fix search UI invisible in an extra network tab that just loaded 2024-02-17 09:45:48 +03:00
AUTOMATIC1111
2e1b61e590 change condition for scheduleAfterScriptsCallbacks() to properly reflect the needed amount of search fields 2024-02-17 09:45:03 +03:00
AUTOMATIC1111
f293dbbf97
Merge pull request #14900 from AUTOMATIC1111/fix-css-color-extra-network-control--enabled
fix extra-network-control--enabled color
2024-02-17 09:00:06 +03:00
AUTOMATIC1111
bf08a5b75e
Merge pull request #14910 from analysisjp/wsl2_flx
fixed webui.sh issue that occurred in WSL environment (fix: #14883)
2024-02-17 08:59:41 +03:00
AUTOMATIC1111
48ce0379bc
Merge pull request #14916 from light-and-ray/use_original_document_title
Use original App Title in progress bar
2024-02-17 08:57:56 +03:00
AUTOMATIC1111
d235aa068d
Merge pull request #14932 from AUTOMATIC1111/fix/esc-interrupt
Only trigger interrupt on `Esc` when interrupt button visible
2024-02-17 08:57:25 +03:00
AUTOMATIC1111
ce57a6c6db
Merge pull request #14933 from AUTOMATIC1111/fix/graceful-mtime-hash-cache-exception
Gracefully handle mtime read exception from cache
2024-02-17 08:56:48 +03:00
AUTOMATIC1111
d70632a7cf
Merge pull request #14934 from AUTOMATIC1111/fix/normalize-cmd-arg-paths
Normalize command-line argument paths
2024-02-17 08:54:06 +03:00
AUTOMATIC1111
4333ecc43f
Merge pull request #14939 from AUTOMATIC1111/Fix-extranetworks-search-reload
Fix the bugs that search/reload will disappear when using other ExtraNetworks extensions
2024-02-17 08:51:11 +03:00
AUTOMATIC1111
a56125b0a8
Merge pull request #14930 from RedDeltas/feat/launch_utils/file_mode_for_clone
Added core.filemode=false so doesn't track changes in file permission…
2024-02-17 08:48:37 +03:00
Kohaku-Blueleaf
23f03d4796 Update extraNetworks.js 2024-02-16 16:43:43 +08:00
catboxanon
06ab10a1be Normalize cmd arg paths
In particular, this fixes an issue on Windows where some functions
will misbehave if forward slashes are provided rather than
double backslashes.
2024-02-15 14:22:13 -05:00
catboxanon
6ee4012c0a Gracefully handle mtime read exception from cache 2024-02-15 13:31:44 -05:00
catboxanon
46988af636 Fix Esc interrupt when button not visible 2024-02-15 13:05:39 -05:00
RedDeltas
18ec22bffe Added core.filemode=false so doesn't track changes in file permissions in more restrictive environments 2024-02-15 12:26:14 +00:00
Andray
1142201a3a Use original App Title in progress bar 2024-02-14 15:26:57 +04:00
analysisjp
69f9564a6d fixed webui.sh issue that occurred in WSL environment (fix: #14883) 2024-02-13 21:49:23 +09:00
Kohaku-Blueleaf
90441294db
Add rescale mechanism
LyCORIS will support save oft_blocks instead of oft_diag in the near future (for both OFT and BOFT)

But this means we need to store the rescale if user enable it.
2024-02-12 14:25:09 +08:00
w-e-w
13fd466c18 fix extra-network-control--enabled color
also add forgotten semicolon
2024-02-12 04:07:14 +09:00
AUTOMATIC1111
b7f45e67dc add before_token_counter callback and use it for prompt comments 2024-02-11 12:56:53 +03:00
AUTOMATIC1111
02ab75b86a Count tokens of enabled styles 2024-02-11 12:40:27 +03:00
AUTOMATIC1111
f6e476d7a8 call the right function for token counter in img2img 2024-02-11 12:24:02 +03:00
AUTOMATIC1111
b531b0bbef add propmpt comments support 2024-02-11 12:23:21 +03:00
AUTOMATIC1111
e2b19900ec add infotext entry for emphasis; put emphasis into a separate file, add an option to parse but still ignore emphasis 2024-02-11 09:39:51 +03:00
AUTOMATIC1111
3732cf2f97
Merge pull request #14874 from hako-mikan/master
Add option to disable normalize embeddings after after calculating emphasis.
2024-02-11 08:34:40 +03:00
AUTOMATIC1111
2f1e2c492f
Merge pull request #14873 from AUTOMATIC1111/check_extensions_list_on_apply_js_method
if extensions page not loaded, prevent apply
2024-02-11 08:29:54 +03:00
AUTOMATIC1111
860534399b
Merge pull request #14879 from AUTOMATIC1111/walk_files-extensions-case-insensitive
util.walk_files extensions case insensitive
2024-02-11 08:29:05 +03:00
AUTOMATIC1111
4d46f8c25c
Merge pull request #14883 from analysisjp/dev_fix_memleak_new
fix prepare_tcmalloc (fix: #14227)(Fixed memory leak issue in Ubuntu 22.04 or modern linux environment)
2024-02-11 08:28:42 +03:00
AUTOMATIC1111
5ddd5d29e5
Merge pull request #14884 from light-and-ray/ResizeHandleRow_png_info_and_train
ResizeHandleRow png_info and train
2024-02-11 08:26:20 +03:00
AUTOMATIC1111
440fff64a2
Merge pull request #14890 from AUTOMATIC1111/always-append-timestamp
Always add timestamp to displayed image
2024-02-11 08:26:00 +03:00
AUTOMATIC1111
d2246df160
Merge pull request #14885 from AUTOMATIC1111/extensions-tab-table-row-hover-highlight
extensions tab table row hover highlight
2024-02-11 08:24:41 +03:00
missionfloyd
c04c4b95de Always add timestamp to displayed image 2024-02-10 14:49:08 -07:00
w-e-w
7583351760 extensions tab table row hover highlight 2024-02-10 18:09:10 +09:00
Andray
82e2e25325 ResizeHandleRow png_info and train 2024-02-10 13:00:16 +04:00
analysisjp
2ba0277b52 fix: prepare_tcmalloc (Fixed memory leak issue in Ubuntu 22.04 or modern linux environment) 2024-02-10 10:09:19 +09:00
w-e-w
542611cce4 walk_files extensions case insensitive 2024-02-10 05:39:01 +09:00
hako-mikan
c3c88ca8b4
Update sd_hijack_clip.py 2024-02-10 00:18:08 +09:00
hako-mikan
6b3f7039b6
add option 2024-02-09 23:57:46 +09:00
w-e-w
6b8458eb9f if extensions page not loaded, prevent apply
since they are built-in extensions we can make the assumption that they will be at least one or more extensions

Co-Authored-By: Andray <33491867+light-and-ray@users.noreply.github.com>
2024-02-09 23:19:39 +09:00
hako-mikan
0bc7867ccd
Merge branch 'AUTOMATIC1111:master' into master 2024-02-09 23:17:40 +09:00
AUTOMATIC1111
d69a7944c9
Merge pull request #14857 from light-and-ray/refresh_extensions_list
Button for refresh extensions list
2024-02-09 16:06:02 +03:00
v0xie
eb6f2df826 Revert "fix: add butterfly_factor fn"
This reverts commit 81c16c965e532c6d86a969284c320ff8fcb0451d.
2024-02-08 22:00:15 -08:00
v0xie
613b0d9548 doc: add boft comment 2024-02-08 21:58:59 -08:00
v0xie
325eaeb584 fix: get boft params from weight shape 2024-02-08 11:55:05 -08:00
v0xie
2f1073dc6e style: fix lint 2024-02-07 04:55:11 -08:00
v0xie
81c16c965e fix: add butterfly_factor fn 2024-02-07 04:54:14 -08:00
v0xie
a4668a16b6 fix: calculate butterfly factor 2024-02-07 04:51:22 -08:00
v0xie
9588721197 feat: support LyCORIS BOFT 2024-02-07 04:49:17 -08:00
Andray
99c6c4a51b add button for refreshing extensions list 2024-02-07 16:06:17 +04:00
AUTOMATIC1111
321b2db067 fix extra networks metadata failing to work properly when you create the .json file with metadata for the first time. 2024-02-02 22:47:51 +03:00
AUTOMATIC1111
1ff1c5be64 fix refresh button forgetting sort order for extra networks #14588 2024-02-02 20:51:54 +03:00
AUTOMATIC1111
5084b39ea5 fix checkpoint selection not working for #14588 2024-02-02 19:41:07 +03:00
AUTOMATIC1111
5904e3f6b3 fix page refresh not re-applying sort/filter for #14588
fix path sortkey not including the filename for #14588
2024-02-02 19:30:59 +03:00
Alex He
db4632f4ba Update to ROCm5.7 and PyTorch
The webui.sh installs ROCm5.4.2 as default. The webui run failed with AMD
Radeon Pro W7900 with **Segmentation Fault** at Ubuntu22.04 maybe the ABI
compatibility issue.

ROCm5.7 is the latest version supported by PyTorch (https://pytorch.org/)
at now. I test it with AMD Radeon Pro W7900 by PyTorch+ROCm5.7 with PASS.

Signed-off-by: Alex He <heye_dev@163.com>
2024-02-02 13:48:42 +08:00
AUTOMATIC1111
2600370659 fix error when editing extra networks card 2024-02-01 23:54:57 +03:00
AUTOMATIC1111
9f3ba38314 Add "Interrupting..." placeholder. 2024-02-01 22:34:29 +03:00
AUTOMATIC1111
b594f518b7
Merge pull request #14814 from AUTOMATIC1111/catch-load-style.csv-error
catch load style.csv error
2024-02-01 22:02:28 +03:00
w-e-w
bbe8e02d74 catch load style.csv error 2024-02-01 15:40:15 +09:00
AUTOMATIC1111
652a7bbf80
Merge pull request #14809 from Cyberbeing/fix_upscaler_autocast_nans
Fix potential autocast NaNs in image upscale
2024-01-31 22:41:22 +03:00
AUTOMATIC1111
1b0931fd92
Merge pull request #14803 from AUTOMATIC1111/create_submit_box-tooltip
add tooltip create_submit_box
2024-01-31 22:39:50 +03:00
AUTOMATIC1111
96b550430a
Merge pull request #14801 from wangshuai09/npu_support
Add NPU Support
2024-01-31 22:39:29 +03:00
Cyberbeing
74b214a92a Fix potential autocast NaNs in image upscale 2024-01-30 22:32:31 -08:00
wangshuai09
cc3f604310 Update 2024-01-31 12:29:58 +08:00
w-e-w
c4255d12f7 add tooltip create_submit_box 2024-01-31 04:36:11 +09:00
wangshuai09
74ff85a1a1
Merge branch 'dev' into npu_support 2024-01-30 19:15:41 +08:00
AUTOMATIC1111
ce168ab5db
Merge pull request #14791 from AUTOMATIC1111/fix-mha-manual-cast
Fix dtype error in MHA layer/change dtype checking mechanism for manual cast
2024-01-29 20:39:06 +03:00
Kohaku-Blueleaf
f9ba7e648a Revert "Try to reverse the dtype checking mechanism"
This reverts commit d243e24f539d717b221992e894a5db5a321bf3cd.
2024-01-29 22:54:12 +08:00
Kohaku-Blueleaf
d243e24f53 Try to reverse the dtype checking mechanism 2024-01-29 22:49:45 +08:00
Kohaku-Blueleaf
6e7f0860f7 linting 2024-01-29 22:46:43 +08:00
Kohaku-Blueleaf
750dd6014a Fix potential bugs 2024-01-29 22:27:53 +08:00
AUTOMATIC1111
6484053037
Merge pull request #14782 from AUTOMATIC1111/safetensors-0.4.2
Bump safetensors' version to 0.4.2
2024-01-29 16:35:07 +03:00
wangshuai09
ec124607f4 Add NPU Support 2024-01-29 19:25:06 +08:00
AUTOMATIC1111
baaf39b6f9 fix the typo -- thanks Cyberbeing 2024-01-29 10:20:27 +03:00
Kohaku-Blueleaf
2cb1b65309 Bump safetensors' version to 0.4.2 2024-01-28 22:18:46 +08:00
AUTOMATIC1111
757dda9ade Add Pad conds v0 option 2024-01-27 22:30:47 +03:00
AUTOMATIC1111
e717eaff86
Merge pull request #14773 from AUTOMATIC1111/rework-set_named_arg
rework set_named_arg
2024-01-27 20:54:47 +03:00
w-e-w
eae0bb89fd set_named_arg fuzzy option 2024-01-27 21:55:52 +09:00
AUTOMATIC1111
0a3a83382f
Merge pull request #14775 from AUTOMATIC1111/fix-CLIP-Interrogator-topN-regex
fix CLIP Interrogator topN regex
2024-01-27 14:36:27 +03:00
w-e-w
486aeda3a7 fix CLIP Interrogator topN regex
Co-Authored-By: Martin Rizzo <60830236+martin-rizzo@users.noreply.github.com>
2024-01-27 19:35:07 +09:00
AUTOMATIC1111
7ea0859362
Merge pull request #14728 from AUTOMATIC1111/another-Hr-button-fix-
Another hr button fix
2024-01-27 10:06:40 +03:00
w-e-w
2996e43ff7 fix txt2img_upscale
use force_enable_hr to set p.enable_hr = True
allow Script.setup() have access to the correct value

add a comment for p.txt2img_upscale
2024-01-27 14:55:47 +09:00
w-e-w
36d1fefc19 rework set_named_arg
change identifying a script from using Scripts class name to Scripts internal name an
as not all Script have unique names

raise RuntimeError when there's issue
2024-01-27 14:42:52 +09:00
AUTOMATIC1111
4d5db58a3e
Merge pull request #14767 from AUTOMATIC1111/minor-fix-to-#14525
minor fix to #14525
2024-01-26 19:04:13 +03:00
w-e-w
47cf92039b minor fix to #14525 2024-01-26 17:16:53 +09:00
AUTOMATIC1111
c6c9d12275
Merge pull request #14754 from AUTOMATIC1111/xyz-filter-blank-for-number-axes
XYZ filter blank for number axes
2024-01-26 00:41:24 +03:00
w-e-w
0466ee2a83 xyz filter blank for number axes 2024-01-25 05:45:45 +09:00
AUTOMATIC1111
19c95de8eb
Merge pull request #14715 from stefanbenten/sb/embedding-refresh
modules/api/api.py: add api endpoint to refresh embeddings list
2024-01-23 22:35:41 +03:00
AUTOMATIC1111
358e9e2847
Merge pull request #14726 from v0xie/fix-oft-device
Fix kohya-ss OFT network wrong device for eye and constraint
2024-01-23 22:34:24 +03:00
AUTOMATIC1111
c17f7ee694
Merge pull request #14707 from AUTOMATIC1111/multi-styles-base-styles-file
re-work multi --styles-file
2024-01-23 22:22:37 +03:00
AUTOMATIC1111
de5a8c5cb4 add an option to not overlay original image for inpainting for #14727 2024-01-23 22:19:38 +03:00
AUTOMATIC1111
bac30eb3e7
Merge pull request #14740 from light-and-ray/make_extras_tab_collumns_resizable
Make extras tab columns resizable
2024-01-23 22:00:56 +03:00
Andray
695e24dbce make extras tab collumns resizable 2024-01-23 21:56:49 +04:00
AUTOMATIC1111
94d4b3c8e7 lint 2024-01-23 00:36:31 +03:00
AUTOMATIC1111
f4e931f18f put extra networks controls row into the tabs UI element for #14588 2024-01-22 23:20:30 +03:00
AUTOMATIC1111
569dc1919c
Merge pull request #14588 from Sj-Si/feature/extra-networks-tree-view
Feature: Extra Networks Tree View
2024-01-22 22:24:06 +03:00
v0xie
fd383140cf fix: wrong devices for eye and constraint 2024-01-22 02:52:34 -08:00
Sj-Si
26e1cd7ec4 Remove unnecessary template and simplify tree list. 2024-01-21 11:34:08 -05:00
Sj-Si
d7d3166a27 Fix broken scrollbars 2024-01-21 11:27:24 -05:00
Stefan Benten
2974b9cee9
modules/api/api.py: add api endpoint to refresh embeddings list 2024-01-21 14:05:47 +01:00
AUTOMATIC1111
8a6a4ad894
Merge pull request #14709 from AUTOMATIC1111/improve-get_crop_region
improve get_crop_region
2024-01-21 16:01:44 +03:00
w-e-w
e36827af32 improve get_crop_region 2024-01-21 09:02:18 +09:00
AUTOMATIC1111
3a5196de1b
Merge pull request #14663 from aalbacetef/feature/add-model-to-log-file
feature/add-model-to-log-file
2024-01-21 02:05:18 +03:00
Arturo Albacete
4aa99f77ab add docstring 2024-01-20 22:04:53 +01:00
Arturo Albacete
f190b85182 restore saving fields 2024-01-20 21:27:38 +01:00
Arturo Albacete
8459015017 skip if headers haven't changed 2024-01-20 21:19:53 +01:00
Arturo Albacete
d0b65e148b merge dev 2024-01-20 21:15:57 +01:00
w-e-w
25e8273d2f re-work multi --styles-file
--styles-file change to append str
--styles-file is [] then defaults to [styles.csv]

--styles-file accepts paths or paths with wildcard "*"

the first `--styles-file` entry is use as the default styles file path
if filename a wildcard then the first matching file is used
if no match is found, create a new "styles.csv" in the same dir as the first path

when saving a new style it will be save in the default styles file
when saving a existing style, it will be saved to file it belongs to

order of the styles files in the styles dropdown can be controlled to a certain degree by the order of --styles-file
2024-01-21 03:53:58 +09:00
Sj-Si
b67a49441f Add option in settings to enable/disable tree view by default. 2024-01-20 13:28:37 -05:00
Sj-Si
2310cd66e5 Add toggle button for tree view. Use default settings for sortmode and direction. 2024-01-20 11:43:45 -05:00
AUTOMATIC1111
f939bce845
Merge pull request #14702 from light-and-ray/keep_postprocessing_upscale_selected_tab_after_restart
[Bug] Keep postprocessing upscale selected tab after restart
2024-01-20 14:56:53 +03:00
Andray
ed383eb5a0 keep postprocessing upscale selected tab after restart 2024-01-20 15:37:49 +04:00
AUTOMATIC1111
c1713bfeac
Merge pull request #14689 from AUTOMATIC1111/fix-nested-manual-cast
Fix nested manual cast
2024-01-20 11:43:51 +03:00
Kohaku-Blueleaf
4a66d2fb22 Avoid exceptions to be silenced 2024-01-20 16:33:59 +08:00
Kohaku-Blueleaf
81126027f5 Avoid early disable 2024-01-20 16:31:12 +08:00
AUTOMATIC1111
1dbee391b4
Merge pull request #14637 from light-and-ray/fix_tab_indexes_resets_after_restart_ui
[Bug] Fix tab indexes are reseted after restart UI
2024-01-20 11:00:29 +03:00
Andray
56676ff923 fix tab indexes reset after restart ui 2024-01-20 11:49:05 +04:00
AUTOMATIC1111
a06ae54a18
Merge pull request #14639 from light-and-ray/fix_extension_check_for_requirements
[Bug] Fix extension check for requirements
2024-01-20 10:30:28 +03:00
AUTOMATIC1111
58a142b56b
Merge pull request #14640 from WebDev9000/replace-hashtags-in-filenames
Add # to the invalid_filename_chars list
2024-01-20 10:29:42 +03:00
AUTOMATIC1111
0f2de4cfbe
Merge pull request #14655 from chi2nagisa/lora-alias-fix
[bug] fix using wrong model caused by alias
2024-01-20 10:27:54 +03:00
AUTOMATIC1111
cfa326bbcc
Merge pull request #14659 from AUTOMATIC1111/immediately-stop-on-second-interrupt
immediately stop on second interrupt
2024-01-20 10:26:52 +03:00
AUTOMATIC1111
7581da5d92
Merge pull request #14645 from AUTOMATIC1111/infotexts
geninfo from Infotexts
2024-01-20 10:26:03 +03:00
AUTOMATIC1111
41c2121e51
Merge pull request #14657 from AUTOMATIC1111/callback-postprocess_image_after_composite
callback postprocess_image_after_composite
2024-01-20 10:25:29 +03:00
AUTOMATIC1111
5df56b3980
Merge pull request #14626 from AUTOMATIC1111/hr-button-fix
more Hr button fix
2024-01-20 10:24:59 +03:00
AUTOMATIC1111
9cdd161160
Merge pull request #14690 from n0kovo/dev
Add support for DAT upscaler models
2024-01-20 10:15:59 +03:00
AUTOMATIC1111
7c30c5eec4
Merge pull request #14699 from light-and-ray/fix_extras_big_batch_crashes
[Bug] Fix extras big batch crashes
2024-01-20 10:12:16 +03:00
AUTOMATIC1111
5cbda43d63
Merge pull request #14638 from WebDev9000/brush-size-adjust
Adjust brush size with hotkeys
2024-01-20 09:42:10 +03:00
WebDev
30f31d23c6
Update hotkey_config.py 2024-01-19 16:39:33 -08:00
WebDev
bcdcc8be7d
Update hotkey_config.py 2024-01-19 16:39:07 -08:00
WebDev
4dde96109b
Update zoom.js 2024-01-19 16:38:34 -08:00
Andray
d31dc7a739 fix extras big batch crashes 2024-01-20 00:40:03 +04:00
n0kovo
1ddb886a80 Fix wrong options value 2024-01-19 00:48:46 +01:00
n0kovo
2e7efe47b6 Minor cleanup 2024-01-19 00:39:14 +01:00
n0kovo
a97147bc8a Add support for DAT upscaler models 2024-01-19 00:10:02 +01:00
Sj-Si
69f4f148dc Fix various bugs including refresh bug. 2024-01-18 12:13:33 -05:00
Sj-Si
50e444fa1d Fix missing important style. 2024-01-18 12:13:09 -05:00
Kohaku-Blueleaf
0181c1f76b Fix nested manual cast 2024-01-19 00:14:03 +08:00
Sj-Si
f25c81a744 Fix embeddings add/remove to/from prompt on click bugs. 2024-01-17 22:38:51 -05:00
w-e-w
2cf23099eb fix console total progress bar when using txt2img_upscale
add p.txt2img_upscale as indicator
2024-01-18 04:44:21 +09:00
w-e-w
e1dfd452c0 parse_generation_parameters with no skip_fields 2024-01-18 02:39:42 +09:00
w-e-w
6916de5c0b parse_generation_parameters skip_fields 2024-01-18 02:39:15 +09:00
w-e-w
45a51c07e2 parse_generation_parameters with no skip_fields 2024-01-18 02:36:19 +09:00
w-e-w
d224fed0ce parse_generation_parameters skip_fields 2024-01-18 02:36:19 +09:00
w-e-w
6acd8e28fc save_files info base on infotexts 2024-01-18 02:33:43 +09:00
w-e-w
0b83f4c263 reuse seed from infotexts 2024-01-18 02:33:43 +09:00
Sj-Si
ccee26b065 fix bugs 2024-01-16 14:54:07 -05:00
Sj-Si
4f96267033 Finish cleanup. 2024-01-16 13:35:01 -05:00
Arturo Albacete
315e40a49c reuse variable for log file path 2024-01-16 19:11:28 +01:00
Arturo Albacete
a75dfe1c0d - expand fields to include model name and hash
- write these in the CSV log file
- ensure old log files are updated w.r.t delimiter count
2024-01-16 19:03:48 +01:00
w-e-w
14b9762bca immediately stop on second interrupt
Revert "immediately stop on second interrupt"

This reverts commit ab409072a1f2a9c911a63aee98a6b42081803cdc.

immediately stop on second interrupt
2024-01-16 17:18:05 +09:00
w-e-w
c1e04c63b3 callback postprocess_image_after_composite 2024-01-16 14:18:20 +09:00
Sj-Si
1fdc18e6a0 Run linting 2024-01-15 18:01:13 -05:00
Sj-Si
f49c220c03 Move extra network tab buttons into tree view; 2024-01-15 17:34:44 -05:00
chi2nagisa
e280eb4055 fix using wrong model caused by alias 2024-01-16 03:45:19 +08:00
Sj-Si
d88424ef2a fix bugs. introduce new ones. 2024-01-15 13:40:47 -05:00
Sj-Si
019f6e3c5a fix linting 2024-01-14 13:49:39 -05:00
Sj-Si
261972f929 fix search box handling. sort maybe broken not sure. need to bug test and finish cleanup. 2024-01-14 13:39:01 -05:00
WebDev
39db1d09d1
Update zoom.js 2024-01-14 01:43:23 -08:00
WebDev
92032f2da8
Update hotkey_config.py 2024-01-14 01:42:03 -08:00
w-e-w
208ccfbe7c seed info from infotexts 2024-01-14 17:57:49 +09:00
w-e-w
ee9d487081 fix gallery black image issue 2024-01-14 17:57:42 +09:00
w-e-w
cfb90a938e allowe hr pass to return multiple images 2024-01-14 17:57:26 +09:00
w-e-w
92501d4f80 disable saving images before highres fix 2024-01-14 17:56:34 +09:00
Sj-Si
02e6963325 continue cleanup and redesign. 2024-01-13 13:16:39 -05:00
Andray
b6dc307c99 fix_extension_check_for_requirements 2024-01-13 14:45:15 +04:00
WebDev
47b52d9b28
Add # to the invalid_filename_chars list 2024-01-13 02:31:26 -08:00
WebDev
541881e318
Adjust brush size with hotkeys. 2024-01-13 02:11:06 -08:00
Sj-Si
036500223d Merge changes from dev 2024-01-11 16:37:35 -05:00
Sj-Si
0726a6e12e Finish base layout. Fix bugs. Need to test for stability and clean up. 2024-01-11 15:06:57 -05:00
AUTOMATIC1111
cb5b335acd
Merge pull request #14618 from akx/log-fmt-fix
Logging: set formatter correctly for fallback logger too
2024-01-11 13:49:36 +03:00
Aarni Koskela
0011640ab1 Logging: set formatter correctly for fallback logger too 2024-01-11 08:29:42 +02:00
Sj-Si
3db6938caa begin redesign of tree module. 2024-01-10 18:11:48 -05:00
AUTOMATIC1111
85bf2eb441
Merge pull request #14598 from AUTOMATIC1111/fix-txt2img_upscale
hires button, fix seeds
2024-01-09 20:05:10 +03:00
w-e-w
4d9f2c3ec8 update p.seed and p.subseed 2024-01-10 01:56:44 +09:00
AUTOMATIC1111
abb630108e
Merge pull request #14589 from Sj-Si/hotfix/remove-upscaler-size-limits
Increase Upscaler Limits
2024-01-09 19:52:54 +03:00
Sj-Si
9dd2534824 Restore scale factor limit changes to master branch. 2024-01-09 11:47:39 -05:00
Sj-Si
3cc7572f5d Restore scale factor limit changes to master branch. 2024-01-09 11:46:10 -05:00
AUTOMATIC1111
751d014cd6
Merge pull request #14583 from continue-revolution/conrevo/lcm-sampler
Official LCM Sampler Support
2024-01-09 19:37:35 +03:00
AUTOMATIC1111
639f22ea7c
Merge pull request #14593 from papuSpartan/api_tls
Allow TLS with API only mode (--nowebui)
2024-01-09 19:33:31 +03:00
AUTOMATIC1111
905b14237f
Merge pull request #14597 from AUTOMATIC1111/improved-manual-cast
Improve the implementation of Manual Cast and IPEX support
2024-01-09 19:33:00 +03:00
Kohaku-Blueleaf
ca671e5d7b rearrange if-statements for cpu 2024-01-09 23:30:55 +08:00
Kohaku-Blueleaf
58d5b042cd Apply the correct behavior of precision='full' 2024-01-09 23:23:40 +08:00
Kohaku-Blueleaf
1fd69655fe Revert "Apply correct inference precision implementation"
This reverts commit e00365962b17550a42235d1fbe2ad2c7cc4b8961.
2024-01-09 23:15:05 +08:00
Kohaku-Blueleaf
e00365962b Apply correct inference precision implementation 2024-01-09 23:13:34 +08:00
Kohaku-Blueleaf
c2c05fcca8 linting and debugs 2024-01-09 22:53:58 +08:00
KohakuBlueleaf
42e6df723c Fix bugs when arg dtype doesn't match 2024-01-09 22:39:39 +08:00
Kohaku-Blueleaf
209c26a1cb improve efficiency and support more device 2024-01-09 22:11:44 +08:00
unknown
8d986727b3
include tls arguments in api uvicorn init 2024-01-09 03:01:20 -06:00
Sj-Si
46413b20a4 Increase limits for upscalers. 2024-01-08 16:23:35 -05:00
Sj-Si
34fc215249 fix linting 2024-01-08 14:23:01 -05:00
Sj-Si
67a70ad112 fix indentation 2024-01-08 14:11:24 -05:00
Sj-Si
df8aa69a99 Add tree-view display for extra networks. 2024-01-08 14:10:03 -05:00
continue-revolution
8e292373ec lcm sampler 2024-01-08 06:43:39 -06:00
AUTOMATIC1111
6869d95890
Merge pull request #14573 from continue-revolution/conrevo/add-p-to-cfg
Add self to CFGDenoiserParams
2024-01-08 10:23:08 +03:00
Chengsong Zhang
37906e429a
make denoiser None by default 2024-01-07 20:17:42 -06:00
continue-revolution
f56cebf5ba add self instead 2024-01-07 12:35:35 -06:00
continue-revolution
425507bd10 add p to cfgdenoiserparams 2024-01-07 10:25:01 -06:00
AUTOMATIC1111
2f98a35fc4 add assets repo; serve fonts locally rather than from google's servers 2024-01-07 09:21:21 +03:00
AUTOMATIC1111
30aa5e0a7c
Merge pull request #14560 from Nuullll/condfunc-warning
Handle CondFunc exception when resolving attributes
2024-01-07 08:23:08 +03:00
AUTOMATIC1111
cab1d839b5
Merge pull request #14563 from Nuullll/model-loaded-callback
Execute model_loaded_callback after moving to target device
2024-01-07 08:22:17 +03:00
AUTOMATIC1111
71e0057137
Merge pull request #14562 from Nuullll/fix-ipex-xpu-generator
[IPEX] Fix xpu generator
2024-01-07 08:21:43 +03:00
Nuullll
a183de04e3 Execute model_loaded_callback after moving to target device 2024-01-06 20:03:33 +08:00
Nuullll
818d6a11e7 Fix format 2024-01-06 19:14:06 +08:00
Nuullll
73786c047f [IPEX] Fix torch.Generator hijack 2024-01-06 19:09:56 +08:00
AUTOMATIC1111
b00b429477
Merge pull request #14559 from Nuullll/ipex-sdpa-fix
[IPEX] Fix SDPA attn_mask dtype
2024-01-06 13:14:18 +03:00
Nuullll
ec9acb3145 Handle CondFunc exception when resolving attributes 2024-01-06 17:18:38 +08:00
Nuullll
16b4d2cf3f [IPEX] Fix SDPA attn_mask dtype 2024-01-06 16:32:18 +08:00
AUTOMATIC1111
8b6848c6db
Merge pull request #14546 from AUTOMATIC1111/fix-oft-dtype
Fix dtype casting in OFT module
2024-01-06 10:50:38 +03:00
AUTOMATIC1111
a4ee64050a
Merge pull request #14547 from AUTOMATIC1111/lyco-forward
Implement general forward method for all method in built-in lora ext
2024-01-06 10:50:06 +03:00
AUTOMATIC1111
942617f828
Merge pull request #14548 from keshav-nischal/patch-2
Update README.md
2024-01-06 10:49:45 +03:00
AUTOMATIC1111
233c66b36e Make the upscale button update the gallery with the new image rather than replace it. 2024-01-05 12:28:41 +03:00
Keshav Nischal
88ba095fd0
Update README.md 2024-01-05 14:15:58 +05:30
Kohaku-Blueleaf
44744d6005 linting 2024-01-05 16:38:05 +08:00
Kohaku-Blueleaf
18ca987c92 Add general forward method for all modules. 2024-01-05 16:32:19 +08:00
Kohaku-Blueleaf
f8f38c7c28 Fix dtype casting for OFT module 2024-01-05 16:31:48 +08:00
AUTOMATIC1111
a06dab8d7a
Merge pull request #14538 from akx/log-wut
Fix logging configuration again
2024-01-05 11:04:14 +03:00
AUTOMATIC1111
6ffbff0857
Merge pull request #14537 from akx/gradio-analytics-enabled-again
Ensure GRADIO_ANALYTICS_ENABLED is set early enough
2024-01-05 11:02:50 +03:00
Aarni Koskela
6fa42e919f Fix logging configuration again
* Only use `tqdm.write()` if `tqdm` is active, defer to stderr
* Correct log formatter for TqdmLoggingHandler
* If `rich` is installed and `SD_WEBUI_RICH_LOG` is set, use `rich`'s formatter
2024-01-04 19:32:03 +02:00
Aarni Koskela
9805f35c6f Ensure GRADIO_ANALYTICS_ENABLED is set early enough 2024-01-04 19:13:47 +02:00
AUTOMATIC1111
15ec54dd96 Have upscale button use the same seed as hires fix. 2024-01-04 19:47:00 +03:00
AUTOMATIC1111
f903b4dda3
Merge pull request #14523 from AUTOMATIC1111/paste-infotext-cast-int-as-float
paste infotext cast int as float
2024-01-04 11:19:18 +03:00
AUTOMATIC1111
3f7f61e541
Merge pull request #14524 from akx/fix-swinir-issues
Fix SwinIR issues
2024-01-04 11:17:20 +03:00
AUTOMATIC1111
1e7a8ce5e4
Merge pull request #14525 from AUTOMATIC1111/handle-config.json-failed-to-load
handle config.json failed to load
2024-01-04 11:16:37 +03:00
AUTOMATIC1111
397251ba0c
Merge pull request #14527 from akx/avoid-isfiles
Avoid unnecessary `isfile`/`exists` calls
2024-01-04 11:15:56 +03:00
AUTOMATIC1111
df62ffbd25
Merge branch 'dev' into avoid-isfiles 2024-01-04 11:15:50 +03:00
AUTOMATIC1111
149c9d2234
Merge pull request #14528 from AUTOMATIC1111/mass-file-lister
mass file lister as an attempt to tackle #14507
2024-01-04 11:09:59 +03:00
AUTOMATIC1111
320a217b78 forgot something 2024-01-04 02:39:02 +03:00
AUTOMATIC1111
420f56c2e8 mass file lister as an attempt to tackle #14507 2024-01-04 02:28:05 +03:00
Aarni Koskela
d9034b48a5 Avoid unnecessary isfile/exists calls 2024-01-04 00:26:30 +02:00
w-e-w
50158a1fc9 handle config.json failed to load 2024-01-04 06:30:52 +09:00
Aarni Koskela
62470ee234 upscale_2: cast image to model's dtype 2024-01-03 22:39:12 +02:00
Aarni Koskela
3d31d5c27b SwinIR: pass model.scale 2024-01-03 22:38:49 +02:00
Aarni Koskela
dfdc51246c SwinIR: use prefer_half 2024-01-03 22:38:13 +02:00
w-e-w
bfc48fbc24 paste infotext cast int as float 2024-01-04 03:46:05 +09:00
AUTOMATIC1111
04a005f0e9
Merge pull request #14512 from AUTOMATIC1111/remove-excessive-extra-networks-reload
reduce unnecessary re-indexing extra networks directory
2024-01-03 19:15:46 +03:00
w-e-w
fccd0b00c2 reduce unnecessary re-indexing extra networks dir 2024-01-03 19:25:06 +09:00
AUTOMATIC1111
9c6ea5386b
Merge pull request #14504 from akx/you-spin-me-round
torch_bgr_to_pil_image: round, don't truncate
2024-01-03 12:42:05 +03:00
Aarni Koskela
7ad6899bf9 torch_bgr_to_pil_image: round, don't truncate
This matches what `realesrgan` does.
2024-01-02 17:14:05 +02:00
AUTOMATIC1111
e4dcdcc955
Merge pull request #14501 from akx/credits-remove-copypaste
Remove licenses and README mentions for code that's no longer copy-pasted
2024-01-02 16:25:26 +03:00
Aarni Koskela
62bd7624d2 Remove licenses for code that's no longer copy-pasted; adjust README 2024-01-02 11:46:42 +02:00
AUTOMATIC1111
7c3ab416ad
Merge pull request #14500 from akx/spandrel-prefer-half
Spandrel: "prefer half" instead of "force half"
2024-01-02 12:23:23 +03:00
Aarni Koskela
2cacbc124c load_spandrel_model: make half prefer_half
As discussed with the Spandrel folks, it's good to heed Spandrel's
"supports half precision" flag to avoid e.g. black blotches and what-not.
2024-01-02 10:44:38 +02:00
AUTOMATIC1111
51f1cca852
Merge pull request #14484 from akx/swinir-resample-for-div8
Refactor Torch-space upscale fully out of ScuNET/SwinIR
2024-01-02 10:56:37 +03:00
Aarni Koskela
cf14a6a7aa Refactor upscale_2 helper out of ScuNET/SwinIR; make sure devices are right 2024-01-02 08:57:12 +02:00
AUTOMATIC1111
980970d390 final touches 2024-01-02 07:08:32 +03:00
AUTOMATIC1111
80873b1538 fix #14497 2024-01-02 07:05:05 +03:00
AUTOMATIC1111
1341b22081 add an option to hide upscaling progressbar 2024-01-02 06:47:26 +03:00
AUTOMATIC1111
6f9fcfdbb7
Merge pull request #14497 from Jibaku789/dev
Add inpaint arguments in .txt file
2024-01-02 06:42:21 +03:00
Jibaku789
a5b6a5a3ad
Add inpaint options to img2img.py 2024-01-01 14:58:55 -06:00
Jibaku789
c2ea571005
Add inpaint options to paste fields 2024-01-01 14:57:41 -06:00
AUTOMATIC1111
ac3cc1adc5
Merge pull request #14495 from akx/fix-js-lint
Fix lint issue from 501993eb
2024-01-01 21:02:47 +03:00
Aarni Koskela
c32c51a0fc Fix lint issue from 501993eb 2024-01-01 19:20:54 +02:00
AUTOMATIC1111
501993ebf2 added a button to run hires fix on selected image in the gallery 2024-01-01 19:31:06 +03:00
AUTOMATIC1111
5d7d1823af rename infotext.py again, this time to infotext_utils.py; I didn't realize infotext would be used for variable names in multiple places, which makes it awkward to import the module; also fix the bug I caused by this rename that breaks tests 2024-01-01 17:25:30 +03:00
AUTOMATIC1111
1ffdedc11d restore lines lost from #13789 merge 2024-01-01 17:03:08 +03:00
AUTOMATIC1111
c507d7b252
Merge pull request #13789 from nickpharrison/finer-settings-freezing-control
Finer settings freezing control
2024-01-01 17:01:28 +03:00
AUTOMATIC1111
7ba02e0b7c
Merge branch 'dev' into finer-settings-freezing-control 2024-01-01 17:01:06 +03:00
AUTOMATIC1111
15156cde18
Merge pull request #14291 from AUTOMATIC1111/on-mouse-hover-show-hide-modal-image-viewer-icons
on mouse hover show / hide modal image viewer icons
2024-01-01 16:53:33 +03:00
AUTOMATIC1111
0aa7c53c0b fix borked merge, rename fields to better match what they do, change setting default to true for #13653 2024-01-01 16:50:59 +03:00
AUTOMATIC1111
2a7ad70db5
Merge pull request #13653 from antfu/feat/interrupted-end
Interrupt after current generation
2024-01-01 16:40:02 +03:00
AUTOMATIC1111
dfd6438221
Merge branch 'dev' into feat/interrupted-end 2024-01-01 16:39:51 +03:00
AUTOMATIC1111
0ce67cb618
Merge pull request #14352 from AUTOMATIC1111/reduce-unnecessary-ui-config-write
only rewrite ui-config when there is change
2024-01-01 16:35:07 +03:00
AUTOMATIC1111
cba6fba123
Merge pull request #14353 from Nuullll/ipex-sdpa
[IPEX] Slice SDPA into smaller chunks
2024-01-01 16:33:55 +03:00
AUTOMATIC1111
ac0ecf3b4b option to convert VAE to bfloat16 (implementation of #9295) 2024-01-01 16:28:58 +03:00
AUTOMATIC1111
0743ee9b3e re-layout checkboxes for XYZ grid a bit 2024-01-01 15:50:47 +03:00
AUTOMATIC1111
c352008c95 Merge remote-tracking branch 'rubberbaron/xyz-grid-vary-seeds' into dev 2024-01-01 15:50:10 +03:00
AUTOMATIC1111
d8126be578 linter 2024-01-01 15:00:39 +03:00
AUTOMATIC1111
45b7bba3d0 add automatic version support for zero terminal SNR noise schedule option from #14145 2024-01-01 14:51:56 +03:00
AUTOMATIC1111
267fd5d76b
Merge pull request #14145 from drhead/zero-terminal-snr
Implement zero terminal SNR noise schedule option
2024-01-01 14:45:12 +03:00
AUTOMATIC1111
d613cd17c7 add automatic backwards version compatibility 2024-01-01 14:38:29 +03:00
AUTOMATIC1111
d859cec696 infotext.py: rename usages in the codebase 2024-01-01 13:53:12 +03:00
AUTOMATIC1111
c5496c7646 infotext.py: add support for old modules.generation_parameters_copypaste name 2024-01-01 13:52:37 +03:00
AUTOMATIC1111
003b91f083 rename generation_parameters_copypaste module to infotext 2024-01-01 13:45:18 +03:00
AUTOMATIC1111
5692bf1517 add missing field for DDIM sampler that was breaking img2img 2024-01-01 11:11:14 +03:00
AUTOMATIC1111
e55fec9d9a
Merge pull request #14487 from AUTOMATIC1111/handle-selectable-script_index-is-None
handle selectable script_index is None
2024-01-01 10:19:58 +03:00
w-e-w
00901bfbe0 handle selectable script_index is None 2024-01-01 15:47:57 +09:00
AUTOMATIC1111
a70dfb64a8 change import statements for #14478 2023-12-31 22:38:30 +03:00
AUTOMATIC1111
be5f1acc8f
Merge pull request #14478 from akx/dtype-inspect
Add utility to inspect a model's dtype/device
2023-12-31 22:33:32 +03:00
AUTOMATIC1111
f3af8c8d04
Merge pull request #14475 from Learwin/negative_prompt
Adding negative prompts to Loras in extra networks
2023-12-31 22:32:28 +03:00
Learwin
b6f74e936e Revert change from linting for unrelated file 2023-12-31 13:36:36 +01:00
Learwin
d4945f4422 Removed weight slider for negative prompts 2023-12-31 13:22:30 +01:00
Aarni Koskela
5768afc776 Add utility to inspect a model's parameters (to get dtype/device) 2023-12-31 13:22:43 +02:00
AUTOMATIC1111
a84e842189
Merge pull request #14476 from akx/dedupe-tiled-weighted-inference
Deduplicate tiled inference code from SwinIR/ScuNET
2023-12-31 09:41:49 +03:00
Aarni Koskela
6f86b62a1b Deduplicate tiled inference code from SwinIR/ScuNET 2023-12-31 01:13:30 +02:00
AUTOMATIC1111
ce21840a04
Merge pull request #14477 from akx/spandrel-type-fix
Be more clear about Spandrel model nomenclature and types
2023-12-31 01:38:43 +03:00
AUTOMATIC1111
ae124439c4
Merge pull request #14471 from akx/bump-numpy
Bump numpy to 1.26.2
2023-12-31 01:37:56 +03:00
Aarni Koskela
777af661a2 Be more clear about Spandrel model nomenclature 2023-12-31 00:22:58 +02:00
Aarni Koskela
c0ca6348e8 load_spandrel_model: always return a model descriptor 2023-12-31 00:04:47 +02:00
AUTOMATIC1111
3be9074031 fix for the previous fix. 2023-12-31 00:43:41 +03:00
Learwin
a2f23f9d22 Code Style fixes 2023-12-30 22:16:51 +01:00
Learwin
bc5ae74c7d Added negative prompts to extra networks lora 2023-12-30 21:52:27 +01:00
AUTOMATIC1111
8100e901ab fix error with RealESRGAN model failing to upscale fp32 image 2023-12-30 22:41:53 +03:00
AUTOMATIC1111
c2fd7c0344
Merge pull request #14474 from akx/realesrgan-is-esrgan
Correct RealESRGAN expected architecture type to ESRGAN
2023-12-30 22:40:11 +03:00
AUTOMATIC1111
7c13ffdbb1
Merge pull request #14472 from akx/drop-move-code
Remove `cleanup_models` code
2023-12-30 22:15:30 +03:00
AUTOMATIC1111
a86f4411cb
Merge pull request #14473 from akx/soften-model-arch-check
Soften Spandrel model-architecture check to just a warning
2023-12-30 22:13:29 +03:00
Aarni Koskela
393a5b82ba Correct RealESRGAN expected architecture type to ESRGAN 2023-12-30 21:12:32 +02:00
Aarni Koskela
af050dcaa7 Soften Spandrel model-architecture check to just a warning 2023-12-30 21:05:59 +02:00
Aarni Koskela
5fbb13e0da Remove cleanup_models code 2023-12-30 20:47:12 +02:00
AUTOMATIC1111
16848f950b
Merge pull request #14467 from akx/drop-basicsr
Drop basicsr dependency
2023-12-30 21:27:33 +03:00
Aarni Koskela
48a2a1a437 Don't wait for 10 minutes for test server to come up 2023-12-30 19:44:38 +02:00
Aarni Koskela
1465dab715 Make Tensorboard a late import (it was implicitly installed by basicsr) 2023-12-30 19:44:05 +02:00
AUTOMATIC1111
79c9151802
Merge pull request #14421 from lanyeeee/api_thread_safe
fix API thread safe issues of txt2img and img2img
2023-12-30 20:21:13 +03:00
lanyeeee
f651405427 remove locks, move init code to __init__ 2023-12-31 01:09:13 +08:00
Aarni Koskela
b58ed1b243 Bump numpy to 1.26.2
This avoids it being downgraded during `launch.py`
2023-12-30 18:02:01 +02:00
Aarni Koskela
c9174253fb Drop dependency on basicsr 2023-12-30 17:53:19 +02:00
lanyeeee
91560e98c4 fix format issue 2023-12-30 23:42:10 +08:00
Aarni Koskela
f476649c02 Correct arg type for restore_face 2023-12-30 17:41:29 +02:00
AUTOMATIC1111
cd12c0e15c
Merge pull request #14425 from akx/spandrel
Use Spandrel for upscaling and face restoration architectures
2023-12-30 18:06:31 +03:00
AUTOMATIC1111
05230c0260 fix img2img api that i broke when implementing infotext support 2023-12-30 18:02:51 +03:00
Aarni Koskela
4ad0c0c0a8 Verify architecture for loaded Spandrel models 2023-12-30 16:37:03 +02:00
Aarni Koskela
c756133541 Add experimental HAT model 2023-12-30 16:30:49 +02:00
Aarni Koskela
b621a63cf6 Unify CodeFormer and GFPGAN restoration backends, use Spandrel for GFPGAN 2023-12-30 16:30:49 +02:00
Aarni Koskela
b0f5934234 Use Spandrel for upscaling and face restoration architectures (aside from GFPGAN and LDSR) 2023-12-30 16:24:01 +02:00
Aarni Koskela
e472383acb Refactor esrgan_upscale to more generic upscale_with_model 2023-12-30 16:24:01 +02:00
Aarni Koskela
12c6f37f8e Add tile_count property to Grid 2023-12-30 16:24:01 +02:00
Aarni Koskela
7aa27b000a Add types to split_grid 2023-12-30 16:24:01 +02:00
AUTOMATIC1111
31992eff9b make it possible again to extract styles that have whitespace at the end. 2023-12-30 16:51:13 +03:00
kurisu_u
d05f9e8124
Merge branch 'dev' into api_thread_safe 2023-12-30 21:47:59 +08:00
lanyeeee
c069c2c562 add locks to ensure init args are thread-safe 2023-12-30 21:32:22 +08:00
AUTOMATIC1111
adcd65ba34
Merge pull request #14367 from AUTOMATIC1111/reorder-post-processing-modules
reorder training preprocessing modules in extras tab
2023-12-30 15:23:52 +03:00
AUTOMATIC1111
f0e2e8b930 update #14354 2023-12-30 15:12:48 +03:00
AUTOMATIC1111
83c0758d90
Merge pull request #14354 from ranareehanaslam/master
Update Added (Fixed) IPV6 Functionality When there is No Webui Argument Passed webui.py
2023-12-30 15:11:49 +03:00
AUTOMATIC1111
1d603eb5a8
Merge pull request #14394 from AUTOMATIC1111/minor-xyz-fix
xyz grid handle axis_type is None
2023-12-30 15:06:39 +03:00
AUTOMATIC1111
4b6eb8072b
Merge pull request #14407 from AUTOMATIC1111/prevent-crash-due-to-Script-__init__-exception
prevent crash due to Script __init__ exception
2023-12-30 14:54:31 +03:00
AUTOMATIC1111
908fb4ea71
Merge pull request #14390 from wangqyqq/sdxl-inpaint
Supporting for SDXL-Inpaint Model
2023-12-30 14:49:52 +03:00
AUTOMATIC1111
c9c105c7db
Merge pull request #14446 from AUTOMATIC1111/base-output-path-off-data_path
Base output path off data path
2023-12-30 14:45:28 +03:00
AUTOMATIC1111
a79890efd6
Merge pull request #14452 from AUTOMATIC1111/save-info-of-init-image
save info of init image
2023-12-30 14:41:39 +03:00
AUTOMATIC1111
32862e4379
Merge pull request #14464 from AUTOMATIC1111/more-lora-not-found-warning
More lora not found warning
2023-12-30 14:04:17 +03:00
AUTOMATIC1111
8f18263759 fix bad values read from infotext for API, add comment 2023-12-30 13:48:25 +03:00
AUTOMATIC1111
11a435b469 img2img support for infotext API 2023-12-30 13:34:46 +03:00
AUTOMATIC1111
0aacd4c72b add support for alwayson scripts for infotext API 2023-12-30 13:33:18 +03:00
AUTOMATIC1111
8b08b78c03 make it so that if an option from infotext conflicts with an argument from API, the latter overrides the former 2023-12-30 12:27:23 +03:00
AUTOMATIC1111
ba92135a2b add override_settings support for infotext API 2023-12-30 12:11:09 +03:00
w-e-w
59d060fd5e More lora not found warning 2023-12-30 17:11:03 +09:00
AUTOMATIC1111
bb07cb6a0d a 2023-12-30 10:42:42 +03:00
w-e-w
dc57ec0296 save info of init image 2023-12-29 01:56:48 +09:00
w-e-w
892e703b59 webpath use truncate_path 2023-12-28 06:52:41 +09:00
w-e-w
af2951ed53 base default image output on data_path
Co-Authored-By: Alberto Cano <34340962+canoalberto@users.noreply.github.com>
2023-12-28 06:52:33 +09:00
w-e-w
de04573438 create utility truncate_path
utli.truncate_path(target_path, base_path)
return the target_path relative to base_path if target_path is a sub path of base_path else return the absolute path
2023-12-28 06:22:51 +09:00
wangqyqq
bfe418a58d add some codes for robust 2023-12-27 10:20:56 +08:00
lanyeeee
00d4a4d4ac move thread-unsafe code to __init__ 2023-12-26 14:46:29 +08:00
w-e-w
edfae95d90 prevent crash due to Script __init__ exception 2023-12-23 01:21:00 +09:00
w-e-w
de1809bd14 handle axis_type is None 2023-12-22 00:37:30 +09:00
wangqyqq
9feb034e34 support for sdxl-inpaint model 2023-12-21 20:15:51 +08:00
w-e-w
3e068de0dc reorder training preprocessing modules in extras tab
using the order from before the rework
11d23e8ca55c097ecfa255a05b63f194e25f08be
2023-12-19 18:48:49 +09:00
Muhammad Rehan Aslam
0d5941edbc
Update webui.py
Co-authored-by: Aarni Koskela <akx@iki.fi>
2023-12-19 09:50:38 +05:00
Muhammad Rehan Aslam
fe4d084390
Update webui.py
Added (Fixed) IPV6 Functionality When there is No Webui Argument Passed
2023-12-18 17:50:00 +05:00
Nuullll
f586f4973a Fix device id 2023-12-18 19:44:52 +08:00
Nuullll
e4b4a9c4ac [IPEX] Slice SDPA into smaller chunks 2023-12-18 18:01:09 +08:00
w-e-w
10945aa41a only rewrite ui-config when there is change
and a typo
2023-12-18 15:27:41 +09:00
AUTOMATIC1111
de03882d6c make task ids for API work without force_task_id 2023-12-17 08:55:35 +03:00
AUTOMATIC1111
3d9a0d9e4b
Merge pull request #14330 from AUTOMATIC1111/fix-extras-caption-BLIP
fix extras caption BLIP
2023-12-16 16:41:40 +03:00
w-e-w
98c5fa9201 fix extras caption BLIP
#14328
2023-12-16 22:14:39 +09:00
AUTOMATIC1111
7428ce52ab
Merge pull request #14327 from AUTOMATIC1111/fp8-cond-cache-fix
Fix FP8 non-reproducible problem
2023-12-16 14:59:35 +03:00
Kohaku-Blueleaf
a978320334 Let fp8-related settings to invalidate cond_cache 2023-12-16 19:39:43 +08:00
AUTOMATIC1111
4f5281a92e
Merge pull request #14227 from kingljl/kingljl-patch-memory-leak
Long running memory leak problem
2023-12-16 11:24:07 +03:00
AUTOMATIC1111
86b3aa94e2 rename pending tasks api endpoint to be more in line with others 2023-12-16 11:04:59 +03:00
AUTOMATIC1111
5b7d86d42b
Merge pull request #14314 from gayshub/master
Add allow specify the task id and get the location of task in the queue of pending task
2023-12-16 11:01:42 +03:00
AUTOMATIC1111
93eae69895 move soft inpainting to a built-in extension 2023-12-16 11:00:42 +03:00
AUTOMATIC1111
cd9ce2e31c Use radio for FP8 mode selection 2023-12-16 10:40:20 +03:00
AUTOMATIC1111
c121f8c315
Merge pull request #14031 from AUTOMATIC1111/test-fp8
A big improvement for dtype casting system with fp8 storage type and manual cast
2023-12-16 10:22:51 +03:00
AUTOMATIC1111
8edb9144cc
Merge branch 'dev' into test-fp8 2023-12-16 10:22:16 +03:00
AUTOMATIC1111
60186c7b9d
Merge pull request #14107 from AUTOMATIC1111/torch210
Torch210
2023-12-16 10:15:55 +03:00
AUTOMATIC1111
7745db6fc0 torch 2.1.2 2023-12-16 10:15:08 +03:00
Kohaku-Blueleaf
ea272152e0 Add FP8 settings into PNG info 2023-12-16 15:08:08 +08:00
AUTOMATIC1111
e9c6325fc6 Merge branch 'dev' into torch210 2023-12-16 10:05:10 +03:00
AUTOMATIC1111
7504f14503 Merge branch 'master' into dev 2023-12-16 09:59:47 +03:00
AUTOMATIC1111
cf2772fab0 Merge branch 'release_candidate' 2023-12-16 09:58:07 +03:00
AUTOMATIC1111
0dfffe53ec Merge pull request #14307 from AUTOMATIC1111/default-Falst-js_live_preview_in_modal_lightbox
default False js_live_preview_in_modal_lightbox
2023-12-16 09:25:33 +03:00
AUTOMATIC1111
c16fcb7f46
Merge pull request #14307 from AUTOMATIC1111/default-Falst-js_live_preview_in_modal_lightbox
default False js_live_preview_in_modal_lightbox
2023-12-16 09:25:08 +03:00
gayshub
6d7e57ba6a fix the problem of ruff of github 2023-12-15 18:03:14 +08:00
gayshub
da45e73b4f fix the problem of ruff of github 2023-12-15 17:57:58 +08:00
gayshub
d859de37d9 fix the problem of ruff of github 2023-12-15 17:48:20 +08:00
gayshub
1242ba08e1 add allow specify the task id and get the location of task in the queue of pending task 2023-12-15 16:57:17 +08:00
w-e-w
0c5427960b make modal toolbar and icon opacity adjustable 2023-12-15 17:11:59 +09:00
w-e-w
3c0c277579 default False js_live_preview_in_modal_lightbox 2023-12-15 00:48:37 +09:00
Kohaku-Blueleaf
0fb34b57b8 Merge branch 'dev' into test-fp8 2023-12-14 16:54:45 +08:00
AUTOMATIC1111
2be85f8fe0 Merge pull request #14237 from ReneKroon/dev
#13354 : solve lora loading issue
2023-12-14 10:15:36 +03:00
AUTOMATIC1111
eb52c803b8 Merge pull request #14216 from wfjsw/state-dict-ref-comparison
change state dict comparison to ref compare
2023-12-14 10:15:22 +03:00
AUTOMATIC1111
f8871dedcf Merge pull request #14230 from AUTOMATIC1111/add-option-Live-preview-in-full-page-image-viewer
add option: Live preview in full page image viewer
2023-12-14 10:15:18 +03:00
AUTOMATIC1111
b7e0d4a7e1 Merge pull request #14229 from Nuullll/ipex-embedding
[IPEX] Fix embedding and ControlNet
2023-12-14 10:14:59 +03:00
AUTOMATIC1111
5cb1ce470d Merge pull request #14266 from kaalibro/dev
Re-add setting lost as part of e294e46
2023-12-14 10:14:54 +03:00
AUTOMATIC1111
888b928f0d Merge pull request #14276 from AUTOMATIC1111/fix-styles
Fix styles
2023-12-14 10:14:50 +03:00
AUTOMATIC1111
b55f09c4e1 Merge pull request #14270 from kaalibro/extra-options-elem-id
Assign id for "extra_options". Replace numeric field with slider.
2023-12-14 10:14:46 +03:00
AUTOMATIC1111
c7cd9b441d Merge pull request #14296 from akx/paste-resolution
Allow pasting in WIDTHxHEIGHT strings into the width/height fields
2023-12-14 10:14:41 +03:00
AUTOMATIC1111
6ef0ff39f2 Merge pull request #14300 from AUTOMATIC1111/oft_fixes
Fix wrong implementation in network_oft
2023-12-14 10:14:19 +03:00
AUTOMATIC1111
aeaf1c510f
Merge pull request #14293 from HinaHyugaHime/master
Bump torch-rocm to 5.6/5.7
2023-12-14 10:10:58 +03:00
AUTOMATIC1111
097140ac1a
Merge branch 'dev' into master 2023-12-14 10:10:43 +03:00
AUTOMATIC1111
778a30a95e
Merge pull request #14237 from ReneKroon/dev
#13354 : solve lora loading issue
2023-12-14 10:08:03 +03:00
AUTOMATIC1111
96c393a7a7
Merge pull request #14269 from kaalibro/skip-interrupt-keyb-shortcuts
Add keyboard shortcuts for generate/skip/interrupt
2023-12-14 10:04:17 +03:00
AUTOMATIC1111
09013b357c
Merge pull request #14216 from wfjsw/state-dict-ref-comparison
change state dict comparison to ref compare
2023-12-14 10:03:14 +03:00
AUTOMATIC1111
d45f790f58
Merge pull request #14230 from AUTOMATIC1111/add-option-Live-preview-in-full-page-image-viewer
add option: Live preview in full page image viewer
2023-12-14 09:59:48 +03:00
AUTOMATIC1111
8c32594d3b
Merge pull request #14208 from CodeHatchling/soft-inpainting
Soft Inpainting
2023-12-14 09:56:12 +03:00
AUTOMATIC1111
f3cc5f8382
Merge pull request #14229 from Nuullll/ipex-embedding
[IPEX] Fix embedding and ControlNet
2023-12-14 09:52:23 +03:00
AUTOMATIC1111
28bafffdc2
Merge pull request #14266 from kaalibro/dev
Re-add setting lost as part of e294e46
2023-12-14 09:48:36 +03:00
AUTOMATIC1111
5db09d1865
Merge pull request #14276 from AUTOMATIC1111/fix-styles
Fix styles
2023-12-14 09:48:14 +03:00
AUTOMATIC1111
c5631aa90d
Merge pull request #14270 from kaalibro/extra-options-elem-id
Assign id for "extra_options". Replace numeric field with slider.
2023-12-14 09:46:05 +03:00
AUTOMATIC1111
206de1a6b0
Merge pull request #14296 from akx/paste-resolution
Allow pasting in WIDTHxHEIGHT strings into the width/height fields
2023-12-14 09:41:18 +03:00
AUTOMATIC1111
b943eebb1d
Merge pull request #14300 from AUTOMATIC1111/oft_fixes
Fix wrong implementation in network_oft
2023-12-14 09:39:57 +03:00
Kohaku-Blueleaf
3772a82a70 better naming and correct order for device. 2023-12-14 01:47:13 +08:00
Kohaku-Blueleaf
8fc67f3851 remove debug print 2023-12-14 01:44:49 +08:00
Kohaku-Blueleaf
265bc26c21 Use self.scale instead of custom finalize 2023-12-14 01:43:24 +08:00
Kohaku-Blueleaf
735c9e8059 Fix network_oft 2023-12-14 01:38:32 +08:00
Aarni Koskela
89cfbc3bbe Allow pasting in WIDTHxHEIGHT strings into the width/height fields 2023-12-13 12:22:13 +02:00
Hina
bda86f0fd9
Update webui.sh 2023-12-12 19:39:14 -06:00
w-e-w
cc41cc4349 on mouse hover show / hide modal image viewer icons 2023-12-13 02:06:56 +09:00
kaalibro
6513470f0d
Remove unnecessary 'else', add 'lightboxModal' check 2023-12-11 18:06:08 +06:00
kaalibro
cee1a40651
Fix linter issues 2023-12-10 17:06:12 +06:00
kaalibro
1d42babd32
Replace Ctrl+Alt+Enter with Esc 2023-12-10 16:28:56 +06:00
kaalibro
6b8143a84e
Number of columns slider: max count set to 20, add description info 2023-12-10 15:35:06 +06:00
w-e-w
8b74389e76 fix styles.csv filename 2023-12-10 15:48:16 +09:00
w-e-w
23a0e60b9b fix save styles 2023-12-10 15:48:00 +09:00
drhead
5381405eaa
re-derive sqrt alpha bar and sqrt one minus alphabar
This is the only place these values are ever referenced outside of training code so this change is very justifiable and more consistent.
2023-12-09 14:09:28 -05:00
kaalibro
1a79a5049b
Assign id for "extra_options". Replace numeric field with slider in Settings. 2023-12-09 22:35:31 +06:00
kaalibro
9c201550dd
Add keyboard shortcuts for generation
(Removed Alt+Enter) Ctrl+Enter to start/restart generation
(New) Alt/Option+Enter to skip generation
(New) Ctrl+Alt/Option+Enter to interrupt generation
2023-12-09 21:04:45 +06:00
kaalibro
39ec4cfea9
Re-add setting lost as part of e294e46 2023-12-09 19:12:59 +06:00
Nuullll
049d5642e5 Fix format 2023-12-09 18:11:26 +08:00
Nuullll
5942979344 Fix ControlNet 2023-12-09 18:09:45 +08:00
CodeHatchling
f1ff932caf Formatted soft_inpainting. 2023-12-08 17:33:11 -07:00
CodeHatchling
b2414476ef soft_inpainting now appears in the "inpaint" section, and will not activate unless inpainting is activated. 2023-12-08 17:32:41 -07:00
Rene Kroon
16bdcce92d #13354: solve lora loading issue 2023-12-08 21:20:55 +01:00
CodeHatchling
659f62e120 Fixed grammar error. 2023-12-07 21:39:54 -07:00
CodeHatchling
fc3e246c0f Fixed complaint about whitespace, updated help section for a parameter. 2023-12-07 20:28:38 -07:00
CodeHatchling
f284ae23bc Added parameters for the composite stage, fixed batched generation. 2023-12-07 20:19:35 -07:00
CodeHatchling
0ef4a4cb23 Fixed error that occurs when using vanilla samplers (somehow). 2023-12-07 14:54:26 -07:00
CodeHatchling
56604f08a1 Moved image filters used by soft inpainting into soft_inpainting.py from images.py 2023-12-07 14:53:44 -07:00
CodeHatchling
8dbacc7d01 Fixed "No newline at end of file". 2023-12-07 14:30:30 -07:00
CodeHatchling
2abc417834 Re-implemented soft inpainting via a script. Also fixed some mistakes with the previous hooks, removed unnecessary formatting changes, removed code that I had forgotten to. 2023-12-07 14:28:02 -07:00
Kohaku-Blueleaf
39ebd5684b Merge remote-tracking branch 'origin/release_candidate' into test-fp8 2023-12-07 20:48:59 +08:00
CodeHatchling
ac45789123 Removed soft inpainting, added hooks for softpainting to work instead. 2023-12-06 21:16:27 -07:00
CodeHatchling
4608f6236f Removed changes in some scripts since the arguments for soft painting are no longer passed through the same path as "mask_blur". 2023-12-06 18:11:17 -07:00
CodeHatchling
e90d4334ad A custom blending function can be provided by p, replacing the use of soft_inpainting. 2023-12-06 18:02:07 -07:00
w-e-w
9d2cbf8e97 add option: Live preview in full page image viewer
make #13459 "show the preview image in the modal view if available" optional
2023-12-06 23:06:32 +09:00
Nuullll
746783f7a4 [IPEX] Fix embedding
Cast `torch.bmm` args into same `dtype`.

Fixes the following error when using Text Inversion embedding (#14224):

```
RuntimeError: could not create a primitive descriptor for a matmul
primitive
```
2023-12-06 20:55:47 +08:00
fuchen.ljl
c2bdbb67b6
Merge branch 'dev' into kingljl-patch-memory-leak 2023-12-06 20:42:04 +08:00
fuchen.ljl
4d56383025
Long distance memory overflow issue
Problem: The memory will slowly increase with the drawing until restarting.
Observation: GC analysis shows that no occupation has occurred, so it is suspected to be a problem with the underlying allocator.
Reason: Under Linux, glibc is used to allocate memory. glibc uses brk and mmap to allocate memory, and the memory allocated by brk cannot be released until the high-address memory is released. That is to say, if you apply for two pieces of memory A and B through brk, it is impossible to release A before B is released, and it is still occupied by the process. Check the suspected "memory leak" through TOP.
So I replaced TCMalloc, but found that libtcmalloc_minimal could not find ptthread_Key_Create. After analysis, it was found that pthread was not entered during compilation.
2023-12-06 20:23:56 +08:00
Kohaku-Blueleaf
294ec5ac37 Merge branch 'dev' into test-fp8 2023-12-06 15:16:49 +08:00
Kohaku-Blueleaf
672dc4efa8 Fix forced reload 2023-12-06 15:16:10 +08:00
Jabasukuriputo Wang
895456c4a2
change state dict comparison to ref compare 2023-12-05 18:00:48 -06:00
AUTOMATIC1111
120a84bd2f Merge pull request #14203 from AUTOMATIC1111/remove-clean_text()
remove clean_text()
2023-12-05 07:15:54 +03:00
AUTOMATIC1111
f92d61497a
Merge pull request #14203 from AUTOMATIC1111/remove-clean_text()
remove clean_text()
2023-12-05 07:15:39 +03:00
CodeHatchling
38864816fa Merge remote-tracking branch 'origin2/dev' into soft-inpainting
# Conflicts:
#	modules/processing.py
2023-12-04 20:38:13 -07:00
CodeHatchling
49bbf11407 Fixed unused import. 2023-12-04 19:47:40 -07:00
CodeHatchling
6fc12428e3 Fixed issue where batched inpainting (batch size > 1) wouldn't work because of mismatched tensor sizes. The 'already_decoded' decoded case should also be handled correctly (tested indirectly). 2023-12-04 19:42:59 -07:00
CodeHatchling
b32a334e3d Applies a convert('RGBA') operation early to mimic previous behaviour. 2023-12-04 17:57:10 -07:00
CodeHatchling
60c602232f Restored original formatting. 2023-12-04 17:55:14 -07:00
CodeHatchling
57f29bd61d Re-introduce latent blending step from the vanilla inpainting procedure. 2023-12-04 17:41:18 -07:00
CodeHatchling
1455159cf4 Fixed issue with whitespace, removed commented out code that was meant to be used as a reference. 2023-12-04 16:43:57 -07:00
CodeHatchling
976c1053ef Cleaned up code, moved main code contributions into soft_inpainting.py 2023-12-04 16:06:58 -07:00
w-e-w
854f8c318c remove clean_text() 2023-12-05 04:41:09 +09:00
AUTOMATIC1111
368d66c9cc add hypertile infotext 2023-12-04 15:56:11 +03:00
AUTOMATIC1111
22e23dbf29 add hypertile infotext 2023-12-04 15:56:03 +03:00
AUTOMATIC1111
81105ee013 repair old handler for postprocessing API in a way that doesn't break interface 2023-12-04 13:11:12 +03:00
AUTOMATIC1111
883d6a2b34 repair old handler for postprocessing API in a way that doesn't break interface 2023-12-04 13:11:00 +03:00
AUTOMATIC1111
24dae9bc4c repair old handler for postprocessing API 2023-12-04 12:36:56 +03:00
AUTOMATIC1111
15322e1b1a repair old handler for postprocessing API 2023-12-04 12:36:41 +03:00
CodeHatchling
259d33c3c8 Enables the original functionality to be toggled on and off. 2023-12-04 01:57:21 -07:00
Kohaku-Blueleaf
f5f89780cc Merge branch 'dev' into test-fp8 2023-12-04 16:47:41 +08:00
CodeHatchling
aaacf48232 Organized the settings and UI of soft inpainting to allow for toggling the feature, and centralizes default values to reduce the amount of copy-pasta. 2023-12-04 01:27:22 -07:00
AUTOMATIC1111
48fae7ccdc update changelog 2023-12-04 09:35:52 +03:00
AUTOMATIC1111
9e1f3feb12 make webui not crash when running with --disable-all-extensions option 2023-12-04 09:15:19 +03:00
AUTOMATIC1111
208760f348
Merge pull request #14192 from illtellyoulater/patch-1
Update launch_utils.py - fixes repetead package reinstalls
2023-12-04 08:14:40 +03:00
missionfloyd
06725af40b
Lint 2023-12-03 21:26:12 -07:00
illtellyoulater
639ccf254b
Update launch_utils.py to fix wrong dep. checks and reinstalls
Fixes failing dependency checks for extensions having a different package name and import name (for example ffmpeg-python / ffmpeg), which currently is causing the unneeded reinstall of packages at runtime.

In fact with current code, the same string is used when installing a package and when checking for its presence, as you can see in the following example:

> launch_utils.run_pip("install ffmpeg-python", "required package")
[ Installing required package: "ffmpeg-python" ... ]
[ Installed ]

> launch_utils.is_installed("ffmpeg-python")
False

... which would actually return true with:

> launch_utils.is_installed("ffmpeg")
True
2023-12-04 02:35:35 +00:00
CodeHatchling
552f8bc832 "Uncrop" the original denoised image for the composite step, fixing a "ValueError: Images do not match" *shudder* 2023-12-03 14:49:41 -07:00
CodeHatchling
28a2b5b4aa Fixed a math mistake. 2023-12-03 14:20:20 -07:00
AUTOMATIC1111
334298d473
Merge pull request #14186 from akx/torchvision-basicsr-hack
Add import_hook hack to work around basicsr/torchvision incompatibility
2023-12-03 19:58:53 +03:00
AUTOMATIC1111
2d5507fce5
Merge pull request #14181 from AUTOMATIC1111/rework-mask-and-mask_composite-logic
slight optimization for mask and mask_composite
2023-12-03 19:58:14 +03:00
Aarni Koskela
d92ce145bb Add import_hook hack to work around basicsr incompatibility
Fixes #13985
2023-12-03 16:55:38 +02:00
w-e-w
d3fdc4af61 rework mask and mask_composite logic 2023-12-03 18:22:41 +09:00
AUTOMATIC1111
b4776ea3a2
Merge pull request #14177 from catboxanon/fix/mask-composite-save
Fix `save_samples` being checked early when saving masked composite
2023-12-03 11:57:14 +03:00
CodeHatchling
3bd3a09160 Merge remote-tracking branch 'origin/dev' into soft-inpainting
# Conflicts:
#	modules/processing.py
2023-12-02 21:14:02 -07:00
CodeHatchling
bb04d400c9 Rewrote latent_blend() to use in-place operations and to aggressively "del" references with the intention of minimizing allocations and easing garbage collection. 2023-12-02 21:08:26 -07:00
CodeHatchling
73ab982d1b Blend masks are now produced afterward, based on an estimate of the visual difference between the original and modified latent images. This should remove ghosting and clipping artifacts from masks, while preserving the details of largely unchanged content. 2023-12-02 21:07:02 -07:00
AUTOMATIC1111
fed5b1d55c
Merge pull request #14178 from catboxanon/fix/missing-setting-v1
Re-add `keyedit_delimiters_whitespace` setting lost as part of commit e294e46
2023-12-03 06:33:16 +03:00
Kohaku-Blueleaf
9a15ae2a92 Merge branch 'dev' into test-fp8 2023-12-03 10:54:54 +08:00
CodeHatchling
609dea36ea Added utility functions related to processing masks. 2023-12-02 18:56:49 -07:00
catboxanon
9528d66c94 Re-add setting lost as part of e294e46 2023-12-02 14:56:26 -05:00
drhead
78acdcf677 fix variable 2023-12-02 14:09:18 -05:00
drhead
dc1adeecdd Create alphas_cumprod_original on full precision path 2023-12-02 14:06:56 -05:00
drhead
4a43334376 Revert 309a606c 2023-12-02 14:05:42 -05:00
catboxanon
83e8c32276 Fix save_samples being checked early when saving masked composite 2023-12-02 13:30:53 -05:00
drhead
81c4ddf6eb
fix linting 2023-12-02 13:11:00 -05:00
drhead
309a606c2f
ensure that original alpha bar always exists 2023-12-02 13:07:45 -05:00
AUTOMATIC1111
ac02216e54 alternate implementation for unet forward replacement that does not depend on hijack being applied 2023-12-02 19:35:47 +03:00
AUTOMATIC1111
af5f0734c9
Merge pull request #14171 from Nuullll/ipex
Initial IPEX support for Intel Arc GPU
2023-12-02 19:22:32 +03:00
AUTOMATIC1111
a5f61aa8c5 potential fix for #14172 2023-12-02 18:03:34 +03:00
AUTOMATIC1111
11d23e8ca5 remove Train/Preprocessing tab and put all its functionality into extras batch images mode 2023-12-02 18:01:11 +03:00
Kohaku-Blueleaf
50a21cb09f Ensure the cached weight will not be affected 2023-12-02 22:06:47 +08:00
Nuullll
96871e4f74 Remove webui-ipex-user.bat 2023-12-02 17:11:31 +08:00
AUTOMATIC1111
4a666381bf extras tab batch: actually use original filename
preprocessing upscale: do not do an extra upscale step if it's not needed
2023-12-02 12:11:21 +03:00
Kohaku-Blueleaf
110485d5bb Merge branch 'dev' into test-fp8 2023-12-02 17:00:09 +08:00
Nuullll
87cd07b3af Fix fp64 2023-12-02 15:54:25 +08:00
AUTOMATIC1111
0bb6e00ba3
Merge pull request #13957 from h43lb1t0/extra_network_subdirs
dir buttons start with / so only the correct dir will be shown and no…
2023-12-02 09:59:29 +03:00
AUTOMATIC1111
87d973e389
Merge pull request #14063 from wfjsw/use-ext-name-for-installed
use extension name for determining an extension is installed in the index
2023-12-02 09:58:44 +03:00
AUTOMATIC1111
ef6b8123dc put code that can cause an exception into its own function for #14120 2023-12-02 09:57:39 +03:00
AUTOMATIC1111
5ed7daa3d9
Merge pull request #14120 from AUTOMATIC1111/protect-against-bad-ui-creation-scripts
catch uncaught exception with ui creation scripts
2023-12-02 09:54:21 +03:00
AUTOMATIC1111
ef1723ef41
Merge pull request #14125 from cjj1977/dev
Allow use of mutiple styles csv files
2023-12-02 09:53:27 +03:00
AUTOMATIC1111
7547d7c791
Merge pull request #14126 from aria1th/hypertile-xyz
Support XYZ scripts / split hires path from unet
2023-12-02 09:48:40 +03:00
AUTOMATIC1111
88736b5557
Merge pull request #14131 from read-0nly/patch-1
Update devices.py - Make 'use-cpu all' actually apply to 'all'
2023-12-02 09:46:19 +03:00
AUTOMATIC1111
9eadc4f146
Merge pull request #14121 from AUTOMATIC1111/fix-Auto-focal-point-crop-for-opencv-4.8.x
Fix auto focal point crop for opencv >= 4.8
2023-12-02 09:46:00 +03:00
AUTOMATIC1111
97c8e7e0c7
Merge pull request #14119 from AUTOMATIC1111/add-Block-component-creation-callback
add Block component creation callback
2023-12-02 09:45:03 +03:00
AUTOMATIC1111
e12a26c253
Merge pull request #14046 from hidenorly/AddFP32FallbackSupportOnSdVaeApprox
Add FP32 fallback support on sd_vae_approx
2023-12-02 09:44:00 +03:00
AUTOMATIC1111
600036d158
Merge pull request #14156 from AUTOMATIC1111/metadata-pop-up-size-limit
fix not able to exit metadata popup when pop up is too big
2023-12-02 09:30:27 +03:00
AUTOMATIC1111
4125552752
Merge pull request #14170 from MrCheeze/sd-turbo
Add support for SD 2.1 Turbo
2023-12-02 09:30:07 +03:00
AUTOMATIC1111
e294e46d46 split UI settings page into many 2023-12-02 09:26:38 +03:00
Nuullll
7499148ad4 Disable ipex autocast due to its bad perf 2023-12-02 14:00:46 +08:00
AUTOMATIC1111
b58d061e41 infotext updates: add option to disregard certain infotext fields, add option to not include VAE in infotext, add explanation to infotext settings page, move some options to infotext settings page 2023-12-02 08:33:28 +03:00
MrCheeze
6080045b2a Add support for SD 2.1 Turbo, by converting the state dict from SGM to LDM on load 2023-12-01 22:58:05 -05:00
MrCheeze
293f44e6c1 Fix bug where is_using_v_parameterization_for_sd2 fails because the sd_hijack is only partially undone 2023-12-01 22:56:08 -05:00
missionfloyd
01c8f1803a
Close popups with escape key 2023-11-30 22:36:12 -07:00
w-e-w
c2ed413203 add max-heigh/width to global-popup-inner
prevent the pop-up from being too big as to making exiting the pop-up impossible
2023-12-01 02:59:41 +09:00
Nuullll
8b40f475a3 Initial IPEX support 2023-11-30 20:22:46 +08:00
drhead
668ae34e21
remove debug print 2023-11-29 22:48:31 -05:00
catboxanon
de79597ab9 Only apply ztSNR related code if alphas_cumprod exists 2023-11-29 18:33:32 -05:00
catboxanon
ffa7f8201d Lint 2023-11-29 18:10:43 -05:00
catboxanon
ec6ee5c13b Fix infotext for ztSNR 2023-11-29 18:10:27 -05:00
drhead
6d0a8dcd89
Implement zero terminal SNR schedule option 2023-11-29 17:42:07 -05:00
drhead
588a52891d
Add options for zero terminal SNR 2023-11-29 17:40:23 -05:00
drhead
b25c126ccd
Protect alphas_cumprod from downcasting 2023-11-29 17:38:53 -05:00
CodeHatchling
c7a1ff8720 Tweaked default values. 2023-11-28 23:31:10 -07:00
CodeHatchling
284fd8f415 Tweaked UI sliders and labels. 2023-11-28 23:03:50 -07:00
CodeHatchling
c5c7fa06aa Added slider for detail preservation strength, removed largely needless offset parameter, changed labels in UI and for saving to/pasting data from PNG files. 2023-11-28 22:35:07 -07:00
CodeHatchling
debf836fcc Added UI elements to control blending parameters. 2023-11-28 16:15:36 -07:00
CodeHatchling
a6e5846453 Nerfs the aggressive post-processing step of overlaying the original image. 2023-11-28 16:13:42 -07:00
CodeHatchling
e715e46b6a Implements "scheduling" for blending of the original latents and a latent blending formula that preserves details in blend transition areas. 2023-11-28 16:10:22 -07:00
CodeHatchling
bbba133f05 Removed conflicting step that replaces the softly inpainted latents with a naive blend with the original latents. 2023-11-28 15:09:43 -07:00
CodeHatchling
dec791d35d Removed code which forces the inpainting mask to be 0 or 1. Now fractional values (e.g. 0.5) are accepted. 2023-11-28 15:05:01 -07:00
hidenorly
81c00728b8 Fix the Ruff error about unused import 2023-11-29 04:59:35 +09:00
hidenorly
a0096c5897 Add FP32 fallback support on torch.nn.functional.interpolate
This tries to execute interpolate with FP32 if it failed.

Background is that
on some environment such as Mx chip MacOS devices, we get error as follows:

```
"torch/nn/functional.py", line 3931, in interpolate
        return torch._C._nn.upsample_nearest2d(input, output_size, scale_factors)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    RuntimeError: "upsample_nearest2d_channels_last" not implemented for 'Half'
```

In this case, ```--no-half``` doesn't help to solve. Therefore this commits add the FP32 fallback execution to solve it.

Note that the ```upsample_nearest2d``` is called from ```torch.nn.functional.interpolate```.
And the fallback for torch.nn.functional.interpolate is necessary at
```modules/sd_vae_approx.py``` 's ```VAEApprox.forward```
```repositories/stable-diffusion-stability-ai/ldm/modules/diffusionmodules/openaimodel.py``` 's ```Upsample.forward```
2023-11-29 04:45:04 +09:00
hidenorly
39eae9f009 Revert "Add FP32 fallback support on sd_vae_approx"
This reverts commit 58c19545c83fa6925c9ce2216ee64964eb5129ce.
Since the modification is expected to move to mac_specific.py
(https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14046#issuecomment-1826731532)
2023-11-29 04:07:48 +09:00
w-e-w
d608926f81 reformat file with uniform indentation 2023-11-28 12:12:27 +09:00
w-e-w
03ee297aa2 fix Auto focal point crop for opencv >= 4.8.x
autocrop.download_and_cache_models
in opencv >= 4.8 the face detection model was updated
download the base on opencv version
returns the model path or raise exception
2023-11-28 12:09:51 +09:00
obsol
3cd6e1d0a0
Update devices.py
fixes issue where "--use-cpu" all properly makes SD run on CPU but leaves ControlNet (and other extensions, I presume) pointed at GPU, causing a crash in ControlNet caused by a mismatch between devices between SD and CN

https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/14097
2023-11-27 19:21:43 -05:00
aria1th
ec78354efa hypertile_xyz: we don't need isnumeric check for AxisOption 2023-11-27 22:25:28 +09:00
aria1th
524d6a4dba fix ruff - set comprehension 2023-11-27 22:13:18 +09:00
aria1th
f207eb7a0d fix ruff in hypertile_xyz.py 2023-11-27 22:11:28 +09:00
aria1th
601a7b4ce5 cache divisors / fix ruff 2023-11-27 22:10:31 +09:00
Charlie Joynt
0cd5b0ed54 Merge branch 'dev' of https://github.com/cjj1977/stable-diffusion-webui into dev 2023-11-27 12:11:06 +00:00
aria1th
23c36f59b4 Support XYZ scripts / split hires path from unet 2023-11-27 21:10:26 +09:00
Charlie Joynt
26a0c29587 Allow use of mutiple styles csv files
* https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/14122
Fix edge case where style text has multiple {prompt} placeholders
* https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/14005
2023-11-27 12:08:51 +00:00
MisterSeajay
a75314b41f
bugfix for warning message (#6)
* bugfix for warning message

* bugfix error message
2023-11-27 12:03:42 +00:00
MisterSeajay
1c64bb7140
bugfix for warning message (#6) 2023-11-27 11:57:27 +00:00
Charlie Joynt
9621ca4d64 Allow use of mutiple styles csv files 2023-11-27 11:39:50 +00:00
w-e-w
8a6e4bda21 catch uncaught exception with ui creation scripts
prevent total webui crash
2023-11-27 14:18:17 +09:00
w-e-w
b30cc87b78 add Block component creation callback 2023-11-27 13:15:17 +09:00
Jabasukuriputo Wang
1f6844eb7e
also consider extension url 2023-11-26 10:04:39 -06:00
AUTOMATIC1111
f0f100e67b add categories to settings 2023-11-26 17:56:22 +03:00
AUTOMATIC1111
500de919ed
Merge pull request #14108 from AUTOMATIC1111/json.dump(ensure_ascii=False)
json.dump(ensure_ascii=False)
2023-11-26 16:15:56 +03:00
w-e-w
a15dd151ff json.dump(ensure_ascii=False)
improve json readability
2023-11-26 21:56:21 +09:00
AUTOMATIC1111
2a40d3c603 compact prompt layout: preserve scroll when switching between lora tabs 2023-11-26 14:58:56 +03:00
Kohaku-Blueleaf
3d341ebc7d Merge branch 'dev' into test-fp8 2023-11-26 17:32:52 +08:00
AUTOMATIC1111
29f04149b6 update torch to 2.1.0 2023-11-26 12:07:33 +03:00
AUTOMATIC1111
e44103264d
Merge pull request #13936 from cabelo/compatibility
Compatibility
2023-11-26 11:57:13 +03:00
AUTOMATIC1111
6955c210b7
Merge pull request #14059 from akx/upruff
Update Ruff to 0.1.6
2023-11-26 11:54:36 +03:00
AUTOMATIC1111
d1750e5eca fix linter errors 2023-11-26 11:37:12 +03:00
AUTOMATIC1111
c5a0c59a83 do not save HTML explanations from options page to config 2023-11-26 11:36:17 +03:00
AUTOMATIC1111
f7f015e84b
Merge pull request #14084 from wfjsw/move-from-sysinfo-to-errors
Move exception_records related methods to errors.py
2023-11-26 11:29:27 +03:00
AUTOMATIC1111
f85b74763d Merge branch 'hypertile-in-sample' into dev 2023-11-26 11:18:49 +03:00
AUTOMATIC1111
fd8674a4bc
Merge pull request #13948 from aria1th/hypertile-in-sample
support HyperTile optimization
2023-11-26 11:18:25 +03:00
AUTOMATIC1111
d2e0c1ca13 rework hypertile into a built-in extension 2023-11-26 11:17:38 +03:00
AUTOMATIC1111
3a9bf4ac10 move file 2023-11-26 08:29:12 +03:00
Kohaku-Blueleaf
40ac134c55 Fix pre-fp8 2023-11-25 12:35:09 +08:00
Jabasukuriputo Wang
5cedc8f9b2
remove traceback in sysinfo 2023-11-24 11:30:30 -06:00
Jabasukuriputo Wang
86b99b1e98
Move exception_records related methods to errors.py 2023-11-24 11:28:54 -06:00
wfjsw
ac2a981c4f use extension name for determining an extension is installed in the index 2023-11-22 22:40:24 -06:00
Aarni Koskela
066afda2f6 Simplify restart_sampler (suggested by ruff) 2023-11-22 18:05:12 +02:00
Aarni Koskela
8fe1e19522 Update ruff to 0.1.6 2023-11-22 18:05:12 +02:00
Kohaku-Blueleaf
f5d719d1f1 Add forced reload for fp16 cache 2023-11-22 01:45:56 +08:00
Kohaku-Blueleaf
370a77f8e7 Option for using fp16 weight when apply lora 2023-11-21 19:59:34 +08:00
AUTOMATIC1111
8aa51f682c fix [Bug]: (Dev Branch) Placing "Dimensions" first in "ui_reorder_list" prevents start #14047 2023-11-21 08:32:07 +03:00
hidenorly
58c19545c8 Add FP32 fallback support on sd_vae_approx
This tries to execute interpolate with FP32 if it failed.

Background is that
on some environment such as Mx chip MacOS devices, we get error as follows:

```
"torch/nn/functional.py", line 3931, in interpolate
        return torch._C._nn.upsample_nearest2d(input, output_size, scale_factors)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    RuntimeError: "upsample_nearest2d_channels_last" not implemented for 'Half'
```

In this case, ```--no-half``` doesn't help to solve. Therefore this commits add the FP32 fallback execution to solve it.

Note that the submodule may require additional modifications. The following is the example modification on the other submodule.

```repositories/stable-diffusion-stability-ai/ldm/modules/diffusionmodules/openaimodel.py

class Upsample(nn.Module):
..snip..
    def forward(self, x):
        assert x.shape[1] == self.channels
        if self.dims == 3:
            x = F.interpolate(
                x, (x.shape[2], x.shape[3] * 2, x.shape[4] * 2), mode="nearest"
            )
        else:
            try:
                x = F.interpolate(x, scale_factor=2, mode="nearest")
            except:
                x = F.interpolate(x.to(th.float32), scale_factor=2, mode="nearest").to(x.dtype)
        if self.use_conv:
            x = self.conv(x)
        return x
..snip..
```

You can see the FP32 fallback execution as same as sd_vae_approx.py.
2023-11-21 01:13:53 +09:00
Tom Haelbich
314ae1535e added option for default behavior of dir buttons 2023-11-20 16:19:54 +01:00
AUTOMATIC1111
5f36f6ab21
Merge pull request #14009 from AUTOMATIC1111/Option-to-show-batch-img2img-results-in-UI
Option to show batch img2img results in UI
2023-11-20 17:44:58 +03:00
AUTOMATIC1111
1463cea949 Merge branch 'dag' into dev 2023-11-20 14:50:01 +03:00
AUTOMATIC1111
73a0b4bba6
Merge pull request #13944 from wfjsw/dag
implementing script metadata and DAG sorting mechanism
2023-11-20 14:49:46 +03:00
AUTOMATIC1111
9b471436b2 rework extensions metadata: use custom sorter that doesn't mess the order as much and ignores cyclic errors, use classes with named fields instead of dictionaries, eliminate some duplicated code 2023-11-20 14:47:09 +03:00
Kohaku-Blueleaf
b2e039d07b Update webui-macos-env.sh 2023-11-20 14:05:32 +08:00
AUTOMATIC1111
411da7c281
Merge pull request #14035 from AUTOMATIC1111/sysinfo-json
save sysinfo as .json
2023-11-20 08:56:45 +03:00
w-e-w
6d337bf23d save sysinfo as .json
GitHub now allows uploading of .json files in issues
2023-11-20 01:38:31 +09:00
w-e-w
dea5e43c83 Option to show batch img2img results in UI
shared.opts.img2img_batch_show_results_limit
limit the number of images return to the UI for batch img2img
default limit 32
0 no images are shown
-1 unlimited, all images are shown
2023-11-19 17:37:32 +09:00
Kohaku-Blueleaf
043d2edcf6 Better naming 2023-11-19 15:56:31 +08:00
Kohaku-Blueleaf
f383af2729 update xformers/torch versions 2023-11-19 15:56:23 +08:00
Kohaku-Blueleaf
890181e1d4 Update the xformers/torch versions 2023-11-19 15:54:39 +08:00
Kohaku-Blueleaf
598da5cd49 Use options instead of cmd_args 2023-11-19 15:50:06 +08:00
Kohaku-Blueleaf
b60e1088db Merge branch 'dev' into test-fp8 2023-11-19 15:24:57 +08:00
wfjsw
bde439ef67 use metadata.ini for meta filename 2023-11-19 00:58:47 -06:00
AUTOMATIC1111
fc83af4432
Merge pull request #13931 from AUTOMATIC1111/style-hotkeys
Enable prompt hotkeys in style editor
2023-11-19 09:11:49 +03:00
AUTOMATIC1111
337bc4a2fb
Merge pull request #13014 from AUTOMATIC1111/thread-safe-extranetworks-list_items
thread safe extra network list_items
2023-11-19 09:09:21 +03:00
AUTOMATIC1111
6fac65f334
Merge pull request #13929 from kingljl/fix-dependency-address-patch-1
Fix dependency address patch 1
2023-11-19 09:01:39 +03:00
AUTOMATIC1111
5a031d9233
Merge pull request #13962 from kaalibro/dev
Fixes generation restart not working for some users when 'Ctrl+Enter' is pressed
2023-11-19 09:01:11 +03:00
AUTOMATIC1111
e4e875fffe
Merge pull request #13968 from kaalibro/extranetworks-path-sorting
Adds 'Path' sorting for Extra network cards
2023-11-19 09:00:05 +03:00
AUTOMATIC1111
b945ba716b
Merge pull request #13977 from AUTOMATIC1111/hotfix-postprocessing-state-end
Hotfix: call shared.state.end() after postprocessing done
2023-11-19 08:59:32 +03:00
AUTOMATIC1111
2207ef363a
Merge pull request #13692 from v0xie/network-oft
Support inference with OFT networks
2023-11-19 08:59:09 +03:00
AUTOMATIC1111
3a13b0e762
Merge pull request #13996 from Luxter77/patch-1
Adds tqdm handler to logging_config.py for progress bar integration
2023-11-19 08:57:14 +03:00
AUTOMATIC1111
6429c3db11
Merge pull request #13826 from ezxzeng/ui_mobile_optimizations
added accordion settings options
2023-11-19 08:42:58 +03:00
AUTOMATIC1111
5a9dc1c0ca
Merge pull request #14004 from storyicon/master
feat: fix randn found element of type float at pos 2
2023-11-19 08:40:29 +03:00
storyicon
4f2a4a3615 feat: fix randn found element of type float at pos 2
Signed-off-by: storyicon <storyicon@foxmail.com>
2023-11-17 09:48:18 +00:00
aria1th
97431f29fe fix double gc and decoding with unet context 2023-11-17 10:05:28 +09:00
aria1th
ffd0f8ddc3 set empty value for SD XL 3rd layer 2023-11-17 09:54:33 +09:00
aria1th
c0725ba2d0 Fix inverted option issue
I'm pretty sure I was sleepy while implementing this
2023-11-17 09:34:50 +09:00
aria1th
c40be2252a Fix critical issue - unet apply 2023-11-17 09:22:27 +09:00
Your Name
7021cdb1de actually adds handler to logging_config.py 2023-11-16 17:53:57 -03:00
Lucas Daniel Velazquez M
cdb60a690d Take into account tqdm not being installed before first boot for logging 2023-11-16 16:49:59 -03:00
Lucas Daniel Velazquez M
236eb82c3a
Adds tqdm handler to logging_config.py for progress bar integration 2023-11-16 13:20:33 -03:00
Kohaku-Blueleaf
cd12256575 Merge branch 'dev' into test-fp8 2023-11-16 21:53:13 +08:00
AngelBottomless
472c22cc8a fix ruff - add newline 2023-11-16 19:03:45 +09:00
AngelBottomless
bcfaf3979a convert/add hypertile options 2023-11-16 18:43:16 +09:00
v0xie
eb667e715a feat: LyCORIS/kohya OFT network support 2023-11-15 18:28:48 -08:00
v0xie
d6d0b22e66 fix: ignore calc_scale() for COFT which has very small alpha 2023-11-15 03:08:50 -08:00
aria1th
af45872fdb copy LDM VAE key from XL 2023-11-15 15:15:14 +09:00
aria1th
b29fc6d4de Implement Hypertile
Co-Authored-By: Kieran Hunt <kph@hotmail.ca>
2023-11-15 15:13:39 +09:00
AngelBottomless
a292d2c47f
hotfix: call shared.state.end() after postprocessing done 2023-11-15 14:26:37 +09:00
kaalibro
c1c816006e
Adds 'Path' sorting for Extra network cards 2023-11-13 22:01:52 +06:00
kaalibro
94e9669566
Fixes generation restart not working for some users when 'Ctrl+Enter' is pressed 2023-11-13 14:51:06 +06:00
missionfloyd
8048f36072
Lint 2023-11-12 17:12:50 -07:00
Tom Haelbich
f6762d2ad9 dir buttons start with / so only the correct dir will be shown and not dirs with a substrings as name from the dir 2023-11-12 14:14:16 +01:00
wfjsw
3bb32befe9 bug fix 2023-11-11 11:58:19 -06:00
wfjsw
48d6102b31 fix 2023-11-11 11:17:26 -06:00
wfjsw
520e52f846 allow comma and whitespace as separator 2023-11-11 10:58:26 -06:00
wfjsw
7af576e745 remove the assumption of same name 2023-11-11 10:46:47 -06:00
aria1th
294f8a514f add hyperTile
https://github.com/tfernd/HyperTile
2023-11-11 23:28:12 +09:00
wfjsw
bc1a450124 reverse the extension load order so builtin extensions load earlier natively 2023-11-11 04:08:45 -06:00
wfjsw
0d1924c48b populate loaded_extensions from extension list instead 2023-11-11 04:03:55 -06:00
wfjsw
0fc7dc1c04 implementing script metadata and DAG sorting mechanism 2023-11-11 04:01:13 -06:00
Emily Zeng
3a4a6c43a4 ExitStack as alternative to suppress 2023-11-10 16:06:01 -05:00
w-e-w
5432d93013 fix added accordion settings options 2023-11-11 05:30:35 +09:00
Alessandro de Oliveira Faria (A.K.A. CABELO)
6a86b3ad9b Compatibility with Debian 11, Fedora 34+ and openSUSE 15.4+ 2023-11-10 14:15:34 -03:00
missionfloyd
7ff54005fe Enable prompt hotkeys in style editor 2023-11-09 23:47:53 -07:00
Alessandro de Oliveira Faria (A.K.A. CABELO)
66767e3876 - opensuse compatibility 2023-11-10 03:45:44 -03:00
fuchen.ljl
6d77a6e1c6
Update README.md
Modify the stablediffusion dependency address
2023-11-10 14:40:39 +08:00
fuchen.ljl
42dbcad3ef
Merge pull request #1 from kingljl/fix-dependency-address-patch-1
Update README.md
2023-11-10 14:38:26 +08:00
fuchen.ljl
98fc525a2c
Update README.md
Modify the stablediffusion dependency address
2023-11-10 14:37:30 +08:00
Emily Zeng
ff2952f105 multiline with statement for readibility 2023-11-09 13:35:52 -05:00
Emily Zeng
9aa4d098f0 removed changes that weren't merged properly 2023-11-09 13:25:24 -05:00
Emily Zeng
a625a7bb81 moved nested with to single line to remove extra tabs 2023-11-09 13:15:06 -05:00
hako-mikan
816096e642
Merge branch 'dev' into master 2023-11-09 21:57:57 +09:00
hako-mikan
6b9795849d
Fix model switch bug 2023-11-09 20:23:37 +09:00
ezxzeng
f9c14a8c8c
Merge branch 'dev' into ui_mobile_optimizations 2023-11-07 15:25:27 -05:00
AUTOMATIC1111
5e80d9ee99 fix pix2pix producing bad results 2023-11-07 11:33:33 +03:00
AUTOMATIC1111
47bccbebae
Merge pull request #13884 from GerryDE/notification-sound-volume
Add option to set notification sound volume
2023-11-07 08:29:06 +03:00
GerryDE
9ba991cad8 Add option to set notification sound volume 2023-11-07 03:09:08 +01:00
AUTOMATIC1111
9c1c0da026 fix exception related to the pix2pix 2023-11-06 11:17:36 +03:00
AUTOMATIC1111
656437e0a5 fix img2img_tabs error 2023-11-06 10:32:21 +03:00
AUTOMATIC1111
6ad666e479 more changes for #13865: fix formatting, rename the function, add comment and add a readme entry 2023-11-05 19:46:20 +03:00
AUTOMATIC1111
80d639a440 linter 2023-11-05 19:32:21 +03:00
AUTOMATIC1111
96ee3eff6c
Merge pull request #13865 from Gothos/master
Add support for SSD-1B
2023-11-05 19:31:44 +03:00
AUTOMATIC1111
ff805d8d0e
Merge branch 'dev' into master 2023-11-05 19:30:57 +03:00
AUTOMATIC1111
c3699d4fd1 compact prompt option disabled by default 2023-11-05 19:23:48 +03:00
AUTOMATIC1111
4d4a9e7332 added compact prompt option 2023-11-05 19:19:55 +03:00
Ritesh Gangnani
44c5097375 Use devices.torch_gc() instead of empty_cache() 2023-11-05 20:31:57 +05:30
Ritesh Gangnani
44db35fb1a Added memory clearance after deletion 2023-11-05 19:15:38 +05:30
Ritesh Gangnani
ff1609f91e Add SSD-1B as a supported model 2023-11-05 19:13:49 +05:30
AUTOMATIC1111
d9499f4301 properly apply sort order for extra network cards when selected from dropdown
allow selection of default sort order in settings
remove 'Default' sort order, replace with 'Name'
2023-11-05 10:12:50 +03:00
AUTOMATIC1111
16ab174290 eslint 2023-11-05 09:20:15 +03:00
AUTOMATIC1111
046c7b053a
Merge pull request #13855 from gibiee/patch-1
Corrected a typo in `modules/cmd_args.py`
2023-11-05 08:57:59 +03:00
AUTOMATIC1111
6b8c661c49 add a visible checkbox to input accordion 2023-11-05 08:55:54 +03:00
gibiee
2b06cefe66
correct a typo
modify "defaul" to "default"
2023-11-05 11:37:23 +09:00
v0xie
7edd50f304
Merge pull request #2 from v0xie/network-oft-change-impl
Use same updown implementation for LyCORIS OFT as kohya-ss OFT
2023-11-04 15:06:04 -07:00
v0xie
bbf00a96af refactor: remove unused function 2023-11-04 14:56:47 -07:00
v0xie
329c8bacce refactor: use same updown for both kohya OFT and LyCORIS diag-oft 2023-11-04 14:54:36 -07:00
Kohaku-Blueleaf
c3facab495 Merge branch 'dev' into test-fp8 2023-11-04 12:56:58 +08:00
v0xie
1dd25be037
Merge pull request #1 from v0xie/oft-faster
Support LyCORIS diag-oft OFT implementation (minus MultiheadAttention layer), maintains support for kohya-ss OFT
2023-11-03 19:47:27 -07:00
v0xie
f6c8201e56 refactor: move factorization to lyco_helpers, separate calc_updown for kohya and kb 2023-11-03 19:35:15 -07:00
v0xie
fe1967a4c4 skip multihead attn for now 2023-11-03 17:52:55 -07:00
AUTOMATIC1111
452ab8fe72
Merge pull request #13718 from avantcontra/bugfix_gfpgan_custom_path
fix bug when using --gfpgan-models-path
2023-11-03 20:19:58 +03:00
AUTOMATIC1111
399baa54c2
Merge pull request #13733 from dben/patch-1
Update prompts_from_file script to allow concatenating entries with the general prompt.
2023-11-03 20:19:04 +03:00
AUTOMATIC1111
21d561885e
Merge pull request #13762 from wkpark/nextjob
call state.jobnext() before postproces*()
2023-11-03 20:16:58 +03:00
AUTOMATIC1111
73c74baa6a
Merge pull request #13797 from Meerkov/master
Fix #13796
2023-11-03 20:11:54 +03:00
AUTOMATIC1111
1f373a2baa
Merge pull request #13829 from AUTOMATIC1111/paren-fix
Fix parenthesis auto selection
2023-11-03 19:59:01 +03:00
AUTOMATIC1111
4afaaf8a02 add changelog entry 2023-11-03 19:50:14 +03:00
AUTOMATIC1111
bda2ecdbf5 Merge pull request #13839 from AUTOMATIC1111/httpx==0.24.1
requirements_versions httpx==0.24.1
2023-11-03 19:46:07 +03:00
AUTOMATIC1111
4c423f6d37
Merge pull request #13839 from AUTOMATIC1111/httpx==0.24.1
requirements_versions httpx==0.24.1
2023-11-03 19:44:57 +03:00
w-e-w
cc80a09d82 Update requirements_versions.txt 2023-11-04 00:50:30 +09:00
missionfloyd
8052a4971e Fix parenthesis auto selection
Fixes #13813
2023-11-03 00:59:19 -06:00
Emily Zeng
759515316e added accordion settings options 2023-11-02 21:54:48 -04:00
v0xie
d727ddfccd no idea what i'm doing, trying to support both type of OFT, kblueleaf diag_oft has MultiheadAttn which kohya's doesn't?, attempt create new module based off network_lora.py, errors about tensor dim mismatch 2023-11-02 00:13:11 -07:00
v0xie
65ccd6305f detect diag_oft type 2023-11-02 00:11:32 -07:00
v0xie
a2fad6ee05 test implementation based on kohaku diag-oft implementation 2023-11-01 22:34:27 -07:00
Meerkov
fbc5c531b9 Fix #13796
Fix comment error that makes understanding scheduling more confusing.
2023-10-29 15:37:08 -07:00
Nick Harrison
be31e7e71a
Remove blank line whitespace 2023-10-29 16:05:01 +00:00
Nick Harrison
844c23975f
Add assertions for checking additional settings freezing parameters 2023-10-29 15:40:58 +00:00
Nick Harrison
f2b83517aa
Add new arguments to known command prompts 2023-10-29 15:40:13 +00:00
KohakuBlueleaf
ddc2a3499b Add MPS manual cast 2023-10-28 16:52:35 +08:00
Kohaku-Blueleaf
d4d3134f6d ManualCast for 10/16 series gpu 2023-10-28 15:24:26 +08:00
Won-Kyu Park
5121846d34
call state.jobnext() before postproces*() 2023-10-25 21:57:41 +09:00
Kohaku-Blueleaf
0beb131c7f change torch version 2023-10-25 20:07:37 +08:00
Kohaku-Blueleaf
dda067f64d ignore mps for fp8 2023-10-25 19:53:22 +08:00
Kohaku-Blueleaf
bf5067f50c Fix alphas cumprod 2023-10-25 12:54:28 +08:00
Kohaku-Blueleaf
4830b25136 Fix alphas_cumprod dtype 2023-10-25 11:53:37 +08:00
Kohaku-Blueleaf
1df6c8bfec fp8 for TE 2023-10-25 11:36:43 +08:00
Kohaku-Blueleaf
9c1eba2af3 Fix lint 2023-10-24 02:11:27 +08:00
Kohaku-Blueleaf
eaa9f5162f Add CPU fp8 support
Since norm layer need fp32, I only convert the linear operation layer(conv2d/linear)

And TE have some pytorch function not support bf16 amp in CPU. I add a condition to indicate if the autocast is for unet.
2023-10-24 01:49:05 +08:00
David Benson
dfc4c27b24
linting issue 2023-10-23 08:26:40 -04:00
David Benson
88b2ef3b04
Update prompts_from_file script to allow concatenating entries with the general prompt. 2023-10-23 08:16:26 -04:00
v0xie
6523edb8a4 style: conform style 2023-10-22 09:31:15 -07:00
v0xie
3b8515d2c9 fix: multiplier applied twice in finalize_updown 2023-10-22 09:27:48 -07:00
v0xie
4a50c9638c refactor: remove used OFT functions 2023-10-22 08:54:24 -07:00
v0xie
de8ee92ed8 fix: use merge_weight to cache value 2023-10-21 17:37:17 -07:00
v0xie
76f5abdbdb style: cleanup oft 2023-10-21 16:07:45 -07:00
v0xie
fce86ab7d7 fix: support multiplier, no forward pass hook 2023-10-21 16:03:54 -07:00
v0xie
7683547728 fix: return orig weights during updown, merge weights before forward 2023-10-21 14:42:24 -07:00
v0xie
2d8c894b27 refactor: use forward hook instead of custom forward 2023-10-21 13:43:31 -07:00
avantcontra
236dd55dbe fix Blank line contains whitespace 2023-10-22 04:32:13 +08:00
avantcontra
443ca983ad fix bug when using --gfpgan-models-path 2023-10-22 03:21:23 +08:00
AUTOMATIC1111
464fbcd921 fix the situation with emphasis editing (aaaa:1.1) bbbb (cccc:1.1) 2023-10-21 09:09:32 +03:00
AUTOMATIC1111
384fab9627 rework some of changes for emphasis editing keys, force conversion of old-style emphasis 2023-10-21 08:45:51 +03:00
v0xie
0550659ce6 style: fix ambiguous variable name 2023-10-19 13:13:02 -07:00
v0xie
d10c4db57e style: formatting 2023-10-19 12:52:14 -07:00
v0xie
321680ccd0 refactor: fix constraint, re-use get_weight 2023-10-19 12:41:17 -07:00
Kohaku-Blueleaf
5f9ddfa46f Add sdxl only arg 2023-10-19 23:57:22 +08:00
Kohaku-Blueleaf
7c128bbdac Add fp8 for sd unet 2023-10-19 13:56:17 +08:00
v0xie
eb01d7f0e0 faster by calculating R in updown and using cached R in forward 2023-10-18 04:56:53 -07:00
v0xie
853e21d98e faster by using cached R in forward 2023-10-18 04:27:44 -07:00
v0xie
1c6efdbba7 inference working but SLOW 2023-10-18 04:16:01 -07:00
v0xie
ec718f76b5 wip incorrect OFT implementation 2023-10-17 23:35:50 -07:00
Anthony Fu
3d15e58b0a feat: refactor 2023-10-16 15:00:17 +08:00
Anthony Fu
8aa13d5dce Interrupt after current generation 2023-10-16 14:12:18 +08:00
AUTOMATIC1111
861cbd5636
Merge pull request #13644 from XpucT/dev
Start / Restart generation by Ctrl (Alt) + Enter
2023-10-15 14:19:48 +03:00
Khachatur Avanesian
d33cb2b812
Add files via upload
LF
2023-10-15 11:01:45 +03:00
Khachatur Avanesian
3e223523ce
Update script.js 2023-10-15 10:48:50 +03:00
Khachatur Avanesian
d295e97a0d
Update script.js
LF instead CRLF
2023-10-15 10:37:48 +03:00
Khachatur Avanesian
77bd953da2
Update script.js
Exclude lambda
2023-10-15 10:25:36 +03:00
AUTOMATIC1111
2f6ea8b103 respect keyedit_precision_attention setting when converting from old (((attention))) syntax 2023-10-15 10:12:38 +03:00
AUTOMATIC1111
a3d9b011a3
Merge pull request #13533 from missionfloyd/edit-attention-fix
Edit-attention fixes
2023-10-15 10:08:52 +03:00
AUTOMATIC1111
282903bb67 repair unload sd checkpoint button 2023-10-15 09:41:02 +03:00
AUTOMATIC1111
0d65d0eabd add an option to not print stack traces on ctrl+c. 2023-10-15 08:45:38 +03:00
Khachatur Avanesian
f00eaa4d00
Start / Restart generation by Ctrl (Alt) + Enter
Add ability to interrupt current generation and start generation again by Ctrl (Alt) + Enter
2023-10-15 02:34:03 +03:00
AUTOMATIC1111
d4255506ff
Merge pull request #13638 from wkpark/user-settings-2
webui.settings.bat support
2023-10-14 23:00:35 +03:00
Won-Kyu Park
117ec71994
support webui.settings.bat 2023-10-15 04:36:27 +09:00
AUTOMATIC1111
4be7b620c2
Merge pull request #13568 from AUTOMATIC1111/lora_emb_bundle
Add lora-embedding bundle system
2023-10-14 12:18:55 +03:00
AUTOMATIC1111
a8cbe50c9f remove duplicated code 2023-10-14 12:17:59 +03:00
AUTOMATIC1111
19f5795c27
Merge pull request #13463 from FluttyProger/patch-1
Ability for extensions to return custom data via api in response.images
2023-10-14 08:37:45 +03:00
AUTOMATIC1111
6fe16a9e1a
Merge pull request #12991 from AUTOMATIC1111/but-report-template
Update bug_report.yml
2023-10-14 08:36:43 +03:00
AUTOMATIC1111
eadef35512
Merge pull request #13567 from LeonZhao28/bugfix_key_error_in_processing
fix the key error exception when processing override_settings keys
2023-10-14 08:34:41 +03:00
AUTOMATIC1111
771dac9c5f
Merge pull request #13459 from wkpark/preview-fix
show the preview image in the modalview if available
2023-10-14 08:21:53 +03:00
AUTOMATIC1111
0619df9835 use shallow copy for #13535 2023-10-14 08:01:04 +03:00
AUTOMATIC1111
7cc96429f2
Merge pull request #13535 from chu8129/dev
fix: checkpoints_loaded:{checkpoint:state_dict}, model.load_state_dict issue in dict value empty
2023-10-14 08:00:04 +03:00
AUTOMATIC1111
26500b8c1b
Merge pull request #13610 from v0xie/network-glora
Support inference with LyCORIS GLora networks
2023-10-14 07:52:52 +03:00
AUTOMATIC1111
a109c7aeb8 more general case of adding an infotext when no images have been generated 2023-10-14 07:49:03 +03:00
AUTOMATIC1111
27fdc26a74
Merge pull request #13630 from wkpark/indexerror-fix
fix IndexError
2023-10-14 07:46:34 +03:00
AUTOMATIC1111
3a66c3c9e1 put notification.mp3 option at the end of the page 2023-10-14 07:35:06 +03:00
AUTOMATIC1111
499543cf1d
Merge pull request #13631 from galekseev/master
added option to play notification sound or not
2023-10-14 07:30:31 +03:00
AUTOMATIC1111
902afa6b4c
Merge pull request #13364 from superhero-7/master
Add altdiffusion-m18 support
2023-10-14 07:29:01 +03:00
missionfloyd
fff1a0c74f Make attention conversion optional
Fix square brackets multiplier
2023-10-13 17:18:02 -06:00
missionfloyd
954499a494 Convert (emphasis) to (emphasis:1.1)
per @SirVeggie's suggestion
2023-10-13 16:46:05 -06:00
Gleb Alekseev
44d14bc32e added option to play notification sound or not 2023-10-13 15:08:59 -03:00
Won-Kyu Park
fbc8d21354
fix IndexError: list index out of range error interrupted while postprocess 2023-10-14 02:45:09 +09:00
v0xie
906d1179e9 support inference with LyCORIS GLora networks 2023-10-11 21:26:58 -07:00
Won-Kyu Park
dbb10fbd8c
show the preview image in the modalview if available 2023-10-11 21:56:17 +09:00
Kohaku-Blueleaf
891ccb767c Fix lint 2023-10-10 15:07:25 +08:00
Kohaku-Blueleaf
81e94de318 Add warning when meet emb name conflicting
Choose standalone embedding (in /embeddings folder) first
2023-10-10 14:44:20 +08:00
Kohaku-Blueleaf
2282eb8dd5 Remove dev debug print 2023-10-10 12:11:00 +08:00
Kohaku-Blueleaf
3d8b1af6be Support string_to_param nested dict
format:
bundle_emb.EMBNAME.string_to_param.KEYNAME
2023-10-10 12:09:33 +08:00
Kohaku-Blueleaf
2aa485b5af add lora bundle system 2023-10-09 22:52:09 +08:00
Leon
9821625a76 fix the key error exception when adding an overwriting key which is defined in the extensions 2023-10-09 18:36:48 +08:00
missionfloyd
3562b0dc74 Fix negative values 2023-10-07 15:52:16 -06:00
missionfloyd
fd51b8501e Fix multi-line selections 2023-10-07 15:28:25 -06:00
missionfloyd
09a2da835e Add brackets, vertical bar to default delimiters 2023-10-07 14:48:43 -06:00
wangqiuwen
770ee23f18 reverst 2023-10-07 15:38:50 +08:00
wangqiuwen
76010a51ef up 2023-10-07 15:36:01 +08:00
missionfloyd
e34949be52 Edit-attention fixes 2023-10-06 22:49:33 -06:00
w-e-w
35fd24e857
Less placeholder bug_report template 2023-10-03 23:05:48 +09:00
AUTOMATIC1111
7d60076b8b case-insensitive search for settings 2023-10-03 16:22:32 +03:00
AUTOMATIC1111
77171923f8
Merge pull request #13475 from wkpark/regress-fix
fix regression
2023-10-03 12:38:11 +03:00
AUTOMATIC1111
c4ffeb857e
Merge pull request #13480 from AUTOMATIC1111/popup-fix
Fix accidentally closing popup dialogs
2023-10-03 12:37:46 +03:00
missionfloyd
e5381320b9 Lint 2023-10-02 22:33:03 -06:00
missionfloyd
86a46e8189 Fix accidentally closing popup dialogs 2023-10-02 22:22:15 -06:00
Won-Kyu Park
c2279da522
fix re_param_code (regression bug PR #13458) 2023-10-03 01:16:41 +09:00
AUTOMATIC1111
dc2074c46d
Merge pull request #13466 from AUTOMATIC1111/denoising-none
Change denoising_strength default to None.
2023-10-02 13:05:27 +03:00
AUTOMATIC1111
362675e75b
Merge pull request #13469 from PermissionDenied7335/master
I found a code snippet in webui.sh that disables python venv and moved it to the appropriate location
2023-10-02 12:47:02 +03:00
PermissionDenied7335
6ab0b65ed1 Added an option not to enable venv 2023-10-02 15:43:59 +08:00
missionfloyd
3f763d41e8
Change denoising_strength default to None. 2023-10-01 22:38:27 -06:00
FluttyProger
f71e919ecb
Ability for extensions to return custom data via api in response.images 2023-10-01 18:06:48 +03:00
AUTOMATIC1111
e3c849da06
Merge pull request #13458 from wkpark/fieldname-regex
fix fieldname regex
2023-10-01 11:49:42 +03:00
AUTOMATIC1111
c0113872c5 add search field to settings 2023-10-01 11:48:41 +03:00
Won-Kyu Park
deeec0b343
fix fieldname regex to accept additional [-/] chars 2023-10-01 16:19:59 +09:00
AUTOMATIC1111
c7e810a985 add onEdit function for js and rework token-counter.js to use it 2023-10-01 10:15:23 +03:00
superhero-7
2d947175b9 fix linter issues 2023-10-01 12:25:19 +08:00
AUTOMATIC1111
7026b96476
Merge pull request #13444 from AUTOMATIC1111/edit-attn-delimiters
edit-attention: Allow editing whitespace delimiters
2023-10-01 07:04:08 +03:00
missionfloyd
56ef5e9d48 Remove end parenthesis from weight 2023-09-30 21:44:05 -06:00
missionfloyd
0eb5fde2fd Remove unneeded code 2023-09-30 21:20:58 -06:00
missionfloyd
0935d2c304 Use checkboxes for whitespace delimiters 2023-09-30 18:37:44 -06:00
AUTOMATIC1111
b2f9709538 get #13121 to work without restart 2023-09-30 10:29:10 +03:00
AUTOMATIC1111
5cc7bf3876 reword sd_checkpoint_dropdown_use_short setting and add explanation 2023-09-30 10:10:57 +03:00
AUTOMATIC1111
416fbde726
Merge pull request #13121 from AUTOMATIC1111/consolidated-allowed-preview-formats
Consolidated allowed preview formats, Fix extra network `.gif` not woking as preview
2023-09-30 10:09:45 +03:00
missionfloyd
1cc7c4bfb3 Allow editing whitespace delimiters 2023-09-30 01:09:09 -06:00
AUTOMATIC1111
951842d785
Merge pull request #13139 from AUTOMATIC1111/ckpt-dir-path-separator
fix `--ckpt-dir` path separator and option use `short name` for checkpoint dropdown
2023-09-30 10:02:28 +03:00
AUTOMATIC1111
591ad1dbc3
Merge pull request #13170 from AUTOMATIC1111/re-fix-batch-img2img-output-dir-with-script
Re fix batch img2img output dir with script
2023-09-30 09:59:21 +03:00
AUTOMATIC1111
fcfe5c179b
Merge pull request #12877 from zixaphir/removeExtraNetworksFromPrompt_fix
account for customizable extra network separators in remove code
2023-09-30 09:49:37 +03:00
AUTOMATIC1111
a0e979badb
Merge pull request #13178 from wpdong0727/fix-lora-bias-backup-reset
fix: lora-bias-backup don't reset cache
2023-09-30 09:48:38 +03:00
AUTOMATIC1111
3aa9f01bdc
Merge pull request #13077 from sdwebui-extensions/master
fix localization when there are multi same localization file in the extensions
2023-09-30 09:47:52 +03:00
AUTOMATIC1111
4e5d2526cb
Merge pull request #13189 from AUTOMATIC1111/make-InputAccordion-work-with-ui-config
make InputAccordion work with ui-config
2023-09-30 09:46:55 +03:00
AUTOMATIC1111
ab63054f95 write infotext to gif image as comment 2023-09-30 09:34:50 +03:00
AUTOMATIC1111
0c71967a53
Merge pull request #13068 from JaredTherriault/master
Load comments from gif images to gather geninfo from gif outputs
2023-09-30 09:33:14 +03:00
AUTOMATIC1111
b20cd352d9
Merge pull request #13210 from AUTOMATIC1111/fetch-version-info-when-webui_dir-is-not-work_dir-
fix issues when webui_dir is not work_dir
2023-09-30 09:23:32 +03:00
AUTOMATIC1111
3a4290f833
Merge pull request #13229 from AUTOMATIC1111/initialize-state.time_start-befroe-state.job_count
initialize state.time_start befroe state.job_count
2023-09-30 09:21:47 +03:00
AUTOMATIC1111
df48222f3e
Merge pull request #13231 from der3318/better-support-for-portable-git
Better Support for Portable Git
2023-09-30 09:21:08 +03:00
AUTOMATIC1111
ee8e98711b
Merge pull request #13266 from wkpark/xyz-prepare
xyz_grid: add prepare
2023-09-30 09:17:24 +03:00
AUTOMATIC1111
87b50397a6 add missing import, simplify code, use patches module for #13276 2023-09-30 09:11:31 +03:00
AUTOMATIC1111
e309583f29
Merge pull request #13276 from woweenie/patch-1
patch DDPM.register_betas so that users can put given_betas in model yaml
2023-09-30 09:01:12 +03:00
AUTOMATIC1111
7ce1f3a142
Merge pull request #13281 from AUTOMATIC1111/Config-states-time-ISO-in-system-time-zone
Config states time ISO in system time zone
2023-09-30 08:59:28 +03:00
AUTOMATIC1111
db63cf7d24
Merge pull request #13282 from AUTOMATIC1111/XYZ-if-not-Include-Sub-Grids-do-not-save-Sub-Grid
XYZ if not include sub grids do not save sub grid
2023-09-30 08:58:07 +03:00
AUTOMATIC1111
cdafbcaad2
Merge pull request #13313 from chu8129/dev
use orderdict as lru cache:opt/bug
2023-09-30 08:55:54 +03:00
AUTOMATIC1111
34055f9d0c
Merge pull request #13302 from Zolxys/patch-1
Fix: --sd_model in "Prompts from file or textbox" script is not working
2023-09-30 08:49:26 +03:00
AUTOMATIC1111
9b17416580
Merge pull request #13372 from ezt19/patch-1
Update dragdrop.js
2023-09-30 08:46:48 +03:00
AUTOMATIC1111
833b9b62b5
Merge pull request #13395 from AUTOMATIC1111/escape-names
Fix viewing/editing metadata when filename contains an apostrophe
2023-09-30 08:32:38 +03:00
AUTOMATIC1111
3b0be0f12f
Merge pull request #13411 from AUTOMATIC1111/update-card-metadata
Update card on correct tab when editing metadata
2023-09-30 08:32:07 +03:00
AUTOMATIC1111
4083639c3c
Merge pull request #13418 from akx/torchsde-bump
Bump to torchsde==0.2.6
2023-09-30 08:31:30 +03:00
AUTOMATIC1111
8a758383d2
Merge pull request #13412 from AUTOMATIC1111/data-sort-name-fix
Fix data-sort-name containing spaces
2023-09-30 08:24:37 +03:00
AUTOMATIC1111
ad3b8a1c41 alternative solution to #13434 2023-09-30 08:23:12 +03:00
AUTOMATIC1111
1b9ca01e4f
Merge pull request #13253 from LeonZhao28/feature_skip_load_model_at_start
add --skip-load-model-at-start
2023-09-30 08:15:00 +03:00
Aarni Koskela
30f4f25b2e Bump to torchsde==0.2.6 2023-09-27 10:21:14 +03:00
missionfloyd
a69daae012 Fix data-sort-name containing spaces 2023-09-26 22:02:52 -06:00
missionfloyd
99aa702015 Update card on correct tab 2023-09-26 21:08:55 -06:00
missionfloyd
d00f6dca28
Escape item names 2023-09-25 22:08:24 -06:00
ezt19
fdecf813b6
Update dragdrop.js
Fixing a problem when u cannot put two images and they are going into two different places for images.
2023-09-23 20:41:28 +00:00
superhero-7
f8f4ff2bb8 support altdiffusion-m18 2023-09-23 17:55:19 +08:00
superhero-7
702a1e1cc7 support m18 2023-09-23 17:51:41 +08:00
王秋文/qwwang
8e355fbd75 fix 2023-09-18 16:45:42 +08:00
Zolxys
701feabf49
Fix: --sd_model in "Promts from file or textbox" script is not working
Fix for bug report #8079
2023-09-17 11:37:15 -05:00
w-e-w
d2878a8b0b XYZ if not Include Sub Grids do not save Sub Grid 2023-09-16 09:54:14 +09:00
w-e-w
663fb87976 Config states time ISO in system time zone 2023-09-16 09:11:54 +09:00
woweenie
d9d94141dc
patch DDPM.register_betas so that users can put given_betas in model yaml 2023-09-15 18:59:44 +02:00
qiuwen.wang
813535d38b
use dict[key]=model; did not update orderdict order, should use move to end 2023-09-15 18:23:23 +08:00
Won-Kyu Park
afd0624587
xyz_grid: add prepare option to AxisOption 2023-09-15 17:30:36 +09:00
Leon
ab3d3528a1 add --skip-load-model-at-start 2023-09-14 18:42:56 +08:00
Der Chien
0ad38a9b87 20230913 setup GIT_PYTHON_GIT_EXECUTABLE for GitPython 2023-09-13 20:20:01 +08:00
w-e-w
cf1edc2b54 initialize state.time_start befroe state.job_count 2023-09-13 16:27:02 +09:00
w-e-w
5b761b49ad correct webpath when webui_dir is not work_dir 2023-09-13 16:05:55 +09:00
AUTOMATIC1111
102b6617da
Merge pull request #13213 from AUTOMATIC1111/fix-add_option-overriding-config-with-default
Fix major issue add_option overriding config with default
2023-09-12 17:50:44 +03:00
w-e-w
93015964c7 fix add_option overriding config with default 2023-09-12 22:53:09 +09:00
w-e-w
6fb2194d9c fetch version info when webui_dir is not work_dir 2023-09-12 16:50:56 +09:00
w-e-w
74b80e7211 add comment 2023-09-12 09:29:07 +09:00
AUTOMATIC1111
59544321aa initial work on sd_unet for SDXL 2023-09-11 21:17:40 +03:00
w-e-w
e785402b6a return nothing if not found 2023-09-11 19:37:55 +09:00
w-e-w
c485a7d12e make InputAccordion work with ui-config 2023-09-11 13:47:44 +09:00
liubo0902
413123f08a
Update localization.py 2023-09-11 09:22:27 +08:00
dongwenpu
7d4d871d46 fix: lora-bias-backup don't reset cache 2023-09-10 17:53:42 +08:00
zixaphir
26d0d87f5b Remove extra spaces 2023-09-09 17:26:46 -07:00
zixaphir
d6478a60aa Remove extra network separator without regex 2023-09-09 17:22:10 -07:00
w-e-w
ab57417175 prevent accessing non-existing keys 2023-09-09 22:35:50 +09:00
w-e-w
f8042cb323 Ensure not override images with script enabled 2023-09-09 22:35:07 +09:00
w-e-w
f5959c1c30 thread safe extra network using list 2023-09-09 17:05:50 +09:00
w-e-w
25de9a785c Revert "thread safe extra network list_items"
This reverts commit aab385d01b4311726127397552d791f4d71b7147.
2023-09-09 16:56:19 +09:00
AUTOMATIC1111
924642331b
Merge pull request #12846 from a666/deprecated-types
Fix some deprecated types
2023-09-09 10:31:56 +03:00
AUTOMATIC1111
c9c457eda8 stylistic changes for #13118 2023-09-09 10:27:16 +03:00
AUTOMATIC1111
73c2a03d49
Merge pull request #13118 from ljleb/fix-counter
Don't use multicond parser for negative prompt counter
2023-09-09 10:24:07 +03:00
AUTOMATIC1111
06af73bd1d linter 2023-09-09 10:23:53 +03:00
AUTOMATIC1111
9cebe308e9 return apply styles to main UI 2023-09-09 10:20:06 +03:00
AUTOMATIC1111
558808c748
Merge pull request #13119 from AUTOMATIC1111/enable_console_prompts-in-settings
enable console prompts in settings
2023-09-09 10:02:02 +03:00
w-e-w
c68aabc852 lint 2023-09-09 15:59:22 +09:00
w-e-w
46ef185709 deprecate --enable-console-prompts
use --enable-console-prompts as the default value for shared.opts.enable_console_prompts
2023-09-09 15:53:10 +09:00
AUTOMATIC1111
46375f0592 fix for crash when running #12924 without --device-id 2023-09-09 09:39:37 +03:00
AUTOMATIC1111
558baffa2c
Merge pull request #12924 from catboxanon/fix/cudnn
More accurate check for enabling cuDNN benchmark on 16XX cards
2023-09-09 09:33:37 +03:00
AUTOMATIC1111
4ebed495ed
Merge pull request #12880 from AUTOMATIC1111/dropdown-padding-mobile
Use default dropdown padding on mobile
2023-09-09 09:29:42 +03:00
AUTOMATIC1111
e6d41b54cd
Merge pull request #12976 from AUTOMATIC1111/toolbutton-tooltips
Restore missing tooltips
2023-09-09 09:29:11 +03:00
AUTOMATIC1111
e06c16e884
Merge pull request #12957 from AnyISalIn/dev
fix: update shared.opts.data when add_option
2023-09-09 09:28:33 +03:00
AUTOMATIC1111
72bc69e741
Merge pull request #12986 from AUTOMATIC1111/update-cmd-arg-description
update cmd arg description
2023-09-09 09:26:29 +03:00
AUTOMATIC1111
b33ffc11aa
Merge pull request #12975 from AUTOMATIC1111/styles-copy-prompt
Add button to copy prompt to style editor
2023-09-09 09:26:03 +03:00
AUTOMATIC1111
0a2c24003c
Merge pull request #12995 from uservar/patch-2
Fix bug with sigma min/max overrides.
2023-09-09 09:25:21 +03:00
AUTOMATIC1111
9e58e11ad4
Merge pull request #13028 from AUTOMATIC1111/fallback-invalid-exif
Add Fallback at images.read_info_from_image if exif data was invalid
2023-09-09 09:21:18 +03:00
AUTOMATIC1111
4c4d7dd01f fix whitespace for #13084 2023-09-09 09:15:09 +03:00
AUTOMATIC1111
adb3f2bcdd
Merge pull request #13084 from AUTOMATIC1111/fix-preview-while-generation
Fix #13080 - Hypernetwork/TI preview generation
2023-09-09 09:14:01 +03:00
AUTOMATIC1111
8afabae67d
Merge pull request #12929 from Beinsezii/dev
WEBUI.SH - Use torch 2.1.0 release candidate for Navi 3
2023-09-09 09:10:07 +03:00
AUTOMATIC1111
fccde0c1f7
Merge pull request #12909 from AUTOMATIC1111/Action-to-calculate-all-SD-checkpoint-hashes
Action to calculate all SD checkpoint hashes
2023-09-09 09:09:29 +03:00
AUTOMATIC1111
3ca4655a18 update for #12926 2023-09-09 09:08:31 +03:00
ljleb
349f893024 Merge branch 'dev' of https://github.com/AUTOMATIC1111/stable-diffusion-webui into fix-counter 2023-09-09 02:06:04 -04:00
ljleb
7b44b85730 refact 2023-09-09 02:01:12 -04:00
AUTOMATIC1111
329c8ab932
Merge pull request #12926 from AUTOMATIC1111/fix-batch-img2img-output-dir-with-script
fix batch img2img output dir with script
2023-09-09 08:56:32 +03:00
AUTOMATIC1111
259768f27f fix the bug in script-info API 2023-09-09 08:38:49 +03:00
AUTOMATIC1111
741e8ecb7d
Merge pull request #13135 from ibrainventures/patch-2
(feat) Include Program Version in info response. Update processing.py
2023-09-09 08:18:51 +03:00
w-e-w
63485b2c55 option use short name for checkpoint dropdown 2023-09-08 10:00:27 +09:00
w-e-w
e4726cccf9 parsing string to path 2023-09-08 09:46:34 +09:00
ibrainventures
f11eec81e3
(feat) Include Program Version in info response. Update processing.py
This would help to organize / memorize the program version for the creation process. (as it is also unformated included inside the infotext).
2023-09-07 23:19:52 +02:00
w-e-w
c3d51fc696
Update bug_report.yml 2023-09-07 19:35:55 +09:00
w-e-w
45881703c5 consolidated allowed preview formats 2023-09-07 12:11:36 +09:00
w-e-w
340fce2113 enable console prompts in settings 2023-09-07 10:01:16 +09:00
w-e-w
657404b75b use original filename batch img2img with scripts 2023-09-06 20:33:43 +09:00
w-e-w
35d1c94549 save_images_add_number_suffix 2023-09-06 20:24:26 +09:00
catboxanon
25189b29af Grammar fixes 2023-09-05 22:13:36 -04:00
AngelBottomless
47033afa5c
Fix preview for textual inversion training 2023-09-05 22:38:02 +09:00
AngelBottomless
de5bb4ca88
Fix #13080 - Hypernetwork/TI preview generation
Fixes sampler name reference

Same patch will be done for TI.
2023-09-05 22:35:17 +09:00
liubo0902
ff7027ffc0
Update localization.py 2023-09-05 15:08:59 +08:00
liubo0902
0c1c9e74cd
Update localization.py 2023-09-05 15:06:47 +08:00
JaredTherriault
022639a145
Load comments from gif images to gather geninfo from gif outputs 2023-09-04 17:37:48 -07:00
JaredTherriault
5e16914a4e
Merge branch 'AUTOMATIC1111:master' into master 2023-09-04 17:29:33 -07:00
JaredTherriault
8f3b02f095
Revert "Offloading custom work"
This reverts commit f3d1631aab82d559294126a9230c979ef4c4e1d6.

This work has been offloaded now into an extension called Prompt Control.
2023-09-03 13:32:56 -07:00
AngelBottomless
f593cbfec4
fallback if exif data was invalid 2023-09-03 21:07:36 +09:00
w-e-w
aab385d01b thread safe extra network list_items 2023-09-03 11:56:02 +09:00
uservar
a51721cb09
Fix bug with sigma min/max overrides. 2023-09-02 11:35:30 +00:00
w-e-w
061a4a295d Update bug_report.yml 2023-09-02 18:11:08 +09:00
w-e-w
ba05e32789 update cmd arg description 2023-09-02 14:12:59 +09:00
missionfloyd
3e67017dfb Restore missing tooltips 2023-09-01 17:01:08 -06:00
missionfloyd
d7e3ea68b3 Remove whitespace 2023-09-01 16:24:35 -06:00
missionfloyd
bf0b083216 Add button to copy prompt to style editor 2023-09-01 16:14:33 -06:00
AnyISalIn
317d00b2a6 fix: update shared.opts.data when add_option
Signed-off-by: AnyISalIn <anyisalin@gmail.com>
2023-09-01 21:56:17 +08:00
Beinsezii
737a013377 WEBUI.SH Navi 3 torch 2.1.0 rc instead of nightly
With the release candidates being out for both torch and vision,
webui should default to these over nightly for a more stable experience.

Stable release isn't excpected until October 4th:
https://dev-discuss.pytorch.org/c/release-announcements/27
2023-08-31 15:03:08 -07:00
zixaphir
78c1a74660 Account for edge case where user deleted leading separator. 2023-08-31 14:18:35 -07:00
w-e-w
bd9b3d15e8 fix batch img2img output dir with script 2023-09-01 04:05:58 +09:00
catboxanon
5681bf8016 More accurate check for enabling cuDNN benchmark on 16XX cards 2023-08-31 14:57:16 -04:00
w-e-w
348c6022f3 Action to calculate all SD checkpoint hashes 2023-09-01 00:56:55 +09:00
missionfloyd
76b1ad7daf
Use default dropdown padding on mobile 2023-08-30 23:07:18 -06:00
AUTOMATIC1111
d39440bfb9 Merge branch 'master' into dev 2023-08-31 07:39:14 +03:00
AUTOMATIC1111
5ef669de08 Merge branch 'release_candidate' 2023-08-31 07:38:34 +03:00
AUTOMATIC1111
20158d77d9 Merge branch 'release_candidate' into dev 2023-08-31 07:37:36 +03:00
AUTOMATIC1111
e7965a5eb8 Merge pull request #12876 from ljleb/fix-re
Fix generation params regex
2023-08-31 07:34:01 +03:00
AUTOMATIC1111
3bff988f1e
Merge pull request #12876 from ljleb/fix-re
Fix generation params regex
2023-08-31 07:30:03 +03:00
zixaphir
41196ccbf7 account for customizable extra network separators in remove code
previous behavior only searched for leading spaces
2023-08-30 20:20:19 -07:00
ljleb
541a3db05b fix generation params regex 2023-08-30 21:38:21 -04:00
AUTOMATIC1111
ae7291fb49 fix an issue where using hires fix with refiner on first pass with medvram would cause an exception when generating 2023-08-30 21:34:17 +03:00
AUTOMATIC1111
d43333ff71 fix an issue where VAE would remain in fp16 after an auto-switch to fp32 2023-08-30 21:13:24 +03:00
AUTOMATIC1111
0cdbd90d6b update bug report template to include sysinfo and not include all other fields that are already covered by sysinfo 2023-08-30 19:50:47 +03:00
AUTOMATIC1111
d0026da483 add --dump-sysinfo, a cmd arg to dump limited sysinfo file at startup 2023-08-30 19:48:47 +03:00
AUTOMATIC1111
8d54739de5 add information about Restore faces and Tiling into the changelog 2023-08-30 19:17:27 +03:00
AUTOMATIC1111
135b61bc0b fix inpainting models in txt2img creating black pictures 2023-08-30 19:08:17 +03:00
AUTOMATIC1111
6adf2b71c2 fix inpainting models in txt2img creating black pictures 2023-08-30 19:08:04 +03:00
AUTOMATIC1111
87cca029d7 add an option to choose how to combine hires fix and refiner 2023-08-30 18:24:21 +03:00
AUTOMATIC1111
ae0b2cc196 add an option to choose how to combine hires fix and refiner 2023-08-30 18:22:50 +03:00
AUTOMATIC1111
1ac11b3dae Merge pull request #12865 from AUTOMATIC1111/another-convert-to-system-time-zone
extension update time, convert to system time zone
2023-08-30 11:00:38 +03:00
AUTOMATIC1111
0ff8b8fb54
Merge pull request #12865 from AUTOMATIC1111/another-convert-to-system-time-zone
extension update time, convert to system time zone
2023-08-30 11:00:29 +03:00
w-e-w
c985d23c52 extension update time, convert to system time zone 2023-08-30 16:18:31 +09:00
AUTOMATIC1111
87a083d1b2 Merge pull request #12864 from AUTOMATIC1111/extension-time-format-time-zone
patch Extension time format in systme time zone
2023-08-30 09:45:23 +03:00
AUTOMATIC1111
644b537014
Merge pull request #12864 from AUTOMATIC1111/extension-time-format-time-zone
patch Extension time format in systme time zone
2023-08-30 09:45:12 +03:00
w-e-w
67cd4ec0aa lint 2023-08-30 15:37:13 +09:00
w-e-w
28b084ca25 extension time format in system time zone 2023-08-30 15:28:46 +09:00
AUTOMATIC1111
503bd3fc0f keep order in list of checkpoints when loading model that doesn't have a checksum 2023-08-30 08:54:41 +03:00
AUTOMATIC1111
f874b1bcad keep order in list of checkpoints when loading model that doesn't have a checksum 2023-08-30 08:54:31 +03:00
AUTOMATIC1111
9e7de49fc5 update changelog 2023-08-30 08:28:46 +03:00
AUTOMATIC1111
06bc1f4f67 Merge pull request #12851 from bluelovers/pr/extension-time-001
chore: change extension time format
2023-08-30 08:24:08 +03:00
AUTOMATIC1111
338d0b6103 go back to single path for filenames in extra networks metadata dialog 2023-08-30 08:23:59 +03:00
AUTOMATIC1111
3989d7e88b Merge pull request #12838 from bluelovers/pr/file-metadata-path-001
display file metadata `path` , `ss_output_name`
2023-08-30 08:23:50 +03:00
AUTOMATIC1111
afea99a72b get progressbar to display correctly in extensions tab 2023-08-30 08:23:47 +03:00
AUTOMATIC1111
965c728914 Merge pull request #12839 from ibrainventures/patch-1
[RC 1.6.0 - zoom is partly hidden] Update style.css
2023-08-30 08:23:44 +03:00
AUTOMATIC1111
46f3ee9594 Merge pull request #12854 from catboxanon/fix/quicksettings-dropdown-unfocus
Do not change quicksettings dropdown option when value returned is `None`
2023-08-30 08:23:42 +03:00
AUTOMATIC1111
323dcadea2 Merge pull request #12855 from dhwz/dev
don't print empty lines
2023-08-30 08:23:40 +03:00
AUTOMATIC1111
642faa1f65 Merge pull request #12856 from catboxanon/extra-noise-noisy-latent
Add noisy latent to `ExtraNoiseParams` for callback
2023-08-30 08:23:37 +03:00
AUTOMATIC1111
d156d5bffd
Merge pull request #12851 from bluelovers/pr/extension-time-001
chore: change extension time format
2023-08-30 08:23:11 +03:00
AUTOMATIC1111
edf3ad5aed go back to single path for filenames in extra networks metadata dialog 2023-08-30 08:22:06 +03:00
AUTOMATIC1111
4aaae3dc65
Merge pull request #12838 from bluelovers/pr/file-metadata-path-001
display file metadata `path` , `ss_output_name`
2023-08-30 08:07:15 +03:00
AUTOMATIC1111
9a4a1aac81 get progressbar to display correctly in extensions tab 2023-08-30 08:05:18 +03:00
AUTOMATIC1111
ee373a737c
Merge pull request #12839 from ibrainventures/patch-1
[RC 1.6.0 - zoom is partly hidden] Update style.css
2023-08-30 07:43:38 +03:00
AUTOMATIC1111
9e248fb24e
Merge pull request #12854 from catboxanon/fix/quicksettings-dropdown-unfocus
Do not change quicksettings dropdown option when value returned is `None`
2023-08-30 07:41:46 +03:00
AUTOMATIC1111
08603378e8
Merge pull request #12855 from dhwz/dev
don't print empty lines
2023-08-30 07:27:45 +03:00
AUTOMATIC1111
834f4c7cd3
Merge pull request #12856 from catboxanon/extra-noise-noisy-latent
Add noisy latent to `ExtraNoiseParams` for callback
2023-08-30 07:27:13 +03:00
catboxanon
549b475be9 Add noisy latent to ExtraNoiseParams for callback 2023-08-29 14:22:04 -04:00
dhwz
7e5fcdaf69
don't print empty lines 2023-08-29 18:49:42 +02:00
catboxanon
e3939f3339 Do not change quicksettings value when value returned is None 2023-08-29 12:19:10 -04:00
bluelovers
cb2a4f2424 chore: change extension time format 2023-08-29 22:47:10 +08:00
bluelovers
f564d8ed2c refactor: refactor function 2023-08-29 22:11:18 +08:00
ibrainventures
ba7d0d225a
Update style.css 2023-08-29 15:31:01 +02:00
AUTOMATIC1111
04b90328c0 revert SGM noise multiplier change for img2img because it breaks hires fix 2023-08-29 15:38:33 +03:00
AUTOMATIC1111
a0af2852b6 revert SGM noise multiplier change for img2img because it breaks hires fix 2023-08-29 15:38:05 +03:00
a666
b6c1a1bbbf Fix some deprecated types 2023-08-29 00:54:57 -06:00
AUTOMATIC1111
00e393ce10 Merge pull request #12833 from catboxanon/fix/dont-print-blank-stdout
Don't print blank stdout in extension installers
2023-08-29 09:02:11 +03:00
AUTOMATIC1111
84d41e49b3
Merge pull request #12833 from catboxanon/fix/dont-print-blank-stdout
Don't print blank stdout in extension installers
2023-08-29 09:00:34 +03:00
AUTOMATIC1111
0c9282b84d Merge pull request #12832 from catboxanon/fix/skip-install-extensions
Honor `--skip-install` for extension installers
2023-08-29 08:58:10 +03:00
AUTOMATIC1111
18ba89863d
Merge pull request #12832 from catboxanon/fix/skip-install-extensions
Honor `--skip-install` for extension installers
2023-08-29 08:58:01 +03:00
AUTOMATIC1111
444f102964 Merge pull request #12834 from catboxanon/fix/notification-tab-switch
Fix notification not playing when built-in webui tab is inactive
2023-08-29 08:55:58 +03:00
AUTOMATIC1111
9e8464db1e
Merge pull request #12834 from catboxanon/fix/notification-tab-switch
Fix notification not playing when built-in webui tab is inactive
2023-08-29 08:55:45 +03:00
AUTOMATIC1111
738e133b24 Merge pull request #12818 from catboxanon/sgm
Add option to align with sgm repo's sampling implementation
2023-08-29 08:54:32 +03:00
AUTOMATIC1111
01a257eb07
Merge pull request #12818 from catboxanon/sgm
Add option to align with sgm repo's sampling implementation
2023-08-29 08:54:09 +03:00
AUTOMATIC1111
6558716018 Merge pull request #12837 from bluelovers/pr/file-metadata-break-001
style: file-metadata word-break
2023-08-29 08:53:37 +03:00
AUTOMATIC1111
9c87ae0d9d
Merge pull request #12837 from bluelovers/pr/file-metadata-break-001
style: file-metadata word-break
2023-08-29 08:52:58 +03:00
catboxanon
7ab16e99ee Add option to align with sgm repo sampling implementation 2023-08-29 01:51:13 -04:00
AUTOMATIC1111
8a7a4275a8 Merge pull request #12842 from dhwz/dev
remove xformers Python version check
2023-08-29 08:44:11 +03:00
AUTOMATIC1111
3269572753
Merge pull request #12842 from dhwz/dev
remove xformers Python version check
2023-08-29 08:32:48 +03:00
dhwz
5070ab8004
remove xformers Python version check 2023-08-29 07:16:32 +02:00
ibrainventures
02e7824e6a
[RC 1.6.1 - zoom is partly hidden] Update style.css
If a image / batch result image is higher or wider than the current viewport, and is zoomed (left corner zoom icon) it is cutted off  on the top and also to the left. This new rule seems to be the culprit.
2023-08-29 02:04:07 +02:00
bluelovers
d83a1ba65b feat: display file metadata ss_output_name
https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/12289
2023-08-29 06:33:00 +08:00
bluelovers
1bb21f3510 feat: display file metadata path
https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/12289
2023-08-29 06:25:16 +08:00
bluelovers
739686b1c5 style: file-metadata word-break 2023-08-29 06:19:22 +08:00
AUTOMATIC1111
c0f9821c35 always show NV as RNG source in infotext 2023-08-28 22:23:29 +03:00
AUTOMATIC1111
cd48308a2a always show NV as RNG source in infotext 2023-08-28 22:22:35 +03:00
catboxanon
592b0dcfa7 Fix notification not playing when built-in webui tab is inactive 2023-08-28 12:09:37 -04:00
catboxanon
20df81b0cc Honor --skip-install for extension installers 2023-08-28 11:26:50 -04:00
catboxanon
99acbd5ebe Don't print blank stdout in extension installers 2023-08-28 11:17:47 -04:00
AUTOMATIC1111
d1c93c3822
Merge pull request #12827 from omahs/patch-1
Fix minor typos
2023-08-28 15:04:07 +03:00
AUTOMATIC1111
9e14cac318
Merge branch 'dev' into patch-1 2023-08-28 15:03:46 +03:00
omahs
f898833ea3
fix typos 2023-08-28 10:43:13 +02:00
JaredTherriault
f3d1631aab
Offloading custom work
-custom_statics works to do mass replace strings, intended for copy-pasting gen info from internet generations and replacing unsavory prompts with safer prompts for my own sanity
-tried to implement this into generation_parameters_copypaste but it didn't work out this iteration, presumably because we return a string and the calling method is looking for an object type
-updated webui-user.bat to set a custom temp directory (for disk space concerns) and to apply xformers (for generation speed)

I probably won't be merging any of this work into the main repo since I don't want to mess with anyone else's prompts, this is just intended to keep my workspace safe from anything I don't want to see. Eventually this should be done in an extension which I could then publish, but I need to learn a lot more about the extension and callback systems in the main repo first. just uploading this to my fork for now so i don't lose the current progress.
2023-08-27 21:54:05 -07:00
AUTOMATIC1111
8632452627
Merge pull request #12815 from AUTOMATIC1111/consolidate-local-check
consolidate local check
2023-08-28 07:53:37 +03:00
AUTOMATIC1111
86708463f1 Merge pull request #12819 from catboxanon/fix/rng-infotext
Add missing infotext for RNG in options
2023-08-28 07:20:48 +03:00
AUTOMATIC1111
66146ed72b
Merge pull request #12819 from catboxanon/fix/rng-infotext
Add missing infotext for RNG in options
2023-08-28 07:20:33 +03:00
catboxanon
2b8484a29d Add missing infotext for RNG 2023-08-27 16:25:26 -04:00
w-e-w
18e3e6d6ab consolidate local check 2023-08-28 03:43:27 +09:00
AUTOMATIC1111
bfc5c08109 Merge pull request #12814 from AUTOMATIC1111/non-local-condition
non-local condition
2023-08-27 21:29:59 +03:00
AUTOMATIC1111
ad266d795e
Merge pull request #12814 from AUTOMATIC1111/non-local-condition
non-local condition
2023-08-27 21:29:48 +03:00
w-e-w
e422f19ee9 non-local condition 2023-08-28 03:27:07 +09:00
AUTOMATIC1111
d0d5075914 update changelog 2023-08-27 20:24:25 +03:00
AUTOMATIC1111
896fde789e hide --gradio-auth and --api-auth values from /internal/sysinfo report 2023-08-27 20:17:01 +03:00
AUTOMATIC1111
d63117ace5 hide --gradio-auth and --api-auth values from /internal/sysinfo report 2023-08-27 20:16:50 +03:00
AUTOMATIC1111
66d7630705 lint 2023-08-27 10:11:22 +03:00
AUTOMATIC1111
63d3150dc4 lint 2023-08-27 10:11:14 +03:00
AUTOMATIC1111
cb81087b59 update changelog 2023-08-27 09:45:12 +03:00
AUTOMATIC1111
6139b145f0 fix style editing dialog breaking if it's opened in both img2img and txt2img tabs 2023-08-27 09:45:08 +03:00
AUTOMATIC1111
f331821b27 Merge pull request #12780 from catboxanon/xyz-hide-samplers
Don't show hidden samplers in dropdown for XYZ script
2023-08-27 09:45:06 +03:00
AUTOMATIC1111
5359dc0a10 Merge pull request #12792 from catboxanon/image-cropper-hide
Hide broken image crop tool
2023-08-27 09:45:03 +03:00
AUTOMATIC1111
7989765faa Merge pull request #12797 from Madrawn/vae_resolve_bug
Small typo: vae resolve bug
2023-08-27 09:45:00 +03:00
AUTOMATIC1111
783a5754d5 Merge pull request #12795 from catboxanon/prevent-duplicate-resize-handler-mk2
Prevent duplicate resize handler
2023-08-27 09:44:56 +03:00
AUTOMATIC1111
897312de46 update changelog 2023-08-27 09:44:13 +03:00
AUTOMATIC1111
23c6b5f124 fix style editing dialog breaking if it's opened in both img2img and txt2img tabs 2023-08-27 09:39:49 +03:00
AUTOMATIC1111
c2463b5323
Merge pull request #12780 from catboxanon/xyz-hide-samplers
Don't show hidden samplers in dropdown for XYZ script
2023-08-27 09:28:12 +03:00
AUTOMATIC1111
ed2a05fc3f
Merge pull request #12792 from catboxanon/image-cropper-hide
Hide broken image crop tool
2023-08-27 09:26:50 +03:00
AUTOMATIC1111
e3174a1a42
Merge pull request #12797 from Madrawn/vae_resolve_bug
Small typo: vae resolve bug
2023-08-27 09:26:18 +03:00
AUTOMATIC1111
07878c6ca8
Merge pull request #12795 from catboxanon/prevent-duplicate-resize-handler-mk2
Prevent duplicate resize handler
2023-08-27 09:24:42 +03:00
AUTOMATIC1111
5e30f737b0 fix for Reload UI function: if you reload UI on one tab, other opened tabs will no longer stop working 2023-08-27 09:19:13 +03:00
AUTOMATIC1111
bd5c16e8da fix for Reload UI function: if you reload UI on one tab, other opened tabs will no longer stop working 2023-08-27 09:19:02 +03:00
AUTOMATIC1111
f2c55523c0 update changelog 2023-08-27 09:17:51 +03:00
AUTOMATIC1111
cb5f0823c6 update gradio to 3.41.2 2023-08-27 08:45:40 +03:00
AUTOMATIC1111
9dd0c4add5 update changelog 2023-08-27 08:45:25 +03:00
AUTOMATIC1111
1b46863f24 update gradio to 3.41.2 2023-08-27 08:45:16 +03:00
AUTOMATIC1111
3d83683a28 fix error that causes some extra networks to be disabled if both <lora:> and <lyco:> are present in the prompt 2023-08-27 08:41:48 +03:00
AUTOMATIC1111
b7f0e81562 fix error that causes some extra networks to be disabled if both <lora:> and <lyco:> are present in the prompt 2023-08-27 08:41:26 +03:00
catboxanon
9d8d279d0d Prevent duplicate resize handler 2023-08-26 17:30:09 -04:00
Daniel Dengler
d888490f85 Merge remote-tracking branch 'origin/dev' into vae_resolve_bug 2023-08-26 23:23:11 +02:00
Daniel Dengler
168eac319d is_automatic is missing () for call 2023-08-26 23:22:57 +02:00
catboxanon
73f69a7453
Fix CSS whitespace 2023-08-26 07:04:11 -04:00
catboxanon
ec54257cb2 Hide broken image crop tool for now 2023-08-26 07:00:09 -04:00
AUTOMATIC1111
72ee347eab update pnginfo checkpoint to return dict with parsed values 2023-08-26 06:52:18 +03:00
AUTOMATIC1111
ac1abf3de6 fix defaults settings page breaking when any of main UI tabs are hidden 2023-08-26 06:34:23 +03:00
AUTOMATIC1111
bb90b0ff42 fix defaults settings page breaking when any of main UI tabs are hidden 2023-08-26 06:34:00 +03:00
catboxanon
db56bdce33 Don't show hidden samplers in dropdown for XYZ script 2023-08-25 16:04:06 -04:00
AUTOMATIC1111
f3a1027869
Merge pull request #12774 from SpenserCai/extensions_api
support installed extensions list api
2023-08-25 19:03:12 +03:00
SpenserCai
dd07b5193e fix format error 2023-08-25 22:23:17 +08:00
SpenserCai
3369fb27df support installed extensions list api 2023-08-25 22:15:35 +08:00
AUTOMATIC1111
4c6788644a Merge branch 'release_candidate' into dev 2023-08-25 16:24:45 +03:00
AUTOMATIC1111
a6cedafb27
Merge pull request #12767 from AUTOMATIC1111/img2img-batch-PNG_info-model_hash
img2img batch PNG info model hash
2023-08-25 11:41:31 +03:00
AUTOMATIC1111
e004384e46 Merge branch 'dev' into release_candidate 2023-08-25 11:40:49 +03:00
AUTOMATIC1111
e835e61f3a
Merge pull request #12754 from daswer123/improve_integration
Zoom and Pan: Resize handler
2023-08-25 11:40:13 +03:00
w-e-w
4130e5db3d img2img batch PNG info model hash 2023-08-25 10:12:19 +09:00
AUTOMATIC1111
c8c73eae59 fix incorrect save/display of new values in Defaults page in settings 2023-08-24 22:03:24 +03:00
Danil Boldyrev
c39efa6ba6 Zoom and Pan: Resize handler 2023-08-24 17:30:35 +03:00
AUTOMATIC1111
935d9d899c update info about gradio in changelog file 2023-08-24 11:16:29 +03:00
AUTOMATIC1111
189229bbf9 Merge branch 'dev' into release_candidate 2023-08-24 11:09:04 +03:00
AUTOMATIC1111
b6c0217405 update changelog 2023-08-24 11:06:23 +03:00
AUTOMATIC1111
995ff5902f add infotext for use_old_scheduling option 2023-08-24 10:07:54 +03:00
AUTOMATIC1111
b0211ff7f8 bump gradio version 2023-08-24 09:41:30 +03:00
AUTOMATIC1111
0027ce1f6e
Merge pull request #12457 from rubberbaron/shared-hires-prompt-test
prompt editing timeline has separate range for first pass and hires-fix pass
2023-08-24 09:41:16 +03:00
AUTOMATIC1111
06f18186dc
Merge pull request #12745 from AUTOMATIC1111/draw-extra-network-buttons-above-description
draw extra network buttons above description
2023-08-24 09:37:17 +03:00
AUTOMATIC1111
2c570f641c
Merge pull request #12749 from daswer123/improve_integration
Zoom and pan: Improve integration
2023-08-24 09:36:53 +03:00
Danil Boldyrev
fa68d66c98 remove console.log 2023-08-24 01:42:37 +03:00
Danil Boldyrev
32e790a47e Fixing and improving integration 2023-08-24 01:40:06 +03:00
w-e-w
ddf3d1a7ac draw extra network buttons above description 2023-08-24 00:34:28 +09:00
AUTOMATIC1111
c9c8485bc1 Merge branch 'release_candidate' 2023-08-23 15:48:09 +03:00
AUTOMATIC1111
31f2be3dce update changelog 2023-08-23 15:47:11 +03:00
AUTOMATIC1111
250c416474 update doggettx cross attention optimization to not use an unreasonable amount of memory in some edge cases -- suggestion by MorkTheOrk 2023-08-23 15:44:38 +03:00
AUTOMATIC1111
12171ca961 fix memory leak when generation fails 2023-08-23 15:40:31 +03:00
AUTOMATIC1111
bae91855f5
Merge pull request #12737 from yajunzhng/master
tell RealESRGANer which device to run on, could be cuda, M1, or other…
2023-08-23 12:30:17 +03:00
yajun
f29b4cd7cb tell RealESRGANer which device to run on, could be cuda, M1, or other GPU 2023-08-23 14:31:38 +08:00
AUTOMATIC1111
0232a987bb set devices.dtype_unet correctly 2023-08-23 07:10:43 +03:00
Danil Boldyrev
6a87e35bef lint 2023-08-23 03:35:09 +03:00
Danil Boldyrev
8fd1558179 Removed the old code 2023-08-23 03:21:28 +03:00
AUTOMATIC1111
04cfcf91d9 fix endless progress requests 2023-08-22 21:05:25 +03:00
AUTOMATIC1111
3ec5ce9416 add type annotations for extra fields of shared.sd_model 2023-08-22 19:05:03 +03:00
AUTOMATIC1111
016554e437 add --medvram-sdxl 2023-08-22 18:49:08 +03:00
AUTOMATIC1111
bb7dd7b646 use an atomic operation to replace the cache with the new version 2023-08-22 17:45:47 +03:00
AUTOMATIC1111
9c82b34be7
Merge pull request #12727 from daswer123/improve_integration
Zoom and pan: Improved integration
2023-08-22 17:19:15 +03:00
Danil Boldyrev
54fbdcf467 Improve integration, fix for new gradio 2023-08-22 16:43:23 +03:00
AUTOMATIC1111
2e9289bcbf
Merge pull request #12722 from ravi9/intel-readme
Update README.md with install instructions on Intel CPUs, GPUs
2023-08-22 15:26:23 +03:00
AUTOMATIC1111
7fd0ccdffc
Merge pull request #12723 from MMP0/dev-resize-handle-fix
Resize handle improvements and bug fixes
2023-08-22 15:25:28 +03:00
MMP0
ed49c7c246 Fix double click event not firing 2023-08-22 21:21:06 +09:00
AUTOMATIC1111
0d90064e9e eslint 2023-08-22 13:57:05 +03:00
AUTOMATIC1111
9158d0fd12 fix broken generate button if not using live previews 2023-08-22 13:54:45 +03:00
MMP0
c4b11ec54e Replace tabs with spaces 2023-08-22 18:48:17 +09:00
AUTOMATIC1111
9e4019c5ff make it possible to localize tooltips and placeholders 2023-08-22 12:00:29 +03:00
MMP0
96edfb560b Limit mouse detection to primary button only 2023-08-22 17:19:26 +09:00
AUTOMATIC1111
f6c52f4f41 for live previews, only hide gallery after at least one live previews pic has been received
fix blinking for live previews
fix a clientside live previews exception that happens when you kill serverside during sampling
match the size of live preview image to gallery image
2023-08-22 11:02:14 +03:00
Ravi Panchumarthy
7d94e5f33b
Update README.md with Intel install instructions 2023-08-22 00:54:01 -07:00
AUTOMATIC1111
e8a9d213e4 dump current stack traces when exiting with SIGINT 2023-08-22 10:49:52 +03:00
MMP0
0998256fc5 Prevent text selection and cursor changes 2023-08-22 16:45:34 +09:00
AUTOMATIC1111
a459075d26 actual solution to the uncommon hanging problem that is seemingly caused by multiple progress requests working on same tensor 2023-08-22 10:41:10 +03:00
MMP0
70283a9f4a Expand the hit area of resize handle 2023-08-22 16:40:50 +09:00
MMP0
e1b37a066d Fix resize handle overflowing in Safari 2023-08-22 16:35:49 +09:00
AUTOMATIC1111
d7c9c61420 attemped solution to the uncommon hanging problem that is seemingly caused by live previews working on the tensor as denoising 2023-08-22 09:55:20 +03:00
AUTOMATIC1111
79fd17ee63 remove unneeded example_inputs from gradio config 2023-08-22 08:18:01 +03:00
AUTOMATIC1111
7a3a6e3855
Merge pull request #12713 from AUTOMATIC1111/XYZ-RNG
add RNG source to XYZ
2023-08-22 07:31:26 +03:00
AUTOMATIC1111
f83996cd9f
Merge pull request #12714 from catboxanon/resize-handle-reset
Reset columns on resize handle double click
2023-08-22 07:30:52 +03:00
AUTOMATIC1111
7da73cbcca
Merge pull request #12717 from brkirch/make-temp-directory
Create Gradio temp directory if necessary
2023-08-22 07:30:25 +03:00
brkirch
299b8096bc Make Gradio temp directory if it doesn't exist
Gradio normally creates the temp directory in `pil_to_temp_file()` (861d752a83/gradio/components/base.py (L313)) but since the Gradio implementation of `pil_to_temp_file()` is replaced with `save_pil_to_file()`, the Gradio temp directory should also be created by `save_pil_to_file()` when necessary.
2023-08-21 17:36:17 -04:00
catboxanon
aed52d1632 Reset columns on resize handle dblclick 2023-08-21 12:40:27 -04:00
w-e-w
9dce2aa735 add RNG source to XYZ 2023-08-21 23:08:47 +09:00
AUTOMATIC1111
953c3eab7b forbid Full live preview method for medvram and add a setting to undo the forbidding 2023-08-21 15:54:30 +03:00
AUTOMATIC1111
18fb522660 citation mk2 2023-08-21 15:27:04 +03:00
AUTOMATIC1111
bd6f070882 add citation 2023-08-21 15:22:47 +03:00
AUTOMATIC1111
a3fdef4ed4
Merge pull request #12707 from AnyISalIn/dev
feat: replace threading.Lock() to FIFOLock
2023-08-21 15:09:26 +03:00
AUTOMATIC1111
dfd6ea3fca ditch --always-batch-cond-uncond in favor of an UI setting 2023-08-21 15:07:10 +03:00
AnyISalIn
71a0f6ef85 feat: replace threading.Lock() to FIFOLock
Signed-off-by: AnyISalIn <anyisalin@gmail.com>
2023-08-21 17:49:58 +08:00
AUTOMATIC1111
d02c4da483 also prevent changing API options via override_settings 2023-08-21 08:58:15 +03:00
AUTOMATIC1111
df595ae313 make resize handle available to extensions 2023-08-21 08:48:46 +03:00
AUTOMATIC1111
b4d21e7113 prevent API options from being changed via API 2023-08-21 08:48:45 +03:00
AUTOMATIC1111
d722d6de36
Merge pull request #12667 from AUTOMATIC1111/switch-to-PNG-when-images-too-large
switch to PNG when images too large
2023-08-21 07:50:50 +03:00
AUTOMATIC1111
76ae1019b9 add settings for http/https URLs in source images in api 2023-08-21 07:38:07 +03:00
AUTOMATIC1111
a7f18b2297
Merge pull request #12698 from Akegarasu/fix-ssrf-in-api
fix potential ssrf attack in #12663
2023-08-21 07:19:48 +03:00
AUTOMATIC1111
d3632368e6
Merge pull request #12704 from fraz0815/master
Update torch for Navi 31 (7900 XT/XTX)
2023-08-21 07:11:17 +03:00
AUTOMATIC1111
5a3fe7a8d1
Merge pull request #12685 from Uminosachi/fix-vae-mismatch
Fix SD VAE switch error after model reuse
2023-08-21 07:10:19 +03:00
Uminosachi
be301f224d Fix for consistency with shared.opts.sd_vae of UI 2023-08-21 11:28:53 +09:00
fraz0815
db6c7ff084
Update torch for Navi 31 (7900 XT/XTX)
Navi 3 needs at least 5.5 which is only on the nightly chain, previous versions are no longer online (torch==2.1.0.dev-20230614+rocm5.5 torchvision==0.16.0.dev-20230614+rocm5.5 torchaudio==2.1.0.dev-20230614+rocm5.5).
so switch to nightly rocm5.6 without explicit versions this time
2023-08-20 22:59:30 +02:00
akiba
268dc9b308
fix potential ssrf attack in #12663 2023-08-20 23:17:50 +08:00
Uminosachi
549b0fc526 Change where VAE state are stored in model 2023-08-20 23:06:51 +09:00
AUTOMATIC1111
42b72fe246 fix for small images in live previews not being scaled up 2023-08-20 14:57:48 +03:00
AUTOMATIC1111
f65d0dc081
Merge pull request #12689 from AUTOMATIC1111/patch-config-status
Patch config status handle corrupted files
2023-08-20 14:20:27 +03:00
Uminosachi
af5d2e8e5f Change to access sd_model attribute with dot 2023-08-20 20:08:22 +09:00
Uminosachi
5159edbf0e Store base_vae and loaded_vae_file in sd_model 2023-08-20 19:44:37 +09:00
AUTOMATIC1111
4a2bf65fea make mobile built-in extension actually do something 2023-08-20 13:40:11 +03:00
AUTOMATIC1111
db5c304e29 make live previews play nice with window/slider resizes 2023-08-20 13:38:35 +03:00
AUTOMATIC1111
a0d721e109 make live preview display work independently from progress bar 2023-08-20 13:00:59 +03:00
w-e-w
2c10fda399 make it obvious that a config_status is corrupted
also format HTML removing unnecessary text blocks
2023-08-20 18:48:23 +09:00
w-e-w
7ca20adc6d no need to use OrderedDict 2023-08-20 18:48:23 +09:00
w-e-w
e0e64bcdf6 assert key created_at exist in config_states 2023-08-20 18:48:23 +09:00
AUTOMATIC1111
499cef3c2b
Merge pull request #12684 from AUTOMATIC1111/fix-xyz-swap-axes
fix xyz swap axes
2023-08-20 12:46:34 +03:00
AUTOMATIC1111
2571767204
Merge pull request #12687 from catboxanon/resize-handle
Add resize-handle (built-in extension)
2023-08-20 12:42:12 +03:00
w-e-w
36ecff71ae catch error when loading config_states
and save config_states with indent
2023-08-20 15:36:39 +09:00
catboxanon
a3c8510c05 Add resize-handler extension 2023-08-20 02:31:32 -04:00
Uminosachi
042e1d5d0b Fix SD VAE switch error after model reuse 2023-08-20 15:00:14 +09:00
w-e-w
ae17c775dc fix xyz swap axes
make csv_string_to_list_strip function
2023-08-20 14:29:26 +09:00
w-e-w
8ce613bb3a switch to PNG when images too large 2023-08-19 16:50:43 +09:00
AUTOMATIC1111
9d2299ed0b implement undo hijack for SDXL 2023-08-19 10:16:27 +03:00
AUTOMATIC1111
35db3665b3 possible fix for dictionary changed size during iteration 2023-08-19 08:39:48 +03:00
AUTOMATIC1111
5a5913828c
Merge pull request #12616 from catboxanon/extra-noise-callback
Add extra noise callback
2023-08-19 08:36:44 +03:00
AUTOMATIC1111
448d6bef37
Merge pull request #12599 from AUTOMATIC1111/ram_optim
RAM optimization round 2
2023-08-19 08:36:20 +03:00
AUTOMATIC1111
7056fdf2be
Merge pull request #12630 from catboxanon/fix/nans-mk2
Attempt to resolve NaN issue with unstable VAEs in fp32 mk2
2023-08-19 08:34:46 +03:00
AUTOMATIC1111
3d81fd714b
Merge pull request #12633 from catboxanon/fix/img2img-bg-color
Fix img2img background color for transparent images option not being used
2023-08-19 08:33:22 +03:00
AUTOMATIC1111
58a9082411
Merge pull request #12635 from catboxanon/fix/full-page-img
Make image viewer actually fit the whole page
2023-08-19 08:32:45 +03:00
AUTOMATIC1111
99a64edea8 do not assign to vae_dict 2023-08-19 08:31:06 +03:00
AUTOMATIC1111
d75b521af8
Merge pull request #12638 from Cschlaefli/fix-api-vae-model-refresh
fix issues with api model-refresh and vae-refresh
2023-08-19 08:28:47 +03:00
AUTOMATIC1111
296c8f6a4a
Merge pull request #12639 from AUTOMATIC1111/more-hash
More hash filename patterns
2023-08-19 08:28:00 +03:00
AUTOMATIC1111
99cd8de234
Merge pull request #12645 from catboxanon/css/sticky-column
Make results column sticky
2023-08-19 08:27:28 +03:00
AUTOMATIC1111
5590be7a8c
Merge pull request #12644 from AUTOMATIC1111/fix-model-override-logic
fix model override logic
2023-08-19 08:26:39 +03:00
AUTOMATIC1111
f084e6bbd0 revert xformers back to 0.0.20 2023-08-19 08:22:12 +03:00
AUTOMATIC1111
cd719b08bd
Merge pull request #12663 from SpenserCai/get_image_from_url
api support get image from url
2023-08-19 08:08:19 +03:00
AUTOMATIC1111
90e560bb75
Merge pull request #12648 from catboxanon/feat/gallery-tweaks
Gallery: Set preview to `True`, allow custom height
2023-08-19 08:06:13 +03:00
AUTOMATIC1111
9182dd7e5d
Merge pull request #12634 from catboxanon/feat/live-preview-fast-interrupt
Improve interrupt speed
2023-08-19 08:05:36 +03:00
AUTOMATIC1111
f739e3e05d second appearance 2023-08-19 08:04:48 +03:00
AUTOMATIC1111
e7a044a2d1
Merge pull request #12653 from S-Del/fix/typo
fix typo `txt2txt` -> `txt2img`
2023-08-19 08:03:40 +03:00
AUTOMATIC1111
ca72db23d2
Merge pull request #12660 from dansgithubuser/fork
Get python print statements to show up in docker logs
2023-08-19 08:03:19 +03:00
AUTOMATIC1111
e4a2a705ad
Merge pull request #12661 from XDOneDude/master
update xformers to 0.0.21 and some fixes
2023-08-19 08:02:18 +03:00
AUTOMATIC1111
bb91bb5e83
Merge pull request #12662 from bluelovers/bluelovers-patch-1-1
refactor: Update ui.js
2023-08-19 08:01:05 +03:00
SpenserCai
4760c3c0b5 api support get image from url 2023-08-19 12:19:21 +08:00
bluelovers
1631e96a98
refactor: Update ui.js 2023-08-19 10:38:43 +08:00
XDOneDude
61c1261e4e more grammar fixes 2023-08-18 21:56:15 -04:00
XDOneDude
956e1d8d90 xformers update 2023-08-18 21:25:59 -04:00
Dan
453a5ac1d0 run python unbuffered so output shows up in docker logs 2023-08-18 21:09:27 -04:00
S-Del
64d5fa1efd fix typo txt2txt -> txt2img 2023-08-18 22:32:20 +09:00
catboxanon
9d1d63afca Exit out of hires fix if interrupted earlier 2023-08-18 05:55:10 -04:00
catboxanon
44d4e7c500 Gallery: Set preview to True, allow custom height 2023-08-18 05:15:30 -04:00
catboxanon
f89f01f9d8 Make results column sticky 2023-08-18 04:18:22 -04:00
w-e-w
640cb1bb8d fix model override logic
do not need extra logic to unload refine model
2023-08-18 17:14:02 +09:00
w-e-w
a81dc43fcd negative_prompt full_prompt hash 2023-08-18 15:13:12 +09:00
w-e-w
8a1f32b6a5 image hash 2023-08-18 14:04:46 +09:00
Cade Schlaefli
f9c2216ffa remove unused import 2023-08-17 21:14:14 -05:00
Cade Schlaefli
959f8b32d5 fix issues with model refresh 2023-08-17 20:48:17 -05:00
catboxanon
13f1357b7f Make image viewer actually fit the whole page 2023-08-17 20:21:46 -04:00
catboxanon
3ce5fb8e5c Add option for faster live interrupt 2023-08-17 20:03:26 -04:00
catboxanon
46e8898f65 Fix img2img background color not being used 2023-08-17 19:35:34 -04:00
catboxanon
3003b10e0a Attempt to resolve NaN issue with unstable VAEs in fp32 mk2 2023-08-17 18:10:55 -04:00
AUTOMATIC1111
0dc74545c0 resolve the issue with loading fp16 checkpoints while using --no-half 2023-08-17 07:54:07 +03:00
catboxanon
254be4eeb2 Add extra noise callback 2023-08-16 21:45:19 -04:00
AUTOMATIC1111
541ef9247c
Merge pull request #12607 from AUTOMATIC1111/return-empty-list-if-extensions_dir-not-exist-
fix Return empty list if extensions dir not exist
2023-08-16 18:41:02 +03:00
w-e-w
e1a29266b2 return empty list if extensions_dir not exist 2023-08-17 00:24:24 +09:00
AUTOMATIC1111
fc3a57ff96
Merge pull request #12603 from AUTOMATIC1111/auto-add-data-dir-to-gradio-allowed-path
auto add data-dir to gradio-allowed-path
2023-08-16 14:48:37 +03:00
w-e-w
0cf85b24df auto add data-dir to gradio-allowed-path 2023-08-16 20:18:46 +09:00
AUTOMATIC1111
eaba3d7349 send weights to target device instead of CPU memory 2023-08-16 12:11:01 +03:00
AUTOMATIC1111
57e59c14c8 Revert "send weights to target device instead of CPU memory"
This reverts commit 0815c45bcdec0a2e5c60bdd5b33d95813d799c01.
2023-08-16 11:28:00 +03:00
AUTOMATIC1111
0815c45bcd send weights to target device instead of CPU memory 2023-08-16 10:44:17 +03:00
AUTOMATIC1111
023a3a98a1
Merge pull request #12596 from AUTOMATIC1111/fix-taesd-scale
Remove wrong TAESD Latent scale
2023-08-16 09:56:12 +03:00
AUTOMATIC1111
86221269f9 RAM optimization round 2 2023-08-16 09:55:35 +03:00
Kohaku-Blueleaf
d9ddc5d4cd Remove wrong scale 2023-08-16 11:21:12 +08:00
AUTOMATIC1111
a7f7701b64
Merge pull request #12589 from catboxanon/fix/css-overflow
CSS: Remove forced visible overflow for Gradio group child divs
2023-08-15 21:47:49 +03:00
AUTOMATIC1111
fd563e3274
Merge pull request #12586 from catboxanon/fix/rng-shape
RNG: Make all elements of shape `int`s
2023-08-15 21:47:02 +03:00
AUTOMATIC1111
d09d33bc2d
Merge pull request #12588 from catboxanon/fix/inpaint-upload
Fix inpaint upload for alpha masks
2023-08-15 21:46:19 +03:00
catboxanon
7083391931 CSS: Remove forced visible overflow for Gradio group child divs 2023-08-15 14:44:13 -04:00
catboxanon
0f77139253 Fix inpaint upload for alpha masks, create reusable function 2023-08-15 14:24:55 -04:00
catboxanon
5b28b7dbc7 RNG: Make all elements of shape ints 2023-08-15 13:38:37 -04:00
AUTOMATIC1111
85fcb7b8df lint 2023-08-15 19:25:03 +03:00
AUTOMATIC1111
8b181c812f
Merge pull request #12584 from AUTOMATIC1111/full-module-with-bias
Add ex_bias into full module
2023-08-15 19:24:15 +03:00
AUTOMATIC1111
f01682ee01 store patches for Lora in a specialized module 2023-08-15 19:23:40 +03:00
Kohaku-Blueleaf
aa57a89a21 full module with ex_bias 2023-08-15 23:41:46 +08:00
AUTOMATIC1111
7327be97aa
Merge pull request #12570 from NoCrypt/add-miku-theme
Add NoCrypt/miku gradio theme
2023-08-15 16:31:12 +03:00
AUTOMATIC1111
63f881a5f0
Merge pull request #12577 from brkirch/fix-vae-near-checkpoint-exception
Fix `sd_vae_as_default` being accessed instead of `sd_vae_overrides_per_model_preferences`
2023-08-15 15:29:48 +03:00
AUTOMATIC1111
dc0e63a48a
Merge pull request #12578 from AUTOMATIC1111/changelog-fix
Changelog minor correction
2023-08-15 15:29:15 +03:00
w-e-w
f117bb64fc Update CHANGELOG.md 2023-08-15 20:19:13 +09:00
brkirch
54209c1639 Use the new SD VAE override setting 2023-08-15 06:29:39 -04:00
AUTOMATIC1111
ec505bac41
Merge pull request #12573 from catboxanon/changelog
Add PR refs to changelog
2023-08-15 11:47:20 +03:00
catboxanon
2154662826 Add PR refs to changelog 2023-08-15 03:23:44 -04:00
AUTOMATIC1111
9ab52caf02 update changelog file 2023-08-15 09:50:57 +03:00
AUTOMATIC1111
bc61ad9ec8
Merge pull request #12564 from catboxanon/feat/img2img-noise
Add extra noise param for img2img operations
2023-08-15 09:50:20 +03:00
NoCrypt
b0a6d61d73 Add NoCrypt/miku gradio theme 2023-08-15 13:22:44 +07:00
catboxanon
371b24b17c Add extra img2img noise 2023-08-15 02:19:19 -04:00
AUTOMATIC1111
79d4e81984 fix processing error that happens if batch_size is not a multiple of how many prompts/negative prompts there are #12509 2023-08-15 08:46:17 +03:00
AUTOMATIC1111
7e77a38cbc get XYZ plot to work with recent changes to refined specified in fields of p rather than in settings 2023-08-15 08:27:50 +03:00
AUTOMATIC1111
d6b79b9963
Merge pull request #12476 from AnyISalIn/dev
xyz_grid: support refiner_checkpoint and refiner_switch_at
2023-08-15 08:26:38 +03:00
AUTOMATIC1111
6f86573247
Merge pull request #12552 from brkirch/update-sdxl-commit-hash
Update SD XL commit hash
2023-08-15 08:12:21 +03:00
AUTOMATIC1111
45be87afc6 correctly add Eta DDIM to infotext when it's 1.0 and do not add it when it's 0.0. 2023-08-14 21:48:05 +03:00
AUTOMATIC1111
5daf7983d1 when refreshing cards in extra networks UI, do not discard user's custom resolution 2023-08-14 19:27:04 +03:00
AUTOMATIC1111
f23e5ce2da revert changed inpainting mask conditioning calculation after #12311 2023-08-14 17:59:03 +03:00
AUTOMATIC1111
e56b7c8419
Merge pull request #12547 from whitebell/fix-typo
Fix typo in shared_options.py
2023-08-14 13:36:10 +03:00
AUTOMATIC1111
2359c07ddf
Merge pull request #12551 from AUTOMATIC1111/separate-Extra-options
separate Extra options
2023-08-14 13:35:41 +03:00
brkirch
bc63339df3 Update hash for SD XL Repo 2023-08-14 06:26:36 -04:00
w-e-w
a2e213bc7b separate Extra options 2023-08-14 18:50:22 +09:00
AUTOMATIC1111
6bfd4dfecf add second_order to samplers that mistakenly didn't have it 2023-08-14 12:07:38 +03:00
Robert Barron
99ab3d43a7 hires prompt timeline: merge to latests, slightly simplify diff 2023-08-14 00:43:27 -07:00
AUTOMATIC1111
353c876172 fix API always using -1 as seed 2023-08-14 10:43:18 +03:00
Robert Barron
d61e31bae6 Merge remote-tracking branch 'auto1111/dev' into shared-hires-prompt-test 2023-08-14 00:35:17 -07:00
AUTOMATIC1111
f3b96d4998 return seed controls UI to how it was before 2023-08-14 10:22:52 +03:00
AUTOMATIC1111
abbecb3e73 further repair the /docs page to not break styles with the attempted fix 2023-08-14 10:15:10 +03:00
whitebell
b39d9364d8
Fix typo in shared_options.py
unperdictable -> unpredictable
2023-08-14 15:58:38 +09:00
AUTOMATIC1111
c7c16f805c repair /docs page 2023-08-14 09:49:51 +03:00
AUTOMATIC1111
f37cc5f5e1
Merge pull request #12542 from AUTOMATIC1111/res-sampler
Add RES sampler and reorder the sampler list
2023-08-14 09:02:10 +03:00
AUTOMATIC1111
3a4bee1096
Merge pull request #12543 from AUTOMATIC1111/extra-norm-module
Fix MHA error with ex_bias and support ex_bias for layers which don't have bias
2023-08-14 09:01:34 +03:00
AUTOMATIC1111
c1a31ec9f7 revert to applying mask before denoising for k-diffusion, like it was before 2023-08-14 08:59:15 +03:00
Kohaku-Blueleaf
f70ded8936 remove "if bias exist" check 2023-08-14 13:53:40 +08:00
Kohaku-Blueleaf
aa26f8eb40 Put frequently used sampler back 2023-08-14 13:50:53 +08:00
AUTOMATIC1111
cda2f0a162 make on_before_component/on_after_component possible earlier 2023-08-14 08:49:39 +03:00
AUTOMATIC1111
aeb76ef174 repair DDIM/PLMS/UniPC batches 2023-08-14 08:49:02 +03:00
Kohaku-Blueleaf
e7c03ccdce Merge branch 'dev' into extra-norm-module 2023-08-14 13:34:51 +08:00
Kohaku-Blueleaf
d9cc27cb29 Fix MHA updown err and support ex-bias for no-bias layer 2023-08-14 13:32:51 +08:00
Kohaku-Blueleaf
0ea61a74be add res(dpmdd 2m sde heun) and reorder the sampler list 2023-08-14 11:46:36 +08:00
AUTOMATIC1111
007ecfbb29 also use setup callback for the refiner instead of before_process 2023-08-13 21:01:13 +03:00
AUTOMATIC1111
9cd0475c08
Merge pull request #12526 from brkirch/mps-adjust-sub-quad
Fixes for `git checkout`, MPS/macOS fixes and optimizations
2023-08-13 20:28:49 +03:00
AUTOMATIC1111
8452708560
Merge pull request #12530 from eltociear/eltociear-patch-1
Fix typo in launch_utils.py
2023-08-13 20:27:17 +03:00
AUTOMATIC1111
16781ba09a fix 2 for git code botched by previous PRs 2023-08-13 20:15:20 +03:00
Ikko Eltociear Ashimine
09ff5b5416
Fix typo in launch_utils.py
existance -> existence
2023-08-14 01:03:49 +09:00
AUTOMATIC1111
f093c9d39d fix broken XYZ plot seeds
add new callback for scripts to be used before processing
2023-08-13 17:31:10 +03:00
brkirch
2035cbbd5d Fix DDIM and PLMS samplers on MPS 2023-08-13 10:07:52 -04:00
brkirch
5df535b7c2 Remove duplicate code for torchsde randn 2023-08-13 10:07:52 -04:00
brkirch
232c931f40 Mac k-diffusion workarounds are no longer needed 2023-08-13 10:07:52 -04:00
brkirch
f4dbb0c820 Change the repositories origin URLs when necessary 2023-08-13 10:07:52 -04:00
brkirch
9058620cec git checkout with commit hash 2023-08-13 10:07:14 -04:00
brkirch
2489252099 torch.empty can create issues; use torch.zeros
For MPS, using a tensor created with `torch.empty()` can cause `torch.baddbmm()` to include NaNs in the tensor it returns, even though `beta=0`. However, with a tensor of shape [1,1,1], there should be a negligible performance difference between `torch.empty()` and `torch.zeros()` anyway, so it's better to just use `torch.zeros()` for this and avoid unnecessarily creating issues.
2023-08-13 10:06:25 -04:00
brkirch
87dd685224 Make sub-quadratic the default for MPS 2023-08-13 10:06:25 -04:00
brkirch
abfa4ad8bc Use fixed size for sub-quadratic chunking on MPS
Even if this causes chunks to be much smaller, performance isn't significantly impacted. This will usually reduce memory usage but should also help with poor performance when free memory is low.
2023-08-13 10:06:25 -04:00
AUTOMATIC1111
3163d1269a fix for the broken run_git calls 2023-08-13 16:51:21 +03:00
AUTOMATIC1111
1c6ca09992
Merge pull request #12510 from catboxanon/feat/extnet/hashes
Support search and display of hashes for all extra network items
2023-08-13 16:46:32 +03:00
AUTOMATIC1111
d73db17ee3
Merge pull request #12515 from catboxanon/fix/gc1
Clear sampler and garbage collect before decoding images to reduce VRAM
2023-08-13 16:45:38 +03:00
AUTOMATIC1111
127ab9114f
Merge pull request #12514 from catboxanon/feat/batch-encode
Encode batch items individually to significantly reduce VRAM
2023-08-13 16:41:07 +03:00
AUTOMATIC1111
d53f3b5596
Merge pull request #12520 from catboxanon/eta
Update description of eta setting
2023-08-13 16:40:17 +03:00
AUTOMATIC1111
d41a5bb97d
Merge pull request #12521 from catboxanon/feat/more-s-noise
Add `s_noise` param to more samplers
2023-08-13 16:39:25 +03:00
AUTOMATIC1111
551d2fabcc
Merge pull request #12522 from catboxanon/fix/extra_params
Restore `extra_params` that was lost in merge
2023-08-13 16:38:27 +03:00
AUTOMATIC1111
db40d26d08 linter 2023-08-13 16:38:10 +03:00
catboxanon
525b55b1e9 Restore extra_params that was lost in merge 2023-08-13 09:08:34 -04:00
catboxanon
ce0829d711 Merge branch 'feat/dpmpp3msde' into feat/more-s-noise 2023-08-13 08:46:58 -04:00
catboxanon
ac790fc49b Discard penultimate sigma for DPM-Solver++(3M) SDE 2023-08-13 08:46:07 -04:00
catboxanon
f4757032e7 Fix s_noise description 2023-08-13 08:24:28 -04:00
catboxanon
d1a70c3f05 Add s_noise param to more samplers 2023-08-13 08:22:24 -04:00
AUTOMATIC1111
d8419762c1 Lora: output warnings in UI rather than fail for unfitting loras; switch to logging for error output in console 2023-08-13 15:07:37 +03:00
catboxanon
60a7405165 Update description of eta setting 2023-08-13 08:06:40 -04:00
catboxanon
1ae9dacb4b Add DPM-Solver++(3M) SDE 2023-08-13 07:57:29 -04:00
catboxanon
69f49c8d39 Clear sampler before decoding images
More significant VRAM reduction.
2023-08-13 04:40:34 -04:00
catboxanon
822597db49 Encode batches separately
Significantly reduces VRAM.
This makes encoding more inline with how decoding currently functions.
2023-08-13 04:16:48 -04:00
catboxanon
7fa5ee54b1 Support search and display of hashes for all extra network items 2023-08-13 02:32:54 -04:00
AUTOMATIC1111
da80d649fd
Merge pull request #12503 from AUTOMATIC1111/extra-norm-module
Add Norm Module to lora ext and add "bias" support
2023-08-13 08:28:48 +03:00
AUTOMATIC1111
61673451ff
Merge pull request #12491 from AUTOMATIC1111/xyz-csv-and-dropdown-mode
Bring back CSV mode for XYZ grid
2023-08-13 08:25:15 +03:00
AUTOMATIC1111
599f61a1e0 use dataclass for StableDiffusionProcessing 2023-08-13 08:24:16 +03:00
w-e-w
0e3bac8132 rephrase and move 2023-08-13 14:09:38 +09:00
AUTOMATIC1111
fa9370b741 add refiner to StableDiffusionProcessing class
write out correct model name in infotext, rather than the refiner model
2023-08-13 06:07:30 +03:00
Kohaku-Blueleaf
5881dcb887 remove debug print 2023-08-13 02:36:02 +08:00
Kohaku-Blueleaf
a2b8305096 return None if no ex_bias 2023-08-13 02:35:04 +08:00
Kohaku-Blueleaf
bd4da4474b Add extra norm module into built-in lora ext
refer to LyCORIS 1.9.0.dev6
add new option and module for training norm layer
(Which is reported to be good for style)
2023-08-13 02:27:39 +08:00
w-e-w
dc5b5ee9c6 properly convert this into CSV string 2023-08-13 02:21:04 +09:00
w-e-w
299eb54308 pass csv_mode 2023-08-13 02:17:13 +09:00
w-e-w
8d9ca46e0a convert value when switching mode 2023-08-13 02:05:20 +09:00
AUTOMATIC1111
b2080756fc make "send to" buttons into small tool buttons 2023-08-12 19:03:33 +03:00
AUTOMATIC1111
9d0ec13596 fix quicksettings on Chrome 2023-08-12 18:42:59 +03:00
AUTOMATIC1111
6816ad5ed8 fix broken reuse seed 2023-08-12 18:36:30 +03:00
AUTOMATIC1111
4e8690906c update seed/subseed HTML widths 2023-08-12 18:00:30 +03:00
AUTOMATIC1111
f0b72b8121 move seed, variation seed and variation seed strength to a single row, dump resize seed from UI
add a way for scripts to register a callback for before/after just a single component's creation
2023-08-12 17:46:13 +03:00
w-e-w
7a68ac6615 rename to csv mode 2023-08-12 23:40:05 +09:00
w-e-w
f131f84e13 dropdown mode chackbox 2023-08-12 23:26:25 +09:00
AUTOMATIC1111
6aa26a26d5 change quicksettings items to have variable width 2023-08-12 16:47:39 +03:00
w-e-w
fd617fad00 Redundant character escape '\]' in RegExp 2023-08-12 22:24:59 +09:00
w-e-w
d20eb11c9e format 2023-08-12 22:24:00 +09:00
w-e-w
c8d453e915 bring back csv mode 2023-08-12 22:20:34 +09:00
AUTOMATIC1111
b293ed3061 make it possible to use hires fix together with refiner 2023-08-12 12:54:32 +03:00
AUTOMATIC1111
64311faa68 put refiner into main UI, into the new accordions section
add VAE from main model into infotext, not from refiner model
option to make scripts UI without gr.Group
fix inconsistencies with refiner when usings samplers that do more denoising than steps
2023-08-12 12:39:59 +03:00
AUTOMATIC1111
26c92f056a
Merge pull request #12480 from catboxanon/fix/cc
Fix color correction by converting image to RGB
2023-08-12 09:12:30 +03:00
AUTOMATIC1111
ebc1bafb03
Merge pull request #12479 from catboxanon/fix/extras-generator
Refactor postprocessing/extras tab to use generator to resolve OOM issues
2023-08-12 08:58:14 +03:00
AUTOMATIC1111
9dae70da79
Merge pull request #12487 from AUTOMATIC1111/disable-extensions-installer-with-arg
pathc: also disable extensions installer with arg
2023-08-12 08:57:35 +03:00
w-e-w
f57bc1a21b disable extensions installer with arg 2023-08-12 12:06:31 +09:00
catboxanon
af27b716e5 Fix color correction by converting image to RGB 2023-08-11 12:22:11 -04:00
catboxanon
7c9c19b2a2 Refactor postprocessing to use generator to resolve OOM issues 2023-08-11 11:32:12 -04:00
AnyISalIn
3b2f51602d xyz_grid: support refiner_checkpoint and refiner_switch_at
Signed-off-by: AnyISalIn <anyisalin@gmail.com>
2023-08-11 21:40:33 +08:00
AUTOMATIC1111
ae6b30907d
Merge pull request #12470 from Splendide-Imaginarius/mask-blur-property+kernel
Make `StableDiffusionProcessingImg2Img.mask_blur` a property, make more inline with PIL `GaussianBlur`
2023-08-11 15:03:18 +03:00
AUTOMATIC1111
77c52ea701 fix accordion style on img2img 2023-08-11 11:59:11 +03:00
AUTOMATIC1111
3c00e41ec0
Merge pull request #12458 from daswer123/auto-expand
Zoom and pan: Some fixes for the auto-expand
2023-08-11 07:56:31 +03:00
AUTOMATIC1111
340c1cc68d
Merge pull request #12463 from catboxanon/fix/vae-hash
Properly return `None` for VAE hash when using `--no-hashing`
2023-08-11 07:55:42 +03:00
AUTOMATIC1111
2c79f2af6e
Merge pull request #12466 from catboxanon/fix/lora-old-mk2
Fix broken `Lora/Networks: use old method` option
2023-08-11 07:53:12 +03:00
catboxanon
4fafc34e49 Fix to make LoRA old method setting work 2023-08-10 23:42:58 -04:00
catboxanon
d456fb797a fix: Properly return None when VAE hash is None 2023-08-10 16:04:49 -04:00
AUTOMATIC1111
458eda1321
Merge pull request #12456 from AUTOMATIC1111/patch-#12453
Patch #12453
2023-08-10 17:55:31 +03:00
Robert Barron
54f926b11d fix bad merge 2023-08-10 07:48:04 -07:00
w-e-w
a75d756a6f use default value if value error 2023-08-10 23:47:28 +09:00
Robert Barron
863613293e Merge branch 'shared-hires-prompt-raw' into shared-hires-prompt-test 2023-08-10 07:45:35 -07:00
AUTOMATIC1111
9af5cce4c7
Merge pull request #12454 from wfjsw/no-autofix-on-fetch
rm dir on failed clone, disable autofix for fetch
2023-08-10 17:28:29 +03:00
AUTOMATIC1111
e0906096c5 remove unnecessary GFPGAN_PACKAGE (we install GFPGAN from the requirements file) 2023-08-10 17:22:08 +03:00
AUTOMATIC1111
4549f2a9cc lint 2023-08-10 17:21:01 +03:00
AUTOMATIC1111
f4979422dd return the line lost during the merge 2023-08-10 17:18:33 +03:00
Jabasukuriputo Wang
5a705c2468
rm dir on failed clone, disable autofix for fetch 2023-08-10 09:18:10 -05:00
AUTOMATIC1111
36762f0eaf
Merge pull request #12371 from AUTOMATIC1111/refiner
initial refiner support
2023-08-10 17:05:32 +03:00
AUTOMATIC1111
ac8a5d18d3 resolve merge issues 2023-08-10 17:04:59 +03:00
AUTOMATIC1111
70a01cd444 Merge branch 'dev' into refiner 2023-08-10 17:04:38 +03:00
AUTOMATIC1111
959404e0e2
Merge pull request #12453 from AUTOMATIC1111/catch-float-ValueError-default-to--1
Catch float value error default to -1
2023-08-10 16:46:40 +03:00
AUTOMATIC1111
887bcfdf65
Merge pull request #12447 from AUTOMATIC1111/extra-networks-metadata-indent-
save extra networks metadata with indent
2023-08-10 16:46:08 +03:00
AUTOMATIC1111
40ccd26b19
Merge pull request #12450 from catboxanon/cache-file
Add env var for cache file
2023-08-10 16:45:44 +03:00
w-e-w
4412398c4b catch float ValueError default -1 2023-08-10 22:44:33 +09:00
AUTOMATIC1111
942d7a118a
Merge pull request #12452 from AUTOMATIC1111/use-new-style-constructor
use new style constructor
2023-08-10 16:43:27 +03:00
AUTOMATIC1111
070b034cd5 put infotext label for setting into OptionInfo definition rather than in a separate list 2023-08-10 16:42:26 +03:00
AUTOMATIC1111
9d78d317ae add VAE to infotext 2023-08-10 16:22:10 +03:00
Danil Boldyrev
045f740892 Height fix 2023-08-10 16:17:52 +03:00
AUTOMATIC1111
b13806c150 fix a bug preventing normal operation if a string is added to a gr.Number component via ui-config.json 2023-08-10 16:15:34 +03:00
AUTOMATIC1111
4f6582cb66 add precision=0 to gr.Number seed 2023-08-10 16:10:42 +03:00
AUTOMATIC1111
1b3093fe3a fix --use-textbox-seed 2023-08-10 15:58:53 +03:00
w-e-w
237b704172 use new style constructor 2023-08-10 21:42:26 +09:00
AUTOMATIC1111
4d93f48f09 fix for multiple input accordions 2023-08-10 15:32:54 +03:00
Danil Boldyrev
ed01d2ee3b a another fix, a different approach 2023-08-10 13:45:25 +03:00
catboxanon
386202895f Add env var for cache file 2023-08-10 06:17:45 -04:00
AUTOMATIC1111
0883810592 comment for InputAccordion 2023-08-10 13:02:50 +03:00
AUTOMATIC1111
faca86620d linter fixes 2023-08-10 12:58:00 +03:00
AUTOMATIC1111
6c23061a7d avoid importing gradio in tests because it spams warnings 2023-08-10 12:50:03 +03:00
AUTOMATIC1111
33446acf47 face restoration and tiling moved to settings - use "Options in main UI" setting if you want them back 2023-08-10 12:41:41 +03:00
w-e-w
0a0a9d4fe9 extra networks metadata indent 2023-08-10 18:05:17 +09:00
AUTOMATIC1111
9199b6b7eb add a custom UI element that combines accordion and checkbox
rework hires fix UI to use accordion
prevent bogus progress output in console when calculating hires fix dimensions
2023-08-10 11:20:46 +03:00
AUTOMATIC1111
2c5106ed06 additional work on gradio styles;
make the accordion change affect all accordions, not just inside scripts div
2023-08-10 07:57:52 +03:00
AUTOMATIC1111
6ed1541ef5
Merge pull request #12312 from catboxanon/script-accordion-style
Add styling for script components
2023-08-10 07:05:44 +03:00
AUTOMATIC1111
736aaf348b
Merge pull request #12440 from catboxanon/dev
Use better symbol for extra networks sort
2023-08-10 06:39:38 +03:00
AUTOMATIC1111
f0edd26998
Merge pull request #12439 from catboxanon/fix/slerp-import
Add slerp import for extension backwards compat
2023-08-10 06:37:44 +03:00
catboxanon
ff1bfd01ba
Remove up down symbol 2023-08-09 14:41:25 -04:00
catboxanon
2ceb4f81e2
Use better symbol for extra networks sort 2023-08-09 14:40:18 -04:00
catboxanon
259805947e
Add slerp import for extension backwards compat 2023-08-09 14:24:16 -04:00
AUTOMATIC1111
66c32e40e8 fix gradio themes not applying 2023-08-09 21:19:33 +03:00
AUTOMATIC1111
edfae9e78a add --loglevel commandline argument for logging
remove the progressbar for extension installation in favor of logging output
2023-08-09 20:49:33 +03:00
Robert Barron
d1ba46b6e1 allow first pass and hires pass to use a single prompt to do different prompt editing, hires is 1.0..2.0:
relative time range is [1..2]
  absolute time range is [steps+1..steps+hire_steps], e.g. with 30 steps and 20 hires steps, '20' is 2/3rds through first pass, and 40 is halfway through hires pass
2023-08-09 10:38:47 -07:00
AUTOMATIC1111
c7b9394daf
Merge pull request #12435 from daswer123/auto-expand
Zoom and pan: fix auto-expand
2023-08-09 20:04:44 +03:00
AUTOMATIC1111
ab42f81c75
Merge pull request #12436 from catboxanon/fix/tqdm
Only import `tqdm` when needed in `launch_utils`
2023-08-09 20:03:55 +03:00
catboxanon
8b7b99f8d5
fix: Only import tqdm when needed 2023-08-09 12:18:03 -04:00
Danil Boldyrev
4a64d34001 fix auto-expand 2023-08-09 18:40:45 +03:00
AUTOMATIC1111
95821f0132 split webui.py's initialization and utility functions into separate files 2023-08-09 18:11:13 +03:00
AUTOMATIC1111
a2a97e57f0 simplify 2023-08-09 17:08:36 +03:00
AUTOMATIC1111
f2ebcee7c4
Merge pull request #11925 from wfjsw/ext-inst-pbar
Progressbar for extension installers
2023-08-09 17:03:24 +03:00
AUTOMATIC1111
eed963e972 Lora cache in memory 2023-08-09 16:54:49 +03:00
AUTOMATIC1111
7ba8f11688 fix missing restricted_opts from shared 2023-08-09 15:06:03 +03:00
AUTOMATIC1111
aa10faa591 fix checkpoint name jumping around in the list of checkpoints for no good reason 2023-08-09 14:47:44 +03:00
AUTOMATIC1111
358f55db6a
Merge pull request #12424 from AUTOMATIC1111/extra-network-metadata-inherit-old-description
extra network metadata inherit old description
2023-08-09 14:41:30 +03:00
AUTOMATIC1111
c8c48640e6
Merge pull request #12426 from AUTOMATIC1111/split_shared
Split shared.py into multiple files
2023-08-09 14:40:06 +03:00
w-e-w
0cac6ab615 extra network metadata inherit old description 2023-08-09 20:35:06 +09:00
AUTOMATIC1111
2617598b7a
Merge pull request #12392 from olivierlacan/fix/fastapi
Pin fastapi to > 0.90.1 to fix crash
2023-08-09 14:25:50 +03:00
AUTOMATIC1111
8eea891718
Merge pull request #12396 from Uminosachi/fix-mismatch-shared
Fix mismatch between shared.sd_model & shared.opts
2023-08-09 14:20:12 +03:00
AUTOMATIC1111
386245a264 split shared.py into multiple files; should resolve all circular reference import errors related to shared.py 2023-08-09 10:25:35 +03:00
AUTOMATIC1111
7d81ecbea6 Split history: mv temp modules/shared.py 2023-08-09 08:47:53 +03:00
AUTOMATIC1111
8cf8fc6794 Split history: merge 2023-08-09 08:47:53 +03:00
AUTOMATIC1111
da0712ee7d Split history: mv modules/shared.py temp 2023-08-09 08:47:53 +03:00
AUTOMATIC1111
a6f840b4dc Split history: mv modules/shared.py modules/shared_options.py 2023-08-09 08:47:52 +03:00
AUTOMATIC1111
0d5dc9a6e7 rework RNG to use generators instead of generating noises beforehand 2023-08-09 08:43:31 +03:00
AUTOMATIC1111
d81d3fa8cd fix styles missing from the prompt in infotext when making a grid of batch of multiplie images 2023-08-09 07:45:06 +03:00
w-e-w
c102780693 extra network metadata inherit old description 2023-08-09 13:38:53 +09:00
AUTOMATIC1111
7f9dbc45b1
Merge pull request #12413 from daswer123/auto-expand
Zoom and pan: option to auto-expand a wide image
2023-08-09 07:03:30 +03:00
AUTOMATIC1111
08e538e2e6
Merge pull request #12422 from catboxanon/fix/hr-same-sampler
Fix HR `Use same sampler` option
2023-08-09 07:00:48 +03:00
catboxanon
bd4b4292ef
Fix hr use same sampler 2023-08-08 20:55:08 -04:00
Danil Boldyrev
e12a1be1ca auto-expand enable by default for js 2023-08-09 00:14:19 +03:00
Danil Boldyrev
a74c014425 auto-expand enable by default 2023-08-09 00:06:51 +03:00
AUTOMATIC1111
a2360de3f3
Merge pull request #12412 from dhwz/dev
fix typo
2023-08-08 23:30:57 +03:00
AUTOMATIC1111
0e83c67525 by request: fix tiled vae extension 2023-08-08 22:27:32 +03:00
AUTOMATIC1111
1aefb50259 add None refiner option 2023-08-08 22:17:25 +03:00
AUTOMATIC1111
ec194b6374 fix webui not switching back to original model from refiner when batch count is greater than 1 2023-08-08 22:14:02 +03:00
AUTOMATIC1111
f8ff8c0638 merge errors 2023-08-08 22:09:51 +03:00
AUTOMATIC1111
54c3e5c913 Merge branch 'dev' into refiner 2023-08-08 21:49:47 +03:00
AUTOMATIC1111
70c63c1208 pass samplers from UI by name, make it possible to use a sampler from infotext even if it's hidden in the dropdown 2023-08-08 21:28:34 +03:00
Danil Boldyrev
bc7906e6d6 Ability to automatically expand a picture that does not fit in the screen 2023-08-08 21:28:16 +03:00
AUTOMATIC1111
ae1bde1aa1 put commonly used samplers on top, make DPM++ 2M Karras the default choice 2023-08-08 21:10:12 +03:00
AUTOMATIC1111
a8a256f9b5 REMOVE 2023-08-08 21:08:50 +03:00
AUTOMATIC1111
8285a149d8 add CFG denoiser implementation for DDIM, PLMS and UniPC (this is the commit when you can run both old and new implementations to compare them) 2023-08-08 21:04:44 +03:00
dhwz
2a72d76d6f fix typo 2023-08-08 19:08:37 +02:00
AUTOMATIC1111
2d8e4a6544 split sd_samplers_kdiffusion into two 2023-08-08 18:35:31 +03:00
AUTOMATIC1111
c721884cf5 Split history: mv temp modules/sd_samplers_kdiffusion.py 2023-08-08 18:32:18 +03:00
AUTOMATIC1111
ee2b8f2e1b Split history: merge 2023-08-08 18:32:18 +03:00
AUTOMATIC1111
a3e27019e4 Split history: mv modules/sd_samplers_kdiffusion.py temp 2023-08-08 18:32:17 +03:00
AUTOMATIC1111
7e88f57aaa Split history: mv modules/sd_samplers_kdiffusion.py modules/sd_samplers_cfg_denoiser.py 2023-08-08 18:32:17 +03:00
AUTOMATIC1111
902f8cf292
Merge pull request #12254 from AUTOMATIC1111/auro-autolaunch
Automatically open webui in browser when running "locally"
2023-08-08 06:44:49 +03:00
w-e-w
f17c8c2eff
Merge branch 'dev' into auro-autolaunch 2023-08-08 11:39:34 +09:00
w-e-w
c75bda867b setting: Automatically open webui in browser on startup 2023-08-08 11:29:33 +09:00
Uminosachi
8c200c2156 Fix mismatch between shared.sd_model & shared.opts 2023-08-08 10:48:03 +09:00
Olivier Lacan
b0f7f4a991 Pin fastapi to > 0.90.1 to fix crash
See https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/11642#issuecomment-1643298659

This resolves a crashing bug for me on Python 3.10 and it appears to do so
as well for others.
2023-08-07 12:46:02 -07:00
AUTOMATIC1111
01997f45ba fix extra_options_section misbehaving when there's just one extra_options element 2023-08-07 18:49:23 +03:00
AUTOMATIC1111
251140fc88
Merge pull request #12379 from diegocr/dev
Allow to open images in new browser tab by MMB.
2023-08-07 17:48:13 +03:00
Diego Casorran
aea0fa9fd5
Allow to open images in new browser tab by MMB.
Signed-off-by: Diego Casorran <dcasorran@gmail.com>
2023-08-07 14:53:42 +02:00
AUTOMATIC1111
912356133a
Merge pull request #12387 from huaizong/feature/whz/fix-api-only-mode-lora-nowork
Feature/whz/fix api only mode lora nowork
2023-08-07 13:36:26 +03:00
王怀宗
250a95b6fe fix: enable before_ui_callback when api only mode (fixes #7984) 2023-08-07 18:08:07 +08:00
AUTOMATIC1111
fd67eafc65
Merge pull request #12385 from catboxanon/dev
Remove deprecated style method
2023-08-07 09:43:59 +03:00
AUTOMATIC1111
4c72377bbf Options in main UI update
- correctly read values from pasted infotext
- setting for column count
- infotext paste: do not add a field to override settings if some other component is already handling it
2023-08-07 09:42:13 +03:00
catboxanon
7d8f55ec7c
Remove style method 2023-08-07 01:45:10 -04:00
AUTOMATIC1111
0ea20a0d52 rework #12230 to not have duplicate code 2023-08-07 08:38:18 +03:00
AUTOMATIC1111
5cf37ca89f
Merge pull request #12230 from wfjsw/git-clone-autofix
Git autofix
2023-08-07 08:27:27 +03:00
AUTOMATIC1111
3453710d10
Merge pull request #12375 from catboxanon/k-diffusion-sigma
Clean up k-diffusion sigma params
2023-08-07 08:20:05 +03:00
AUTOMATIC1111
6e7828e1d2 apply unet overrides after switching model 2023-08-07 08:16:20 +03:00
AUTOMATIC1111
c96e4750d8 SD VAE rework 2
- the setting for preferring opts.sd_vae has been inverted and reworded
- resolve_vae function made easier to read and now returns an object rather than a tuple
- if the checkbox for overriding per-model preferences is checked, opts.sd_vae overrides checkpoint user metadata
- changing VAE in user metadata  for currently loaded model immediately applies the selection
2023-08-07 08:07:20 +03:00
catboxanon
7bcfb4654f
Add info to k-diffusion sigma params 2023-08-06 12:41:21 -04:00
catboxanon
976963ab6d
Clean up k-diffusion sigma params 2023-08-06 12:30:23 -04:00
AUTOMATIC1111
5a0db84b6c add infotext
add proper support for recalculating conds in k-diffusion samplers
remove support for compvis samplers
2023-08-06 17:53:33 +03:00
AUTOMATIC1111
5a38a9c0ee
Merge pull request #12369 from diegocr/dev
add explicit content-type header for image/webp
2023-08-06 17:52:28 +03:00
AUTOMATIC1111
956e69bf3a lint! 2023-08-06 17:07:08 +03:00
AUTOMATIC1111
f1975b0213 initial refiner support 2023-08-06 17:01:07 +03:00
Diego Casorran
e866c35462
add explicit content-type header for image/webp 2023-08-06 12:25:04 +00:00
AUTOMATIC1111
57e8a11d17 enable cond cache by default 2023-08-06 13:25:51 +03:00
AUTOMATIC1111
f9950da3e3 create dir for gradio themes cache if it's missing 2023-08-06 12:39:28 +03:00
AUTOMATIC1111
aa42c0ff8e repair broken live previews if using VAE with half 2023-08-06 07:41:24 +03:00
AUTOMATIC1111
06da34d47a
Merge pull request #12358 from catboxanon/sigma-infotext
Add missing k-diffusion sigma params to infotext
2023-08-06 06:56:07 +03:00
AUTOMATIC1111
5cae08f2c3 fix rework saving incomplete images 2023-08-06 06:55:19 +03:00
catboxanon
8f31b139b8 Assume 0 = inf for s_tmax 2023-08-05 23:50:33 -04:00
catboxanon
ce4be668fe Read kdiffusion sigma params from opts 2023-08-05 23:42:20 -04:00
AUTOMATIC1111
2e8b40004e
Merge pull request #12355 from AUTOMATIC1111/gradio-theme-cache
Gradio theme cache
2023-08-06 06:37:48 +03:00
catboxanon
1e8482356c Merge branch 'dev' into sigma-infotext 2023-08-05 23:37:38 -04:00
w-e-w
e9c591b101 Gradio theme cache 2023-08-06 12:33:20 +09:00
AUTOMATIC1111
ee96a6a588 do the same for s_tmax #12345 2023-08-06 06:32:41 +03:00
AUTOMATIC1111
92b99f3273
Merge pull request #12354 from catboxanon/fix/s-noise
Allow `s_noise` override to actually be used
2023-08-06 06:26:57 +03:00
AUTOMATIC1111
ee75416e3e
Merge branch 'dev' into fix/s-noise 2023-08-06 06:25:35 +03:00
AUTOMATIC1111
d86d12e911 rework saving incomplete images 2023-08-06 06:21:36 +03:00
AUTOMATIC1111
2844d9597b
Merge pull request #12338 from AUTOMATIC1111/dont-save-incomplete-images
don't save incomplete images
2023-08-06 06:05:47 +03:00
AUTOMATIC1111
dd1e2726f3
Merge pull request #12352 from bannsec/bannsec-patch-1
Update README.md
2023-08-06 06:05:28 +03:00
catboxanon
f18a032190 Correct s_noise fix 2023-08-05 23:05:25 -04:00
AUTOMATIC1111
9cbde6c9fd
Merge pull request #12356 from catboxanon/fix/s-churn-max
Increase `s_churn` max value
2023-08-06 05:56:05 +03:00
AUTOMATIC1111
f4e4992a4a
Merge pull request #12357 from catboxanon/s-tmax
Add option for `s_tmax`
2023-08-06 05:55:20 +03:00
catboxanon
31506f0771 Add sigma params to infotext 2023-08-05 22:37:25 -04:00
catboxanon
85c2c138d2 Attempt to read s_tmax from arg first if option not found 2023-08-05 21:51:46 -04:00
catboxanon
c11104fed5 Add s_tmax 2023-08-05 21:42:03 -04:00
catboxanon
dfc01c68cd
Increase s_churn max value 2023-08-05 21:23:58 -04:00
catboxanon
496cef956b Allow s_noise override to actually be used 2023-08-05 21:14:13 -04:00
bannsec
b315c20756
Update README.md
Correct install instructions on linux and provide additional required apt packages
Fixes #12351
2023-08-05 14:07:35 -04:00
AUTOMATIC1111
c6278c15a8 add explanation for gradio themes 2023-08-05 17:11:37 +03:00
AUTOMATIC1111
0a0a6b2a4d
Merge pull request #12346 from dhwz/dev
add new gradio themes
2023-08-05 17:08:38 +03:00
dhwz
1f7fc4d7a3 fix whitespace 2023-08-05 16:07:57 +02:00
dhwz
8ece321df3 add new gradio themes 2023-08-05 16:03:06 +02:00
w-e-w
1d7dcdb6c3 Option to not save incomplete images 2023-08-05 19:07:53 +09:00
AUTOMATIC1111
60183eebc3 add description to VAE setting page 2023-08-05 11:18:13 +03:00
AUTOMATIC1111
36ca80d004 put VAE into a separate settings page 2023-08-05 10:43:06 +03:00
AUTOMATIC1111
3f451f3042 do not add VAE Encoder/Decoder to infotext if it's the default 2023-08-05 10:36:26 +03:00
AUTOMATIC1111
c980dca234
Merge pull request #12331 from AUTOMATIC1111/need_Reload-UI_not_Restart
only need Reload UI not Restart
2023-08-05 09:37:18 +03:00
AUTOMATIC1111
f879cac1e7
Merge pull request #12311 from AUTOMATIC1111/efficient-vae-methods
Add TAESD(or more) options for all the VAE encode/decode operation
2023-08-05 09:24:26 +03:00
AUTOMATIC1111
ad510b2cd3 fix refresh button for styles 2023-08-05 09:17:36 +03:00
AUTOMATIC1111
c74c708ed8 add checkbox to show/hide dirs for extra networks 2023-08-05 09:15:18 +03:00
AUTOMATIC1111
e053e21af6 put localStorage stuff into its own file 2023-08-05 08:48:03 +03:00
w-e-w
7a64601428 need Reload UI not Restart 2023-08-05 14:21:28 +09:00
Kohaku-Blueleaf
b85ec2b9b6 Fix some merge mistakes 2023-08-05 13:14:00 +08:00
Kohaku-Blueleaf
d56a9cfe6a Merge branch 'dev' into efficient-vae-methods 2023-08-05 13:12:37 +08:00
AUTOMATIC1111
a32f270a47
Merge pull request #11808 from AUTOMATIC1111/extra-networks-always-visible
Always show extra networks tabs in the UI
2023-08-05 08:07:26 +03:00
AUTOMATIC1111
8197f24dbc remove the extra networks button 2023-08-05 08:07:13 +03:00
AUTOMATIC1111
ef1698fd6d Merge branch 'dev' into extra-networks-always-visible 2023-08-05 08:01:38 +03:00
Splendide Imaginarius
56888644a6 Reduce mask blur kernel size to 2.5 sigmas
This more closely matches the old behavior of PIL's Gaussian blur, and
fixes breakage when tiling.

See https://github.com/Coyote-A/ultimate-upscale-for-automatic1111/issues/111#issuecomment-1663504109

Thanks to Алексей Трофимов and eunnone for reporting the issue.
2023-08-05 04:54:23 +00:00
AUTOMATIC1111
c613416af3
Merge pull request #12227 from AUTOMATIC1111/multiple_loaded_models
option to keep multiple models in memory
2023-08-05 07:52:50 +03:00
AUTOMATIC1111
22ecb78b51 Merge branch 'dev' into multiple_loaded_models 2023-08-05 07:52:29 +03:00
Kohaku-Blueleaf
a6b245e46f dix 2023-08-05 12:49:35 +08:00
AUTOMATIC1111
0ae2767ae6
Merge pull request #12181 from AUTOMATIC1111/hires_checkpoint
Hires fix change checkpoint
2023-08-05 07:47:34 +03:00
AUTOMATIC1111
e64263653a
Merge pull request #12327 from catboxanon/fix/filename-invalid-chars
Add tab and carriage return to invalid filename chars
2023-08-05 07:47:07 +03:00
AUTOMATIC1111
d2b842ce07 move img2img settings to their own section 2023-08-05 07:46:22 +03:00
Kohaku-Blueleaf
d8371d0b3c update info 2023-08-05 12:37:46 +08:00
AUTOMATIC1111
e7140a36c0 change default color to white 2023-08-05 07:36:25 +03:00
Kohaku-Blueleaf
aa744cadc8 add infotext 2023-08-05 12:35:40 +08:00
AUTOMATIC1111
63cac3c3cc
Merge pull request #12326 from AUTOMATIC1111/configurable-masks-color-and-default-brush-color-
configurable masks color and default brush color
2023-08-05 07:34:22 +03:00
catboxanon
bcff763b6e
Add tab and carriage return to invalid filename chars 2023-08-04 22:59:47 -04:00
Kohaku-Blueleaf
9ac2989edd Merge branch 'dev' into efficient-vae-methods 2023-08-05 10:43:17 +08:00
w-e-w
1d60a609a9 configurable masks color and default brush color 2023-08-05 09:34:26 +09:00
AUTOMATIC1111
4560176640 added VAE selection to checkpoint user metadata 2023-08-04 22:05:50 +03:00
AUTOMATIC1111
31a9966b9d
Merge pull request #12319 from catboxanon/fix/alternating-words-empty
Prompt parser: Account for empty field in alternating words syntax
2023-08-04 20:35:25 +03:00
AUTOMATIC1111
c57cb6e89c
Merge pull request #12318 from catboxanon/sysinfo-new-page
Open raw sysinfo link in new page
2023-08-04 20:31:10 +03:00
catboxanon
b6596cdb19
Prompt parser: account for empty field in alternating words syntax 2023-08-04 13:26:37 -04:00
catboxanon
9213d5cb3b
Open raw sysinfo link in new page 2023-08-04 12:26:37 -04:00
AUTOMATIC1111
682ff8936d glorious, glorious wonderful clear milky white butter smooth color for inpainting
you are the best, gradio
how I yearned for this day
i always believed in you
i knew you had it in you
this day marks a new beginning
thank you, everyone
thank you
2023-08-04 18:51:25 +03:00
AUTOMATIC1111
f08a69e629
Merge pull request #12310 from catboxanon/fix/gradio-3-39-0-textbox-overflow
Fix Gradio 3.39.0 textbox overflow
2023-08-04 15:55:25 +03:00
AUTOMATIC1111
fadbab3781 Curse you, gradio!!! fixes broken refresh button #12309 2023-08-04 14:56:39 +03:00
catboxanon
3ca3c7f1c6
Add styling for script components 2023-08-04 07:20:32 -04:00
catboxanon
daee41e0d6
Fix Gradio 3.39.0 textbox overflow 2023-08-04 06:45:12 -04:00
Kohaku-Blueleaf
21000f13a1 replace get_first_stage_encoding 2023-08-04 18:23:14 +08:00
AUTOMATIC1111
a0e74c4db4
Merge pull request #12308 from catboxanon/fix/gradio-3-39-0-inpaint-mask
Fix inpaint mask for Gradio 3.39.0
2023-08-04 13:16:50 +03:00
Kohaku-Blueleaf
073342c887 remove noneed scale 2023-08-04 17:55:52 +08:00
Kohaku-Blueleaf
6346d8eeaa Revert "change all encode"
This reverts commit 094c416a801b16c7d8e1944e2e9fae2c9e98bf12.
2023-08-04 17:53:30 +08:00
Kohaku-Blueleaf
094c416a80 change all encode 2023-08-04 17:53:16 +08:00
catboxanon
99f5f8e76b
Fix string quotes 2023-08-04 05:47:25 -04:00
catboxanon
cd4e053e5e
Simply img2img mask conversion, fix threshold 2023-08-04 05:43:53 -04:00
catboxanon
2dc2bc4ab5
Fix string quotes 2023-08-04 05:40:13 -04:00
catboxanon
e219211ff6
Remove unused import in img2img 2023-08-04 05:35:47 -04:00
catboxanon
df9fd1d3ae
Fix inpaint mask for Gradio 3.39.0 2023-08-04 05:31:38 -04:00
AUTOMATIC1111
2e613a6ffc
Merge pull request #12304 from catboxanon/fix/extras-infotext-paste
Correctly toggle extras checkbox for infotext paste
2023-08-04 12:04:11 +03:00
catboxanon
f5994e84a2
Cleanup extras checkbox infotext paste check 2023-08-04 04:57:01 -04:00
AUTOMATIC1111
c93857922a
Merge pull request #12201 from AnyISalIn/dev
fix: sdxl model invalid configuration after the hijack
2023-08-04 11:53:19 +03:00
AUTOMATIC1111
6391128b41
Merge pull request #12306 from catboxanon/fix/hires-infotext-paste
Only enable hires fix if hires scale or upscaler found in params for infotext paste
2023-08-04 11:52:17 +03:00
catboxanon
7c5480eb96
Cleanup hr infotext paste check mk2 2023-08-04 04:42:35 -04:00
catboxanon
67312653d7
Cleanup hr infotext paste check 2023-08-04 04:40:56 -04:00
AUTOMATIC1111
e81b431701
Merge pull request #12307 from daxijiu/dev
fix some content are ignore by localization
2023-08-04 11:33:34 +03:00
daxijiu
695300929a
Merge pull request #1 from daxijiu/fix-some-content-are-ignore-by-localization
fix some content  are ignore by localization
2023-08-04 16:12:41 +08:00
daxijiu
82b415c9c1
fix some content are ignore by localization
in setting "Face restoration model" and "Select which Real-ESRGAN models" and in extras "upscaler 1 & 2" are ignore by localization
2023-08-04 16:03:49 +08:00
catboxanon
d89a915b74
Only enable hr fix if hr scale or upscale in infotext on paste 2023-08-04 04:03:37 -04:00
catboxanon
ac8dfd9386
Toggle extras checkbox for infotext paste 2023-08-04 03:52:22 -04:00
Kohaku-Blueleaf
1f6bfdea80 move the modified decode into smapler_common 2023-08-04 14:38:52 +08:00
Kohaku-Blueleaf
70e66e81e5 Merge branch 'dev' into efficient-vae-methods 2023-08-04 14:38:16 +08:00
AUTOMATIC1111
f0c1063a70 resolve some of circular import issues for kohaku 2023-08-04 09:13:46 +03:00
AUTOMATIC1111
09165916fa
Merge pull request #12297 from AUTOMATIC1111/sort-VAE
sort VAE
2023-08-04 08:53:47 +03:00
Kohaku-Blueleaf
c134a48016 Fix code style 2023-08-04 13:40:20 +08:00
Kohaku-Blueleaf
75336dfc84 add TAESD for i2i and t2i 2023-08-04 13:38:52 +08:00
AUTOMATIC1111
3f9e09a615
Merge pull request #11831 from wzgrx/dev
Dev The requirements.txt installation version is required to be updated. I have tested the latest version and SD can be used normally
2023-08-04 08:12:33 +03:00
AUTOMATIC1111
01486f6896
Merge pull request #12300 from catboxanon/dev
Add exponential scheduler variant to sampler selection for DPM-Solver++(2M) SDE sampler
2023-08-04 08:11:13 +03:00
AUTOMATIC1111
56c3f94ba3
Merge branch 'dev' into dev 2023-08-04 08:05:21 +03:00
AUTOMATIC1111
073c0ebba3 add gradio version warning 2023-08-04 08:04:23 +03:00
AUTOMATIC1111
362789a379 gradio 3.39 2023-08-04 08:04:23 +03:00
w-e-w
7f1d087cba sort VAE 2023-08-04 14:01:22 +09:00
catboxanon
3bd2c68eb4
Add exponential scheduler for DPM-Solver++(2M) SDE
Better quality results than Karras.
Related discussion: https://gist.github.com/crowsonkb/3ed16fba35c73ece7cf4b9a2095f2b78
2023-08-04 00:51:49 -04:00
AUTOMATIC1111
71efc5bda8
Merge pull request #12298 from catboxanon/xyz-sampler
XYZ: Support hires sampler
2023-08-04 07:47:35 +03:00
w-e-w
f4d9297127 use samplers_for_img2img for Hires sampler 2023-08-04 13:27:25 +09:00
AUTOMATIC1111
220e298417
Merge pull request #12294 from AUTOMATIC1111/cmd_arg-disable-extensions
add cmd_arg --disable-extensions all extra
2023-08-04 07:26:34 +03:00
catboxanon
f7813fad1c
XYZ: Use default label format for hires sampler
If both sampler and hires sampler are used this makes the distinction more clear.
2023-08-04 00:19:30 -04:00
catboxanon
8b37734244
XYZ: Support hires sampler, cleanup 2023-08-04 00:10:14 -04:00
w-e-w
bbfff771d7 --disable-all-extensions --disable-extra-extensions 2023-08-04 12:44:52 +09:00
AnyISalIn
24f21583cd fix: prevent cache model.state_dict() after model hijack
Signed-off-by: AnyISalIn <anyisalin@gmail.com>
2023-08-04 11:43:27 +08:00
AUTOMATIC1111
09c1be9674 put some of the shared functionality into toprow
write a comment for the toprow
2023-08-03 23:31:14 +03:00
AUTOMATIC1111
af528552d6 fix linter issues 2023-08-03 23:31:14 +03:00
AUTOMATIC1111
20549a50cb add style editor dialog
rework toprow for img2img and txt2img to use a class with fields
fix the console error when editing checkpoint user metadata
2023-08-03 23:31:13 +03:00
AUTOMATIC1111
8e840e1519
Merge pull request #12269 from AUTOMATIC1111/TI-Hash-fix
fix missing TI hash
2023-08-03 12:56:19 +03:00
w-e-w
f56a309432 fix missing TI hash 2023-08-03 18:46:49 +09:00
AUTOMATIC1111
0904df84e2 minor performance improvements for philox 2023-08-03 07:53:03 +03:00
AUTOMATIC1111
fca42949a3 rework torchsde._brownian.brownian_interval replacement to use device.randn_local and respect the NV setting. 2023-08-03 07:18:55 +03:00
Splendide Imaginarius
a1825ee741 Make StableDiffusionProcessingImg2Img.mask_blur a property
Fixes breakage when mask_blur is set after construction.

See https://github.com/Coyote-A/ultimate-upscale-for-automatic1111/issues/111#issuecomment-1652091424

Thanks to Алексей Трофимов and eunnone for reporting the issue.
2023-08-03 02:07:00 +00:00
AUTOMATIC1111
84b6fcd02c add NV option for Random number generator source setting, which allows to generate same pictures on CPU/AMD/Mac as on NVidia videocards. 2023-08-03 00:00:23 +03:00
AUTOMATIC1111
ccb9233934 add yet another torch_gc to reclaim some of VRAM after the initial stage of img2img 2023-08-02 18:53:09 +03:00
AUTOMATIC1111
10ff071e33 update doggettx cross attention optimization to not use an unreasonable amount of memory in some edge cases -- suggestion by MorkTheOrk 2023-08-02 18:37:16 +03:00
AUTOMATIC1111
390bffa81b repair merge error 2023-08-01 17:13:15 +03:00
AUTOMATIC1111
0c9b1e7969 Merge branch 'dev' into multiple_loaded_models 2023-08-01 16:55:55 +03:00
AUTOMATIC1111
6a0d498c8e support tooltip kwarg for gradio elements 2023-08-01 12:50:23 +03:00
AUTOMATIC1111
401ba1b879 XYZ plot do not fail if an exception occurs 2023-08-01 09:22:53 +03:00
AUTOMATIC1111
07be13caa3 add metadata to checkpoint merger 2023-08-01 08:27:54 +03:00
AUTOMATIC1111
6d3a0c9506 move checkpoint merger UI to its own file 2023-08-01 07:43:43 +03:00
AUTOMATIC1111
0042954490 Split history: mv temp modules/ui.py 2023-08-01 07:15:16 +03:00
AUTOMATIC1111
8a4149accc Split history: merge 2023-08-01 07:15:16 +03:00
AUTOMATIC1111
b98fa1c397 Split history: mv modules/ui.py temp 2023-08-01 07:15:15 +03:00
AUTOMATIC1111
c6b826d796 Split history: mv modules/ui.py modules/ui_checkpoint_merger.py 2023-08-01 07:15:15 +03:00
AUTOMATIC1111
2860c3be3e add filename to to the table in user metadata editor 2023-08-01 07:10:42 +03:00
AUTOMATIC1111
4b43480fe8 show metadata for SD checkpoints in the extra networks UI 2023-08-01 07:08:11 +03:00
Jabasukuriputo Wang
8b036d8a82
fix 2023-08-01 11:26:59 +08:00
Jabasukuriputo Wang
c46525b70b
fix exception 2023-08-01 11:26:17 +08:00
Jabasukuriputo Wang
955542a654
also check on rev-parse 2023-08-01 11:24:54 +08:00
Jabasukuriputo Wang
2f1d5b6b04
attempt to fix workspace status when doing git clone 2023-08-01 11:20:59 +08:00
AUTOMATIC1111
151b8ed3a6 repair PLMS 2023-08-01 00:38:34 +03:00
AUTOMATIC1111
b235022c61 option to keep multiple models in memory 2023-08-01 00:24:48 +03:00
AUTOMATIC1111
c10633f93a fix memory leak when generation fails 2023-07-31 22:03:05 +03:00
AUTOMATIC1111
0d577aba26
Merge pull request #12207 from akx/local-storage-guard
Don't crash if out of local storage quota
2023-07-31 14:00:49 +03:00
AUTOMATIC1111
c09bc2c608 fix "clamp_scalar_cpu" not implemented for 'Half' 2023-07-31 13:20:26 +03:00
Aarni Koskela
fb87a05fe8 Don't crash if out of local storage quota
Fixes #12206 (works around it)
2023-07-31 11:23:26 +02:00
AUTOMATIC1111
4d9b096663 additional memory improvements when switching between models of different types 2023-07-31 10:43:31 +03:00
AUTOMATIC1111
29d7e31d89 repair AttributeError: 'NoneType' object has no attribute 'conditioning_key' 2023-07-31 10:43:26 +03:00
AUTOMATIC1111
dca121e903 set the field to None instead 2023-07-31 09:13:07 +03:00
AUTOMATIC1111
0af4127fd1 delete the field that is preventing the model from being unloaded and is causing increased RAM usage 2023-07-30 19:36:24 +03:00
AUTOMATIC1111
a1eb49627a
Merge pull request #12177 from rubberbaron/prompt-parse-whitespace-around-numbers
add support for whitespace after the number in constructions like [fo…
2023-07-30 17:23:19 +03:00
AUTOMATIC1111
02038036ff make it so that VAE NaNs autodetection also works during first pass of hires fix 2023-07-30 16:16:31 +03:00
AUTOMATIC1111
f60d9fbe29
Merge pull request #12178 from rubberbaron/xyz-grid-remove-dir
xyz_grid: in the axis labels, remove pathnames from model filenames
2023-07-30 15:32:34 +03:00
AUTOMATIC1111
cc53db6652 this time for sure 2023-07-30 15:30:33 +03:00
AUTOMATIC1111
a64fbe8928 make it possible to use checkpoints of different types (SD1, SDXL) in first and second pass of hires fix 2023-07-30 15:12:09 +03:00
AUTOMATIC1111
eec540b227 repair non-latent upscaling broken for SDXL 2023-07-30 15:04:12 +03:00
AUTOMATIC1111
77761e7bad linter 2023-07-30 14:10:33 +03:00
AUTOMATIC1111
40cd59207b make it work with SDXL 2023-07-30 14:10:26 +03:00
AUTOMATIC1111
3bca90b249 hires fix checkpoint selection 2023-07-30 13:48:27 +03:00
Robert Barron
c4ee6d9b73 xyz_grid: allow varying the seed along an axis along with the axis's other changes 2023-07-30 03:45:02 -07:00
Robert Barron
085c903229 xyz_grid: in the legend, remove pathnames from model filenames 2023-07-30 03:35:32 -07:00
Robert Barron
8a40e30d08 add support for whitespace after the number in constructions like [foo:bar: 0.5 ] and (foo : 0.5 ) 2023-07-30 01:46:25 -07:00
AUTOMATIC1111
63a8861c19
Merge pull request #12164 from AUTOMATIC1111/rework-img2img-batch-image-save
Rework img2img batch image save
2023-07-30 11:45:33 +03:00
w-e-w
fb44838176 strip output_dir 2023-07-30 14:47:24 +09:00
w-e-w
53ccdefc01 don't override default if output_dir is blank 2023-07-30 00:34:04 +09:00
w-e-w
9857537053 lint 2023-07-30 00:06:25 +09:00
w-e-w
b95a41ad72 rework img2img batch image save 2023-07-30 00:02:31 +09:00
AUTOMATIC1111
6f0abbb71a textual inversion support for SDXL 2023-07-29 15:15:06 +03:00
AUTOMATIC1111
4ca9f70b59
Merge pull request #11950 from AnyISalIn/dev
feat: add refresh vae api
2023-07-29 09:37:02 +03:00
AUTOMATIC1111
e18fc29bbf put the entry for the sampler in the readme section in order of addition 2023-07-29 08:40:43 +03:00
AUTOMATIC1111
79d6e9cd32 some stylistic changes for the sampler code 2023-07-29 08:38:00 +03:00
AUTOMATIC1111
aefe1325df split the new sampler into a different file 2023-07-29 08:11:59 +03:00
AUTOMATIC1111
11dc92dc0a Split history: mv temp modules/sd_samplers_kdiffusion.py 2023-07-29 08:06:04 +03:00
AUTOMATIC1111
bdeb44aeb2 Split history: merge 2023-07-29 08:06:03 +03:00
AUTOMATIC1111
e1323fc1b7 Split history: mv modules/sd_samplers_kdiffusion.py temp 2023-07-29 08:06:03 +03:00
AUTOMATIC1111
3ac950248d Split history: mv modules/sd_samplers_kdiffusion.py modules/sd_samplers_extra.py 2023-07-29 08:06:03 +03:00
AUTOMATIC1111
bef40851af
Merge pull request #11850 from lambertae/restart_sampling
Restart sampling
2023-07-29 08:03:32 +03:00
AUTOMATIC1111
9a52a30d2f
Merge pull request #12107 from JetVarimax/patch-2
Fix typo
2023-07-29 07:49:22 +03:00
AUTOMATIC1111
fc163218c4
Merge pull request #12120 from DiabolicDiabetic/patch-2
IMG2IMG TIF batch fix img2img.py
2023-07-29 07:48:44 +03:00
AUTOMATIC1111
19ac0adf03
Merge pull request #12124 from Xstephen/master
Add total_tqdm clear in the end of txt2img & img2img api.
2023-07-29 07:44:00 +03:00
AUTOMATIC1111
ac81c1dd1f
Merge pull request #11958 from AUTOMATIC1111/conserve-ram
Use less RAM when creating models
2023-07-29 07:43:04 +03:00
caoxipeng
6cc5a886ae Add total_tqdm clear in the end of txt2img & img2img api. 2023-07-28 11:40:10 +08:00
DiabolicDiabetic
9cbf3461f7
IMG2IMG TIF batch fix img2img.py
IMG2IMG batch tab wouldn't process tif images
2023-07-27 20:15:50 -05:00
AUTOMATIC1111
25004d4eee Merge branch 'master' into dev 2023-07-27 09:03:44 +03:00
AUTOMATIC1111
56236dfd3f Merge branch 'master' into release_candidate 2023-07-27 09:03:26 +03:00
AUTOMATIC1111
91a131aa6c update lora extension to work with python 3.8 2023-07-27 09:00:47 +03:00
AUTOMATIC1111
0cb9711a15
Merge pull request #12020 from Littleor/dev
Fix the error in rendering the name and description in the extra network UI.
2023-07-26 15:17:37 +03:00
AUTOMATIC1111
89e6dfff71 repair SDXL 2023-07-26 15:07:56 +03:00
AUTOMATIC1111
8284ebd94c fix autograd which i broke for no good reason when implementing SDXL 2023-07-26 13:03:52 +03:00
Littleor
187323a606 fix: extra network ui description allow HTML tags 2023-07-26 17:23:57 +08:00
AUTOMATIC1111
deed8439d5
Merge pull request #12032 from AUTOMATIC1111/fix-api-get-options-sd_model_checkpoint
api /sdapi/v1/options use "Any" type when default type is None
2023-07-26 11:52:42 +03:00
w-e-w
6305632493 use "Any" type when type is None 2023-07-26 17:20:04 +09:00
AUTOMATIC1111
246d1f1f70 delete scale checker script due to user demand 2023-07-26 09:19:46 +03:00
AUTOMATIC1111
ca6f90dc6d
Merge pull request #12023 from AUTOMATIC1111/create_infotext_fix
Create infotext fix
2023-07-26 08:07:07 +03:00
AUTOMATIC1111
835a7dbf0e simplify PostprocessBatchListArgs 2023-07-26 07:49:57 +03:00
AUTOMATIC1111
225eb1b1a0
Merge pull request #12024 from AUTOMATIC1111/fix-check-for-updates-status-always-unknown-
fix check for updates status always "unknown"
2023-07-26 07:45:48 +03:00
w-e-w
b8a903efbe fix check for updates status always "unknown" 2023-07-26 13:43:38 +09:00
AUTOMATIC1111
7c22bbd3ad attempt 2 2023-07-26 07:04:07 +03:00
AUTOMATIC1111
13e371af73 doc update 2023-07-26 06:37:13 +03:00
AUTOMATIC1111
ae36e0899f alternative solution for infotext issue 2023-07-26 06:36:06 +03:00
Littleor
b73c405013 fix: error rendering name and description in extra network ui 2023-07-26 11:02:34 +08:00
lambertae
8de6d3ff77 fix progress bar & torchHijack 2023-07-25 22:35:43 -04:00
JetVarimax
fd43558586
Fix typo 2023-07-25 20:31:15 +01:00
AUTOMATIC1111
d0bf509fa1 fix for #11963 2023-07-25 16:18:10 +03:00
AUTOMATIC1111
d6ec08ba89
Merge pull request #11963 from catboxanon/fix/lora-te
Fix parsing text encoder blocks in some LoRAs
2023-07-25 16:17:41 +03:00
AUTOMATIC1111
65bf3ba260
Merge pull request #11979 from AUTOMATIC1111/catch-exception-for-non-git-extensions
catch exception for non git extensions
2023-07-25 15:23:35 +03:00
AUTOMATIC1111
bed598ce7f
Merge pull request #11984 from AUTOMATIC1111/api-only-subpath-(root_path)
api only subpath (rootpath)
2023-07-25 15:19:10 +03:00
w-e-w
b1a16a298c api only subpath (rootpath)
Co-Authored-By: 陈杰 <pythias@gmail.com>
2023-07-25 20:51:27 +09:00
w-e-w
fee593a07f catch exception for non git extensions 2023-07-25 20:01:10 +09:00
AUTOMATIC1111
fc8e23dec5 Merge branch 'master' into dev 2023-07-25 08:20:42 +03:00
catboxanon
a68f469030
Fix to parse TE in some LoRAs 2023-07-24 17:54:59 -04:00
AUTOMATIC1111
f7c0a963f1
Merge pull request #11957 from ljleb/pp-batch-list
Add postprocess_batch_list script callback
2023-07-24 23:18:16 +03:00
ljleb
5b06607476 simplify 2023-07-24 15:43:06 -04:00
ljleb
6b68b59032 use local vars 2023-07-24 15:38:52 -04:00
AUTOMATIC1111
0a89cd1a58 Use less RAM when creating models 2023-07-24 22:08:08 +03:00
ljleb
ca45ff1ae6 add postprocess_batch_list callback 2023-07-24 13:52:24 -04:00
AnyISalIn
1cbfafafd2 feat: add refresh vae api
Signed-off-by: AnyISalIn <anyisalin@gmail.com>
2023-07-24 19:45:08 +08:00
AUTOMATIC1111
f451994053 Merge branch 'release_candidate' into dev 2023-07-24 11:58:15 +03:00
Jabasukuriputo Wang
f2a4073aea
Merge branch 'dev' into ext-inst-pbar 2023-07-23 23:32:13 +08:00
AUTOMATIC1111
ec83db8978 restyle Startup profile for black users 2023-07-22 17:15:38 +03:00
AUTOMATIC1111
a8d4213317 add --log-startup option to print detailed startup progress 2023-07-22 17:15:38 +03:00
Jabasukuriputo Wang
9421c11346
Merge branch 'dev' into ext-inst-pbar 2023-07-22 21:58:59 +08:00
AUTOMATIC1111
0615b3c532
Merge pull request #11926 from wfjsw/fix-env-get-1
fix 11291#issuecomment-1646547908
2023-07-22 16:37:03 +03:00
AUTOMATIC1111
2d635c0192
Merge pull request #11927 from ljleb/fix-AND
Fix composable diffusion weight parsing
2023-07-22 16:36:40 +03:00
ljleb
88a3e1d306 fix AND linebreaks 2023-07-22 07:40:30 -04:00
ljleb
0674fabd0d fix AND linebreaks 2023-07-22 07:10:20 -04:00
AUTOMATIC1111
c76a30af41 more info for startup timings 2023-07-22 13:49:29 +03:00
Jabasukuriputo Wang
3c26734d60
nop 2023-07-22 18:33:59 +08:00
Jabasukuriputo Wang
2a7e34fe79
fix https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/11921#issuecomment-1646547908 2023-07-22 18:09:00 +08:00
Jabasukuriputo Wang
b2f0040da7
fix tqdm not found on new instance 2023-07-22 17:51:15 +08:00
Jabasukuriputo Wang
7afe7375e1
display a progressbar for extension installer 2023-07-22 17:46:50 +08:00
AUTOMATIC1111
90eb731ff1 start timer early anyway 2023-07-22 12:21:05 +03:00
AUTOMATIC1111
491d42bb1c
Merge pull request #11856 from wfjsw/move-start-timer
Only start timer when actually starting
2023-07-22 12:19:36 +03:00
AUTOMATIC1111
45c0f58dc6
Merge pull request #11923 from AnyISalIn/dev
[bug] If txt2img/img2img raises an exception, finally call state.end()
2023-07-22 07:03:21 +03:00
AnyISalIn
1fe2dcaa2a [bug] If txt2img/img2img raises an exception, finally call state.end()
Signed-off-by: AnyISalIn <anyisalin@gmail.com>
2023-07-22 10:00:27 +08:00
AUTOMATIC1111
075934a944
Merge pull request #11920 from wfjsw/typo-fix-1
typo fix
2023-07-21 18:01:20 +03:00
AUTOMATIC1111
ed4d7912c7
Merge pull request #11921 from wfjsw/prepend-pythonpath
prepend the pythonpath instead of overriding it
2023-07-21 18:00:03 +03:00
Jabasukuriputo Wang
16eddc622e
prepend the pythonpath instead of overriding it 2023-07-21 22:00:03 +08:00
w-e-w
bc91f15ed3 typo fix 2023-07-21 22:56:41 +09:00
Jabasukuriputo Wang
118529a6dc
typo fix 2023-07-21 21:49:33 +08:00
Jabasukuriputo Wang
33694baea1
avoid importing timer when it is not strictly needed 2023-07-21 17:15:44 +08:00
lambertae
f873890298 new restart scheme 2023-07-20 21:27:43 -04:00
lambertae
128d59c9cc fix ruff 2023-07-20 20:36:40 -04:00
lambertae
2f57a559ac allow choise of restart_list & use karras from kdiffusion 2023-07-20 20:34:41 -04:00
AUTOMATIC1111
2f98f7c924 Merge branch 'release_candidate' into dev 2023-07-20 19:16:55 +03:00
lambertae
6233268964 add credit 2023-07-20 02:27:28 -04:00
lambertae
ddbf4a73f5 restart-sampler with correct steps 2023-07-20 02:24:18 -04:00
AUTOMATIC1111
4bf64976c1 Merge branch 'release_candidate' into dev 2023-07-19 20:23:48 +03:00
AUTOMATIC1111
5677296d1b
Merge pull request #11878 from Bourne-M/patch-1
【bug】reload altclip model error
2023-07-19 16:26:12 +03:00
yfzhou
cb75734896
【bug】reload altclip model error
When using BertSeriesModelWithTransformation as the cond_stage_model, the undo_hijack should be performed using the FrozenXLMREmbedderWithCustomWords type; otherwise, it will result in a failed model reload.
2023-07-19 17:53:28 +08:00
Jabasukuriputo Wang
fc3bdf8c11
Merge branch 'dev' into move-start-timer 2023-07-19 10:33:31 +08:00
AUTOMATIC1111
0fae47e974
Merge pull request #11867 from AUTOMATIC1111/add-dropdown-extra_sort_order-lable
add dropdown extra_sort_order lable
2023-07-18 23:23:26 +03:00
w-e-w
c278e60131 add dropdown extra_sort_order lable 2023-07-19 04:58:30 +09:00
wfjsw
3c570421d3 move start timer 2023-07-18 19:00:16 +08:00
lambertae
7bb0fbed13 code styling 2023-07-18 01:02:04 -04:00
lambertae
37e048a7e2 fix floating error 2023-07-18 00:55:02 -04:00
lambertae
15a94d6cf7 remove useless header 2023-07-18 00:39:26 -04:00
lambertae
40a18d38a8 add restart sampler 2023-07-18 00:32:01 -04:00
wzgrx
952effa8b1
Update requirements_versions.txt 2023-07-17 18:50:29 +08:00
wzgrx
0dcf6436a8
Update requirements.txt 2023-07-17 18:49:53 +08:00
AUTOMATIC1111
95c5c4d64e fix tabs height on small screens 2023-07-17 11:18:08 +03:00
w-e-w
543ea5730b fix extra search button 2023-07-17 16:35:41 +09:00
AUTOMATIC1111
643836007f more tweaking for cards section height 2023-07-16 14:46:05 +03:00
AUTOMATIC1111
24bad5dc7b change extra networks list to have constant height and scrolling 2023-07-16 13:59:15 +03:00
AUTOMATIC1111
57d61de25c fix unneded reload from disk 2023-07-16 11:52:29 +03:00
AUTOMATIC1111
5ef7590324 always show extra networks tabs in the UI 2023-07-16 11:38:59 +03:00
246 changed files with 21035 additions and 10639 deletions

View File

@ -74,9 +74,12 @@ module.exports = {
create_submit_args: "readonly",
restart_reload: "readonly",
updateInput: "readonly",
onEdit: "readonly",
//extraNetworks.js
requestGet: "readonly",
popup: "readonly",
// profilerVisualization.js
createVisualizationTable: "readonly",
// from python
localization: "readonly",
// progrssbar.js
@ -85,7 +88,11 @@ module.exports = {
// imageviewer.js
modalPrevImage: "readonly",
modalNextImage: "readonly",
// token-counters.js
setupTokenCounters: "readonly",
// localStorage.js
localSet: "readonly",
localGet: "readonly",
localRemove: "readonly",
// resizeHandle.js
setupResizeHandle: "writable"
}
};

View File

@ -1,35 +1,55 @@
name: Bug Report
description: You think somethings is broken in the UI
description: You think something is broken in the UI
title: "[Bug]: "
labels: ["bug-report"]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered, and that it hasn't been fixed in a recent build/commit.
options:
- label: I have searched the existing issues and checked the recent builds/commits
required: true
- type: markdown
attributes:
value: |
*Please fill this form with as much information as possible, don't forget to fill "What OS..." and "What browsers" and *provide screenshots if possible**
> The title of the bug report should be short and descriptive.
> Use relevant keywords for searchability.
> Do not leave it blank, but also do not put an entire error log in it.
- type: checkboxes
attributes:
label: Checklist
description: |
Please perform basic debugging to see if extensions or configuration is the cause of the issue.
Basic debug procedure
 1. Disable all third-party extensions - check if extension is the cause
 2. Update extensions and webui - sometimes things just need to be updated
 3. Backup and remove your config.json and ui-config.json - check if the issue is caused by bad configuration
 4. Delete venv with third-party extensions disabled - sometimes extensions might cause wrong libraries to be installed
 5. Try a fresh installation webui in a different directory - see if a clean installation solves the issue
Before making a issue report please, check that the issue hasn't been reported recently.
options:
- label: The issue exists after disabling all extensions
- label: The issue exists on a clean installation of webui
- label: The issue is caused by an extension, but I believe it is caused by a bug in the webui
- label: The issue exists in the current version of the webui
- label: The issue has not been reported before recently
- label: The issue has been reported before but has not been fixed yet
- type: markdown
attributes:
value: |
> Please fill this form with as much information as possible. Don't forget to "Upload Sysinfo" and "What browsers" and provide screenshots if possible
- type: textarea
id: what-did
attributes:
label: What happened?
description: Tell us what happened in a very clear and simple way
placeholder: |
txt2img is not working as intended.
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce the problem
description: Please provide us with precise step by step information on how to reproduce the bug
value: |
1. Go to ....
2. Press ....
description: Please provide us with precise step by step instructions on how to reproduce the bug
placeholder: |
1. Go to ...
2. Press ...
3. ...
validations:
required: true
@ -37,64 +57,9 @@ body:
id: what-should
attributes:
label: What should have happened?
description: Tell what you think the normal behavior should be
validations:
required: true
- type: input
id: commit
attributes:
label: Version or Commit where the problem happens
description: "Which webui version or commit are you running ? (Do not write *Latest Version/repo/commit*, as this means nothing and will have changed by the time we read your issue. Rather, copy the **Version: v1.2.3** link at the bottom of the UI, or from the cmd/terminal if you can't launch it.)"
validations:
required: true
- type: dropdown
id: py-version
attributes:
label: What Python version are you running on ?
multiple: false
options:
- Python 3.10.x
- Python 3.11.x (above, no supported yet)
- Python 3.9.x (below, no recommended)
- type: dropdown
id: platforms
attributes:
label: What platforms do you use to access the UI ?
multiple: true
options:
- Windows
- Linux
- MacOS
- iOS
- Android
- Other/Cloud
- type: dropdown
id: device
attributes:
label: What device are you running WebUI on?
multiple: true
options:
- Nvidia GPUs (RTX 20 above)
- Nvidia GPUs (GTX 16 below)
- AMD GPUs (RX 6000 above)
- AMD GPUs (RX 5000 below)
- CPU
- Other GPUs
- type: dropdown
id: cross_attention_opt
attributes:
label: Cross attention optimization
description: What cross attention optimization are you using, Settings -> Optimizations -> Cross attention optimization
multiple: false
options:
- Automatic
- xformers
- sdp-no-mem
- sdp
- Doggettx
- V1
- InvokeAI
- "None "
description: Tell us what you think the normal behavior should be
placeholder: |
WebUI should ...
validations:
required: true
- type: dropdown
@ -108,26 +73,25 @@ body:
- Brave
- Apple Safari
- Microsoft Edge
- Android
- iOS
- Other
- type: textarea
id: cmdargs
id: sysinfo
attributes:
label: Command Line Arguments
description: Are you using any launching parameters/command line arguments (modified webui-user .bat/.sh) ? If yes, please write them below. Write "No" otherwise.
render: Shell
validations:
required: true
- type: textarea
id: extensions
attributes:
label: List of extensions
description: Are you using any extensions other than built-ins? If yes, provide a list, you can copy it at "Extensions" tab. Write "No" otherwise.
label: Sysinfo
description: System info file, generated by WebUI. You can generate it in settings, on the Sysinfo page. Drag the file into the field to upload it. If you submit your report without including the sysinfo file, the report will be closed. If needed, review the report to make sure it includes no personal information you don't want to share. If you can't start WebUI, you can use --dump-sysinfo commandline argument to generate the file.
placeholder: |
1. Go to WebUI Settings -> Sysinfo -> Download system info.
If WebUI fails to launch, use --dump-sysinfo commandline argument to generate the file
2. Upload the Sysinfo as a attached file, Do NOT paste it in as plain text.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Console logs
description: Please provide **full** cmd/terminal logs from the moment you started UI to the end of it, after your bug happened. If it's very long, provide a link to pastebin or similar service.
description: Please provide **full** cmd/terminal logs from the moment you started UI to the end of it, after the bug occurred. If it's very long, provide a link to pastebin or similar service.
render: Shell
validations:
required: true
@ -135,4 +99,7 @@ body:
id: misc
attributes:
label: Additional information
description: Please provide us with any relevant additional info or context.
description: |
Please provide us with any relevant additional info or context.
Examples:
 I have updated my GPU driver recently.

View File

@ -11,8 +11,8 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- name: Checkout Code
uses: actions/checkout@v3
- uses: actions/setup-python@v4
uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.11
# NB: there's no cache: pip here since we're not installing anything
@ -20,7 +20,7 @@ jobs:
# not to have GHA download an (at the time of writing) 4 GB cache
# of PyTorch and other dependencies.
- name: Install Ruff
run: pip install ruff==0.0.272
run: pip install ruff==0.3.3
- name: Run Ruff
run: ruff .
lint-js:
@ -29,9 +29,9 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- name: Checkout Code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18
- run: npm i --ci

View File

@ -11,15 +11,21 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- name: Checkout Code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up Python 3.10
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.10.6
cache: pip
cache-dependency-path: |
**/requirements*txt
launch.py
- name: Cache models
id: cache-models
uses: actions/cache@v4
with:
path: models
key: "2023-12-30"
- name: Install test dependencies
run: pip install wait-for-it -r requirements-test.txt
env:
@ -33,6 +39,8 @@ jobs:
TORCH_INDEX_URL: https://download.pytorch.org/whl/cpu
WEBUI_LAUNCH_LIVE_OUTPUT: "1"
PYTHONUNBUFFERED: "1"
- name: Print installed packages
run: pip freeze
- name: Start test server
run: >
python -m coverage run
@ -49,7 +57,7 @@ jobs:
2>&1 | tee output.txt &
- name: Run tests
run: |
wait-for-it --service 127.0.0.1:7860 -t 600
wait-for-it --service 127.0.0.1:7860 -t 20
python -m pytest -vv --junitxml=test/results.xml --cov . --cov-report=xml --verify-base-url test
- name: Kill test server
if: always()
@ -60,13 +68,13 @@ jobs:
python -m coverage report -i
python -m coverage html -i
- name: Upload main app output
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: always()
with:
name: output
path: output.txt
- name: Upload coverage HTML
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: always()
with:
name: htmlcov

5
.gitignore vendored
View File

@ -2,6 +2,7 @@ __pycache__
*.ckpt
*.safetensors
*.pth
.DS_Store
/ESRGAN/*
/SwinIR/*
/repositories
@ -37,3 +38,7 @@ notification.mp3
/node_modules
/package-lock.json
/.coverage*
/test/test_outputs
/cache
trace.json
/sysinfo-????-??-??-??-??.json

View File

@ -1,3 +1,736 @@
## 1.10.1
### Bug Fixes:
* fix image upscale on cpu ([#16275](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16275))
## 1.10.0
### Features:
* A lot of performance improvements (see below in Performance section)
* Stable Diffusion 3 support ([#16030](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16030), [#16164](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16164), [#16212](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16212))
* Recommended Euler sampler; DDIM and other timestamp samplers currently not supported
* T5 text model is disabled by default, enable it in settings
* New schedulers:
* Align Your Steps ([#15751](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15751))
* KL Optimal ([#15608](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15608))
* Normal ([#16149](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16149))
* DDIM ([#16149](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16149))
* Simple ([#16142](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16142))
* Beta ([#16235](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16235))
* New sampler: DDIM CFG++ ([#16035](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16035))
### Minor:
* Option to skip CFG on early steps ([#15607](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15607))
* Add --models-dir option ([#15742](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15742))
* Allow mobile users to open context menu by using two fingers press ([#15682](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15682))
* Infotext: add Lora name as TI hashes for bundled Textual Inversion ([#15679](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15679))
* Check model's hash after downloading it to prevent corruped downloads ([#15602](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15602))
* More extension tag filtering options ([#15627](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15627))
* When saving AVIF, use JPEG's quality setting ([#15610](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15610))
* Add filename pattern: `[basename]` ([#15978](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15978))
* Add option to enable clip skip for clip L on SDXL ([#15992](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15992))
* Option to prevent screen sleep during generation ([#16001](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16001))
* ToggleLivePriview button in image viewer ([#16065](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16065))
* Remove ui flashing on reloading and fast scrollong ([#16153](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16153))
* option to disable save button log.csv ([#16242](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16242))
### Extensions and API:
* Add process_before_every_sampling hook ([#15984](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15984))
* Return HTTP 400 instead of 404 on invalid sampler error ([#16140](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16140))
### Performance:
* [Performance 1/6] use_checkpoint = False ([#15803](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15803))
* [Performance 2/6] Replace einops.rearrange with torch native ops ([#15804](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15804))
* [Performance 4/6] Precompute is_sdxl_inpaint flag ([#15806](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15806))
* [Performance 5/6] Prevent unnecessary extra networks bias backup ([#15816](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15816))
* [Performance 6/6] Add --precision half option to avoid casting during inference ([#15820](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15820))
* [Performance] LDM optimization patches ([#15824](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15824))
* [Performance] Keep sigmas on CPU ([#15823](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15823))
* Check for nans in unet only once, after all steps have been completed
* Added pption to run torch profiler for image generation
### Bug Fixes:
* Fix for grids without comprehensive infotexts ([#15958](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15958))
* feat: lora partial update precede full update ([#15943](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15943))
* Fix bug where file extension had an extra '.' under some circumstances ([#15893](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15893))
* Fix corrupt model initial load loop ([#15600](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15600))
* Allow old sampler names in API ([#15656](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15656))
* more old sampler scheduler compatibility ([#15681](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15681))
* Fix Hypertile xyz ([#15831](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15831))
* XYZ CSV skipinitialspace ([#15832](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15832))
* fix soft inpainting on mps and xpu, torch_utils.float64 ([#15815](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15815))
* fix extention update when not on main branch ([#15797](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15797))
* update pickle safe filenames
* use relative path for webui-assets css ([#15757](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15757))
* When creating a virtual environment, upgrade pip in webui.bat/webui.sh ([#15750](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15750))
* Fix AttributeError ([#15738](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15738))
* use script_path for webui root in launch_utils ([#15705](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15705))
* fix extra batch mode P Transparency ([#15664](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15664))
* use gradio theme colors in css ([#15680](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15680))
* Fix dragging text within prompt input ([#15657](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15657))
* Add correct mimetype for .mjs files ([#15654](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15654))
* QOL Items - handle metadata issues more cleanly for SD models, Loras and embeddings ([#15632](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15632))
* replace wsl-open with wslpath and explorer.exe ([#15968](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15968))
* Fix SDXL Inpaint ([#15976](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15976))
* multi size grid ([#15988](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15988))
* fix Replace preview ([#16118](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16118))
* Possible fix of wrong scale in weight decomposition ([#16151](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16151))
* Ensure use of python from venv on Mac and Linux ([#16116](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16116))
* Prioritize python3.10 over python3 if both are available on Linux and Mac (with fallback) ([#16092](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16092))
* stoping generation extras ([#16085](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16085))
* Fix SD2 loading ([#16078](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16078), [#16079](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16079))
* fix infotext Lora hashes for hires fix different lora ([#16062](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16062))
* Fix sampler scheduler autocorrection warning ([#16054](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16054))
* fix ui flashing on reloading and fast scrollong ([#16153](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16153))
* fix upscale logic ([#16239](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16239))
* [bug] do not break progressbar on non-job actions (add wrap_gradio_call_no_job) ([#16202](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16202))
* fix OSError: cannot write mode P as JPEG ([#16194](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16194))
### Other:
* fix changelog #15883 -> #15882 ([#15907](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15907))
* ReloadUI backgroundColor --background-fill-primary ([#15864](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15864))
* Use different torch versions for Intel and ARM Macs ([#15851](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15851))
* XYZ override rework ([#15836](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15836))
* scroll extensions table on overflow ([#15830](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15830))
* img2img batch upload method ([#15817](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15817))
* chore: sync v1.8.0 packages according to changelog ([#15783](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15783))
* Add AVIF MIME type support to mimetype definitions ([#15739](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15739))
* Update imageviewer.js ([#15730](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15730))
* no-referrer ([#15641](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15641))
* .gitignore trace.json ([#15980](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15980))
* Bump spandrel to 0.3.4 ([#16144](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16144))
* Defunct --max-batch-count ([#16119](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16119))
* docs: update bug_report.yml ([#16102](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16102))
* Maintaining Project Compatibility for Python 3.9 Users Without Upgrade Requirements. ([#16088](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16088), [#16169](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16169), [#16192](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16192))
* Update torch for ARM Macs to 2.3.1 ([#16059](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16059))
* remove deprecated setting dont_fix_second_order_samplers_schedule ([#16061](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16061))
* chore: fix typos ([#16060](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16060))
* shlex.join launch args in console log ([#16170](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16170))
* activate venv .bat ([#16231](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16231))
* add ids to the resize tabs in img2img ([#16218](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16218))
* update installation guide linux ([#16178](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16178))
* Robust sysinfo ([#16173](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16173))
* do not send image size on paste inpaint ([#16180](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16180))
* Fix noisy DS_Store files for MacOS ([#16166](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/16166))
## 1.9.4
### Bug Fixes:
* pin setuptools version to fix the startup error ([#15882](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15882))
## 1.9.3
### Bug Fixes:
* fix get_crop_region_v2 ([#15594](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15594))
## 1.9.2
### Extensions and API:
* restore 1.8.0-style naming of scripts
## 1.9.1
### Minor:
* Add avif support ([#15582](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15582))
* Add filename patterns: `[sampler_scheduler]` and `[scheduler]` ([#15581](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15581))
### Extensions and API:
* undo adding scripts to sys.modules
* Add schedulers API endpoint ([#15577](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15577))
* Remove API upscaling factor limits ([#15560](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15560))
### Bug Fixes:
* Fix images do not match / Coordinate 'right' is less than 'left' ([#15534](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15534))
* fix: remove_callbacks_for_function should also remove from the ordered map ([#15533](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15533))
* fix x1 upscalers ([#15555](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15555))
* Fix cls.__module__ value in extension script ([#15532](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15532))
* fix typo in function call (eror -> error) ([#15531](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15531))
### Other:
* Hide 'No Image data blocks found.' message ([#15567](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15567))
* Allow webui.sh to be runnable from arbitrary directories containing a .git file ([#15561](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15561))
* Compatibility with Debian 11, Fedora 34+ and openSUSE 15.4+ ([#15544](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15544))
* numpy DeprecationWarning product -> prod ([#15547](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15547))
* get_crop_region_v2 ([#15583](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15583), [#15587](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15587))
## 1.9.0
### Features:
* Make refiner switchover based on model timesteps instead of sampling steps ([#14978](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14978))
* add an option to have old-style directory view instead of tree view; stylistic changes for extra network sorting/search controls
* add UI for reordering callbacks, support for specifying callback order in extension metadata ([#15205](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15205))
* Sgm uniform scheduler for SDXL-Lightning models ([#15325](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15325))
* Scheduler selection in main UI ([#15333](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15333), [#15361](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15361), [#15394](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15394))
### Minor:
* "open images directory" button now opens the actual dir ([#14947](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14947))
* Support inference with LyCORIS BOFT networks ([#14871](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14871), [#14973](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14973))
* make extra network card description plaintext by default, with an option to re-enable HTML as it was
* resize handle for extra networks ([#15041](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15041))
* cmd args: `--unix-filenames-sanitization` and `--filenames-max-length` ([#15031](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15031))
* show extra networks parameters in HTML table rather than raw JSON ([#15131](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15131))
* Add DoRA (weight-decompose) support for LoRA/LoHa/LoKr ([#15160](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15160), [#15283](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15283))
* Add '--no-prompt-history' cmd args for disable last generation prompt history ([#15189](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15189))
* update preview on Replace Preview ([#15201](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15201))
* only fetch updates for extensions' active git branches ([#15233](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15233))
* put upscale postprocessing UI into an accordion ([#15223](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15223))
* Support dragdrop for URLs to read infotext ([#15262](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15262))
* use diskcache library for caching ([#15287](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15287), [#15299](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15299))
* Allow PNG-RGBA for Extras Tab ([#15334](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15334))
* Support cover images embedded in safetensors metadata ([#15319](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15319))
* faster interrupt when using NN upscale ([#15380](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15380))
* Extras upscaler: an input field to limit maximul side length for the output image ([#15293](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15293), [#15415](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15415), [#15417](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15417), [#15425](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15425))
* add an option to hide postprocessing options in Extras tab
### Extensions and API:
* ResizeHandleRow - allow overriden column scale parametr ([#15004](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15004))
* call script_callbacks.ui_settings_callback earlier; fix extra-options-section built-in extension killing the ui if using a setting that doesn't exist
* make it possible to use zoom.js outside webui context ([#15286](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15286), [#15288](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15288))
* allow variants for extension name in metadata.ini ([#15290](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15290))
* make reloading UI scripts optional when doing Reload UI, and off by default
* put request: gr.Request at start of img2img function similar to txt2img
* open_folder as util ([#15442](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15442))
* make it possible to import extensions' script files as `import scripts.<filename>` ([#15423](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15423))
### Performance:
* performance optimization for extra networks HTML pages
* optimization for extra networks filtering
* optimization for extra networks sorting
### Bug Fixes:
* prevent escape button causing an interrupt when no generation has been made yet
* [bug] avoid doble upscaling in inpaint ([#14966](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14966))
* possible fix for reload button not appearing in some cases for extra networks.
* fix: the `split_threshold` parameter does not work when running Split oversized images ([#15006](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15006))
* Fix resize-handle visability for vertical layout (mobile) ([#15010](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15010))
* register_tmp_file also for mtime ([#15012](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15012))
* Protect alphas_cumprod during refiner switchover ([#14979](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14979))
* Fix EXIF orientation in API image loading ([#15062](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15062))
* Only override emphasis if actually used in prompt ([#15141](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15141))
* Fix emphasis infotext missing from `params.txt` ([#15142](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15142))
* fix extract_style_text_from_prompt #15132 ([#15135](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15135))
* Fix Soft Inpaint for AnimateDiff ([#15148](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15148))
* edit-attention: deselect surrounding whitespace ([#15178](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15178))
* chore: fix font not loaded ([#15183](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15183))
* use natural sort in extra networks when ordering by path
* Fix built-in lora system bugs caused by torch.nn.MultiheadAttention ([#15190](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15190))
* Avoid error from None in get_learned_conditioning ([#15191](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15191))
* Add entry to MassFileLister after writing metadata ([#15199](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15199))
* fix issue with Styles when Hires prompt is used ([#15269](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15269), [#15276](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15276))
* Strip comments from hires fix prompt ([#15263](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15263))
* Make imageviewer event listeners browser consistent ([#15261](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15261))
* Fix AttributeError in OFT when trying to get MultiheadAttention weight ([#15260](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15260))
* Add missing .mean() back ([#15239](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15239))
* fix "Restore progress" button ([#15221](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15221))
* fix ui-config for InputAccordion [custom_script_source] ([#15231](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15231))
* handle 0 wheel deltaY ([#15268](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15268))
* prevent alt menu for firefox ([#15267](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15267))
* fix: fix syntax errors ([#15179](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15179))
* restore outputs path ([#15307](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15307))
* Escape btn_copy_path filename ([#15316](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15316))
* Fix extra networks buttons when filename contains an apostrophe ([#15331](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15331))
* escape brackets in lora random prompt generator ([#15343](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15343))
* fix: Python version check for PyTorch installation compatibility ([#15390](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15390))
* fix typo in call_queue.py ([#15386](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15386))
* fix: when find already_loaded model, remove loaded by array index ([#15382](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15382))
* minor bug fix of sd model memory management ([#15350](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15350))
* Fix CodeFormer weight ([#15414](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15414))
* Fix: Remove script callbacks in ordered_callbacks_map ([#15428](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15428))
* fix limited file write (thanks, Sylwia)
* Fix extra-single-image API not doing upscale failed ([#15465](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15465))
* error handling paste_field callables ([#15470](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15470))
### Hardware:
* Add training support and change lspci for Ascend NPU ([#14981](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14981))
* Update to ROCm5.7 and PyTorch ([#14820](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14820))
* Better workaround for Navi1, removing --pre for Navi3 ([#15224](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15224))
* Ascend NPU wiki page ([#15228](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15228))
### Other:
* Update comment for Pad prompt/negative prompt v0 to add a warning about truncation, make it override the v1 implementation
* support resizable columns for touch (tablets) ([#15002](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15002))
* Fix #14591 using translated content to do categories mapping ([#14995](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14995))
* Use `absolute` path for normalized filepath ([#15035](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15035))
* resizeHandle handle double tap ([#15065](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15065))
* --dat-models-path cmd flag ([#15039](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15039))
* Add a direct link to the binary release ([#15059](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15059))
* upscaler_utils: Reduce logging ([#15084](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15084))
* Fix various typos with crate-ci/typos ([#15116](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15116))
* fix_jpeg_live_preview ([#15102](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15102))
* [alternative fix] can't load webui if selected wrong extra option in ui ([#15121](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15121))
* Error handling for unsupported transparency ([#14958](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14958))
* Add model description to searched terms ([#15198](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15198))
* bump action version ([#15272](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15272))
* PEP 604 annotations ([#15259](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15259))
* Automatically Set the Scale by value when user selects an Upscale Model ([#15244](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15244))
* move postprocessing-for-training into builtin extensions ([#15222](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15222))
* type hinting in shared.py ([#15211](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15211))
* update ruff to 0.3.3
* Update pytorch lightning utilities ([#15310](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15310))
* Add Size as an XYZ Grid option ([#15354](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15354))
* Use HF_ENDPOINT variable for HuggingFace domain with default ([#15443](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15443))
* re-add update_file_entry ([#15446](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15446))
* create_infotext allow index and callable, re-work Hires prompt infotext ([#15460](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15460))
* update restricted_opts to include more options for --hide-ui-dir-config ([#15492](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15492))
## 1.8.0
### Features:
* Update torch to version 2.1.2
* Soft Inpainting ([#14208](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14208))
* FP8 support ([#14031](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14031), [#14327](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14327))
* Support for SDXL-Inpaint Model ([#14390](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14390))
* Use Spandrel for upscaling and face restoration architectures ([#14425](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14425), [#14467](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14467), [#14473](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14473), [#14474](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14474), [#14477](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14477), [#14476](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14476), [#14484](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14484), [#14500](https://github.com/AUTOMATIC1111/stable-difusion-webui/pull/14500), [#14501](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14501), [#14504](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14504), [#14524](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14524), [#14809](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14809))
* Automatic backwards version compatibility (when loading infotexts from old images with program version specified, will add compatibility settings)
* Implement zero terminal SNR noise schedule option (**[SEED BREAKING CHANGE](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Seed-breaking-changes#180-dev-170-225-2024-01-01---zero-terminal-snr-noise-schedule-option)**, [#14145](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14145), [#14979](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14979))
* Add a [✨] button to run hires fix on selected image in the gallery (with help from [#14598](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14598), [#14626](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14626), [#14728](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14728))
* [Separate assets repository](https://github.com/AUTOMATIC1111/stable-diffusion-webui-assets); serve fonts locally rather than from google's servers
* Official LCM Sampler Support ([#14583](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14583))
* Add support for DAT upscaler models ([#14690](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14690), [#15039](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15039))
* Extra Networks Tree View ([#14588](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14588), [#14900](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14900))
* NPU Support ([#14801](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14801))
* Prompt comments support
### Minor:
* Allow pasting in WIDTHxHEIGHT strings into the width/height fields ([#14296](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14296))
* add option: Live preview in full page image viewer ([#14230](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14230), [#14307](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14307))
* Add keyboard shortcuts for generate/skip/interrupt ([#14269](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14269))
* Better TCMALLOC support on different platforms ([#14227](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14227), [#14883](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14883), [#14910](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14910))
* Lora not found warning ([#14464](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14464))
* Adding negative prompts to Loras in extra networks ([#14475](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14475))
* xyz_grid: allow varying the seed along an axis separate from axis options ([#12180](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12180))
* option to convert VAE to bfloat16 (implementation of [#9295](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/9295))
* Better IPEX support ([#14229](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14229), [#14353](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14353), [#14559](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14559), [#14562](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14562), [#14597](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14597))
* Option to interrupt after current generation rather than immediately ([#13653](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13653), [#14659](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14659))
* Fullscreen Preview control fading/disable ([#14291](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14291))
* Finer settings freezing control ([#13789](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13789))
* Increase Upscaler Limits ([#14589](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14589))
* Adjust brush size with hotkeys ([#14638](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14638))
* Add checkpoint info to csv log file when saving images ([#14663](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14663))
* Make more columns resizable ([#14740](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14740), [#14884](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14884))
* Add an option to not overlay original image for inpainting for #14727
* Add Pad conds v0 option to support same generation with DDIM as before 1.6.0
* Add "Interrupting..." placeholder.
* Button for refresh extensions list ([#14857](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14857))
* Add an option to disable normalization after calculating emphasis. ([#14874](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14874))
* When counting tokens, also include enabled styles (can be disabled in settings to revert to previous behavior)
* Configuration for the [📂] button for image gallery ([#14947](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14947))
* Support inference with LyCORIS BOFT networks ([#14871](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14871), [#14973](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14973))
* support resizable columns for touch (tablets) ([#15002](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15002))
### Extensions and API:
* Removed packages from requirements: basicsr, gfpgan, realesrgan; as well as their dependencies: absl-py, addict, beautifulsoup4, future, gdown, grpcio, importlib-metadata, lmdb, lpips, Markdown, platformdirs, PySocks, soupsieve, tb-nightly, tensorboard-data-server, tomli, Werkzeug, yapf, zipp, soupsieve
* Enable task ids for API ([#14314](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14314))
* add override_settings support for infotext API
* rename generation_parameters_copypaste module to infotext_utils
* prevent crash due to Script __init__ exception ([#14407](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14407))
* Bump numpy to 1.26.2 ([#14471](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14471))
* Add utility to inspect a model's dtype/device ([#14478](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14478))
* Implement general forward method for all method in built-in lora ext ([#14547](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14547))
* Execute model_loaded_callback after moving to target device ([#14563](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14563))
* Add self to CFGDenoiserParams ([#14573](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14573))
* Allow TLS with API only mode (--nowebui) ([#14593](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14593))
* New callback: postprocess_image_after_composite ([#14657](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14657))
* modules/api/api.py: add api endpoint to refresh embeddings list ([#14715](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14715))
* set_named_arg ([#14773](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14773))
* add before_token_counter callback and use it for prompt comments
* ResizeHandleRow - allow overridden column scale parameter ([#15004](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15004))
### Performance:
* Massive performance improvement for extra networks directories with a huge number of files in them in an attempt to tackle #14507 ([#14528](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14528))
* Reduce unnecessary re-indexing extra networks directory ([#14512](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14512))
* Avoid unnecessary `isfile`/`exists` calls ([#14527](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14527))
### Bug Fixes:
* fix multiple bugs related to styles multi-file support ([#14203](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14203), [#14276](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14276), [#14707](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14707))
* Lora fixes ([#14300](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14300), [#14237](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14237), [#14546](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14546), [#14726](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14726))
* Re-add setting lost as part of e294e46 ([#14266](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14266))
* fix extras caption BLIP ([#14330](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14330))
* include infotext into saved init image for img2img ([#14452](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14452))
* xyz grid handle axis_type is None ([#14394](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14394))
* Update Added (Fixed) IPV6 Functionality When there is No Webui Argument Passed webui.py ([#14354](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14354))
* fix API thread safe issues of txt2img and img2img ([#14421](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14421))
* handle selectable script_index is None ([#14487](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14487))
* handle config.json failed to load ([#14525](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14525), [#14767](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14767))
* paste infotext cast int as float ([#14523](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14523))
* Ensure GRADIO_ANALYTICS_ENABLED is set early enough ([#14537](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14537))
* Fix logging configuration again ([#14538](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14538))
* Handle CondFunc exception when resolving attributes ([#14560](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14560))
* Fix extras big batch crashes ([#14699](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14699))
* Fix using wrong model caused by alias ([#14655](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14655))
* Add # to the invalid_filename_chars list ([#14640](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14640))
* Fix extension check for requirements ([#14639](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14639))
* Fix tab indexes are reset after restart UI ([#14637](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14637))
* Fix nested manual cast ([#14689](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14689))
* Keep postprocessing upscale selected tab after restart ([#14702](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14702))
* XYZ grid: filter out blank vals when axis is int or float type (like int axis seed) ([#14754](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14754))
* fix CLIP Interrogator topN regex ([#14775](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14775))
* Fix dtype error in MHA layer/change dtype checking mechanism for manual cast ([#14791](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14791))
* catch load style.csv error ([#14814](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14814))
* fix error when editing extra networks card
* fix extra networks metadata failing to work properly when you create the .json file with metadata for the first time.
* util.walk_files extensions case insensitive ([#14879](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14879))
* if extensions page not loaded, prevent apply ([#14873](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14873))
* call the right function for token counter in img2img
* Fix the bugs that search/reload will disappear when using other ExtraNetworks extensions ([#14939](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14939))
* Gracefully handle mtime read exception from cache ([#14933](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14933))
* Only trigger interrupt on `Esc` when interrupt button visible ([#14932](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14932))
* Disable prompt token counters option actually disables token counting rather than just hiding results.
* avoid double upscaling in inpaint ([#14966](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14966))
* Fix #14591 using translated content to do categories mapping ([#14995](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14995))
* fix: the `split_threshold` parameter does not work when running Split oversized images ([#15006](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15006))
* Fix resize-handle for mobile ([#15010](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15010), [#15065](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15065))
### Other:
* Assign id for "extra_options". Replace numeric field with slider. ([#14270](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14270))
* change state dict comparison to ref compare ([#14216](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14216))
* Bump torch-rocm to 5.6/5.7 ([#14293](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14293))
* Base output path off data path ([#14446](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14446))
* reorder training preprocessing modules in extras tab ([#14367](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14367))
* Remove `cleanup_models` code ([#14472](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14472))
* only rewrite ui-config when there is change ([#14352](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14352))
* Fix lint issue from 501993eb ([#14495](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14495))
* Update README.md ([#14548](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14548))
* hires button, fix seeds ()
* Logging: set formatter correctly for fallback logger too ([#14618](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14618))
* Read generation info from infotexts rather than json for internal needs (save, extract seed from generated pic) ([#14645](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14645))
* improve get_crop_region ([#14709](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14709))
* Bump safetensors' version to 0.4.2 ([#14782](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14782))
* add tooltip create_submit_box ([#14803](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14803))
* extensions tab table row hover highlight ([#14885](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14885))
* Always add timestamp to displayed image ([#14890](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14890))
* Added core.filemode=false so doesn't track changes in file permission… ([#14930](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14930))
* Normalize command-line argument paths ([#14934](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14934), [#15035](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15035))
* Use original App Title in progress bar ([#14916](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14916))
* register_tmp_file also for mtime ([#15012](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15012))
## 1.7.0
### Features:
* settings tab rework: add search field, add categories, split UI settings page into many
* add altdiffusion-m18 support ([#13364](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13364))
* support inference with LyCORIS GLora networks ([#13610](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13610))
* add lora-embedding bundle system ([#13568](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13568))
* option to move prompt from top row into generation parameters
* add support for SSD-1B ([#13865](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13865))
* support inference with OFT networks ([#13692](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13692))
* script metadata and DAG sorting mechanism ([#13944](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13944))
* support HyperTile optimization ([#13948](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13948))
* add support for SD 2.1 Turbo ([#14170](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14170))
* remove Train->Preprocessing tab and put all its functionality into Extras tab
* initial IPEX support for Intel Arc GPU ([#14171](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14171))
### Minor:
* allow reading model hash from images in img2img batch mode ([#12767](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12767))
* add option to align with sgm repo's sampling implementation ([#12818](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12818))
* extra field for lora metadata viewer: `ss_output_name` ([#12838](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12838))
* add action in settings page to calculate all SD checkpoint hashes ([#12909](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12909))
* add button to copy prompt to style editor ([#12975](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12975))
* add --skip-load-model-at-start option ([#13253](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13253))
* write infotext to gif images
* read infotext from gif images ([#13068](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13068))
* allow configuring the initial state of InputAccordion in ui-config.json ([#13189](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13189))
* allow editing whitespace delimiters for ctrl+up/ctrl+down prompt editing ([#13444](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13444))
* prevent accidentally closing popup dialogs ([#13480](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13480))
* added option to play notification sound or not ([#13631](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13631))
* show the preview image in the full screen image viewer if available ([#13459](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13459))
* support for webui.settings.bat ([#13638](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13638))
* add an option to not print stack traces on ctrl+c
* start/restart generation by Ctrl (Alt) + Enter ([#13644](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13644))
* update prompts_from_file script to allow concatenating entries with the general prompt ([#13733](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13733))
* added a visible checkbox to input accordion
* added an option to hide all txt2img/img2img parameters in an accordion ([#13826](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13826))
* added 'Path' sorting option for Extra network cards ([#13968](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13968))
* enable prompt hotkeys in style editor ([#13931](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13931))
* option to show batch img2img results in UI ([#14009](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14009))
* infotext updates: add option to disregard certain infotext fields, add option to not include VAE in infotext, add explanation to infotext settings page, move some options to infotext settings page
* add FP32 fallback support on sd_vae_approx ([#14046](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14046))
* support XYZ scripts / split hires path from unet ([#14126](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14126))
* allow use of multiple styles csv files ([#14125](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14125))
* make extra network card description plaintext by default, with an option (Treat card description as HTML) to re-enable HTML as it was (originally by [#13241](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13241))
### Extensions and API:
* update gradio to 3.41.2
* support installed extensions list api ([#12774](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12774))
* update pnginfo API to return dict with parsed values
* add noisy latent to `ExtraNoiseParams` for callback ([#12856](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12856))
* show extension datetime in UTC ([#12864](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12864), [#12865](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12865), [#13281](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13281))
* add an option to choose how to combine hires fix and refiner
* include program version in info response. ([#13135](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13135))
* sd_unet support for SDXL
* patch DDPM.register_betas so that users can put given_betas in model yaml ([#13276](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13276))
* xyz_grid: add prepare ([#13266](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13266))
* allow multiple localization files with same language in extensions ([#13077](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13077))
* add onEdit function for js and rework token-counter.js to use it
* fix the key error exception when processing override_settings keys ([#13567](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13567))
* ability for extensions to return custom data via api in response.images ([#13463](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13463))
* call state.jobnext() before postproces*() ([#13762](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13762))
* add option to set notification sound volume ([#13884](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13884))
* update Ruff to 0.1.6 ([#14059](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14059))
* add Block component creation callback ([#14119](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14119))
* catch uncaught exception with ui creation scripts ([#14120](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14120))
* use extension name for determining an extension is installed in the index ([#14063](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14063))
* update is_installed() from launch_utils.py to fix reinstalling already installed packages ([#14192](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14192))
### Bug Fixes:
* fix pix2pix producing bad results
* fix defaults settings page breaking when any of main UI tabs are hidden
* fix error that causes some extra networks to be disabled if both <lora:> and <lyco:> are present in the prompt
* fix for Reload UI function: if you reload UI on one tab, other opened tabs will no longer stop working
* prevent duplicate resize handler ([#12795](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12795))
* small typo: vae resolve bug ([#12797](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12797))
* hide broken image crop tool ([#12792](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12792))
* don't show hidden samplers in dropdown for XYZ script ([#12780](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12780))
* fix style editing dialog breaking if it's opened in both img2img and txt2img tabs
* hide --gradio-auth and --api-auth values from /internal/sysinfo report
* add missing infotext for RNG in options ([#12819](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12819))
* fix notification not playing when built-in webui tab is inactive ([#12834](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12834))
* honor `--skip-install` for extension installers ([#12832](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12832))
* don't print blank stdout in extension installers ([#12833](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12833), [#12855](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12855))
* get progressbar to display correctly in extensions tab
* keep order in list of checkpoints when loading model that doesn't have a checksum
* fix inpainting models in txt2img creating black pictures
* fix generation params regex ([#12876](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12876))
* fix batch img2img output dir with script ([#12926](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12926))
* fix #13080 - Hypernetwork/TI preview generation ([#13084](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13084))
* fix bug with sigma min/max overrides. ([#12995](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12995))
* more accurate check for enabling cuDNN benchmark on 16XX cards ([#12924](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12924))
* don't use multicond parser for negative prompt counter ([#13118](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13118))
* fix data-sort-name containing spaces ([#13412](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13412))
* update card on correct tab when editing metadata ([#13411](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13411))
* fix viewing/editing metadata when filename contains an apostrophe ([#13395](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13395))
* fix: --sd_model in "Prompts from file or textbox" script is not working ([#13302](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13302))
* better Support for Portable Git ([#13231](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13231))
* fix issues when webui_dir is not work_dir ([#13210](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13210))
* fix: lora-bias-backup don't reset cache ([#13178](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13178))
* account for customizable extra network separators whyen removing extra network text from the prompt ([#12877](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12877))
* re fix batch img2img output dir with script ([#13170](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13170))
* fix `--ckpt-dir` path separator and option use `short name` for checkpoint dropdown ([#13139](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13139))
* consolidated allowed preview formats, Fix extra network `.gif` not woking as preview ([#13121](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13121))
* fix venv_dir=- environment variable not working as expected on linux ([#13469](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13469))
* repair unload sd checkpoint button
* edit-attention fixes ([#13533](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13533))
* fix bug when using --gfpgan-models-path ([#13718](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13718))
* properly apply sort order for extra network cards when selected from dropdown
* fixes generation restart not working for some users when 'Ctrl+Enter' is pressed ([#13962](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13962))
* thread safe extra network list_items ([#13014](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13014))
* fix not able to exit metadata popup when pop up is too big ([#14156](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14156))
* fix auto focal point crop for opencv >= 4.8 ([#14121](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14121))
* make 'use-cpu all' actually apply to 'all' ([#14131](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14131))
* extras tab batch: actually use original filename
* make webui not crash when running with --disable-all-extensions option
### Other:
* non-local condition ([#12814](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12814))
* fix minor typos ([#12827](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12827))
* remove xformers Python version check ([#12842](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12842))
* style: file-metadata word-break ([#12837](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12837))
* revert SGM noise multiplier change for img2img because it breaks hires fix
* do not change quicksettings dropdown option when value returned is `None` ([#12854](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12854))
* [RC 1.6.0 - zoom is partly hidden] Update style.css ([#12839](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12839))
* chore: change extension time format ([#12851](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12851))
* WEBUI.SH - Use torch 2.1.0 release candidate for Navi 3 ([#12929](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12929))
* add Fallback at images.read_info_from_image if exif data was invalid ([#13028](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13028))
* update cmd arg description ([#12986](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12986))
* fix: update shared.opts.data when add_option ([#12957](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12957), [#13213](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13213))
* restore missing tooltips ([#12976](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12976))
* use default dropdown padding on mobile ([#12880](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12880))
* put enable console prompts option into settings from commandline args ([#13119](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13119))
* fix some deprecated types ([#12846](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12846))
* bump to torchsde==0.2.6 ([#13418](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13418))
* update dragdrop.js ([#13372](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13372))
* use orderdict as lru cache:opt/bug ([#13313](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13313))
* XYZ if not include sub grids do not save sub grid ([#13282](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13282))
* initialize state.time_start befroe state.job_count ([#13229](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13229))
* fix fieldname regex ([#13458](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13458))
* change denoising_strength default to None. ([#13466](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13466))
* fix regression ([#13475](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13475))
* fix IndexError ([#13630](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13630))
* fix: checkpoints_loaded:{checkpoint:state_dict}, model.load_state_dict issue in dict value empty ([#13535](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13535))
* update bug_report.yml ([#12991](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12991))
* requirements_versions httpx==0.24.1 ([#13839](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13839))
* fix parenthesis auto selection ([#13829](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13829))
* fix #13796 ([#13797](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13797))
* corrected a typo in `modules/cmd_args.py` ([#13855](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13855))
* feat: fix randn found element of type float at pos 2 ([#14004](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14004))
* adds tqdm handler to logging_config.py for progress bar integration ([#13996](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13996))
* hotfix: call shared.state.end() after postprocessing done ([#13977](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13977))
* fix dependency address patch 1 ([#13929](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13929))
* save sysinfo as .json ([#14035](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14035))
* move exception_records related methods to errors.py ([#14084](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14084))
* compatibility ([#13936](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13936))
* json.dump(ensure_ascii=False) ([#14108](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14108))
* dir buttons start with / so only the correct dir will be shown and no… ([#13957](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13957))
* alternate implementation for unet forward replacement that does not depend on hijack being applied
* re-add `keyedit_delimiters_whitespace` setting lost as part of commit e294e46 ([#14178](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14178))
* fix `save_samples` being checked early when saving masked composite ([#14177](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14177))
* slight optimization for mask and mask_composite ([#14181](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14181))
* add import_hook hack to work around basicsr/torchvision incompatibility ([#14186](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14186))
## 1.6.1
### Bug Fixes:
* fix an error causing the webui to fail to start ([#13839](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/13839))
## 1.6.0
### Features:
* refiner support [#12371](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12371)
* add NV option for Random number generator source setting, which allows to generate same pictures on CPU/AMD/Mac as on NVidia videocards
* add style editor dialog
* hires fix: add an option to use a different checkpoint for second pass ([#12181](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12181))
* option to keep multiple loaded models in memory ([#12227](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12227))
* new samplers: Restart, DPM++ 2M SDE Exponential, DPM++ 2M SDE Heun, DPM++ 2M SDE Heun Karras, DPM++ 2M SDE Heun Exponential, DPM++ 3M SDE, DPM++ 3M SDE Karras, DPM++ 3M SDE Exponential ([#12300](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12300), [#12519](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12519), [#12542](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12542))
* rework DDIM, PLMS, UniPC to use CFG denoiser same as in k-diffusion samplers:
* makes all of them work with img2img
* makes prompt composition possible (AND)
* makes them available for SDXL
* always show extra networks tabs in the UI ([#11808](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/11808))
* use less RAM when creating models ([#11958](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/11958), [#12599](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12599))
* textual inversion inference support for SDXL
* extra networks UI: show metadata for SD checkpoints
* checkpoint merger: add metadata support
* prompt editing and attention: add support for whitespace after the number ([ red : green : 0.5 ]) (seed breaking change) ([#12177](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12177))
* VAE: allow selecting own VAE for each checkpoint (in user metadata editor)
* VAE: add selected VAE to infotext
* options in main UI: add own separate setting for txt2img and img2img, correctly read values from pasted infotext, add setting for column count ([#12551](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12551))
* add resize handle to txt2img and img2img tabs, allowing to change the amount of horizontable space given to generation parameters and resulting image gallery ([#12687](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12687), [#12723](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12723))
* change default behavior for batching cond/uncond -- now it's on by default, and is disabled by an UI setting (Optimizatios -> Batch cond/uncond) - if you are on lowvram/medvram and are getting OOM exceptions, you will need to enable it
* show current position in queue and make it so that requests are processed in the order of arrival ([#12707](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12707))
* add `--medvram-sdxl` flag that only enables `--medvram` for SDXL models
* prompt editing timeline has separate range for first pass and hires-fix pass (seed breaking change) ([#12457](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12457))
### Minor:
* img2img batch: RAM savings, VRAM savings, .tif, .tiff in img2img batch ([#12120](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12120), [#12514](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12514), [#12515](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12515))
* postprocessing/extras: RAM savings ([#12479](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12479))
* XYZ: in the axis labels, remove pathnames from model filenames
* XYZ: support hires sampler ([#12298](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12298))
* XYZ: new option: use text inputs instead of dropdowns ([#12491](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12491))
* add gradio version warning
* sort list of VAE checkpoints ([#12297](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12297))
* use transparent white for mask in inpainting, along with an option to select the color ([#12326](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12326))
* move some settings to their own section: img2img, VAE
* add checkbox to show/hide dirs for extra networks
* Add TAESD(or more) options for all the VAE encode/decode operation ([#12311](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12311))
* gradio theme cache, new gradio themes, along with explanation that the user can input his own values ([#12346](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12346), [#12355](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12355))
* sampler fixes/tweaks: s_tmax, s_churn, s_noise, s_tmax ([#12354](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12354), [#12356](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12356), [#12357](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12357), [#12358](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12358), [#12375](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12375), [#12521](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12521))
* update README.md with correct instructions for Linux installation ([#12352](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12352))
* option to not save incomplete images, on by default ([#12338](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12338))
* enable cond cache by default
* git autofix for repos that are corrupted ([#12230](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12230))
* allow to open images in new browser tab by middle mouse button ([#12379](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12379))
* automatically open webui in browser when running "locally" ([#12254](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12254))
* put commonly used samplers on top, make DPM++ 2M Karras the default choice
* zoom and pan: option to auto-expand a wide image, improved integration ([#12413](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12413), [#12727](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12727))
* option to cache Lora networks in memory
* rework hires fix UI to use accordion
* face restoration and tiling moved to settings - use "Options in main UI" setting if you want them back
* change quicksettings items to have variable width
* Lora: add Norm module, add support for bias ([#12503](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12503))
* Lora: output warnings in UI rather than fail for unfitting loras; switch to logging for error output in console
* support search and display of hashes for all extra network items ([#12510](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12510))
* add extra noise param for img2img operations ([#12564](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12564))
* support for Lora with bias ([#12584](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12584))
* make interrupt quicker ([#12634](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12634))
* configurable gallery height ([#12648](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12648))
* make results column sticky ([#12645](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12645))
* more hash filename patterns ([#12639](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12639))
* make image viewer actually fit the whole page ([#12635](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12635))
* make progress bar work independently from live preview display which results in it being updated a lot more often
* forbid Full live preview method for medvram and add a setting to undo the forbidding
* make it possible to localize tooltips and placeholders
* add option to align with sgm repo's sampling implementation ([#12818](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12818))
* Restore faces and Tiling generation parameters have been moved to settings out of main UI
* if you want to put them back into main UI, use `Options in main UI` setting on the UI page.
### Extensions and API:
* gradio 3.41.2
* also bump versions for packages: transformers, GitPython, accelerate, scikit-image, timm, tomesd
* support tooltip kwarg for gradio elements: gr.Textbox(label='hello', tooltip='world')
* properly clear the total console progressbar when using txt2img and img2img from API
* add cmd_arg --disable-extra-extensions and --disable-all-extensions ([#12294](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12294))
* shared.py and webui.py split into many files
* add --loglevel commandline argument for logging
* add a custom UI element that combines accordion and checkbox
* avoid importing gradio in tests because it spams warnings
* put infotext label for setting into OptionInfo definition rather than in a separate list
* make `StableDiffusionProcessingImg2Img.mask_blur` a property, make more inline with PIL `GaussianBlur` ([#12470](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12470))
* option to make scripts UI without gr.Group
* add a way for scripts to register a callback for before/after just a single component's creation
* use dataclass for StableDiffusionProcessing
* store patches for Lora in a specialized module instead of inside torch
* support http/https URLs in API ([#12663](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12663), [#12698](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12698))
* add extra noise callback ([#12616](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12616))
* dump current stack traces when exiting with SIGINT
* add type annotations for extra fields of shared.sd_model
### Bug Fixes:
* Don't crash if out of local storage quota for javascriot localStorage
* XYZ plot do not fail if an exception occurs
* fix missing TI hash in infotext if generation uses both negative and positive TI ([#12269](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12269))
* localization fixes ([#12307](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12307))
* fix sdxl model invalid configuration after the hijack
* correctly toggle extras checkbox for infotext paste ([#12304](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12304))
* open raw sysinfo link in new page ([#12318](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12318))
* prompt parser: Account for empty field in alternating words syntax ([#12319](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12319))
* add tab and carriage return to invalid filename chars ([#12327](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12327))
* fix api only Lora not working ([#12387](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12387))
* fix options in main UI misbehaving when there's just one element
* make it possible to use a sampler from infotext even if it's hidden in the dropdown
* fix styles missing from the prompt in infotext when making a grid of batch of multiplie images
* prevent bogus progress output in console when calculating hires fix dimensions
* fix --use-textbox-seed
* fix broken `Lora/Networks: use old method` option ([#12466](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12466))
* properly return `None` for VAE hash when using `--no-hashing` ([#12463](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12463))
* MPS/macOS fixes and optimizations ([#12526](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12526))
* add second_order to samplers that mistakenly didn't have it
* when refreshing cards in extra networks UI, do not discard user's custom resolution
* fix processing error that happens if batch_size is not a multiple of how many prompts/negative prompts there are ([#12509](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12509))
* fix inpaint upload for alpha masks ([#12588](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12588))
* fix exception when image sizes are not integers ([#12586](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12586))
* fix incorrect TAESD Latent scale ([#12596](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12596))
* auto add data-dir to gradio-allowed-path ([#12603](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12603))
* fix exception if extensuions dir is missing ([#12607](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12607))
* fix issues with api model-refresh and vae-refresh ([#12638](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12638))
* fix img2img background color for transparent images option not being used ([#12633](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12633))
* attempt to resolve NaN issue with unstable VAEs in fp32 mk2 ([#12630](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12630))
* implement missing undo hijack for SDXL
* fix xyz swap axes ([#12684](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12684))
* fix errors in backup/restore tab if any of config files are broken ([#12689](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12689))
* fix SD VAE switch error after model reuse ([#12685](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12685))
* fix trying to create images too large for the chosen format ([#12667](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12667))
* create Gradio temp directory if necessary ([#12717](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12717))
* prevent possible cache loss if exiting as it's being written by using an atomic operation to replace the cache with the new version
* set devices.dtype_unet correctly
* run RealESRGAN on GPU for non-CUDA devices ([#12737](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12737))
* prevent extra network buttons being obscured by description for very small card sizes ([#12745](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12745))
* fix error that causes some extra networks to be disabled if both <lora:> and <lyco:> are present in the prompt
* fix defaults settings page breaking when any of main UI tabs are hidden
* fix incorrect save/display of new values in Defaults page in settings
* fix for Reload UI function: if you reload UI on one tab, other opened tabs will no longer stop working
* fix an error that prevents VAE being reloaded after an option change if a VAE near the checkpoint exists ([#12797](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12737))
* hide broken image crop tool ([#12792](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12737))
* don't show hidden samplers in dropdown for XYZ script ([#12780](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12737))
* fix style editing dialog breaking if it's opened in both img2img and txt2img tabs
* fix a bug allowing users to bypass gradio and API authentication (reported by vysecurity)
* fix notification not playing when built-in webui tab is inactive ([#12834](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12834))
* honor `--skip-install` for extension installers ([#12832](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12832))
* don't print blank stdout in extension installers ([#12833](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12832), [#12855](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12855))
* do not change quicksettings dropdown option when value returned is `None` ([#12854](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12854))
* get progressbar to display correctly in extensions tab
## 1.5.2
### Bug Fixes:
* fix memory leak when generation fails
* update doggettx cross attention optimization to not use an unreasonable amount of memory in some edge cases -- suggestion by MorkTheOrk
## 1.5.1
### Minor:
@ -30,7 +763,7 @@
* user metadata system for custom networks
* extended Lora metadata editor: set activation text, default weight, view tags, training info
* Lora extension rework to include other types of networks (all that were previously handled by LyCORIS extension)
* show github stars for extenstions
* show github stars for extensions
* img2img batch mode can read extra stuff from png info
* img2img batch works with subdirectories
* hotkeys to move prompt elements: alt+left/right
@ -249,7 +982,7 @@
* do not wait for Stable Diffusion model to load at startup
* add filename patterns: `[denoising]`
* directory hiding for extra networks: dirs starting with `.` will hide their cards on extra network tabs unless specifically searched for
* LoRA: for the `<...>` text in prompt, use name of LoRA that is in the metdata of the file, if present, instead of filename (both can be used to activate LoRA)
* LoRA: for the `<...>` text in prompt, use name of LoRA that is in the metadata of the file, if present, instead of filename (both can be used to activate LoRA)
* LoRA: read infotext params from kohya-ss's extension parameters if they are present and if his extension is not active
* LoRA: fix some LoRAs not working (ones that have 3x3 convolution layer)
* LoRA: add an option to use old method of applying LoRAs (producing same results as with kohya-ss)
@ -279,7 +1012,7 @@
* fix gamepad navigation
* make the lightbox fullscreen image function properly
* fix squished thumbnails in extras tab
* keep "search" filter for extra networks when user refreshes the tab (previously it showed everthing after you refreshed)
* keep "search" filter for extra networks when user refreshes the tab (previously it showed everything after you refreshed)
* fix webui showing the same image if you configure the generation to always save results into same file
* fix bug with upscalers not working properly
* fix MPS on PyTorch 2.0.1, Intel Macs
@ -297,7 +1030,7 @@
* switch to PyTorch 2.0.0 (except for AMD GPUs)
* visual improvements to custom code scripts
* add filename patterns: `[clip_skip]`, `[hasprompt<>]`, `[batch_number]`, `[generation_number]`
* add support for saving init images in img2img, and record their hashes in infotext for reproducability
* add support for saving init images in img2img, and record their hashes in infotext for reproducibility
* automatically select current word when adjusting weight with ctrl+up/down
* add dropdowns for X/Y/Z plot
* add setting: Stable Diffusion/Random number generator source: makes it possible to make images generated from a given manual seed consistent across different GPUs

7
CITATION.cff Normal file
View File

@ -0,0 +1,7 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
authors:
- given-names: AUTOMATIC1111
title: "Stable Diffusion Web UI"
date-released: 2022-08-22
url: "https://github.com/AUTOMATIC1111/stable-diffusion-webui"

View File

@ -1,5 +1,5 @@
# Stable Diffusion web UI
A browser interface based on Gradio library for Stable Diffusion.
A web interface for Stable Diffusion, implemented using Gradio library.
![](screenshot.png)
@ -78,7 +78,7 @@ A browser interface based on Gradio library for Stable Diffusion.
- Clip skip
- Hypernetworks
- Loras (same as Hypernetworks but more pretty)
- A sparate UI where you can choose, with preview, which embeddings, hypernetworks or Loras to add to your prompt
- A separate UI where you can choose, with preview, which embeddings, hypernetworks or Loras to add to your prompt
- Can select to load a different VAE from settings screen
- Estimated completion time in progress bar
- API
@ -88,19 +88,24 @@ A browser interface based on Gradio library for Stable Diffusion.
- [Alt-Diffusion](https://arxiv.org/abs/2211.06679) support - see [wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#alt-diffusion) for instructions
- Now without any bad letters!
- Load checkpoints in safetensors format
- Eased resolution restriction: generated image's domension must be a multiple of 8 rather than 64
- Eased resolution restriction: generated image's dimensions must be a multiple of 8 rather than 64
- Now with a license!
- Reorder elements in the UI from settings screen
- [Segmind Stable Diffusion](https://huggingface.co/segmind/SSD-1B) support
## Installation and Running
Make sure the required [dependencies](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Dependencies) are met and follow the instructions available for both [NVidia](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-NVidia-GPUs) (recommended) and [AMD](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs) GPUs.
Make sure the required [dependencies](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Dependencies) are met and follow the instructions available for:
- [NVidia](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-NVidia-GPUs) (recommended)
- [AMD](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs) GPUs.
- [Intel CPUs, Intel GPUs (both integrated and discrete)](https://github.com/openvinotoolkit/stable-diffusion-webui/wiki/Installation-on-Intel-Silicon) (external wiki page)
- [Ascend NPUs](https://github.com/wangshuai09/stable-diffusion-webui/wiki/Install-and-run-on-Ascend-NPUs) (external wiki page)
Alternatively, use online services (like Google Colab):
- [List of Online Services](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Online-Services)
### Installation on Windows 10/11 with NVidia-GPUs using release package
1. Download `sd.webui.zip` from [v1.0.0-pre](https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases/tag/v1.0.0-pre) and extract it's contents.
1. Download `sd.webui.zip` from [v1.0.0-pre](https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases/tag/v1.0.0-pre) and extract its contents.
2. Run `update.bat`.
3. Run `run.bat`.
> For more details see [Install-and-Run-on-NVidia-GPUs](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-NVidia-GPUs)
@ -115,16 +120,40 @@ Alternatively, use online services (like Google Colab):
1. Install the dependencies:
```bash
# Debian-based:
sudo apt install wget git python3 python3-venv
sudo apt install wget git python3 python3-venv libgl1 libglib2.0-0
# Red Hat-based:
sudo dnf install wget git python3
sudo dnf install wget git python3 gperftools-libs libglvnd-glx
# openSUSE-based:
sudo zypper install wget git python3 libtcmalloc4 libglvnd
# Arch-based:
sudo pacman -S wget git python3
```
If your system is very new, you need to install python3.11 or python3.10:
```bash
# Ubuntu 24.04
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.11
# Manjaro/Arch
sudo pacman -S yay
yay -S python311 # do not confuse with python3.11 package
# Only for 3.11
# Then set up env variable in launch script
export python_cmd="python3.11"
# or in webui-user.sh
python_cmd="python3.11"
```
2. Navigate to the directory you would like the webui to be installed and execute the following command:
```bash
bash <(wget -qO- https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui/master/webui.sh)
wget -q https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui/master/webui.sh
```
Or just clone the repo wherever you want:
```bash
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui
```
3. Run `webui.sh`.
4. Check `webui-user.sh` for options.
### Installation on Apple Silicon
@ -143,13 +172,14 @@ For the purposes of getting Google and other search engines to crawl the wiki, h
## Credits
Licenses for borrowed code can be found in `Settings -> Licenses` screen, and also in `html/licenses.html` file.
- Stable Diffusion - https://github.com/CompVis/stable-diffusion, https://github.com/CompVis/taming-transformers
- Stable Diffusion - https://github.com/Stability-AI/stablediffusion, https://github.com/CompVis/taming-transformers, https://github.com/mcmonkey4eva/sd3-ref
- k-diffusion - https://github.com/crowsonkb/k-diffusion.git
- GFPGAN - https://github.com/TencentARC/GFPGAN.git
- CodeFormer - https://github.com/sczhou/CodeFormer
- ESRGAN - https://github.com/xinntao/ESRGAN
- SwinIR - https://github.com/JingyunLiang/SwinIR
- Swin2SR - https://github.com/mv-lab/swin2sr
- Spandrel - https://github.com/chaiNNer-org/spandrel implementing
- GFPGAN - https://github.com/TencentARC/GFPGAN.git
- CodeFormer - https://github.com/sczhou/CodeFormer
- ESRGAN - https://github.com/xinntao/ESRGAN
- SwinIR - https://github.com/JingyunLiang/SwinIR
- Swin2SR - https://github.com/mv-lab/swin2sr
- LDSR - https://github.com/Hafiidz/latent-diffusion
- MiDaS - https://github.com/isl-org/MiDaS
- Ideas for optimizations - https://github.com/basujindal/stable-diffusion
@ -169,5 +199,7 @@ Licenses for borrowed code can be found in `Settings -> Licenses` screen, and al
- UniPC sampler - Wenliang Zhao - https://github.com/wl-zhao/UniPC
- TAESD - Ollin Boer Bohan - https://github.com/madebyollin/taesd
- LyCORIS - KohakuBlueleaf
- Restart sampling - lambertae - https://github.com/Newbeeer/diffusion_restart_sampling
- Hypertile - tfernd - https://github.com/tfernd/HyperTile
- Initial Gradio script - posted on 4chan by an Anonymous user. Thank you Anonymous user.
- (You)

5
_typos.toml Normal file
View File

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

View File

@ -40,7 +40,7 @@ model:
use_spatial_transformer: True
transformer_depth: 1
context_dim: 768
use_checkpoint: True
use_checkpoint: False
legacy: False
first_stage_config:

View File

@ -0,0 +1,73 @@
model:
base_learning_rate: 1.0e-04
target: ldm.models.diffusion.ddpm.LatentDiffusion
params:
linear_start: 0.00085
linear_end: 0.0120
num_timesteps_cond: 1
log_every_t: 200
timesteps: 1000
first_stage_key: "jpg"
cond_stage_key: "txt"
image_size: 64
channels: 4
cond_stage_trainable: false # Note: different from the one we trained before
conditioning_key: crossattn
monitor: val/loss_simple_ema
scale_factor: 0.18215
use_ema: False
scheduler_config: # 10000 warmup steps
target: ldm.lr_scheduler.LambdaLinearScheduler
params:
warm_up_steps: [ 10000 ]
cycle_lengths: [ 10000000000000 ] # incredibly large number to prevent corner cases
f_start: [ 1.e-6 ]
f_max: [ 1. ]
f_min: [ 1. ]
unet_config:
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
params:
image_size: 32 # unused
in_channels: 4
out_channels: 4
model_channels: 320
attention_resolutions: [ 4, 2, 1 ]
num_res_blocks: 2
channel_mult: [ 1, 2, 4, 4 ]
num_head_channels: 64
use_spatial_transformer: True
use_linear_in_transformer: True
transformer_depth: 1
context_dim: 1024
use_checkpoint: False
legacy: False
first_stage_config:
target: ldm.models.autoencoder.AutoencoderKL
params:
embed_dim: 4
monitor: val/rec_loss
ddconfig:
double_z: true
z_channels: 4
resolution: 256
in_channels: 3
out_ch: 3
ch: 128
ch_mult:
- 1
- 2
- 4
- 4
num_res_blocks: 2
attn_resolutions: []
dropout: 0.0
lossconfig:
target: torch.nn.Identity
cond_stage_config:
target: modules.xlmr_m18.BertSeriesModelWithTransformation
params:
name: "XLMR-Large"

View File

@ -45,7 +45,7 @@ model:
use_spatial_transformer: True
transformer_depth: 1
context_dim: 768
use_checkpoint: True
use_checkpoint: False
legacy: False
first_stage_config:

View File

@ -0,0 +1,5 @@
model:
target: modules.models.sd3.sd3_model.SD3Inferencer
params:
shift: 3
state_dict: null

View File

@ -0,0 +1,98 @@
model:
target: sgm.models.diffusion.DiffusionEngine
params:
scale_factor: 0.13025
disable_first_stage_autocast: True
denoiser_config:
target: sgm.modules.diffusionmodules.denoiser.DiscreteDenoiser
params:
num_idx: 1000
weighting_config:
target: sgm.modules.diffusionmodules.denoiser_weighting.EpsWeighting
scaling_config:
target: sgm.modules.diffusionmodules.denoiser_scaling.EpsScaling
discretization_config:
target: sgm.modules.diffusionmodules.discretizer.LegacyDDPMDiscretization
network_config:
target: sgm.modules.diffusionmodules.openaimodel.UNetModel
params:
adm_in_channels: 2816
num_classes: sequential
use_checkpoint: False
in_channels: 9
out_channels: 4
model_channels: 320
attention_resolutions: [4, 2]
num_res_blocks: 2
channel_mult: [1, 2, 4]
num_head_channels: 64
use_spatial_transformer: True
use_linear_in_transformer: True
transformer_depth: [1, 2, 10] # note: the first is unused (due to attn_res starting at 2) 32, 16, 8 --> 64, 32, 16
context_dim: 2048
spatial_transformer_attn_type: softmax-xformers
legacy: False
conditioner_config:
target: sgm.modules.GeneralConditioner
params:
emb_models:
# crossattn cond
- is_trainable: False
input_key: txt
target: sgm.modules.encoders.modules.FrozenCLIPEmbedder
params:
layer: hidden
layer_idx: 11
# crossattn and vector cond
- is_trainable: False
input_key: txt
target: sgm.modules.encoders.modules.FrozenOpenCLIPEmbedder2
params:
arch: ViT-bigG-14
version: laion2b_s39b_b160k
freeze: True
layer: penultimate
always_return_pooled: True
legacy: False
# vector cond
- is_trainable: False
input_key: original_size_as_tuple
target: sgm.modules.encoders.modules.ConcatTimestepEmbedderND
params:
outdim: 256 # multiplied by two
# vector cond
- is_trainable: False
input_key: crop_coords_top_left
target: sgm.modules.encoders.modules.ConcatTimestepEmbedderND
params:
outdim: 256 # multiplied by two
# vector cond
- is_trainable: False
input_key: target_size_as_tuple
target: sgm.modules.encoders.modules.ConcatTimestepEmbedderND
params:
outdim: 256 # multiplied by two
first_stage_config:
target: sgm.models.autoencoder.AutoencoderKLInferenceWrapper
params:
embed_dim: 4
monitor: val/rec_loss
ddconfig:
attn_type: vanilla-xformers
double_z: true
z_channels: 4
resolution: 256
in_channels: 3
out_ch: 3
ch: 128
ch_mult: [1, 2, 4, 4]
num_res_blocks: 2
attn_resolutions: []
dropout: 0.0
lossconfig:
target: torch.nn.Identity

View File

@ -40,7 +40,7 @@ model:
use_spatial_transformer: True
transformer_depth: 1
context_dim: 768
use_checkpoint: True
use_checkpoint: False
legacy: False
first_stage_config:

View File

@ -40,7 +40,7 @@ model:
use_spatial_transformer: True
transformer_depth: 1
context_dim: 768
use_checkpoint: True
use_checkpoint: False
legacy: False
first_stage_config:

View File

@ -301,7 +301,7 @@ class DDPMV1(pl.LightningModule):
elif self.parameterization == "x0":
target = x_start
else:
raise NotImplementedError(f"Paramterization {self.parameterization} not yet supported")
raise NotImplementedError(f"Parameterization {self.parameterization} not yet supported")
loss = self.get_loss(model_out, target, mean=False).mean(dim=[1, 2, 3])
@ -572,7 +572,7 @@ class LatentDiffusionV1(DDPMV1):
:param h: height
:param w: width
:return: normalized distance to image border,
wtith min distance = 0 at border and max dist = 0.5 at image center
with min distance = 0 at border and max dist = 0.5 at image center
"""
lower_right_corner = torch.tensor([h - 1, w - 1]).view(1, 1, 2)
arr = self.meshgrid(h, w) / lower_right_corner
@ -880,7 +880,7 @@ class LatentDiffusionV1(DDPMV1):
def apply_model(self, x_noisy, t, cond, return_ids=False):
if isinstance(cond, dict):
# hybrid case, cond is exptected to be a dict
# hybrid case, cond is expected to be a dict
pass
else:
if not isinstance(cond, list):
@ -916,7 +916,7 @@ class LatentDiffusionV1(DDPMV1):
cond_list = [{c_key: [c[:, :, :, :, i]]} for i in range(c.shape[-1])]
elif self.cond_stage_key == 'coordinates_bbox':
assert 'original_image_size' in self.split_input_params, 'BoudingBoxRescaling is missing original_image_size'
assert 'original_image_size' in self.split_input_params, 'BoundingBoxRescaling is missing original_image_size'
# assuming padding of unfold is always 0 and its dilation is always 1
n_patches_per_row = int((w - ks[0]) / stride[0] + 1)
@ -926,7 +926,7 @@ class LatentDiffusionV1(DDPMV1):
num_downs = self.first_stage_model.encoder.num_resolutions - 1
rescale_latent = 2 ** (num_downs)
# get top left postions of patches as conforming for the bbbox tokenizer, therefore we
# get top left positions of patches as conforming for the bbbox tokenizer, therefore we
# need to rescale the tl patch coordinates to be in between (0,1)
tl_patch_coordinates = [(rescale_latent * stride[0] * (patch_nr % n_patches_per_row) / full_img_w,
rescale_latent * stride[1] * (patch_nr // n_patches_per_row) / full_img_h)

View File

@ -6,9 +6,16 @@ class ExtraNetworkLora(extra_networks.ExtraNetwork):
def __init__(self):
super().__init__('lora')
self.errors = {}
"""mapping of network names to the number of errors the network had during operation"""
remove_symbols = str.maketrans('', '', ":,")
def activate(self, p, params_list):
additional = shared.opts.sd_lora
self.errors.clear()
if additional != "None" and additional in networks.available_networks and not any(x for x in params_list if x.items[0] == additional):
p.all_prompts = [x + f"<lora:{additional}:{shared.opts.extra_networks_default_multiplier}>" for x in p.all_prompts]
params_list.append(extra_networks.ExtraNetworkParams(items=[additional, shared.opts.extra_networks_default_multiplier]))
@ -38,22 +45,18 @@ class ExtraNetworkLora(extra_networks.ExtraNetwork):
networks.load_networks(names, te_multipliers, unet_multipliers, dyn_dims)
if shared.opts.lora_add_hashes_to_infotext:
network_hashes = []
if not getattr(p, "is_hr_pass", False) or not hasattr(p, "lora_hashes"):
p.lora_hashes = {}
for item in networks.loaded_networks:
shorthash = item.network_on_disk.shorthash
if not shorthash:
continue
if item.network_on_disk.shorthash and item.mentioned_name:
p.lora_hashes[item.mentioned_name.translate(self.remove_symbols)] = item.network_on_disk.shorthash
alias = item.mentioned_name
if not alias:
continue
alias = alias.replace(":", "").replace(",", "")
network_hashes.append(f"{alias}: {shorthash}")
if network_hashes:
p.extra_generation_params["Lora hashes"] = ", ".join(network_hashes)
if p.lora_hashes:
p.extra_generation_params["Lora hashes"] = ', '.join(f'{k}: {v}' for k, v in p.lora_hashes.items())
def deactivate(self, p):
pass
if self.errors:
p.comment("Networks with errors: " + ", ".join(f"{k} ({v})" for k, v in self.errors.items()))
self.errors.clear()

View File

@ -0,0 +1,33 @@
import sys
import copy
import logging
class ColoredFormatter(logging.Formatter):
COLORS = {
"DEBUG": "\033[0;36m", # CYAN
"INFO": "\033[0;32m", # GREEN
"WARNING": "\033[0;33m", # YELLOW
"ERROR": "\033[0;31m", # RED
"CRITICAL": "\033[0;37;41m", # WHITE ON RED
"RESET": "\033[0m", # RESET COLOR
}
def format(self, record):
colored_record = copy.copy(record)
levelname = colored_record.levelname
seq = self.COLORS.get(levelname, self.COLORS["RESET"])
colored_record.levelname = f"{seq}{levelname}{self.COLORS['RESET']}"
return super().format(colored_record)
logger = logging.getLogger("lora")
logger.propagate = False
if not logger.handlers:
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(
ColoredFormatter("[%(name)s]-%(levelname)s: %(message)s")
)
logger.addHandler(handler)

View File

@ -0,0 +1,31 @@
import torch
import networks
from modules import patches
class LoraPatches:
def __init__(self):
self.Linear_forward = patches.patch(__name__, torch.nn.Linear, 'forward', networks.network_Linear_forward)
self.Linear_load_state_dict = patches.patch(__name__, torch.nn.Linear, '_load_from_state_dict', networks.network_Linear_load_state_dict)
self.Conv2d_forward = patches.patch(__name__, torch.nn.Conv2d, 'forward', networks.network_Conv2d_forward)
self.Conv2d_load_state_dict = patches.patch(__name__, torch.nn.Conv2d, '_load_from_state_dict', networks.network_Conv2d_load_state_dict)
self.GroupNorm_forward = patches.patch(__name__, torch.nn.GroupNorm, 'forward', networks.network_GroupNorm_forward)
self.GroupNorm_load_state_dict = patches.patch(__name__, torch.nn.GroupNorm, '_load_from_state_dict', networks.network_GroupNorm_load_state_dict)
self.LayerNorm_forward = patches.patch(__name__, torch.nn.LayerNorm, 'forward', networks.network_LayerNorm_forward)
self.LayerNorm_load_state_dict = patches.patch(__name__, torch.nn.LayerNorm, '_load_from_state_dict', networks.network_LayerNorm_load_state_dict)
self.MultiheadAttention_forward = patches.patch(__name__, torch.nn.MultiheadAttention, 'forward', networks.network_MultiheadAttention_forward)
self.MultiheadAttention_load_state_dict = patches.patch(__name__, torch.nn.MultiheadAttention, '_load_from_state_dict', networks.network_MultiheadAttention_load_state_dict)
def undo(self):
self.Linear_forward = patches.undo(__name__, torch.nn.Linear, 'forward')
self.Linear_load_state_dict = patches.undo(__name__, torch.nn.Linear, '_load_from_state_dict')
self.Conv2d_forward = patches.undo(__name__, torch.nn.Conv2d, 'forward')
self.Conv2d_load_state_dict = patches.undo(__name__, torch.nn.Conv2d, '_load_from_state_dict')
self.GroupNorm_forward = patches.undo(__name__, torch.nn.GroupNorm, 'forward')
self.GroupNorm_load_state_dict = patches.undo(__name__, torch.nn.GroupNorm, '_load_from_state_dict')
self.LayerNorm_forward = patches.undo(__name__, torch.nn.LayerNorm, 'forward')
self.LayerNorm_load_state_dict = patches.undo(__name__, torch.nn.LayerNorm, '_load_from_state_dict')
self.MultiheadAttention_forward = patches.undo(__name__, torch.nn.MultiheadAttention, 'forward')
self.MultiheadAttention_load_state_dict = patches.undo(__name__, torch.nn.MultiheadAttention, '_load_from_state_dict')

View File

@ -19,3 +19,50 @@ def rebuild_cp_decomposition(up, down, mid):
up = up.reshape(up.size(0), -1)
down = down.reshape(down.size(0), -1)
return torch.einsum('n m k l, i n, m j -> i j k l', mid, up, down)
# copied from https://github.com/KohakuBlueleaf/LyCORIS/blob/dev/lycoris/modules/lokr.py
def factorization(dimension: int, factor:int=-1) -> tuple[int, int]:
'''
return a tuple of two value of input dimension decomposed by the number closest to factor
second value is higher or equal than first value.
In LoRA with Kroneckor Product, first value is a value for weight scale.
secon value is a value for weight.
Because of non-commutative property, AB BA. Meaning of two matrices is slightly different.
examples)
factor
-1 2 4 8 16 ...
127 -> 1, 127 127 -> 1, 127 127 -> 1, 127 127 -> 1, 127 127 -> 1, 127
128 -> 8, 16 128 -> 2, 64 128 -> 4, 32 128 -> 8, 16 128 -> 8, 16
250 -> 10, 25 250 -> 2, 125 250 -> 2, 125 250 -> 5, 50 250 -> 10, 25
360 -> 8, 45 360 -> 2, 180 360 -> 4, 90 360 -> 8, 45 360 -> 12, 30
512 -> 16, 32 512 -> 2, 256 512 -> 4, 128 512 -> 8, 64 512 -> 16, 32
1024 -> 32, 32 1024 -> 2, 512 1024 -> 4, 256 1024 -> 8, 128 1024 -> 16, 64
'''
if factor > 0 and (dimension % factor) == 0:
m = factor
n = dimension // factor
if m > n:
n, m = m, n
return m, n
if factor < 0:
factor = dimension
m, n = 1, dimension
length = m + n
while m<n:
new_m = m + 1
while dimension%new_m != 0:
new_m += 1
new_n = dimension // new_m
if new_m + new_n > length or new_m>factor:
break
else:
m, n = new_m, new_n
if m > n:
n, m = m, n
return m, n

View File

@ -3,7 +3,11 @@ import os
from collections import namedtuple
import enum
import torch.nn as nn
import torch.nn.functional as F
from modules import sd_models, cache, errors, hashes, shared
import modules.models.sd3.mmdit
NetworkWeights = namedtuple('NetworkWeights', ['network_key', 'sd_key', 'w', 'sd_module'])
@ -26,7 +30,6 @@ class NetworkOnDisk:
def read_metadata():
metadata = sd_models.read_metadata_from_safetensors(filename)
metadata.pop('ssmd_cover_images', None) # those are cover images, and they are too big to display in UI as text
return metadata
@ -93,6 +96,7 @@ class Network: # LoraModule
self.unet_multiplier = 1.0
self.dyn_dim = None
self.modules = {}
self.bundle_embeddings = {}
self.mtime = None
self.mentioned_name = None
@ -111,14 +115,49 @@ class NetworkModule:
self.sd_key = weights.sd_key
self.sd_module = weights.sd_module
if hasattr(self.sd_module, 'weight'):
if isinstance(self.sd_module, modules.models.sd3.mmdit.QkvLinear):
s = self.sd_module.weight.shape
self.shape = (s[0] // 3, s[1])
elif hasattr(self.sd_module, 'weight'):
self.shape = self.sd_module.weight.shape
elif isinstance(self.sd_module, nn.MultiheadAttention):
# For now, only self-attn use Pytorch's MHA
# So assume all qkvo proj have same shape
self.shape = self.sd_module.out_proj.weight.shape
else:
self.shape = None
self.ops = None
self.extra_kwargs = {}
if isinstance(self.sd_module, nn.Conv2d):
self.ops = F.conv2d
self.extra_kwargs = {
'stride': self.sd_module.stride,
'padding': self.sd_module.padding
}
elif isinstance(self.sd_module, nn.Linear):
self.ops = F.linear
elif isinstance(self.sd_module, nn.LayerNorm):
self.ops = F.layer_norm
self.extra_kwargs = {
'normalized_shape': self.sd_module.normalized_shape,
'eps': self.sd_module.eps
}
elif isinstance(self.sd_module, nn.GroupNorm):
self.ops = F.group_norm
self.extra_kwargs = {
'num_groups': self.sd_module.num_groups,
'eps': self.sd_module.eps
}
self.dim = None
self.bias = weights.w.get("bias")
self.alpha = weights.w["alpha"].item() if "alpha" in weights.w else None
self.scale = weights.w["scale"].item() if "scale" in weights.w else None
self.dora_scale = weights.w.get("dora_scale", None)
self.dora_norm_dims = len(self.shape) - 1
def multiplier(self):
if 'transformer' in self.sd_key[:20]:
return self.network.te_multiplier
@ -133,10 +172,31 @@ class NetworkModule:
return 1.0
def finalize_updown(self, updown, orig_weight, output_shape):
def apply_weight_decompose(self, updown, orig_weight):
# Match the device/dtype
orig_weight = orig_weight.to(updown.dtype)
dora_scale = self.dora_scale.to(device=orig_weight.device, dtype=updown.dtype)
updown = updown.to(orig_weight.device)
merged_scale1 = updown + orig_weight
merged_scale1_norm = (
merged_scale1.transpose(0, 1)
.reshape(merged_scale1.shape[1], -1)
.norm(dim=1, keepdim=True)
.reshape(merged_scale1.shape[1], *[1] * self.dora_norm_dims)
.transpose(0, 1)
)
dora_merged = (
merged_scale1 * (dora_scale / merged_scale1_norm)
)
final_updown = dora_merged - orig_weight
return final_updown
def finalize_updown(self, updown, orig_weight, output_shape, ex_bias=None):
if self.bias is not None:
updown = updown.reshape(self.bias.shape)
updown += self.bias.to(orig_weight.device, dtype=orig_weight.dtype)
updown += self.bias.to(orig_weight.device, dtype=updown.dtype)
updown = updown.reshape(output_shape)
if len(output_shape) == 4:
@ -145,11 +205,24 @@ class NetworkModule:
if orig_weight.size().numel() == updown.size().numel():
updown = updown.reshape(orig_weight.shape)
return updown * self.calc_scale() * self.multiplier()
if ex_bias is not None:
ex_bias = ex_bias * self.multiplier()
updown = updown * self.calc_scale()
if self.dora_scale is not None:
updown = self.apply_weight_decompose(updown, orig_weight)
return updown * self.multiplier(), ex_bias
def calc_updown(self, target):
raise NotImplementedError()
def forward(self, x, y):
raise NotImplementedError()
"""A general forward implementation for all modules"""
if self.ops is None:
raise NotImplementedError()
else:
updown, ex_bias = self.calc_updown(self.sd_module.weight)
return y + self.ops(x, weight=updown, bias=ex_bias, **self.extra_kwargs)

View File

@ -14,9 +14,14 @@ class NetworkModuleFull(network.NetworkModule):
super().__init__(net, weights)
self.weight = weights.w.get("diff")
self.ex_bias = weights.w.get("diff_b")
def calc_updown(self, orig_weight):
output_shape = self.weight.shape
updown = self.weight.to(orig_weight.device, dtype=orig_weight.dtype)
updown = self.weight.to(orig_weight.device)
if self.ex_bias is not None:
ex_bias = self.ex_bias.to(orig_weight.device)
else:
ex_bias = None
return self.finalize_updown(updown, orig_weight, output_shape)
return self.finalize_updown(updown, orig_weight, output_shape, ex_bias)

View File

@ -0,0 +1,33 @@
import network
class ModuleTypeGLora(network.ModuleType):
def create_module(self, net: network.Network, weights: network.NetworkWeights):
if all(x in weights.w for x in ["a1.weight", "a2.weight", "alpha", "b1.weight", "b2.weight"]):
return NetworkModuleGLora(net, weights)
return None
# adapted from https://github.com/KohakuBlueleaf/LyCORIS
class NetworkModuleGLora(network.NetworkModule):
def __init__(self, net: network.Network, weights: network.NetworkWeights):
super().__init__(net, weights)
if hasattr(self.sd_module, 'weight'):
self.shape = self.sd_module.weight.shape
self.w1a = weights.w["a1.weight"]
self.w1b = weights.w["b1.weight"]
self.w2a = weights.w["a2.weight"]
self.w2b = weights.w["b2.weight"]
def calc_updown(self, orig_weight):
w1a = self.w1a.to(orig_weight.device)
w1b = self.w1b.to(orig_weight.device)
w2a = self.w2a.to(orig_weight.device)
w2b = self.w2b.to(orig_weight.device)
output_shape = [w1a.size(0), w1b.size(1)]
updown = ((w2b @ w1b) + ((orig_weight.to(dtype = w1a.dtype) @ w2a) @ w1a))
return self.finalize_updown(updown, orig_weight, output_shape)

View File

@ -27,16 +27,16 @@ class NetworkModuleHada(network.NetworkModule):
self.t2 = weights.w.get("hada_t2")
def calc_updown(self, orig_weight):
w1a = self.w1a.to(orig_weight.device, dtype=orig_weight.dtype)
w1b = self.w1b.to(orig_weight.device, dtype=orig_weight.dtype)
w2a = self.w2a.to(orig_weight.device, dtype=orig_weight.dtype)
w2b = self.w2b.to(orig_weight.device, dtype=orig_weight.dtype)
w1a = self.w1a.to(orig_weight.device)
w1b = self.w1b.to(orig_weight.device)
w2a = self.w2a.to(orig_weight.device)
w2b = self.w2b.to(orig_weight.device)
output_shape = [w1a.size(0), w1b.size(1)]
if self.t1 is not None:
output_shape = [w1a.size(1), w1b.size(1)]
t1 = self.t1.to(orig_weight.device, dtype=orig_weight.dtype)
t1 = self.t1.to(orig_weight.device)
updown1 = lyco_helpers.make_weight_cp(t1, w1a, w1b)
output_shape += t1.shape[2:]
else:
@ -45,7 +45,7 @@ class NetworkModuleHada(network.NetworkModule):
updown1 = lyco_helpers.rebuild_conventional(w1a, w1b, output_shape)
if self.t2 is not None:
t2 = self.t2.to(orig_weight.device, dtype=orig_weight.dtype)
t2 = self.t2.to(orig_weight.device)
updown2 = lyco_helpers.make_weight_cp(t2, w2a, w2b)
else:
updown2 = lyco_helpers.rebuild_conventional(w2a, w2b, output_shape)

View File

@ -17,7 +17,7 @@ class NetworkModuleIa3(network.NetworkModule):
self.on_input = weights.w["on_input"].item()
def calc_updown(self, orig_weight):
w = self.w.to(orig_weight.device, dtype=orig_weight.dtype)
w = self.w.to(orig_weight.device)
output_shape = [w.size(0), orig_weight.size(1)]
if self.on_input:

View File

@ -37,22 +37,22 @@ class NetworkModuleLokr(network.NetworkModule):
def calc_updown(self, orig_weight):
if self.w1 is not None:
w1 = self.w1.to(orig_weight.device, dtype=orig_weight.dtype)
w1 = self.w1.to(orig_weight.device)
else:
w1a = self.w1a.to(orig_weight.device, dtype=orig_weight.dtype)
w1b = self.w1b.to(orig_weight.device, dtype=orig_weight.dtype)
w1a = self.w1a.to(orig_weight.device)
w1b = self.w1b.to(orig_weight.device)
w1 = w1a @ w1b
if self.w2 is not None:
w2 = self.w2.to(orig_weight.device, dtype=orig_weight.dtype)
w2 = self.w2.to(orig_weight.device)
elif self.t2 is None:
w2a = self.w2a.to(orig_weight.device, dtype=orig_weight.dtype)
w2b = self.w2b.to(orig_weight.device, dtype=orig_weight.dtype)
w2a = self.w2a.to(orig_weight.device)
w2b = self.w2b.to(orig_weight.device)
w2 = w2a @ w2b
else:
t2 = self.t2.to(orig_weight.device, dtype=orig_weight.dtype)
w2a = self.w2a.to(orig_weight.device, dtype=orig_weight.dtype)
w2b = self.w2b.to(orig_weight.device, dtype=orig_weight.dtype)
t2 = self.t2.to(orig_weight.device)
w2a = self.w2a.to(orig_weight.device)
w2b = self.w2b.to(orig_weight.device)
w2 = lyco_helpers.make_weight_cp(t2, w2a, w2b)
output_shape = [w1.size(0) * w2.size(0), w1.size(1) * w2.size(1)]

View File

@ -1,6 +1,7 @@
import torch
import lyco_helpers
import modules.models.sd3.mmdit
import network
from modules import devices
@ -10,6 +11,13 @@ class ModuleTypeLora(network.ModuleType):
if all(x in weights.w for x in ["lora_up.weight", "lora_down.weight"]):
return NetworkModuleLora(net, weights)
if all(x in weights.w for x in ["lora_A.weight", "lora_B.weight"]):
w = weights.w.copy()
weights.w.clear()
weights.w.update({"lora_up.weight": w["lora_B.weight"], "lora_down.weight": w["lora_A.weight"]})
return NetworkModuleLora(net, weights)
return None
@ -29,7 +37,7 @@ class NetworkModuleLora(network.NetworkModule):
if weight is None and none_ok:
return None
is_linear = type(self.sd_module) in [torch.nn.Linear, torch.nn.modules.linear.NonDynamicallyQuantizableLinear, torch.nn.MultiheadAttention]
is_linear = type(self.sd_module) in [torch.nn.Linear, torch.nn.modules.linear.NonDynamicallyQuantizableLinear, torch.nn.MultiheadAttention, modules.models.sd3.mmdit.QkvLinear]
is_conv = type(self.sd_module) in [torch.nn.Conv2d]
if is_linear:
@ -61,13 +69,13 @@ class NetworkModuleLora(network.NetworkModule):
return module
def calc_updown(self, orig_weight):
up = self.up_model.weight.to(orig_weight.device, dtype=orig_weight.dtype)
down = self.down_model.weight.to(orig_weight.device, dtype=orig_weight.dtype)
up = self.up_model.weight.to(orig_weight.device)
down = self.down_model.weight.to(orig_weight.device)
output_shape = [up.size(0), down.size(1)]
if self.mid_model is not None:
# cp-decomposition
mid = self.mid_model.weight.to(orig_weight.device, dtype=orig_weight.dtype)
mid = self.mid_model.weight.to(orig_weight.device)
updown = lyco_helpers.rebuild_cp_decomposition(up, down, mid)
output_shape += mid.shape[2:]
else:

View File

@ -0,0 +1,28 @@
import network
class ModuleTypeNorm(network.ModuleType):
def create_module(self, net: network.Network, weights: network.NetworkWeights):
if all(x in weights.w for x in ["w_norm", "b_norm"]):
return NetworkModuleNorm(net, weights)
return None
class NetworkModuleNorm(network.NetworkModule):
def __init__(self, net: network.Network, weights: network.NetworkWeights):
super().__init__(net, weights)
self.w_norm = weights.w.get("w_norm")
self.b_norm = weights.w.get("b_norm")
def calc_updown(self, orig_weight):
output_shape = self.w_norm.shape
updown = self.w_norm.to(orig_weight.device)
if self.b_norm is not None:
ex_bias = self.b_norm.to(orig_weight.device)
else:
ex_bias = None
return self.finalize_updown(updown, orig_weight, output_shape, ex_bias)

View File

@ -0,0 +1,118 @@
import torch
import network
from einops import rearrange
class ModuleTypeOFT(network.ModuleType):
def create_module(self, net: network.Network, weights: network.NetworkWeights):
if all(x in weights.w for x in ["oft_blocks"]) or all(x in weights.w for x in ["oft_diag"]):
return NetworkModuleOFT(net, weights)
return None
# Supports both kohya-ss' implementation of COFT https://github.com/kohya-ss/sd-scripts/blob/main/networks/oft.py
# and KohakuBlueleaf's implementation of OFT/COFT https://github.com/KohakuBlueleaf/LyCORIS/blob/dev/lycoris/modules/diag_oft.py
class NetworkModuleOFT(network.NetworkModule):
def __init__(self, net: network.Network, weights: network.NetworkWeights):
super().__init__(net, weights)
self.lin_module = None
self.org_module: list[torch.Module] = [self.sd_module]
self.scale = 1.0
self.is_R = False
self.is_boft = False
# kohya-ss/New LyCORIS OFT/BOFT
if "oft_blocks" in weights.w.keys():
self.oft_blocks = weights.w["oft_blocks"] # (num_blocks, block_size, block_size)
self.alpha = weights.w.get("alpha", None) # alpha is constraint
self.dim = self.oft_blocks.shape[0] # lora dim
# Old LyCORIS OFT
elif "oft_diag" in weights.w.keys():
self.is_R = True
self.oft_blocks = weights.w["oft_diag"]
# self.alpha is unused
self.dim = self.oft_blocks.shape[1] # (num_blocks, block_size, block_size)
is_linear = type(self.sd_module) in [torch.nn.Linear, torch.nn.modules.linear.NonDynamicallyQuantizableLinear]
is_conv = type(self.sd_module) in [torch.nn.Conv2d]
is_other_linear = type(self.sd_module) in [torch.nn.MultiheadAttention] # unsupported
if is_linear:
self.out_dim = self.sd_module.out_features
elif is_conv:
self.out_dim = self.sd_module.out_channels
elif is_other_linear:
self.out_dim = self.sd_module.embed_dim
# LyCORIS BOFT
if self.oft_blocks.dim() == 4:
self.is_boft = True
self.rescale = weights.w.get('rescale', None)
if self.rescale is not None and not is_other_linear:
self.rescale = self.rescale.reshape(-1, *[1]*(self.org_module[0].weight.dim() - 1))
self.num_blocks = self.dim
self.block_size = self.out_dim // self.dim
self.constraint = (0 if self.alpha is None else self.alpha) * self.out_dim
if self.is_R:
self.constraint = None
self.block_size = self.dim
self.num_blocks = self.out_dim // self.dim
elif self.is_boft:
self.boft_m = self.oft_blocks.shape[0]
self.num_blocks = self.oft_blocks.shape[1]
self.block_size = self.oft_blocks.shape[2]
self.boft_b = self.block_size
def calc_updown(self, orig_weight):
oft_blocks = self.oft_blocks.to(orig_weight.device)
eye = torch.eye(self.block_size, device=oft_blocks.device)
if not self.is_R:
block_Q = oft_blocks - oft_blocks.transpose(-1, -2) # ensure skew-symmetric orthogonal matrix
if self.constraint != 0:
norm_Q = torch.norm(block_Q.flatten())
new_norm_Q = torch.clamp(norm_Q, max=self.constraint.to(oft_blocks.device))
block_Q = block_Q * ((new_norm_Q + 1e-8) / (norm_Q + 1e-8))
oft_blocks = torch.matmul(eye + block_Q, (eye - block_Q).float().inverse())
R = oft_blocks.to(orig_weight.device)
if not self.is_boft:
# This errors out for MultiheadAttention, might need to be handled up-stream
merged_weight = rearrange(orig_weight, '(k n) ... -> k n ...', k=self.num_blocks, n=self.block_size)
merged_weight = torch.einsum(
'k n m, k n ... -> k m ...',
R,
merged_weight
)
merged_weight = rearrange(merged_weight, 'k m ... -> (k m) ...')
else:
# TODO: determine correct value for scale
scale = 1.0
m = self.boft_m
b = self.boft_b
r_b = b // 2
inp = orig_weight
for i in range(m):
bi = R[i] # b_num, b_size, b_size
if i == 0:
# Apply multiplier/scale and rescale into first weight
bi = bi * scale + (1 - scale) * eye
inp = rearrange(inp, "(c g k) ... -> (c k g) ...", g=2, k=2**i * r_b)
inp = rearrange(inp, "(d b) ... -> d b ...", b=b)
inp = torch.einsum("b i j, b j ... -> b i ...", bi, inp)
inp = rearrange(inp, "d b ... -> (d b) ...")
inp = rearrange(inp, "(c k g) ... -> (c g k) ...", g=2, k=2**i * r_b)
merged_weight = inp
# Rescale mechanism
if self.rescale is not None:
merged_weight = self.rescale.to(merged_weight) * merged_weight
updown = merged_weight.to(orig_weight.device) - orig_weight.to(merged_weight.dtype)
output_shape = orig_weight.shape
return self.finalize_updown(updown, orig_weight, output_shape)

View File

@ -1,17 +1,28 @@
from __future__ import annotations
import gradio as gr
import logging
import os
import re
import lora_patches
import network
import network_lora
import network_glora
import network_hada
import network_ia3
import network_lokr
import network_full
import network_norm
import network_oft
import torch
from typing import Union
from modules import shared, devices, sd_models, errors, scripts, sd_hijack
import modules.textual_inversion.textual_inversion as textual_inversion
import modules.models.sd3.mmdit
from lora_logger import logger
module_types = [
network_lora.ModuleTypeLora(),
@ -19,6 +30,9 @@ module_types = [
network_ia3.ModuleTypeIa3(),
network_lokr.ModuleTypeLokr(),
network_full.ModuleTypeFull(),
network_norm.ModuleTypeNorm(),
network_glora.ModuleTypeGLora(),
network_oft.ModuleTypeOFT(),
]
@ -31,6 +45,8 @@ suffix_conversion = {
"resnets": {
"conv1": "in_layers_2",
"conv2": "out_layers_3",
"norm1": "in_layers_0",
"norm2": "out_layers_0",
"time_emb_proj": "emb_layers_1",
"conv_shortcut": "skip_connection",
}
@ -116,7 +132,9 @@ def assign_network_names_to_compvis_modules(sd_model):
network_layer_mapping[network_name] = module
module.network_layer_name = network_name
else:
for name, module in shared.sd_model.cond_stage_model.wrapped.named_modules():
cond_stage_model = getattr(shared.sd_model.cond_stage_model, 'wrapped', shared.sd_model.cond_stage_model)
for name, module in cond_stage_model.named_modules():
network_name = name.replace(".", "_")
network_layer_mapping[network_name] = module
module.network_layer_name = network_name
@ -129,6 +147,14 @@ def assign_network_names_to_compvis_modules(sd_model):
sd_model.network_layer_mapping = network_layer_mapping
class BundledTIHash(str):
def __init__(self, hash_str):
self.hash = hash_str
def __str__(self):
return self.hash if shared.opts.lora_bundled_ti_to_infotext else ''
def load_network(name, network_on_disk):
net = network.Network(name, network_on_disk)
net.mtime = os.path.getmtime(network_on_disk.filename)
@ -141,13 +167,42 @@ def load_network(name, network_on_disk):
keys_failed_to_match = {}
is_sd2 = 'model_transformer_resblocks' in shared.sd_model.network_layer_mapping
if hasattr(shared.sd_model, 'diffusers_weight_map'):
diffusers_weight_map = shared.sd_model.diffusers_weight_map
elif hasattr(shared.sd_model, 'diffusers_weight_mapping'):
diffusers_weight_map = {}
for k, v in shared.sd_model.diffusers_weight_mapping():
diffusers_weight_map[k] = v
shared.sd_model.diffusers_weight_map = diffusers_weight_map
else:
diffusers_weight_map = None
matched_networks = {}
bundle_embeddings = {}
for key_network, weight in sd.items():
key_network_without_network_parts, network_part = key_network.split(".", 1)
key = convert_diffusers_name_to_compvis(key_network_without_network_parts, is_sd2)
if diffusers_weight_map:
key_network_without_network_parts, network_name, network_weight = key_network.rsplit(".", 2)
network_part = network_name + '.' + network_weight
else:
key_network_without_network_parts, _, network_part = key_network.partition(".")
if key_network_without_network_parts == "bundle_emb":
emb_name, vec_name = network_part.split(".", 1)
emb_dict = bundle_embeddings.get(emb_name, {})
if vec_name.split('.')[0] == 'string_to_param':
_, k2 = vec_name.split('.', 1)
emb_dict['string_to_param'] = {k2: weight}
else:
emb_dict[vec_name] = weight
bundle_embeddings[emb_name] = emb_dict
if diffusers_weight_map:
key = diffusers_weight_map.get(key_network_without_network_parts, key_network_without_network_parts)
else:
key = convert_diffusers_name_to_compvis(key_network_without_network_parts, is_sd2)
sd_module = shared.sd_model.network_layer_mapping.get(key, None)
if sd_module is None:
@ -168,6 +223,17 @@ def load_network(name, network_on_disk):
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)
# kohya_ss OFT module
elif sd_module is None and "oft_unet" in key_network_without_network_parts:
key = key_network_without_network_parts.replace("oft_unet", "diffusion_model")
sd_module = shared.sd_model.network_layer_mapping.get(key, None)
# KohakuBlueLeaf OFT module
if sd_module is None and "oft_diag" in key:
key = key_network_without_network_parts.replace("lora_unet", "diffusion_model")
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)
if sd_module is None:
keys_failed_to_match[key_network] = key
continue
@ -189,38 +255,73 @@ def load_network(name, network_on_disk):
net.modules[key] = net_module
embeddings = {}
for emb_name, data in bundle_embeddings.items():
embedding = textual_inversion.create_embedding_from_data(data, emb_name, filename=network_on_disk.filename + "/" + emb_name)
embedding.loaded = None
embedding.shorthash = BundledTIHash(name)
embeddings[emb_name] = embedding
net.bundle_embeddings = embeddings
if keys_failed_to_match:
print(f"Failed to match keys when loading network {network_on_disk.filename}: {keys_failed_to_match}")
logging.debug(f"Network {network_on_disk.filename} didn't match keys: {keys_failed_to_match}")
return net
def purge_networks_from_memory():
while len(networks_in_memory) > shared.opts.lora_in_memory_limit and len(networks_in_memory) > 0:
name = next(iter(networks_in_memory))
networks_in_memory.pop(name, None)
devices.torch_gc()
def load_networks(names, te_multipliers=None, unet_multipliers=None, dyn_dims=None):
emb_db = sd_hijack.model_hijack.embedding_db
already_loaded = {}
for net in loaded_networks:
if net.name in names:
already_loaded[net.name] = net
for emb_name, embedding in net.bundle_embeddings.items():
if embedding.loaded:
emb_db.register_embedding_by_name(None, shared.sd_model, emb_name)
loaded_networks.clear()
networks_on_disk = [available_network_aliases.get(name, None) for name in names]
unavailable_networks = []
for name in names:
if name.lower() in forbidden_network_aliases and available_networks.get(name) is None:
unavailable_networks.append(name)
elif available_network_aliases.get(name) is None:
unavailable_networks.append(name)
if unavailable_networks:
update_available_networks_by_names(unavailable_networks)
networks_on_disk = [available_networks.get(name, None) if name.lower() in forbidden_network_aliases else available_network_aliases.get(name, None) for name in names]
if any(x is None for x in networks_on_disk):
list_available_networks()
networks_on_disk = [available_network_aliases.get(name, None) for name in names]
networks_on_disk = [available_networks.get(name, None) if name.lower() in forbidden_network_aliases else available_network_aliases.get(name, None) for name in names]
failed_to_load_networks = []
for i, name in enumerate(names):
for i, (network_on_disk, name) in enumerate(zip(networks_on_disk, names)):
net = already_loaded.get(name, None)
network_on_disk = networks_on_disk[i]
if network_on_disk is not None:
if net is None:
net = networks_in_memory.get(name)
if net is None or os.path.getmtime(network_on_disk.filename) > net.mtime:
try:
net = load_network(name, network_on_disk)
networks_in_memory.pop(name, None)
networks_in_memory[name] = net
except Exception as e:
errors.display(e, f"loading network {network_on_disk.filename}")
continue
@ -231,7 +332,7 @@ def load_networks(names, te_multipliers=None, unet_multipliers=None, dyn_dims=No
if net is None:
failed_to_load_networks.append(name)
print(f"Couldn't find network with name {name}")
logging.info(f"Couldn't find network with name {name}")
continue
net.te_multiplier = te_multipliers[i] if te_multipliers else 1.0
@ -239,28 +340,79 @@ def load_networks(names, te_multipliers=None, unet_multipliers=None, dyn_dims=No
net.dyn_dim = dyn_dims[i] if dyn_dims else 1.0
loaded_networks.append(net)
for emb_name, embedding in net.bundle_embeddings.items():
if embedding.loaded is None and emb_name in emb_db.word_embeddings:
logger.warning(
f'Skip bundle embedding: "{emb_name}"'
' as it was already loaded from embeddings folder'
)
continue
embedding.loaded = False
if emb_db.expected_shape == -1 or emb_db.expected_shape == embedding.shape:
embedding.loaded = True
emb_db.register_embedding(embedding, shared.sd_model)
else:
emb_db.skipped_embeddings[name] = embedding
if failed_to_load_networks:
sd_hijack.model_hijack.comments.append("Failed to find networks: " + ", ".join(failed_to_load_networks))
lora_not_found_message = f'Lora not found: {", ".join(failed_to_load_networks)}'
sd_hijack.model_hijack.comments.append(lora_not_found_message)
if shared.opts.lora_not_found_warning_console:
print(f'\n{lora_not_found_message}\n')
if shared.opts.lora_not_found_gradio_warning:
gr.Warning(lora_not_found_message)
purge_networks_from_memory()
def network_restore_weights_from_backup(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.MultiheadAttention]):
weights_backup = getattr(self, "network_weights_backup", None)
def allowed_layer_without_weight(layer):
if isinstance(layer, torch.nn.LayerNorm) and not layer.elementwise_affine:
return True
if weights_backup is None:
return False
def store_weights_backup(weight):
if weight is None:
return None
return weight.to(devices.cpu, copy=True)
def restore_weights_backup(obj, field, weight):
if weight is None:
setattr(obj, field, None)
return
getattr(obj, field).copy_(weight)
def network_restore_weights_from_backup(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.GroupNorm, torch.nn.LayerNorm, torch.nn.MultiheadAttention]):
weights_backup = getattr(self, "network_weights_backup", None)
bias_backup = getattr(self, "network_bias_backup", None)
if weights_backup is None and bias_backup is None:
return
if weights_backup is not None:
if isinstance(self, torch.nn.MultiheadAttention):
restore_weights_backup(self, 'in_proj_weight', weights_backup[0])
restore_weights_backup(self.out_proj, 'weight', weights_backup[1])
else:
restore_weights_backup(self, 'weight', weights_backup)
if isinstance(self, torch.nn.MultiheadAttention):
self.in_proj_weight.copy_(weights_backup[0])
self.out_proj.weight.copy_(weights_backup[1])
restore_weights_backup(self.out_proj, 'bias', bias_backup)
else:
self.weight.copy_(weights_backup)
restore_weights_backup(self, 'bias', bias_backup)
def network_apply_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.MultiheadAttention]):
def network_apply_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.GroupNorm, torch.nn.LayerNorm, torch.nn.MultiheadAttention]):
"""
Applies the currently selected set of networks to the weights of torch layer self.
If weights already have this particular set of networks applied, does nothing.
If not, restores orginal weights from backup and alters weights according to networks.
If not, restores original weights from backup and alters weights according to networks.
"""
network_layer_name = getattr(self, 'network_layer_name', None)
@ -271,29 +423,66 @@ def network_apply_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn
wanted_names = tuple((x.name, x.te_multiplier, x.unet_multiplier, x.dyn_dim) for x in loaded_networks)
weights_backup = getattr(self, "network_weights_backup", None)
if weights_backup is None:
if weights_backup is None and wanted_names != ():
if current_names != () and not allowed_layer_without_weight(self):
raise RuntimeError(f"{network_layer_name} - no backup weights found and current weights are not unchanged")
if isinstance(self, torch.nn.MultiheadAttention):
weights_backup = (self.in_proj_weight.to(devices.cpu, copy=True), self.out_proj.weight.to(devices.cpu, copy=True))
weights_backup = (store_weights_backup(self.in_proj_weight), store_weights_backup(self.out_proj.weight))
else:
weights_backup = self.weight.to(devices.cpu, copy=True)
weights_backup = store_weights_backup(self.weight)
self.network_weights_backup = weights_backup
bias_backup = getattr(self, "network_bias_backup", None)
if bias_backup is None and wanted_names != ():
if isinstance(self, torch.nn.MultiheadAttention) and self.out_proj.bias is not None:
bias_backup = store_weights_backup(self.out_proj.bias)
elif getattr(self, 'bias', None) is not None:
bias_backup = store_weights_backup(self.bias)
else:
bias_backup = None
# Unlike weight which always has value, some modules don't have bias.
# Only report if bias is not None and current bias are not unchanged.
if bias_backup is not None and current_names != ():
raise RuntimeError("no backup bias found and current bias are not unchanged")
self.network_bias_backup = bias_backup
if current_names != wanted_names:
network_restore_weights_from_backup(self)
for net in loaded_networks:
module = net.modules.get(network_layer_name, None)
if module is not None and hasattr(self, 'weight'):
with torch.no_grad():
updown = module.calc_updown(self.weight)
if module is not None and hasattr(self, 'weight') and not isinstance(module, modules.models.sd3.mmdit.QkvLinear):
try:
with torch.no_grad():
if getattr(self, 'fp16_weight', None) is None:
weight = self.weight
bias = self.bias
else:
weight = self.fp16_weight.clone().to(self.weight.device)
bias = getattr(self, 'fp16_bias', None)
if bias is not None:
bias = bias.clone().to(self.bias.device)
updown, ex_bias = module.calc_updown(weight)
if len(self.weight.shape) == 4 and self.weight.shape[1] == 9:
# inpainting model. zero pad updown to make channel[1] 4 to 9
updown = torch.nn.functional.pad(updown, (0, 0, 0, 0, 0, 5))
if len(weight.shape) == 4 and weight.shape[1] == 9:
# inpainting model. zero pad updown to make channel[1] 4 to 9
updown = torch.nn.functional.pad(updown, (0, 0, 0, 0, 0, 5))
self.weight += updown
continue
self.weight.copy_((weight.to(dtype=updown.dtype) + updown).to(dtype=self.weight.dtype))
if ex_bias is not None and hasattr(self, 'bias'):
if self.bias is None:
self.bias = torch.nn.Parameter(ex_bias).to(self.weight.dtype)
else:
self.bias.copy_((bias + ex_bias).to(dtype=self.bias.dtype))
except RuntimeError as e:
logging.debug(f"Network {net.name} layer {network_layer_name}: {e}")
extra_network_lora.errors[net.name] = extra_network_lora.errors.get(net.name, 0) + 1
continue
module_q = net.modules.get(network_layer_name + "_q_proj", None)
module_k = net.modules.get(network_layer_name + "_k_proj", None)
@ -301,48 +490,81 @@ def network_apply_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn
module_out = net.modules.get(network_layer_name + "_out_proj", None)
if isinstance(self, torch.nn.MultiheadAttention) and module_q and module_k and module_v and module_out:
with torch.no_grad():
updown_q = module_q.calc_updown(self.in_proj_weight)
updown_k = module_k.calc_updown(self.in_proj_weight)
updown_v = module_v.calc_updown(self.in_proj_weight)
updown_qkv = torch.vstack([updown_q, updown_k, updown_v])
updown_out = module_out.calc_updown(self.out_proj.weight)
try:
with torch.no_grad():
# Send "real" orig_weight into MHA's lora module
qw, kw, vw = self.in_proj_weight.chunk(3, 0)
updown_q, _ = module_q.calc_updown(qw)
updown_k, _ = module_k.calc_updown(kw)
updown_v, _ = module_v.calc_updown(vw)
del qw, kw, vw
updown_qkv = torch.vstack([updown_q, updown_k, updown_v])
updown_out, ex_bias = module_out.calc_updown(self.out_proj.weight)
self.in_proj_weight += updown_qkv
self.out_proj.weight += updown_out
continue
self.in_proj_weight += updown_qkv
self.out_proj.weight += updown_out
if ex_bias is not None:
if self.out_proj.bias is None:
self.out_proj.bias = torch.nn.Parameter(ex_bias)
else:
self.out_proj.bias += ex_bias
except RuntimeError as e:
logging.debug(f"Network {net.name} layer {network_layer_name}: {e}")
extra_network_lora.errors[net.name] = extra_network_lora.errors.get(net.name, 0) + 1
continue
if isinstance(self, modules.models.sd3.mmdit.QkvLinear) and module_q and module_k and module_v:
try:
with torch.no_grad():
# Send "real" orig_weight into MHA's lora module
qw, kw, vw = self.weight.chunk(3, 0)
updown_q, _ = module_q.calc_updown(qw)
updown_k, _ = module_k.calc_updown(kw)
updown_v, _ = module_v.calc_updown(vw)
del qw, kw, vw
updown_qkv = torch.vstack([updown_q, updown_k, updown_v])
self.weight += updown_qkv
except RuntimeError as e:
logging.debug(f"Network {net.name} layer {network_layer_name}: {e}")
extra_network_lora.errors[net.name] = extra_network_lora.errors.get(net.name, 0) + 1
continue
if module is None:
continue
print(f'failed to calculate network weights for layer {network_layer_name}')
logging.debug(f"Network {net.name} layer {network_layer_name}: couldn't find supported operation")
extra_network_lora.errors[net.name] = extra_network_lora.errors.get(net.name, 0) + 1
self.network_current_names = wanted_names
def network_forward(module, input, original_forward):
def network_forward(org_module, input, original_forward):
"""
Old way of applying Lora by executing operations during layer's forward.
Stacking many loras this way results in big performance degradation.
"""
if len(loaded_networks) == 0:
return original_forward(module, input)
return original_forward(org_module, input)
input = devices.cond_cast_unet(input)
network_restore_weights_from_backup(module)
network_reset_cached_weight(module)
network_restore_weights_from_backup(org_module)
network_reset_cached_weight(org_module)
y = original_forward(module, input)
y = original_forward(org_module, input)
network_layer_name = getattr(module, 'network_layer_name', None)
network_layer_name = getattr(org_module, 'network_layer_name', None)
for lora in loaded_networks:
module = lora.modules.get(network_layer_name, None)
if module is None:
continue
y = module.forward(y, input)
y = module.forward(input, y)
return y
@ -350,66 +572,91 @@ def network_forward(module, input, original_forward):
def network_reset_cached_weight(self: Union[torch.nn.Conv2d, torch.nn.Linear]):
self.network_current_names = ()
self.network_weights_backup = None
self.network_bias_backup = None
def network_Linear_forward(self, input):
if shared.opts.lora_functional:
return network_forward(self, input, torch.nn.Linear_forward_before_network)
return network_forward(self, input, originals.Linear_forward)
network_apply_weights(self)
return torch.nn.Linear_forward_before_network(self, input)
return originals.Linear_forward(self, input)
def network_Linear_load_state_dict(self, *args, **kwargs):
network_reset_cached_weight(self)
return torch.nn.Linear_load_state_dict_before_network(self, *args, **kwargs)
return originals.Linear_load_state_dict(self, *args, **kwargs)
def network_Conv2d_forward(self, input):
if shared.opts.lora_functional:
return network_forward(self, input, torch.nn.Conv2d_forward_before_network)
return network_forward(self, input, originals.Conv2d_forward)
network_apply_weights(self)
return torch.nn.Conv2d_forward_before_network(self, input)
return originals.Conv2d_forward(self, input)
def network_Conv2d_load_state_dict(self, *args, **kwargs):
network_reset_cached_weight(self)
return torch.nn.Conv2d_load_state_dict_before_network(self, *args, **kwargs)
return originals.Conv2d_load_state_dict(self, *args, **kwargs)
def network_GroupNorm_forward(self, input):
if shared.opts.lora_functional:
return network_forward(self, input, originals.GroupNorm_forward)
network_apply_weights(self)
return originals.GroupNorm_forward(self, input)
def network_GroupNorm_load_state_dict(self, *args, **kwargs):
network_reset_cached_weight(self)
return originals.GroupNorm_load_state_dict(self, *args, **kwargs)
def network_LayerNorm_forward(self, input):
if shared.opts.lora_functional:
return network_forward(self, input, originals.LayerNorm_forward)
network_apply_weights(self)
return originals.LayerNorm_forward(self, input)
def network_LayerNorm_load_state_dict(self, *args, **kwargs):
network_reset_cached_weight(self)
return originals.LayerNorm_load_state_dict(self, *args, **kwargs)
def network_MultiheadAttention_forward(self, *args, **kwargs):
network_apply_weights(self)
return torch.nn.MultiheadAttention_forward_before_network(self, *args, **kwargs)
return originals.MultiheadAttention_forward(self, *args, **kwargs)
def network_MultiheadAttention_load_state_dict(self, *args, **kwargs):
network_reset_cached_weight(self)
return torch.nn.MultiheadAttention_load_state_dict_before_network(self, *args, **kwargs)
return originals.MultiheadAttention_load_state_dict(self, *args, **kwargs)
def list_available_networks():
available_networks.clear()
available_network_aliases.clear()
forbidden_network_aliases.clear()
available_network_hash_lookup.clear()
forbidden_network_aliases.update({"none": 1, "Addams": 1})
os.makedirs(shared.cmd_opts.lora_dir, exist_ok=True)
def process_network_files(names: list[str] | None = None):
candidates = list(shared.walk_files(shared.cmd_opts.lora_dir, allowed_extensions=[".pt", ".ckpt", ".safetensors"]))
candidates += list(shared.walk_files(shared.cmd_opts.lyco_dir_backcompat, allowed_extensions=[".pt", ".ckpt", ".safetensors"]))
for filename in candidates:
if os.path.isdir(filename):
continue
name = os.path.splitext(os.path.basename(filename))[0]
# if names is provided, only load networks with names in the list
if names and name not in names:
continue
try:
entry = network.NetworkOnDisk(name, filename)
except OSError: # should catch FileNotFoundError and PermissionError etc.
@ -425,6 +672,22 @@ def list_available_networks():
available_network_aliases[entry.alias] = entry
def update_available_networks_by_names(names: list[str]):
process_network_files(names)
def list_available_networks():
available_networks.clear()
available_network_aliases.clear()
forbidden_network_aliases.clear()
available_network_hash_lookup.clear()
forbidden_network_aliases.update({"none": 1, "Addams": 1})
os.makedirs(shared.cmd_opts.lora_dir, exist_ok=True)
process_network_files()
re_network_name = re.compile(r"(.*)\s*\([0-9a-fA-F]+\)")
@ -459,9 +722,15 @@ def infotext_pasted(infotext, params):
params["Prompt"] += "\n" + "".join(added)
originals: lora_patches.LoraPatches = None
extra_network_lora = None
available_networks = {}
available_network_aliases = {}
loaded_networks = []
loaded_bundle_embeddings = {}
networks_in_memory = {}
available_network_hash_lookup = {}
forbidden_network_aliases = {}

View File

@ -1,7 +1,8 @@
import os
from modules import paths
from modules.paths_internal import normalized_filepath
def preload(parser):
parser.add_argument("--lora-dir", type=str, help="Path to directory with Lora networks.", default=os.path.join(paths.models_path, 'Lora'))
parser.add_argument("--lyco-dir-backcompat", type=str, help="Path to directory with LyCORIS networks (for backawards compatibility; can also use --lyco-dir).", default=os.path.join(paths.models_path, 'LyCORIS'))
parser.add_argument("--lora-dir", type=normalized_filepath, help="Path to directory with Lora networks.", default=os.path.join(paths.models_path, 'Lora'))
parser.add_argument("--lyco-dir-backcompat", type=normalized_filepath, help="Path to directory with LyCORIS networks (for backawards compatibility; can also use --lyco-dir).", default=os.path.join(paths.models_path, 'LyCORIS'))

View File

@ -1,57 +1,30 @@
import re
import torch
import gradio as gr
from fastapi import FastAPI
import network
import networks
import lora # noqa:F401
import lora_patches
import extra_networks_lora
import ui_extra_networks_lora
from modules import script_callbacks, ui_extra_networks, extra_networks, shared
def unload():
torch.nn.Linear.forward = torch.nn.Linear_forward_before_network
torch.nn.Linear._load_from_state_dict = torch.nn.Linear_load_state_dict_before_network
torch.nn.Conv2d.forward = torch.nn.Conv2d_forward_before_network
torch.nn.Conv2d._load_from_state_dict = torch.nn.Conv2d_load_state_dict_before_network
torch.nn.MultiheadAttention.forward = torch.nn.MultiheadAttention_forward_before_network
torch.nn.MultiheadAttention._load_from_state_dict = torch.nn.MultiheadAttention_load_state_dict_before_network
networks.originals.undo()
def before_ui():
ui_extra_networks.register_page(ui_extra_networks_lora.ExtraNetworksPageLora())
extra_network = extra_networks_lora.ExtraNetworkLora()
extra_networks.register_extra_network(extra_network)
extra_networks.register_extra_network_alias(extra_network, "lyco")
networks.extra_network_lora = extra_networks_lora.ExtraNetworkLora()
extra_networks.register_extra_network(networks.extra_network_lora)
extra_networks.register_extra_network_alias(networks.extra_network_lora, "lyco")
if not hasattr(torch.nn, 'Linear_forward_before_network'):
torch.nn.Linear_forward_before_network = torch.nn.Linear.forward
if not hasattr(torch.nn, 'Linear_load_state_dict_before_network'):
torch.nn.Linear_load_state_dict_before_network = torch.nn.Linear._load_from_state_dict
if not hasattr(torch.nn, 'Conv2d_forward_before_network'):
torch.nn.Conv2d_forward_before_network = torch.nn.Conv2d.forward
if not hasattr(torch.nn, 'Conv2d_load_state_dict_before_network'):
torch.nn.Conv2d_load_state_dict_before_network = torch.nn.Conv2d._load_from_state_dict
if not hasattr(torch.nn, 'MultiheadAttention_forward_before_network'):
torch.nn.MultiheadAttention_forward_before_network = torch.nn.MultiheadAttention.forward
if not hasattr(torch.nn, 'MultiheadAttention_load_state_dict_before_network'):
torch.nn.MultiheadAttention_load_state_dict_before_network = torch.nn.MultiheadAttention._load_from_state_dict
torch.nn.Linear.forward = networks.network_Linear_forward
torch.nn.Linear._load_from_state_dict = networks.network_Linear_load_state_dict
torch.nn.Conv2d.forward = networks.network_Conv2d_forward
torch.nn.Conv2d._load_from_state_dict = networks.network_Conv2d_load_state_dict
torch.nn.MultiheadAttention.forward = networks.network_MultiheadAttention_forward
torch.nn.MultiheadAttention._load_from_state_dict = networks.network_MultiheadAttention_load_state_dict
networks.originals = lora_patches.LoraPatches()
script_callbacks.on_model_loaded(networks.assign_network_names_to_compvis_modules)
script_callbacks.on_script_unloaded(unload)
@ -63,8 +36,12 @@ shared.options_templates.update(shared.options_section(('extra_networks', "Extra
"sd_lora": shared.OptionInfo("None", "Add network to prompt", gr.Dropdown, lambda: {"choices": ["None", *networks.available_networks]}, refresh=networks.list_available_networks),
"lora_preferred_name": shared.OptionInfo("Alias from file", "When adding to prompt, refer to Lora by", gr.Radio, {"choices": ["Alias from file", "Filename"]}),
"lora_add_hashes_to_infotext": shared.OptionInfo(True, "Add Lora hashes to infotext"),
"lora_bundled_ti_to_infotext": shared.OptionInfo(True, "Add Lora name as TI hashes for bundled Textual Inversion").info('"Add Textual Inversion hashes to infotext" needs to be enabled'),
"lora_show_all": shared.OptionInfo(False, "Always show all networks on the Lora page").info("otherwise, those detected as for incompatible version of Stable Diffusion will be hidden"),
"lora_hide_unknown_for_versions": shared.OptionInfo([], "Hide networks of unknown versions for model versions", gr.CheckboxGroup, {"choices": ["SD1", "SD2", "SDXL"]}),
"lora_in_memory_limit": shared.OptionInfo(0, "Number of Lora networks to keep cached in memory", gr.Number, {"precision": 0}),
"lora_not_found_warning_console": shared.OptionInfo(False, "Lora not found warning in console"),
"lora_not_found_gradio_warning": shared.OptionInfo(False, "Lora not found warning popup in webui"),
}))
@ -121,3 +98,5 @@ def infotext_pasted(infotext, d):
script_callbacks.on_infotext_pasted(infotext_pasted)
shared.opts.onchange("lora_in_memory_limit", networks.purge_networks_from_memory)

View File

@ -21,10 +21,12 @@ re_comma = re.compile(r" *, *")
def build_tags(metadata):
tags = {}
for _, tags_dict in metadata.get("ss_tag_frequency", {}).items():
for tag, tag_count in tags_dict.items():
tag = tag.strip()
tags[tag] = tags.get(tag, 0) + int(tag_count)
ss_tag_frequency = metadata.get("ss_tag_frequency", {})
if ss_tag_frequency is not None and hasattr(ss_tag_frequency, 'items'):
for _, tags_dict in ss_tag_frequency.items():
for tag, tag_count in tags_dict.items():
tag = tag.strip()
tags[tag] = tags.get(tag, 0) + int(tag_count)
if tags and is_non_comma_tagset(tags):
new_tags = {}
@ -54,12 +56,13 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
self.slider_preferred_weight = None
self.edit_notes = None
def save_lora_user_metadata(self, name, desc, sd_version, activation_text, preferred_weight, notes):
def save_lora_user_metadata(self, name, desc, sd_version, activation_text, preferred_weight, negative_text, notes):
user_metadata = self.get_user_metadata(name)
user_metadata["description"] = desc
user_metadata["sd version"] = sd_version
user_metadata["activation text"] = activation_text
user_metadata["preferred weight"] = preferred_weight
user_metadata["negative text"] = negative_text
user_metadata["notes"] = notes
self.write_user_metadata(name, user_metadata)
@ -70,6 +73,7 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
metadata = item.get("metadata") or {}
keys = {
'ss_output_name': "Output name:",
'ss_sd_model_name': "Model:",
'ss_clip_skip': "Clip skip:",
'ss_network_module': "Kohya module:",
@ -126,6 +130,7 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
gr.HighlightedText.update(value=gradio_tags, visible=True if tags else False),
user_metadata.get('activation text', ''),
float(user_metadata.get('preferred weight', 0.0)),
user_metadata.get('negative text', ''),
gr.update(visible=True if tags else False),
gr.update(value=self.generate_random_prompt_from_tags(tags), visible=True if tags else False),
]
@ -146,6 +151,8 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
v = random.random() * max_count
if count > v:
for x in "({[]})":
tag = tag.replace(x, '\\' + x)
res.append(tag)
return ", ".join(sorted(res))
@ -161,13 +168,13 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
self.taginfo = gr.HighlightedText(label="Training dataset tags")
self.edit_activation_text = gr.Text(label='Activation text', info="Will be added to prompt along with Lora")
self.slider_preferred_weight = gr.Slider(label='Preferred weight', info="Set to 0 to disable", minimum=0.0, maximum=2.0, step=0.01)
self.edit_negative_text = gr.Text(label='Negative prompt', info="Will be added to negative prompts")
with gr.Row() as row_random_prompt:
with gr.Column(scale=8):
random_prompt = gr.Textbox(label='Random prompt', lines=4, max_lines=4, interactive=False)
with gr.Column(scale=1, min_width=120):
generate_random_prompt = gr.Button('Generate').style(full_width=True, size="lg")
generate_random_prompt = gr.Button('Generate', size="lg", scale=1)
self.edit_notes = gr.TextArea(label='Notes', lines=4)
@ -197,6 +204,7 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
self.taginfo,
self.edit_activation_text,
self.slider_preferred_weight,
self.edit_negative_text,
row_random_prompt,
random_prompt,
]
@ -210,7 +218,9 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
self.select_sd_version,
self.edit_activation_text,
self.slider_preferred_weight,
self.edit_negative_text,
self.edit_notes,
]
self.setup_save_handler(self.button_save, self.save_lora_user_metadata, edited_components)

View File

@ -17,17 +17,23 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
def create_item(self, name, index=None, enable_filter=True):
lora_on_disk = networks.available_networks.get(name)
if lora_on_disk is None:
return
path, ext = os.path.splitext(lora_on_disk.filename)
alias = lora_on_disk.get_alias()
search_terms = [self.search_terms_from_path(lora_on_disk.filename)]
if lora_on_disk.hash:
search_terms.append(lora_on_disk.hash)
item = {
"name": name,
"filename": lora_on_disk.filename,
"preview": self.find_preview(path),
"shorthash": lora_on_disk.shorthash,
"preview": self.find_preview(path) or self.find_embedded_preview(path, name, lora_on_disk.metadata),
"description": self.find_description(path),
"search_term": self.search_terms_from_path(lora_on_disk.filename),
"search_terms": search_terms,
"local_preview": f"{path}.{shared.opts.samples_format}",
"metadata": lora_on_disk.metadata,
"sort_keys": {'default': index, **self.get_sort_keys(lora_on_disk.filename)},
@ -42,6 +48,11 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
if activation_text:
item["prompt"] += " + " + quote_js(" " + activation_text)
negative_prompt = item["user_metadata"].get("negative text")
item["negative_prompt"] = quote_js("")
if negative_prompt:
item["negative_prompt"] = quote_js('(' + negative_prompt + ':1)')
sd_version = item["user_metadata"].get("sd version")
if sd_version in network.SdVersion.__members__:
item["sd_version"] = sd_version
@ -49,7 +60,7 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
else:
sd_version = lora_on_disk.sd_version
if shared.opts.lora_show_all or not enable_filter:
if shared.opts.lora_show_all or not enable_filter or not shared.sd_model:
pass
elif sd_version == network.SdVersion.Unknown:
model_version = network.SdVersion.SDXL if shared.sd_model.is_sdxl else network.SdVersion.SD2 if shared.sd_model.is_sd2 else network.SdVersion.SD1
@ -65,9 +76,10 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
return item
def list_items(self):
for index, name in enumerate(networks.available_networks):
# instantiate a list to protect against concurrent modification
names = list(networks.available_networks)
for index, name in enumerate(names):
item = self.create_item(name, index)
if item is not None:
yield item

View File

@ -1,16 +1,9 @@
import sys
import PIL.Image
import numpy as np
import torch
from tqdm import tqdm
import modules.upscaler
from modules import devices, modelloader, script_callbacks, errors
from scunet_model_arch import SCUNet
from modules.modelloader import load_file_from_url
from modules.shared import opts
from modules import devices, errors, modelloader, script_callbacks, shared, upscaler_utils
class UpscalerScuNET(modules.upscaler.Upscaler):
@ -42,100 +35,37 @@ class UpscalerScuNET(modules.upscaler.Upscaler):
scalers.append(scaler_data2)
self.scalers = scalers
@staticmethod
@torch.no_grad()
def tiled_inference(img, model):
# test the image tile by tile
h, w = img.shape[2:]
tile = opts.SCUNET_tile
tile_overlap = opts.SCUNET_tile_overlap
if tile == 0:
return model(img)
device = devices.get_device_for('scunet')
assert tile % 8 == 0, "tile size should be a multiple of window_size"
sf = 1
stride = tile - tile_overlap
h_idx_list = list(range(0, h - tile, stride)) + [h - tile]
w_idx_list = list(range(0, w - tile, stride)) + [w - tile]
E = torch.zeros(1, 3, h * sf, w * sf, dtype=img.dtype, device=device)
W = torch.zeros_like(E, dtype=devices.dtype, device=device)
with tqdm(total=len(h_idx_list) * len(w_idx_list), desc="ScuNET tiles") as pbar:
for h_idx in h_idx_list:
for w_idx in w_idx_list:
in_patch = img[..., h_idx: h_idx + tile, w_idx: w_idx + tile]
out_patch = model(in_patch)
out_patch_mask = torch.ones_like(out_patch)
E[
..., h_idx * sf: (h_idx + tile) * sf, w_idx * sf: (w_idx + tile) * sf
].add_(out_patch)
W[
..., h_idx * sf: (h_idx + tile) * sf, w_idx * sf: (w_idx + tile) * sf
].add_(out_patch_mask)
pbar.update(1)
output = E.div_(W)
return output
def do_upscale(self, img: PIL.Image.Image, selected_file):
devices.torch_gc()
try:
model = self.load_model(selected_file)
except Exception as e:
print(f"ScuNET: Unable to load model from {selected_file}: {e}", file=sys.stderr)
return img
device = devices.get_device_for('scunet')
tile = opts.SCUNET_tile
h, w = img.height, img.width
np_img = np.array(img)
np_img = np_img[:, :, ::-1] # RGB to BGR
np_img = np_img.transpose((2, 0, 1)) / 255 # HWC to CHW
torch_img = torch.from_numpy(np_img).float().unsqueeze(0).to(device) # type: ignore
if tile > h or tile > w:
_img = torch.zeros(1, 3, max(h, tile), max(w, tile), dtype=torch_img.dtype, device=torch_img.device)
_img[:, :, :h, :w] = torch_img # pad image
torch_img = _img
torch_output = self.tiled_inference(torch_img, model).squeeze(0)
torch_output = torch_output[:, :h * 1, :w * 1] # remove padding, if any
np_output: np.ndarray = torch_output.float().cpu().clamp_(0, 1).numpy()
del torch_img, torch_output
img = upscaler_utils.upscale_2(
img,
model,
tile_size=shared.opts.SCUNET_tile,
tile_overlap=shared.opts.SCUNET_tile_overlap,
scale=1, # ScuNET is a denoising model, not an upscaler
desc='ScuNET',
)
devices.torch_gc()
output = np_output.transpose((1, 2, 0)) # CHW to HWC
output = output[:, :, ::-1] # BGR to RGB
return PIL.Image.fromarray((output * 255).astype(np.uint8))
return img
def load_model(self, path: str):
device = devices.get_device_for('scunet')
if path.startswith("http"):
# TODO: this doesn't use `path` at all?
filename = load_file_from_url(self.model_url, model_dir=self.model_download_path, file_name=f"{self.name}.pth")
filename = modelloader.load_file_from_url(self.model_url, model_dir=self.model_download_path, file_name=f"{self.name}.pth")
else:
filename = path
model = SCUNet(in_nc=3, config=[4, 4, 4, 4, 4, 4, 4], dim=64)
model.load_state_dict(torch.load(filename), strict=True)
model.eval()
for _, v in model.named_parameters():
v.requires_grad = False
model = model.to(device)
return model
return modelloader.load_spandrel_model(filename, device=device, expected_architecture='SCUNet')
def on_ui_settings():
import gradio as gr
from modules import shared
shared.opts.add_option("SCUNET_tile", shared.OptionInfo(256, "Tile size for SCUNET upscalers.", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}, section=('upscaling', "Upscaling")).info("0 = no tiling"))
shared.opts.add_option("SCUNET_tile_overlap", shared.OptionInfo(8, "Tile overlap for SCUNET upscalers.", gr.Slider, {"minimum": 0, "maximum": 64, "step": 1}, section=('upscaling', "Upscaling")).info("Low values = visible seam"))

View File

@ -1,268 +0,0 @@
# -*- coding: utf-8 -*-
import numpy as np
import torch
import torch.nn as nn
from einops import rearrange
from einops.layers.torch import Rearrange
from timm.models.layers import trunc_normal_, DropPath
class WMSA(nn.Module):
""" Self-attention module in Swin Transformer
"""
def __init__(self, input_dim, output_dim, head_dim, window_size, type):
super(WMSA, self).__init__()
self.input_dim = input_dim
self.output_dim = output_dim
self.head_dim = head_dim
self.scale = self.head_dim ** -0.5
self.n_heads = input_dim // head_dim
self.window_size = window_size
self.type = type
self.embedding_layer = nn.Linear(self.input_dim, 3 * self.input_dim, bias=True)
self.relative_position_params = nn.Parameter(
torch.zeros((2 * window_size - 1) * (2 * window_size - 1), self.n_heads))
self.linear = nn.Linear(self.input_dim, self.output_dim)
trunc_normal_(self.relative_position_params, std=.02)
self.relative_position_params = torch.nn.Parameter(
self.relative_position_params.view(2 * window_size - 1, 2 * window_size - 1, self.n_heads).transpose(1,
2).transpose(
0, 1))
def generate_mask(self, h, w, p, shift):
""" generating the mask of SW-MSA
Args:
shift: shift parameters in CyclicShift.
Returns:
attn_mask: should be (1 1 w p p),
"""
# supporting square.
attn_mask = torch.zeros(h, w, p, p, p, p, dtype=torch.bool, device=self.relative_position_params.device)
if self.type == 'W':
return attn_mask
s = p - shift
attn_mask[-1, :, :s, :, s:, :] = True
attn_mask[-1, :, s:, :, :s, :] = True
attn_mask[:, -1, :, :s, :, s:] = True
attn_mask[:, -1, :, s:, :, :s] = True
attn_mask = rearrange(attn_mask, 'w1 w2 p1 p2 p3 p4 -> 1 1 (w1 w2) (p1 p2) (p3 p4)')
return attn_mask
def forward(self, x):
""" Forward pass of Window Multi-head Self-attention module.
Args:
x: input tensor with shape of [b h w c];
attn_mask: attention mask, fill -inf where the value is True;
Returns:
output: tensor shape [b h w c]
"""
if self.type != 'W':
x = torch.roll(x, shifts=(-(self.window_size // 2), -(self.window_size // 2)), dims=(1, 2))
x = rearrange(x, 'b (w1 p1) (w2 p2) c -> b w1 w2 p1 p2 c', p1=self.window_size, p2=self.window_size)
h_windows = x.size(1)
w_windows = x.size(2)
# square validation
# assert h_windows == w_windows
x = rearrange(x, 'b w1 w2 p1 p2 c -> b (w1 w2) (p1 p2) c', p1=self.window_size, p2=self.window_size)
qkv = self.embedding_layer(x)
q, k, v = rearrange(qkv, 'b nw np (threeh c) -> threeh b nw np c', c=self.head_dim).chunk(3, dim=0)
sim = torch.einsum('hbwpc,hbwqc->hbwpq', q, k) * self.scale
# Adding learnable relative embedding
sim = sim + rearrange(self.relative_embedding(), 'h p q -> h 1 1 p q')
# Using Attn Mask to distinguish different subwindows.
if self.type != 'W':
attn_mask = self.generate_mask(h_windows, w_windows, self.window_size, shift=self.window_size // 2)
sim = sim.masked_fill_(attn_mask, float("-inf"))
probs = nn.functional.softmax(sim, dim=-1)
output = torch.einsum('hbwij,hbwjc->hbwic', probs, v)
output = rearrange(output, 'h b w p c -> b w p (h c)')
output = self.linear(output)
output = rearrange(output, 'b (w1 w2) (p1 p2) c -> b (w1 p1) (w2 p2) c', w1=h_windows, p1=self.window_size)
if self.type != 'W':
output = torch.roll(output, shifts=(self.window_size // 2, self.window_size // 2), dims=(1, 2))
return output
def relative_embedding(self):
cord = torch.tensor(np.array([[i, j] for i in range(self.window_size) for j in range(self.window_size)]))
relation = cord[:, None, :] - cord[None, :, :] + self.window_size - 1
# negative is allowed
return self.relative_position_params[:, relation[:, :, 0].long(), relation[:, :, 1].long()]
class Block(nn.Module):
def __init__(self, input_dim, output_dim, head_dim, window_size, drop_path, type='W', input_resolution=None):
""" SwinTransformer Block
"""
super(Block, self).__init__()
self.input_dim = input_dim
self.output_dim = output_dim
assert type in ['W', 'SW']
self.type = type
if input_resolution <= window_size:
self.type = 'W'
self.ln1 = nn.LayerNorm(input_dim)
self.msa = WMSA(input_dim, input_dim, head_dim, window_size, self.type)
self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
self.ln2 = nn.LayerNorm(input_dim)
self.mlp = nn.Sequential(
nn.Linear(input_dim, 4 * input_dim),
nn.GELU(),
nn.Linear(4 * input_dim, output_dim),
)
def forward(self, x):
x = x + self.drop_path(self.msa(self.ln1(x)))
x = x + self.drop_path(self.mlp(self.ln2(x)))
return x
class ConvTransBlock(nn.Module):
def __init__(self, conv_dim, trans_dim, head_dim, window_size, drop_path, type='W', input_resolution=None):
""" SwinTransformer and Conv Block
"""
super(ConvTransBlock, self).__init__()
self.conv_dim = conv_dim
self.trans_dim = trans_dim
self.head_dim = head_dim
self.window_size = window_size
self.drop_path = drop_path
self.type = type
self.input_resolution = input_resolution
assert self.type in ['W', 'SW']
if self.input_resolution <= self.window_size:
self.type = 'W'
self.trans_block = Block(self.trans_dim, self.trans_dim, self.head_dim, self.window_size, self.drop_path,
self.type, self.input_resolution)
self.conv1_1 = nn.Conv2d(self.conv_dim + self.trans_dim, self.conv_dim + self.trans_dim, 1, 1, 0, bias=True)
self.conv1_2 = nn.Conv2d(self.conv_dim + self.trans_dim, self.conv_dim + self.trans_dim, 1, 1, 0, bias=True)
self.conv_block = nn.Sequential(
nn.Conv2d(self.conv_dim, self.conv_dim, 3, 1, 1, bias=False),
nn.ReLU(True),
nn.Conv2d(self.conv_dim, self.conv_dim, 3, 1, 1, bias=False)
)
def forward(self, x):
conv_x, trans_x = torch.split(self.conv1_1(x), (self.conv_dim, self.trans_dim), dim=1)
conv_x = self.conv_block(conv_x) + conv_x
trans_x = Rearrange('b c h w -> b h w c')(trans_x)
trans_x = self.trans_block(trans_x)
trans_x = Rearrange('b h w c -> b c h w')(trans_x)
res = self.conv1_2(torch.cat((conv_x, trans_x), dim=1))
x = x + res
return x
class SCUNet(nn.Module):
# def __init__(self, in_nc=3, config=[2, 2, 2, 2, 2, 2, 2], dim=64, drop_path_rate=0.0, input_resolution=256):
def __init__(self, in_nc=3, config=None, dim=64, drop_path_rate=0.0, input_resolution=256):
super(SCUNet, self).__init__()
if config is None:
config = [2, 2, 2, 2, 2, 2, 2]
self.config = config
self.dim = dim
self.head_dim = 32
self.window_size = 8
# drop path rate for each layer
dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(config))]
self.m_head = [nn.Conv2d(in_nc, dim, 3, 1, 1, bias=False)]
begin = 0
self.m_down1 = [ConvTransBlock(dim // 2, dim // 2, self.head_dim, self.window_size, dpr[i + begin],
'W' if not i % 2 else 'SW', input_resolution)
for i in range(config[0])] + \
[nn.Conv2d(dim, 2 * dim, 2, 2, 0, bias=False)]
begin += config[0]
self.m_down2 = [ConvTransBlock(dim, dim, self.head_dim, self.window_size, dpr[i + begin],
'W' if not i % 2 else 'SW', input_resolution // 2)
for i in range(config[1])] + \
[nn.Conv2d(2 * dim, 4 * dim, 2, 2, 0, bias=False)]
begin += config[1]
self.m_down3 = [ConvTransBlock(2 * dim, 2 * dim, self.head_dim, self.window_size, dpr[i + begin],
'W' if not i % 2 else 'SW', input_resolution // 4)
for i in range(config[2])] + \
[nn.Conv2d(4 * dim, 8 * dim, 2, 2, 0, bias=False)]
begin += config[2]
self.m_body = [ConvTransBlock(4 * dim, 4 * dim, self.head_dim, self.window_size, dpr[i + begin],
'W' if not i % 2 else 'SW', input_resolution // 8)
for i in range(config[3])]
begin += config[3]
self.m_up3 = [nn.ConvTranspose2d(8 * dim, 4 * dim, 2, 2, 0, bias=False), ] + \
[ConvTransBlock(2 * dim, 2 * dim, self.head_dim, self.window_size, dpr[i + begin],
'W' if not i % 2 else 'SW', input_resolution // 4)
for i in range(config[4])]
begin += config[4]
self.m_up2 = [nn.ConvTranspose2d(4 * dim, 2 * dim, 2, 2, 0, bias=False), ] + \
[ConvTransBlock(dim, dim, self.head_dim, self.window_size, dpr[i + begin],
'W' if not i % 2 else 'SW', input_resolution // 2)
for i in range(config[5])]
begin += config[5]
self.m_up1 = [nn.ConvTranspose2d(2 * dim, dim, 2, 2, 0, bias=False), ] + \
[ConvTransBlock(dim // 2, dim // 2, self.head_dim, self.window_size, dpr[i + begin],
'W' if not i % 2 else 'SW', input_resolution)
for i in range(config[6])]
self.m_tail = [nn.Conv2d(dim, in_nc, 3, 1, 1, bias=False)]
self.m_head = nn.Sequential(*self.m_head)
self.m_down1 = nn.Sequential(*self.m_down1)
self.m_down2 = nn.Sequential(*self.m_down2)
self.m_down3 = nn.Sequential(*self.m_down3)
self.m_body = nn.Sequential(*self.m_body)
self.m_up3 = nn.Sequential(*self.m_up3)
self.m_up2 = nn.Sequential(*self.m_up2)
self.m_up1 = nn.Sequential(*self.m_up1)
self.m_tail = nn.Sequential(*self.m_tail)
# self.apply(self._init_weights)
def forward(self, x0):
h, w = x0.size()[-2:]
paddingBottom = int(np.ceil(h / 64) * 64 - h)
paddingRight = int(np.ceil(w / 64) * 64 - w)
x0 = nn.ReplicationPad2d((0, paddingRight, 0, paddingBottom))(x0)
x1 = self.m_head(x0)
x2 = self.m_down1(x1)
x3 = self.m_down2(x2)
x4 = self.m_down3(x3)
x = self.m_body(x4)
x = self.m_up3(x + x4)
x = self.m_up2(x + x3)
x = self.m_up1(x + x2)
x = self.m_tail(x + x1)
x = x[..., :h, :w]
return x
def _init_weights(self, m):
if isinstance(m, nn.Linear):
trunc_normal_(m.weight, std=.02)
if m.bias is not None:
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.LayerNorm):
nn.init.constant_(m.bias, 0)
nn.init.constant_(m.weight, 1.0)

View File

@ -1,20 +1,15 @@
import logging
import sys
import platform
import numpy as np
import torch
from PIL import Image
from tqdm import tqdm
from modules import modelloader, devices, script_callbacks, shared
from modules.shared import opts, state
from swinir_model_arch import SwinIR
from swinir_model_arch_v2 import Swin2SR
from modules import devices, modelloader, script_callbacks, shared, upscaler_utils
from modules.upscaler import Upscaler, UpscalerData
SWINIR_MODEL_URL = "https://github.com/JingyunLiang/SwinIR/releases/download/v0.0/003_realSR_BSRGAN_DFOWMFC_s64w8_SwinIR-L_x4_GAN.pth"
device_swinir = devices.get_device_for('swinir')
logger = logging.getLogger(__name__)
class UpscalerSwinIR(Upscaler):
@ -37,26 +32,28 @@ class UpscalerSwinIR(Upscaler):
scalers.append(model_data)
self.scalers = scalers
def do_upscale(self, img, model_file):
use_compile = hasattr(opts, 'SWIN_torch_compile') and opts.SWIN_torch_compile \
and int(torch.__version__.split('.')[0]) >= 2 and platform.system() != "Windows"
current_config = (model_file, opts.SWIN_tile)
def do_upscale(self, img: Image.Image, model_file: str) -> Image.Image:
current_config = (model_file, shared.opts.SWIN_tile)
if use_compile and self._cached_model_config == current_config:
if self._cached_model_config == current_config:
model = self._cached_model
else:
self._cached_model = None
try:
model = self.load_model(model_file)
except Exception as e:
print(f"Failed loading SwinIR model {model_file}: {e}", file=sys.stderr)
return img
model = model.to(device_swinir, dtype=devices.dtype)
if use_compile:
model = torch.compile(model)
self._cached_model = model
self._cached_model_config = current_config
img = upscale(img, model)
self._cached_model = model
self._cached_model_config = current_config
img = upscaler_utils.upscale_2(
img,
model,
tile_size=shared.opts.SWIN_tile,
tile_overlap=shared.opts.SWIN_tile_overlap,
scale=model.scale,
desc="SwinIR",
)
devices.torch_gc()
return img
@ -69,115 +66,22 @@ class UpscalerSwinIR(Upscaler):
)
else:
filename = path
if filename.endswith(".v2.pth"):
model = Swin2SR(
upscale=scale,
in_chans=3,
img_size=64,
window_size=8,
img_range=1.0,
depths=[6, 6, 6, 6, 6, 6],
embed_dim=180,
num_heads=[6, 6, 6, 6, 6, 6],
mlp_ratio=2,
upsampler="nearest+conv",
resi_connection="1conv",
)
params = None
else:
model = SwinIR(
upscale=scale,
in_chans=3,
img_size=64,
window_size=8,
img_range=1.0,
depths=[6, 6, 6, 6, 6, 6, 6, 6, 6],
embed_dim=240,
num_heads=[8, 8, 8, 8, 8, 8, 8, 8, 8],
mlp_ratio=2,
upsampler="nearest+conv",
resi_connection="3conv",
)
params = "params_ema"
pretrained_model = torch.load(filename)
if params is not None:
model.load_state_dict(pretrained_model[params], strict=True)
else:
model.load_state_dict(pretrained_model, strict=True)
return model
model_descriptor = modelloader.load_spandrel_model(
filename,
device=self._get_device(),
prefer_half=(devices.dtype == torch.float16),
expected_architecture="SwinIR",
)
if getattr(shared.opts, 'SWIN_torch_compile', False):
try:
model_descriptor.model.compile()
except Exception:
logger.warning("Failed to compile SwinIR model, fallback to JIT", exc_info=True)
return model_descriptor
def upscale(
img,
model,
tile=None,
tile_overlap=None,
window_size=8,
scale=4,
):
tile = tile or opts.SWIN_tile
tile_overlap = tile_overlap or opts.SWIN_tile_overlap
img = np.array(img)
img = img[:, :, ::-1]
img = np.moveaxis(img, 2, 0) / 255
img = torch.from_numpy(img).float()
img = img.unsqueeze(0).to(device_swinir, dtype=devices.dtype)
with torch.no_grad(), devices.autocast():
_, _, h_old, w_old = img.size()
h_pad = (h_old // window_size + 1) * window_size - h_old
w_pad = (w_old // window_size + 1) * window_size - w_old
img = torch.cat([img, torch.flip(img, [2])], 2)[:, :, : h_old + h_pad, :]
img = torch.cat([img, torch.flip(img, [3])], 3)[:, :, :, : w_old + w_pad]
output = inference(img, model, tile, tile_overlap, window_size, scale)
output = output[..., : h_old * scale, : w_old * scale]
output = output.data.squeeze().float().cpu().clamp_(0, 1).numpy()
if output.ndim == 3:
output = np.transpose(
output[[2, 1, 0], :, :], (1, 2, 0)
) # CHW-RGB to HCW-BGR
output = (output * 255.0).round().astype(np.uint8) # float32 to uint8
return Image.fromarray(output, "RGB")
def inference(img, model, tile, tile_overlap, window_size, scale):
# test the image tile by tile
b, c, h, w = img.size()
tile = min(tile, h, w)
assert tile % window_size == 0, "tile size should be a multiple of window_size"
sf = scale
stride = tile - tile_overlap
h_idx_list = list(range(0, h - tile, stride)) + [h - tile]
w_idx_list = list(range(0, w - tile, stride)) + [w - tile]
E = torch.zeros(b, c, h * sf, w * sf, dtype=devices.dtype, device=device_swinir).type_as(img)
W = torch.zeros_like(E, dtype=devices.dtype, device=device_swinir)
with tqdm(total=len(h_idx_list) * len(w_idx_list), desc="SwinIR tiles") as pbar:
for h_idx in h_idx_list:
if state.interrupted or state.skipped:
break
for w_idx in w_idx_list:
if state.interrupted or state.skipped:
break
in_patch = img[..., h_idx: h_idx + tile, w_idx: w_idx + tile]
out_patch = model(in_patch)
out_patch_mask = torch.ones_like(out_patch)
E[
..., h_idx * sf: (h_idx + tile) * sf, w_idx * sf: (w_idx + tile) * sf
].add_(out_patch)
W[
..., h_idx * sf: (h_idx + tile) * sf, w_idx * sf: (w_idx + tile) * sf
].add_(out_patch_mask)
pbar.update(1)
output = E.div_(W)
return output
def _get_device(self):
return devices.get_device_for('swinir')
def on_ui_settings():
@ -185,8 +89,7 @@ def on_ui_settings():
shared.opts.add_option("SWIN_tile", shared.OptionInfo(192, "Tile size for all SwinIR.", gr.Slider, {"minimum": 16, "maximum": 512, "step": 16}, section=('upscaling', "Upscaling")))
shared.opts.add_option("SWIN_tile_overlap", shared.OptionInfo(8, "Tile overlap, in pixels for SwinIR. Low values = visible seam.", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}, section=('upscaling', "Upscaling")))
if int(torch.__version__.split('.')[0]) >= 2 and platform.system() != "Windows": # torch.compile() require pytorch 2.0 or above, and not on Windows
shared.opts.add_option("SWIN_torch_compile", shared.OptionInfo(False, "Use torch.compile to accelerate SwinIR.", gr.Checkbox, {"interactive": True}, section=('upscaling', "Upscaling")).info("Takes longer on first run"))
shared.opts.add_option("SWIN_torch_compile", shared.OptionInfo(False, "Use torch.compile to accelerate SwinIR.", gr.Checkbox, {"interactive": True}, section=('upscaling', "Upscaling")).info("Takes longer on first run"))
script_callbacks.on_ui_settings(on_ui_settings)

View File

@ -1,867 +0,0 @@
# -----------------------------------------------------------------------------------
# SwinIR: Image Restoration Using Swin Transformer, https://arxiv.org/abs/2108.10257
# Originally Written by Ze Liu, Modified by Jingyun Liang.
# -----------------------------------------------------------------------------------
import math
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.checkpoint as checkpoint
from timm.models.layers import DropPath, to_2tuple, trunc_normal_
class Mlp(nn.Module):
def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):
super().__init__()
out_features = out_features or in_features
hidden_features = hidden_features or in_features
self.fc1 = nn.Linear(in_features, hidden_features)
self.act = act_layer()
self.fc2 = nn.Linear(hidden_features, out_features)
self.drop = nn.Dropout(drop)
def forward(self, x):
x = self.fc1(x)
x = self.act(x)
x = self.drop(x)
x = self.fc2(x)
x = self.drop(x)
return x
def window_partition(x, window_size):
"""
Args:
x: (B, H, W, C)
window_size (int): window size
Returns:
windows: (num_windows*B, window_size, window_size, C)
"""
B, H, W, C = x.shape
x = x.view(B, H // window_size, window_size, W // window_size, window_size, C)
windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C)
return windows
def window_reverse(windows, window_size, H, W):
"""
Args:
windows: (num_windows*B, window_size, window_size, C)
window_size (int): Window size
H (int): Height of image
W (int): Width of image
Returns:
x: (B, H, W, C)
"""
B = int(windows.shape[0] / (H * W / window_size / window_size))
x = windows.view(B, H // window_size, W // window_size, window_size, window_size, -1)
x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1)
return x
class WindowAttention(nn.Module):
r""" Window based multi-head self attention (W-MSA) module with relative position bias.
It supports both of shifted and non-shifted window.
Args:
dim (int): Number of input channels.
window_size (tuple[int]): The height and width of the window.
num_heads (int): Number of attention heads.
qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set
attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0
proj_drop (float, optional): Dropout ratio of output. Default: 0.0
"""
def __init__(self, dim, window_size, num_heads, qkv_bias=True, qk_scale=None, attn_drop=0., proj_drop=0.):
super().__init__()
self.dim = dim
self.window_size = window_size # Wh, Ww
self.num_heads = num_heads
head_dim = dim // num_heads
self.scale = qk_scale or head_dim ** -0.5
# define a parameter table of relative position bias
self.relative_position_bias_table = nn.Parameter(
torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1), num_heads)) # 2*Wh-1 * 2*Ww-1, nH
# get pair-wise relative position index for each token inside the window
coords_h = torch.arange(self.window_size[0])
coords_w = torch.arange(self.window_size[1])
coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww
coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww
relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww
relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2
relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0
relative_coords[:, :, 1] += self.window_size[1] - 1
relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1
relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww
self.register_buffer("relative_position_index", relative_position_index)
self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
self.attn_drop = nn.Dropout(attn_drop)
self.proj = nn.Linear(dim, dim)
self.proj_drop = nn.Dropout(proj_drop)
trunc_normal_(self.relative_position_bias_table, std=.02)
self.softmax = nn.Softmax(dim=-1)
def forward(self, x, mask=None):
"""
Args:
x: input features with shape of (num_windows*B, N, C)
mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None
"""
B_, N, C = x.shape
qkv = self.qkv(x).reshape(B_, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple)
q = q * self.scale
attn = (q @ k.transpose(-2, -1))
relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view(
self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH
relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww
attn = attn + relative_position_bias.unsqueeze(0)
if mask is not None:
nW = mask.shape[0]
attn = attn.view(B_ // nW, nW, self.num_heads, N, N) + mask.unsqueeze(1).unsqueeze(0)
attn = attn.view(-1, self.num_heads, N, N)
attn = self.softmax(attn)
else:
attn = self.softmax(attn)
attn = self.attn_drop(attn)
x = (attn @ v).transpose(1, 2).reshape(B_, N, C)
x = self.proj(x)
x = self.proj_drop(x)
return x
def extra_repr(self) -> str:
return f'dim={self.dim}, window_size={self.window_size}, num_heads={self.num_heads}'
def flops(self, N):
# calculate flops for 1 window with token length of N
flops = 0
# qkv = self.qkv(x)
flops += N * self.dim * 3 * self.dim
# attn = (q @ k.transpose(-2, -1))
flops += self.num_heads * N * (self.dim // self.num_heads) * N
# x = (attn @ v)
flops += self.num_heads * N * N * (self.dim // self.num_heads)
# x = self.proj(x)
flops += N * self.dim * self.dim
return flops
class SwinTransformerBlock(nn.Module):
r""" Swin Transformer Block.
Args:
dim (int): Number of input channels.
input_resolution (tuple[int]): Input resolution.
num_heads (int): Number of attention heads.
window_size (int): Window size.
shift_size (int): Shift size for SW-MSA.
mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set.
drop (float, optional): Dropout rate. Default: 0.0
attn_drop (float, optional): Attention dropout rate. Default: 0.0
drop_path (float, optional): Stochastic depth rate. Default: 0.0
act_layer (nn.Module, optional): Activation layer. Default: nn.GELU
norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
"""
def __init__(self, dim, input_resolution, num_heads, window_size=7, shift_size=0,
mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., drop_path=0.,
act_layer=nn.GELU, norm_layer=nn.LayerNorm):
super().__init__()
self.dim = dim
self.input_resolution = input_resolution
self.num_heads = num_heads
self.window_size = window_size
self.shift_size = shift_size
self.mlp_ratio = mlp_ratio
if min(self.input_resolution) <= self.window_size:
# if window size is larger than input resolution, we don't partition windows
self.shift_size = 0
self.window_size = min(self.input_resolution)
assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size"
self.norm1 = norm_layer(dim)
self.attn = WindowAttention(
dim, window_size=to_2tuple(self.window_size), num_heads=num_heads,
qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
self.norm2 = norm_layer(dim)
mlp_hidden_dim = int(dim * mlp_ratio)
self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
if self.shift_size > 0:
attn_mask = self.calculate_mask(self.input_resolution)
else:
attn_mask = None
self.register_buffer("attn_mask", attn_mask)
def calculate_mask(self, x_size):
# calculate attention mask for SW-MSA
H, W = x_size
img_mask = torch.zeros((1, H, W, 1)) # 1 H W 1
h_slices = (slice(0, -self.window_size),
slice(-self.window_size, -self.shift_size),
slice(-self.shift_size, None))
w_slices = (slice(0, -self.window_size),
slice(-self.window_size, -self.shift_size),
slice(-self.shift_size, None))
cnt = 0
for h in h_slices:
for w in w_slices:
img_mask[:, h, w, :] = cnt
cnt += 1
mask_windows = window_partition(img_mask, self.window_size) # nW, window_size, window_size, 1
mask_windows = mask_windows.view(-1, self.window_size * self.window_size)
attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2)
attn_mask = attn_mask.masked_fill(attn_mask != 0, float(-100.0)).masked_fill(attn_mask == 0, float(0.0))
return attn_mask
def forward(self, x, x_size):
H, W = x_size
B, L, C = x.shape
# assert L == H * W, "input feature has wrong size"
shortcut = x
x = self.norm1(x)
x = x.view(B, H, W, C)
# cyclic shift
if self.shift_size > 0:
shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2))
else:
shifted_x = x
# partition windows
x_windows = window_partition(shifted_x, self.window_size) # nW*B, window_size, window_size, C
x_windows = x_windows.view(-1, self.window_size * self.window_size, C) # nW*B, window_size*window_size, C
# W-MSA/SW-MSA (to be compatible for testing on images whose shapes are the multiple of window size
if self.input_resolution == x_size:
attn_windows = self.attn(x_windows, mask=self.attn_mask) # nW*B, window_size*window_size, C
else:
attn_windows = self.attn(x_windows, mask=self.calculate_mask(x_size).to(x.device))
# merge windows
attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C)
shifted_x = window_reverse(attn_windows, self.window_size, H, W) # B H' W' C
# reverse cyclic shift
if self.shift_size > 0:
x = torch.roll(shifted_x, shifts=(self.shift_size, self.shift_size), dims=(1, 2))
else:
x = shifted_x
x = x.view(B, H * W, C)
# FFN
x = shortcut + self.drop_path(x)
x = x + self.drop_path(self.mlp(self.norm2(x)))
return x
def extra_repr(self) -> str:
return f"dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, " \
f"window_size={self.window_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}"
def flops(self):
flops = 0
H, W = self.input_resolution
# norm1
flops += self.dim * H * W
# W-MSA/SW-MSA
nW = H * W / self.window_size / self.window_size
flops += nW * self.attn.flops(self.window_size * self.window_size)
# mlp
flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio
# norm2
flops += self.dim * H * W
return flops
class PatchMerging(nn.Module):
r""" Patch Merging Layer.
Args:
input_resolution (tuple[int]): Resolution of input feature.
dim (int): Number of input channels.
norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
"""
def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm):
super().__init__()
self.input_resolution = input_resolution
self.dim = dim
self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False)
self.norm = norm_layer(4 * dim)
def forward(self, x):
"""
x: B, H*W, C
"""
H, W = self.input_resolution
B, L, C = x.shape
assert L == H * W, "input feature has wrong size"
assert H % 2 == 0 and W % 2 == 0, f"x size ({H}*{W}) are not even."
x = x.view(B, H, W, C)
x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C
x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C
x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C
x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C
x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C
x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C
x = self.norm(x)
x = self.reduction(x)
return x
def extra_repr(self) -> str:
return f"input_resolution={self.input_resolution}, dim={self.dim}"
def flops(self):
H, W = self.input_resolution
flops = H * W * self.dim
flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim
return flops
class BasicLayer(nn.Module):
""" A basic Swin Transformer layer for one stage.
Args:
dim (int): Number of input channels.
input_resolution (tuple[int]): Input resolution.
depth (int): Number of blocks.
num_heads (int): Number of attention heads.
window_size (int): Local window size.
mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set.
drop (float, optional): Dropout rate. Default: 0.0
attn_drop (float, optional): Attention dropout rate. Default: 0.0
drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0
norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None
use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False.
"""
def __init__(self, dim, input_resolution, depth, num_heads, window_size,
mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0.,
drop_path=0., norm_layer=nn.LayerNorm, downsample=None, use_checkpoint=False):
super().__init__()
self.dim = dim
self.input_resolution = input_resolution
self.depth = depth
self.use_checkpoint = use_checkpoint
# build blocks
self.blocks = nn.ModuleList([
SwinTransformerBlock(dim=dim, input_resolution=input_resolution,
num_heads=num_heads, window_size=window_size,
shift_size=0 if (i % 2 == 0) else window_size // 2,
mlp_ratio=mlp_ratio,
qkv_bias=qkv_bias, qk_scale=qk_scale,
drop=drop, attn_drop=attn_drop,
drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path,
norm_layer=norm_layer)
for i in range(depth)])
# patch merging layer
if downsample is not None:
self.downsample = downsample(input_resolution, dim=dim, norm_layer=norm_layer)
else:
self.downsample = None
def forward(self, x, x_size):
for blk in self.blocks:
if self.use_checkpoint:
x = checkpoint.checkpoint(blk, x, x_size)
else:
x = blk(x, x_size)
if self.downsample is not None:
x = self.downsample(x)
return x
def extra_repr(self) -> str:
return f"dim={self.dim}, input_resolution={self.input_resolution}, depth={self.depth}"
def flops(self):
flops = 0
for blk in self.blocks:
flops += blk.flops()
if self.downsample is not None:
flops += self.downsample.flops()
return flops
class RSTB(nn.Module):
"""Residual Swin Transformer Block (RSTB).
Args:
dim (int): Number of input channels.
input_resolution (tuple[int]): Input resolution.
depth (int): Number of blocks.
num_heads (int): Number of attention heads.
window_size (int): Local window size.
mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set.
drop (float, optional): Dropout rate. Default: 0.0
attn_drop (float, optional): Attention dropout rate. Default: 0.0
drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0
norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None
use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False.
img_size: Input image size.
patch_size: Patch size.
resi_connection: The convolutional block before residual connection.
"""
def __init__(self, dim, input_resolution, depth, num_heads, window_size,
mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0.,
drop_path=0., norm_layer=nn.LayerNorm, downsample=None, use_checkpoint=False,
img_size=224, patch_size=4, resi_connection='1conv'):
super(RSTB, self).__init__()
self.dim = dim
self.input_resolution = input_resolution
self.residual_group = BasicLayer(dim=dim,
input_resolution=input_resolution,
depth=depth,
num_heads=num_heads,
window_size=window_size,
mlp_ratio=mlp_ratio,
qkv_bias=qkv_bias, qk_scale=qk_scale,
drop=drop, attn_drop=attn_drop,
drop_path=drop_path,
norm_layer=norm_layer,
downsample=downsample,
use_checkpoint=use_checkpoint)
if resi_connection == '1conv':
self.conv = nn.Conv2d(dim, dim, 3, 1, 1)
elif resi_connection == '3conv':
# to save parameters and memory
self.conv = nn.Sequential(nn.Conv2d(dim, dim // 4, 3, 1, 1), nn.LeakyReLU(negative_slope=0.2, inplace=True),
nn.Conv2d(dim // 4, dim // 4, 1, 1, 0),
nn.LeakyReLU(negative_slope=0.2, inplace=True),
nn.Conv2d(dim // 4, dim, 3, 1, 1))
self.patch_embed = PatchEmbed(
img_size=img_size, patch_size=patch_size, in_chans=0, embed_dim=dim,
norm_layer=None)
self.patch_unembed = PatchUnEmbed(
img_size=img_size, patch_size=patch_size, in_chans=0, embed_dim=dim,
norm_layer=None)
def forward(self, x, x_size):
return self.patch_embed(self.conv(self.patch_unembed(self.residual_group(x, x_size), x_size))) + x
def flops(self):
flops = 0
flops += self.residual_group.flops()
H, W = self.input_resolution
flops += H * W * self.dim * self.dim * 9
flops += self.patch_embed.flops()
flops += self.patch_unembed.flops()
return flops
class PatchEmbed(nn.Module):
r""" Image to Patch Embedding
Args:
img_size (int): Image size. Default: 224.
patch_size (int): Patch token size. Default: 4.
in_chans (int): Number of input image channels. Default: 3.
embed_dim (int): Number of linear projection output channels. Default: 96.
norm_layer (nn.Module, optional): Normalization layer. Default: None
"""
def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None):
super().__init__()
img_size = to_2tuple(img_size)
patch_size = to_2tuple(patch_size)
patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]]
self.img_size = img_size
self.patch_size = patch_size
self.patches_resolution = patches_resolution
self.num_patches = patches_resolution[0] * patches_resolution[1]
self.in_chans = in_chans
self.embed_dim = embed_dim
if norm_layer is not None:
self.norm = norm_layer(embed_dim)
else:
self.norm = None
def forward(self, x):
x = x.flatten(2).transpose(1, 2) # B Ph*Pw C
if self.norm is not None:
x = self.norm(x)
return x
def flops(self):
flops = 0
H, W = self.img_size
if self.norm is not None:
flops += H * W * self.embed_dim
return flops
class PatchUnEmbed(nn.Module):
r""" Image to Patch Unembedding
Args:
img_size (int): Image size. Default: 224.
patch_size (int): Patch token size. Default: 4.
in_chans (int): Number of input image channels. Default: 3.
embed_dim (int): Number of linear projection output channels. Default: 96.
norm_layer (nn.Module, optional): Normalization layer. Default: None
"""
def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None):
super().__init__()
img_size = to_2tuple(img_size)
patch_size = to_2tuple(patch_size)
patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]]
self.img_size = img_size
self.patch_size = patch_size
self.patches_resolution = patches_resolution
self.num_patches = patches_resolution[0] * patches_resolution[1]
self.in_chans = in_chans
self.embed_dim = embed_dim
def forward(self, x, x_size):
B, HW, C = x.shape
x = x.transpose(1, 2).view(B, self.embed_dim, x_size[0], x_size[1]) # B Ph*Pw C
return x
def flops(self):
flops = 0
return flops
class Upsample(nn.Sequential):
"""Upsample module.
Args:
scale (int): Scale factor. Supported scales: 2^n and 3.
num_feat (int): Channel number of intermediate features.
"""
def __init__(self, scale, num_feat):
m = []
if (scale & (scale - 1)) == 0: # scale = 2^n
for _ in range(int(math.log(scale, 2))):
m.append(nn.Conv2d(num_feat, 4 * num_feat, 3, 1, 1))
m.append(nn.PixelShuffle(2))
elif scale == 3:
m.append(nn.Conv2d(num_feat, 9 * num_feat, 3, 1, 1))
m.append(nn.PixelShuffle(3))
else:
raise ValueError(f'scale {scale} is not supported. ' 'Supported scales: 2^n and 3.')
super(Upsample, self).__init__(*m)
class UpsampleOneStep(nn.Sequential):
"""UpsampleOneStep module (the difference with Upsample is that it always only has 1conv + 1pixelshuffle)
Used in lightweight SR to save parameters.
Args:
scale (int): Scale factor. Supported scales: 2^n and 3.
num_feat (int): Channel number of intermediate features.
"""
def __init__(self, scale, num_feat, num_out_ch, input_resolution=None):
self.num_feat = num_feat
self.input_resolution = input_resolution
m = []
m.append(nn.Conv2d(num_feat, (scale ** 2) * num_out_ch, 3, 1, 1))
m.append(nn.PixelShuffle(scale))
super(UpsampleOneStep, self).__init__(*m)
def flops(self):
H, W = self.input_resolution
flops = H * W * self.num_feat * 3 * 9
return flops
class SwinIR(nn.Module):
r""" SwinIR
A PyTorch impl of : `SwinIR: Image Restoration Using Swin Transformer`, based on Swin Transformer.
Args:
img_size (int | tuple(int)): Input image size. Default 64
patch_size (int | tuple(int)): Patch size. Default: 1
in_chans (int): Number of input image channels. Default: 3
embed_dim (int): Patch embedding dimension. Default: 96
depths (tuple(int)): Depth of each Swin Transformer layer.
num_heads (tuple(int)): Number of attention heads in different layers.
window_size (int): Window size. Default: 7
mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4
qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True
qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. Default: None
drop_rate (float): Dropout rate. Default: 0
attn_drop_rate (float): Attention dropout rate. Default: 0
drop_path_rate (float): Stochastic depth rate. Default: 0.1
norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm.
ape (bool): If True, add absolute position embedding to the patch embedding. Default: False
patch_norm (bool): If True, add normalization after patch embedding. Default: True
use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False
upscale: Upscale factor. 2/3/4/8 for image SR, 1 for denoising and compress artifact reduction
img_range: Image range. 1. or 255.
upsampler: The reconstruction reconstruction module. 'pixelshuffle'/'pixelshuffledirect'/'nearest+conv'/None
resi_connection: The convolutional block before residual connection. '1conv'/'3conv'
"""
def __init__(self, img_size=64, patch_size=1, in_chans=3,
embed_dim=96, depths=(6, 6, 6, 6), num_heads=(6, 6, 6, 6),
window_size=7, mlp_ratio=4., qkv_bias=True, qk_scale=None,
drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1,
norm_layer=nn.LayerNorm, ape=False, patch_norm=True,
use_checkpoint=False, upscale=2, img_range=1., upsampler='', resi_connection='1conv',
**kwargs):
super(SwinIR, self).__init__()
num_in_ch = in_chans
num_out_ch = in_chans
num_feat = 64
self.img_range = img_range
if in_chans == 3:
rgb_mean = (0.4488, 0.4371, 0.4040)
self.mean = torch.Tensor(rgb_mean).view(1, 3, 1, 1)
else:
self.mean = torch.zeros(1, 1, 1, 1)
self.upscale = upscale
self.upsampler = upsampler
self.window_size = window_size
#####################################################################################################
################################### 1, shallow feature extraction ###################################
self.conv_first = nn.Conv2d(num_in_ch, embed_dim, 3, 1, 1)
#####################################################################################################
################################### 2, deep feature extraction ######################################
self.num_layers = len(depths)
self.embed_dim = embed_dim
self.ape = ape
self.patch_norm = patch_norm
self.num_features = embed_dim
self.mlp_ratio = mlp_ratio
# split image into non-overlapping patches
self.patch_embed = PatchEmbed(
img_size=img_size, patch_size=patch_size, in_chans=embed_dim, embed_dim=embed_dim,
norm_layer=norm_layer if self.patch_norm else None)
num_patches = self.patch_embed.num_patches
patches_resolution = self.patch_embed.patches_resolution
self.patches_resolution = patches_resolution
# merge non-overlapping patches into image
self.patch_unembed = PatchUnEmbed(
img_size=img_size, patch_size=patch_size, in_chans=embed_dim, embed_dim=embed_dim,
norm_layer=norm_layer if self.patch_norm else None)
# absolute position embedding
if self.ape:
self.absolute_pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim))
trunc_normal_(self.absolute_pos_embed, std=.02)
self.pos_drop = nn.Dropout(p=drop_rate)
# stochastic depth
dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule
# build Residual Swin Transformer blocks (RSTB)
self.layers = nn.ModuleList()
for i_layer in range(self.num_layers):
layer = RSTB(dim=embed_dim,
input_resolution=(patches_resolution[0],
patches_resolution[1]),
depth=depths[i_layer],
num_heads=num_heads[i_layer],
window_size=window_size,
mlp_ratio=self.mlp_ratio,
qkv_bias=qkv_bias, qk_scale=qk_scale,
drop=drop_rate, attn_drop=attn_drop_rate,
drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], # no impact on SR results
norm_layer=norm_layer,
downsample=None,
use_checkpoint=use_checkpoint,
img_size=img_size,
patch_size=patch_size,
resi_connection=resi_connection
)
self.layers.append(layer)
self.norm = norm_layer(self.num_features)
# build the last conv layer in deep feature extraction
if resi_connection == '1conv':
self.conv_after_body = nn.Conv2d(embed_dim, embed_dim, 3, 1, 1)
elif resi_connection == '3conv':
# to save parameters and memory
self.conv_after_body = nn.Sequential(nn.Conv2d(embed_dim, embed_dim // 4, 3, 1, 1),
nn.LeakyReLU(negative_slope=0.2, inplace=True),
nn.Conv2d(embed_dim // 4, embed_dim // 4, 1, 1, 0),
nn.LeakyReLU(negative_slope=0.2, inplace=True),
nn.Conv2d(embed_dim // 4, embed_dim, 3, 1, 1))
#####################################################################################################
################################ 3, high quality image reconstruction ################################
if self.upsampler == 'pixelshuffle':
# for classical SR
self.conv_before_upsample = nn.Sequential(nn.Conv2d(embed_dim, num_feat, 3, 1, 1),
nn.LeakyReLU(inplace=True))
self.upsample = Upsample(upscale, num_feat)
self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
elif self.upsampler == 'pixelshuffledirect':
# for lightweight SR (to save parameters)
self.upsample = UpsampleOneStep(upscale, embed_dim, num_out_ch,
(patches_resolution[0], patches_resolution[1]))
elif self.upsampler == 'nearest+conv':
# for real-world SR (less artifacts)
self.conv_before_upsample = nn.Sequential(nn.Conv2d(embed_dim, num_feat, 3, 1, 1),
nn.LeakyReLU(inplace=True))
self.conv_up1 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
if self.upscale == 4:
self.conv_up2 = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
self.conv_hr = nn.Conv2d(num_feat, num_feat, 3, 1, 1)
self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
self.lrelu = nn.LeakyReLU(negative_slope=0.2, inplace=True)
else:
# for image denoising and JPEG compression artifact reduction
self.conv_last = nn.Conv2d(embed_dim, num_out_ch, 3, 1, 1)
self.apply(self._init_weights)
def _init_weights(self, m):
if isinstance(m, nn.Linear):
trunc_normal_(m.weight, std=.02)
if isinstance(m, nn.Linear) and m.bias is not None:
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.LayerNorm):
nn.init.constant_(m.bias, 0)
nn.init.constant_(m.weight, 1.0)
@torch.jit.ignore
def no_weight_decay(self):
return {'absolute_pos_embed'}
@torch.jit.ignore
def no_weight_decay_keywords(self):
return {'relative_position_bias_table'}
def check_image_size(self, x):
_, _, h, w = x.size()
mod_pad_h = (self.window_size - h % self.window_size) % self.window_size
mod_pad_w = (self.window_size - w % self.window_size) % self.window_size
x = F.pad(x, (0, mod_pad_w, 0, mod_pad_h), 'reflect')
return x
def forward_features(self, x):
x_size = (x.shape[2], x.shape[3])
x = self.patch_embed(x)
if self.ape:
x = x + self.absolute_pos_embed
x = self.pos_drop(x)
for layer in self.layers:
x = layer(x, x_size)
x = self.norm(x) # B L C
x = self.patch_unembed(x, x_size)
return x
def forward(self, x):
H, W = x.shape[2:]
x = self.check_image_size(x)
self.mean = self.mean.type_as(x)
x = (x - self.mean) * self.img_range
if self.upsampler == 'pixelshuffle':
# for classical SR
x = self.conv_first(x)
x = self.conv_after_body(self.forward_features(x)) + x
x = self.conv_before_upsample(x)
x = self.conv_last(self.upsample(x))
elif self.upsampler == 'pixelshuffledirect':
# for lightweight SR
x = self.conv_first(x)
x = self.conv_after_body(self.forward_features(x)) + x
x = self.upsample(x)
elif self.upsampler == 'nearest+conv':
# for real-world SR
x = self.conv_first(x)
x = self.conv_after_body(self.forward_features(x)) + x
x = self.conv_before_upsample(x)
x = self.lrelu(self.conv_up1(torch.nn.functional.interpolate(x, scale_factor=2, mode='nearest')))
if self.upscale == 4:
x = self.lrelu(self.conv_up2(torch.nn.functional.interpolate(x, scale_factor=2, mode='nearest')))
x = self.conv_last(self.lrelu(self.conv_hr(x)))
else:
# for image denoising and JPEG compression artifact reduction
x_first = self.conv_first(x)
res = self.conv_after_body(self.forward_features(x_first)) + x_first
x = x + self.conv_last(res)
x = x / self.img_range + self.mean
return x[:, :, :H*self.upscale, :W*self.upscale]
def flops(self):
flops = 0
H, W = self.patches_resolution
flops += H * W * 3 * self.embed_dim * 9
flops += self.patch_embed.flops()
for layer in self.layers:
flops += layer.flops()
flops += H * W * 3 * self.embed_dim * self.embed_dim
flops += self.upsample.flops()
return flops
if __name__ == '__main__':
upscale = 4
window_size = 8
height = (1024 // upscale // window_size + 1) * window_size
width = (720 // upscale // window_size + 1) * window_size
model = SwinIR(upscale=2, img_size=(height, width),
window_size=window_size, img_range=1., depths=[6, 6, 6, 6],
embed_dim=60, num_heads=[6, 6, 6, 6], mlp_ratio=2, upsampler='pixelshuffledirect')
print(model)
print(height, width, model.flops() / 1e9)
x = torch.randn((1, 3, height, width))
x = model(x)
print(x.shape)

File diff suppressed because it is too large Load Diff

View File

@ -12,9 +12,24 @@ onUiLoaded(async() => {
"Sketch": elementIDs.sketch
};
// Helper functions
// Get active tab
/**
* Waits for an element to be present in the DOM.
*/
const waitForElement = (id) => new Promise(resolve => {
const checkForElement = () => {
const element = document.querySelector(id);
if (element) return resolve(element);
setTimeout(checkForElement, 100);
};
checkForElement();
});
function getActiveTab(elements, all = false) {
if (!elements.img2imgTabs) return null;
const tabs = elements.img2imgTabs.querySelectorAll("button");
if (all) return tabs;
@ -29,12 +44,13 @@ onUiLoaded(async() => {
// Get tab ID
function getTabId(elements) {
const activeTab = getActiveTab(elements);
if (!activeTab) return null;
return tabNameToElementId[activeTab.innerText];
}
// Wait until opts loaded
async function waitForOpts() {
for (;;) {
for (; ;) {
if (window.opts && Object.keys(window.opts).length) {
return window.opts;
}
@ -42,6 +58,11 @@ onUiLoaded(async() => {
}
}
// Detect whether the element has a horizontal scroll bar
function hasHorizontalScrollbar(element) {
return element.scrollWidth > element.clientWidth;
}
// Function for defining the "Ctrl", "Shift" and "Alt" keys
function isModifierKey(event, key) {
switch (key) {
@ -199,14 +220,19 @@ onUiLoaded(async() => {
canvas_hotkey_fullscreen: "KeyS",
canvas_hotkey_move: "KeyF",
canvas_hotkey_overlap: "KeyO",
canvas_hotkey_shrink_brush: "KeyQ",
canvas_hotkey_grow_brush: "KeyW",
canvas_disabled_functions: [],
canvas_show_tooltip: true,
canvas_blur_prompt: false
canvas_auto_expand: true,
canvas_blur_prompt: false,
};
const functionMap = {
"Zoom": "canvas_hotkey_zoom",
"Adjust brush size": "canvas_hotkey_adjust",
"Hotkey shrink brush": "canvas_hotkey_shrink_brush",
"Hotkey enlarge brush": "canvas_hotkey_grow_brush",
"Moving canvas": "canvas_hotkey_move",
"Fullscreen": "canvas_hotkey_fullscreen",
"Reset Zoom": "canvas_hotkey_reset",
@ -228,6 +254,7 @@ onUiLoaded(async() => {
let isMoving = false;
let mouseX, mouseY;
let activeElement;
let interactedWithAltKey = false;
const elements = Object.fromEntries(
Object.keys(elementIDs).map(id => [
@ -249,11 +276,11 @@ onUiLoaded(async() => {
input?.addEventListener("input", () => restoreImgRedMask(elements));
}
function applyZoomAndPan(elemId) {
function applyZoomAndPan(elemId, isExtension = true) {
const targetElement = gradioApp().querySelector(elemId);
if (!targetElement) {
console.log("Element not found");
console.log("Element not found", elemId);
return;
}
@ -268,7 +295,7 @@ onUiLoaded(async() => {
// Create tooltip
function createTooltip() {
const toolTipElemnt =
const toolTipElement =
targetElement.querySelector(".image-container");
const tooltip = document.createElement("div");
tooltip.className = "canvas-tooltip";
@ -331,7 +358,7 @@ onUiLoaded(async() => {
tooltip.appendChild(tooltipContent);
// Add a hint element to the target element
toolTipElemnt.appendChild(tooltip);
toolTipElement.appendChild(tooltip);
}
//Show tool tip if setting enable
@ -341,9 +368,9 @@ onUiLoaded(async() => {
// In the course of research, it was found that the tag img is very harmful when zooming and creates white canvases. This hack allows you to almost never think about this problem, it has no effect on webui.
function fixCanvas() {
const activeTab = getActiveTab(elements).textContent.trim();
const activeTab = getActiveTab(elements)?.textContent.trim();
if (activeTab !== "img2img") {
if (activeTab && activeTab !== "img2img") {
const img = targetElement.querySelector(`${elemId} img`);
if (img && img.style.display !== "none") {
@ -361,6 +388,12 @@ onUiLoaded(async() => {
panY: 0
};
if (isExtension) {
targetElement.style.overflow = "hidden";
}
targetElement.isZoomed = false;
fixCanvas();
targetElement.style.transform = `scale(${elemData[elemId].zoomLevel}) translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px)`;
@ -371,8 +404,27 @@ onUiLoaded(async() => {
toggleOverlap("off");
fullScreenMode = false;
const closeBtn = targetElement.querySelector("button[aria-label='Remove Image']");
if (closeBtn) {
closeBtn.addEventListener("click", resetZoom);
}
if (canvas && isExtension) {
const parentElement = targetElement.closest('[id^="component-"]');
if (
canvas &&
parseFloat(canvas.style.width) > parentElement.offsetWidth &&
parseFloat(targetElement.style.width) > parentElement.offsetWidth
) {
fitToElement();
return;
}
}
if (
canvas &&
!isExtension &&
parseFloat(canvas.style.width) > 865 &&
parseFloat(targetElement.style.width) > 865
) {
@ -381,9 +433,6 @@ onUiLoaded(async() => {
}
targetElement.style.width = "";
if (canvas) {
targetElement.style.height = canvas.style.height;
}
}
// Toggle the zIndex of the target element between two values, allowing it to overlap or be overlapped by other elements
@ -439,7 +488,7 @@ onUiLoaded(async() => {
// Update the zoom level and pan position of the target element based on the values of the zoomLevel, panX and panY variables
function updateZoom(newZoomLevel, mouseX, mouseY) {
newZoomLevel = Math.max(0.5, Math.min(newZoomLevel, 15));
newZoomLevel = Math.max(0.1, Math.min(newZoomLevel, 15));
elemData[elemId].panX +=
mouseX - (mouseX * newZoomLevel) / elemData[elemId].zoomLevel;
@ -450,6 +499,10 @@ onUiLoaded(async() => {
targetElement.style.transform = `translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px) scale(${newZoomLevel})`;
toggleOverlap("on");
if (isExtension) {
targetElement.style.overflow = "visible";
}
return newZoomLevel;
}
@ -458,6 +511,10 @@ onUiLoaded(async() => {
if (isModifierKey(e, hotkeysConfig.canvas_hotkey_zoom)) {
e.preventDefault();
if (hotkeysConfig.canvas_hotkey_zoom === "Alt") {
interactedWithAltKey = true;
}
let zoomPosX, zoomPosY;
let delta = 0.2;
if (elemData[elemId].zoomLevel > 7) {
@ -472,10 +529,12 @@ onUiLoaded(async() => {
fullScreenMode = false;
elemData[elemId].zoomLevel = updateZoom(
elemData[elemId].zoomLevel +
(operation === "+" ? delta : -delta),
(operation === "+" ? delta : -delta),
zoomPosX - targetElement.getBoundingClientRect().left,
zoomPosY - targetElement.getBoundingClientRect().top
);
targetElement.isZoomed = true;
}
}
@ -489,10 +548,19 @@ onUiLoaded(async() => {
//Reset Zoom
targetElement.style.transform = `translate(${0}px, ${0}px) scale(${1})`;
let parentElement;
if (isExtension) {
parentElement = targetElement.closest('[id^="component-"]');
} else {
parentElement = targetElement.parentElement;
}
// Get element and screen dimensions
const elementWidth = targetElement.offsetWidth;
const elementHeight = targetElement.offsetHeight;
const parentElement = targetElement.parentElement;
const screenWidth = parentElement.clientWidth;
const screenHeight = parentElement.clientHeight;
@ -545,8 +613,12 @@ onUiLoaded(async() => {
if (!canvas) return;
if (canvas.offsetWidth > 862) {
targetElement.style.width = canvas.offsetWidth + "px";
if (canvas.offsetWidth > 862 || isExtension) {
targetElement.style.width = (canvas.offsetWidth + 2) + "px";
}
if (isExtension) {
targetElement.style.overflow = "visible";
}
if (fullScreenMode) {
@ -625,7 +697,9 @@ onUiLoaded(async() => {
const hotkeyActions = {
[hotkeysConfig.canvas_hotkey_reset]: resetZoom,
[hotkeysConfig.canvas_hotkey_overlap]: toggleOverlap,
[hotkeysConfig.canvas_hotkey_fullscreen]: fitToScreen
[hotkeysConfig.canvas_hotkey_fullscreen]: fitToScreen,
[hotkeysConfig.canvas_hotkey_shrink_brush]: () => adjustBrushSize(elemId, 10),
[hotkeysConfig.canvas_hotkey_grow_brush]: () => adjustBrushSize(elemId, -10)
};
const action = hotkeyActions[event.code];
@ -648,8 +722,48 @@ onUiLoaded(async() => {
mouseY = e.offsetY;
}
// Simulation of the function to put a long image into the screen.
// We detect if an image has a scroll bar or not, make a fullscreen to reveal the image, then reduce it to fit into the element.
// We hide the image and show it to the user when it is ready.
targetElement.isExpanded = false;
function autoExpand() {
const canvas = document.querySelector(`${elemId} canvas[key="interface"]`);
if (canvas) {
if (hasHorizontalScrollbar(targetElement) && targetElement.isExpanded === false) {
targetElement.style.visibility = "hidden";
setTimeout(() => {
fitToScreen();
resetZoom();
targetElement.style.visibility = "visible";
targetElement.isExpanded = true;
}, 10);
}
}
}
targetElement.addEventListener("mousemove", getMousePosition);
//observers
// Creating an observer with a callback function to handle DOM changes
const observer = new MutationObserver((mutationsList, observer) => {
for (let mutation of mutationsList) {
// If the style attribute of the canvas has changed, by observation it happens only when the picture changes
if (mutation.type === 'attributes' && mutation.attributeName === 'style' &&
mutation.target.tagName.toLowerCase() === 'canvas') {
targetElement.isExpanded = false;
setTimeout(resetZoom, 10);
}
}
});
// Apply auto expand if enabled
if (hotkeysConfig.canvas_auto_expand) {
targetElement.addEventListener("mousemove", autoExpand);
// Set up an observer to track attribute changes
observer.observe(targetElement, {attributes: true, childList: true, subtree: true});
}
// Handle events only inside the targetElement
let isKeyDownHandlerAttached = false;
@ -676,23 +790,29 @@ onUiLoaded(async() => {
targetElement.addEventListener("mouseleave", handleMouseLeave);
// Reset zoom when click on another tab
elements.img2imgTabs.addEventListener("click", resetZoom);
elements.img2imgTabs.addEventListener("click", () => {
// targetElement.style.width = "";
if (parseInt(targetElement.style.width) > 865) {
setTimeout(fitToElement, 0);
}
});
if (elements.img2imgTabs) {
elements.img2imgTabs.addEventListener("click", resetZoom);
elements.img2imgTabs.addEventListener("click", () => {
// targetElement.style.width = "";
if (parseInt(targetElement.style.width) > 865) {
setTimeout(fitToElement, 0);
}
});
}
targetElement.addEventListener("wheel", e => {
// change zoom level
const operation = e.deltaY > 0 ? "-" : "+";
const operation = (e.deltaY || -e.wheelDelta) > 0 ? "-" : "+";
changeZoomLevel(operation, e);
// Handle brush size adjustment with ctrl key pressed
if (isModifierKey(e, hotkeysConfig.canvas_hotkey_adjust)) {
e.preventDefault();
if (hotkeysConfig.canvas_hotkey_adjust === "Alt") {
interactedWithAltKey = true;
}
// Increase or decrease brush size based on scroll direction
adjustBrushSize(elemId, e.deltaY);
}
@ -732,6 +852,20 @@ onUiLoaded(async() => {
document.addEventListener("keydown", handleMoveKeyDown);
document.addEventListener("keyup", handleMoveKeyUp);
// Prevent firefox from opening main menu when alt is used as a hotkey for zoom or brush size
function handleAltKeyUp(e) {
if (e.key !== "Alt" || !interactedWithAltKey) {
return;
}
e.preventDefault();
interactedWithAltKey = false;
}
document.addEventListener("keyup", handleAltKeyUp);
// Detect zoom level and update the pan speed.
function updatePanPosition(movementX, movementY) {
let panSpeed = 2;
@ -754,6 +888,11 @@ onUiLoaded(async() => {
if (isMoving && elemId === activeElement) {
updatePanPosition(e.movementX, e.movementY);
targetElement.style.pointerEvents = "none";
if (isExtension) {
targetElement.style.overflow = "visible";
}
} else {
targetElement.style.pointerEvents = "auto";
}
@ -764,13 +903,93 @@ onUiLoaded(async() => {
isMoving = false;
};
// Checks for extension
function checkForOutBox() {
const parentElement = targetElement.closest('[id^="component-"]');
if (parentElement.offsetWidth < targetElement.offsetWidth && !targetElement.isExpanded) {
resetZoom();
targetElement.isExpanded = true;
}
if (parentElement.offsetWidth < targetElement.offsetWidth && elemData[elemId].zoomLevel == 1) {
resetZoom();
}
if (parentElement.offsetWidth < targetElement.offsetWidth && targetElement.offsetWidth * elemData[elemId].zoomLevel > parentElement.offsetWidth && elemData[elemId].zoomLevel < 1 && !targetElement.isZoomed) {
resetZoom();
}
}
if (isExtension) {
targetElement.addEventListener("mousemove", checkForOutBox);
}
window.addEventListener('resize', (e) => {
resetZoom();
if (isExtension) {
targetElement.isExpanded = false;
targetElement.isZoomed = false;
}
});
gradioApp().addEventListener("mousemove", handleMoveByKey);
}
applyZoomAndPan(elementIDs.sketch);
applyZoomAndPan(elementIDs.inpaint);
applyZoomAndPan(elementIDs.inpaintSketch);
applyZoomAndPan(elementIDs.sketch, false);
applyZoomAndPan(elementIDs.inpaint, false);
applyZoomAndPan(elementIDs.inpaintSketch, false);
// Make the function global so that other extensions can take advantage of this solution
window.applyZoomAndPan = applyZoomAndPan;
const applyZoomAndPanIntegration = async(id, elementIDs) => {
const mainEl = document.querySelector(id);
if (id.toLocaleLowerCase() === "none") {
for (const elementID of elementIDs) {
const el = await waitForElement(elementID);
if (!el) break;
applyZoomAndPan(elementID);
}
return;
}
if (!mainEl) return;
mainEl.addEventListener("click", async() => {
for (const elementID of elementIDs) {
const el = await waitForElement(elementID);
if (!el) break;
applyZoomAndPan(elementID);
}
}, {once: true});
};
window.applyZoomAndPan = applyZoomAndPan; // Only 1 elements, argument elementID, for example applyZoomAndPan("#txt2img_controlnet_ControlNet_input_image")
window.applyZoomAndPanIntegration = applyZoomAndPanIntegration; // for any extension
/*
The function `applyZoomAndPanIntegration` takes two arguments:
1. `id`: A string identifier for the element to which zoom and pan functionality will be applied on click.
If the `id` value is "none", the functionality will be applied to all elements specified in the second argument without a click event.
2. `elementIDs`: An array of string identifiers for elements. Zoom and pan functionality will be applied to each of these elements on click of the element specified by the first argument.
If "none" is specified in the first argument, the functionality will be applied to each of these elements without a click event.
Example usage:
applyZoomAndPanIntegration("#txt2img_controlnet", ["#txt2img_controlnet_ControlNet_input_image"]);
In this example, zoom and pan functionality will be applied to the element with the identifier "txt2img_controlnet_ControlNet_input_image" upon clicking the element with the identifier "txt2img_controlnet".
*/
// More examples
// Add integration with ControlNet txt2img One TAB
// applyZoomAndPanIntegration("#txt2img_controlnet", ["#txt2img_controlnet_ControlNet_input_image"]);
// Add integration with ControlNet txt2img Tabs
// applyZoomAndPanIntegration("#txt2img_controlnet",Array.from({ length: 10 }, (_, i) => `#txt2img_controlnet_ControlNet-${i}_input_image`));
// Add integration with Inpaint Anything
// applyZoomAndPanIntegration("None", ["#ia_sam_image", "#ia_sel_mask"]);
});

View File

@ -4,11 +4,14 @@ from modules import shared
shared.options_templates.update(shared.options_section(('canvas_hotkey', "Canvas Hotkeys"), {
"canvas_hotkey_zoom": shared.OptionInfo("Alt", "Zoom canvas", gr.Radio, {"choices": ["Shift","Ctrl", "Alt"]}).info("If you choose 'Shift' you cannot scroll horizontally, 'Alt' can cause a little trouble in firefox"),
"canvas_hotkey_adjust": shared.OptionInfo("Ctrl", "Adjust brush size", gr.Radio, {"choices": ["Shift","Ctrl", "Alt"]}).info("If you choose 'Shift' you cannot scroll horizontally, 'Alt' can cause a little trouble in firefox"),
"canvas_hotkey_shrink_brush": shared.OptionInfo("Q", "Shrink the brush size"),
"canvas_hotkey_grow_brush": shared.OptionInfo("W", "Enlarge the brush size"),
"canvas_hotkey_move": shared.OptionInfo("F", "Moving the canvas").info("To work correctly in firefox, turn off 'Automatically search the page text when typing' in the browser settings"),
"canvas_hotkey_fullscreen": shared.OptionInfo("S", "Fullscreen Mode, maximizes the picture so that it fits into the screen and stretches it to its full width "),
"canvas_hotkey_reset": shared.OptionInfo("R", "Reset zoom and canvas positon"),
"canvas_hotkey_overlap": shared.OptionInfo("O", "Toggle overlap").info("Technical button, neededs for testing"),
"canvas_hotkey_reset": shared.OptionInfo("R", "Reset zoom and canvas position"),
"canvas_hotkey_overlap": shared.OptionInfo("O", "Toggle overlap").info("Technical button, needed for testing"),
"canvas_show_tooltip": shared.OptionInfo(True, "Enable tooltip on the canvas"),
"canvas_auto_expand": shared.OptionInfo(True, "Automatically expands an image that does not fit completely in the canvas area, similar to manually pressing the S and R buttons"),
"canvas_blur_prompt": shared.OptionInfo(False, "Take the focus off the prompt when working with a canvas"),
"canvas_disabled_functions": shared.OptionInfo(["Overlap"], "Disable function that you don't use", gr.CheckboxGroup, {"choices": ["Zoom","Adjust brush size", "Moving canvas","Fullscreen","Reset Zoom","Overlap"]}),
"canvas_disabled_functions": shared.OptionInfo(["Overlap"], "Disable function that you don't use", gr.CheckboxGroup, {"choices": ["Zoom","Adjust brush size","Hotkey enlarge brush","Hotkey shrink brush","Moving canvas","Fullscreen","Reset Zoom","Overlap"]}),
}))

View File

@ -61,3 +61,6 @@
to {opacity: 1;}
}
.styler {
overflow:inherit !important;
}

View File

@ -1,5 +1,7 @@
import math
import gradio as gr
from modules import scripts, shared, ui_components, ui_settings
from modules import scripts, shared, ui_components, ui_settings, infotext_utils, errors
from modules.ui_components import FormColumn
@ -19,18 +21,43 @@ class ExtraOptionsSection(scripts.Script):
def ui(self, is_img2img):
self.comps = []
self.setting_names = []
self.infotext_fields = []
extra_options = shared.opts.extra_options_img2img if is_img2img else shared.opts.extra_options_txt2img
elem_id_tabname = "extra_options_" + ("img2img" if is_img2img else "txt2img")
mapping = {k: v for v, k in infotext_utils.infotext_to_setting_name_mapping}
with gr.Blocks() as interface:
with gr.Accordion("Options", open=False) if shared.opts.extra_options_accordion and shared.opts.extra_options else gr.Group(), gr.Row():
for setting_name in shared.opts.extra_options:
with FormColumn():
comp = ui_settings.create_setting_component(setting_name)
with gr.Accordion("Options", open=False, elem_id=elem_id_tabname) if shared.opts.extra_options_accordion and extra_options else gr.Group(elem_id=elem_id_tabname):
self.comps.append(comp)
self.setting_names.append(setting_name)
row_count = math.ceil(len(extra_options) / shared.opts.extra_options_cols)
for row in range(row_count):
with gr.Row():
for col in range(shared.opts.extra_options_cols):
index = row * shared.opts.extra_options_cols + col
if index >= len(extra_options):
break
setting_name = extra_options[index]
with FormColumn():
try:
comp = ui_settings.create_setting_component(setting_name)
except KeyError:
errors.report(f"Can't add extra options for {setting_name} in ui")
continue
self.comps.append(comp)
self.setting_names.append(setting_name)
setting_infotext_name = mapping.get(setting_name)
if setting_infotext_name is not None:
self.infotext_fields.append((comp, setting_infotext_name))
def get_settings_values():
return [ui_settings.get_value_for_setting(key) for key in self.setting_names]
res = [ui_settings.get_value_for_setting(key) for key in self.setting_names]
return res[0] if len(res) == 1 else res
interface.load(fn=get_settings_values, inputs=[], outputs=self.comps, queue=False, show_progress=False)
@ -42,7 +69,14 @@ class ExtraOptionsSection(scripts.Script):
p.override_settings[name] = value
shared.options_templates.update(shared.options_section(('ui', "User interface"), {
"extra_options": shared.OptionInfo([], "Options in main UI", ui_components.DropdownMulti, lambda: {"choices": list(shared.opts.data_labels.keys())}).js("info", "settingsHintsShowQuicksettings").info("setting entries that also appear in txt2img/img2img interfaces").needs_restart(),
"extra_options_accordion": shared.OptionInfo(False, "Place options in main UI into an accordion")
shared.options_templates.update(shared.options_section(('settings_in_ui', "Settings in UI", "ui"), {
"settings_in_ui": shared.OptionHTML("""
This page allows you to add some settings to the main interface of txt2img and img2img tabs.
"""),
"extra_options_txt2img": shared.OptionInfo([], "Settings for txt2img", ui_components.DropdownMulti, lambda: {"choices": list(shared.opts.data_labels.keys())}).js("info", "settingsHintsShowQuicksettings").info("setting entries that also appear in txt2img interfaces").needs_reload_ui(),
"extra_options_img2img": shared.OptionInfo([], "Settings for img2img", ui_components.DropdownMulti, lambda: {"choices": list(shared.opts.data_labels.keys())}).js("info", "settingsHintsShowQuicksettings").info("setting entries that also appear in img2img interfaces").needs_reload_ui(),
"extra_options_cols": shared.OptionInfo(1, "Number of columns for added settings", gr.Slider, {"step": 1, "minimum": 1, "maximum": 20}).info("displayed amount will depend on the actual browser window width").needs_reload_ui(),
"extra_options_accordion": shared.OptionInfo(False, "Place added settings into an accordion").needs_reload_ui()
}))

View File

@ -0,0 +1,351 @@
"""
Hypertile module for splitting attention layers in SD-1.5 U-Net and SD-1.5 VAE
Warn: The patch works well only if the input image has a width and height that are multiples of 128
Original author: @tfernd Github: https://github.com/tfernd/HyperTile
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Callable
from functools import wraps, cache
import math
import torch.nn as nn
import random
from einops import rearrange
@dataclass
class HypertileParams:
depth = 0
layer_name = ""
tile_size: int = 0
swap_size: int = 0
aspect_ratio: float = 1.0
forward = None
enabled = False
# TODO add SD-XL layers
DEPTH_LAYERS = {
0: [
# SD 1.5 U-Net (diffusers)
"down_blocks.0.attentions.0.transformer_blocks.0.attn1",
"down_blocks.0.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.0.transformer_blocks.0.attn1",
"up_blocks.3.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.1.1.transformer_blocks.0.attn1",
"input_blocks.2.1.transformer_blocks.0.attn1",
"output_blocks.9.1.transformer_blocks.0.attn1",
"output_blocks.10.1.transformer_blocks.0.attn1",
"output_blocks.11.1.transformer_blocks.0.attn1",
# SD 1.5 VAE
"decoder.mid_block.attentions.0",
"decoder.mid.attn_1",
],
1: [
# SD 1.5 U-Net (diffusers)
"down_blocks.1.attentions.0.transformer_blocks.0.attn1",
"down_blocks.1.attentions.1.transformer_blocks.0.attn1",
"up_blocks.2.attentions.0.transformer_blocks.0.attn1",
"up_blocks.2.attentions.1.transformer_blocks.0.attn1",
"up_blocks.2.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.4.1.transformer_blocks.0.attn1",
"input_blocks.5.1.transformer_blocks.0.attn1",
"output_blocks.6.1.transformer_blocks.0.attn1",
"output_blocks.7.1.transformer_blocks.0.attn1",
"output_blocks.8.1.transformer_blocks.0.attn1",
],
2: [
# SD 1.5 U-Net (diffusers)
"down_blocks.2.attentions.0.transformer_blocks.0.attn1",
"down_blocks.2.attentions.1.transformer_blocks.0.attn1",
"up_blocks.1.attentions.0.transformer_blocks.0.attn1",
"up_blocks.1.attentions.1.transformer_blocks.0.attn1",
"up_blocks.1.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.7.1.transformer_blocks.0.attn1",
"input_blocks.8.1.transformer_blocks.0.attn1",
"output_blocks.3.1.transformer_blocks.0.attn1",
"output_blocks.4.1.transformer_blocks.0.attn1",
"output_blocks.5.1.transformer_blocks.0.attn1",
],
3: [
# SD 1.5 U-Net (diffusers)
"mid_block.attentions.0.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"middle_block.1.transformer_blocks.0.attn1",
],
}
# XL layers, thanks for GitHub@gel-crabs for the help
DEPTH_LAYERS_XL = {
0: [
# SD 1.5 U-Net (diffusers)
"down_blocks.0.attentions.0.transformer_blocks.0.attn1",
"down_blocks.0.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.0.transformer_blocks.0.attn1",
"up_blocks.3.attentions.1.transformer_blocks.0.attn1",
"up_blocks.3.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.4.1.transformer_blocks.0.attn1",
"input_blocks.5.1.transformer_blocks.0.attn1",
"output_blocks.3.1.transformer_blocks.0.attn1",
"output_blocks.4.1.transformer_blocks.0.attn1",
"output_blocks.5.1.transformer_blocks.0.attn1",
# SD 1.5 VAE
"decoder.mid_block.attentions.0",
"decoder.mid.attn_1",
],
1: [
# SD 1.5 U-Net (diffusers)
#"down_blocks.1.attentions.0.transformer_blocks.0.attn1",
#"down_blocks.1.attentions.1.transformer_blocks.0.attn1",
#"up_blocks.2.attentions.0.transformer_blocks.0.attn1",
#"up_blocks.2.attentions.1.transformer_blocks.0.attn1",
#"up_blocks.2.attentions.2.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"input_blocks.4.1.transformer_blocks.1.attn1",
"input_blocks.5.1.transformer_blocks.1.attn1",
"output_blocks.3.1.transformer_blocks.1.attn1",
"output_blocks.4.1.transformer_blocks.1.attn1",
"output_blocks.5.1.transformer_blocks.1.attn1",
"input_blocks.7.1.transformer_blocks.0.attn1",
"input_blocks.8.1.transformer_blocks.0.attn1",
"output_blocks.0.1.transformer_blocks.0.attn1",
"output_blocks.1.1.transformer_blocks.0.attn1",
"output_blocks.2.1.transformer_blocks.0.attn1",
"input_blocks.7.1.transformer_blocks.1.attn1",
"input_blocks.8.1.transformer_blocks.1.attn1",
"output_blocks.0.1.transformer_blocks.1.attn1",
"output_blocks.1.1.transformer_blocks.1.attn1",
"output_blocks.2.1.transformer_blocks.1.attn1",
"input_blocks.7.1.transformer_blocks.2.attn1",
"input_blocks.8.1.transformer_blocks.2.attn1",
"output_blocks.0.1.transformer_blocks.2.attn1",
"output_blocks.1.1.transformer_blocks.2.attn1",
"output_blocks.2.1.transformer_blocks.2.attn1",
"input_blocks.7.1.transformer_blocks.3.attn1",
"input_blocks.8.1.transformer_blocks.3.attn1",
"output_blocks.0.1.transformer_blocks.3.attn1",
"output_blocks.1.1.transformer_blocks.3.attn1",
"output_blocks.2.1.transformer_blocks.3.attn1",
"input_blocks.7.1.transformer_blocks.4.attn1",
"input_blocks.8.1.transformer_blocks.4.attn1",
"output_blocks.0.1.transformer_blocks.4.attn1",
"output_blocks.1.1.transformer_blocks.4.attn1",
"output_blocks.2.1.transformer_blocks.4.attn1",
"input_blocks.7.1.transformer_blocks.5.attn1",
"input_blocks.8.1.transformer_blocks.5.attn1",
"output_blocks.0.1.transformer_blocks.5.attn1",
"output_blocks.1.1.transformer_blocks.5.attn1",
"output_blocks.2.1.transformer_blocks.5.attn1",
"input_blocks.7.1.transformer_blocks.6.attn1",
"input_blocks.8.1.transformer_blocks.6.attn1",
"output_blocks.0.1.transformer_blocks.6.attn1",
"output_blocks.1.1.transformer_blocks.6.attn1",
"output_blocks.2.1.transformer_blocks.6.attn1",
"input_blocks.7.1.transformer_blocks.7.attn1",
"input_blocks.8.1.transformer_blocks.7.attn1",
"output_blocks.0.1.transformer_blocks.7.attn1",
"output_blocks.1.1.transformer_blocks.7.attn1",
"output_blocks.2.1.transformer_blocks.7.attn1",
"input_blocks.7.1.transformer_blocks.8.attn1",
"input_blocks.8.1.transformer_blocks.8.attn1",
"output_blocks.0.1.transformer_blocks.8.attn1",
"output_blocks.1.1.transformer_blocks.8.attn1",
"output_blocks.2.1.transformer_blocks.8.attn1",
"input_blocks.7.1.transformer_blocks.9.attn1",
"input_blocks.8.1.transformer_blocks.9.attn1",
"output_blocks.0.1.transformer_blocks.9.attn1",
"output_blocks.1.1.transformer_blocks.9.attn1",
"output_blocks.2.1.transformer_blocks.9.attn1",
],
2: [
# SD 1.5 U-Net (diffusers)
"mid_block.attentions.0.transformer_blocks.0.attn1",
# SD 1.5 U-Net (ldm)
"middle_block.1.transformer_blocks.0.attn1",
"middle_block.1.transformer_blocks.1.attn1",
"middle_block.1.transformer_blocks.2.attn1",
"middle_block.1.transformer_blocks.3.attn1",
"middle_block.1.transformer_blocks.4.attn1",
"middle_block.1.transformer_blocks.5.attn1",
"middle_block.1.transformer_blocks.6.attn1",
"middle_block.1.transformer_blocks.7.attn1",
"middle_block.1.transformer_blocks.8.attn1",
"middle_block.1.transformer_blocks.9.attn1",
],
3 : [] # TODO - separate layers for SD-XL
}
RNG_INSTANCE = random.Random()
@cache
def get_divisors(value: int, min_value: int, /, max_options: int = 1) -> list[int]:
"""
Returns divisors of value that
x * min_value <= value
in big -> small order, amount of divisors is limited by max_options
"""
max_options = max(1, max_options) # at least 1 option should be returned
min_value = min(min_value, value)
divisors = [i for i in range(min_value, value + 1) if value % i == 0] # divisors in small -> big order
ns = [value // i for i in divisors[:max_options]] # has at least 1 element # big -> small order
return ns
def random_divisor(value: int, min_value: int, /, max_options: int = 1) -> int:
"""
Returns a random divisor of value that
x * min_value <= value
if max_options is 1, the behavior is deterministic
"""
ns = get_divisors(value, min_value, max_options=max_options) # get cached divisors
idx = RNG_INSTANCE.randint(0, len(ns) - 1)
return ns[idx]
def set_hypertile_seed(seed: int) -> None:
RNG_INSTANCE.seed(seed)
@cache
def largest_tile_size_available(width: int, height: int) -> int:
"""
Calculates the largest tile size available for a given width and height
Tile size is always a power of 2
"""
gcd = math.gcd(width, height)
largest_tile_size_available = 1
while gcd % (largest_tile_size_available * 2) == 0:
largest_tile_size_available *= 2
return largest_tile_size_available
def iterative_closest_divisors(hw:int, aspect_ratio:float) -> tuple[int, int]:
"""
Finds h and w such that h*w = hw and h/w = aspect_ratio
We check all possible divisors of hw and return the closest to the aspect ratio
"""
divisors = [i for i in range(2, hw + 1) if hw % i == 0] # all divisors of hw
pairs = [(i, hw // i) for i in divisors] # all pairs of divisors of hw
ratios = [w/h for h, w in pairs] # all ratios of pairs of divisors of hw
closest_ratio = min(ratios, key=lambda x: abs(x - aspect_ratio)) # closest ratio to aspect_ratio
closest_pair = pairs[ratios.index(closest_ratio)] # closest pair of divisors to aspect_ratio
return closest_pair
@cache
def find_hw_candidates(hw:int, aspect_ratio:float) -> tuple[int, int]:
"""
Finds h and w such that h*w = hw and h/w = aspect_ratio
"""
h, w = round(math.sqrt(hw * aspect_ratio)), round(math.sqrt(hw / aspect_ratio))
# find h and w such that h*w = hw and h/w = aspect_ratio
if h * w != hw:
w_candidate = hw / h
# check if w is an integer
if not w_candidate.is_integer():
h_candidate = hw / w
# check if h is an integer
if not h_candidate.is_integer():
return iterative_closest_divisors(hw, aspect_ratio)
else:
h = int(h_candidate)
else:
w = int(w_candidate)
return h, w
def self_attn_forward(params: HypertileParams, scale_depth=True) -> Callable:
@wraps(params.forward)
def wrapper(*args, **kwargs):
if not params.enabled:
return params.forward(*args, **kwargs)
latent_tile_size = max(128, params.tile_size) // 8
x = args[0]
# VAE
if x.ndim == 4:
b, c, h, w = x.shape
nh = random_divisor(h, latent_tile_size, params.swap_size)
nw = random_divisor(w, latent_tile_size, params.swap_size)
if nh * nw > 1:
x = rearrange(x, "b c (nh h) (nw w) -> (b nh nw) c h w", nh=nh, nw=nw) # split into nh * nw tiles
out = params.forward(x, *args[1:], **kwargs)
if nh * nw > 1:
out = rearrange(out, "(b nh nw) c h w -> b c (nh h) (nw w)", nh=nh, nw=nw)
# U-Net
else:
hw: int = x.size(1)
h, w = find_hw_candidates(hw, params.aspect_ratio)
assert h * w == hw, f"Invalid aspect ratio {params.aspect_ratio} for input of shape {x.shape}, hw={hw}, h={h}, w={w}"
factor = 2 ** params.depth if scale_depth else 1
nh = random_divisor(h, latent_tile_size * factor, params.swap_size)
nw = random_divisor(w, latent_tile_size * factor, params.swap_size)
if nh * nw > 1:
x = rearrange(x, "b (nh h nw w) c -> (b nh nw) (h w) c", h=h // nh, w=w // nw, nh=nh, nw=nw)
out = params.forward(x, *args[1:], **kwargs)
if nh * nw > 1:
out = rearrange(out, "(b nh nw) hw c -> b nh nw hw c", nh=nh, nw=nw)
out = rearrange(out, "b nh nw (h w) c -> b (nh h nw w) c", h=h // nh, w=w // nw)
return out
return wrapper
def hypertile_hook_model(model: nn.Module, width, height, *, enable=False, tile_size_max=128, swap_size=1, max_depth=3, is_sdxl=False):
hypertile_layers = getattr(model, "__webui_hypertile_layers", None)
if hypertile_layers is None:
if not enable:
return
hypertile_layers = {}
layers = DEPTH_LAYERS_XL if is_sdxl else DEPTH_LAYERS
for depth in range(4):
for layer_name, module in model.named_modules():
if any(layer_name.endswith(try_name) for try_name in layers[depth]):
params = HypertileParams()
module.__webui_hypertile_params = params
params.forward = module.forward
params.depth = depth
params.layer_name = layer_name
module.forward = self_attn_forward(params)
hypertile_layers[layer_name] = 1
model.__webui_hypertile_layers = hypertile_layers
aspect_ratio = width / height
tile_size = min(largest_tile_size_available(width, height), tile_size_max)
for layer_name, module in model.named_modules():
if layer_name in hypertile_layers:
params = module.__webui_hypertile_params
params.tile_size = tile_size
params.swap_size = swap_size
params.aspect_ratio = aspect_ratio
params.enabled = enable and params.depth <= max_depth

View File

@ -0,0 +1,122 @@
import hypertile
from modules import scripts, script_callbacks, shared
class ScriptHypertile(scripts.Script):
name = "Hypertile"
def title(self):
return self.name
def show(self, is_img2img):
return scripts.AlwaysVisible
def process(self, p, *args):
hypertile.set_hypertile_seed(p.all_seeds[0])
configure_hypertile(p.width, p.height, enable_unet=shared.opts.hypertile_enable_unet)
self.add_infotext(p)
def before_hr(self, p, *args):
enable = shared.opts.hypertile_enable_unet_secondpass or shared.opts.hypertile_enable_unet
# exclusive hypertile seed for the second pass
if enable:
hypertile.set_hypertile_seed(p.all_seeds[0])
configure_hypertile(p.hr_upscale_to_x, p.hr_upscale_to_y, enable_unet=enable)
if enable and not shared.opts.hypertile_enable_unet:
p.extra_generation_params["Hypertile U-Net second pass"] = True
self.add_infotext(p, add_unet_params=True)
def add_infotext(self, p, add_unet_params=False):
def option(name):
value = getattr(shared.opts, name)
default_value = shared.opts.get_default(name)
return None if value == default_value else value
if shared.opts.hypertile_enable_unet:
p.extra_generation_params["Hypertile U-Net"] = True
if shared.opts.hypertile_enable_unet or add_unet_params:
p.extra_generation_params["Hypertile U-Net max depth"] = option('hypertile_max_depth_unet')
p.extra_generation_params["Hypertile U-Net max tile size"] = option('hypertile_max_tile_unet')
p.extra_generation_params["Hypertile U-Net swap size"] = option('hypertile_swap_size_unet')
if shared.opts.hypertile_enable_vae:
p.extra_generation_params["Hypertile VAE"] = True
p.extra_generation_params["Hypertile VAE max depth"] = option('hypertile_max_depth_vae')
p.extra_generation_params["Hypertile VAE max tile size"] = option('hypertile_max_tile_vae')
p.extra_generation_params["Hypertile VAE swap size"] = option('hypertile_swap_size_vae')
def configure_hypertile(width, height, enable_unet=True):
hypertile.hypertile_hook_model(
shared.sd_model.first_stage_model,
width,
height,
swap_size=shared.opts.hypertile_swap_size_vae,
max_depth=shared.opts.hypertile_max_depth_vae,
tile_size_max=shared.opts.hypertile_max_tile_vae,
enable=shared.opts.hypertile_enable_vae,
)
hypertile.hypertile_hook_model(
shared.sd_model.model,
width,
height,
swap_size=shared.opts.hypertile_swap_size_unet,
max_depth=shared.opts.hypertile_max_depth_unet,
tile_size_max=shared.opts.hypertile_max_tile_unet,
enable=enable_unet,
is_sdxl=shared.sd_model.is_sdxl
)
def on_ui_settings():
import gradio as gr
options = {
"hypertile_explanation": shared.OptionHTML("""
<a href='https://github.com/tfernd/HyperTile'>Hypertile</a> optimizes the self-attention layer within U-Net and VAE models,
resulting in a reduction in computation time ranging from 1 to 4 times. The larger the generated image is, the greater the
benefit.
"""),
"hypertile_enable_unet": shared.OptionInfo(False, "Enable Hypertile U-Net", infotext="Hypertile U-Net").info("enables hypertile for all modes, including hires fix second pass; noticeable change in details of the generated picture"),
"hypertile_enable_unet_secondpass": shared.OptionInfo(False, "Enable Hypertile U-Net for hires fix second pass", infotext="Hypertile U-Net second pass").info("enables hypertile just for hires fix second pass - regardless of whether the above setting is enabled"),
"hypertile_max_depth_unet": shared.OptionInfo(3, "Hypertile U-Net max depth", gr.Slider, {"minimum": 0, "maximum": 3, "step": 1}, infotext="Hypertile U-Net max depth").info("larger = more neural network layers affected; minor effect on performance"),
"hypertile_max_tile_unet": shared.OptionInfo(256, "Hypertile U-Net max tile size", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}, infotext="Hypertile U-Net max tile size").info("larger = worse performance"),
"hypertile_swap_size_unet": shared.OptionInfo(3, "Hypertile U-Net swap size", gr.Slider, {"minimum": 0, "maximum": 64, "step": 1}, infotext="Hypertile U-Net swap size"),
"hypertile_enable_vae": shared.OptionInfo(False, "Enable Hypertile VAE", infotext="Hypertile VAE").info("minimal change in the generated picture"),
"hypertile_max_depth_vae": shared.OptionInfo(3, "Hypertile VAE max depth", gr.Slider, {"minimum": 0, "maximum": 3, "step": 1}, infotext="Hypertile VAE max depth"),
"hypertile_max_tile_vae": shared.OptionInfo(128, "Hypertile VAE max tile size", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}, infotext="Hypertile VAE max tile size"),
"hypertile_swap_size_vae": shared.OptionInfo(3, "Hypertile VAE swap size ", gr.Slider, {"minimum": 0, "maximum": 64, "step": 1}, infotext="Hypertile VAE swap size"),
}
for name, opt in options.items():
opt.section = ('hypertile', "Hypertile")
shared.opts.add_option(name, opt)
def add_axis_options():
xyz_grid = [x for x in scripts.scripts_data if x.script_class.__module__ == "xyz_grid.py"][0].module
xyz_grid.axis_options.extend([
xyz_grid.AxisOption("[Hypertile] Unet First pass Enabled", str, xyz_grid.apply_override('hypertile_enable_unet', boolean=True), choices=xyz_grid.boolean_choice(reverse=True)),
xyz_grid.AxisOption("[Hypertile] Unet Second pass Enabled", str, xyz_grid.apply_override('hypertile_enable_unet_secondpass', boolean=True), choices=xyz_grid.boolean_choice(reverse=True)),
xyz_grid.AxisOption("[Hypertile] Unet Max Depth", int, xyz_grid.apply_override("hypertile_max_depth_unet"), confirm=xyz_grid.confirm_range(0, 3, '[Hypertile] Unet Max Depth'), choices=lambda: [str(x) for x in range(4)]),
xyz_grid.AxisOption("[Hypertile] Unet Max Tile Size", int, xyz_grid.apply_override("hypertile_max_tile_unet"), confirm=xyz_grid.confirm_range(0, 512, '[Hypertile] Unet Max Tile Size')),
xyz_grid.AxisOption("[Hypertile] Unet Swap Size", int, xyz_grid.apply_override("hypertile_swap_size_unet"), confirm=xyz_grid.confirm_range(0, 64, '[Hypertile] Unet Swap Size')),
xyz_grid.AxisOption("[Hypertile] VAE Enabled", str, xyz_grid.apply_override('hypertile_enable_vae', boolean=True), choices=xyz_grid.boolean_choice(reverse=True)),
xyz_grid.AxisOption("[Hypertile] VAE Max Depth", int, xyz_grid.apply_override("hypertile_max_depth_vae"), confirm=xyz_grid.confirm_range(0, 3, '[Hypertile] VAE Max Depth'), choices=lambda: [str(x) for x in range(4)]),
xyz_grid.AxisOption("[Hypertile] VAE Max Tile Size", int, xyz_grid.apply_override("hypertile_max_tile_vae"), confirm=xyz_grid.confirm_range(0, 512, '[Hypertile] VAE Max Tile Size')),
xyz_grid.AxisOption("[Hypertile] VAE Swap Size", int, xyz_grid.apply_override("hypertile_swap_size_vae"), confirm=xyz_grid.confirm_range(0, 64, '[Hypertile] VAE Swap Size')),
])
script_callbacks.on_ui_settings(on_ui_settings)
script_callbacks.on_before_ui(add_axis_options)

View File

@ -12,6 +12,8 @@ function isMobile() {
}
function reportWindowSize() {
if (gradioApp().querySelector('.toprow-compact-tools')) return; // not applicable for compact prompt layout
var currentlyMobile = isMobile();
if (currentlyMobile == isSetupForMobile) return;
isSetupForMobile = currentlyMobile;
@ -20,7 +22,13 @@ function reportWindowSize() {
var button = gradioApp().getElementById(tab + '_generate_box');
var target = gradioApp().getElementById(currentlyMobile ? tab + '_results' : tab + '_actions_column');
target.insertBefore(button, target.firstElementChild);
gradioApp().getElementById(tab + '_results').classList.toggle('mobile', currentlyMobile);
}
}
window.addEventListener("resize", reportWindowSize);
onUiLoaded(function() {
reportWindowSize();
});

View File

@ -0,0 +1,64 @@
from PIL import Image
from modules import scripts_postprocessing, ui_components
import gradio as gr
def center_crop(image: Image, w: int, h: int):
iw, ih = image.size
if ih / h < iw / w:
sw = w * ih / h
box = (iw - sw) / 2, 0, iw - (iw - sw) / 2, ih
else:
sh = h * iw / w
box = 0, (ih - sh) / 2, iw, ih - (ih - sh) / 2
return image.resize((w, h), Image.Resampling.LANCZOS, box)
def multicrop_pic(image: Image, mindim, maxdim, minarea, maxarea, objective, threshold):
iw, ih = image.size
err = lambda w, h: 1 - (lambda x: x if x < 1 else 1 / x)(iw / ih / (w / h))
wh = max(((w, h) for w in range(mindim, maxdim + 1, 64) for h in range(mindim, maxdim + 1, 64)
if minarea <= w * h <= maxarea and err(w, h) <= threshold),
key=lambda wh: (wh[0] * wh[1], -err(*wh))[::1 if objective == 'Maximize area' else -1],
default=None
)
return wh and center_crop(image, *wh)
class ScriptPostprocessingAutosizedCrop(scripts_postprocessing.ScriptPostprocessing):
name = "Auto-sized crop"
order = 4020
def ui(self):
with ui_components.InputAccordion(False, label="Auto-sized crop") as enable:
gr.Markdown('Each image is center-cropped with an automatically chosen width and height.')
with gr.Row():
mindim = gr.Slider(minimum=64, maximum=2048, step=8, label="Dimension lower bound", value=384, elem_id="postprocess_multicrop_mindim")
maxdim = gr.Slider(minimum=64, maximum=2048, step=8, label="Dimension upper bound", value=768, elem_id="postprocess_multicrop_maxdim")
with gr.Row():
minarea = gr.Slider(minimum=64 * 64, maximum=2048 * 2048, step=1, label="Area lower bound", value=64 * 64, elem_id="postprocess_multicrop_minarea")
maxarea = gr.Slider(minimum=64 * 64, maximum=2048 * 2048, step=1, label="Area upper bound", value=640 * 640, elem_id="postprocess_multicrop_maxarea")
with gr.Row():
objective = gr.Radio(["Maximize area", "Minimize error"], value="Maximize area", label="Resizing objective", elem_id="postprocess_multicrop_objective")
threshold = gr.Slider(minimum=0, maximum=1, step=0.01, label="Error threshold", value=0.1, elem_id="postprocess_multicrop_threshold")
return {
"enable": enable,
"mindim": mindim,
"maxdim": maxdim,
"minarea": minarea,
"maxarea": maxarea,
"objective": objective,
"threshold": threshold,
}
def process(self, pp: scripts_postprocessing.PostprocessedImage, enable, mindim, maxdim, minarea, maxarea, objective, threshold):
if not enable:
return
cropped = multicrop_pic(pp.image, mindim, maxdim, minarea, maxarea, objective, threshold)
if cropped is not None:
pp.image = cropped
else:
print(f"skipped {pp.image.width}x{pp.image.height} image (can't find suitable size within error threshold)")

View File

@ -0,0 +1,30 @@
from modules import scripts_postprocessing, ui_components, deepbooru, shared
import gradio as gr
class ScriptPostprocessingCeption(scripts_postprocessing.ScriptPostprocessing):
name = "Caption"
order = 4040
def ui(self):
with ui_components.InputAccordion(False, label="Caption") as enable:
option = gr.CheckboxGroup(value=["Deepbooru"], choices=["Deepbooru", "BLIP"], show_label=False)
return {
"enable": enable,
"option": option,
}
def process(self, pp: scripts_postprocessing.PostprocessedImage, enable, option):
if not enable:
return
captions = [pp.caption]
if "Deepbooru" in option:
captions.append(deepbooru.model.tag(pp.image))
if "BLIP" in option:
captions.append(shared.interrogator.interrogate(pp.image.convert("RGB")))
pp.caption = ", ".join([x for x in captions if x])

View File

@ -0,0 +1,32 @@
from PIL import ImageOps, Image
from modules import scripts_postprocessing, ui_components
import gradio as gr
class ScriptPostprocessingCreateFlippedCopies(scripts_postprocessing.ScriptPostprocessing):
name = "Create flipped copies"
order = 4030
def ui(self):
with ui_components.InputAccordion(False, label="Create flipped copies") as enable:
with gr.Row():
option = gr.CheckboxGroup(value=["Horizontal"], choices=["Horizontal", "Vertical", "Both"], show_label=False)
return {
"enable": enable,
"option": option,
}
def process(self, pp: scripts_postprocessing.PostprocessedImage, enable, option):
if not enable:
return
if "Horizontal" in option:
pp.extra_images.append(ImageOps.mirror(pp.image))
if "Vertical" in option:
pp.extra_images.append(pp.image.transpose(Image.Transpose.FLIP_TOP_BOTTOM))
if "Both" in option:
pp.extra_images.append(pp.image.transpose(Image.Transpose.FLIP_TOP_BOTTOM).transpose(Image.Transpose.FLIP_LEFT_RIGHT))

View File

@ -0,0 +1,54 @@
from modules import scripts_postprocessing, ui_components, errors
import gradio as gr
from modules.textual_inversion import autocrop
class ScriptPostprocessingFocalCrop(scripts_postprocessing.ScriptPostprocessing):
name = "Auto focal point crop"
order = 4010
def ui(self):
with ui_components.InputAccordion(False, label="Auto focal point crop") as enable:
face_weight = gr.Slider(label='Focal point face weight', value=0.9, minimum=0.0, maximum=1.0, step=0.05, elem_id="postprocess_focal_crop_face_weight")
entropy_weight = gr.Slider(label='Focal point entropy weight', value=0.15, minimum=0.0, maximum=1.0, step=0.05, elem_id="postprocess_focal_crop_entropy_weight")
edges_weight = gr.Slider(label='Focal point edges weight', value=0.5, minimum=0.0, maximum=1.0, step=0.05, elem_id="postprocess_focal_crop_edges_weight")
debug = gr.Checkbox(label='Create debug image', elem_id="train_process_focal_crop_debug")
return {
"enable": enable,
"face_weight": face_weight,
"entropy_weight": entropy_weight,
"edges_weight": edges_weight,
"debug": debug,
}
def process(self, pp: scripts_postprocessing.PostprocessedImage, enable, face_weight, entropy_weight, edges_weight, debug):
if not enable:
return
if not pp.shared.target_width or not pp.shared.target_height:
return
dnn_model_path = None
try:
dnn_model_path = autocrop.download_and_cache_models()
except Exception:
errors.report("Unable to load face detection model for auto crop selection. Falling back to lower quality haar method.", exc_info=True)
autocrop_settings = autocrop.Settings(
crop_width=pp.shared.target_width,
crop_height=pp.shared.target_height,
face_points_weight=face_weight,
entropy_points_weight=entropy_weight,
corner_points_weight=edges_weight,
annotate_image=debug,
dnn_model_path=dnn_model_path,
)
result, *others = autocrop.crop_image(pp.image, autocrop_settings)
pp.image = result
pp.extra_images = [pp.create_copy(x, nametags=["focal-crop-debug"], disable_processing=True) for x in others]

View File

@ -0,0 +1,71 @@
import math
from modules import scripts_postprocessing, ui_components
import gradio as gr
def split_pic(image, inverse_xy, width, height, overlap_ratio):
if inverse_xy:
from_w, from_h = image.height, image.width
to_w, to_h = height, width
else:
from_w, from_h = image.width, image.height
to_w, to_h = width, height
h = from_h * to_w // from_w
if inverse_xy:
image = image.resize((h, to_w))
else:
image = image.resize((to_w, h))
split_count = math.ceil((h - to_h * overlap_ratio) / (to_h * (1.0 - overlap_ratio)))
y_step = (h - to_h) / (split_count - 1)
for i in range(split_count):
y = int(y_step * i)
if inverse_xy:
splitted = image.crop((y, 0, y + to_h, to_w))
else:
splitted = image.crop((0, y, to_w, y + to_h))
yield splitted
class ScriptPostprocessingSplitOversized(scripts_postprocessing.ScriptPostprocessing):
name = "Split oversized images"
order = 4000
def ui(self):
with ui_components.InputAccordion(False, label="Split oversized images") as enable:
with gr.Row():
split_threshold = gr.Slider(label='Threshold', value=0.5, minimum=0.0, maximum=1.0, step=0.05, elem_id="postprocess_split_threshold")
overlap_ratio = gr.Slider(label='Overlap ratio', value=0.2, minimum=0.0, maximum=0.9, step=0.05, elem_id="postprocess_overlap_ratio")
return {
"enable": enable,
"split_threshold": split_threshold,
"overlap_ratio": overlap_ratio,
}
def process(self, pp: scripts_postprocessing.PostprocessedImage, enable, split_threshold, overlap_ratio):
if not enable:
return
width = pp.shared.target_width
height = pp.shared.target_height
if not width or not height:
return
if pp.image.height > pp.image.width:
ratio = (pp.image.width * height) / (pp.image.height * width)
inverse_xy = False
else:
ratio = (pp.image.height * width) / (pp.image.width * height)
inverse_xy = True
if ratio >= 1.0 or ratio > split_threshold:
return
result, *others = split_pic(pp.image, inverse_xy, width, height, overlap_ratio)
pp.image = result
pp.extra_images = [pp.create_copy(x) for x in others]

View File

@ -0,0 +1,760 @@
import numpy as np
import gradio as gr
import math
from modules.ui_components import InputAccordion
import modules.scripts as scripts
from modules.torch_utils import float64
class SoftInpaintingSettings:
def __init__(self,
mask_blend_power,
mask_blend_scale,
inpaint_detail_preservation,
composite_mask_influence,
composite_difference_threshold,
composite_difference_contrast):
self.mask_blend_power = mask_blend_power
self.mask_blend_scale = mask_blend_scale
self.inpaint_detail_preservation = inpaint_detail_preservation
self.composite_mask_influence = composite_mask_influence
self.composite_difference_threshold = composite_difference_threshold
self.composite_difference_contrast = composite_difference_contrast
def add_generation_params(self, dest):
dest[enabled_gen_param_label] = True
dest[gen_param_labels.mask_blend_power] = self.mask_blend_power
dest[gen_param_labels.mask_blend_scale] = self.mask_blend_scale
dest[gen_param_labels.inpaint_detail_preservation] = self.inpaint_detail_preservation
dest[gen_param_labels.composite_mask_influence] = self.composite_mask_influence
dest[gen_param_labels.composite_difference_threshold] = self.composite_difference_threshold
dest[gen_param_labels.composite_difference_contrast] = self.composite_difference_contrast
# ------------------- Methods -------------------
def processing_uses_inpainting(p):
# TODO: Figure out a better way to determine if inpainting is being used by p
if getattr(p, "image_mask", None) is not None:
return True
if getattr(p, "mask", None) is not None:
return True
if getattr(p, "nmask", None) is not None:
return True
return False
def latent_blend(settings, a, b, t):
"""
Interpolates two latent image representations according to the parameter t,
where the interpolated vectors' magnitudes are also interpolated separately.
The "detail_preservation" factor biases the magnitude interpolation towards
the larger of the two magnitudes.
"""
import torch
# NOTE: We use inplace operations wherever possible.
if len(t.shape) == 3:
# [4][w][h] to [1][4][w][h]
t2 = t.unsqueeze(0)
# [4][w][h] to [1][1][w][h] - the [4] seem redundant.
t3 = t[0].unsqueeze(0).unsqueeze(0)
else:
t2 = t
t3 = t[:, 0][:, None]
one_minus_t2 = 1 - t2
one_minus_t3 = 1 - t3
# Linearly interpolate the image vectors.
a_scaled = a * one_minus_t2
b_scaled = b * t2
image_interp = a_scaled
image_interp.add_(b_scaled)
result_type = image_interp.dtype
del a_scaled, b_scaled, t2, one_minus_t2
# Calculate the magnitude of the interpolated vectors. (We will remove this magnitude.)
# 64-bit operations are used here to allow large exponents.
current_magnitude = torch.norm(image_interp, p=2, dim=1, keepdim=True).to(float64(image_interp)).add_(0.00001)
# Interpolate the powered magnitudes, then un-power them (bring them back to a power of 1).
a_magnitude = torch.norm(a, p=2, dim=1, keepdim=True).to(float64(a)).pow_(settings.inpaint_detail_preservation) * one_minus_t3
b_magnitude = torch.norm(b, p=2, dim=1, keepdim=True).to(float64(b)).pow_(settings.inpaint_detail_preservation) * t3
desired_magnitude = a_magnitude
desired_magnitude.add_(b_magnitude).pow_(1 / settings.inpaint_detail_preservation)
del a_magnitude, b_magnitude, t3, one_minus_t3
# Change the linearly interpolated image vectors' magnitudes to the value we want.
# This is the last 64-bit operation.
image_interp_scaling_factor = desired_magnitude
image_interp_scaling_factor.div_(current_magnitude)
image_interp_scaling_factor = image_interp_scaling_factor.to(result_type)
image_interp_scaled = image_interp
image_interp_scaled.mul_(image_interp_scaling_factor)
del current_magnitude
del desired_magnitude
del image_interp
del image_interp_scaling_factor
del result_type
return image_interp_scaled
def get_modified_nmask(settings, nmask, sigma):
"""
Converts a negative mask representing the transparency of the original latent vectors being overlaid
to a mask that is scaled according to the denoising strength for this step.
Where:
0 = fully opaque, infinite density, fully masked
1 = fully transparent, zero density, fully unmasked
We bring this transparency to a power, as this allows one to simulate N number of blending operations
where N can be any positive real value. Using this one can control the balance of influence between
the denoiser and the original latents according to the sigma value.
NOTE: "mask" is not used
"""
import torch
return torch.pow(nmask, (sigma ** settings.mask_blend_power) * settings.mask_blend_scale)
def apply_adaptive_masks(
settings: SoftInpaintingSettings,
nmask,
latent_orig,
latent_processed,
overlay_images,
width, height,
paste_to):
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter
# TODO: Bias the blending according to the latent mask, add adjustable parameter for bias control.
if len(nmask.shape) == 3:
latent_mask = nmask[0].float()
else:
latent_mask = nmask[:, 0].float()
# convert the original mask into a form we use to scale distances for thresholding
mask_scalar = 1 - (torch.clamp(latent_mask, min=0, max=1) ** (settings.mask_blend_scale / 2))
mask_scalar = (0.5 * (1 - settings.composite_mask_influence)
+ mask_scalar * settings.composite_mask_influence)
mask_scalar = mask_scalar / (1.00001 - mask_scalar)
mask_scalar = mask_scalar.cpu().numpy()
latent_distance = torch.norm(latent_processed - latent_orig, p=2, dim=1)
kernel, kernel_center = get_gaussian_kernel(stddev_radius=1.5, max_radius=2)
masks_for_overlay = []
for i, (distance_map, overlay_image) in enumerate(zip(latent_distance, overlay_images)):
converted_mask = distance_map.float().cpu().numpy()
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.9, percentile_max=1, min_width=1)
converted_mask = weighted_histogram_filter(converted_mask, kernel, kernel_center,
percentile_min=0.25, percentile_max=0.75, min_width=1)
# The distance at which opacity of original decreases to 50%
if len(mask_scalar.shape) == 3:
if mask_scalar.shape[0] > i:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar[i]
else:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar[0]
else:
half_weighted_distance = settings.composite_difference_threshold * mask_scalar
converted_mask = converted_mask / half_weighted_distance
converted_mask = 1 / (1 + converted_mask ** settings.composite_difference_contrast)
converted_mask = smootherstep(converted_mask)
converted_mask = 1 - converted_mask
converted_mask = 255. * converted_mask
converted_mask = converted_mask.astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)
# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))
# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(overlay_image.width, overlay_image.height),
paste_to)
masks_for_overlay.append(converted_mask)
image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))
overlay_images[i] = image_masked.convert('RGBA')
return masks_for_overlay
def apply_masks(
settings,
nmask,
overlay_images,
width, height,
paste_to):
import torch
import modules.processing as proc
import modules.images as images
from PIL import Image, ImageOps, ImageFilter
converted_mask = nmask[0].float()
converted_mask = torch.clamp(converted_mask, min=0, max=1).pow_(settings.mask_blend_scale / 2)
converted_mask = 255. * converted_mask
converted_mask = converted_mask.cpu().numpy().astype(np.uint8)
converted_mask = Image.fromarray(converted_mask)
converted_mask = images.resize_image(2, converted_mask, width, height)
converted_mask = proc.create_binary_mask(converted_mask, round=False)
# Remove aliasing artifacts using a gaussian blur.
converted_mask = converted_mask.filter(ImageFilter.GaussianBlur(radius=4))
# Expand the mask to fit the whole image if needed.
if paste_to is not None:
converted_mask = proc.uncrop(converted_mask,
(width, height),
paste_to)
masks_for_overlay = []
for i, overlay_image in enumerate(overlay_images):
masks_for_overlay[i] = converted_mask
image_masked = Image.new('RGBa', (overlay_image.width, overlay_image.height))
image_masked.paste(overlay_image.convert("RGBA").convert("RGBa"),
mask=ImageOps.invert(converted_mask.convert('L')))
overlay_images[i] = image_masked.convert('RGBA')
return masks_for_overlay
def weighted_histogram_filter(img, kernel, kernel_center, percentile_min=0.0, percentile_max=1.0, min_width=1.0):
"""
Generalization convolution filter capable of applying
weighted mean, median, maximum, and minimum filters
parametrically using an arbitrary kernel.
Args:
img (nparray):
The image, a 2-D array of floats, to which the filter is being applied.
kernel (nparray):
The kernel, a 2-D array of floats.
kernel_center (nparray):
The kernel center coordinate, a 1-D array with two elements.
percentile_min (float):
The lower bound of the histogram window used by the filter,
from 0 to 1.
percentile_max (float):
The upper bound of the histogram window used by the filter,
from 0 to 1.
min_width (float):
The minimum size of the histogram window bounds, in weight units.
Must be greater than 0.
Returns:
(nparray): A filtered copy of the input image "img", a 2-D array of floats.
"""
# Converts an index tuple into a vector.
def vec(x):
return np.array(x)
kernel_min = -kernel_center
kernel_max = vec(kernel.shape) - kernel_center
def weighted_histogram_filter_single(idx):
idx = vec(idx)
min_index = np.maximum(0, idx + kernel_min)
max_index = np.minimum(vec(img.shape), idx + kernel_max)
window_shape = max_index - min_index
class WeightedElement:
"""
An element of the histogram, its weight
and bounds.
"""
def __init__(self, value, weight):
self.value: float = value
self.weight: float = weight
self.window_min: float = 0.0
self.window_max: float = 1.0
# Collect the values in the image as WeightedElements,
# weighted by their corresponding kernel values.
values = []
for window_tup in np.ndindex(tuple(window_shape)):
window_index = vec(window_tup)
image_index = window_index + min_index
centered_kernel_index = image_index - idx
kernel_index = centered_kernel_index + kernel_center
element = WeightedElement(img[tuple(image_index)], kernel[tuple(kernel_index)])
values.append(element)
def sort_key(x: WeightedElement):
return x.value
values.sort(key=sort_key)
# Calculate the height of the stack (sum)
# and each sample's range they occupy in the stack
sum = 0
for i in range(len(values)):
values[i].window_min = sum
sum += values[i].weight
values[i].window_max = sum
# Calculate what range of this stack ("window")
# we want to get the weighted average across.
window_min = sum * percentile_min
window_max = sum * percentile_max
window_width = window_max - window_min
# Ensure the window is within the stack and at least a certain size.
if window_width < min_width:
window_center = (window_min + window_max) / 2
window_min = window_center - min_width / 2
window_max = window_center + min_width / 2
if window_max > sum:
window_max = sum
window_min = sum - min_width
if window_min < 0:
window_min = 0
window_max = min_width
value = 0
value_weight = 0
# Get the weighted average of all the samples
# that overlap with the window, weighted
# by the size of their overlap.
for i in range(len(values)):
if window_min >= values[i].window_max:
continue
if window_max <= values[i].window_min:
break
s = max(window_min, values[i].window_min)
e = min(window_max, values[i].window_max)
w = e - s
value += values[i].value * w
value_weight += w
return value / value_weight if value_weight != 0 else 0
img_out = img.copy()
# Apply the kernel operation over each pixel.
for index in np.ndindex(img.shape):
img_out[index] = weighted_histogram_filter_single(index)
return img_out
def smoothstep(x):
"""
The smoothstep function, input should be clamped to 0-1 range.
Turns a diagonal line (f(x) = x) into a sigmoid-like curve.
"""
return x * x * (3 - 2 * x)
def smootherstep(x):
"""
The smootherstep function, input should be clamped to 0-1 range.
Turns a diagonal line (f(x) = x) into a sigmoid-like curve.
"""
return x * x * x * (x * (6 * x - 15) + 10)
def get_gaussian_kernel(stddev_radius=1.0, max_radius=2):
"""
Creates a Gaussian kernel with thresholded edges.
Args:
stddev_radius (float):
Standard deviation of the gaussian kernel, in pixels.
max_radius (int):
The size of the filter kernel. The number of pixels is (max_radius*2+1) ** 2.
The kernel is thresholded so that any values one pixel beyond this radius
is weighted at 0.
Returns:
(nparray, nparray): A kernel array (shape: (N, N)), its center coordinate (shape: (2))
"""
# Evaluates a 0-1 normalized gaussian function for a given square distance from the mean.
def gaussian(sqr_mag):
return math.exp(-sqr_mag / (stddev_radius * stddev_radius))
# Helper function for converting a tuple to an array.
def vec(x):
return np.array(x)
"""
Since a gaussian is unbounded, we need to limit ourselves
to a finite range.
We taper the ends off at the end of that range so they equal zero
while preserving the maximum value of 1 at the mean.
"""
zero_radius = max_radius + 1.0
gauss_zero = gaussian(zero_radius * zero_radius)
gauss_kernel_scale = 1 / (1 - gauss_zero)
def gaussian_kernel_func(coordinate):
x = coordinate[0] ** 2.0 + coordinate[1] ** 2.0
x = gaussian(x)
x -= gauss_zero
x *= gauss_kernel_scale
x = max(0.0, x)
return x
size = max_radius * 2 + 1
kernel_center = max_radius
kernel = np.zeros((size, size))
for index in np.ndindex(kernel.shape):
kernel[index] = gaussian_kernel_func(vec(index) - kernel_center)
return kernel, kernel_center
# ------------------- Constants -------------------
default = SoftInpaintingSettings(1, 0.5, 4, 0, 0.5, 2)
enabled_ui_label = "Soft inpainting"
enabled_gen_param_label = "Soft inpainting enabled"
enabled_el_id = "soft_inpainting_enabled"
ui_labels = SoftInpaintingSettings(
"Schedule bias",
"Preservation strength",
"Transition contrast boost",
"Mask influence",
"Difference threshold",
"Difference contrast")
ui_info = SoftInpaintingSettings(
"Shifts when preservation of original content occurs during denoising.",
"How strongly partially masked content should be preserved.",
"Amplifies the contrast that may be lost in partially masked regions.",
"How strongly the original mask should bias the difference threshold.",
"How much an image region can change before the original pixels are not blended in anymore.",
"How sharp the transition should be between blended and not blended.")
gen_param_labels = SoftInpaintingSettings(
"Soft inpainting schedule bias",
"Soft inpainting preservation strength",
"Soft inpainting transition contrast boost",
"Soft inpainting mask influence",
"Soft inpainting difference threshold",
"Soft inpainting difference contrast")
el_ids = SoftInpaintingSettings(
"mask_blend_power",
"mask_blend_scale",
"inpaint_detail_preservation",
"composite_mask_influence",
"composite_difference_threshold",
"composite_difference_contrast")
# ------------------- Script -------------------
class Script(scripts.Script):
def __init__(self):
self.section = "inpaint"
self.masks_for_overlay = None
self.overlay_images = None
def title(self):
return "Soft Inpainting"
def show(self, is_img2img):
return scripts.AlwaysVisible if is_img2img else False
def ui(self, is_img2img):
if not is_img2img:
return
with InputAccordion(False, label=enabled_ui_label, elem_id=enabled_el_id) as soft_inpainting_enabled:
with gr.Group():
gr.Markdown(
"""
Soft inpainting allows you to **seamlessly blend original content with inpainted content** according to the mask opacity.
**High _Mask blur_** values are recommended!
""")
power = \
gr.Slider(label=ui_labels.mask_blend_power,
info=ui_info.mask_blend_power,
minimum=0,
maximum=8,
step=0.1,
value=default.mask_blend_power,
elem_id=el_ids.mask_blend_power)
scale = \
gr.Slider(label=ui_labels.mask_blend_scale,
info=ui_info.mask_blend_scale,
minimum=0,
maximum=8,
step=0.05,
value=default.mask_blend_scale,
elem_id=el_ids.mask_blend_scale)
detail = \
gr.Slider(label=ui_labels.inpaint_detail_preservation,
info=ui_info.inpaint_detail_preservation,
minimum=1,
maximum=32,
step=0.5,
value=default.inpaint_detail_preservation,
elem_id=el_ids.inpaint_detail_preservation)
gr.Markdown(
"""
### Pixel Composite Settings
""")
mask_inf = \
gr.Slider(label=ui_labels.composite_mask_influence,
info=ui_info.composite_mask_influence,
minimum=0,
maximum=1,
step=0.05,
value=default.composite_mask_influence,
elem_id=el_ids.composite_mask_influence)
dif_thresh = \
gr.Slider(label=ui_labels.composite_difference_threshold,
info=ui_info.composite_difference_threshold,
minimum=0,
maximum=8,
step=0.25,
value=default.composite_difference_threshold,
elem_id=el_ids.composite_difference_threshold)
dif_contr = \
gr.Slider(label=ui_labels.composite_difference_contrast,
info=ui_info.composite_difference_contrast,
minimum=0,
maximum=8,
step=0.25,
value=default.composite_difference_contrast,
elem_id=el_ids.composite_difference_contrast)
with gr.Accordion("Help", open=False):
gr.Markdown(
f"""
### {ui_labels.mask_blend_power}
The blending strength of original content is scaled proportionally with the decreasing noise level values at each step (sigmas).
This ensures that the influence of the denoiser and original content preservation is roughly balanced at each step.
This balance can be shifted using this parameter, controlling whether earlier or later steps have stronger preservation.
- **Below 1**: Stronger preservation near the end (with low sigma)
- **1**: Balanced (proportional to sigma)
- **Above 1**: Stronger preservation in the beginning (with high sigma)
""")
gr.Markdown(
f"""
### {ui_labels.mask_blend_scale}
Skews whether partially masked image regions should be more likely to preserve the original content or favor inpainted content.
This may need to be adjusted depending on the {ui_labels.mask_blend_power}, CFG Scale, prompt and Denoising strength.
- **Low values**: Favors generated content.
- **High values**: Favors original content.
""")
gr.Markdown(
f"""
### {ui_labels.inpaint_detail_preservation}
This parameter controls how the original latent vectors and denoised latent vectors are interpolated.
With higher values, the magnitude of the resulting blended vector will be closer to the maximum of the two interpolated vectors.
This can prevent the loss of contrast that occurs with linear interpolation.
- **Low values**: Softer blending, details may fade.
- **High values**: Stronger contrast, may over-saturate colors.
""")
gr.Markdown(
"""
## Pixel Composite Settings
Masks are generated based on how much a part of the image changed after denoising.
These masks are used to blend the original and final images together.
If the difference is low, the original pixels are used instead of the pixels returned by the inpainting process.
""")
gr.Markdown(
f"""
### {ui_labels.composite_mask_influence}
This parameter controls how much the mask should bias this sensitivity to difference.
- **0**: Ignore the mask, only consider differences in image content.
- **1**: Follow the mask closely despite image content changes.
""")
gr.Markdown(
f"""
### {ui_labels.composite_difference_threshold}
This value represents the difference at which the original pixels will have less than 50% opacity.
- **Low values**: Two images patches must be almost the same in order to retain original pixels.
- **High values**: Two images patches can be very different and still retain original pixels.
""")
gr.Markdown(
f"""
### {ui_labels.composite_difference_contrast}
This value represents the contrast between the opacity of the original and inpainted content.
- **Low values**: The blend will be more gradual and have longer transitions, but may cause ghosting.
- **High values**: Ghosting will be less common, but transitions may be very sudden.
""")
self.infotext_fields = [(soft_inpainting_enabled, enabled_gen_param_label),
(power, gen_param_labels.mask_blend_power),
(scale, gen_param_labels.mask_blend_scale),
(detail, gen_param_labels.inpaint_detail_preservation),
(mask_inf, gen_param_labels.composite_mask_influence),
(dif_thresh, gen_param_labels.composite_difference_threshold),
(dif_contr, gen_param_labels.composite_difference_contrast)]
self.paste_field_names = []
for _, field_name in self.infotext_fields:
self.paste_field_names.append(field_name)
return [soft_inpainting_enabled,
power,
scale,
detail,
mask_inf,
dif_thresh,
dif_contr]
def process(self, p, enabled, power, scale, detail_preservation, mask_inf, dif_thresh, dif_contr):
if not enabled:
return
if not processing_uses_inpainting(p):
return
# Shut off the rounding it normally does.
p.mask_round = False
settings = SoftInpaintingSettings(power, scale, detail_preservation, mask_inf, dif_thresh, dif_contr)
# p.extra_generation_params["Mask rounding"] = False
settings.add_generation_params(p.extra_generation_params)
def on_mask_blend(self, p, mba: scripts.MaskBlendArgs, enabled, power, scale, detail_preservation, mask_inf,
dif_thresh, dif_contr):
if not enabled:
return
if not processing_uses_inpainting(p):
return
if mba.is_final_blend:
mba.blended_latent = mba.current_latent
return
settings = SoftInpaintingSettings(power, scale, detail_preservation, mask_inf, dif_thresh, dif_contr)
# todo: Why is sigma 2D? Both values are the same.
mba.blended_latent = latent_blend(settings,
mba.init_latent,
mba.current_latent,
get_modified_nmask(settings, mba.nmask, mba.sigma[0]))
def post_sample(self, p, ps: scripts.PostSampleArgs, enabled, power, scale, detail_preservation, mask_inf,
dif_thresh, dif_contr):
if not enabled:
return
if not processing_uses_inpainting(p):
return
nmask = getattr(p, "nmask", None)
if nmask is None:
return
from modules import images
from modules.shared import opts
settings = SoftInpaintingSettings(power, scale, detail_preservation, mask_inf, dif_thresh, dif_contr)
# since the original code puts holes in the existing overlay images,
# we have to rebuild them.
self.overlay_images = []
for img in p.init_images:
image = images.flatten(img, opts.img2img_background_color)
if p.paste_to is None and p.resize_mode != 3:
image = images.resize_image(p.resize_mode, image, p.width, p.height)
self.overlay_images.append(image.convert('RGBA'))
if len(p.init_images) == 1:
self.overlay_images = self.overlay_images * p.batch_size
if getattr(ps.samples, 'already_decoded', False):
self.masks_for_overlay = apply_masks(settings=settings,
nmask=nmask,
overlay_images=self.overlay_images,
width=p.width,
height=p.height,
paste_to=p.paste_to)
else:
self.masks_for_overlay = apply_adaptive_masks(settings=settings,
nmask=nmask,
latent_orig=p.init_latent,
latent_processed=ps.samples,
overlay_images=self.overlay_images,
width=p.width,
height=p.height,
paste_to=p.paste_to)
def postprocess_maskoverlay(self, p, ppmo: scripts.PostProcessMaskOverlayArgs, enabled, power, scale,
detail_preservation, mask_inf, dif_thresh, dif_contr):
if not enabled:
return
if not processing_uses_inpainting(p):
return
if self.masks_for_overlay is None:
return
if self.overlay_images is None:
return
ppmo.mask_for_overlay = self.masks_for_overlay[ppmo.index]
ppmo.overlay_image = self.overlay_images[ppmo.index]

View File

@ -1,14 +1,9 @@
<div class='card' style={style} onclick={card_clicked} data-name="{name}" {sort_keys}>
<div class="card" style="{style}" onclick="{card_clicked}" data-name="{name}" {sort_keys}>
{background_image}
<div class="button-row">
{metadata_button}
{edit_button}
</div>
<div class='actions'>
<div class='additional'>
<span style="display:none" class='search_term{search_only}'>{search_term}</span>
</div>
<span class='name'>{name}</span>
<span class='description'>{description}</span>
<div class="button-row">{copy_path_button}{metadata_button}{edit_button}</div>
<div class="actions">
<div class="additional">{search_terms}</div>
<span class="name">{name}</span>
<span class="description">{description}</span>
</div>
</div>

View File

@ -0,0 +1,5 @@
<div class="copy-path-button card-button"
title="Copy path to clipboard"
onclick="extraNetworksCopyCardPath(event)"
data-clipboard-text="{filename}">
</div>

View File

@ -0,0 +1,4 @@
<div class="edit-button card-button"
title="Edit metadata"
onclick="extraNetworksEditUserMetadata(event, '{tabname}', '{extra_networks_tabname}')">
</div>

View File

@ -0,0 +1,4 @@
<div class="metadata-button card-button"
title="Show internal metadata"
onclick="extraNetworksRequestMetadata(event, '{extra_networks_tabname}')">
</div>

View File

@ -0,0 +1,8 @@
<div class="extra-network-pane-content-dirs">
<div id='{tabname}_{extra_networks_tabname}_dirs' class='extra-network-dirs'>
{dirs_html}
</div>
<div id='{tabname}_{extra_networks_tabname}_cards' class='extra-network-cards'>
{items_html}
</div>
</div>

View File

@ -0,0 +1,8 @@
<div class="extra-network-pane-content-tree resize-handle-row">
<div id='{tabname}_{extra_networks_tabname}_tree' class='extra-network-tree' style='flex-basis: {extra_networks_tree_view_default_width}px'>
{tree_html}
</div>
<div id='{tabname}_{extra_networks_tabname}_cards' class='extra-network-cards' style='flex-grow: 1;'>
{items_html}
</div>
</div>

View File

@ -0,0 +1,81 @@
<div id='{tabname}_{extra_networks_tabname}_pane' class='extra-network-pane {tree_view_div_default_display_class}'>
<div class="extra-network-control" id="{tabname}_{extra_networks_tabname}_controls" style="display:none" >
<div class="extra-network-control--search">
<input
id="{tabname}_{extra_networks_tabname}_extra_search"
class="extra-network-control--search-text"
type="search"
placeholder="Search"
>
</div>
<small>Sort: </small>
<div
id="{tabname}_{extra_networks_tabname}_extra_sort_path"
class="extra-network-control--sort{sort_path_active}"
data-sortkey="default"
title="Sort by path"
onclick="extraNetworksControlSortOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--sort-icon"></i>
</div>
<div
id="{tabname}_{extra_networks_tabname}_extra_sort_name"
class="extra-network-control--sort{sort_name_active}"
data-sortkey="name"
title="Sort by name"
onclick="extraNetworksControlSortOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--sort-icon"></i>
</div>
<div
id="{tabname}_{extra_networks_tabname}_extra_sort_date_created"
class="extra-network-control--sort{sort_date_created_active}"
data-sortkey="date_created"
title="Sort by date created"
onclick="extraNetworksControlSortOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--sort-icon"></i>
</div>
<div
id="{tabname}_{extra_networks_tabname}_extra_sort_date_modified"
class="extra-network-control--sort{sort_date_modified_active}"
data-sortkey="date_modified"
title="Sort by date modified"
onclick="extraNetworksControlSortOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--sort-icon"></i>
</div>
<small> </small>
<div
id="{tabname}_{extra_networks_tabname}_extra_sort_dir"
class="extra-network-control--sort-dir"
data-sortdir="{data_sortdir}"
title="Sort ascending"
onclick="extraNetworksControlSortDirOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--sort-dir-icon"></i>
</div>
<small> </small>
<div
id="{tabname}_{extra_networks_tabname}_extra_tree_view"
class="extra-network-control--tree-view {tree_view_btn_extra_class}"
title="Enable Tree View"
onclick="extraNetworksControlTreeViewOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--tree-view-icon"></i>
</div>
<div
id="{tabname}_{extra_networks_tabname}_extra_refresh"
class="extra-network-control--refresh"
title="Refresh page"
onclick="extraNetworksControlRefreshOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--refresh-icon"></i>
</div>
</div>
{pane_content}
</div>

View File

@ -0,0 +1,23 @@
<span data-filterable-item-text hidden>{search_terms}</span>
<div class="tree-list-content {subclass}"
type="button"
onclick="extraNetworksTreeOnClick(event, '{tabname}', '{extra_networks_tabname}');{onclick_extra}"
data-path="{data_path}"
data-hash="{data_hash}"
>
<span class='tree-list-item-action tree-list-item-action--leading'>
{action_list_item_action_leading}
</span>
<span class="tree-list-item-visual tree-list-item-visual--leading">
{action_list_item_visual_leading}
</span>
<span class="tree-list-item-label tree-list-item-label--truncate">
{action_list_item_label}
</span>
<span class="tree-list-item-visual tree-list-item-visual--trailing">
{action_list_item_visual_trailing}
</span>
<span class="tree-list-item-action tree-list-item-action--trailing">
{action_list_item_action_trailing}
</span>
</div>

View File

@ -4,107 +4,6 @@
#licenses pre { margin: 1em 0 2em 0;}
</style>
<h2><a href="https://github.com/sczhou/CodeFormer/blob/master/LICENSE">CodeFormer</a></h2>
<small>Parts of CodeFormer code had to be copied to be compatible with GFPGAN.</small>
<pre>
S-Lab License 1.0
Copyright 2022 S-Lab
Redistribution and use for non-commercial purpose in source and
binary forms, with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
In the event that redistribution and/or use for commercial purpose in
source or binary forms, with or without modification is required,
please contact the contributor(s) of the work.
</pre>
<h2><a href="https://github.com/victorca25/iNNfer/blob/main/LICENSE">ESRGAN</a></h2>
<small>Code for architecture and reading models copied.</small>
<pre>
MIT License
Copyright (c) 2021 victorca25
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre>
<h2><a href="https://github.com/xinntao/Real-ESRGAN/blob/master/LICENSE">Real-ESRGAN</a></h2>
<small>Some code is copied to support ESRGAN models.</small>
<pre>
BSD 3-Clause License
Copyright (c) 2021, Xintao Wang
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</pre>
<h2><a href="https://github.com/invoke-ai/InvokeAI/blob/main/LICENSE">InvokeAI</a></h2>
<small>Some code for compatibility with OSX is taken from lstein's repository.</small>
<pre>
@ -183,213 +82,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre>
<h2><a href="https://github.com/JingyunLiang/SwinIR/blob/main/LICENSE">SwinIR</a></h2>
<small>Code added by contributors, most likely copied from this repository.</small>
<pre>
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2021] [SwinIR Authors]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</pre>
<h2><a href="https://github.com/AminRezaei0x443/memory-efficient-attention/blob/main/LICENSE">Memory Efficient Attention</a></h2>
<small>The sub-quadratic cross attention optimization uses modified code from the Memory Efficient Attention package that Alex Birch optimized for 3D tensors. This license is updated to reflect that.</small>
<pre>
@ -687,4 +379,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre>
</pre>

View File

@ -50,17 +50,17 @@ function dimensionChange(e, is_width, is_height) {
var scaledx = targetElement.naturalWidth * viewportscale;
var scaledy = targetElement.naturalHeight * viewportscale;
var cleintRectTop = (viewportOffset.top + window.scrollY);
var cleintRectLeft = (viewportOffset.left + window.scrollX);
var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2);
var cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth / 2);
var clientRectTop = (viewportOffset.top + window.scrollY);
var clientRectLeft = (viewportOffset.left + window.scrollX);
var clientRectCentreY = clientRectTop + (targetElement.clientHeight / 2);
var clientRectCentreX = clientRectLeft + (targetElement.clientWidth / 2);
var arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight);
var arscaledx = currentWidth * arscale;
var arscaledy = currentHeight * arscale;
var arRectTop = cleintRectCentreY - (arscaledy / 2);
var arRectLeft = cleintRectCentreX - (arscaledx / 2);
var arRectTop = clientRectCentreY - (arscaledy / 2);
var arRectLeft = clientRectCentreX - (arscaledx / 2);
var arRectWidth = arscaledx;
var arRectHeight = arscaledy;

View File

@ -8,9 +8,6 @@ var contextMenuInit = function() {
};
function showContextMenu(event, element, menuEntries) {
let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
let oldMenu = gradioApp().querySelector('#context-menu');
if (oldMenu) {
oldMenu.remove();
@ -23,10 +20,8 @@ var contextMenuInit = function() {
contextMenu.style.background = baseStyle.background;
contextMenu.style.color = baseStyle.color;
contextMenu.style.fontFamily = baseStyle.fontFamily;
contextMenu.style.top = posy + 'px';
contextMenu.style.left = posx + 'px';
contextMenu.style.top = event.pageY + 'px';
contextMenu.style.left = event.pageX + 'px';
const contextMenuList = document.createElement('ul');
contextMenuList.className = 'context-menu-items';
@ -43,21 +38,6 @@ var contextMenuInit = function() {
});
gradioApp().appendChild(contextMenu);
let menuWidth = contextMenu.offsetWidth + 4;
let menuHeight = contextMenu.offsetHeight + 4;
let windowWidth = window.innerWidth;
let windowHeight = window.innerHeight;
if ((windowWidth - posx) < menuWidth) {
contextMenu.style.left = windowWidth - menuWidth + "px";
}
if ((windowHeight - posy) < menuHeight) {
contextMenu.style.top = windowHeight - menuHeight + "px";
}
}
function appendContextMenuOption(targetElementSelector, entryName, entryFunction) {
@ -107,16 +87,23 @@ var contextMenuInit = function() {
oldMenu.remove();
}
});
gradioApp().addEventListener("contextmenu", function(e) {
let oldMenu = gradioApp().querySelector('#context-menu');
if (oldMenu) {
oldMenu.remove();
}
menuSpecs.forEach(function(v, k) {
if (e.composedPath()[0].matches(k)) {
showContextMenu(e, e.composedPath()[0], v);
e.preventDefault();
['contextmenu', 'touchstart'].forEach((eventType) => {
gradioApp().addEventListener(eventType, function(e) {
let ev = e;
if (eventType.startsWith('touch')) {
if (e.touches.length !== 2) return;
ev = e.touches[0];
}
let oldMenu = gradioApp().querySelector('#context-menu');
if (oldMenu) {
oldMenu.remove();
}
menuSpecs.forEach(function(v, k) {
if (e.composedPath()[0].matches(k)) {
showContextMenu(ev, e.composedPath()[0], v);
e.preventDefault();
}
});
});
});
eventListenerApplied = true;

View File

@ -56,6 +56,15 @@ function eventHasFiles(e) {
return false;
}
function isURL(url) {
try {
const _ = new URL(url);
return true;
} catch {
return false;
}
}
function dragDropTargetIsPrompt(target) {
if (target?.placeholder && target?.placeholder.indexOf("Prompt") >= 0) return true;
if (target?.parentNode?.parentNode?.className?.indexOf("prompt") > 0) return true;
@ -74,22 +83,39 @@ window.document.addEventListener('dragover', e => {
e.dataTransfer.dropEffect = 'copy';
});
window.document.addEventListener('drop', e => {
window.document.addEventListener('drop', async e => {
const target = e.composedPath()[0];
if (!eventHasFiles(e)) return;
const url = e.dataTransfer.getData('text/uri-list') || e.dataTransfer.getData('text/plain');
if (!eventHasFiles(e) && !isURL(url)) return;
if (dragDropTargetIsPrompt(target)) {
e.stopPropagation();
e.preventDefault();
let prompt_target = get_tab_index('tabs') == 1 ? "img2img_prompt_image" : "txt2img_prompt_image";
const isImg2img = get_tab_index('tabs') == 1;
let prompt_image_target = isImg2img ? "img2img_prompt_image" : "txt2img_prompt_image";
const imgParent = gradioApp().getElementById(prompt_target);
const imgParent = gradioApp().getElementById(prompt_image_target);
const files = e.dataTransfer.files;
const fileInput = imgParent.querySelector('input[type="file"]');
if (fileInput) {
if (eventHasFiles(e) && fileInput) {
fileInput.files = files;
fileInput.dispatchEvent(new Event('change'));
} else if (url) {
try {
const request = await fetch(url);
if (!request.ok) {
console.error('Error fetching URL:', url, request.status);
return;
}
const data = new DataTransfer();
data.items.add(new File([await request.blob()], 'image.png'));
fileInput.files = data.files;
fileInput.dispatchEvent(new Event('change'));
} catch (error) {
console.error('Error fetching URL:', url, error);
return;
}
}
}
@ -119,7 +145,7 @@ window.addEventListener('paste', e => {
}
const firstFreeImageField = visibleImageFields
.filter(el => el.querySelector('input[type=file]'))?.[0];
.filter(el => !el.querySelector('img'))?.[0];
dropReplaceImage(
firstFreeImageField ?

View File

@ -18,37 +18,43 @@ function keyupEditAttention(event) {
const before = text.substring(0, selectionStart);
let beforeParen = before.lastIndexOf(OPEN);
if (beforeParen == -1) return false;
let beforeParenClose = before.lastIndexOf(CLOSE);
while (beforeParenClose !== -1 && beforeParenClose > beforeParen) {
beforeParen = before.lastIndexOf(OPEN, beforeParen - 1);
beforeParenClose = before.lastIndexOf(CLOSE, beforeParenClose - 1);
}
let beforeClosingParen = before.lastIndexOf(CLOSE);
if (beforeClosingParen != -1 && beforeClosingParen > beforeParen) return false;
// Find closing parenthesis around current cursor
const after = text.substring(selectionStart);
let afterParen = after.indexOf(CLOSE);
if (afterParen == -1) return false;
let afterParenOpen = after.indexOf(OPEN);
while (afterParenOpen !== -1 && afterParen > afterParenOpen) {
afterParen = after.indexOf(CLOSE, afterParen + 1);
afterParenOpen = after.indexOf(OPEN, afterParenOpen + 1);
}
if (beforeParen === -1 || afterParen === -1) return false;
let afterOpeningParen = after.indexOf(OPEN);
if (afterOpeningParen != -1 && afterOpeningParen < afterParen) return false;
// Set the selection to the text between the parenthesis
const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen);
const lastColon = parenContent.lastIndexOf(":");
selectionStart = beforeParen + 1;
selectionEnd = selectionStart + lastColon;
if (/.*:-?[\d.]+/s.test(parenContent)) {
const lastColon = parenContent.lastIndexOf(":");
selectionStart = beforeParen + 1;
selectionEnd = selectionStart + lastColon;
} else {
selectionStart = beforeParen + 1;
selectionEnd = selectionStart + parenContent.length;
}
target.setSelectionRange(selectionStart, selectionEnd);
return true;
}
function selectCurrentWord() {
if (selectionStart !== selectionEnd) return false;
const delimiters = opts.keyedit_delimiters + " \r\n\t";
const whitespace_delimiters = {"Tab": "\t", "Carriage Return": "\r", "Line Feed": "\n"};
let delimiters = opts.keyedit_delimiters;
// seek backward until to find beggining
for (let i of opts.keyedit_delimiters_whitespace) {
delimiters += whitespace_delimiters[i];
}
// seek backward to find beginning
while (!delimiters.includes(text[selectionStart - 1]) && selectionStart > 0) {
selectionStart--;
}
@ -58,12 +64,20 @@ function keyupEditAttention(event) {
selectionEnd++;
}
// deselect surrounding whitespace
while (text[selectionStart] == " " && selectionStart < selectionEnd) {
selectionStart++;
}
while (text[selectionEnd - 1] == " " && selectionEnd > selectionStart) {
selectionEnd--;
}
target.setSelectionRange(selectionStart, selectionEnd);
return true;
}
// If the user hasn't selected anything, let's select their current parenthesis block or word
if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')')) {
if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')') && !selectCurrentParenthesisBlock('[', ']')) {
selectCurrentWord();
}
@ -71,33 +85,54 @@ function keyupEditAttention(event) {
var closeCharacter = ')';
var delta = opts.keyedit_precision_attention;
var start = selectionStart > 0 ? text[selectionStart - 1] : "";
var end = text[selectionEnd];
if (selectionStart > 0 && text[selectionStart - 1] == '<') {
if (start == '<') {
closeCharacter = '>';
delta = opts.keyedit_precision_extra;
} else if (selectionStart == 0 || text[selectionStart - 1] != "(") {
} else if (start == '(' && end == ')' || start == '[' && end == ']') { // convert old-style (((emphasis)))
let numParen = 0;
while (text[selectionStart - numParen - 1] == start && text[selectionEnd + numParen] == end) {
numParen++;
}
if (start == "[") {
weight = (1 / 1.1) ** numParen;
} else {
weight = 1.1 ** numParen;
}
weight = Math.round(weight / opts.keyedit_precision_attention) * opts.keyedit_precision_attention;
text = text.slice(0, selectionStart - numParen) + "(" + text.slice(selectionStart, selectionEnd) + ":" + weight + ")" + text.slice(selectionEnd + numParen);
selectionStart -= numParen - 1;
selectionEnd -= numParen - 1;
} else if (start != '(') {
// do not include spaces at the end
while (selectionEnd > selectionStart && text[selectionEnd - 1] == ' ') {
selectionEnd -= 1;
selectionEnd--;
}
if (selectionStart == selectionEnd) {
return;
}
text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd);
selectionStart += 1;
selectionEnd += 1;
selectionStart++;
selectionEnd++;
}
var end = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1;
var weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + 1 + end));
if (text[selectionEnd] != ':') return;
var weightLength = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1;
var weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + weightLength));
if (isNaN(weight)) return;
weight += isPlus ? delta : -delta;
weight = parseFloat(weight.toPrecision(12));
if (String(weight).length == 1) weight += ".0";
if (Number.isInteger(weight)) weight += ".0";
if (closeCharacter == ')' && weight == 1) {
var endParenPos = text.substring(selectionEnd).indexOf(')');
@ -105,7 +140,7 @@ function keyupEditAttention(event) {
selectionStart--;
selectionEnd--;
} else {
text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + end);
text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + weightLength);
}
target.focus();

View File

@ -2,8 +2,11 @@
function extensions_apply(_disabled_list, _update_list, disable_all) {
var disable = [];
var update = [];
gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x) {
const extensions_input = gradioApp().querySelectorAll('#extensions input[type="checkbox"]');
if (extensions_input.length == 0) {
throw Error("Extensions page not yet loaded.");
}
extensions_input.forEach(function(x) {
if (x.name.startsWith("enable_") && !x.checked) {
disable.push(x.name.substring(7));
}
@ -33,7 +36,7 @@ function extensions_check() {
var id = randomId();
requestProgress(id, gradioApp().getElementById('extensions_installed_top'), null, function() {
requestProgress(id, gradioApp().getElementById('extensions_installed_html'), null, function() {
});

View File

@ -1,98 +1,21 @@
function toggleCss(key, css, enable) {
var style = document.getElementById(key);
if (enable && !style) {
style = document.createElement('style');
style.id = key;
style.type = 'text/css';
document.head.appendChild(style);
}
if (style && !enable) {
document.head.removeChild(style);
}
if (style) {
style.innerHTML == '';
style.appendChild(document.createTextNode(css));
}
}
function setupExtraNetworksForTab(tabname) {
gradioApp().querySelector('#' + tabname + '_extra_tabs').classList.add('extra-networks');
var tabs = gradioApp().querySelector('#' + tabname + '_extra_tabs > div');
var search = gradioApp().querySelector('#' + tabname + '_extra_search textarea');
var sort = gradioApp().getElementById(tabname + '_extra_sort');
var sortOrder = gradioApp().getElementById(tabname + '_extra_sortorder');
var refresh = gradioApp().getElementById(tabname + '_extra_refresh');
search.classList.add('search');
sort.classList.add('sort');
sortOrder.classList.add('sortorder');
sort.dataset.sortkey = 'sortDefault';
tabs.appendChild(search);
tabs.appendChild(sort);
tabs.appendChild(sortOrder);
tabs.appendChild(refresh);
var applyFilter = function() {
var searchTerm = search.value.toLowerCase();
gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card').forEach(function(elem) {
var searchOnly = elem.querySelector('.search_only');
var text = elem.querySelector('.name').textContent.toLowerCase() + " " + elem.querySelector('.search_term').textContent.toLowerCase();
var visible = text.indexOf(searchTerm) != -1;
if (searchOnly && searchTerm.length < 4) {
visible = false;
}
elem.style.display = visible ? "" : "none";
});
};
var applySort = function() {
var reverse = sortOrder.classList.contains("sortReverse");
var sortKey = sort.querySelector("input").value.toLowerCase().replace("sort", "").replaceAll(" ", "_").replace(/_+$/, "").trim();
sortKey = sortKey ? "sort" + sortKey.charAt(0).toUpperCase() + sortKey.slice(1) : "";
var sortKeyStore = sortKey ? sortKey + (reverse ? "Reverse" : "") : "";
if (!sortKey || sortKeyStore == sort.dataset.sortkey) {
return;
}
sort.dataset.sortkey = sortKeyStore;
var cards = gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card');
cards.forEach(function(card) {
card.originalParentElement = card.parentElement;
});
var sortedCards = Array.from(cards);
sortedCards.sort(function(cardA, cardB) {
var a = cardA.dataset[sortKey];
var b = cardB.dataset[sortKey];
if (!isNaN(a) && !isNaN(b)) {
return parseInt(a) - parseInt(b);
}
return (a < b ? -1 : (a > b ? 1 : 0));
});
if (reverse) {
sortedCards.reverse();
}
cards.forEach(function(card) {
card.remove();
});
sortedCards.forEach(function(card) {
card.originalParentElement.appendChild(card);
});
};
search.addEventListener("input", applyFilter);
applyFilter();
["change", "blur", "click"].forEach(function(evt) {
sort.querySelector("input").addEventListener(evt, applySort);
});
sortOrder.addEventListener("click", function() {
sortOrder.classList.toggle("sortReverse");
applySort();
});
extraNetworksApplyFilter[tabname] = applyFilter;
}
function applyExtraNetworkFilter(tabname) {
setTimeout(extraNetworksApplyFilter[tabname], 1);
}
var extraNetworksApplyFilter = {};
var activePromptTextarea = {};
function setupExtraNetworks() {
setupExtraNetworksForTab('txt2img');
setupExtraNetworksForTab('img2img');
function registerPrompt(tabname, id) {
var textarea = gradioApp().querySelector("#" + id + " > label > textarea");
@ -105,27 +28,195 @@ function setupExtraNetworks() {
});
}
registerPrompt('txt2img', 'txt2img_prompt');
registerPrompt('txt2img', 'txt2img_neg_prompt');
registerPrompt('img2img', 'img2img_prompt');
registerPrompt('img2img', 'img2img_neg_prompt');
var tabnav = gradioApp().querySelector('#' + tabname + '_extra_tabs > div.tab-nav');
var controlsDiv = document.createElement('DIV');
controlsDiv.classList.add('extra-networks-controls-div');
tabnav.appendChild(controlsDiv);
tabnav.insertBefore(controlsDiv, null);
var this_tab = gradioApp().querySelector('#' + tabname + '_extra_tabs');
this_tab.querySelectorAll(":scope > [id^='" + tabname + "_']").forEach(function(elem) {
// tabname_full = {tabname}_{extra_networks_tabname}
var tabname_full = elem.id;
var search = gradioApp().querySelector("#" + tabname_full + "_extra_search");
var sort_dir = gradioApp().querySelector("#" + tabname_full + "_extra_sort_dir");
var refresh = gradioApp().querySelector("#" + tabname_full + "_extra_refresh");
var currentSort = '';
// If any of the buttons above don't exist, we want to skip this iteration of the loop.
if (!search || !sort_dir || !refresh) {
return; // `return` is equivalent of `continue` but for forEach loops.
}
var applyFilter = function(force) {
var searchTerm = search.value.toLowerCase();
gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card').forEach(function(elem) {
var searchOnly = elem.querySelector('.search_only');
var text = Array.prototype.map.call(elem.querySelectorAll('.search_terms, .description'), function(t) {
return t.textContent.toLowerCase();
}).join(" ");
var visible = text.indexOf(searchTerm) != -1;
if (searchOnly && searchTerm.length < 4) {
visible = false;
}
if (visible) {
elem.classList.remove("hidden");
} else {
elem.classList.add("hidden");
}
});
applySort(force);
};
var applySort = function(force) {
var cards = gradioApp().querySelectorAll('#' + tabname_full + ' div.card');
var parent = gradioApp().querySelector('#' + tabname_full + "_cards");
var reverse = sort_dir.dataset.sortdir == "Descending";
var activeSearchElem = gradioApp().querySelector('#' + tabname_full + "_controls .extra-network-control--sort.extra-network-control--enabled");
var sortKey = activeSearchElem ? activeSearchElem.dataset.sortkey : "default";
var sortKeyDataField = "sort" + sortKey.charAt(0).toUpperCase() + sortKey.slice(1);
var sortKeyStore = sortKey + "-" + sort_dir.dataset.sortdir + "-" + cards.length;
if (sortKeyStore == currentSort && !force) {
return;
}
currentSort = sortKeyStore;
var sortedCards = Array.from(cards);
sortedCards.sort(function(cardA, cardB) {
var a = cardA.dataset[sortKeyDataField];
var b = cardB.dataset[sortKeyDataField];
if (!isNaN(a) && !isNaN(b)) {
return parseInt(a) - parseInt(b);
}
return (a < b ? -1 : (a > b ? 1 : 0));
});
if (reverse) {
sortedCards.reverse();
}
parent.innerHTML = '';
var frag = document.createDocumentFragment();
sortedCards.forEach(function(card) {
frag.appendChild(card);
});
parent.appendChild(frag);
};
search.addEventListener("input", function() {
applyFilter();
});
applySort();
applyFilter();
extraNetworksApplySort[tabname_full] = applySort;
extraNetworksApplyFilter[tabname_full] = applyFilter;
var controls = gradioApp().querySelector("#" + tabname_full + "_controls");
controlsDiv.insertBefore(controls, null);
if (elem.style.display != "none") {
extraNetworksShowControlsForPage(tabname, tabname_full);
}
});
registerPrompt(tabname, tabname + "_prompt");
registerPrompt(tabname, tabname + "_neg_prompt");
}
onUiLoaded(setupExtraNetworks);
function extraNetworksMovePromptToTab(tabname, id, showPrompt, showNegativePrompt) {
if (!gradioApp().querySelector('.toprow-compact-tools')) return; // only applicable for compact prompt layout
var re_extranet = /<([^:]+:[^:]+):[\d.]+>(.*)/;
var re_extranet_g = /\s+<([^:]+:[^:]+):[\d.]+>/g;
var promptContainer = gradioApp().getElementById(tabname + '_prompt_container');
var prompt = gradioApp().getElementById(tabname + '_prompt_row');
var negPrompt = gradioApp().getElementById(tabname + '_neg_prompt_row');
var elem = id ? gradioApp().getElementById(id) : null;
function tryToRemoveExtraNetworkFromPrompt(textarea, text) {
var m = text.match(re_extranet);
if (showNegativePrompt && elem) {
elem.insertBefore(negPrompt, elem.firstChild);
} else {
promptContainer.insertBefore(negPrompt, promptContainer.firstChild);
}
if (showPrompt && elem) {
elem.insertBefore(prompt, elem.firstChild);
} else {
promptContainer.insertBefore(prompt, promptContainer.firstChild);
}
if (elem) {
elem.classList.toggle('extra-page-prompts-active', showNegativePrompt || showPrompt);
}
}
function extraNetworksShowControlsForPage(tabname, tabname_full) {
gradioApp().querySelectorAll('#' + tabname + '_extra_tabs .extra-networks-controls-div > div').forEach(function(elem) {
var targetId = tabname_full + "_controls";
elem.style.display = elem.id == targetId ? "" : "none";
});
}
function extraNetworksUnrelatedTabSelected(tabname) { // called from python when user selects an unrelated tab (generate)
extraNetworksMovePromptToTab(tabname, '', false, false);
extraNetworksShowControlsForPage(tabname, null);
}
function extraNetworksTabSelected(tabname, id, showPrompt, showNegativePrompt, tabname_full) { // called from python when user selects an extra networks tab
extraNetworksMovePromptToTab(tabname, id, showPrompt, showNegativePrompt);
extraNetworksShowControlsForPage(tabname, tabname_full);
}
function applyExtraNetworkFilter(tabname_full) {
var doFilter = function() {
var applyFunction = extraNetworksApplyFilter[tabname_full];
if (applyFunction) {
applyFunction(true);
}
};
setTimeout(doFilter, 1);
}
function applyExtraNetworkSort(tabname_full) {
var doSort = function() {
extraNetworksApplySort[tabname_full](true);
};
setTimeout(doSort, 1);
}
var extraNetworksApplyFilter = {};
var extraNetworksApplySort = {};
var activePromptTextarea = {};
function setupExtraNetworks() {
setupExtraNetworksForTab('txt2img');
setupExtraNetworksForTab('img2img');
}
var re_extranet = /<([^:^>]+:[^:]+):[\d.]+>(.*)/;
var re_extranet_g = /<([^:^>]+:[^:]+):[\d.]+>/g;
var re_extranet_neg = /\(([^:^>]+:[\d.]+)\)/;
var re_extranet_g_neg = /\(([^:^>]+:[\d.]+)\)/g;
function tryToRemoveExtraNetworkFromPrompt(textarea, text, isNeg) {
var m = text.match(isNeg ? re_extranet_neg : re_extranet);
var replaced = false;
var newTextareaText;
var extraTextBeforeNet = opts.extra_networks_add_text_separator;
if (m) {
var extraTextAfterNet = m[2];
var partToSearch = m[1];
var foundAtPosition = -1;
newTextareaText = textarea.value.replaceAll(re_extranet_g, function(found, net, pos) {
m = found.match(re_extranet);
newTextareaText = textarea.value.replaceAll(isNeg ? re_extranet_g_neg : re_extranet_g, function(found, net, pos) {
m = found.match(isNeg ? re_extranet_neg : re_extranet);
if (m[1] == partToSearch) {
replaced = true;
foundAtPosition = pos;
@ -133,18 +224,17 @@ function tryToRemoveExtraNetworkFromPrompt(textarea, text) {
}
return found;
});
if (foundAtPosition >= 0 && newTextareaText.substr(foundAtPosition, extraTextAfterNet.length) == extraTextAfterNet) {
newTextareaText = newTextareaText.substr(0, foundAtPosition) + newTextareaText.substr(foundAtPosition + extraTextAfterNet.length);
if (foundAtPosition >= 0) {
if (extraTextAfterNet && newTextareaText.substr(foundAtPosition, extraTextAfterNet.length) == extraTextAfterNet) {
newTextareaText = newTextareaText.substr(0, foundAtPosition) + newTextareaText.substr(foundAtPosition + extraTextAfterNet.length);
}
if (newTextareaText.substr(foundAtPosition - extraTextBeforeNet.length, extraTextBeforeNet.length) == extraTextBeforeNet) {
newTextareaText = newTextareaText.substr(0, foundAtPosition - extraTextBeforeNet.length) + newTextareaText.substr(foundAtPosition);
}
}
} else {
newTextareaText = textarea.value.replaceAll(new RegExp(text, "g"), function(found) {
if (found == text) {
replaced = true;
return "";
}
return found;
});
newTextareaText = textarea.value.replaceAll(new RegExp(`((?:${extraTextBeforeNet})?${text})`, "g"), "");
replaced = (newTextareaText != textarea.value);
}
if (replaced) {
@ -155,14 +245,22 @@ function tryToRemoveExtraNetworkFromPrompt(textarea, text) {
return false;
}
function cardClicked(tabname, textToAdd, allowNegativePrompt) {
var textarea = allowNegativePrompt ? activePromptTextarea[tabname] : gradioApp().querySelector("#" + tabname + "_prompt > label > textarea");
if (!tryToRemoveExtraNetworkFromPrompt(textarea, textToAdd)) {
textarea.value = textarea.value + opts.extra_networks_add_text_separator + textToAdd;
function updatePromptArea(text, textArea, isNeg) {
if (!tryToRemoveExtraNetworkFromPrompt(textArea, text, isNeg)) {
textArea.value = textArea.value + opts.extra_networks_add_text_separator + text;
}
updateInput(textarea);
updateInput(textArea);
}
function cardClicked(tabname, textToAdd, textToAddNegative, allowNegativePrompt) {
if (textToAddNegative.length > 0) {
updatePromptArea(textToAdd, gradioApp().querySelector("#" + tabname + "_prompt > label > textarea"));
updatePromptArea(textToAddNegative, gradioApp().querySelector("#" + tabname + "_neg_prompt > label > textarea"), true);
} else {
var textarea = allowNegativePrompt ? activePromptTextarea[tabname] : gradioApp().querySelector("#" + tabname + "_prompt > label > textarea");
updatePromptArea(textToAdd, textarea);
}
}
function saveCardPreview(event, tabname, filename) {
@ -178,8 +276,8 @@ function saveCardPreview(event, tabname, filename) {
event.preventDefault();
}
function extraNetworksSearchButton(tabs_id, event) {
var searchTextarea = gradioApp().querySelector("#" + tabs_id + ' > div > textarea');
function extraNetworksSearchButton(tabname, extra_networks_tabname, event) {
var searchTextarea = gradioApp().querySelector("#" + tabname + "_" + extra_networks_tabname + "_extra_search");
var button = event.target;
var text = button.classList.contains("search-all") ? "" : button.textContent.trim();
@ -187,29 +285,207 @@ function extraNetworksSearchButton(tabs_id, event) {
updateInput(searchTextarea);
}
function extraNetworksTreeProcessFileClick(event, btn, tabname, extra_networks_tabname) {
/**
* Processes `onclick` events when user clicks on files in tree.
*
* @param event The generated event.
* @param btn The clicked `tree-list-item` button.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
// NOTE: Currently unused.
return;
}
function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, extra_networks_tabname) {
/**
* Processes `onclick` events when user clicks on directories in tree.
*
* Here is how the tree reacts to clicks for various states:
* unselected unopened directory: Directory is selected and expanded.
* unselected opened directory: Directory is selected.
* selected opened directory: Directory is collapsed and deselected.
* chevron is clicked: Directory is expanded or collapsed. Selected state unchanged.
*
* @param event The generated event.
* @param btn The clicked `tree-list-item` button.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
var ul = btn.nextElementSibling;
// This is the actual target that the user clicked on within the target button.
// We use this to detect if the chevron was clicked.
var true_targ = event.target;
function _expand_or_collapse(_ul, _btn) {
// Expands <ul> if it is collapsed, collapses otherwise. Updates button attributes.
if (_ul.hasAttribute("hidden")) {
_ul.removeAttribute("hidden");
_btn.dataset.expanded = "";
} else {
_ul.setAttribute("hidden", "");
delete _btn.dataset.expanded;
}
}
function _remove_selected_from_all() {
// Removes the `selected` attribute from all buttons.
var sels = document.querySelectorAll("div.tree-list-content");
[...sels].forEach(el => {
delete el.dataset.selected;
});
}
function _select_button(_btn) {
// Removes `data-selected` attribute from all buttons then adds to passed button.
_remove_selected_from_all();
_btn.dataset.selected = "";
}
function _update_search(_tabname, _extra_networks_tabname, _search_text) {
// Update search input with select button's path.
var search_input_elem = gradioApp().querySelector("#" + tabname + "_" + extra_networks_tabname + "_extra_search");
search_input_elem.value = _search_text;
updateInput(search_input_elem);
}
// If user clicks on the chevron, then we do not select the folder.
if (true_targ.matches(".tree-list-item-action--leading, .tree-list-item-action-chevron")) {
_expand_or_collapse(ul, btn);
} else {
// User clicked anywhere else on the button.
if ("selected" in btn.dataset && !(ul.hasAttribute("hidden"))) {
// If folder is select and open, collapse and deselect button.
_expand_or_collapse(ul, btn);
delete btn.dataset.selected;
_update_search(tabname, extra_networks_tabname, "");
} else if (!(!("selected" in btn.dataset) && !(ul.hasAttribute("hidden")))) {
// If folder is open and not selected, then we don't collapse; just select.
// NOTE: Double inversion sucks but it is the clearest way to show the branching here.
_expand_or_collapse(ul, btn);
_select_button(btn, tabname, extra_networks_tabname);
_update_search(tabname, extra_networks_tabname, btn.dataset.path);
} else {
// All other cases, just select the button.
_select_button(btn, tabname, extra_networks_tabname);
_update_search(tabname, extra_networks_tabname, btn.dataset.path);
}
}
}
function extraNetworksTreeOnClick(event, tabname, extra_networks_tabname) {
/**
* Handles `onclick` events for buttons within an `extra-network-tree .tree-list--tree`.
*
* Determines whether the clicked button in the tree is for a file entry or a directory
* then calls the appropriate function.
*
* @param event The generated event.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
var btn = event.currentTarget;
var par = btn.parentElement;
if (par.dataset.treeEntryType === "file") {
extraNetworksTreeProcessFileClick(event, btn, tabname, extra_networks_tabname);
} else {
extraNetworksTreeProcessDirectoryClick(event, btn, tabname, extra_networks_tabname);
}
}
function extraNetworksControlSortOnClick(event, tabname, extra_networks_tabname) {
/** Handles `onclick` events for Sort Mode buttons. */
var self = event.currentTarget;
var parent = event.currentTarget.parentElement;
parent.querySelectorAll('.extra-network-control--sort').forEach(function(x) {
x.classList.remove('extra-network-control--enabled');
});
self.classList.add('extra-network-control--enabled');
applyExtraNetworkSort(tabname + "_" + extra_networks_tabname);
}
function extraNetworksControlSortDirOnClick(event, tabname, extra_networks_tabname) {
/**
* Handles `onclick` events for the Sort Direction button.
*
* Modifies the data attributes of the Sort Direction button to cycle between
* ascending and descending sort directions.
*
* @param event The generated event.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
if (event.currentTarget.dataset.sortdir == "Ascending") {
event.currentTarget.dataset.sortdir = "Descending";
event.currentTarget.setAttribute("title", "Sort descending");
} else {
event.currentTarget.dataset.sortdir = "Ascending";
event.currentTarget.setAttribute("title", "Sort ascending");
}
applyExtraNetworkSort(tabname + "_" + extra_networks_tabname);
}
function extraNetworksControlTreeViewOnClick(event, tabname, extra_networks_tabname) {
/**
* Handles `onclick` events for the Tree View button.
*
* Toggles the tree view in the extra networks pane.
*
* @param event The generated event.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
var button = event.currentTarget;
button.classList.toggle("extra-network-control--enabled");
var show = !button.classList.contains("extra-network-control--enabled");
var pane = gradioApp().getElementById(tabname + "_" + extra_networks_tabname + "_pane");
pane.classList.toggle("extra-network-dirs-hidden", show);
}
function extraNetworksControlRefreshOnClick(event, tabname, extra_networks_tabname) {
/**
* Handles `onclick` events for the Refresh Page button.
*
* In order to actually call the python functions in `ui_extra_networks.py`
* to refresh the page, we created an empty gradio button in that file with an
* event handler that refreshes the page. So what this function here does
* is it manually raises a `click` event on that button.
*
* @param event The generated event.
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/
var btn_refresh_internal = gradioApp().getElementById(tabname + "_" + extra_networks_tabname + "_extra_refresh_internal");
btn_refresh_internal.dispatchEvent(new Event("click"));
}
var globalPopup = null;
var globalPopupInner = null;
function closePopup() {
if (!globalPopup) return;
globalPopup.style.display = "none";
}
function popup(contents) {
if (!globalPopup) {
globalPopup = document.createElement('div');
globalPopup.onclick = closePopup;
globalPopup.classList.add('global-popup');
var close = document.createElement('div');
close.classList.add('global-popup-close');
close.onclick = closePopup;
close.addEventListener("click", closePopup);
close.title = "Close";
globalPopup.appendChild(close);
globalPopupInner = document.createElement('div');
globalPopupInner.onclick = function(event) {
event.stopPropagation(); return false;
};
globalPopupInner.classList.add('global-popup-inner');
globalPopup.appendChild(globalPopupInner);
@ -222,12 +498,85 @@ function popup(contents) {
globalPopup.style.display = "flex";
}
var storedPopupIds = {};
function popupId(id) {
if (!storedPopupIds[id]) {
storedPopupIds[id] = gradioApp().getElementById(id);
}
popup(storedPopupIds[id]);
}
function extraNetworksFlattenMetadata(obj) {
const result = {};
// Convert any stringified JSON objects to actual objects
for (const key of Object.keys(obj)) {
if (typeof obj[key] === 'string') {
try {
const parsed = JSON.parse(obj[key]);
if (parsed && typeof parsed === 'object') {
obj[key] = parsed;
}
} catch (error) {
continue;
}
}
}
// Flatten the object
for (const key of Object.keys(obj)) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
const nested = extraNetworksFlattenMetadata(obj[key]);
for (const nestedKey of Object.keys(nested)) {
result[`${key}/${nestedKey}`] = nested[nestedKey];
}
} else {
result[key] = obj[key];
}
}
// Special case for handling modelspec keys
for (const key of Object.keys(result)) {
if (key.startsWith("modelspec.")) {
result[key.replaceAll(".", "/")] = result[key];
delete result[key];
}
}
// Add empty keys to designate hierarchy
for (const key of Object.keys(result)) {
const parts = key.split("/");
for (let i = 1; i < parts.length; i++) {
const parent = parts.slice(0, i).join("/");
if (!result[parent]) {
result[parent] = "";
}
}
}
return result;
}
function extraNetworksShowMetadata(text) {
try {
let parsed = JSON.parse(text);
if (parsed && typeof parsed === 'object') {
parsed = extraNetworksFlattenMetadata(parsed);
const table = createVisualizationTable(parsed, 0);
popup(table);
return;
}
} catch (error) {
console.error(error);
}
var elem = document.createElement('pre');
elem.classList.add('popup-metadata');
elem.textContent = text;
popup(elem);
return;
}
function requestGet(url, data, handler, errorHandler) {
@ -256,11 +605,18 @@ function requestGet(url, data, handler, errorHandler) {
xhr.send(js);
}
function extraNetworksRequestMetadata(event, extraPage, cardName) {
function extraNetworksCopyCardPath(event) {
navigator.clipboard.writeText(event.target.getAttribute("data-clipboard-text"));
event.stopPropagation();
}
function extraNetworksRequestMetadata(event, extraPage) {
var showError = function() {
extraNetworksShowMetadata("there was an error getting metadata");
};
var cardName = event.target.parentElement.parentElement.getAttribute("data-name");
requestGet("./sd_extra_networks/metadata", {page: extraPage, item: cardName}, function(data) {
if (data && data.metadata) {
extraNetworksShowMetadata(data.metadata);
@ -274,7 +630,7 @@ function extraNetworksRequestMetadata(event, extraPage, cardName) {
var extraPageUserMetadataEditors = {};
function extraNetworksEditUserMetadata(event, tabname, extraPage, cardName) {
function extraNetworksEditUserMetadata(event, tabname, extraPage) {
var id = tabname + '_' + extraPage + '_edit_user_metadata';
var editor = extraPageUserMetadataEditors[id];
@ -286,6 +642,7 @@ function extraNetworksEditUserMetadata(event, tabname, extraPage, cardName) {
extraPageUserMetadataEditors[id] = editor;
}
var cardName = event.target.parentElement.parentElement.getAttribute("data-name");
editor.nameTextarea.value = cardName;
updateInput(editor.nameTextarea);
@ -299,15 +656,57 @@ function extraNetworksEditUserMetadata(event, tabname, extraPage, cardName) {
function extraNetworksRefreshSingleCard(page, tabname, name) {
requestGet("./sd_extra_networks/get-single-card", {page: page, tabname: tabname, name: name}, function(data) {
if (data && data.html) {
var card = gradioApp().querySelector('.card[data-name=' + JSON.stringify(name) + ']'); // likely using the wrong stringify function
var card = gradioApp().querySelector(`#${tabname}_${page.replace(" ", "_")}_cards > .card[data-name="${name}"]`);
var newDiv = document.createElement('DIV');
newDiv.innerHTML = data.html;
var newCard = newDiv.firstElementChild;
newCard.style = '';
newCard.style.display = '';
card.parentElement.insertBefore(newCard, card);
card.parentElement.removeChild(card);
}
});
}
window.addEventListener("keydown", function(event) {
if (event.key == "Escape") {
closePopup();
}
});
/**
* Setup custom loading for this script.
* We need to wait for all of our HTML to be generated in the extra networks tabs
* before we can actually run the `setupExtraNetworks` function.
* The `onUiLoaded` function actually runs before all of our extra network tabs are
* finished generating. Thus we needed this new method.
*
*/
var uiAfterScriptsCallbacks = [];
var uiAfterScriptsTimeout = null;
var executedAfterScripts = false;
function scheduleAfterScriptsCallbacks() {
clearTimeout(uiAfterScriptsTimeout);
uiAfterScriptsTimeout = setTimeout(function() {
executeCallbacks(uiAfterScriptsCallbacks);
}, 200);
}
onUiLoaded(function() {
var mutationObserver = new MutationObserver(function(m) {
let existingSearchfields = gradioApp().querySelectorAll("[id$='_extra_search']").length;
let neededSearchfields = gradioApp().querySelectorAll("[id$='_extra_tabs'] > .tab-nav > button").length - 2;
if (!executedAfterScripts && existingSearchfields >= neededSearchfields) {
mutationObserver.disconnect();
executedAfterScripts = true;
scheduleAfterScriptsCallbacks();
}
});
mutationObserver.observe(gradioApp(), {childList: true, subtree: true});
});
uiAfterScriptsCallbacks.push(setupExtraNetworks);

View File

@ -190,3 +190,14 @@ onUiUpdate(function(mutationRecords) {
tooltipCheckTimer = setTimeout(processTooltipCheckNodes, 1000);
}
});
onUiLoaded(function() {
for (var comp of window.gradio_config.components) {
if (comp.props.webui_tooltip && comp.props.elem_id) {
var elem = gradioApp().getElementById(comp.props.elem_id);
if (elem) {
elem.title = comp.props.webui_tooltip;
}
}
}
});

View File

@ -6,6 +6,8 @@ function closeModal() {
function showModal(event) {
const source = event.target || event.srcElement;
const modalImage = gradioApp().getElementById("modalImage");
const modalToggleLivePreviewBtn = gradioApp().getElementById("modal_toggle_live_preview");
modalToggleLivePreviewBtn.innerHTML = opts.js_live_preview_in_modal_lightbox ? "&#x1F5C7;" : "&#x1F5C6;";
const lb = gradioApp().getElementById("lightboxModal");
modalImage.src = source.src;
if (modalImage.style.display === 'none') {
@ -33,8 +35,11 @@ function updateOnBackgroundChange() {
const modalImage = gradioApp().getElementById("modalImage");
if (modalImage && modalImage.offsetParent) {
let currentButton = selected_gallery_button();
if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {
let preview = gradioApp().querySelectorAll('.livePreview > img');
if (opts.js_live_preview_in_modal_lightbox && preview.length > 0) {
// show preview image if available
modalImage.src = preview[preview.length - 1].src;
} else if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {
modalImage.src = currentButton.children[0].src;
if (modalImage.style.display === 'none') {
const modal = gradioApp().getElementById("lightboxModal");
@ -48,14 +53,7 @@ function modalImageSwitch(offset) {
var galleryButtons = all_gallery_buttons();
if (galleryButtons.length > 1) {
var currentButton = selected_gallery_button();
var result = -1;
galleryButtons.forEach(function(v, i) {
if (v == currentButton) {
result = i;
}
});
var result = selected_gallery_index();
if (result != -1) {
var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)];
@ -128,14 +126,15 @@ function setupImageForLightbox(e) {
e.style.cursor = 'pointer';
e.style.userSelect = 'none';
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
e.addEventListener('mousedown', function(evt) {
if (evt.button == 1) {
open(evt.target.src);
evt.preventDefault();
return;
}
}, true);
// For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please.
// For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click';
e.addEventListener(event, function(evt) {
e.addEventListener('click', function(evt) {
if (!opts.js_modal_lightbox || evt.button != 0) return;
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed);
@ -155,6 +154,13 @@ function modalZoomToggle(event) {
event.stopPropagation();
}
function modalLivePreviewToggle(event) {
const modalToggleLivePreview = gradioApp().getElementById("modal_toggle_live_preview");
opts.js_live_preview_in_modal_lightbox = !opts.js_live_preview_in_modal_lightbox;
modalToggleLivePreview.innerHTML = opts.js_live_preview_in_modal_lightbox ? "&#x1F5C7;" : "&#x1F5C6;";
event.stopPropagation();
}
function modalTileImageToggle(event) {
const modalImage = gradioApp().getElementById("modalImage");
const modal = gradioApp().getElementById("lightboxModal");
@ -212,6 +218,14 @@ document.addEventListener("DOMContentLoaded", function() {
modalSave.title = "Save Image(s)";
modalControls.appendChild(modalSave);
const modalToggleLivePreview = document.createElement('span');
modalToggleLivePreview.className = 'modalToggleLivePreview cursor';
modalToggleLivePreview.id = "modal_toggle_live_preview";
modalToggleLivePreview.innerHTML = "&#x1F5C6;";
modalToggleLivePreview.onclick = modalLivePreviewToggle;
modalToggleLivePreview.title = "Toggle live preview";
modalControls.appendChild(modalToggleLivePreview);
const modalClose = document.createElement('span');
modalClose.className = 'modalClose cursor';
modalClose.innerHTML = '&times;';

View File

@ -0,0 +1,68 @@
function inputAccordionChecked(id, checked) {
var accordion = gradioApp().getElementById(id);
accordion.visibleCheckbox.checked = checked;
accordion.onVisibleCheckboxChange();
}
function setupAccordion(accordion) {
var labelWrap = accordion.querySelector('.label-wrap');
var gradioCheckbox = gradioApp().querySelector('#' + accordion.id + "-checkbox input");
var extra = gradioApp().querySelector('#' + accordion.id + "-extra");
var span = labelWrap.querySelector('span');
var linked = true;
var isOpen = function() {
return labelWrap.classList.contains('open');
};
var observerAccordionOpen = new MutationObserver(function(mutations) {
mutations.forEach(function(mutationRecord) {
accordion.classList.toggle('input-accordion-open', isOpen());
if (linked) {
accordion.visibleCheckbox.checked = isOpen();
accordion.onVisibleCheckboxChange();
}
});
});
observerAccordionOpen.observe(labelWrap, {attributes: true, attributeFilter: ['class']});
if (extra) {
labelWrap.insertBefore(extra, labelWrap.lastElementChild);
}
accordion.onChecked = function(checked) {
if (isOpen() != checked) {
labelWrap.click();
}
};
var visibleCheckbox = document.createElement('INPUT');
visibleCheckbox.type = 'checkbox';
visibleCheckbox.checked = isOpen();
visibleCheckbox.id = accordion.id + "-visible-checkbox";
visibleCheckbox.className = gradioCheckbox.className + " input-accordion-checkbox";
span.insertBefore(visibleCheckbox, span.firstChild);
accordion.visibleCheckbox = visibleCheckbox;
accordion.onVisibleCheckboxChange = function() {
if (linked && isOpen() != visibleCheckbox.checked) {
labelWrap.click();
}
gradioCheckbox.checked = visibleCheckbox.checked;
updateInput(gradioCheckbox);
};
visibleCheckbox.addEventListener('click', function(event) {
linked = false;
event.stopPropagation();
});
visibleCheckbox.addEventListener('input', accordion.onVisibleCheckboxChange);
}
onUiLoaded(function() {
for (var accordion of gradioApp().querySelectorAll('.input-accordion')) {
setupAccordion(accordion);
}
});

View File

@ -0,0 +1,26 @@
function localSet(k, v) {
try {
localStorage.setItem(k, v);
} catch (e) {
console.warn(`Failed to save ${k} to localStorage: ${e}`);
}
}
function localGet(k, def) {
try {
return localStorage.getItem(k);
} catch (e) {
console.warn(`Failed to load ${k} from localStorage: ${e}`);
}
return def;
}
function localRemove(k) {
try {
return localStorage.removeItem(k);
} catch (e) {
console.warn(`Failed to remove ${k} from localStorage: ${e}`);
}
}

View File

@ -11,11 +11,11 @@ var ignore_ids_for_localization = {
train_hypernetwork: 'OPTION',
txt2img_styles: 'OPTION',
img2img_styles: 'OPTION',
setting_random_artist_categories: 'SPAN',
setting_face_restoration_model: 'SPAN',
setting_realesrgan_enabled_models: 'SPAN',
extras_upscaler_1: 'SPAN',
extras_upscaler_2: 'SPAN',
setting_random_artist_categories: 'OPTION',
setting_face_restoration_model: 'OPTION',
setting_realesrgan_enabled_models: 'OPTION',
extras_upscaler_1: 'OPTION',
extras_upscaler_2: 'OPTION',
};
var re_num = /^[.\d]+$/;
@ -107,12 +107,41 @@ function processNode(node) {
});
}
function localizeWholePage() {
processNode(gradioApp());
function elem(comp) {
var elem_id = comp.props.elem_id ? comp.props.elem_id : "component-" + comp.id;
return gradioApp().getElementById(elem_id);
}
for (var comp of window.gradio_config.components) {
if (comp.props.webui_tooltip) {
let e = elem(comp);
let tl = e ? getTranslation(e.title) : undefined;
if (tl !== undefined) {
e.title = tl;
}
}
if (comp.props.placeholder) {
let e = elem(comp);
let textbox = e ? e.querySelector('[placeholder]') : null;
let tl = textbox ? getTranslation(textbox.placeholder) : undefined;
if (tl !== undefined) {
textbox.placeholder = tl;
}
}
}
}
function dumpTranslations() {
if (!hasLocalization()) {
// If we don't have any localization,
// we will not have traversed the app to find
// original_lines, so do that now.
processNode(gradioApp());
localizeWholePage();
}
var dumped = {};
if (localization.rtl) {
@ -154,7 +183,7 @@ document.addEventListener("DOMContentLoaded", function() {
});
});
processNode(gradioApp());
localizeWholePage();
if (localization.rtl) { // if the language is from right to left,
(new MutationObserver((mutations, observer) => { // wait for the style to load

View File

@ -15,7 +15,7 @@ onAfterUiUpdate(function() {
}
}
const galleryPreviews = gradioApp().querySelectorAll('div[id^="tab_"][style*="display: block"] div[id$="_results"] .thumbnail-item > img');
const galleryPreviews = gradioApp().querySelectorAll('div[id^="tab_"] div[id$="_results"] .thumbnail-item > img');
if (galleryPreviews == null) return;
@ -26,7 +26,11 @@ onAfterUiUpdate(function() {
lastHeadImg = headImg;
// play notification sound if available
gradioApp().querySelector('#audio_notification audio')?.play();
const notificationAudio = gradioApp().querySelector('#audio_notification audio');
if (notificationAudio) {
notificationAudio.volume = opts.notification_volume / 100.0 || 1.0;
notificationAudio.play();
}
if (document.hasFocus()) return;

View File

@ -33,120 +33,141 @@ function createRow(table, cellName, items) {
return res;
}
function showProfile(path, cutoff = 0.05) {
requestGet(path, {}, function(data) {
var table = document.createElement('table');
table.className = 'popup-table';
function createVisualizationTable(data, cutoff = 0, sort = "") {
var table = document.createElement('table');
table.className = 'popup-table';
data.records['total'] = data.total;
var keys = Object.keys(data.records).sort(function(a, b) {
return data.records[b] - data.records[a];
var keys = Object.keys(data);
if (sort === "number") {
keys = keys.sort(function(a, b) {
return data[b] - data[a];
});
var items = keys.map(function(x) {
return {key: x, parts: x.split('/'), time: data.records[x]};
} else {
keys = keys.sort();
}
var items = keys.map(function(x) {
return {key: x, parts: x.split('/'), value: data[x]};
});
var maxLength = items.reduce(function(a, b) {
return Math.max(a, b.parts.length);
}, 0);
var cols = createRow(
table,
'th',
[
cutoff === 0 ? 'key' : 'record',
cutoff === 0 ? 'value' : 'seconds'
]
);
cols[0].colSpan = maxLength;
function arraysEqual(a, b) {
return !(a < b || b < a);
}
var addLevel = function(level, parent, hide) {
var matching = items.filter(function(x) {
return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent);
});
var maxLength = items.reduce(function(a, b) {
return Math.max(a, b.parts.length);
}, 0);
var cols = createRow(table, 'th', ['record', 'seconds']);
cols[0].colSpan = maxLength;
function arraysEqual(a, b) {
return !(a < b || b < a);
if (sort === "number") {
matching = matching.sort(function(a, b) {
return b.value - a.value;
});
} else {
matching = matching.sort();
}
var othersTime = 0;
var othersList = [];
var othersRows = [];
var childrenRows = [];
matching.forEach(function(x) {
var visible = (cutoff === 0 && !hide) || (x.value >= cutoff && !hide);
var addLevel = function(level, parent, hide) {
var matching = items.filter(function(x) {
return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent);
});
var sorted = matching.sort(function(a, b) {
return b.time - a.time;
});
var othersTime = 0;
var othersList = [];
var othersRows = [];
var childrenRows = [];
sorted.forEach(function(x) {
var visible = x.time >= cutoff && !hide;
var cells = [];
for (var i = 0; i < maxLength; i++) {
cells.push(x.parts[i]);
}
cells.push(cutoff === 0 ? x.value : x.value.toFixed(3));
var cols = createRow(table, 'td', cells);
for (i = 0; i < level; i++) {
cols[i].className = 'muted';
}
var cells = [];
for (var i = 0; i < maxLength; i++) {
cells.push(x.parts[i]);
}
cells.push(x.time.toFixed(3));
var cols = createRow(table, 'td', cells);
for (i = 0; i < level; i++) {
cols[i].className = 'muted';
}
var tr = cols[0].parentNode;
if (!visible) {
tr.classList.add("hidden");
}
var tr = cols[0].parentNode;
if (!visible) {
tr.classList.add("hidden");
}
if (x.time >= cutoff) {
childrenRows.push(tr);
} else {
othersTime += x.time;
othersList.push(x.parts[level]);
othersRows.push(tr);
}
var children = addLevel(level + 1, parent.concat([x.parts[level]]), true);
if (children.length > 0) {
var cell = cols[level];
var onclick = function() {
cell.classList.remove("link");
cell.removeEventListener("click", onclick);
children.forEach(function(x) {
x.classList.remove("hidden");
});
};
cell.classList.add("link");
cell.addEventListener("click", onclick);
}
});
if (othersTime > 0) {
var cells = [];
for (var i = 0; i < maxLength; i++) {
cells.push(parent[i]);
}
cells.push(othersTime.toFixed(3));
cells[level] = 'others';
var cols = createRow(table, 'td', cells);
for (i = 0; i < level; i++) {
cols[i].className = 'muted';
}
if (cutoff === 0 || x.value >= cutoff) {
childrenRows.push(tr);
} else {
othersTime += x.value;
othersList.push(x.parts[level]);
othersRows.push(tr);
}
var children = addLevel(level + 1, parent.concat([x.parts[level]]), true);
if (children.length > 0) {
var cell = cols[level];
var tr = cell.parentNode;
var onclick = function() {
tr.classList.add("hidden");
cell.classList.remove("link");
cell.removeEventListener("click", onclick);
othersRows.forEach(function(x) {
children.forEach(function(x) {
x.classList.remove("hidden");
});
};
cell.title = othersList.join(", ");
cell.classList.add("link");
cell.addEventListener("click", onclick);
}
});
if (hide) {
tr.classList.add("hidden");
}
childrenRows.push(tr);
if (othersTime > 0) {
var cells = [];
for (var i = 0; i < maxLength; i++) {
cells.push(parent[i]);
}
cells.push(othersTime.toFixed(3));
cells[level] = 'others';
var cols = createRow(table, 'td', cells);
for (i = 0; i < level; i++) {
cols[i].className = 'muted';
}
return childrenRows;
};
var cell = cols[level];
var tr = cell.parentNode;
var onclick = function() {
tr.classList.add("hidden");
cell.classList.remove("link");
cell.removeEventListener("click", onclick);
othersRows.forEach(function(x) {
x.classList.remove("hidden");
});
};
addLevel(0, []);
cell.title = othersList.join(", ");
cell.classList.add("link");
cell.addEventListener("click", onclick);
if (hide) {
tr.classList.add("hidden");
}
childrenRows.push(tr);
}
return childrenRows;
};
addLevel(0, []);
return table;
}
function showProfile(path, cutoff = 0.05) {
requestGet(path, {}, function(data) {
data.records['total'] = data.total;
const table = createVisualizationTable(data.records, cutoff, "number");
popup(table);
});
}

View File

@ -45,8 +45,15 @@ function formatTime(secs) {
}
}
var originalAppTitle = undefined;
onUiLoaded(function() {
originalAppTitle = document.title;
});
function setTitle(progress) {
var title = 'Stable Diffusion';
var title = originalAppTitle;
if (opts.show_progress_in_title && progress) {
title = '[' + progress.trim() + '] ' + title;
@ -69,7 +76,26 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre
var dateStart = new Date();
var wasEverActive = false;
var parentProgressbar = progressbarContainer.parentNode;
var parentGallery = gallery ? gallery.parentNode : null;
var wakeLock = null;
var requestWakeLock = async function() {
if (!opts.prevent_screen_sleep_during_generation || wakeLock) return;
try {
wakeLock = await navigator.wakeLock.request('screen');
} catch (err) {
console.error('Wake Lock is not supported.');
}
};
var releaseWakeLock = async function() {
if (!opts.prevent_screen_sleep_during_generation || !wakeLock) return;
try {
await wakeLock.release();
wakeLock = null;
} catch (err) {
console.error('Wake Lock release failed', err);
}
};
var divProgress = document.createElement('div');
divProgress.className = 'progressDiv';
@ -80,32 +106,28 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre
divProgress.appendChild(divInner);
parentProgressbar.insertBefore(divProgress, progressbarContainer);
if (parentGallery) {
var livePreview = document.createElement('div');
livePreview.className = 'livePreview';
parentGallery.insertBefore(livePreview, gallery);
}
var livePreview = null;
var removeProgressBar = function() {
releaseWakeLock();
if (!divProgress) return;
setTitle("");
parentProgressbar.removeChild(divProgress);
if (parentGallery) parentGallery.removeChild(livePreview);
if (gallery && livePreview) gallery.removeChild(livePreview);
atEnd();
divProgress = null;
};
var fun = function(id_task, id_live_preview) {
request("./internal/progress", {id_task: id_task, id_live_preview: id_live_preview}, function(res) {
var funProgress = function(id_task) {
requestWakeLock();
request("./internal/progress", {id_task: id_task, live_preview: false}, function(res) {
if (res.completed) {
removeProgressBar();
return;
}
var rect = progressbarContainer.getBoundingClientRect();
if (rect.width) {
divProgress.style.width = rect.width + "px";
}
let progressText = "";
divInner.style.width = ((res.progress || 0) * 100.0) + '%';
@ -119,7 +141,6 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre
progressText += " ETA: " + formatTime(res.eta);
}
setTitle(progressText);
if (res.textinfo && res.textinfo.indexOf("\n") == -1) {
@ -142,16 +163,33 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre
return;
}
if (onProgress) {
onProgress(res);
}
setTimeout(() => {
funProgress(id_task, res.id_live_preview);
}, opts.live_preview_refresh_period || 500);
}, function() {
removeProgressBar();
});
};
var funLivePreview = function(id_task, id_live_preview) {
request("./internal/progress", {id_task: id_task, id_live_preview: id_live_preview}, function(res) {
if (!divProgress) {
return;
}
if (res.live_preview && gallery) {
rect = gallery.getBoundingClientRect();
if (rect.width) {
livePreview.style.width = rect.width + "px";
livePreview.style.height = rect.height + "px";
}
var img = new Image();
img.onload = function() {
if (!livePreview) {
livePreview = document.createElement('div');
livePreview.className = 'livePreview';
gallery.insertBefore(livePreview, gallery.firstElementChild);
}
livePreview.appendChild(img);
if (livePreview.childElementCount > 2) {
livePreview.removeChild(livePreview.firstElementChild);
@ -160,18 +198,18 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre
img.src = res.live_preview;
}
if (onProgress) {
onProgress(res);
}
setTimeout(() => {
fun(id_task, res.id_live_preview);
funLivePreview(id_task, res.id_live_preview);
}, opts.live_preview_refresh_period || 500);
}, function() {
removeProgressBar();
});
};
fun(id_task, 0);
funProgress(id_task, 0);
if (gallery) {
funLivePreview(id_task, 0);
}
}

205
javascript/resizeHandle.js Normal file
View File

@ -0,0 +1,205 @@
(function() {
const GRADIO_MIN_WIDTH = 320;
const PAD = 16;
const DEBOUNCE_TIME = 100;
const DOUBLE_TAP_DELAY = 200; //ms
const R = {
tracking: false,
parent: null,
parentWidth: null,
leftCol: null,
leftColStartWidth: null,
screenX: null,
lastTapTime: null,
};
let resizeTimer;
let parents = [];
function setLeftColGridTemplate(el, width) {
el.style.gridTemplateColumns = `${width}px 16px 1fr`;
}
function displayResizeHandle(parent) {
if (!parent.needHideOnMoblie) {
return true;
}
if (window.innerWidth < GRADIO_MIN_WIDTH * 2 + PAD * 4) {
parent.style.display = 'flex';
parent.resizeHandle.style.display = "none";
return false;
} else {
parent.style.display = 'grid';
parent.resizeHandle.style.display = "block";
return true;
}
}
function afterResize(parent) {
if (displayResizeHandle(parent) && parent.style.gridTemplateColumns != parent.style.originalGridTemplateColumns) {
const oldParentWidth = R.parentWidth;
const newParentWidth = parent.offsetWidth;
const widthL = parseInt(parent.style.gridTemplateColumns.split(' ')[0]);
const ratio = newParentWidth / oldParentWidth;
const newWidthL = Math.max(Math.floor(ratio * widthL), parent.minLeftColWidth);
setLeftColGridTemplate(parent, newWidthL);
R.parentWidth = newParentWidth;
}
}
function setup(parent) {
function onDoubleClick(evt) {
evt.preventDefault();
evt.stopPropagation();
parent.style.gridTemplateColumns = parent.style.originalGridTemplateColumns;
}
const leftCol = parent.firstElementChild;
const rightCol = parent.lastElementChild;
parents.push(parent);
parent.style.display = 'grid';
parent.style.gap = '0';
let leftColTemplate = "";
if (parent.children[0].style.flexGrow) {
leftColTemplate = `${parent.children[0].style.flexGrow}fr`;
parent.minLeftColWidth = GRADIO_MIN_WIDTH;
parent.minRightColWidth = GRADIO_MIN_WIDTH;
parent.needHideOnMoblie = true;
} else {
leftColTemplate = parent.children[0].style.flexBasis;
parent.minLeftColWidth = parent.children[0].style.flexBasis.slice(0, -2) / 2;
parent.minRightColWidth = 0;
parent.needHideOnMoblie = false;
}
if (!leftColTemplate) {
leftColTemplate = '1fr';
}
const gridTemplateColumns = `${leftColTemplate} ${PAD}px ${parent.children[1].style.flexGrow}fr`;
parent.style.gridTemplateColumns = gridTemplateColumns;
parent.style.originalGridTemplateColumns = gridTemplateColumns;
const resizeHandle = document.createElement('div');
resizeHandle.classList.add('resize-handle');
parent.insertBefore(resizeHandle, rightCol);
parent.resizeHandle = resizeHandle;
['mousedown', 'touchstart'].forEach((eventType) => {
resizeHandle.addEventListener(eventType, (evt) => {
if (eventType.startsWith('mouse')) {
if (evt.button !== 0) return;
} else {
if (evt.changedTouches.length !== 1) return;
const currentTime = new Date().getTime();
if (R.lastTapTime && currentTime - R.lastTapTime <= DOUBLE_TAP_DELAY) {
onDoubleClick(evt);
return;
}
R.lastTapTime = currentTime;
}
evt.preventDefault();
evt.stopPropagation();
document.body.classList.add('resizing');
R.tracking = true;
R.parent = parent;
R.parentWidth = parent.offsetWidth;
R.leftCol = leftCol;
R.leftColStartWidth = leftCol.offsetWidth;
if (eventType.startsWith('mouse')) {
R.screenX = evt.screenX;
} else {
R.screenX = evt.changedTouches[0].screenX;
}
});
});
resizeHandle.addEventListener('dblclick', onDoubleClick);
afterResize(parent);
}
['mousemove', 'touchmove'].forEach((eventType) => {
window.addEventListener(eventType, (evt) => {
if (eventType.startsWith('mouse')) {
if (evt.button !== 0) return;
} else {
if (evt.changedTouches.length !== 1) return;
}
if (R.tracking) {
if (eventType.startsWith('mouse')) {
evt.preventDefault();
}
evt.stopPropagation();
let delta = 0;
if (eventType.startsWith('mouse')) {
delta = R.screenX - evt.screenX;
} else {
delta = R.screenX - evt.changedTouches[0].screenX;
}
const leftColWidth = Math.max(Math.min(R.leftColStartWidth - delta, R.parent.offsetWidth - R.parent.minRightColWidth - PAD), R.parent.minLeftColWidth);
setLeftColGridTemplate(R.parent, leftColWidth);
}
});
});
['mouseup', 'touchend'].forEach((eventType) => {
window.addEventListener(eventType, (evt) => {
if (eventType.startsWith('mouse')) {
if (evt.button !== 0) return;
} else {
if (evt.changedTouches.length !== 1) return;
}
if (R.tracking) {
evt.preventDefault();
evt.stopPropagation();
R.tracking = false;
document.body.classList.remove('resizing');
}
});
});
window.addEventListener('resize', () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
for (const parent of parents) {
afterResize(parent);
}
}, DEBOUNCE_TIME);
});
setupResizeHandle = setup;
})();
function setupAllResizeHandles() {
for (var elem of gradioApp().querySelectorAll('.resize-handle-row')) {
if (!elem.querySelector('.resize-handle') && !elem.children[0].classList.contains("hidden")) {
setupResizeHandle(elem);
}
}
}
onUiLoaded(setupAllResizeHandles);

71
javascript/settings.js Normal file
View File

@ -0,0 +1,71 @@
let settingsExcludeTabsFromShowAll = {
settings_tab_defaults: 1,
settings_tab_sysinfo: 1,
settings_tab_actions: 1,
settings_tab_licenses: 1,
};
function settingsShowAllTabs() {
gradioApp().querySelectorAll('#settings > div').forEach(function(elem) {
if (settingsExcludeTabsFromShowAll[elem.id]) return;
elem.style.display = "block";
});
}
function settingsShowOneTab() {
gradioApp().querySelector('#settings_show_one_page').click();
}
onUiLoaded(function() {
var edit = gradioApp().querySelector('#settings_search');
var editTextarea = gradioApp().querySelector('#settings_search > label > input');
var buttonShowAllPages = gradioApp().getElementById('settings_show_all_pages');
var settings_tabs = gradioApp().querySelector('#settings div');
onEdit('settingsSearch', editTextarea, 250, function() {
var searchText = (editTextarea.value || "").trim().toLowerCase();
gradioApp().querySelectorAll('#settings > div[id^=settings_] div[id^=column_settings_] > *').forEach(function(elem) {
var visible = elem.textContent.trim().toLowerCase().indexOf(searchText) != -1;
elem.style.display = visible ? "" : "none";
});
if (searchText != "") {
settingsShowAllTabs();
} else {
settingsShowOneTab();
}
});
settings_tabs.insertBefore(edit, settings_tabs.firstChild);
settings_tabs.appendChild(buttonShowAllPages);
buttonShowAllPages.addEventListener("click", settingsShowAllTabs);
});
onOptionsChanged(function() {
if (gradioApp().querySelector('#settings .settings-category')) return;
var sectionMap = {};
gradioApp().querySelectorAll('#settings > div > button').forEach(function(x) {
sectionMap[x.textContent.trim()] = x;
});
opts._categories.forEach(function(x) {
var section = localization[x[0]] ?? x[0];
var category = localization[x[1]] ?? x[1];
var span = document.createElement('SPAN');
span.textContent = category;
span.className = 'settings-category';
var sectionElem = sectionMap[section];
if (!sectionElem) return;
sectionElem.parentElement.insertBefore(span, sectionElem);
});
});

View File

@ -1,10 +1,9 @@
let promptTokenCountDebounceTime = 800;
let promptTokenCountTimeouts = {};
var promptTokenCountUpdateFunctions = {};
let promptTokenCountUpdateFunctions = {};
function update_txt2img_tokens(...args) {
// Called from Gradio
update_token_counter("txt2img_token_button");
update_token_counter("txt2img_negative_token_button");
if (args.length == 2) {
return args[0];
}
@ -14,6 +13,7 @@ function update_txt2img_tokens(...args) {
function update_img2img_tokens(...args) {
// Called from Gradio
update_token_counter("img2img_token_button");
update_token_counter("img2img_negative_token_button");
if (args.length == 2) {
return args[0];
}
@ -21,16 +21,7 @@ function update_img2img_tokens(...args) {
}
function update_token_counter(button_id) {
if (opts.disable_token_counters) {
return;
}
if (promptTokenCountTimeouts[button_id]) {
clearTimeout(promptTokenCountTimeouts[button_id]);
}
promptTokenCountTimeouts[button_id] = setTimeout(
() => gradioApp().getElementById(button_id)?.click(),
promptTokenCountDebounceTime,
);
promptTokenCountUpdateFunctions[button_id]?.();
}
@ -57,11 +48,6 @@ function setupTokenCounting(id, id_counter, id_button) {
var counter = gradioApp().getElementById(id_counter);
var textarea = gradioApp().querySelector(`#${id} > label > textarea`);
if (opts.disable_token_counters) {
counter.style.display = "none";
return;
}
if (counter.parentElement == prompt.parentElement) {
return;
}
@ -69,15 +55,33 @@ function setupTokenCounting(id, id_counter, id_button) {
prompt.parentElement.insertBefore(counter, prompt);
prompt.parentElement.style.position = "relative";
promptTokenCountUpdateFunctions[id] = function() {
update_token_counter(id_button);
};
textarea.addEventListener("input", promptTokenCountUpdateFunctions[id]);
var func = onEdit(id, textarea, 800, function() {
if (counter.classList.contains("token-counter-visible")) {
gradioApp().getElementById(id_button)?.click();
}
});
promptTokenCountUpdateFunctions[id] = func;
promptTokenCountUpdateFunctions[id_button] = func;
}
function setupTokenCounters() {
setupTokenCounting('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button');
setupTokenCounting('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button');
setupTokenCounting('img2img_prompt', 'img2img_token_counter', 'img2img_token_button');
setupTokenCounting('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button');
function toggleTokenCountingVisibility(id, id_counter, id_button) {
var counter = gradioApp().getElementById(id_counter);
counter.style.display = opts.disable_token_counters ? "none" : "block";
counter.classList.toggle("token-counter-visible", !opts.disable_token_counters);
}
function runCodeForTokenCounters(fun) {
fun('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button');
fun('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button');
fun('img2img_prompt', 'img2img_token_counter', 'img2img_token_button');
fun('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button');
}
onUiLoaded(function() {
runCodeForTokenCounters(setupTokenCounting);
});
onOptionsChanged(function() {
runCodeForTokenCounters(toggleTokenCountingVisibility);
});

View File

@ -19,28 +19,19 @@ function all_gallery_buttons() {
}
function selected_gallery_button() {
var allCurrentButtons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery].gradio-gallery .thumbnail-item.thumbnail-small.selected');
var visibleCurrentButton = null;
allCurrentButtons.forEach(function(elem) {
if (elem.parentElement.offsetParent) {
visibleCurrentButton = elem;
}
});
return visibleCurrentButton;
return all_gallery_buttons().find(elem => elem.classList.contains('selected')) ?? null;
}
function selected_gallery_index() {
var buttons = all_gallery_buttons();
var button = selected_gallery_button();
return all_gallery_buttons().findIndex(elem => elem.classList.contains('selected'));
}
var result = -1;
buttons.forEach(function(v, i) {
if (v == button) {
result = i;
}
});
function gallery_container_buttons(gallery_container) {
return gradioApp().querySelectorAll(`#${gallery_container} .thumbnail-item.thumbnail-small`);
}
return result;
function selected_gallery_index_id(gallery_container) {
return Array.from(gallery_container_buttons(gallery_container)).findIndex(elem => elem.classList.contains('selected'));
}
function extract_image_from_gallery(gallery) {
@ -136,27 +127,35 @@ function create_submit_args(args) {
return res;
}
function setSubmitButtonsVisibility(tabname, showInterrupt, showSkip, showInterrupting) {
gradioApp().getElementById(tabname + '_interrupt').style.display = showInterrupt ? "block" : "none";
gradioApp().getElementById(tabname + '_skip').style.display = showSkip ? "block" : "none";
gradioApp().getElementById(tabname + '_interrupting').style.display = showInterrupting ? "block" : "none";
}
function showSubmitButtons(tabname, show) {
gradioApp().getElementById(tabname + '_interrupt').style.display = show ? "none" : "block";
gradioApp().getElementById(tabname + '_skip').style.display = show ? "none" : "block";
setSubmitButtonsVisibility(tabname, !show, !show, false);
}
function showSubmitInterruptingPlaceholder(tabname) {
setSubmitButtonsVisibility(tabname, false, true, true);
}
function showRestoreProgressButton(tabname, show) {
var button = gradioApp().getElementById(tabname + "_restore_progress");
if (!button) return;
button.style.display = show ? "flex" : "none";
button.style.setProperty('display', show ? 'flex' : 'none', 'important');
}
function submit() {
showSubmitButtons('txt2img', false);
var id = randomId();
localStorage.setItem("txt2img_task_id", id);
localSet("txt2img_task_id", id);
requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() {
showSubmitButtons('txt2img', true);
localStorage.removeItem("txt2img_task_id");
localRemove("txt2img_task_id");
showRestoreProgressButton('txt2img', false);
});
@ -167,15 +166,23 @@ function submit() {
return res;
}
function submit_txt2img_upscale() {
var res = submit(...arguments);
res[2] = selected_gallery_index();
return res;
}
function submit_img2img() {
showSubmitButtons('img2img', false);
var id = randomId();
localStorage.setItem("img2img_task_id", id);
localSet("img2img_task_id", id);
requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() {
showSubmitButtons('img2img', true);
localStorage.removeItem("img2img_task_id");
localRemove("img2img_task_id");
showRestoreProgressButton('img2img', false);
});
@ -187,13 +194,29 @@ function submit_img2img() {
return res;
}
function submit_extras() {
showSubmitButtons('extras', false);
var id = randomId();
requestProgress(id, gradioApp().getElementById('extras_gallery_container'), gradioApp().getElementById('extras_gallery'), function() {
showSubmitButtons('extras', true);
});
var res = create_submit_args(arguments);
res[0] = id;
console.log(res);
return res;
}
function restoreProgressTxt2img() {
showRestoreProgressButton("txt2img", false);
var id = localStorage.getItem("txt2img_task_id");
id = localStorage.getItem("txt2img_task_id");
var id = localGet("txt2img_task_id");
if (id) {
showSubmitInterruptingPlaceholder('txt2img');
requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() {
showSubmitButtons('txt2img', true);
}, null, 0);
@ -205,9 +228,10 @@ function restoreProgressTxt2img() {
function restoreProgressImg2img() {
showRestoreProgressButton("img2img", false);
var id = localStorage.getItem("img2img_task_id");
var id = localGet("img2img_task_id");
if (id) {
showSubmitInterruptingPlaceholder('img2img');
requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() {
showSubmitButtons('img2img', true);
}, null, 0);
@ -217,9 +241,33 @@ function restoreProgressImg2img() {
}
/**
* Configure the width and height elements on `tabname` to accept
* pasting of resolutions in the form of "width x height".
*/
function setupResolutionPasting(tabname) {
var width = gradioApp().querySelector(`#${tabname}_width input[type=number]`);
var height = gradioApp().querySelector(`#${tabname}_height input[type=number]`);
for (const el of [width, height]) {
el.addEventListener('paste', function(event) {
var pasteData = event.clipboardData.getData('text/plain');
var parsed = pasteData.match(/^\s*(\d+)\D+(\d+)\s*$/);
if (parsed) {
width.value = parsed[1];
height.value = parsed[2];
updateInput(width);
updateInput(height);
event.preventDefault();
}
});
}
}
onUiLoaded(function() {
showRestoreProgressButton('txt2img', localStorage.getItem("txt2img_task_id"));
showRestoreProgressButton('img2img', localStorage.getItem("img2img_task_id"));
showRestoreProgressButton('txt2img', localGet("txt2img_task_id"));
showRestoreProgressButton('img2img', localGet("img2img_task_id"));
setupResolutionPasting('txt2img');
setupResolutionPasting('img2img');
});
@ -259,6 +307,7 @@ onAfterUiUpdate(function() {
var jsdata = textarea.value;
opts = JSON.parse(jsdata);
executeCallbacks(optionsAvailableCallbacks); /*global optionsAvailableCallbacks*/
executeCallbacks(optionsChangedCallbacks); /*global optionsChangedCallbacks*/
Object.defineProperty(textarea, 'value', {
@ -280,23 +329,6 @@ onAfterUiUpdate(function() {
});
json_elem.parentElement.style.display = "none";
setupTokenCounters();
var show_all_pages = gradioApp().getElementById('settings_show_all_pages');
var settings_tabs = gradioApp().querySelector('#settings div');
if (show_all_pages && settings_tabs) {
settings_tabs.appendChild(show_all_pages);
show_all_pages.onclick = function() {
gradioApp().querySelectorAll('#settings > div').forEach(function(elem) {
if (elem.id == "settings_tab_licenses") {
return;
}
elem.style.display = "block";
});
};
}
});
onOptionsChanged(function() {
@ -314,8 +346,8 @@ onOptionsChanged(function() {
let txt2img_textarea, img2img_textarea = undefined;
function restart_reload() {
document.body.style.backgroundColor = "var(--background-fill-primary)";
document.body.innerHTML = '<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>';
var requestPing = function() {
requestGet("./internal/ping", {}, function(data) {
location.reload();
@ -385,3 +417,20 @@ function switchWidthHeight(tabname) {
updateInput(height);
return [];
}
var onEditTimers = {};
// calls func after afterMs milliseconds has passed since the input elem has been edited by user
function onEdit(editId, elem, afterMs, func) {
var edited = function() {
var existingTimer = onEditTimers[editId];
if (existingTimer) clearTimeout(existingTimer);
onEditTimers[editId] = setTimeout(func, afterMs);
};
elem.addEventListener("input", edited);
return edited;
}

View File

@ -1,6 +1,5 @@
from modules import launch_utils
args = launch_utils.args
python = launch_utils.python
git = launch_utils.git
@ -26,8 +25,18 @@ start = launch_utils.start
def main():
if not args.skip_prepare_environment:
prepare_environment()
if args.dump_sysinfo:
filename = launch_utils.dump_sysinfo()
print(f"Sysinfo saved as {filename}. Exiting...")
exit(0)
launch_utils.startup_timer.record("initial startup")
with launch_utils.startup_timer.subcategory("prepare environment"):
if not args.skip_prepare_environment:
prepare_environment()
if args.test_server:
configure_for_tests()

View File

@ -4,6 +4,8 @@ import os
import time
import datetime
import uvicorn
import ipaddress
import requests
import gradio as gr
from threading import Lock
from io import BytesIO
@ -15,24 +17,21 @@ from fastapi.encoders import jsonable_encoder
from secrets import compare_digest
import modules.shared as shared
from modules import sd_samplers, deepbooru, sd_hijack, images, scripts, ui, postprocessing, errors, restart
from modules import sd_samplers, deepbooru, sd_hijack, images, scripts, ui, postprocessing, errors, restart, shared_items, script_callbacks, infotext_utils, sd_models, sd_schedulers
from modules.api import models
from modules.shared import opts
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
from modules.textual_inversion.textual_inversion import create_embedding, train_embedding
from modules.textual_inversion.preprocess import preprocess
from modules.hypernetworks.hypernetwork import create_hypernetwork, train_hypernetwork
from PIL import PngImagePlugin,Image
from modules.sd_models import checkpoints_list, unload_model_weights, reload_model_weights, checkpoint_aliases
from modules.sd_vae import vae_dict
from PIL import PngImagePlugin
from modules.sd_models_config import find_checkpoint_config_near_filename
from modules.realesrgan_model import get_realesrgan_models
from modules import devices
from typing import Dict, List, Any
from typing import Any
import piexif
import piexif.helper
from contextlib import closing
from modules.progress import create_task_id, add_task_to_queue, start_task, finish_task, current_task
def script_name_to_index(name, scripts):
try:
@ -44,7 +43,7 @@ def script_name_to_index(name, scripts):
def validate_sampler_name(name):
config = sd_samplers.all_samplers_map.get(name, None)
if config is None:
raise HTTPException(status_code=404, detail="Sampler not found")
raise HTTPException(status_code=400, detail="Sampler not found")
return name
@ -56,11 +55,45 @@ def setUpscalers(req: dict):
return reqDict
def verify_url(url):
"""Returns True if the url refers to a global resource."""
import socket
from urllib.parse import urlparse
try:
parsed_url = urlparse(url)
domain_name = parsed_url.netloc
host = socket.gethostbyname_ex(domain_name)
for ip in host[2]:
ip_addr = ipaddress.ip_address(ip)
if not ip_addr.is_global:
return False
except Exception:
return False
return True
def decode_base64_to_image(encoding):
if encoding.startswith("http://") or encoding.startswith("https://"):
if not opts.api_enable_requests:
raise HTTPException(status_code=500, detail="Requests not allowed")
if opts.api_forbid_local_requests and not verify_url(encoding):
raise HTTPException(status_code=500, detail="Request to local resource not allowed")
headers = {'user-agent': opts.api_useragent} if opts.api_useragent else {}
response = requests.get(encoding, timeout=30, headers=headers)
try:
image = images.read(BytesIO(response.content))
return image
except Exception as e:
raise HTTPException(status_code=500, detail="Invalid image url") from e
if encoding.startswith("data:image/"):
encoding = encoding.split(";")[1].split(",")[1]
try:
image = Image.open(BytesIO(base64.b64decode(encoding)))
image = images.read(BytesIO(base64.b64decode(encoding)))
return image
except Exception as e:
raise HTTPException(status_code=500, detail="Invalid encoded image") from e
@ -68,7 +101,8 @@ def decode_base64_to_image(encoding):
def encode_pil_to_base64(image):
with io.BytesIO() as output_bytes:
if isinstance(image, str):
return image
if opts.samples_format.lower() == 'png':
use_metadata = False
metadata = PngImagePlugin.PngInfo()
@ -79,7 +113,7 @@ def encode_pil_to_base64(image):
image.save(output_bytes, format="PNG", pnginfo=(metadata if use_metadata else None), quality=opts.jpeg_quality)
elif opts.samples_format.lower() in ("jpg", "jpeg", "webp"):
if image.mode == "RGBA":
if image.mode in ("RGBA", "P"):
image = image.convert("RGB")
parameters = image.info.get('parameters', None)
exif_bytes = piexif.dump({
@ -186,27 +220,30 @@ class Api:
self.add_api_route("/sdapi/v1/options", self.get_config, methods=["GET"], response_model=models.OptionsModel)
self.add_api_route("/sdapi/v1/options", self.set_config, methods=["POST"])
self.add_api_route("/sdapi/v1/cmd-flags", self.get_cmd_flags, methods=["GET"], response_model=models.FlagsModel)
self.add_api_route("/sdapi/v1/samplers", self.get_samplers, methods=["GET"], response_model=List[models.SamplerItem])
self.add_api_route("/sdapi/v1/upscalers", self.get_upscalers, methods=["GET"], response_model=List[models.UpscalerItem])
self.add_api_route("/sdapi/v1/latent-upscale-modes", self.get_latent_upscale_modes, methods=["GET"], response_model=List[models.LatentUpscalerModeItem])
self.add_api_route("/sdapi/v1/sd-models", self.get_sd_models, methods=["GET"], response_model=List[models.SDModelItem])
self.add_api_route("/sdapi/v1/sd-vae", self.get_sd_vaes, methods=["GET"], response_model=List[models.SDVaeItem])
self.add_api_route("/sdapi/v1/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=List[models.HypernetworkItem])
self.add_api_route("/sdapi/v1/face-restorers", self.get_face_restorers, methods=["GET"], response_model=List[models.FaceRestorerItem])
self.add_api_route("/sdapi/v1/realesrgan-models", self.get_realesrgan_models, methods=["GET"], response_model=List[models.RealesrganItem])
self.add_api_route("/sdapi/v1/prompt-styles", self.get_prompt_styles, methods=["GET"], response_model=List[models.PromptStyleItem])
self.add_api_route("/sdapi/v1/samplers", self.get_samplers, methods=["GET"], response_model=list[models.SamplerItem])
self.add_api_route("/sdapi/v1/schedulers", self.get_schedulers, methods=["GET"], response_model=list[models.SchedulerItem])
self.add_api_route("/sdapi/v1/upscalers", self.get_upscalers, methods=["GET"], response_model=list[models.UpscalerItem])
self.add_api_route("/sdapi/v1/latent-upscale-modes", self.get_latent_upscale_modes, methods=["GET"], response_model=list[models.LatentUpscalerModeItem])
self.add_api_route("/sdapi/v1/sd-models", self.get_sd_models, methods=["GET"], response_model=list[models.SDModelItem])
self.add_api_route("/sdapi/v1/sd-vae", self.get_sd_vaes, methods=["GET"], response_model=list[models.SDVaeItem])
self.add_api_route("/sdapi/v1/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=list[models.HypernetworkItem])
self.add_api_route("/sdapi/v1/face-restorers", self.get_face_restorers, methods=["GET"], response_model=list[models.FaceRestorerItem])
self.add_api_route("/sdapi/v1/realesrgan-models", self.get_realesrgan_models, methods=["GET"], response_model=list[models.RealesrganItem])
self.add_api_route("/sdapi/v1/prompt-styles", self.get_prompt_styles, methods=["GET"], response_model=list[models.PromptStyleItem])
self.add_api_route("/sdapi/v1/embeddings", self.get_embeddings, methods=["GET"], response_model=models.EmbeddingsResponse)
self.add_api_route("/sdapi/v1/refresh-embeddings", self.refresh_embeddings, methods=["POST"])
self.add_api_route("/sdapi/v1/refresh-checkpoints", self.refresh_checkpoints, methods=["POST"])
self.add_api_route("/sdapi/v1/refresh-vae", self.refresh_vae, methods=["POST"])
self.add_api_route("/sdapi/v1/create/embedding", self.create_embedding, methods=["POST"], response_model=models.CreateResponse)
self.add_api_route("/sdapi/v1/create/hypernetwork", self.create_hypernetwork, methods=["POST"], response_model=models.CreateResponse)
self.add_api_route("/sdapi/v1/preprocess", self.preprocess, methods=["POST"], response_model=models.PreprocessResponse)
self.add_api_route("/sdapi/v1/train/embedding", self.train_embedding, methods=["POST"], response_model=models.TrainResponse)
self.add_api_route("/sdapi/v1/train/hypernetwork", self.train_hypernetwork, methods=["POST"], response_model=models.TrainResponse)
self.add_api_route("/sdapi/v1/memory", self.get_memory, methods=["GET"], response_model=models.MemoryResponse)
self.add_api_route("/sdapi/v1/unload-checkpoint", self.unloadapi, methods=["POST"])
self.add_api_route("/sdapi/v1/reload-checkpoint", self.reloadapi, methods=["POST"])
self.add_api_route("/sdapi/v1/scripts", self.get_scripts_list, methods=["GET"], response_model=models.ScriptsList)
self.add_api_route("/sdapi/v1/script-info", self.get_script_info, methods=["GET"], response_model=List[models.ScriptInfo])
self.add_api_route("/sdapi/v1/script-info", self.get_script_info, methods=["GET"], response_model=list[models.ScriptInfo])
self.add_api_route("/sdapi/v1/extensions", self.get_extensions_list, methods=["GET"], response_model=list[models.ExtensionItem])
if shared.cmd_opts.api_server_stop:
self.add_api_route("/sdapi/v1/server-kill", self.kill_webui, methods=["POST"])
@ -216,6 +253,24 @@ class Api:
self.default_script_arg_txt2img = []
self.default_script_arg_img2img = []
txt2img_script_runner = scripts.scripts_txt2img
img2img_script_runner = scripts.scripts_img2img
if not txt2img_script_runner.scripts or not img2img_script_runner.scripts:
ui.create_ui()
if not txt2img_script_runner.scripts:
txt2img_script_runner.initialize_scripts(False)
if not self.default_script_arg_txt2img:
self.default_script_arg_txt2img = self.init_default_script_args(txt2img_script_runner)
if not img2img_script_runner.scripts:
img2img_script_runner.initialize_scripts(True)
if not self.default_script_arg_img2img:
self.default_script_arg_img2img = self.init_default_script_args(img2img_script_runner)
def add_api_route(self, path: str, endpoint, **kwargs):
if shared.cmd_opts.api_auth:
return self.app.add_api_route(path, endpoint, dependencies=[Depends(self.auth)], **kwargs)
@ -277,8 +332,13 @@ class Api:
script_args[script.args_from:script.args_to] = ui_default_values
return script_args
def init_script_args(self, request, default_script_args, selectable_scripts, selectable_idx, script_runner):
def init_script_args(self, request, default_script_args, selectable_scripts, selectable_idx, script_runner, *, input_script_args=None):
script_args = default_script_args.copy()
if input_script_args is not None:
for index, value in input_script_args.items():
script_args[index] = value
# position 0 in script_arg is the idx+1 of the selectable script that is going to be run when using scripts.scripts_*2img.run()
if selectable_scripts:
script_args[selectable_scripts.args_from:selectable_scripts.args_to] = request.script_args
@ -300,55 +360,138 @@ class Api:
script_args[alwayson_script.args_from + idx] = request.alwayson_scripts[alwayson_script_name]["args"][idx]
return script_args
def apply_infotext(self, request, tabname, *, script_runner=None, mentioned_script_args=None):
"""Processes `infotext` field from the `request`, and sets other fields of the `request` according to what's in infotext.
If request already has a field set, and that field is encountered in infotext too, the value from infotext is ignored.
Additionally, fills `mentioned_script_args` dict with index: value pairs for script arguments read from infotext.
"""
if not request.infotext:
return {}
possible_fields = infotext_utils.paste_fields[tabname]["fields"]
set_fields = request.model_dump(exclude_unset=True) if hasattr(request, "request") else request.dict(exclude_unset=True) # pydantic v1/v2 have different names for this
params = infotext_utils.parse_generation_parameters(request.infotext)
def get_field_value(field, params):
value = field.function(params) if field.function else params.get(field.label)
if value is None:
return None
if field.api in request.__fields__:
target_type = request.__fields__[field.api].type_
else:
target_type = type(field.component.value)
if target_type == type(None):
return None
if isinstance(value, dict) and value.get('__type__') == 'generic_update': # this is a gradio.update rather than a value
value = value.get('value')
if value is not None and not isinstance(value, target_type):
value = target_type(value)
return value
for field in possible_fields:
if not field.api:
continue
if field.api in set_fields:
continue
value = get_field_value(field, params)
if value is not None:
setattr(request, field.api, value)
if request.override_settings is None:
request.override_settings = {}
overridden_settings = infotext_utils.get_override_settings(params)
for _, setting_name, value in overridden_settings:
if setting_name not in request.override_settings:
request.override_settings[setting_name] = value
if script_runner is not None and mentioned_script_args is not None:
indexes = {v: i for i, v in enumerate(script_runner.inputs)}
script_fields = ((field, indexes[field.component]) for field in possible_fields if field.component in indexes)
for field, index in script_fields:
value = get_field_value(field, params)
if value is None:
continue
mentioned_script_args[index] = value
return params
def text2imgapi(self, txt2imgreq: models.StableDiffusionTxt2ImgProcessingAPI):
task_id = txt2imgreq.force_task_id or create_task_id("txt2img")
script_runner = scripts.scripts_txt2img
if not script_runner.scripts:
script_runner.initialize_scripts(False)
ui.create_ui()
if not self.default_script_arg_txt2img:
self.default_script_arg_txt2img = self.init_default_script_args(script_runner)
infotext_script_args = {}
self.apply_infotext(txt2imgreq, "txt2img", script_runner=script_runner, mentioned_script_args=infotext_script_args)
selectable_scripts, selectable_script_idx = self.get_selectable_script(txt2imgreq.script_name, script_runner)
sampler, scheduler = sd_samplers.get_sampler_and_scheduler(txt2imgreq.sampler_name or txt2imgreq.sampler_index, txt2imgreq.scheduler)
populate = txt2imgreq.copy(update={ # Override __init__ params
"sampler_name": validate_sampler_name(txt2imgreq.sampler_name or txt2imgreq.sampler_index),
"sampler_name": validate_sampler_name(sampler),
"do_not_save_samples": not txt2imgreq.save_images,
"do_not_save_grid": not txt2imgreq.save_images,
})
if populate.sampler_name:
populate.sampler_index = None # prevent a warning later on
if not populate.scheduler and scheduler != "Automatic":
populate.scheduler = scheduler
args = vars(populate)
args.pop('script_name', None)
args.pop('script_args', None) # will refeed them to the pipeline directly after initializing them
args.pop('alwayson_scripts', None)
args.pop('infotext', None)
script_args = self.init_script_args(txt2imgreq, self.default_script_arg_txt2img, selectable_scripts, selectable_script_idx, script_runner)
script_args = self.init_script_args(txt2imgreq, self.default_script_arg_txt2img, selectable_scripts, selectable_script_idx, script_runner, input_script_args=infotext_script_args)
send_images = args.pop('send_images', True)
args.pop('save_images', None)
add_task_to_queue(task_id)
with self.queue_lock:
with closing(StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **args)) as p:
p.is_api = True
p.scripts = script_runner
p.outpath_grids = opts.outdir_txt2img_grids
p.outpath_samples = opts.outdir_txt2img_samples
try:
shared.state.begin(job="scripts_txt2img")
start_task(task_id)
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)
finish_task(task_id)
finally:
shared.state.end()
shared.total_tqdm.clear()
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
return models.TextToImageResponse(images=b64images, parameters=vars(txt2imgreq), info=processed.js())
def img2imgapi(self, img2imgreq: models.StableDiffusionImg2ImgProcessingAPI):
task_id = img2imgreq.force_task_id or create_task_id("img2img")
init_images = img2imgreq.init_images
if init_images is None:
raise HTTPException(status_code=404, detail="Init image not found")
@ -358,15 +501,15 @@ class Api:
mask = decode_base64_to_image(mask)
script_runner = scripts.scripts_img2img
if not script_runner.scripts:
script_runner.initialize_scripts(True)
ui.create_ui()
if not self.default_script_arg_img2img:
self.default_script_arg_img2img = self.init_default_script_args(script_runner)
infotext_script_args = {}
self.apply_infotext(img2imgreq, "img2img", script_runner=script_runner, mentioned_script_args=infotext_script_args)
selectable_scripts, selectable_script_idx = self.get_selectable_script(img2imgreq.script_name, script_runner)
sampler, scheduler = sd_samplers.get_sampler_and_scheduler(img2imgreq.sampler_name or img2imgreq.sampler_index, img2imgreq.scheduler)
populate = img2imgreq.copy(update={ # Override __init__ params
"sampler_name": validate_sampler_name(img2imgreq.sampler_name or img2imgreq.sampler_index),
"sampler_name": validate_sampler_name(sampler),
"do_not_save_samples": not img2imgreq.save_images,
"do_not_save_grid": not img2imgreq.save_images,
"mask": mask,
@ -374,34 +517,44 @@ class Api:
if populate.sampler_name:
populate.sampler_index = None # prevent a warning later on
if not populate.scheduler and scheduler != "Automatic":
populate.scheduler = scheduler
args = vars(populate)
args.pop('include_init_images', None) # this is meant to be done by "exclude": True in model, but it's for a reason that I cannot determine.
args.pop('script_name', None)
args.pop('script_args', None) # will refeed them to the pipeline directly after initializing them
args.pop('alwayson_scripts', None)
args.pop('infotext', None)
script_args = self.init_script_args(img2imgreq, self.default_script_arg_img2img, selectable_scripts, selectable_script_idx, script_runner)
script_args = self.init_script_args(img2imgreq, self.default_script_arg_img2img, selectable_scripts, selectable_script_idx, script_runner, input_script_args=infotext_script_args)
send_images = args.pop('send_images', True)
args.pop('save_images', None)
add_task_to_queue(task_id)
with self.queue_lock:
with closing(StableDiffusionProcessingImg2Img(sd_model=shared.sd_model, **args)) as p:
p.init_images = [decode_base64_to_image(x) for x in init_images]
p.is_api = True
p.scripts = script_runner
p.outpath_grids = opts.outdir_img2img_grids
p.outpath_samples = opts.outdir_img2img_samples
try:
shared.state.begin(job="scripts_img2img")
start_task(task_id)
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)
finish_task(task_id)
finally:
shared.state.end()
shared.total_tqdm.clear()
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
@ -433,9 +586,6 @@ class Api:
return models.ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1])
def pnginfoapi(self, req: models.PNGInfoRequest):
if(not req.image.strip()):
return models.PNGInfoResponse(info="")
image = decode_base64_to_image(req.image.strip())
if image is None:
return models.PNGInfoResponse(info="")
@ -444,9 +594,10 @@ class Api:
if geninfo is None:
geninfo = ""
items = {**{'parameters': geninfo}, **items}
params = infotext_utils.parse_generation_parameters(geninfo)
script_callbacks.infotext_pasted_callback(geninfo, params)
return models.PNGInfoResponse(info=geninfo, items=items)
return models.PNGInfoResponse(info=geninfo, items=items, parameters=params)
def progressapi(self, req: models.ProgressRequest = Depends()):
# copy from check_progress_call of ui.py
@ -474,7 +625,7 @@ class Api:
if shared.state.current_image and not req.skip_current_image:
current_image = encode_pil_to_base64(shared.state.current_image)
return models.ProgressResponse(progress=progress, eta_relative=eta_relative, state=shared.state.dict(), current_image=current_image, textinfo=shared.state.textinfo)
return models.ProgressResponse(progress=progress, eta_relative=eta_relative, state=shared.state.dict(), current_image=current_image, textinfo=shared.state.textinfo, current_task=current_task)
def interrogateapi(self, interrogatereq: models.InterrogateRequest):
image_b64 = interrogatereq.image
@ -501,12 +652,12 @@ class Api:
return {}
def unloadapi(self):
unload_model_weights()
sd_models.unload_model_weights()
return {}
def reloadapi(self):
reload_model_weights()
sd_models.send_model_to_device(shared.sd_model)
return {}
@ -524,13 +675,13 @@ class Api:
return options
def set_config(self, req: Dict[str, Any]):
def set_config(self, req: dict[str, Any]):
checkpoint_name = req.get("sd_model_checkpoint", None)
if checkpoint_name is not None and checkpoint_name not in checkpoint_aliases:
if checkpoint_name is not None and checkpoint_name not in sd_models.checkpoint_aliases:
raise RuntimeError(f"model {checkpoint_name!r} not found")
for k, v in req.items():
shared.opts.set(k, v)
shared.opts.set(k, v, is_api=True)
shared.opts.save(shared.config_filename)
return
@ -541,6 +692,17 @@ class Api:
def get_samplers(self):
return [{"name": sampler[0], "aliases":sampler[2], "options":sampler[3]} for sampler in sd_samplers.all_samplers]
def get_schedulers(self):
return [
{
"name": scheduler.name,
"label": scheduler.label,
"aliases": scheduler.aliases,
"default_rho": scheduler.default_rho,
"need_inner_model": scheduler.need_inner_model,
}
for scheduler in sd_schedulers.schedulers]
def get_upscalers(self):
return [
{
@ -562,10 +724,12 @@ class Api:
]
def get_sd_models(self):
return [{"title": x.title, "model_name": x.model_name, "hash": x.shorthash, "sha256": x.sha256, "filename": x.filename, "config": find_checkpoint_config_near_filename(x)} for x in checkpoints_list.values()]
import modules.sd_models as sd_models
return [{"title": x.title, "model_name": x.model_name, "hash": x.shorthash, "sha256": x.sha256, "filename": x.filename, "config": find_checkpoint_config_near_filename(x)} for x in sd_models.checkpoints_list.values()]
def get_sd_vaes(self):
return [{"model_name": x, "filename": vae_dict[x]} for x in vae_dict.keys()]
import modules.sd_vae as sd_vae
return [{"model_name": x, "filename": sd_vae.vae_dict[x]} for x in sd_vae.vae_dict.keys()]
def get_hypernetworks(self):
return [{"name": name, "path": shared.hypernetworks[name]} for name in shared.hypernetworks]
@ -604,10 +768,18 @@ class Api:
"skipped": convert_embeddings(db.skipped_embeddings),
}
def refresh_embeddings(self):
with self.queue_lock:
sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings(force_reload=True)
def refresh_checkpoints(self):
with self.queue_lock:
shared.refresh_checkpoints()
def refresh_vae(self):
with self.queue_lock:
shared_items.refresh_vae_list()
def create_embedding(self, args: dict):
try:
shared.state.begin(job="create_embedding")
@ -630,19 +802,6 @@ class Api:
finally:
shared.state.end()
def preprocess(self, args: dict):
try:
shared.state.begin(job="preprocess")
preprocess(**args) # quick operation unless blip/booru interrogation is enabled
shared.state.end()
return models.PreprocessResponse(info='preprocess complete')
except KeyError as e:
return models.PreprocessResponse(info=f"preprocess error: invalid token: {e}")
except Exception as e:
return models.PreprocessResponse(info=f"preprocess error: {e}")
finally:
shared.state.end()
def train_embedding(self, args: dict):
try:
shared.state.begin(job="train_embedding")
@ -724,9 +883,36 @@ class Api:
cuda = {'error': f'{err}'}
return models.MemoryResponse(ram=ram, cuda=cuda)
def get_extensions_list(self):
from modules import extensions
extensions.list_extensions()
ext_list = []
for ext in extensions.extensions:
ext: extensions.Extension
ext.read_info_from_repo()
if ext.remote is not None:
ext_list.append({
"name": ext.name,
"remote": ext.remote,
"branch": ext.branch,
"commit_hash":ext.commit_hash,
"commit_date":ext.commit_date,
"version":ext.version,
"enabled":ext.enabled
})
return ext_list
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, root_path=root_path)
uvicorn.run(
self.app,
host=server_name,
port=port,
timeout_keep_alive=shared.cmd_opts.timeout_keep_alive,
root_path=root_path,
ssl_keyfile=shared.cmd_opts.tls_keyfile,
ssl_certfile=shared.cmd_opts.tls_certfile
)
def kill_webui(self):
restart.stop_program()

View File

@ -1,12 +1,10 @@
import inspect
from pydantic import BaseModel, Field, create_model
from typing import Any, Optional
from typing_extensions import Literal
from typing import Any, Optional, Literal
from inflection import underscore
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img
from modules.shared import sd_upscalers, opts, parser
from typing import Dict, List
API_NOT_ALLOWED = [
"self",
@ -50,10 +48,12 @@ class PydanticModelGenerator:
additional_fields = None,
):
def field_type_generator(k, v):
# field_type = str if not overrides.get(k) else overrides[k]["type"]
# print(k, v.annotation, v.default)
field_type = v.annotation
if field_type == 'Image':
# images are sent as base64 strings via API
field_type = 'str'
return Optional[field_type]
def merge_class_params(class_):
@ -63,7 +63,6 @@ class PydanticModelGenerator:
parameters = {**parameters, **inspect.signature(classes.__init__).parameters}
return parameters
self._model_name = model_name
self._class_data = merge_class_params(class_instance)
@ -72,7 +71,7 @@ class PydanticModelGenerator:
field=underscore(k),
field_alias=k,
field_type=field_type_generator(k, v),
field_value=v.default
field_value=None if isinstance(v.default, property) else v.default
)
for (k,v) in self._class_data.items() if k not in API_NOT_ALLOWED
]
@ -108,6 +107,8 @@ StableDiffusionTxt2ImgProcessingAPI = PydanticModelGenerator(
{"key": "send_images", "type": bool, "default": True},
{"key": "save_images", "type": bool, "default": False},
{"key": "alwayson_scripts", "type": dict, "default": {}},
{"key": "force_task_id", "type": str, "default": None},
{"key": "infotext", "type": str, "default": None},
]
).generate_model()
@ -125,16 +126,18 @@ StableDiffusionImg2ImgProcessingAPI = PydanticModelGenerator(
{"key": "send_images", "type": bool, "default": True},
{"key": "save_images", "type": bool, "default": False},
{"key": "alwayson_scripts", "type": dict, "default": {}},
{"key": "force_task_id", "type": str, "default": None},
{"key": "infotext", "type": str, "default": None},
]
).generate_model()
class TextToImageResponse(BaseModel):
images: List[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
images: list[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
parameters: dict
info: str
class ImageToImageResponse(BaseModel):
images: List[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
images: list[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
parameters: dict
info: str
@ -144,7 +147,7 @@ class ExtrasBaseRequest(BaseModel):
gfpgan_visibility: float = Field(default=0, title="GFPGAN Visibility", ge=0, le=1, allow_inf_nan=False, description="Sets the visibility of GFPGAN, values should be between 0 and 1.")
codeformer_visibility: float = Field(default=0, title="CodeFormer Visibility", ge=0, le=1, allow_inf_nan=False, description="Sets the visibility of CodeFormer, values should be between 0 and 1.")
codeformer_weight: float = Field(default=0, title="CodeFormer Weight", ge=0, le=1, allow_inf_nan=False, description="Sets the weight of CodeFormer, values should be between 0 and 1.")
upscaling_resize: float = Field(default=2, title="Upscaling Factor", ge=1, le=8, description="By how much to upscale the image, only used when resize_mode=0.")
upscaling_resize: float = Field(default=2, title="Upscaling Factor", gt=0, description="By how much to upscale the image, only used when resize_mode=0.")
upscaling_resize_w: int = Field(default=512, title="Target Width", ge=1, description="Target width for the upscaler to hit. Only used when resize_mode=1.")
upscaling_resize_h: int = Field(default=512, title="Target Height", ge=1, description="Target height for the upscaler to hit. Only used when resize_mode=1.")
upscaling_crop: bool = Field(default=True, title="Crop to fit", description="Should the upscaler crop the image to fit in the chosen size?")
@ -167,17 +170,18 @@ class FileData(BaseModel):
name: str = Field(title="File name")
class ExtrasBatchImagesRequest(ExtrasBaseRequest):
imageList: List[FileData] = Field(title="Images", description="List of images to work on. Must be Base64 strings")
imageList: list[FileData] = Field(title="Images", description="List of images to work on. Must be Base64 strings")
class ExtrasBatchImagesResponse(ExtraBaseResponse):
images: List[str] = Field(title="Images", description="The generated images in base64 format.")
images: list[str] = Field(title="Images", description="The generated images in base64 format.")
class PNGInfoRequest(BaseModel):
image: str = Field(title="Image", description="The base64 encoded PNG image")
class PNGInfoResponse(BaseModel):
info: str = Field(title="Image info", description="A string with the parameters used to generate the image")
items: dict = Field(title="Items", description="An object containing all the info the image had")
items: dict = Field(title="Items", description="A dictionary containing all the other fields the image had")
parameters: dict = Field(title="Parameters", description="A dictionary with parsed generation info fields")
class ProgressRequest(BaseModel):
skip_current_image: bool = Field(default=False, title="Skip current image", description="Skip current image serialization")
@ -202,9 +206,6 @@ class TrainResponse(BaseModel):
class CreateResponse(BaseModel):
info: str = Field(title="Create info", description="Response string from create embedding or hypernetwork task.")
class PreprocessResponse(BaseModel):
info: str = Field(title="Preprocess info", description="Response string from preprocessing task.")
fields = {}
for key, metadata in opts.data_labels.items():
value = opts.data.get(key)
@ -231,8 +232,15 @@ FlagsModel = create_model("Flags", **flags)
class SamplerItem(BaseModel):
name: str = Field(title="Name")
aliases: List[str] = Field(title="Aliases")
options: Dict[str, str] = Field(title="Options")
aliases: list[str] = Field(title="Aliases")
options: dict[str, str] = Field(title="Options")
class SchedulerItem(BaseModel):
name: str = Field(title="Name")
label: str = Field(title="Label")
aliases: Optional[list[str]] = Field(title="Aliases")
default_rho: Optional[float] = Field(title="Default Rho")
need_inner_model: Optional[bool] = Field(title="Needs Inner Model")
class UpscalerItem(BaseModel):
name: str = Field(title="Name")
@ -283,8 +291,8 @@ class EmbeddingItem(BaseModel):
vectors: int = Field(title="Vectors", description="The number of vectors in the embedding")
class EmbeddingsResponse(BaseModel):
loaded: Dict[str, EmbeddingItem] = Field(title="Loaded", description="Embeddings loaded for the current model")
skipped: Dict[str, EmbeddingItem] = Field(title="Skipped", description="Embeddings skipped for the current model (likely due to architecture incompatibility)")
loaded: dict[str, EmbeddingItem] = Field(title="Loaded", description="Embeddings loaded for the current model")
skipped: dict[str, EmbeddingItem] = Field(title="Skipped", description="Embeddings skipped for the current model (likely due to architecture incompatibility)")
class MemoryResponse(BaseModel):
ram: dict = Field(title="RAM", description="System memory stats")
@ -302,11 +310,20 @@ class ScriptArg(BaseModel):
minimum: Optional[Any] = Field(default=None, title="Minimum", description="Minimum allowed value for the argumentin UI")
maximum: Optional[Any] = Field(default=None, title="Minimum", description="Maximum allowed value for the argumentin UI")
step: Optional[Any] = Field(default=None, title="Minimum", description="Step for changing value of the argumentin UI")
choices: Optional[List[str]] = Field(default=None, title="Choices", description="Possible values for the argument")
choices: Optional[list[str]] = Field(default=None, title="Choices", description="Possible values for the argument")
class ScriptInfo(BaseModel):
name: str = Field(default=None, title="Name", description="Script name")
is_alwayson: bool = Field(default=None, title="IsAlwayson", description="Flag specifying whether this script is an alwayson script")
is_img2img: bool = Field(default=None, title="IsImg2img", description="Flag specifying whether this script is an img2img script")
args: List[ScriptArg] = Field(title="Arguments", description="List of script's arguments")
args: list[ScriptArg] = Field(title="Arguments", description="List of script's arguments")
class ExtensionItem(BaseModel):
name: str = Field(title="Name", description="Extension name")
remote: str = Field(title="Remote", description="Extension Repository URL")
branch: str = Field(title="Branch", description="Extension Repository Branch")
commit_hash: str = Field(title="Commit Hash", description="Extension Repository Commit Hash")
version: str = Field(title="Version", description="Extension Version")
commit_date: str = Field(title="Commit Date", description="Extension Repository Commit Date")
enabled: bool = Field(title="Enabled", description="Flag specifying whether this extension is enabled")

View File

@ -1,45 +1,56 @@
import json
import os
import os.path
import threading
import time
import diskcache
import tqdm
from modules.paths import data_path, script_path
cache_filename = os.path.join(data_path, "cache.json")
cache_data = None
cache_filename = os.environ.get('SD_WEBUI_CACHE_FILE', os.path.join(data_path, "cache.json"))
cache_dir = os.environ.get('SD_WEBUI_CACHE_DIR', os.path.join(data_path, "cache"))
caches = {}
cache_lock = threading.Lock()
dump_cache_after = None
dump_cache_thread = None
def dump_cache():
"""
Marks cache for writing to disk. 5 seconds after no one else flags the cache for writing, it is written.
"""
"""old function for dumping cache to disk; does nothing since diskcache."""
global dump_cache_after
global dump_cache_thread
pass
def thread_func():
global dump_cache_after
global dump_cache_thread
while dump_cache_after is not None and time.time() < dump_cache_after:
time.sleep(1)
def make_cache(subsection: str) -> diskcache.Cache:
return diskcache.Cache(
os.path.join(cache_dir, subsection),
size_limit=2**32, # 4 GB, culling oldest first
disk_min_file_size=2**18, # keep up to 256KB in Sqlite
)
with cache_lock:
with open(cache_filename, "w", encoding="utf8") as file:
json.dump(cache_data, file, indent=4)
dump_cache_after = None
dump_cache_thread = None
def convert_old_cached_data():
try:
with open(cache_filename, "r", encoding="utf8") as file:
data = json.load(file)
except FileNotFoundError:
return
except Exception:
os.replace(cache_filename, os.path.join(script_path, "tmp", "cache.json"))
print('[ERROR] issue occurred while trying to read cache.json; old cache has been moved to tmp/cache.json')
return
with cache_lock:
dump_cache_after = time.time() + 5
if dump_cache_thread is None:
dump_cache_thread = threading.Thread(name='cache-writer', target=thread_func)
dump_cache_thread.start()
total_count = sum(len(keyvalues) for keyvalues in data.values())
with tqdm.tqdm(total=total_count, desc="converting cache") as progress:
for subsection, keyvalues in data.items():
cache_obj = caches.get(subsection)
if cache_obj is None:
cache_obj = make_cache(subsection)
caches[subsection] = cache_obj
for key, value in keyvalues.items():
cache_obj[key] = value
progress.update(1)
def cache(subsection):
@ -50,29 +61,21 @@ def cache(subsection):
subsection (str): The subsection identifier for the cache.
Returns:
dict: The cache data for the specified subsection.
diskcache.Cache: The cache data for the specified subsection.
"""
global cache_data
if cache_data is None:
cache_obj = caches.get(subsection)
if not cache_obj:
with cache_lock:
if cache_data is None:
if not os.path.isfile(cache_filename):
cache_data = {}
else:
try:
with open(cache_filename, "r", encoding="utf8") as file:
cache_data = json.load(file)
except Exception:
os.replace(cache_filename, os.path.join(script_path, "tmp", "cache.json"))
print('[ERROR] issue occurred while trying to read cache.json, move current cache to tmp/cache.json and create new cache')
cache_data = {}
if not os.path.exists(cache_dir) and os.path.isfile(cache_filename):
convert_old_cached_data()
s = cache_data.get(subsection, {})
cache_data[subsection] = s
cache_obj = caches.get(subsection)
if not cache_obj:
cache_obj = make_cache(subsection)
caches[subsection] = cache_obj
return s
return cache_obj
def cached_data_for_file(subsection, title, filename, func):

View File

@ -1,11 +1,11 @@
import os.path
from functools import wraps
import html
import threading
import time
from modules import shared, progress, errors
from modules import shared, progress, errors, devices, fifo_lock, profiling
queue_lock = threading.Lock()
queue_lock = fifo_lock.FIFOLock()
def wrap_queued_call(func):
@ -47,6 +47,22 @@ def wrap_gradio_gpu_call(func, extra_outputs=None):
def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
@wraps(func)
def f(*args, **kwargs):
try:
res = func(*args, **kwargs)
finally:
shared.state.skipped = False
shared.state.interrupted = False
shared.state.stopping_generation = False
shared.state.job_count = 0
shared.state.job = ""
return res
return wrap_gradio_call_no_job(f, extra_outputs, add_stats)
def wrap_gradio_call_no_job(func, extra_outputs=None, add_stats=False):
@wraps(func)
def f(*args, extra_outputs_array=extra_outputs, **kwargs):
run_memmon = shared.opts.memmon_poll_rate > 0 and not shared.mem_mon.disabled and add_stats
@ -66,18 +82,13 @@ def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
arg_str += f" (Argument list truncated at {max_debug_str_len}/{len(arg_str)} characters)"
errors.report(f"{message}\n{arg_str}", exc_info=True)
shared.state.job = ""
shared.state.job_count = 0
if extra_outputs_array is None:
extra_outputs_array = [None, '']
error_message = f'{type(e).__name__}: {e}'
res = extra_outputs_array + [f"<div class='error'>{html.escape(error_message)}</div>"]
shared.state.skipped = False
shared.state.interrupted = False
shared.state.job_count = 0
devices.torch_gc()
if not add_stats:
return tuple(res)
@ -98,8 +109,8 @@ def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
sys_pct = sys_peak/max(sys_total, 1) * 100
toltip_a = "Active: peak amount of video memory used during generation (excluding cached data)"
toltip_r = "Reserved: total amout of video memory allocated by the Torch library "
toltip_sys = "System: peak amout of video memory allocated by all running programs, out of total capacity"
toltip_r = "Reserved: total amount of video memory allocated by the Torch library "
toltip_sys = "System: peak amount of video memory allocated by all running programs, out of total capacity"
text_a = f"<abbr title='{toltip_a}'>A</abbr>: <span class='measurement'>{active_peak/1024:.2f} GB</span>"
text_r = f"<abbr title='{toltip_r}'>R</abbr>: <span class='measurement'>{reserved_peak/1024:.2f} GB</span>"
@ -109,9 +120,15 @@ def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
else:
vram_html = ''
if shared.opts.profiling_enable and os.path.exists(shared.opts.profiling_filename):
profiling_html = f"<p class='profile'> [ <a href='{profiling.webpath()}' download>Profile</a> ] </p>"
else:
profiling_html = ''
# last item is always HTML
res[-1] += f"<div class='performance'><p class='time'>Time taken: <wbr><span class='measurement'>{elapsed_text}</span></p>{vram_html}</div>"
res[-1] += f"<div class='performance'><p class='time'>Time taken: <wbr><span class='measurement'>{elapsed_text}</span></p>{vram_html}{profiling_html}</div>"
return tuple(res)
return f

View File

@ -1,7 +1,7 @@
import argparse
import json
import os
from modules.paths_internal import models_path, script_path, data_path, extensions_dir, extensions_builtin_dir, sd_default_config, sd_model_file # noqa: F401
from modules.paths_internal import normalized_filepath, models_path, script_path, data_path, extensions_dir, extensions_builtin_dir, sd_default_config, sd_model_file # noqa: F401
parser = argparse.ArgumentParser()
@ -13,43 +13,49 @@ parser.add_argument("--reinstall-xformers", action='store_true', help="launch.py
parser.add_argument("--reinstall-torch", action='store_true', help="launch.py argument: install the appropriate version of torch even if you have some version already installed")
parser.add_argument("--update-check", action='store_true', help="launch.py argument: check for updates at startup")
parser.add_argument("--test-server", action='store_true', help="launch.py argument: configure server for testing")
parser.add_argument("--log-startup", action='store_true', help="launch.py argument: print a detailed log of what's happening at startup")
parser.add_argument("--skip-prepare-environment", action='store_true', help="launch.py argument: skip all environment preparation")
parser.add_argument("--skip-install", action='store_true', help="launch.py argument: skip installation of packages")
parser.add_argument("--dump-sysinfo", action='store_true', help="launch.py argument: dump limited sysinfo file (without information about extensions, options) to disk and quit")
parser.add_argument("--loglevel", type=str, help="log level; one of: CRITICAL, ERROR, WARNING, INFO, DEBUG", default=None)
parser.add_argument("--do-not-download-clip", action='store_true', help="do not download CLIP model even if it's not included in the checkpoint")
parser.add_argument("--data-dir", type=str, default=os.path.dirname(os.path.dirname(os.path.realpath(__file__))), help="base path where all user data is stored")
parser.add_argument("--config", type=str, default=sd_default_config, help="path to config which constructs model",)
parser.add_argument("--ckpt", type=str, default=sd_model_file, help="path to checkpoint of stable diffusion model; if specified, this checkpoint will be added to the list of checkpoints and loaded",)
parser.add_argument("--ckpt-dir", type=str, default=None, help="Path to directory with stable diffusion checkpoints")
parser.add_argument("--vae-dir", type=str, default=None, help="Path to directory with VAE files")
parser.add_argument("--gfpgan-dir", type=str, help="GFPGAN directory", default=('./src/gfpgan' if os.path.exists('./src/gfpgan') else './GFPGAN'))
parser.add_argument("--gfpgan-model", type=str, help="GFPGAN model file name", default=None)
parser.add_argument("--data-dir", type=normalized_filepath, default=os.path.dirname(os.path.dirname(os.path.realpath(__file__))), help="base path where all user data is stored")
parser.add_argument("--models-dir", type=normalized_filepath, default=None, help="base path where models are stored; overrides --data-dir")
parser.add_argument("--config", type=normalized_filepath, default=sd_default_config, help="path to config which constructs model",)
parser.add_argument("--ckpt", type=normalized_filepath, default=sd_model_file, help="path to checkpoint of stable diffusion model; if specified, this checkpoint will be added to the list of checkpoints and loaded",)
parser.add_argument("--ckpt-dir", type=normalized_filepath, default=None, help="Path to directory with stable diffusion checkpoints")
parser.add_argument("--vae-dir", type=normalized_filepath, default=None, help="Path to directory with VAE files")
parser.add_argument("--gfpgan-dir", type=normalized_filepath, help="GFPGAN directory", default=('./src/gfpgan' if os.path.exists('./src/gfpgan') else './GFPGAN'))
parser.add_argument("--gfpgan-model", type=normalized_filepath, help="GFPGAN model file name", default=None)
parser.add_argument("--no-half", action='store_true', help="do not switch the model to 16-bit floats")
parser.add_argument("--no-half-vae", action='store_true', help="do not switch the VAE model to 16-bit floats")
parser.add_argument("--no-progressbar-hiding", action='store_true', help="do not hide progressbar in gradio UI (we hide it because it slows down ML if you have hardware acceleration in browser)")
parser.add_argument("--max-batch-count", type=int, default=16, help="maximum batch count value for the UI")
parser.add_argument("--embeddings-dir", type=str, default=os.path.join(data_path, 'embeddings'), help="embeddings directory for textual inversion (default: embeddings)")
parser.add_argument("--textual-inversion-templates-dir", type=str, default=os.path.join(script_path, 'textual_inversion_templates'), help="directory with textual inversion templates")
parser.add_argument("--hypernetwork-dir", type=str, default=os.path.join(models_path, 'hypernetworks'), help="hypernetwork directory")
parser.add_argument("--localizations-dir", type=str, default=os.path.join(script_path, 'localizations'), help="localizations directory")
parser.add_argument("--max-batch-count", type=int, default=16, help="does not do anything")
parser.add_argument("--embeddings-dir", type=normalized_filepath, default=os.path.join(data_path, 'embeddings'), help="embeddings directory for textual inversion (default: embeddings)")
parser.add_argument("--textual-inversion-templates-dir", type=normalized_filepath, default=os.path.join(script_path, 'textual_inversion_templates'), help="directory with textual inversion templates")
parser.add_argument("--hypernetwork-dir", type=normalized_filepath, default=os.path.join(models_path, 'hypernetworks'), help="hypernetwork directory")
parser.add_argument("--localizations-dir", type=normalized_filepath, default=os.path.join(script_path, 'localizations'), help="localizations directory")
parser.add_argument("--allow-code", action='store_true', help="allow custom script execution from webui")
parser.add_argument("--medvram", action='store_true', help="enable stable diffusion model optimizations for sacrificing a little speed for low VRM usage")
parser.add_argument("--medvram-sdxl", action='store_true', help="enable --medvram optimization just for SDXL models")
parser.add_argument("--lowvram", action='store_true', help="enable stable diffusion model optimizations for sacrificing a lot of speed for very low VRM usage")
parser.add_argument("--lowram", action='store_true', help="load stable diffusion checkpoint weights to VRAM instead of RAM")
parser.add_argument("--always-batch-cond-uncond", action='store_true', help="disables cond/uncond batching that is enabled to save memory with --medvram or --lowvram")
parser.add_argument("--always-batch-cond-uncond", action='store_true', help="does not do anything")
parser.add_argument("--unload-gfpgan", action='store_true', help="does not do anything.")
parser.add_argument("--precision", type=str, help="evaluate at this precision", choices=["full", "autocast"], default="autocast")
parser.add_argument("--precision", type=str, help="evaluate at this precision", choices=["full", "half", "autocast"], default="autocast")
parser.add_argument("--upcast-sampling", action='store_true', help="upcast sampling. No effect with --no-half. Usually produces similar results to --no-half with better performance while using less memory.")
parser.add_argument("--share", action='store_true', help="use share=True for gradio and make the UI accessible through their site")
parser.add_argument("--ngrok", type=str, help="ngrok authtoken, alternative to gradio --share", default=None)
parser.add_argument("--ngrok-region", type=str, help="does not do anything.", default="")
parser.add_argument("--ngrok-options", type=json.loads, help='The options to pass to ngrok in JSON format, e.g.: \'{"authtoken_from_env":true, "basic_auth":"user:password", "oauth_provider":"google", "oauth_allow_emails":"user@asdf.com"}\'', default=dict())
parser.add_argument("--enable-insecure-extension-access", action='store_true', help="enable extensions tab regardless of other options")
parser.add_argument("--codeformer-models-path", type=str, help="Path to directory with codeformer model file(s).", default=os.path.join(models_path, 'Codeformer'))
parser.add_argument("--gfpgan-models-path", type=str, help="Path to directory with GFPGAN model file(s).", default=os.path.join(models_path, 'GFPGAN'))
parser.add_argument("--esrgan-models-path", type=str, help="Path to directory with ESRGAN model file(s).", default=os.path.join(models_path, 'ESRGAN'))
parser.add_argument("--bsrgan-models-path", type=str, help="Path to directory with BSRGAN model file(s).", default=os.path.join(models_path, 'BSRGAN'))
parser.add_argument("--realesrgan-models-path", type=str, help="Path to directory with RealESRGAN model file(s).", default=os.path.join(models_path, 'RealESRGAN'))
parser.add_argument("--clip-models-path", type=str, help="Path to directory with CLIP model file(s).", default=None)
parser.add_argument("--codeformer-models-path", type=normalized_filepath, help="Path to directory with codeformer model file(s).", default=os.path.join(models_path, 'Codeformer'))
parser.add_argument("--gfpgan-models-path", type=normalized_filepath, help="Path to directory with GFPGAN model file(s).", default=os.path.join(models_path, 'GFPGAN'))
parser.add_argument("--esrgan-models-path", type=normalized_filepath, help="Path to directory with ESRGAN model file(s).", default=os.path.join(models_path, 'ESRGAN'))
parser.add_argument("--bsrgan-models-path", type=normalized_filepath, help="Path to directory with BSRGAN model file(s).", default=os.path.join(models_path, 'BSRGAN'))
parser.add_argument("--realesrgan-models-path", type=normalized_filepath, help="Path to directory with RealESRGAN model file(s).", default=os.path.join(models_path, 'RealESRGAN'))
parser.add_argument("--dat-models-path", type=normalized_filepath, help="Path to directory with DAT model file(s).", default=os.path.join(models_path, 'DAT'))
parser.add_argument("--clip-models-path", type=normalized_filepath, help="Path to directory with CLIP model file(s).", default=None)
parser.add_argument("--xformers", action='store_true', help="enable xformers for cross attention layers")
parser.add_argument("--force-enable-xformers", action='store_true', help="enable xformers for cross attention layers regardless of whether the checking code thinks you can run it; do not make bug reports if this fails to work")
parser.add_argument("--xformers-flash-attention", action='store_true', help="enable xformers with Flash Attention to improve reproducibility (supported for SD2.x or variant only)")
@ -66,27 +72,31 @@ parser.add_argument("--opt-sdp-no-mem-attention", action='store_true', help="pre
parser.add_argument("--disable-opt-split-attention", action='store_true', help="prefer no cross-attention layer optimization for automatic choice of optimization")
parser.add_argument("--disable-nan-check", action='store_true', help="do not check if produced images/latent spaces have nans; useful for running without a checkpoint in CI")
parser.add_argument("--use-cpu", nargs='+', help="use CPU as torch device for specified modules", default=[], type=str.lower)
parser.add_argument("--use-ipex", action="store_true", help="use Intel XPU as torch device")
parser.add_argument("--disable-model-loading-ram-optimization", action='store_true', help="disable an optimization that reduces RAM use when loading a model")
parser.add_argument("--listen", action='store_true', help="launch gradio with 0.0.0.0 as server name, allowing to respond to network requests")
parser.add_argument("--port", type=int, help="launch gradio with given server port, you need root/admin rights for ports < 1024, defaults to 7860 if available", default=None)
parser.add_argument("--show-negative-prompt", action='store_true', help="does not do anything", default=False)
parser.add_argument("--ui-config-file", type=str, help="filename to use for ui configuration", default=os.path.join(data_path, 'ui-config.json'))
parser.add_argument("--hide-ui-dir-config", action='store_true', help="hide directory configuration from webui", default=False)
parser.add_argument("--freeze-settings", action='store_true', help="disable editing settings", default=False)
parser.add_argument("--freeze-settings", action='store_true', help="disable editing of all settings globally", default=False)
parser.add_argument("--freeze-settings-in-sections", type=str, help='disable editing settings in specific sections of the settings page by specifying a comma-delimited list such like "saving-images,upscaling". The list of setting names can be found in the modules/shared_options.py file', default=None)
parser.add_argument("--freeze-specific-settings", type=str, help='disable editing of individual settings by specifying a comma-delimited list like "samples_save,samples_format". The list of setting names can be found in the config.json file', default=None)
parser.add_argument("--ui-settings-file", type=str, help="filename to use for ui settings", default=os.path.join(data_path, 'config.json'))
parser.add_argument("--gradio-debug", action='store_true', help="launch gradio with --debug option")
parser.add_argument("--gradio-auth", type=str, help='set gradio authentication like "username:password"; or comma-delimit multiple like "u1:p1,u2:p2,u3:p3"', default=None)
parser.add_argument("--gradio-auth-path", type=str, help='set gradio authentication file path ex. "/path/to/auth/file" same auth format as --gradio-auth', default=None)
parser.add_argument("--gradio-auth-path", type=normalized_filepath, help='set gradio authentication file path ex. "/path/to/auth/file" same auth format as --gradio-auth', default=None)
parser.add_argument("--gradio-img2img-tool", type=str, help='does not do anything')
parser.add_argument("--gradio-inpaint-tool", type=str, help="does not do anything")
parser.add_argument("--gradio-allowed-path", action='append', help="add path to gradio's allowed_paths, make it possible to serve files from it")
parser.add_argument("--gradio-allowed-path", action='append', help="add path to gradio's allowed_paths, make it possible to serve files from it", default=[data_path])
parser.add_argument("--opt-channelslast", action='store_true', help="change memory type for stable diffusion to channels last")
parser.add_argument("--styles-file", type=str, help="filename to use for styles", default=os.path.join(data_path, 'styles.csv'))
parser.add_argument("--styles-file", type=str, action='append', help="path or wildcard path of styles files, allow multiple entries.", default=[])
parser.add_argument("--autolaunch", action='store_true', help="open the webui URL in the system's default browser upon launch", default=False)
parser.add_argument("--theme", type=str, help="launches the UI with light or dark theme", default=None)
parser.add_argument("--use-textbox-seed", action='store_true', help="use textbox for seeds in UI (no up/down, but possible to input long seeds)", default=False)
parser.add_argument("--disable-console-progressbars", action='store_true', help="do not output progressbars to console", default=False)
parser.add_argument("--enable-console-prompts", action='store_true', help="print prompts to console when generating with txt2img and img2img", default=False)
parser.add_argument('--vae-path', type=str, help='Checkpoint to use as VAE; setting this argument disables all settings related to VAE', default=None)
parser.add_argument("--enable-console-prompts", action='store_true', help="does not do anything", default=False) # Legacy compatibility, use as default value shared.opts.enable_console_prompts
parser.add_argument('--vae-path', type=normalized_filepath, help='Checkpoint to use as VAE; setting this argument disables all settings related to VAE', default=None)
parser.add_argument("--disable-safe-unpickle", action='store_true', help="disable checking pytorch models for malicious code", default=False)
parser.add_argument("--api", action='store_true', help="use api=True to launch the API together with the webui (use --nowebui instead for only the API)")
parser.add_argument("--api-auth", type=str, help='Set authentication for API like "username:password"; or comma-delimit multiple like "u1:p1,u2:p2,u3:p3"', default=None)
@ -102,11 +112,17 @@ parser.add_argument("--tls-certfile", type=str, help="Partially enables TLS, req
parser.add_argument("--disable-tls-verify", action="store_false", help="When passed, enables the use of self-signed certificates.", default=None)
parser.add_argument("--server-name", type=str, help="Sets hostname of server", default=None)
parser.add_argument("--gradio-queue", action='store_true', help="does not do anything", default=True)
parser.add_argument("--no-gradio-queue", action='store_true', help="Disables gradio queue; causes the webpage to use http requests instead of websockets; was the defaul in earlier versions")
parser.add_argument("--no-gradio-queue", action='store_true', help="Disables gradio queue; causes the webpage to use http requests instead of websockets; was the default in earlier versions")
parser.add_argument("--skip-version-check", action='store_true', help="Do not check versions of torch and xformers")
parser.add_argument("--no-hashing", action='store_true', help="disable sha256 hashing of checkpoints to help loading performance", default=False)
parser.add_argument("--no-download-sd-model", action='store_true', help="don't download SD1.5 model even if no model is found in --ckpt-dir", default=False)
parser.add_argument('--subpath', type=str, help='customize the subpath for gradio, use with reverse proxy')
parser.add_argument('--add-stop-route', action='store_true', help='add /_stop route to stop server')
parser.add_argument('--add-stop-route', action='store_true', help='does not do anything')
parser.add_argument('--api-server-stop', action='store_true', help='enable server stop/restart/kill via api')
parser.add_argument('--timeout-keep-alive', type=int, default=30, help='set timeout_keep_alive for uvicorn')
parser.add_argument("--disable-all-extensions", action='store_true', help="prevent all extensions from running regardless of any other settings", default=False)
parser.add_argument("--disable-extra-extensions", action='store_true', help="prevent all extensions except built-in from running regardless of any other settings", default=False)
parser.add_argument("--skip-load-model-at-start", action='store_true', help="if load a model at web start, only take effect when --nowebui")
parser.add_argument("--unix-filenames-sanitization", action='store_true', help="allow any symbols except '/' in filenames. May conflict with your browser and file system")
parser.add_argument("--filenames-max-length", type=int, default=128, help='maximal length of filenames of saved images. If you override it, it can conflict with your file system')
parser.add_argument("--no-prompt-history", action='store_true', help="disable read prompt from last generation feature; settings this argument will not create '--data_path/params.txt' file")

View File

@ -1,276 +0,0 @@
# this file is copied from CodeFormer repository. Please see comment in modules/codeformer_model.py
import math
import torch
from torch import nn, Tensor
import torch.nn.functional as F
from typing import Optional
from modules.codeformer.vqgan_arch import VQAutoEncoder, ResBlock
from basicsr.utils.registry import ARCH_REGISTRY
def calc_mean_std(feat, eps=1e-5):
"""Calculate mean and std for adaptive_instance_normalization.
Args:
feat (Tensor): 4D tensor.
eps (float): A small value added to the variance to avoid
divide-by-zero. Default: 1e-5.
"""
size = feat.size()
assert len(size) == 4, 'The input feature should be 4D tensor.'
b, c = size[:2]
feat_var = feat.view(b, c, -1).var(dim=2) + eps
feat_std = feat_var.sqrt().view(b, c, 1, 1)
feat_mean = feat.view(b, c, -1).mean(dim=2).view(b, c, 1, 1)
return feat_mean, feat_std
def adaptive_instance_normalization(content_feat, style_feat):
"""Adaptive instance normalization.
Adjust the reference features to have the similar color and illuminations
as those in the degradate features.
Args:
content_feat (Tensor): The reference feature.
style_feat (Tensor): The degradate features.
"""
size = content_feat.size()
style_mean, style_std = calc_mean_std(style_feat)
content_mean, content_std = calc_mean_std(content_feat)
normalized_feat = (content_feat - content_mean.expand(size)) / content_std.expand(size)
return normalized_feat * style_std.expand(size) + style_mean.expand(size)
class PositionEmbeddingSine(nn.Module):
"""
This is a more standard version of the position embedding, very similar to the one
used by the Attention is all you need paper, generalized to work on images.
"""
def __init__(self, num_pos_feats=64, temperature=10000, normalize=False, scale=None):
super().__init__()
self.num_pos_feats = num_pos_feats
self.temperature = temperature
self.normalize = normalize
if scale is not None and normalize is False:
raise ValueError("normalize should be True if scale is passed")
if scale is None:
scale = 2 * math.pi
self.scale = scale
def forward(self, x, mask=None):
if mask is None:
mask = torch.zeros((x.size(0), x.size(2), x.size(3)), device=x.device, dtype=torch.bool)
not_mask = ~mask
y_embed = not_mask.cumsum(1, dtype=torch.float32)
x_embed = not_mask.cumsum(2, dtype=torch.float32)
if self.normalize:
eps = 1e-6
y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale
x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale
dim_t = torch.arange(self.num_pos_feats, dtype=torch.float32, device=x.device)
dim_t = self.temperature ** (2 * (dim_t // 2) / self.num_pos_feats)
pos_x = x_embed[:, :, :, None] / dim_t
pos_y = y_embed[:, :, :, None] / dim_t
pos_x = torch.stack(
(pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4
).flatten(3)
pos_y = torch.stack(
(pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4
).flatten(3)
pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2)
return pos
def _get_activation_fn(activation):
"""Return an activation function given a string"""
if activation == "relu":
return F.relu
if activation == "gelu":
return F.gelu
if activation == "glu":
return F.glu
raise RuntimeError(F"activation should be relu/gelu, not {activation}.")
class TransformerSALayer(nn.Module):
def __init__(self, embed_dim, nhead=8, dim_mlp=2048, dropout=0.0, activation="gelu"):
super().__init__()
self.self_attn = nn.MultiheadAttention(embed_dim, nhead, dropout=dropout)
# Implementation of Feedforward model - MLP
self.linear1 = nn.Linear(embed_dim, dim_mlp)
self.dropout = nn.Dropout(dropout)
self.linear2 = nn.Linear(dim_mlp, embed_dim)
self.norm1 = nn.LayerNorm(embed_dim)
self.norm2 = nn.LayerNorm(embed_dim)
self.dropout1 = nn.Dropout(dropout)
self.dropout2 = nn.Dropout(dropout)
self.activation = _get_activation_fn(activation)
def with_pos_embed(self, tensor, pos: Optional[Tensor]):
return tensor if pos is None else tensor + pos
def forward(self, tgt,
tgt_mask: Optional[Tensor] = None,
tgt_key_padding_mask: Optional[Tensor] = None,
query_pos: Optional[Tensor] = None):
# self attention
tgt2 = self.norm1(tgt)
q = k = self.with_pos_embed(tgt2, query_pos)
tgt2 = self.self_attn(q, k, value=tgt2, attn_mask=tgt_mask,
key_padding_mask=tgt_key_padding_mask)[0]
tgt = tgt + self.dropout1(tgt2)
# ffn
tgt2 = self.norm2(tgt)
tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt2))))
tgt = tgt + self.dropout2(tgt2)
return tgt
class Fuse_sft_block(nn.Module):
def __init__(self, in_ch, out_ch):
super().__init__()
self.encode_enc = ResBlock(2*in_ch, out_ch)
self.scale = nn.Sequential(
nn.Conv2d(in_ch, out_ch, kernel_size=3, padding=1),
nn.LeakyReLU(0.2, True),
nn.Conv2d(out_ch, out_ch, kernel_size=3, padding=1))
self.shift = nn.Sequential(
nn.Conv2d(in_ch, out_ch, kernel_size=3, padding=1),
nn.LeakyReLU(0.2, True),
nn.Conv2d(out_ch, out_ch, kernel_size=3, padding=1))
def forward(self, enc_feat, dec_feat, w=1):
enc_feat = self.encode_enc(torch.cat([enc_feat, dec_feat], dim=1))
scale = self.scale(enc_feat)
shift = self.shift(enc_feat)
residual = w * (dec_feat * scale + shift)
out = dec_feat + residual
return out
@ARCH_REGISTRY.register()
class CodeFormer(VQAutoEncoder):
def __init__(self, dim_embd=512, n_head=8, n_layers=9,
codebook_size=1024, latent_size=256,
connect_list=('32', '64', '128', '256'),
fix_modules=('quantize', 'generator')):
super(CodeFormer, self).__init__(512, 64, [1, 2, 2, 4, 4, 8], 'nearest',2, [16], codebook_size)
if fix_modules is not None:
for module in fix_modules:
for param in getattr(self, module).parameters():
param.requires_grad = False
self.connect_list = connect_list
self.n_layers = n_layers
self.dim_embd = dim_embd
self.dim_mlp = dim_embd*2
self.position_emb = nn.Parameter(torch.zeros(latent_size, self.dim_embd))
self.feat_emb = nn.Linear(256, self.dim_embd)
# transformer
self.ft_layers = nn.Sequential(*[TransformerSALayer(embed_dim=dim_embd, nhead=n_head, dim_mlp=self.dim_mlp, dropout=0.0)
for _ in range(self.n_layers)])
# logits_predict head
self.idx_pred_layer = nn.Sequential(
nn.LayerNorm(dim_embd),
nn.Linear(dim_embd, codebook_size, bias=False))
self.channels = {
'16': 512,
'32': 256,
'64': 256,
'128': 128,
'256': 128,
'512': 64,
}
# after second residual block for > 16, before attn layer for ==16
self.fuse_encoder_block = {'512':2, '256':5, '128':8, '64':11, '32':14, '16':18}
# after first residual block for > 16, before attn layer for ==16
self.fuse_generator_block = {'16':6, '32': 9, '64':12, '128':15, '256':18, '512':21}
# fuse_convs_dict
self.fuse_convs_dict = nn.ModuleDict()
for f_size in self.connect_list:
in_ch = self.channels[f_size]
self.fuse_convs_dict[f_size] = Fuse_sft_block(in_ch, in_ch)
def _init_weights(self, module):
if isinstance(module, (nn.Linear, nn.Embedding)):
module.weight.data.normal_(mean=0.0, std=0.02)
if isinstance(module, nn.Linear) and module.bias is not None:
module.bias.data.zero_()
elif isinstance(module, nn.LayerNorm):
module.bias.data.zero_()
module.weight.data.fill_(1.0)
def forward(self, x, w=0, detach_16=True, code_only=False, adain=False):
# ################### Encoder #####################
enc_feat_dict = {}
out_list = [self.fuse_encoder_block[f_size] for f_size in self.connect_list]
for i, block in enumerate(self.encoder.blocks):
x = block(x)
if i in out_list:
enc_feat_dict[str(x.shape[-1])] = x.clone()
lq_feat = x
# ################# Transformer ###################
# quant_feat, codebook_loss, quant_stats = self.quantize(lq_feat)
pos_emb = self.position_emb.unsqueeze(1).repeat(1,x.shape[0],1)
# BCHW -> BC(HW) -> (HW)BC
feat_emb = self.feat_emb(lq_feat.flatten(2).permute(2,0,1))
query_emb = feat_emb
# Transformer encoder
for layer in self.ft_layers:
query_emb = layer(query_emb, query_pos=pos_emb)
# output logits
logits = self.idx_pred_layer(query_emb) # (hw)bn
logits = logits.permute(1,0,2) # (hw)bn -> b(hw)n
if code_only: # for training stage II
# logits doesn't need softmax before cross_entropy loss
return logits, lq_feat
# ################# Quantization ###################
# if self.training:
# quant_feat = torch.einsum('btn,nc->btc', [soft_one_hot, self.quantize.embedding.weight])
# # b(hw)c -> bc(hw) -> bchw
# quant_feat = quant_feat.permute(0,2,1).view(lq_feat.shape)
# ------------
soft_one_hot = F.softmax(logits, dim=2)
_, top_idx = torch.topk(soft_one_hot, 1, dim=2)
quant_feat = self.quantize.get_codebook_feat(top_idx, shape=[x.shape[0],16,16,256])
# preserve gradients
# quant_feat = lq_feat + (quant_feat - lq_feat).detach()
if detach_16:
quant_feat = quant_feat.detach() # for training stage III
if adain:
quant_feat = adaptive_instance_normalization(quant_feat, lq_feat)
# ################## Generator ####################
x = quant_feat
fuse_list = [self.fuse_generator_block[f_size] for f_size in self.connect_list]
for i, block in enumerate(self.generator.blocks):
x = block(x)
if i in fuse_list: # fuse after i-th block
f_size = str(x.shape[-1])
if w>0:
x = self.fuse_convs_dict[f_size](enc_feat_dict[f_size].detach(), x, w)
out = x
# logits doesn't need softmax before cross_entropy loss
return out, logits, lq_feat

View File

@ -1,435 +0,0 @@
# this file is copied from CodeFormer repository. Please see comment in modules/codeformer_model.py
'''
VQGAN code, adapted from the original created by the Unleashing Transformers authors:
https://github.com/samb-t/unleashing-transformers/blob/master/models/vqgan.py
'''
import torch
import torch.nn as nn
import torch.nn.functional as F
from basicsr.utils import get_root_logger
from basicsr.utils.registry import ARCH_REGISTRY
def normalize(in_channels):
return torch.nn.GroupNorm(num_groups=32, num_channels=in_channels, eps=1e-6, affine=True)
@torch.jit.script
def swish(x):
return x*torch.sigmoid(x)
# Define VQVAE classes
class VectorQuantizer(nn.Module):
def __init__(self, codebook_size, emb_dim, beta):
super(VectorQuantizer, self).__init__()
self.codebook_size = codebook_size # number of embeddings
self.emb_dim = emb_dim # dimension of embedding
self.beta = beta # commitment cost used in loss term, beta * ||z_e(x)-sg[e]||^2
self.embedding = nn.Embedding(self.codebook_size, self.emb_dim)
self.embedding.weight.data.uniform_(-1.0 / self.codebook_size, 1.0 / self.codebook_size)
def forward(self, z):
# reshape z -> (batch, height, width, channel) and flatten
z = z.permute(0, 2, 3, 1).contiguous()
z_flattened = z.view(-1, self.emb_dim)
# distances from z to embeddings e_j (z - e)^2 = z^2 + e^2 - 2 e * z
d = (z_flattened ** 2).sum(dim=1, keepdim=True) + (self.embedding.weight**2).sum(1) - \
2 * torch.matmul(z_flattened, self.embedding.weight.t())
mean_distance = torch.mean(d)
# find closest encodings
# min_encoding_indices = torch.argmin(d, dim=1).unsqueeze(1)
min_encoding_scores, min_encoding_indices = torch.topk(d, 1, dim=1, largest=False)
# [0-1], higher score, higher confidence
min_encoding_scores = torch.exp(-min_encoding_scores/10)
min_encodings = torch.zeros(min_encoding_indices.shape[0], self.codebook_size).to(z)
min_encodings.scatter_(1, min_encoding_indices, 1)
# get quantized latent vectors
z_q = torch.matmul(min_encodings, self.embedding.weight).view(z.shape)
# compute loss for embedding
loss = torch.mean((z_q.detach()-z)**2) + self.beta * torch.mean((z_q - z.detach()) ** 2)
# preserve gradients
z_q = z + (z_q - z).detach()
# perplexity
e_mean = torch.mean(min_encodings, dim=0)
perplexity = torch.exp(-torch.sum(e_mean * torch.log(e_mean + 1e-10)))
# reshape back to match original input shape
z_q = z_q.permute(0, 3, 1, 2).contiguous()
return z_q, loss, {
"perplexity": perplexity,
"min_encodings": min_encodings,
"min_encoding_indices": min_encoding_indices,
"min_encoding_scores": min_encoding_scores,
"mean_distance": mean_distance
}
def get_codebook_feat(self, indices, shape):
# input indices: batch*token_num -> (batch*token_num)*1
# shape: batch, height, width, channel
indices = indices.view(-1,1)
min_encodings = torch.zeros(indices.shape[0], self.codebook_size).to(indices)
min_encodings.scatter_(1, indices, 1)
# get quantized latent vectors
z_q = torch.matmul(min_encodings.float(), self.embedding.weight)
if shape is not None: # reshape back to match original input shape
z_q = z_q.view(shape).permute(0, 3, 1, 2).contiguous()
return z_q
class GumbelQuantizer(nn.Module):
def __init__(self, codebook_size, emb_dim, num_hiddens, straight_through=False, kl_weight=5e-4, temp_init=1.0):
super().__init__()
self.codebook_size = codebook_size # number of embeddings
self.emb_dim = emb_dim # dimension of embedding
self.straight_through = straight_through
self.temperature = temp_init
self.kl_weight = kl_weight
self.proj = nn.Conv2d(num_hiddens, codebook_size, 1) # projects last encoder layer to quantized logits
self.embed = nn.Embedding(codebook_size, emb_dim)
def forward(self, z):
hard = self.straight_through if self.training else True
logits = self.proj(z)
soft_one_hot = F.gumbel_softmax(logits, tau=self.temperature, dim=1, hard=hard)
z_q = torch.einsum("b n h w, n d -> b d h w", soft_one_hot, self.embed.weight)
# + kl divergence to the prior loss
qy = F.softmax(logits, dim=1)
diff = self.kl_weight * torch.sum(qy * torch.log(qy * self.codebook_size + 1e-10), dim=1).mean()
min_encoding_indices = soft_one_hot.argmax(dim=1)
return z_q, diff, {
"min_encoding_indices": min_encoding_indices
}
class Downsample(nn.Module):
def __init__(self, in_channels):
super().__init__()
self.conv = torch.nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=2, padding=0)
def forward(self, x):
pad = (0, 1, 0, 1)
x = torch.nn.functional.pad(x, pad, mode="constant", value=0)
x = self.conv(x)
return x
class Upsample(nn.Module):
def __init__(self, in_channels):
super().__init__()
self.conv = nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1)
def forward(self, x):
x = F.interpolate(x, scale_factor=2.0, mode="nearest")
x = self.conv(x)
return x
class ResBlock(nn.Module):
def __init__(self, in_channels, out_channels=None):
super(ResBlock, self).__init__()
self.in_channels = in_channels
self.out_channels = in_channels if out_channels is None else out_channels
self.norm1 = normalize(in_channels)
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1)
self.norm2 = normalize(out_channels)
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)
if self.in_channels != self.out_channels:
self.conv_out = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0)
def forward(self, x_in):
x = x_in
x = self.norm1(x)
x = swish(x)
x = self.conv1(x)
x = self.norm2(x)
x = swish(x)
x = self.conv2(x)
if self.in_channels != self.out_channels:
x_in = self.conv_out(x_in)
return x + x_in
class AttnBlock(nn.Module):
def __init__(self, in_channels):
super().__init__()
self.in_channels = in_channels
self.norm = normalize(in_channels)
self.q = torch.nn.Conv2d(
in_channels,
in_channels,
kernel_size=1,
stride=1,
padding=0
)
self.k = torch.nn.Conv2d(
in_channels,
in_channels,
kernel_size=1,
stride=1,
padding=0
)
self.v = torch.nn.Conv2d(
in_channels,
in_channels,
kernel_size=1,
stride=1,
padding=0
)
self.proj_out = torch.nn.Conv2d(
in_channels,
in_channels,
kernel_size=1,
stride=1,
padding=0
)
def forward(self, x):
h_ = x
h_ = self.norm(h_)
q = self.q(h_)
k = self.k(h_)
v = self.v(h_)
# compute attention
b, c, h, w = q.shape
q = q.reshape(b, c, h*w)
q = q.permute(0, 2, 1)
k = k.reshape(b, c, h*w)
w_ = torch.bmm(q, k)
w_ = w_ * (int(c)**(-0.5))
w_ = F.softmax(w_, dim=2)
# attend to values
v = v.reshape(b, c, h*w)
w_ = w_.permute(0, 2, 1)
h_ = torch.bmm(v, w_)
h_ = h_.reshape(b, c, h, w)
h_ = self.proj_out(h_)
return x+h_
class Encoder(nn.Module):
def __init__(self, in_channels, nf, emb_dim, ch_mult, num_res_blocks, resolution, attn_resolutions):
super().__init__()
self.nf = nf
self.num_resolutions = len(ch_mult)
self.num_res_blocks = num_res_blocks
self.resolution = resolution
self.attn_resolutions = attn_resolutions
curr_res = self.resolution
in_ch_mult = (1,)+tuple(ch_mult)
blocks = []
# initial convultion
blocks.append(nn.Conv2d(in_channels, nf, kernel_size=3, stride=1, padding=1))
# residual and downsampling blocks, with attention on smaller res (16x16)
for i in range(self.num_resolutions):
block_in_ch = nf * in_ch_mult[i]
block_out_ch = nf * ch_mult[i]
for _ in range(self.num_res_blocks):
blocks.append(ResBlock(block_in_ch, block_out_ch))
block_in_ch = block_out_ch
if curr_res in attn_resolutions:
blocks.append(AttnBlock(block_in_ch))
if i != self.num_resolutions - 1:
blocks.append(Downsample(block_in_ch))
curr_res = curr_res // 2
# non-local attention block
blocks.append(ResBlock(block_in_ch, block_in_ch))
blocks.append(AttnBlock(block_in_ch))
blocks.append(ResBlock(block_in_ch, block_in_ch))
# normalise and convert to latent size
blocks.append(normalize(block_in_ch))
blocks.append(nn.Conv2d(block_in_ch, emb_dim, kernel_size=3, stride=1, padding=1))
self.blocks = nn.ModuleList(blocks)
def forward(self, x):
for block in self.blocks:
x = block(x)
return x
class Generator(nn.Module):
def __init__(self, nf, emb_dim, ch_mult, res_blocks, img_size, attn_resolutions):
super().__init__()
self.nf = nf
self.ch_mult = ch_mult
self.num_resolutions = len(self.ch_mult)
self.num_res_blocks = res_blocks
self.resolution = img_size
self.attn_resolutions = attn_resolutions
self.in_channels = emb_dim
self.out_channels = 3
block_in_ch = self.nf * self.ch_mult[-1]
curr_res = self.resolution // 2 ** (self.num_resolutions-1)
blocks = []
# initial conv
blocks.append(nn.Conv2d(self.in_channels, block_in_ch, kernel_size=3, stride=1, padding=1))
# non-local attention block
blocks.append(ResBlock(block_in_ch, block_in_ch))
blocks.append(AttnBlock(block_in_ch))
blocks.append(ResBlock(block_in_ch, block_in_ch))
for i in reversed(range(self.num_resolutions)):
block_out_ch = self.nf * self.ch_mult[i]
for _ in range(self.num_res_blocks):
blocks.append(ResBlock(block_in_ch, block_out_ch))
block_in_ch = block_out_ch
if curr_res in self.attn_resolutions:
blocks.append(AttnBlock(block_in_ch))
if i != 0:
blocks.append(Upsample(block_in_ch))
curr_res = curr_res * 2
blocks.append(normalize(block_in_ch))
blocks.append(nn.Conv2d(block_in_ch, self.out_channels, kernel_size=3, stride=1, padding=1))
self.blocks = nn.ModuleList(blocks)
def forward(self, x):
for block in self.blocks:
x = block(x)
return x
@ARCH_REGISTRY.register()
class VQAutoEncoder(nn.Module):
def __init__(self, img_size, nf, ch_mult, quantizer="nearest", res_blocks=2, attn_resolutions=None, codebook_size=1024, emb_dim=256,
beta=0.25, gumbel_straight_through=False, gumbel_kl_weight=1e-8, model_path=None):
super().__init__()
logger = get_root_logger()
self.in_channels = 3
self.nf = nf
self.n_blocks = res_blocks
self.codebook_size = codebook_size
self.embed_dim = emb_dim
self.ch_mult = ch_mult
self.resolution = img_size
self.attn_resolutions = attn_resolutions or [16]
self.quantizer_type = quantizer
self.encoder = Encoder(
self.in_channels,
self.nf,
self.embed_dim,
self.ch_mult,
self.n_blocks,
self.resolution,
self.attn_resolutions
)
if self.quantizer_type == "nearest":
self.beta = beta #0.25
self.quantize = VectorQuantizer(self.codebook_size, self.embed_dim, self.beta)
elif self.quantizer_type == "gumbel":
self.gumbel_num_hiddens = emb_dim
self.straight_through = gumbel_straight_through
self.kl_weight = gumbel_kl_weight
self.quantize = GumbelQuantizer(
self.codebook_size,
self.embed_dim,
self.gumbel_num_hiddens,
self.straight_through,
self.kl_weight
)
self.generator = Generator(
self.nf,
self.embed_dim,
self.ch_mult,
self.n_blocks,
self.resolution,
self.attn_resolutions
)
if model_path is not None:
chkpt = torch.load(model_path, map_location='cpu')
if 'params_ema' in chkpt:
self.load_state_dict(torch.load(model_path, map_location='cpu')['params_ema'])
logger.info(f'vqgan is loaded from: {model_path} [params_ema]')
elif 'params' in chkpt:
self.load_state_dict(torch.load(model_path, map_location='cpu')['params'])
logger.info(f'vqgan is loaded from: {model_path} [params]')
else:
raise ValueError('Wrong params!')
def forward(self, x):
x = self.encoder(x)
quant, codebook_loss, quant_stats = self.quantize(x)
x = self.generator(quant)
return x, codebook_loss, quant_stats
# patch based discriminator
@ARCH_REGISTRY.register()
class VQGANDiscriminator(nn.Module):
def __init__(self, nc=3, ndf=64, n_layers=4, model_path=None):
super().__init__()
layers = [nn.Conv2d(nc, ndf, kernel_size=4, stride=2, padding=1), nn.LeakyReLU(0.2, True)]
ndf_mult = 1
ndf_mult_prev = 1
for n in range(1, n_layers): # gradually increase the number of filters
ndf_mult_prev = ndf_mult
ndf_mult = min(2 ** n, 8)
layers += [
nn.Conv2d(ndf * ndf_mult_prev, ndf * ndf_mult, kernel_size=4, stride=2, padding=1, bias=False),
nn.BatchNorm2d(ndf * ndf_mult),
nn.LeakyReLU(0.2, True)
]
ndf_mult_prev = ndf_mult
ndf_mult = min(2 ** n_layers, 8)
layers += [
nn.Conv2d(ndf * ndf_mult_prev, ndf * ndf_mult, kernel_size=4, stride=1, padding=1, bias=False),
nn.BatchNorm2d(ndf * ndf_mult),
nn.LeakyReLU(0.2, True)
]
layers += [
nn.Conv2d(ndf * ndf_mult, 1, kernel_size=4, stride=1, padding=1)] # output 1 channel prediction map
self.main = nn.Sequential(*layers)
if model_path is not None:
chkpt = torch.load(model_path, map_location='cpu')
if 'params_d' in chkpt:
self.load_state_dict(torch.load(model_path, map_location='cpu')['params_d'])
elif 'params' in chkpt:
self.load_state_dict(torch.load(model_path, map_location='cpu')['params'])
else:
raise ValueError('Wrong params!')
def forward(self, x):
return self.main(x)

View File

@ -1,132 +1,64 @@
import os
from __future__ import annotations
import logging
import cv2
import torch
import modules.face_restoration
import modules.shared
from modules import shared, devices, modelloader, errors
from modules.paths import models_path
from modules import (
devices,
errors,
face_restoration,
face_restoration_utils,
modelloader,
shared,
)
logger = logging.getLogger(__name__)
# codeformer people made a choice to include modified basicsr library to their project which makes
# it utterly impossible to use it alongside with other libraries that also use basicsr, like GFPGAN.
# I am making a choice to include some files from codeformer to work around this issue.
model_dir = "Codeformer"
model_path = os.path.join(models_path, model_dir)
model_url = 'https://github.com/sczhou/CodeFormer/releases/download/v0.1.0/codeformer.pth'
model_download_name = 'codeformer-v0.1.0.pth'
codeformer = None
# used by e.g. postprocessing_codeformer.py
codeformer: face_restoration.FaceRestoration | None = None
def setup_model(dirname):
os.makedirs(model_path, exist_ok=True)
class FaceRestorerCodeFormer(face_restoration_utils.CommonFaceRestoration):
def name(self):
return "CodeFormer"
path = modules.paths.paths.get("CodeFormer", None)
if path is None:
return
def load_net(self) -> torch.Module:
for model_path in modelloader.load_models(
model_path=self.model_path,
model_url=model_url,
command_path=self.model_path,
download_name=model_download_name,
ext_filter=['.pth'],
):
return modelloader.load_spandrel_model(
model_path,
device=devices.device_codeformer,
expected_architecture='CodeFormer',
).model
raise ValueError("No codeformer model found")
def get_device(self):
return devices.device_codeformer
def restore(self, np_image, w: float | None = None):
if w is None:
w = getattr(shared.opts, "code_former_weight", 0.5)
def restore_face(cropped_face_t):
assert self.net is not None
return self.net(cropped_face_t, weight=w, adain=True)[0]
return self.restore_with_helper(np_image, restore_face)
def setup_model(dirname: str) -> None:
global codeformer
try:
from torchvision.transforms.functional import normalize
from modules.codeformer.codeformer_arch import CodeFormer
from basicsr.utils import img2tensor, tensor2img
from facelib.utils.face_restoration_helper import FaceRestoreHelper
from facelib.detection.retinaface import retinaface
net_class = CodeFormer
class FaceRestorerCodeFormer(modules.face_restoration.FaceRestoration):
def name(self):
return "CodeFormer"
def __init__(self, dirname):
self.net = None
self.face_helper = None
self.cmd_dir = dirname
def create_models(self):
if self.net is not None and self.face_helper is not None:
self.net.to(devices.device_codeformer)
return self.net, self.face_helper
model_paths = modelloader.load_models(model_path, model_url, self.cmd_dir, download_name='codeformer-v0.1.0.pth', ext_filter=['.pth'])
if len(model_paths) != 0:
ckpt_path = model_paths[0]
else:
print("Unable to load codeformer model.")
return None, None
net = net_class(dim_embd=512, codebook_size=1024, n_head=8, n_layers=9, connect_list=['32', '64', '128', '256']).to(devices.device_codeformer)
checkpoint = torch.load(ckpt_path)['params_ema']
net.load_state_dict(checkpoint)
net.eval()
if hasattr(retinaface, 'device'):
retinaface.device = devices.device_codeformer
face_helper = FaceRestoreHelper(1, face_size=512, crop_ratio=(1, 1), det_model='retinaface_resnet50', save_ext='png', use_parse=True, device=devices.device_codeformer)
self.net = net
self.face_helper = face_helper
return net, face_helper
def send_model_to(self, device):
self.net.to(device)
self.face_helper.face_det.to(device)
self.face_helper.face_parse.to(device)
def restore(self, np_image, w=None):
np_image = np_image[:, :, ::-1]
original_resolution = np_image.shape[0:2]
self.create_models()
if self.net is None or self.face_helper is None:
return np_image
self.send_model_to(devices.device_codeformer)
self.face_helper.clean_all()
self.face_helper.read_image(np_image)
self.face_helper.get_face_landmarks_5(only_center_face=False, resize=640, eye_dist_threshold=5)
self.face_helper.align_warp_face()
for cropped_face in self.face_helper.cropped_faces:
cropped_face_t = img2tensor(cropped_face / 255., bgr2rgb=True, float32=True)
normalize(cropped_face_t, (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True)
cropped_face_t = cropped_face_t.unsqueeze(0).to(devices.device_codeformer)
try:
with torch.no_grad():
output = self.net(cropped_face_t, w=w if w is not None else shared.opts.code_former_weight, adain=True)[0]
restored_face = tensor2img(output, rgb2bgr=True, min_max=(-1, 1))
del output
devices.torch_gc()
except Exception:
errors.report('Failed inference for CodeFormer', exc_info=True)
restored_face = tensor2img(cropped_face_t, rgb2bgr=True, min_max=(-1, 1))
restored_face = restored_face.astype('uint8')
self.face_helper.add_restored_face(restored_face)
self.face_helper.get_inverse_affine(None)
restored_img = self.face_helper.paste_faces_to_input_image()
restored_img = restored_img[:, :, ::-1]
if original_resolution != restored_img.shape[0:2]:
restored_img = cv2.resize(restored_img, (0, 0), fx=original_resolution[1]/restored_img.shape[1], fy=original_resolution[0]/restored_img.shape[0], interpolation=cv2.INTER_LINEAR)
self.face_helper.clean_all()
if shared.opts.face_restoration_unload:
self.send_model_to(devices.cpu)
return restored_img
global codeformer
codeformer = FaceRestorerCodeFormer(dirname)
shared.face_restorers.append(codeformer)
except Exception:
errors.report("Error setting up CodeFormer", exc_info=True)
# sys.path = stored_sys_path

View File

@ -4,18 +4,15 @@ Supports saving and restoring webui and extensions from a known working set of c
import os
import json
import time
import tqdm
from datetime import datetime
from collections import OrderedDict
import git
from modules import shared, extensions, errors
from modules.paths_internal import script_path, config_states_dir
all_config_states = OrderedDict()
all_config_states = {}
def list_config_states():
@ -28,15 +25,19 @@ def list_config_states():
for filename in os.listdir(config_states_dir):
if filename.endswith(".json"):
path = os.path.join(config_states_dir, filename)
with open(path, "r", encoding="utf-8") as f:
j = json.load(f)
j["filepath"] = path
config_states.append(j)
try:
with open(path, "r", encoding="utf-8") as f:
j = json.load(f)
assert "created_at" in j, '"created_at" does not exist'
j["filepath"] = path
config_states.append(j)
except Exception as e:
print(f'[ERROR]: Config states {path}, {e}')
config_states = sorted(config_states, key=lambda cs: cs["created_at"], reverse=True)
for cs in config_states:
timestamp = time.asctime(time.gmtime(cs["created_at"]))
timestamp = datetime.fromtimestamp(cs["created_at"]).strftime('%Y-%m-%d %H:%M:%S')
name = cs.get("name", "Config")
full_name = f"{name}: {timestamp}"
all_config_states[full_name] = cs

79
modules/dat_model.py Normal file
View File

@ -0,0 +1,79 @@
import os
from modules import modelloader, errors
from modules.shared import cmd_opts, opts
from modules.upscaler import Upscaler, UpscalerData
from modules.upscaler_utils import upscale_with_model
class UpscalerDAT(Upscaler):
def __init__(self, user_path):
self.name = "DAT"
self.user_path = user_path
self.scalers = []
super().__init__()
for file in self.find_models(ext_filter=[".pt", ".pth"]):
name = modelloader.friendly_name(file)
scaler_data = UpscalerData(name, file, upscaler=self, scale=None)
self.scalers.append(scaler_data)
for model in get_dat_models(self):
if model.name in opts.dat_enabled_models:
self.scalers.append(model)
def do_upscale(self, img, path):
try:
info = self.load_model(path)
except Exception:
errors.report(f"Unable to load DAT model {path}", exc_info=True)
return img
model_descriptor = modelloader.load_spandrel_model(
info.local_data_path,
device=self.device,
prefer_half=(not cmd_opts.no_half and not cmd_opts.upcast_sampling),
expected_architecture="DAT",
)
return upscale_with_model(
model_descriptor,
img,
tile_size=opts.DAT_tile,
tile_overlap=opts.DAT_tile_overlap,
)
def load_model(self, path):
for scaler in self.scalers:
if scaler.data_path == path:
if scaler.local_data_path.startswith("http"):
scaler.local_data_path = modelloader.load_file_from_url(
scaler.data_path,
model_dir=self.model_download_path,
)
if not os.path.exists(scaler.local_data_path):
raise FileNotFoundError(f"DAT data missing: {scaler.local_data_path}")
return scaler
raise ValueError(f"Unable to find model info: {path}")
def get_dat_models(scaler):
return [
UpscalerData(
name="DAT x2",
path="https://github.com/n0kovo/dat_upscaler_models/raw/main/DAT/DAT_x2.pth",
scale=2,
upscaler=scaler,
),
UpscalerData(
name="DAT x3",
path="https://github.com/n0kovo/dat_upscaler_models/raw/main/DAT/DAT_x3.pth",
scale=3,
upscaler=scaler,
),
UpscalerData(
name="DAT x4",
path="https://github.com/n0kovo/dat_upscaler_models/raw/main/DAT/DAT_x4.pth",
scale=4,
upscaler=scaler,
),
]

View File

@ -57,7 +57,7 @@ class DeepDanbooru:
a = np.expand_dims(np.array(pic, dtype=np.float32), 0) / 255
with torch.no_grad(), devices.autocast():
x = torch.from_numpy(a).to(devices.device)
x = torch.from_numpy(a).to(devices.device, devices.dtype)
y = self.model(x)[0].detach().cpu().numpy()
probability_dict = {}

View File

@ -3,11 +3,18 @@ import contextlib
from functools import lru_cache
import torch
from modules import errors
from modules import errors, shared, npu_specific
if sys.platform == "darwin":
from modules import mac_specific
if shared.cmd_opts.use_ipex:
from modules import xpu_specific
def has_xpu() -> bool:
return shared.cmd_opts.use_ipex and xpu_specific.has_xpu
def has_mps() -> bool:
if sys.platform != "darwin":
@ -16,9 +23,24 @@ def has_mps() -> bool:
return mac_specific.has_mps
def get_cuda_device_string():
from modules import shared
def cuda_no_autocast(device_id=None) -> bool:
if device_id is None:
device_id = get_cuda_device_id()
return (
torch.cuda.get_device_capability(device_id) == (7, 5)
and torch.cuda.get_device_name(device_id).startswith("NVIDIA GeForce GTX 16")
)
def get_cuda_device_id():
return (
int(shared.cmd_opts.device_id)
if shared.cmd_opts.device_id is not None and shared.cmd_opts.device_id.isdigit()
else 0
) or torch.cuda.current_device()
def get_cuda_device_string():
if shared.cmd_opts.device_id is not None:
return f"cuda:{shared.cmd_opts.device_id}"
@ -32,6 +54,12 @@ def get_optimal_device_name():
if has_mps():
return "mps"
if has_xpu():
return xpu_specific.get_xpu_device_string()
if npu_specific.has_npu:
return npu_specific.get_npu_device_string()
return "cpu"
@ -40,9 +68,7 @@ def get_optimal_device():
def get_device_for(task):
from modules import shared
if task in shared.cmd_opts.use_cpu:
if task in shared.cmd_opts.use_cpu or "all" in shared.cmd_opts.use_cpu:
return cpu
return get_optimal_device()
@ -58,31 +84,54 @@ def torch_gc():
if has_mps():
mac_specific.torch_mps_gc()
if has_xpu():
xpu_specific.torch_xpu_gc()
if npu_specific.has_npu:
torch_npu_set_device()
npu_specific.torch_npu_gc()
def torch_npu_set_device():
# Work around due to bug in torch_npu, revert me after fixed, @see https://gitee.com/ascend/pytorch/issues/I8KECW?from=project-issue
if npu_specific.has_npu:
torch.npu.set_device(0)
def enable_tf32():
if torch.cuda.is_available():
# enabling benchmark option seems to enable a range of cards to do fp16 when they otherwise can't
# see https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/4407
if any(torch.cuda.get_device_capability(devid) == (7, 5) for devid in range(0, torch.cuda.device_count())):
if cuda_no_autocast():
torch.backends.cudnn.benchmark = True
torch.backends.cuda.matmul.allow_tf32 = True
torch.backends.cudnn.allow_tf32 = True
errors.run(enable_tf32, "Enabling TF32")
cpu = torch.device("cpu")
device = device_interrogate = device_gfpgan = device_esrgan = device_codeformer = None
dtype = torch.float16
dtype_vae = torch.float16
dtype_unet = torch.float16
cpu: torch.device = torch.device("cpu")
fp8: bool = False
# Force fp16 for all models in inference. No casting during inference.
# This flag is controlled by "--precision half" command line arg.
force_fp16: bool = False
device: torch.device = None
device_interrogate: torch.device = None
device_gfpgan: torch.device = None
device_esrgan: torch.device = None
device_codeformer: torch.device = None
dtype: torch.dtype = torch.float16
dtype_vae: torch.dtype = torch.float16
dtype_unet: torch.dtype = torch.float16
dtype_inference: torch.dtype = torch.float16
unet_needs_upcast = False
def cond_cast_unet(input):
if force_fp16:
return input.to(torch.float16)
return input.to(dtype_unet) if unet_needs_upcast else input
@ -90,32 +139,95 @@ def cond_cast_float(input):
return input.float() if unet_needs_upcast else input
def randn(seed, shape):
from modules.shared import opts
torch.manual_seed(seed)
if opts.randn_source == "CPU" or device.type == 'mps':
return torch.randn(shape, device=cpu).to(device)
return torch.randn(shape, device=device)
nv_rng = None
patch_module_list = [
torch.nn.Linear,
torch.nn.Conv2d,
torch.nn.MultiheadAttention,
torch.nn.GroupNorm,
torch.nn.LayerNorm,
]
def randn_without_seed(shape):
from modules.shared import opts
def manual_cast_forward(target_dtype):
def forward_wrapper(self, *args, **kwargs):
if any(
isinstance(arg, torch.Tensor) and arg.dtype != target_dtype
for arg in args
):
args = [arg.to(target_dtype) if isinstance(arg, torch.Tensor) else arg for arg in args]
kwargs = {k: v.to(target_dtype) if isinstance(v, torch.Tensor) else v for k, v in kwargs.items()}
if opts.randn_source == "CPU" or device.type == 'mps':
return torch.randn(shape, device=cpu).to(device)
return torch.randn(shape, device=device)
org_dtype = target_dtype
for param in self.parameters():
if param.dtype != target_dtype:
org_dtype = param.dtype
break
if org_dtype != target_dtype:
self.to(target_dtype)
result = self.org_forward(*args, **kwargs)
if org_dtype != target_dtype:
self.to(org_dtype)
if target_dtype != dtype_inference:
if isinstance(result, tuple):
result = tuple(
i.to(dtype_inference)
if isinstance(i, torch.Tensor)
else i
for i in result
)
elif isinstance(result, torch.Tensor):
result = result.to(dtype_inference)
return result
return forward_wrapper
@contextlib.contextmanager
def manual_cast(target_dtype):
applied = False
for module_type in patch_module_list:
if hasattr(module_type, "org_forward"):
continue
applied = True
org_forward = module_type.forward
if module_type == torch.nn.MultiheadAttention:
module_type.forward = manual_cast_forward(torch.float32)
else:
module_type.forward = manual_cast_forward(target_dtype)
module_type.org_forward = org_forward
try:
yield None
finally:
if applied:
for module_type in patch_module_list:
if hasattr(module_type, "org_forward"):
module_type.forward = module_type.org_forward
delattr(module_type, "org_forward")
def autocast(disable=False):
from modules import shared
if disable:
return contextlib.nullcontext()
if dtype == torch.float32 or shared.cmd_opts.precision == "full":
if force_fp16:
# No casting during inference if force_fp16 is enabled.
# All tensor dtype conversion happens before inference.
return contextlib.nullcontext()
if fp8 and device==cpu:
return torch.autocast("cpu", dtype=torch.bfloat16, enabled=True)
if fp8 and dtype_inference == torch.float32:
return manual_cast(dtype)
if dtype == torch.float32 or dtype_inference == torch.float32:
return contextlib.nullcontext()
if has_xpu() or has_mps() or cuda_no_autocast():
return manual_cast(dtype)
return torch.autocast("cuda")
@ -128,27 +240,25 @@ class NansException(Exception):
def test_for_nans(x, where):
from modules import shared
if shared.cmd_opts.disable_nan_check:
return
if not torch.all(torch.isnan(x)).item():
if not torch.isnan(x[(0, ) * len(x.shape)]):
return
if where == "unet":
message = "A tensor with all NaNs was produced in Unet."
message = "A tensor with NaNs was produced in Unet."
if not shared.cmd_opts.no_half:
message += " This could be either because there's not enough precision to represent the picture, or because your video card does not support half type. Try setting the \"Upcast cross attention layer to float32\" option in Settings > Stable Diffusion or using the --no-half commandline argument to fix this."
elif where == "vae":
message = "A tensor with all NaNs was produced in VAE."
message = "A tensor with NaNs was produced in VAE."
if not shared.cmd_opts.no_half and not shared.cmd_opts.no_half_vae:
message += " This could be because there's not enough precision to represent the picture. Try adding --no-half-vae commandline argument to fix this."
else:
message = "A tensor with all NaNs was produced."
message = "A tensor with NaNs was produced."
message += " Use --disable-nan-check commandline argument to disable this check."
@ -158,8 +268,8 @@ def test_for_nans(x, where):
@lru_cache
def first_time_calculation():
"""
just do any calculation with pytorch layers - the first time this is done it allocaltes about 700MB of memory and
spends about 2.7 seconds doing that, at least wih NVidia.
just do any calculation with pytorch layers - the first time this is done it allocates about 700MB of memory and
spends about 2.7 seconds doing that, at least with NVidia.
"""
x = torch.zeros((1, 1)).to(device, dtype)
@ -169,3 +279,17 @@ def first_time_calculation():
x = torch.zeros((1, 1, 3, 3)).to(device, dtype)
conv2d = torch.nn.Conv2d(1, 1, (3, 3)).to(device, dtype)
conv2d(x)
def force_model_fp16():
"""
ldm and sgm has modules.diffusionmodules.util.GroupNorm32.forward, which
force conversion of input to float32. If force_fp16 is enabled, we need to
prevent this casting.
"""
assert force_fp16
import sgm.modules.diffusionmodules.util as sgm_util
import ldm.modules.diffusionmodules.util as ldm_util
sgm_util.GroupNorm32 = torch.nn.GroupNorm
ldm_util.GroupNorm32 = torch.nn.GroupNorm
print("ldm/sgm GroupNorm32 replaced with normal torch.nn.GroupNorm due to `--precision half`.")

View File

@ -6,6 +6,21 @@ import traceback
exception_records = []
def format_traceback(tb):
return [[f"{x.filename}, line {x.lineno}, {x.name}", x.line] for x in traceback.extract_tb(tb)]
def format_exception(e, tb):
return {"exception": str(e), "traceback": format_traceback(tb)}
def get_exceptions():
try:
return list(reversed(exception_records))
except Exception as e:
return str(e)
def record_exception():
_, e, tb = sys.exc_info()
if e is None:
@ -14,7 +29,7 @@ def record_exception():
if exception_records and exception_records[-1] == e:
return
exception_records.append((e, tb))
exception_records.append(format_exception(e, tb))
if len(exception_records) > 5:
exception_records.pop(0)
@ -83,3 +98,53 @@ def run(code, task):
code()
except Exception as e:
display(task, e)
def check_versions():
from packaging import version
from modules import shared
import torch
import gradio
expected_torch_version = "2.1.2"
expected_xformers_version = "0.0.23.post1"
expected_gradio_version = "3.41.2"
if version.parse(torch.__version__) < version.parse(expected_torch_version):
print_error_explanation(f"""
You are running torch {torch.__version__}.
The program is tested to work with torch {expected_torch_version}.
To reinstall the desired version, run with commandline flag --reinstall-torch.
Beware that this will cause a lot of large files to be downloaded, as well as
there are reports of issues with training tab on the latest version.
Use --skip-version-check commandline argument to disable this check.
""".strip())
if shared.xformers_available:
import xformers
if version.parse(xformers.__version__) < version.parse(expected_xformers_version):
print_error_explanation(f"""
You are running xformers {xformers.__version__}.
The program is tested to work with xformers {expected_xformers_version}.
To reinstall the desired version, run with commandline flag --reinstall-xformers.
Use --skip-version-check commandline argument to disable this check.
""".strip())
if gradio.__version__ != expected_gradio_version:
print_error_explanation(f"""
You are running gradio {gradio.__version__}.
The program is designed to work with gradio {expected_gradio_version}.
Using a different version of gradio is extremely likely to break the program.
Reasons why you have the mismatched gradio version can be:
- you use --skip-install flag.
- you use webui.py to start the program instead of launch.py.
- an extension installs the incompatible gradio version.
Use --skip-version-check commandline argument to disable this check.
""".strip())

View File

@ -1,121 +1,7 @@
import sys
import numpy as np
import torch
from PIL import Image
import modules.esrgan_model_arch as arch
from modules import modelloader, images, devices
from modules import modelloader, devices, errors
from modules.shared import opts
from modules.upscaler import Upscaler, UpscalerData
def mod2normal(state_dict):
# this code is copied from https://github.com/victorca25/iNNfer
if 'conv_first.weight' in state_dict:
crt_net = {}
items = list(state_dict)
crt_net['model.0.weight'] = state_dict['conv_first.weight']
crt_net['model.0.bias'] = state_dict['conv_first.bias']
for k in items.copy():
if 'RDB' in k:
ori_k = k.replace('RRDB_trunk.', 'model.1.sub.')
if '.weight' in k:
ori_k = ori_k.replace('.weight', '.0.weight')
elif '.bias' in k:
ori_k = ori_k.replace('.bias', '.0.bias')
crt_net[ori_k] = state_dict[k]
items.remove(k)
crt_net['model.1.sub.23.weight'] = state_dict['trunk_conv.weight']
crt_net['model.1.sub.23.bias'] = state_dict['trunk_conv.bias']
crt_net['model.3.weight'] = state_dict['upconv1.weight']
crt_net['model.3.bias'] = state_dict['upconv1.bias']
crt_net['model.6.weight'] = state_dict['upconv2.weight']
crt_net['model.6.bias'] = state_dict['upconv2.bias']
crt_net['model.8.weight'] = state_dict['HRconv.weight']
crt_net['model.8.bias'] = state_dict['HRconv.bias']
crt_net['model.10.weight'] = state_dict['conv_last.weight']
crt_net['model.10.bias'] = state_dict['conv_last.bias']
state_dict = crt_net
return state_dict
def resrgan2normal(state_dict, nb=23):
# this code is copied from https://github.com/victorca25/iNNfer
if "conv_first.weight" in state_dict and "body.0.rdb1.conv1.weight" in state_dict:
re8x = 0
crt_net = {}
items = list(state_dict)
crt_net['model.0.weight'] = state_dict['conv_first.weight']
crt_net['model.0.bias'] = state_dict['conv_first.bias']
for k in items.copy():
if "rdb" in k:
ori_k = k.replace('body.', 'model.1.sub.')
ori_k = ori_k.replace('.rdb', '.RDB')
if '.weight' in k:
ori_k = ori_k.replace('.weight', '.0.weight')
elif '.bias' in k:
ori_k = ori_k.replace('.bias', '.0.bias')
crt_net[ori_k] = state_dict[k]
items.remove(k)
crt_net[f'model.1.sub.{nb}.weight'] = state_dict['conv_body.weight']
crt_net[f'model.1.sub.{nb}.bias'] = state_dict['conv_body.bias']
crt_net['model.3.weight'] = state_dict['conv_up1.weight']
crt_net['model.3.bias'] = state_dict['conv_up1.bias']
crt_net['model.6.weight'] = state_dict['conv_up2.weight']
crt_net['model.6.bias'] = state_dict['conv_up2.bias']
if 'conv_up3.weight' in state_dict:
# modification supporting: https://github.com/ai-forever/Real-ESRGAN/blob/main/RealESRGAN/rrdbnet_arch.py
re8x = 3
crt_net['model.9.weight'] = state_dict['conv_up3.weight']
crt_net['model.9.bias'] = state_dict['conv_up3.bias']
crt_net[f'model.{8+re8x}.weight'] = state_dict['conv_hr.weight']
crt_net[f'model.{8+re8x}.bias'] = state_dict['conv_hr.bias']
crt_net[f'model.{10+re8x}.weight'] = state_dict['conv_last.weight']
crt_net[f'model.{10+re8x}.bias'] = state_dict['conv_last.bias']
state_dict = crt_net
return state_dict
def infer_params(state_dict):
# this code is copied from https://github.com/victorca25/iNNfer
scale2x = 0
scalemin = 6
n_uplayer = 0
plus = False
for block in list(state_dict):
parts = block.split(".")
n_parts = len(parts)
if n_parts == 5 and parts[2] == "sub":
nb = int(parts[3])
elif n_parts == 3:
part_num = int(parts[1])
if (part_num > scalemin
and parts[0] == "model"
and parts[2] == "weight"):
scale2x += 1
if part_num > n_uplayer:
n_uplayer = part_num
out_nc = state_dict[block].shape[0]
if not plus and "conv1x1" in block:
plus = True
nf = state_dict["model.0.weight"].shape[0]
in_nc = state_dict["model.0.weight"].shape[1]
out_nc = out_nc
scale = 2 ** scale2x
return in_nc, out_nc, nf, nb, plus, scale
from modules.upscaler_utils import upscale_with_model
class UpscalerESRGAN(Upscaler):
@ -143,12 +29,11 @@ class UpscalerESRGAN(Upscaler):
def do_upscale(self, img, selected_model):
try:
model = self.load_model(selected_model)
except Exception as e:
print(f"Unable to load ESRGAN model {selected_model}: {e}", file=sys.stderr)
except Exception:
errors.report(f"Unable to load ESRGAN model {selected_model}", exc_info=True)
return img
model.to(devices.device_esrgan)
img = esrgan_upscale(model, img)
return img
return esrgan_upscale(model, img)
def load_model(self, path: str):
if path.startswith("http"):
@ -161,69 +46,17 @@ class UpscalerESRGAN(Upscaler):
else:
filename = path
state_dict = torch.load(filename, map_location='cpu' if devices.device_esrgan.type == 'mps' else None)
if "params_ema" in state_dict:
state_dict = state_dict["params_ema"]
elif "params" in state_dict:
state_dict = state_dict["params"]
num_conv = 16 if "realesr-animevideov3" in filename else 32
model = arch.SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=num_conv, upscale=4, act_type='prelu')
model.load_state_dict(state_dict)
model.eval()
return model
if "body.0.rdb1.conv1.weight" in state_dict and "conv_first.weight" in state_dict:
nb = 6 if "RealESRGAN_x4plus_anime_6B" in filename else 23
state_dict = resrgan2normal(state_dict, nb)
elif "conv_first.weight" in state_dict:
state_dict = mod2normal(state_dict)
elif "model.0.weight" not in state_dict:
raise Exception("The file is not a recognized ESRGAN model.")
in_nc, out_nc, nf, nb, plus, mscale = infer_params(state_dict)
model = arch.RRDBNet(in_nc=in_nc, out_nc=out_nc, nf=nf, nb=nb, upscale=mscale, plus=plus)
model.load_state_dict(state_dict)
model.eval()
return model
def upscale_without_tiling(model, img):
img = np.array(img)
img = img[:, :, ::-1]
img = np.ascontiguousarray(np.transpose(img, (2, 0, 1))) / 255
img = torch.from_numpy(img).float()
img = img.unsqueeze(0).to(devices.device_esrgan)
with torch.no_grad():
output = model(img)
output = output.squeeze().float().cpu().clamp_(0, 1).numpy()
output = 255. * np.moveaxis(output, 0, 2)
output = output.astype(np.uint8)
output = output[:, :, ::-1]
return Image.fromarray(output, 'RGB')
return modelloader.load_spandrel_model(
filename,
device=('cpu' if devices.device_esrgan.type == 'mps' else None),
expected_architecture='ESRGAN',
)
def esrgan_upscale(model, img):
if opts.ESRGAN_tile == 0:
return upscale_without_tiling(model, img)
grid = images.split_grid(img, opts.ESRGAN_tile, opts.ESRGAN_tile, opts.ESRGAN_tile_overlap)
newtiles = []
scale_factor = 1
for y, h, row in grid.tiles:
newrow = []
for tiledata in row:
x, w, tile = tiledata
output = upscale_without_tiling(model, tile)
scale_factor = output.width // tile.width
newrow.append([x * scale_factor, w * scale_factor, output])
newtiles.append([y * scale_factor, h * scale_factor, newrow])
newgrid = images.Grid(newtiles, grid.tile_w * scale_factor, grid.tile_h * scale_factor, grid.image_w * scale_factor, grid.image_h * scale_factor, grid.overlap * scale_factor)
output = images.combine_grid(newgrid)
return output
return upscale_with_model(
model,
img,
tile_size=opts.ESRGAN_tile,
tile_overlap=opts.ESRGAN_tile_overlap,
)

View File

@ -1,465 +0,0 @@
# this file is adapted from https://github.com/victorca25/iNNfer
from collections import OrderedDict
import math
import torch
import torch.nn as nn
import torch.nn.functional as F
####################
# RRDBNet Generator
####################
class RRDBNet(nn.Module):
def __init__(self, in_nc, out_nc, nf, nb, nr=3, gc=32, upscale=4, norm_type=None,
act_type='leakyrelu', mode='CNA', upsample_mode='upconv', convtype='Conv2D',
finalact=None, gaussian_noise=False, plus=False):
super(RRDBNet, self).__init__()
n_upscale = int(math.log(upscale, 2))
if upscale == 3:
n_upscale = 1
self.resrgan_scale = 0
if in_nc % 16 == 0:
self.resrgan_scale = 1
elif in_nc != 4 and in_nc % 4 == 0:
self.resrgan_scale = 2
fea_conv = conv_block(in_nc, nf, kernel_size=3, norm_type=None, act_type=None, convtype=convtype)
rb_blocks = [RRDB(nf, nr, kernel_size=3, gc=32, stride=1, bias=1, pad_type='zero',
norm_type=norm_type, act_type=act_type, mode='CNA', convtype=convtype,
gaussian_noise=gaussian_noise, plus=plus) for _ in range(nb)]
LR_conv = conv_block(nf, nf, kernel_size=3, norm_type=norm_type, act_type=None, mode=mode, convtype=convtype)
if upsample_mode == 'upconv':
upsample_block = upconv_block
elif upsample_mode == 'pixelshuffle':
upsample_block = pixelshuffle_block
else:
raise NotImplementedError(f'upsample mode [{upsample_mode}] is not found')
if upscale == 3:
upsampler = upsample_block(nf, nf, 3, act_type=act_type, convtype=convtype)
else:
upsampler = [upsample_block(nf, nf, act_type=act_type, convtype=convtype) for _ in range(n_upscale)]
HR_conv0 = conv_block(nf, nf, kernel_size=3, norm_type=None, act_type=act_type, convtype=convtype)
HR_conv1 = conv_block(nf, out_nc, kernel_size=3, norm_type=None, act_type=None, convtype=convtype)
outact = act(finalact) if finalact else None
self.model = sequential(fea_conv, ShortcutBlock(sequential(*rb_blocks, LR_conv)),
*upsampler, HR_conv0, HR_conv1, outact)
def forward(self, x, outm=None):
if self.resrgan_scale == 1:
feat = pixel_unshuffle(x, scale=4)
elif self.resrgan_scale == 2:
feat = pixel_unshuffle(x, scale=2)
else:
feat = x
return self.model(feat)
class RRDB(nn.Module):
"""
Residual in Residual Dense Block
(ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks)
"""
def __init__(self, nf, nr=3, kernel_size=3, gc=32, stride=1, bias=1, pad_type='zero',
norm_type=None, act_type='leakyrelu', mode='CNA', convtype='Conv2D',
spectral_norm=False, gaussian_noise=False, plus=False):
super(RRDB, self).__init__()
# This is for backwards compatibility with existing models
if nr == 3:
self.RDB1 = ResidualDenseBlock_5C(nf, kernel_size, gc, stride, bias, pad_type,
norm_type, act_type, mode, convtype, spectral_norm=spectral_norm,
gaussian_noise=gaussian_noise, plus=plus)
self.RDB2 = ResidualDenseBlock_5C(nf, kernel_size, gc, stride, bias, pad_type,
norm_type, act_type, mode, convtype, spectral_norm=spectral_norm,
gaussian_noise=gaussian_noise, plus=plus)
self.RDB3 = ResidualDenseBlock_5C(nf, kernel_size, gc, stride, bias, pad_type,
norm_type, act_type, mode, convtype, spectral_norm=spectral_norm,
gaussian_noise=gaussian_noise, plus=plus)
else:
RDB_list = [ResidualDenseBlock_5C(nf, kernel_size, gc, stride, bias, pad_type,
norm_type, act_type, mode, convtype, spectral_norm=spectral_norm,
gaussian_noise=gaussian_noise, plus=plus) for _ in range(nr)]
self.RDBs = nn.Sequential(*RDB_list)
def forward(self, x):
if hasattr(self, 'RDB1'):
out = self.RDB1(x)
out = self.RDB2(out)
out = self.RDB3(out)
else:
out = self.RDBs(x)
return out * 0.2 + x
class ResidualDenseBlock_5C(nn.Module):
"""
Residual Dense Block
The core module of paper: (Residual Dense Network for Image Super-Resolution, CVPR 18)
Modified options that can be used:
- "Partial Convolution based Padding" arXiv:1811.11718
- "Spectral normalization" arXiv:1802.05957
- "ICASSP 2020 - ESRGAN+ : Further Improving ESRGAN" N. C.
{Rakotonirina} and A. {Rasoanaivo}
"""
def __init__(self, nf=64, kernel_size=3, gc=32, stride=1, bias=1, pad_type='zero',
norm_type=None, act_type='leakyrelu', mode='CNA', convtype='Conv2D',
spectral_norm=False, gaussian_noise=False, plus=False):
super(ResidualDenseBlock_5C, self).__init__()
self.noise = GaussianNoise() if gaussian_noise else None
self.conv1x1 = conv1x1(nf, gc) if plus else None
self.conv1 = conv_block(nf, gc, kernel_size, stride, bias=bias, pad_type=pad_type,
norm_type=norm_type, act_type=act_type, mode=mode, convtype=convtype,
spectral_norm=spectral_norm)
self.conv2 = conv_block(nf+gc, gc, kernel_size, stride, bias=bias, pad_type=pad_type,
norm_type=norm_type, act_type=act_type, mode=mode, convtype=convtype,
spectral_norm=spectral_norm)
self.conv3 = conv_block(nf+2*gc, gc, kernel_size, stride, bias=bias, pad_type=pad_type,
norm_type=norm_type, act_type=act_type, mode=mode, convtype=convtype,
spectral_norm=spectral_norm)
self.conv4 = conv_block(nf+3*gc, gc, kernel_size, stride, bias=bias, pad_type=pad_type,
norm_type=norm_type, act_type=act_type, mode=mode, convtype=convtype,
spectral_norm=spectral_norm)
if mode == 'CNA':
last_act = None
else:
last_act = act_type
self.conv5 = conv_block(nf+4*gc, nf, 3, stride, bias=bias, pad_type=pad_type,
norm_type=norm_type, act_type=last_act, mode=mode, convtype=convtype,
spectral_norm=spectral_norm)
def forward(self, x):
x1 = self.conv1(x)
x2 = self.conv2(torch.cat((x, x1), 1))
if self.conv1x1:
x2 = x2 + self.conv1x1(x)
x3 = self.conv3(torch.cat((x, x1, x2), 1))
x4 = self.conv4(torch.cat((x, x1, x2, x3), 1))
if self.conv1x1:
x4 = x4 + x2
x5 = self.conv5(torch.cat((x, x1, x2, x3, x4), 1))
if self.noise:
return self.noise(x5.mul(0.2) + x)
else:
return x5 * 0.2 + x
####################
# ESRGANplus
####################
class GaussianNoise(nn.Module):
def __init__(self, sigma=0.1, is_relative_detach=False):
super().__init__()
self.sigma = sigma
self.is_relative_detach = is_relative_detach
self.noise = torch.tensor(0, dtype=torch.float)
def forward(self, x):
if self.training and self.sigma != 0:
self.noise = self.noise.to(x.device)
scale = self.sigma * x.detach() if self.is_relative_detach else self.sigma * x
sampled_noise = self.noise.repeat(*x.size()).normal_() * scale
x = x + sampled_noise
return x
def conv1x1(in_planes, out_planes, stride=1):
return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)
####################
# SRVGGNetCompact
####################
class SRVGGNetCompact(nn.Module):
"""A compact VGG-style network structure for super-resolution.
This class is copied from https://github.com/xinntao/Real-ESRGAN
"""
def __init__(self, num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=16, upscale=4, act_type='prelu'):
super(SRVGGNetCompact, self).__init__()
self.num_in_ch = num_in_ch
self.num_out_ch = num_out_ch
self.num_feat = num_feat
self.num_conv = num_conv
self.upscale = upscale
self.act_type = act_type
self.body = nn.ModuleList()
# the first conv
self.body.append(nn.Conv2d(num_in_ch, num_feat, 3, 1, 1))
# the first activation
if act_type == 'relu':
activation = nn.ReLU(inplace=True)
elif act_type == 'prelu':
activation = nn.PReLU(num_parameters=num_feat)
elif act_type == 'leakyrelu':
activation = nn.LeakyReLU(negative_slope=0.1, inplace=True)
self.body.append(activation)
# the body structure
for _ in range(num_conv):
self.body.append(nn.Conv2d(num_feat, num_feat, 3, 1, 1))
# activation
if act_type == 'relu':
activation = nn.ReLU(inplace=True)
elif act_type == 'prelu':
activation = nn.PReLU(num_parameters=num_feat)
elif act_type == 'leakyrelu':
activation = nn.LeakyReLU(negative_slope=0.1, inplace=True)
self.body.append(activation)
# the last conv
self.body.append(nn.Conv2d(num_feat, num_out_ch * upscale * upscale, 3, 1, 1))
# upsample
self.upsampler = nn.PixelShuffle(upscale)
def forward(self, x):
out = x
for i in range(0, len(self.body)):
out = self.body[i](out)
out = self.upsampler(out)
# add the nearest upsampled image, so that the network learns the residual
base = F.interpolate(x, scale_factor=self.upscale, mode='nearest')
out += base
return out
####################
# Upsampler
####################
class Upsample(nn.Module):
r"""Upsamples a given multi-channel 1D (temporal), 2D (spatial) or 3D (volumetric) data.
The input data is assumed to be of the form
`minibatch x channels x [optional depth] x [optional height] x width`.
"""
def __init__(self, size=None, scale_factor=None, mode="nearest", align_corners=None):
super(Upsample, self).__init__()
if isinstance(scale_factor, tuple):
self.scale_factor = tuple(float(factor) for factor in scale_factor)
else:
self.scale_factor = float(scale_factor) if scale_factor else None
self.mode = mode
self.size = size
self.align_corners = align_corners
def forward(self, x):
return nn.functional.interpolate(x, size=self.size, scale_factor=self.scale_factor, mode=self.mode, align_corners=self.align_corners)
def extra_repr(self):
if self.scale_factor is not None:
info = f'scale_factor={self.scale_factor}'
else:
info = f'size={self.size}'
info += f', mode={self.mode}'
return info
def pixel_unshuffle(x, scale):
""" Pixel unshuffle.
Args:
x (Tensor): Input feature with shape (b, c, hh, hw).
scale (int): Downsample ratio.
Returns:
Tensor: the pixel unshuffled feature.
"""
b, c, hh, hw = x.size()
out_channel = c * (scale**2)
assert hh % scale == 0 and hw % scale == 0
h = hh // scale
w = hw // scale
x_view = x.view(b, c, h, scale, w, scale)
return x_view.permute(0, 1, 3, 5, 2, 4).reshape(b, out_channel, h, w)
def pixelshuffle_block(in_nc, out_nc, upscale_factor=2, kernel_size=3, stride=1, bias=True,
pad_type='zero', norm_type=None, act_type='relu', convtype='Conv2D'):
"""
Pixel shuffle layer
(Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional
Neural Network, CVPR17)
"""
conv = conv_block(in_nc, out_nc * (upscale_factor ** 2), kernel_size, stride, bias=bias,
pad_type=pad_type, norm_type=None, act_type=None, convtype=convtype)
pixel_shuffle = nn.PixelShuffle(upscale_factor)
n = norm(norm_type, out_nc) if norm_type else None
a = act(act_type) if act_type else None
return sequential(conv, pixel_shuffle, n, a)
def upconv_block(in_nc, out_nc, upscale_factor=2, kernel_size=3, stride=1, bias=True,
pad_type='zero', norm_type=None, act_type='relu', mode='nearest', convtype='Conv2D'):
""" Upconv layer """
upscale_factor = (1, upscale_factor, upscale_factor) if convtype == 'Conv3D' else upscale_factor
upsample = Upsample(scale_factor=upscale_factor, mode=mode)
conv = conv_block(in_nc, out_nc, kernel_size, stride, bias=bias,
pad_type=pad_type, norm_type=norm_type, act_type=act_type, convtype=convtype)
return sequential(upsample, conv)
####################
# Basic blocks
####################
def make_layer(basic_block, num_basic_block, **kwarg):
"""Make layers by stacking the same blocks.
Args:
basic_block (nn.module): nn.module class for basic block. (block)
num_basic_block (int): number of blocks. (n_layers)
Returns:
nn.Sequential: Stacked blocks in nn.Sequential.
"""
layers = []
for _ in range(num_basic_block):
layers.append(basic_block(**kwarg))
return nn.Sequential(*layers)
def act(act_type, inplace=True, neg_slope=0.2, n_prelu=1, beta=1.0):
""" activation helper """
act_type = act_type.lower()
if act_type == 'relu':
layer = nn.ReLU(inplace)
elif act_type in ('leakyrelu', 'lrelu'):
layer = nn.LeakyReLU(neg_slope, inplace)
elif act_type == 'prelu':
layer = nn.PReLU(num_parameters=n_prelu, init=neg_slope)
elif act_type == 'tanh': # [-1, 1] range output
layer = nn.Tanh()
elif act_type == 'sigmoid': # [0, 1] range output
layer = nn.Sigmoid()
else:
raise NotImplementedError(f'activation layer [{act_type}] is not found')
return layer
class Identity(nn.Module):
def __init__(self, *kwargs):
super(Identity, self).__init__()
def forward(self, x, *kwargs):
return x
def norm(norm_type, nc):
""" Return a normalization layer """
norm_type = norm_type.lower()
if norm_type == 'batch':
layer = nn.BatchNorm2d(nc, affine=True)
elif norm_type == 'instance':
layer = nn.InstanceNorm2d(nc, affine=False)
elif norm_type == 'none':
def norm_layer(x): return Identity()
else:
raise NotImplementedError(f'normalization layer [{norm_type}] is not found')
return layer
def pad(pad_type, padding):
""" padding layer helper """
pad_type = pad_type.lower()
if padding == 0:
return None
if pad_type == 'reflect':
layer = nn.ReflectionPad2d(padding)
elif pad_type == 'replicate':
layer = nn.ReplicationPad2d(padding)
elif pad_type == 'zero':
layer = nn.ZeroPad2d(padding)
else:
raise NotImplementedError(f'padding layer [{pad_type}] is not implemented')
return layer
def get_valid_padding(kernel_size, dilation):
kernel_size = kernel_size + (kernel_size - 1) * (dilation - 1)
padding = (kernel_size - 1) // 2
return padding
class ShortcutBlock(nn.Module):
""" Elementwise sum the output of a submodule to its input """
def __init__(self, submodule):
super(ShortcutBlock, self).__init__()
self.sub = submodule
def forward(self, x):
output = x + self.sub(x)
return output
def __repr__(self):
return 'Identity + \n|' + self.sub.__repr__().replace('\n', '\n|')
def sequential(*args):
""" Flatten Sequential. It unwraps nn.Sequential. """
if len(args) == 1:
if isinstance(args[0], OrderedDict):
raise NotImplementedError('sequential does not support OrderedDict input.')
return args[0] # No sequential is needed.
modules = []
for module in args:
if isinstance(module, nn.Sequential):
for submodule in module.children():
modules.append(submodule)
elif isinstance(module, nn.Module):
modules.append(module)
return nn.Sequential(*modules)
def conv_block(in_nc, out_nc, kernel_size, stride=1, dilation=1, groups=1, bias=True,
pad_type='zero', norm_type=None, act_type='relu', mode='CNA', convtype='Conv2D',
spectral_norm=False):
""" Conv layer with padding, normalization, activation """
assert mode in ['CNA', 'NAC', 'CNAC'], f'Wrong conv mode [{mode}]'
padding = get_valid_padding(kernel_size, dilation)
p = pad(pad_type, padding) if pad_type and pad_type != 'zero' else None
padding = padding if pad_type == 'zero' else 0
if convtype=='PartialConv2D':
from torchvision.ops import PartialConv2d # this is definitely not going to work, but PartialConv2d doesn't work anyway and this shuts up static analyzer
c = PartialConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
dilation=dilation, bias=bias, groups=groups)
elif convtype=='DeformConv2D':
from torchvision.ops import DeformConv2d # not tested
c = DeformConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
dilation=dilation, bias=bias, groups=groups)
elif convtype=='Conv3D':
c = nn.Conv3d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
dilation=dilation, bias=bias, groups=groups)
else:
c = nn.Conv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
dilation=dilation, bias=bias, groups=groups)
if spectral_norm:
c = nn.utils.spectral_norm(c)
a = act(act_type) if act_type else None
if 'CNA' in mode:
n = norm(norm_type, out_nc) if norm_type else None
return sequential(p, c, n, a)
elif mode == 'NAC':
if norm_type is None and act_type is not None:
a = act(act_type, inplace=False)
n = norm(norm_type, in_nc) if norm_type else None
return sequential(n, a, p, c)

View File

@ -1,29 +1,113 @@
from __future__ import annotations
import configparser
import dataclasses
import os
import threading
import re
from modules import shared, errors, cache
from modules import shared, errors, cache, scripts
from modules.gitpython_hack import Repo
from modules.paths_internal import extensions_dir, extensions_builtin_dir, script_path # noqa: F401
extensions = []
extensions: list[Extension] = []
extension_paths: dict[str, Extension] = {}
loaded_extensions: dict[str, Exception] = {}
os.makedirs(extensions_dir, exist_ok=True)
def active():
if shared.opts.disable_all_extensions == "all":
if shared.cmd_opts.disable_all_extensions or shared.opts.disable_all_extensions == "all":
return []
elif shared.opts.disable_all_extensions == "extra":
elif shared.cmd_opts.disable_extra_extensions or shared.opts.disable_all_extensions == "extra":
return [x for x in extensions if x.enabled and x.is_builtin]
else:
return [x for x in extensions if x.enabled]
@dataclasses.dataclass
class CallbackOrderInfo:
name: str
before: list
after: list
class ExtensionMetadata:
filename = "metadata.ini"
config: configparser.ConfigParser
canonical_name: str
requires: list
def __init__(self, path, canonical_name):
self.config = configparser.ConfigParser()
filepath = os.path.join(path, self.filename)
# `self.config.read()` will quietly swallow OSErrors (which FileNotFoundError is),
# so no need to check whether the file exists beforehand.
try:
self.config.read(filepath)
except Exception:
errors.report(f"Error reading {self.filename} for extension {canonical_name}.", exc_info=True)
self.canonical_name = self.config.get("Extension", "Name", fallback=canonical_name)
self.canonical_name = canonical_name.lower().strip()
self.requires = None
def get_script_requirements(self, field, section, extra_section=None):
"""reads a list of requirements from the config; field is the name of the field in the ini file,
like Requires or Before, and section is the name of the [section] in the ini file; additionally,
reads more requirements from [extra_section] if specified."""
x = self.config.get(section, field, fallback='')
if extra_section:
x = x + ', ' + self.config.get(extra_section, field, fallback='')
listed_requirements = self.parse_list(x.lower())
res = []
for requirement in listed_requirements:
loaded_requirements = (x for x in requirement.split("|") if x in loaded_extensions)
relevant_requirement = next(loaded_requirements, requirement)
res.append(relevant_requirement)
return res
def parse_list(self, text):
"""converts a line from config ("ext1 ext2, ext3 ") into a python list (["ext1", "ext2", "ext3"])"""
if not text:
return []
# both "," and " " are accepted as separator
return [x for x in re.split(r"[,\s]+", text.strip()) if x]
def list_callback_order_instructions(self):
for section in self.config.sections():
if not section.startswith("callbacks/"):
continue
callback_name = section[10:]
if not callback_name.startswith(self.canonical_name):
errors.report(f"Callback order section for extension {self.canonical_name} is referencing the wrong extension: {section}")
continue
before = self.parse_list(self.config.get(section, 'Before', fallback=''))
after = self.parse_list(self.config.get(section, 'After', fallback=''))
yield CallbackOrderInfo(callback_name, before, after)
class Extension:
lock = threading.Lock()
cached_fields = ['remote', 'commit_date', 'branch', 'commit_hash', 'version']
metadata: ExtensionMetadata
def __init__(self, name, path, enabled=True, is_builtin=False):
def __init__(self, name, path, enabled=True, is_builtin=False, metadata=None):
self.name = name
self.path = path
self.enabled = enabled
@ -36,6 +120,8 @@ class Extension:
self.branch = None
self.remote = None
self.have_info_from_repo = False
self.metadata = metadata if metadata else ExtensionMetadata(self.path, name.lower())
self.canonical_name = metadata.canonical_name
def to_dict(self):
return {x: getattr(self, x) for x in self.cached_fields}
@ -56,6 +142,7 @@ class Extension:
self.do_read_info_from_repo()
return self.to_dict()
try:
d = cache.cached_data_for_file('extensions-git', self.name, os.path.join(self.path, ".git"), read_from_repo)
self.from_dict(d)
@ -90,8 +177,6 @@ class Extension:
self.have_info_from_repo = True
def list_files(self, subdir, extension):
from modules import scripts
dirpath = os.path.join(self.path, subdir)
if not os.path.isdir(dirpath):
return []
@ -106,14 +191,17 @@ class Extension:
def check_updates(self):
repo = Repo(self.path)
branch_name = f'{repo.remote().name}/{self.branch}'
for fetch in repo.remote().fetch(dry_run=True):
if self.branch and fetch.name != branch_name:
continue
if fetch.flags != fetch.HEAD_UPTODATE:
self.can_update = True
self.status = "new commits"
return
try:
origin = repo.rev_parse('origin')
origin = repo.rev_parse(branch_name)
if repo.head.commit != origin:
self.can_update = True
self.status = "behind HEAD"
@ -126,8 +214,10 @@ class Extension:
self.can_update = False
self.status = "latest"
def fetch_and_reset_hard(self, commit='origin'):
def fetch_and_reset_hard(self, commit=None):
repo = Repo(self.path)
if commit is None:
commit = f'{repo.remote().name}/{self.branch}'
# Fix: `error: Your local changes to the following files would be overwritten by merge`,
# because WSL2 Docker set 755 file permissions instead of 644, this results to the error.
repo.git.fetch(all=True)
@ -137,27 +227,73 @@ class Extension:
def list_extensions():
extensions.clear()
extension_paths.clear()
loaded_extensions.clear()
if not os.path.isdir(extensions_dir):
return
if shared.opts.disable_all_extensions == "all":
if shared.cmd_opts.disable_all_extensions:
print("*** \"--disable-all-extensions\" arg was used, will not load any extensions ***")
elif shared.opts.disable_all_extensions == "all":
print("*** \"Disable all extensions\" option was set, will not load any extensions ***")
elif shared.cmd_opts.disable_extra_extensions:
print("*** \"--disable-extra-extensions\" arg was used, will only load built-in extensions ***")
elif shared.opts.disable_all_extensions == "extra":
print("*** \"Disable all extensions\" option was set, will only load built-in extensions ***")
extension_paths = []
for dirname in [extensions_dir, extensions_builtin_dir]:
# scan through extensions directory and load metadata
for dirname in [extensions_builtin_dir, extensions_dir]:
if not os.path.isdir(dirname):
return
continue
for extension_dirname in sorted(os.listdir(dirname)):
path = os.path.join(dirname, extension_dirname)
if not os.path.isdir(path):
continue
extension_paths.append((extension_dirname, path, dirname == extensions_builtin_dir))
canonical_name = extension_dirname
metadata = ExtensionMetadata(path, canonical_name)
# check for duplicated canonical names
already_loaded_extension = loaded_extensions.get(metadata.canonical_name)
if already_loaded_extension is not None:
errors.report(f'Duplicate canonical name "{canonical_name}" found in extensions "{extension_dirname}" and "{already_loaded_extension.name}". Former will be discarded.', exc_info=False)
continue
is_builtin = dirname == extensions_builtin_dir
extension = Extension(name=extension_dirname, path=path, enabled=extension_dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin, metadata=metadata)
extensions.append(extension)
extension_paths[extension.path] = extension
loaded_extensions[canonical_name] = extension
for extension in extensions:
extension.metadata.requires = extension.metadata.get_script_requirements("Requires", "Extension")
# check for requirements
for extension in extensions:
if not extension.enabled:
continue
for req in extension.metadata.requires:
required_extension = loaded_extensions.get(req)
if required_extension is None:
errors.report(f'Extension "{extension.name}" requires "{req}" which is not installed.', exc_info=False)
continue
if not required_extension.enabled:
errors.report(f'Extension "{extension.name}" requires "{required_extension.name}" which is disabled.', exc_info=False)
continue
def find_extension(filename):
parentdir = os.path.dirname(os.path.realpath(filename))
while parentdir != filename:
extension = extension_paths.get(parentdir)
if extension is not None:
return extension
filename = parentdir
parentdir = os.path.dirname(filename)
return None
for dirname, path, is_builtin in extension_paths:
extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin)
extensions.append(extension)

View File

@ -1,4 +1,7 @@
import json
import os
import re
import logging
from collections import defaultdict
from modules import errors
@ -57,7 +60,7 @@ class ExtraNetwork:
Where name matches the name of this ExtraNetwork object, and arg1:arg2:arg3 are any natural number of text arguments
separated by colon.
Even if the user does not mention this ExtraNetwork in his prompt, the call will stil be made, with empty params_list -
Even if the user does not mention this ExtraNetwork in his prompt, the call will still be made, with empty params_list -
in this case, all effects of this extra networks should be disabled.
Can be called multiple times before deactivate() - each new call should override the previous call completely.
@ -84,27 +87,55 @@ class ExtraNetwork:
raise NotImplementedError
def lookup_extra_networks(extra_network_data):
"""returns a dict mapping ExtraNetwork objects to lists of arguments for those extra networks.
Example input:
{
'lora': [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D58310>],
'lyco': [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D58F70>],
'hypernet': [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D5A800>]
}
Example output:
{
<extra_networks_lora.ExtraNetworkLora object at 0x0000020581BEECE0>: [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D58310>, <modules.extra_networks.ExtraNetworkParams object at 0x0000020690D58F70>],
<modules.extra_networks_hypernet.ExtraNetworkHypernet object at 0x0000020581BEEE60>: [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D5A800>]
}
"""
res = {}
for extra_network_name, extra_network_args in list(extra_network_data.items()):
extra_network = extra_network_registry.get(extra_network_name, None)
alias = extra_network_aliases.get(extra_network_name, None)
if alias is not None and extra_network is None:
extra_network = alias
if extra_network is None:
logging.info(f"Skipping unknown extra network: {extra_network_name}")
continue
res.setdefault(extra_network, []).extend(extra_network_args)
return res
def activate(p, extra_network_data):
"""call activate for extra networks in extra_network_data in specified order, then call
activate for all remaining registered networks with an empty argument list"""
activated = []
for extra_network_name, extra_network_args in extra_network_data.items():
extra_network = extra_network_registry.get(extra_network_name, None)
if extra_network is None:
extra_network = extra_network_aliases.get(extra_network_name, None)
if extra_network is None:
print(f"Skipping unknown extra network: {extra_network_name}")
continue
for extra_network, extra_network_args in lookup_extra_networks(extra_network_data).items():
try:
extra_network.activate(p, extra_network_args)
activated.append(extra_network)
except Exception as e:
errors.display(e, f"activating extra network {extra_network_name} with arguments {extra_network_args}")
errors.display(e, f"activating extra network {extra_network.name} with arguments {extra_network_args}")
for extra_network_name, extra_network in extra_network_registry.items():
if extra_network in activated:
@ -123,19 +154,16 @@ def deactivate(p, extra_network_data):
"""call deactivate for extra networks in extra_network_data in specified order, then call
deactivate for all remaining registered networks"""
for extra_network_name in extra_network_data:
extra_network = extra_network_registry.get(extra_network_name, None)
if extra_network is None:
continue
data = lookup_extra_networks(extra_network_data)
for extra_network in data:
try:
extra_network.deactivate(p)
except Exception as e:
errors.display(e, f"deactivating extra network {extra_network_name}")
errors.display(e, f"deactivating extra network {extra_network.name}")
for extra_network_name, extra_network in extra_network_registry.items():
args = extra_network_data.get(extra_network_name, None)
if args is not None:
if extra_network in data:
continue
try:
@ -177,3 +205,21 @@ def parse_prompts(prompts):
return res, extra_data
def get_user_metadata(filename, lister=None):
if filename is None:
return {}
basename, ext = os.path.splitext(filename)
metadata_filename = basename + '.json'
metadata = {}
try:
exists = lister.exists(metadata_filename) if lister else os.path.exists(metadata_filename)
if exists:
with open(metadata_filename, "r", encoding="utf8") as file:
metadata = json.load(file)
except Exception as e:
errors.display(e, f"reading extra network user metadata from {metadata_filename}")
return metadata

View File

@ -7,7 +7,7 @@ import json
import torch
import tqdm
from modules import shared, images, sd_models, sd_vae, sd_models_config
from modules import shared, images, sd_models, sd_vae, sd_models_config, errors
from modules.ui_common import plaintext_to_html
import gradio as gr
import safetensors.torch
@ -72,7 +72,20 @@ def to_half(tensor, enable):
return tensor
def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_model_name, interp_method, multiplier, save_as_half, custom_name, checkpoint_format, config_source, bake_in_vae, discard_weights, save_metadata):
def read_metadata(primary_model_name, secondary_model_name, tertiary_model_name):
metadata = {}
for checkpoint_name in [primary_model_name, secondary_model_name, tertiary_model_name]:
checkpoint_info = sd_models.checkpoints_list.get(checkpoint_name, None)
if checkpoint_info is None:
continue
metadata.update(checkpoint_info.metadata)
return json.dumps(metadata, indent=4, ensure_ascii=False)
def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_model_name, interp_method, multiplier, save_as_half, custom_name, checkpoint_format, config_source, bake_in_vae, discard_weights, save_metadata, add_merge_recipe, copy_metadata_fields, metadata_json):
shared.state.begin(job="model-merge")
def fail(message):
@ -241,11 +254,25 @@ def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_
shared.state.textinfo = "Saving"
print(f"Saving to {output_modelname}...")
metadata = None
metadata = {}
if save_metadata and copy_metadata_fields:
if primary_model_info:
metadata.update(primary_model_info.metadata)
if secondary_model_info:
metadata.update(secondary_model_info.metadata)
if tertiary_model_info:
metadata.update(tertiary_model_info.metadata)
if save_metadata:
metadata = {"format": "pt"}
try:
metadata.update(json.loads(metadata_json))
except Exception as e:
errors.display(e, "readin metadata from json")
metadata["format"] = "pt"
if save_metadata and add_merge_recipe:
merge_recipe = {
"type": "webui", # indicate this model was merged with webui's built-in merger
"primary_model_hash": primary_model_info.sha256,
@ -261,7 +288,6 @@ def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_
"is_inpainting": result_is_inpainting_model,
"is_instruct_pix2pix": result_is_instruct_pix2pix_model
}
metadata["sd_merge_recipe"] = json.dumps(merge_recipe)
sd_merge_models = {}
@ -281,11 +307,12 @@ def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_
if tertiary_model_info:
add_model_metadata(tertiary_model_info)
metadata["sd_merge_recipe"] = json.dumps(merge_recipe)
metadata["sd_merge_models"] = json.dumps(sd_merge_models)
_, extension = os.path.splitext(output_modelname)
if extension.lower() == ".safetensors":
safetensors.torch.save_file(theta_0, output_modelname, metadata=metadata)
safetensors.torch.save_file(theta_0, output_modelname, metadata=metadata if len(metadata)>0 else None)
else:
torch.save(theta_0, output_modelname)

View File

@ -0,0 +1,180 @@
from __future__ import annotations
import logging
import os
from functools import cached_property
from typing import TYPE_CHECKING, Callable
import cv2
import numpy as np
import torch
from modules import devices, errors, face_restoration, shared
if TYPE_CHECKING:
from facexlib.utils.face_restoration_helper import FaceRestoreHelper
logger = logging.getLogger(__name__)
def bgr_image_to_rgb_tensor(img: np.ndarray) -> torch.Tensor:
"""Convert a BGR NumPy image in [0..1] range to a PyTorch RGB float32 tensor."""
assert img.shape[2] == 3, "image must be RGB"
if img.dtype == "float64":
img = img.astype("float32")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
return torch.from_numpy(img.transpose(2, 0, 1)).float()
def rgb_tensor_to_bgr_image(tensor: torch.Tensor, *, min_max=(0.0, 1.0)) -> np.ndarray:
"""
Convert a PyTorch RGB tensor in range `min_max` to a BGR NumPy image in [0..1] range.
"""
tensor = tensor.squeeze(0).float().detach().cpu().clamp_(*min_max)
tensor = (tensor - min_max[0]) / (min_max[1] - min_max[0])
assert tensor.dim() == 3, "tensor must be RGB"
img_np = tensor.numpy().transpose(1, 2, 0)
if img_np.shape[2] == 1: # gray image, no RGB/BGR required
return np.squeeze(img_np, axis=2)
return cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
def create_face_helper(device) -> FaceRestoreHelper:
from facexlib.detection import retinaface
from facexlib.utils.face_restoration_helper import FaceRestoreHelper
if hasattr(retinaface, 'device'):
retinaface.device = device
return FaceRestoreHelper(
upscale_factor=1,
face_size=512,
crop_ratio=(1, 1),
det_model='retinaface_resnet50',
save_ext='png',
use_parse=True,
device=device,
)
def restore_with_face_helper(
np_image: np.ndarray,
face_helper: FaceRestoreHelper,
restore_face: Callable[[torch.Tensor], torch.Tensor],
) -> np.ndarray:
"""
Find faces in the image using face_helper, restore them using restore_face, and paste them back into the image.
`restore_face` should take a cropped face image and return a restored face image.
"""
from torchvision.transforms.functional import normalize
np_image = np_image[:, :, ::-1]
original_resolution = np_image.shape[0:2]
try:
logger.debug("Detecting faces...")
face_helper.clean_all()
face_helper.read_image(np_image)
face_helper.get_face_landmarks_5(only_center_face=False, resize=640, eye_dist_threshold=5)
face_helper.align_warp_face()
logger.debug("Found %d faces, restoring", len(face_helper.cropped_faces))
for cropped_face in face_helper.cropped_faces:
cropped_face_t = bgr_image_to_rgb_tensor(cropped_face / 255.0)
normalize(cropped_face_t, (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True)
cropped_face_t = cropped_face_t.unsqueeze(0).to(devices.device_codeformer)
try:
with torch.no_grad():
cropped_face_t = restore_face(cropped_face_t)
devices.torch_gc()
except Exception:
errors.report('Failed face-restoration inference', exc_info=True)
restored_face = rgb_tensor_to_bgr_image(cropped_face_t, min_max=(-1, 1))
restored_face = (restored_face * 255.0).astype('uint8')
face_helper.add_restored_face(restored_face)
logger.debug("Merging restored faces into image")
face_helper.get_inverse_affine(None)
img = face_helper.paste_faces_to_input_image()
img = img[:, :, ::-1]
if original_resolution != img.shape[0:2]:
img = cv2.resize(
img,
(0, 0),
fx=original_resolution[1] / img.shape[1],
fy=original_resolution[0] / img.shape[0],
interpolation=cv2.INTER_LINEAR,
)
logger.debug("Face restoration complete")
finally:
face_helper.clean_all()
return img
class CommonFaceRestoration(face_restoration.FaceRestoration):
net: torch.Module | None
model_url: str
model_download_name: str
def __init__(self, model_path: str):
super().__init__()
self.net = None
self.model_path = model_path
os.makedirs(model_path, exist_ok=True)
@cached_property
def face_helper(self) -> FaceRestoreHelper:
return create_face_helper(self.get_device())
def send_model_to(self, device):
if self.net:
logger.debug("Sending %s to %s", self.net, device)
self.net.to(device)
if self.face_helper:
logger.debug("Sending face helper to %s", device)
self.face_helper.face_det.to(device)
self.face_helper.face_parse.to(device)
def get_device(self):
raise NotImplementedError("get_device must be implemented by subclasses")
def load_net(self) -> torch.Module:
raise NotImplementedError("load_net must be implemented by subclasses")
def restore_with_helper(
self,
np_image: np.ndarray,
restore_face: Callable[[torch.Tensor], torch.Tensor],
) -> np.ndarray:
try:
if self.net is None:
self.net = self.load_net()
except Exception:
logger.warning("Unable to load face-restoration model", exc_info=True)
return np_image
try:
self.send_model_to(self.get_device())
return restore_with_face_helper(np_image, self.face_helper, restore_face)
finally:
if shared.opts.face_restoration_unload:
self.send_model_to(devices.cpu)
def patch_facexlib(dirname: str) -> None:
import facexlib.detection
import facexlib.parsing
det_facex_load_file_from_url = facexlib.detection.load_file_from_url
par_facex_load_file_from_url = facexlib.parsing.load_file_from_url
def update_kwargs(kwargs):
return dict(kwargs, save_dir=dirname, model_dir=None)
def facex_load_file_from_url(**kwargs):
return det_facex_load_file_from_url(**update_kwargs(kwargs))
def facex_load_file_from_url2(**kwargs):
return par_facex_load_file_from_url(**update_kwargs(kwargs))
facexlib.detection.load_file_from_url = facex_load_file_from_url
facexlib.parsing.load_file_from_url = facex_load_file_from_url2

Some files were not shown because too many files have changed in this diff Show More