Compare commits

...

2714 Commits

Author SHA1 Message Date
w-e-w 9bc3332d86 make process_boolean_tag case insensitive 2024-08-06 19:25:30 +09:00
w-e-w f8395750f4 add Usage Syntax to Prompts from file or textbox 2024-08-06 19:25:30 +09:00
AUTOMATIC1111 48239090f1 Merge branch 'master' into dev 2024-07-27 15:50:26 +03:00
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 850e14923e Merge pull request #16275 from AUTOMATIC1111/fix-image-upscale-on-cpu
fix image upscale on cpu
2024-07-27 15:47:49 +03:00
w-e-w 8e0881d9ab fix image upscale on cpu
for some reason upscale using cpu will fail with
RuntimeError: Inplace update to inference tensor outside InferenceMode
switch from no_grad to inference_mode seems to have fixed it
2024-07-27 21:28:10 +09:00
AUTOMATIC1111 834297b13d Merge branch 'master' into dev 2024-07-27 07:09:08 +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 4cc3add770, reversing
changes made to 50514ce414.
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 dcd4f880a8
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 dcd4f880a8 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 81c16c965e.
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 d243e24f53.
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 e00365962b.
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
11d23e8ca5
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 58c19545c8.
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 aab385d01b.
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 f3d1631aab.

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()` (https://github.com/gradio-app/gradio/blob/861d752a83da0f95e9f79173069b69eababeed39/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 0815c45bcd.
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 094c416a80.
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 68f336bd99 Merge branch 'release_candidate' 2023-07-27 09:02:22 +03:00
AUTOMATIC1111 50973ec77c update the changelog 2023-07-27 09:02:02 +03:00
AUTOMATIC1111 f82e08cf45 update lora extension to work with python 3.8 2023-07-27 09:00:59 +03:00
AUTOMATIC1111 91a131aa6c update lora extension to work with python 3.8 2023-07-27 09:00:47 +03:00
AUTOMATIC1111 3039925b27 update readme 2023-07-26 15:19:02 +03:00
AUTOMATIC1111 8220cf37da 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:18:04 +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 055461ae41 repair SDXL 2023-07-26 15:08:12 +03:00
AUTOMATIC1111 89e6dfff71 repair SDXL 2023-07-26 15:07:56 +03:00
AUTOMATIC1111 5c8f91b229 fix autograd which i broke for no good reason when implementing SDXL 2023-07-26 13:04:10 +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 6b877c35da 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:58 +03: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 eb6d330bb7 delete scale checker script due to user demand 2023-07-26 09:20:02 +03:00
AUTOMATIC1111 246d1f1f70 delete scale checker script due to user demand 2023-07-26 09:19:46 +03:00
AUTOMATIC1111 5360ae2cc5 Merge pull request #12023 from AUTOMATIC1111/create_infotext_fix
Create infotext fix
2023-07-26 08:10:21 +03:00
AUTOMATIC1111 e16eb3d0cb Merge pull request #12024 from AUTOMATIC1111/fix-check-for-updates-status-always-unknown-
fix check for updates status always "unknown"
2023-07-26 08:10:12 +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 99ef3b6c52 update readme 2023-07-25 16:31:01 +03:00
AUTOMATIC1111 65b6f8d3d5 fix for #11963 2023-07-25 16:20:55 +03:00
AUTOMATIC1111 b57a816038 Merge pull request #11963 from catboxanon/fix/lora-te
Fix parsing text encoder blocks in some LoRAs
2023-07-25 16:20:52 +03:00
AUTOMATIC1111 11f996a096 Merge pull request #11979 from AUTOMATIC1111/catch-exception-for-non-git-extensions
catch exception for non git extensions
2023-07-25 16:20:49 +03:00
AUTOMATIC1111 ce0aab3643 Merge pull request #11984 from AUTOMATIC1111/api-only-subpath-(root_path)
api only subpath (rootpath)
2023-07-25 16:20:46 +03:00
AUTOMATIC1111 c251e8db8d Merge pull request #11957 from ljleb/pp-batch-list
Add postprocess_batch_list script callback
2023-07-25 16:20:33 +03:00
AUTOMATIC1111 284822323a restyle Startup profile for black users 2023-07-25 16:20:16 +03:00
AUTOMATIC1111 1f59be5188 Merge pull request #11926 from wfjsw/fix-env-get-1
fix 11291#issuecomment-1646547908
2023-07-25 16:20:07 +03:00
AUTOMATIC1111 cad87bf4e3 Merge pull request #11927 from ljleb/fix-AND
Fix composable diffusion weight parsing
2023-07-25 16:20:01 +03:00
AUTOMATIC1111 704628b903 Merge pull request #11923 from AnyISalIn/dev
[bug] If txt2img/img2img raises an exception, finally call state.end()
2023-07-25 16:19:36 +03:00
AUTOMATIC1111 636ff513b0 Merge pull request #11920 from wfjsw/typo-fix-1
typo fix
2023-07-25 16:19:22 +03:00
AUTOMATIC1111 51206edb62 Merge pull request #11921 from wfjsw/prepend-pythonpath
prepend the pythonpath instead of overriding it
2023-07-25 16:19:08 +03:00
AUTOMATIC1111 c5934fb6e3 Merge pull request #11878 from Bourne-M/patch-1
【bug】reload altclip model error
2023-07-25 16:18:55 +03: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
AUTOMATIC1111 a3ddf464a2 Merge branch 'release_candidate' 2023-07-25 08:18:02 +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
AUTOMATIC1111 2c11e9009e repair --medvram for SD2.x too after SDXL update 2023-07-24 11:57:59 +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
AUTOMATIC1111 1f26815dd3 Merge pull request #11898 from janekm/janekm-patch-1
Update sd_models_xl.py
2023-07-20 19:16:40 +03:00
Janek Mann 8218f6cd37 Update sd_models_xl.py
Fix width/height not getting fed into the conditioning
2023-07-20 16:22:52 +01: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 23c947ab03 automatically switch to 32-bit float VAE if the generated picture has NaNs. 2023-07-19 20:23:30 +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
AUTOMATIC1111 0e47c36a28 Merge branch 'dev' into release_candidate 2023-07-19 15:50:49 +03:00
AUTOMATIC1111 4334d25978 bugfix: model name was added together with directory name to infotext and to [model_name] filename pattern 2023-07-19 15:49:54 +03:00
AUTOMATIC1111 05ccb4d0e3 bugfix: model name was added together with directory name to infotext and to [model_name] filename pattern 2023-07-19 15:49:31 +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
AUTOMATIC1111 d5c850aab5 Merge pull request #11866 from kopyl/allow-no-venv-install
Make possible to install web ui without venv with venv_dir=- env variable for Linux
2023-07-19 08:00:05 +03:00
AUTOMATIC1111 0a334b447f Merge branch 'dev' into allow-no-venv-install 2023-07-19 07:59:39 +03:00
AUTOMATIC1111 c2b9754857 Merge pull request #11869 from AUTOMATIC1111/missing-p-save_image-before-highres-fix
Fix missing p save_image before-highres-fix
2023-07-19 07:58:34 +03:00
Jabasukuriputo Wang fc3bdf8c11 Merge branch 'dev' into move-start-timer 2023-07-19 10:33:31 +08:00
w-e-w c8b55f29e2 missing p save_image before-highres-fix 2023-07-19 08:27:19 +09:00
kopyl 6094310704 improve var naming 2023-07-19 01:48:21 +03:00
kopyl 0c4ca5f43e Replace argument with env variable 2023-07-19 01:47:39 +03:00
AUTOMATIC1111 b010eea520 fix incorrect multiplier for Loras 2023-07-19 00:41:00 +03: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
kopyl 2b42f73e3d Make possible to install web ui without venv with --novenv flag
When passing `--novenv` flag to webui.sh it can skip venv.
Might be useful for installing in Docker since messing with venv in Docker might be a bit complicated.

Example usage:
`webui.sh --novenv`

Hope this gets approved and pushed into future versions of Web UI
2023-07-18 22:43:18 +03:00
AUTOMATIC1111 136c8859a4 add backwards compatibility --lyco-dir-backcompat option, use that for LyCORIS directory instead of hardcoded value
prevent running preload.py for disabled extensions
2023-07-18 20:11:30 +03:00
AUTOMATIC1111 eb7c9b58fc Merge branch 'dev' into release_candidate 2023-07-18 18:20:22 +03:00
AUTOMATIC1111 7f7db1700b linter fix 2023-07-18 18:16:23 +03:00
AUTOMATIC1111 b270ded268 fix the issue with /sdapi/v1/options failing (this time for sure!)
fix automated tests downloading CLIP model
2023-07-18 18:10:04 +03:00
AUTOMATIC1111 be16d274f8 changelog for 1.5.0 2023-07-18 17:44:56 +03:00
AUTOMATIC1111 66c5f1bb15 return sd_model_checkpoint to None 2023-07-18 17:41:37 +03:00
AUTOMATIC1111 4b5a63aa11 add a bit more metadata info for the lora user metadata page 2023-07-18 17:32:46 +03:00
AUTOMATIC1111 ed82f1c5f1 lint 2023-07-18 15:55:23 +03:00
wfjsw 3c570421d3 move start timer 2023-07-18 19:00:16 +08:00
AUTOMATIC1111 420cc8f68e also make None a valid option for options API for #11854 2023-07-18 11:48:40 +03:00
AUTOMATIC1111 6be5ccb530 Merge pull request #11854 from leon0707/fix-11805
Fix #11805
2023-07-18 11:48:01 +03:00
Leon Feng a3730bd9be Merge branch 'dev' into fix-11805 2023-07-18 04:24:14 -04:00
Leon Feng d6668347c8 remove duplicate 2023-07-18 04:19:58 -04:00
AUTOMATIC1111 871b8687a8 Merge pull request #11846 from brkirch/sd-xl-upcast-sampling-fix
Add support for using `--upcast-sampling` with SD XL
2023-07-18 08:08:19 +03:00
AUTOMATIC1111 20c41364cc Merge pull request #11843 from KohakuBlueleaf/fix-lyco-support
Fix wrong key name in lokr module
2023-07-18 08:05:28 +03: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
brkirch f0e2098f1a Add support for --upcast-sampling with SD XL 2023-07-18 00:39:50 -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
Kohaku-Blueleaf 3d31caf4a5 use "is not None" for Tensor 2023-07-18 10:45:42 +08:00
Kohaku-Blueleaf 17e14ed2d9 Fix wrong key name in lokr module 2023-07-18 10:23:41 +08:00
AUTOMATIC1111 a99d5708e6 skip installing packages with pip if theyare already installed
record time it took to launch
2023-07-17 20:10:24 +03:00
AUTOMATIC1111 699108bfbb hide cards for networks of incompatible stable diffusion version in Lora extra networks interface 2023-07-17 18:56:22 +03:00
AUTOMATIC1111 f97e35929b Merge pull request #11824 from AUTOMATIC1111/XYZ-always_discard_next_to_last_sigma
XYZ always_discard_next_to_last_sigma
2023-07-17 15:56:34 +03:00
AUTOMATIC1111 2164578738 Merge pull request #11821 from AUTOMATIC1111/lora_lyco
lora extension rework to include other types of networks
2023-07-17 15:51:59 +03: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 05d23c7837 move generate button below the picture for mobile clients 2023-07-17 11:44:29 +03: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 35510f7529 add alias to lyco network
read networks from LyCORIS dir if it exists
add credits
2023-07-17 10:06:02 +03:00
AUTOMATIC1111 9251ae3bc7 delay writing cache to prevent writing the same thing over and over 2023-07-17 09:29:36 +03:00
AUTOMATIC1111 2e07a8ae6b some backwards compatibility
linter
2023-07-17 09:05:18 +03:00
AUTOMATIC1111 238adeaffb support specifying te and unet weights separately
update lora code
support full module
2023-07-17 09:00:47 +03:00
w-e-w 8941297ceb lowercase 2023-07-17 12:45:38 +09:00
w-e-w c03856bfdf reversible boolean_choice order 2023-07-17 12:45:10 +09:00
w-e-w 7870937c77 XYZ always_discard_next_to_last_sigma
Co-authored-by: Franck Mahon <franck.mahon@gmail.com>
2023-07-17 12:25:29 +09:00
AUTOMATIC1111 46466f09d0 Lokr support 2023-07-17 00:29:07 +03:00
AUTOMATIC1111 58c3df32f3 IA3 support 2023-07-17 00:12:18 +03:00
AUTOMATIC1111 ef5dac7786 fix 2023-07-17 00:01:17 +03:00
AUTOMATIC1111 c2297b89d3 linter 2023-07-16 23:14:57 +03:00
AUTOMATIC1111 b75b004fe6 lora extension rework to include other types of networks 2023-07-16 23:13:55 +03:00
AUTOMATIC1111 643836007f more tweaking for cards section height 2023-07-16 14:46:05 +03:00
AUTOMATIC1111 7d26c479ee changelog for future 1.5.0 2023-07-16 14:39:47 +03:00
AUTOMATIC1111 24bad5dc7b change extra networks list to have constant height and scrolling 2023-07-16 13:59:15 +03:00
AUTOMATIC1111 67ea4eabc3 fix cache loading wrong entries from old cache files 2023-07-16 13:46:33 +03:00
AUTOMATIC1111 ace0c78373 Merge pull request #11669 from gitama2023/patch-1
Added a prompt for users using poor scaling
2023-07-16 13:12:18 +03:00
AUTOMATIC1111 570f42afd1 possible fix for FP16 VAE failing in img2img SDXL 2023-07-16 12:28:50 +03:00
AUTOMATIC1111 0198eaec45 Merge pull request #11757 from AUTOMATIC1111/sdxl
SD XL support
2023-07-16 12:04:53 +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
AUTOMATIC1111 9d3dd64fe9 minor restyling for extra networks 2023-07-16 10:44:04 +03:00
AUTOMATIC1111 690d56f3c1 nuke thumbs extra networks view mode (use settings tab to change width/height/scale to get thumbs) 2023-07-16 10:25:34 +03:00
AUTOMATIC1111 7b052eb70e add resolution calculation from buckets for lora user metadata page 2023-07-16 10:07:02 +03:00
AUTOMATIC1111 ccd97886da fix bogus metadata for extra networks appearing out of cache
fix description editing for checkpoint not immediately appearing on cards
2023-07-16 09:49:34 +03:00
AUTOMATIC1111 f71630edb3 Merge pull request #11794 from MarcusAdams/none-filename-token
Added [none] filename token.
2023-07-16 09:27:28 +03:00
AUTOMATIC1111 89c3e17c65 Merge pull request #11797 from wfjsw/ext-index-env
allow replacing extensions index with environment variable
2023-07-16 09:27:07 +03:00
AUTOMATIC1111 d2e64e26e5 Merge pull request #11802 from AUTOMATIC1111/warns-merge-into-master
Warns merge into master
2023-07-16 09:26:47 +03:00
AUTOMATIC1111 57e4422bdb Merge pull request #11806 from huchenlei/file_500
404 when thumb file not found
2023-07-16 09:26:07 +03:00
AUTOMATIC1111 47d9dd0240 speedup extra networks listing 2023-07-16 09:25:32 +03:00
AUTOMATIC1111 a1d6ada69a allow refreshing single card after editing user metadata instead of all cards 2023-07-16 08:38:23 +03:00
huchenlei 8c11b126e5 404 when thumb file not found 2023-07-15 23:51:18 -04:00
Leon Feng d380f939b5 Update shared.py 2023-07-15 23:31:59 -04:00
AUTOMATIC1111 efceed8c7f fix styles for dark people 2023-07-16 01:09:19 +03:00
AUTOMATIC1111 11f339733d add lora user metadata editor dialog inspired by MrKuenning's mockup from #7458 2023-07-16 00:57:45 +03:00
AUTOMATIC1111 5decbf184b eslint 2023-07-15 21:05:33 +03:00
AUTOMATIC1111 e5d3ae2bf4 user metadata system for custom networks 2023-07-15 20:39:10 +03:00
w-e-w 2970d712ee Warns merge into master 2023-07-16 02:29:20 +09:00
Jabasukuriputo Wang 2d9d53be21 allow replacing extensions index with environment variable 2023-07-15 17:09:51 +08:00
AUTOMATIC1111 c58cf73c80 remove "## " from changelog.md version 2023-07-15 09:33:21 +03:00
AUTOMATIC1111 0aa8d538e1 suppress printing TI embedding into console by default 2023-07-15 09:24:22 +03:00
AUTOMATIC1111 510e5fc8c6 cache git extension repo information 2023-07-15 09:20:43 +03:00
AUTOMATIC1111 2b1bae0d75 add textual inversion hashes to infotext 2023-07-15 08:41:22 +03:00
AUTOMATIC1111 127635409a add padding and identification to generation log section (Failed to find Loras, Used embeddings, etc...) 2023-07-15 08:07:25 +03:00
AUTOMATIC1111 b8bd8ce4cf disable rich exception output in console for API by default, use WEBUI_RICH_EXCEPTIONS env var to enable 2023-07-15 07:44:37 +03:00
AUTOMATIC1111 14cf434bc3 fix an issue in live previews that happens when you use SDXL with fp16 VAE 2023-07-15 07:33:16 +03:00
Marcus Adams 5d94088eac Added [none] filename token. 2023-07-14 21:52:00 -04:00
AUTOMATIC1111 95ee0cb188 restyle time taken/VRAM display 2023-07-14 22:51:58 +03:00
AUTOMATIC1111 5dee0fa1f8 add a message about unsupported samplers 2023-07-14 21:41:21 +03:00
AUTOMATIC1111 ac2d47ff4c add cheap VAE approximation coeffs for SDXL 2023-07-14 20:27:41 +03:00
AUTOMATIC1111 471a5a66b7 add more relevant fields to caching conds 2023-07-14 17:54:09 +03:00
AUTOMATIC1111 92a3236161 Merge branch 'dev' into sdxl 2023-07-14 10:12:48 +03:00
AUTOMATIC1111 9893d09b43 Merge pull request #11779 from AUTOMATIC1111/do-not-run-twice
Do not run git workflows twice for PRs from this repo
2023-07-14 10:09:20 +03:00
AUTOMATIC1111 62e3263467 edit names more 2023-07-14 10:07:08 +03:00
AUTOMATIC1111 9a3f35b028 repair medvram and lowvram 2023-07-14 09:56:01 +03:00
AUTOMATIC1111 714c920c20 do not run workflow items twice for PRs from this repo
update names
2023-07-14 09:47:44 +03:00
AUTOMATIC1111 abb948dab0 raise maximum Negative Guidance minimum sigma due to request in PR discussion 2023-07-14 09:28:01 +03:00
AUTOMATIC1111 b7dbeda0d9 linter 2023-07-14 09:19:08 +03:00
AUTOMATIC1111 6d8dcdefa0 initial SDXL refiner support 2023-07-14 09:16:01 +03:00
AUTOMATIC1111 073e30ee15 Merge pull request #11775 from AUTOMATIC1111/handles-model-hash-cache.json-error
handles model hash cache.json error
2023-07-14 00:18:17 +03:00
w-e-w a3db187e4f handles model hash cache.json error 2023-07-14 05:48:14 +09:00
AUTOMATIC1111 dc39061856 thank you linter 2023-07-13 21:19:41 +03:00
AUTOMATIC1111 6c5f83b19b add support for SDXL loras with te1/te2 modules 2023-07-13 21:17:50 +03:00
AUTOMATIC1111 ff73841c60 mute SDXL imports in the place there SDXL is imported for the first time instead of launch.py 2023-07-13 17:42:16 +03:00
AUTOMATIC1111 e16ebc917d repair --no-half for SDXL 2023-07-13 17:32:35 +03:00
AUTOMATIC1111 b8159d0919 add XL support for live previews: approx and TAESD 2023-07-13 17:24:54 +03:00
AUTOMATIC1111 6f23da603d fix broken img2img 2023-07-13 16:18:39 +03:00
AUTOMATIC1111 066d5edf17 Merge pull request #11730 from tangjicheng46/master
fix: timeout_keep_alive_handler error
2023-07-13 15:21:50 +03:00
AUTOMATIC1111 b7c5b30f14 Merge branch 'dev' into master 2023-07-13 15:21:39 +03:00
AUTOMATIC1111 262ec8ecda Merge pull request #11707 from wfjsw/revert-11244
Revert #11244
2023-07-13 14:51:04 +03:00
AUTOMATIC1111 ed0512c76f Merge pull request #11747 from AUTOMATIC1111/img2img-save
Save img2img batch with images.save_image()
2023-07-13 14:50:08 +03:00
AUTOMATIC1111 cc0a3cc492 Merge pull request #11750 from AUTOMATIC1111/quick-settings-textbox
Use submit and blur for quick settings textbox
2023-07-13 14:49:48 +03:00
AUTOMATIC1111 e93f582a78 Merge pull request #11748 from huaizong/fix/x/resize-less-than-two-pixel-error
fix: check fill size none zero when resize  (fixes #11425)
2023-07-13 14:48:19 +03:00
AUTOMATIC1111 76ebb175ca lora support 2023-07-13 12:59:31 +03:00
AUTOMATIC1111 594c8e7b26 fix CLIP doing the unneeded normalization
revert SD2.1 back to use the original repo
add SDXL's force_zero_embeddings to negative prompt
2023-07-13 11:35:52 +03:00
AUTOMATIC1111 21aec6f567 lint 2023-07-13 09:38:54 +03:00
AUTOMATIC1111 ac4ccfa136 get attention optimizations to work 2023-07-13 09:30:33 +03:00
AUTOMATIC1111 b717eb7e56 mute unneeded SDXL imports for tests too 2023-07-13 08:29:37 +03:00
AUTOMATIC1111 a04c955121 fix importlib.machinery issue on github's autotests #yolo 2023-07-13 00:12:25 +03:00
AUTOMATIC1111 5cf623c58e linter 2023-07-13 00:08:19 +03:00
AUTOMATIC1111 60397a7800 Merge branch 'dev' into sdxl 2023-07-12 23:53:26 +03:00
AUTOMATIC1111 da464a3fb3 SDXL support 2023-07-12 23:52:43 +03:00
w-e-w ea49bb0612 use submit blur for quick settings textbox 2023-07-12 23:30:22 +09:00
AUTOMATIC1111 e5ca987778 Merge pull request #11749 from akx/mps-gc-fix-2
Don't do MPS GC when there's a latent
2023-07-12 16:57:07 +03:00
Aarni Koskela 3d524fd3f1 Don't do MPS GC when there's a latent that could still be sampled 2023-07-12 15:17:30 +03:00
Aarni Koskela 8f6b24ce59 Add correct logger name 2023-07-12 15:16:42 +03:00
missionfloyd e0218c4f22 Merge branch 'dev' into img2img-save 2023-07-12 02:57:57 -06:00
王怀宗 6c0d5d1198 fix: check fill size none zero when resize (fixes #11425) 2023-07-12 16:51:50 +08:00
missionfloyd 3fee3c34f1 Save img2img batch with images.save_image() 2023-07-12 02:45:03 -06:00
AUTOMATIC1111 af081211ee getting SD2.1 to run on SDXL repo 2023-07-11 21:16:43 +03:00
AUTOMATIC1111 15adff3d6d Merge pull request #11733 from akx/brace-for-impact
Allow using alt in the prompt fields again
2023-07-11 15:25:59 +03:00
Aarni Koskela 3636c2c6ed Allow using alt in the prompt fields again 2023-07-11 15:05:20 +03:00
AUTOMATIC1111 799760ab95 Merge pull request #11722 from akx/mps-gc-fix
Fix MPS cache cleanup
2023-07-11 13:49:02 +03:00
Aarni Koskela b85fc7187d Fix MPS cache cleanup
Importing torch does not import torch.mps so the call failed.
2023-07-11 12:51:05 +03:00
TangJicheng 14501f56aa set timeout_keep_alive 2023-07-11 17:32:04 +09:00
TangJicheng 10d4e4ace2 add cmd_args: --timeout-keep-alive 2023-07-11 17:30:57 +09:00
AUTOMATIC1111 7b833291b3 Merge branch 'master' into dev 2023-07-11 06:25:50 +03:00
AUTOMATIC1111 f865d3e116 add changelog for 1.4.1 2023-07-11 06:23:52 +03:00
AUTOMATIC1111 910d4f61e5 Merge pull request #11720 from akx/closing
Use closing() with processing classes everywhere
2023-07-10 20:41:09 +03:00
AUTOMATIC1111 8d0078b6ef Merge pull request #11718 from tangjicheng46/master
fix: add queue lock for refresh-checkpoints
2023-07-10 20:40:58 +03:00
Aarni Koskela 44c27ebc73 Use closing() with processing classes everywhere
Follows up on #11569
2023-07-10 20:08:23 +03:00
tangjicheng 089a0022ae add queue lock for refresh-checkpoints 2023-07-10 23:10:14 +09:00
wfjsw 75f56406ce Revert Pull Request #11244
Revert "Add github mirror for the download extension"

This reverts commit 9ec2ba2d28.

Revert "Update code style"

This reverts commit de022c4c80.

Revert "Update call method"

This reverts commit e9bd18c57b.

Revert "move github proxy to settings, System page."

This reverts commit 4981c7d370.
2023-07-09 22:42:00 +08:00
AUTOMATIC1111 bcb6ad5fab Merge pull request #11696 from WuSiYu/feat_SWIN_torch_compile
feat: add option SWIN_torch_compile to accelerate SwinIR upscale
2023-07-08 23:05:17 +03:00
SiYu Wu 44d66daaad add option SWIN_torch_compile to accelerate SwinIR upscale using torch.compile() 2023-07-09 03:27:33 +08:00
AUTOMATIC1111 7dcdf81b84 Merge pull request #11595 from akx/alisases
Fix typo: checkpoint_alisases
2023-07-08 17:53:55 +03:00
AUTOMATIC1111 e3507a1be4 fix for eslint 2023-07-08 17:53:17 +03:00
AUTOMATIC1111 4981c7d370 move github proxy to settings, System page. 2023-07-08 17:52:03 +03:00
AUTOMATIC1111 ee642a2ff4 Merge pull request #11244 from MaiXiaoMeng/dev
Add github mirror for the download extension
2023-07-08 17:38:29 +03:00
AUTOMATIC1111 4da92281f6 pin version for torch for Navi3 according to comment from #11228 2023-07-08 17:29:28 +03:00
Aarni Koskela da468a585b Fix typo: checkpoint_alisases 2023-07-08 17:28:42 +03:00
AUTOMATIC1111 ed855783ed Merge pull request #11228 from Beinsezii/dev
WEBUI.SH Navi 3 Support
2023-07-08 17:28:04 +03:00
AUTOMATIC1111 386f78035b Merge pull request #11672 from nelsonjchen/patch-1
Add a link to an index-able/crawl-able wiki mirroring service of the wiki
2023-07-08 17:21:05 +03:00
AUTOMATIC1111 da8916f926 added torch.mps.empty_cache() to torch_gc()
changed a bunch of places that use torch.cuda.empty_cache() to use torch_gc() instead
2023-07-08 17:13:18 +03:00
AUTOMATIC1111 e161b5a025 rework #10436 to use shared.walk_files 2023-07-08 16:54:03 +03:00
AUTOMATIC1111 353031a014 Merge pull request #10436 from lenankamp/patch-1
Recursive batch img2img.py
2023-07-08 16:50:54 +03:00
AUTOMATIC1111 993dd9a892 Merge branch 'dev' into patch-1 2023-07-08 16:50:23 +03:00
AUTOMATIC1111 d7d6e8cfc8 use natural sort for shared.walk_files and shared.listfiles, as well as for dirs in extra networks 2023-07-08 16:45:59 +03:00
AUTOMATIC1111 7a6abc59ea for #10650: change key to alt+arrows, enable by default 2023-07-08 16:15:28 +03:00
AUTOMATIC1111 12a29a677a Merge pull request #10650 from missionfloyd/reorder-hotkeys
Hotkeys to move prompt elements
2023-07-08 16:12:01 +03:00
AUTOMATIC1111 274a3e21ba small rework for img2img PNG info 2023-07-08 15:42:00 +03:00
AUTOMATIC1111 1d71c36de2 third time's the charm 2023-07-08 15:21:29 +03:00
AUTOMATIC1111 9043b91649 additional changes for merge conflict for #11337 2023-07-08 15:14:24 +03:00
AUTOMATIC1111 b88645d9eb additional changes for merge conflict for #11337 2023-07-08 15:14:14 +03:00
AUTOMATIC1111 b0419b60a0 Merge pull request #11337 from FWeynschenk/img2img-batch-png-info
Img2img batch png info
2023-07-08 15:10:33 +03:00
AUTOMATIC1111 ec9bbda3da Merge branch 'dev' into img2img-batch-png-info 2023-07-08 15:10:10 +03:00
AUTOMATIC1111 18256c5f01 fix for #11478 2023-07-08 14:58:33 +03:00
AUTOMATIC1111 211c3398f6 Merge pull request #11478 from catalpaaa/subpath
Fixing --subpath on newer gradio version
2023-07-08 14:53:42 +03:00
AUTOMATIC1111 539518292e Merge pull request #11468 from NoCrypt/grid-colors-options
Add options to change colors in grid
2023-07-08 14:51:50 +03:00
AUTOMATIC1111 f0c62688d2 Merge pull request #11488 from AUTOMATIC1111/callback-after_extra_networks_activate
add callback after_extra_networks_activate
2023-07-08 14:50:11 +03:00
AUTOMATIC1111 3602602260 whitespace for #11477 2023-07-08 14:44:02 +03:00
AUTOMATIC1111 53924aeaf0 Merge pull request #11477 from hako-mikan/master
add `before_hr` script callback
2023-07-08 14:43:06 +03:00
AUTOMATIC1111 953147bf6b Merge pull request #11495 from missionfloyd/end-paren-fix
Correctly remove end parenthesis with ctrl+up/down
2023-07-08 14:41:33 +03:00
AUTOMATIC1111 eb51acb89e Merge pull request #11503 from AUTOMATIC1111/rename---add-stop-route-to---api-server-stop
Rename --add-stop-route to --api-server-stop
2023-07-08 14:40:21 +03:00
AUTOMATIC1111 6acc4cd7e1 Merge pull request #11513 from Akegarasu/dev
fix can't get current hash
2023-07-08 14:39:52 +03:00
AUTOMATIC1111 b25925c95b Merge pull request #11520 from AUTOMATIC1111/extension-metadata
Extension metadata
2023-07-08 14:30:17 +03:00
AUTOMATIC1111 b74f661ed9 Merge pull request #11529 from hunshcn/sync-weight
sync default value of process_focal_crop_entropy_weight between ui and api
2023-07-08 14:24:48 +03:00
AUTOMATIC1111 7a7fa25d02 lint fix for #11492 2023-07-08 14:21:40 +03:00
AUTOMATIC1111 d78377ea5d Merge pull request #11593 from akx/better-status-reporting-1
Better status reporting, part 1
2023-07-08 14:20:28 +03:00
AUTOMATIC1111 fc049a2fd3 Merge branch 'dev' into better-status-reporting-1 2023-07-08 14:19:34 +03:00
AUTOMATIC1111 ae74b44c69 Merge pull request #11596 from akx/use-read-info
postprocessing: use read_info_from_image
2023-07-08 14:14:12 +03:00
AUTOMATIC1111 9be8903ca9 Merge pull request #11567 from AUTOMATIC1111/seed_resize_to_0
Don't add "Seed Resize: -1x-1" to API image metadata
2023-07-08 13:58:31 +03:00
AUTOMATIC1111 e338f4142f Merge pull request #11592 from onyasumi/launchscript-directory
Fixed launch script to be runnable from any directory
2023-07-08 13:57:01 +03:00
AUTOMATIC1111 3a294a08bc Merge pull request #11535 from gshawn3/bugfix/11534
fix for #11534: canvas zoom and pan extension hijacking shortcut keys
2023-07-08 13:48:58 +03:00
AUTOMATIC1111 d12ccb91a8 Merge pull request #11631 from AUTOMATIC1111/gif-preview
Allow gif for extra network previews
2023-07-08 13:47:57 +03:00
AUTOMATIC1111 2151a9881f Merge pull request #11492 from semjon00/dev
Fix throwing exception when trying to resize image with I;16 mode
2023-07-08 13:46:08 +03:00
AUTOMATIC1111 19772c3c97 fix problem with extra network saving images as previews losing generation info
add a description for save_image_with_geninfo
2023-07-08 13:43:42 +03:00
AUTOMATIC1111 16045d0877 Merge pull request #11637 from Hao-Wu/fix-has-mps-deprecated
Fix warning of 'has_mps' deprecated from PyTorch
2023-07-08 13:11:52 +03:00
AUTOMATIC1111 5ed1ae5003 Merge pull request #11656 from jovijovi/dev
fix(api): convert to "RGB" if image mode is "RGBA" #11655
2023-07-08 13:10:50 +03:00
AUTOMATIC1111 46c2b1e202 Merge pull request #11660 from neilmahaseth/patch-1
Fix UnicodeEncodeError when writing to file CLIP Interrogator Batch Mode
2023-07-08 13:10:03 +03:00
AUTOMATIC1111 7348440524 Merge pull request #11569 from ramyma/hotfix-api-cache
Hotfix: API cache cleanup
2023-07-08 13:09:20 +03:00
Nelson Chen a369a0cf65 Add a link to an index-able/crawl-able wiki mirroring service of the wiki
At the moment, the wiki is editable by GitHub users, so it is blocked from indexing. If you are searching for something related to this repo, Google and other search engines will not use the content for it.

This link hack just sticks a link on the README so search engines may prioritize it. At the moment, 0 pages from GitHub are index and only 7 pages from my proxy service are. If you add this, the rest should get indexed.

An indexable page looks like this: https://github-wiki-see.page/m/AUTOMATIC1111/stable-diffusion-webui/wiki/Command-Line-Arguments-and-Settings. It is not meant to be read, just indexed, and users are expected to click through to the GitHub copy.

https://github-wiki-see.page/ has more information about the situation. I built the tool and I'm happy to answer any questions I can.

Similar: https://github.com/MiSTer-devel/Main_MiSTer#main_mister-main-binary-and-wiki-repo:~:text=For%20the%20purposes%20of%20getting%20google%20to%20crawl%20the%20wiki%2C%20here%27s%20a%20link%20to%20the%20(not%20for%20humans)%20crawlable%20wiki
2023-07-07 09:04:49 -07:00
gitama2023 f439179641 Added a prompt for users using poor scaling
Added a JavaScript file that detects browser scaling and prompts users when scale is not 100%
2023-07-07 16:18:01 +08:00
Neil Mahseth c258dd34a8 Fix UnicodeEncodeError when writing to file CLIP Interrogator Batch Mode
The code snippet print(interrogation_function(img), file=open(os.path.join(ii_output_dir, f"{left}.txt"), 'a')) raises a UnicodeEncodeError with the message "'charmap' codec can't encode character '\u016b' in position 129". This error occurs because the default encoding used by the open() function cannot handle certain Unicode characters.

To fix this issue, the encoding parameter needs to be explicitly specified when opening the file. By using an appropriate encoding, such as 'utf-8', we can ensure that Unicode characters are properly encoded and written to the file.

The updated code should be modified as follows:

python
Copy code
print(interrogation_function(img), file=open(os.path.join(ii_output_dir, f"{left}.txt"), 'a', encoding='utf-8'))
By making this change, the code will no longer raise the UnicodeEncodeError and will correctly handle Unicode characters during the file write operation.
2023-07-06 22:02:47 +05:30
jovijovi 259967b7c6 fix(api): convert to "RGB" if image mode is "RGBA" 2023-07-06 18:43:17 +08:00
Hao-Wu daf41a2734 Fix warning of 'has_mps' is deprecated from PyTorch 2023-07-06 15:37:10 +08:00
semjon00 fb661e089f Fix throwing exception when trying to resize image with I;16 mode 2023-07-05 15:39:04 +03:00
missionfloyd c602471b85 Allow gif for extra network previews 2023-07-05 03:19:26 -06:00
Danil Boldyrev f325783abd made the blur function optional, added exclusion buttons 2023-07-04 22:26:43 +03:00
missionfloyd f731a728c6 Check seed_resize_from <= 0 2023-07-03 11:41:10 -06:00
ramyma c1c0492859 Use contextlib for closing the generation process 2023-07-03 20:17:47 +03:00
ramyma 3278887317 Handle cleanup in case there's an exception thrown 2023-07-03 20:02:30 +03:00
Aarni Koskela 5c6a33b3e1 read_info_from_image: don't mutate info in passed-in image 2023-07-03 13:10:42 +03:00
Aarni Koskela 96f0593c8f read_info_from_image: add type 2023-07-03 13:10:20 +03:00
Aarni Koskela b2c574891f read_info_from_image: add photoshop to ignored 2023-07-03 13:09:37 +03:00
Aarni Koskela 08f9b705cd Use read_info_from_image in postprocessing
Avoids bad keys such as `exif` ending up in the "PNG info" passed forward
2023-07-03 13:08:28 +03:00
Aarni Koskela 522a8b9f62 Add a status logger in modules.shared 2023-07-03 11:07:57 +03:00
Aarni Koskela e430344347 API: use finally: for state.end() 2023-07-03 11:03:41 +03:00
Aarni Koskela f44feb6a10 Add job argument to State.begin() 2023-07-03 11:03:41 +03:00
Aarni Koskela b70001e618 Add SD_WEBUI_LOG_LEVEL envvar 2023-07-03 11:03:41 +03:00
Frank Tao e33e2c5175 Update webui.sh 2023-07-03 03:17:27 -04:00
onyasumi 5a32d4fcb1 Fix launch script to be runnable from any directory 2023-07-03 07:15:19 +00:00
Danil Boldyrev 8519d52ef5 fixing the copy/paste function, correct code 2023-07-02 19:20:49 +03:00
ramyma 74d001bc68 Hotfix: call processing close to cleanup API generation calls 2023-07-02 04:59:59 +03:00
missionfloyd 7f46f81dd7 Change default seed_resize to 0 2023-07-01 17:20:56 -06:00
gshawn3 8a07c59baa fix for #11534: canvas zoom and pan extension hijacking shortcut keys 2023-06-30 03:49:26 -07:00
w-e-w 2ccc832b33 add extensions Update Created dates with sorting 2023-06-29 22:46:59 +09:00
Akiba 0416a7bfba fix can't get current hash 2023-06-29 18:46:52 +08:00
w-e-w b1c6e39620 starts left 2023-06-29 19:25:34 +09:00
w-e-w d47324b898 add stars 2023-06-29 19:25:18 +09:00
hunshcn 0bc0e652a3 sync default value of process_focal_crop_entropy_weight between ui and api 2023-06-29 18:12:55 +08:00
w-e-w cc9c171978 rename --add-stop-route to --api-server-stop 2023-06-29 14:21:28 +09:00
missionfloyd 0b0767939d Correctly remove end parenthesis with ctrl+up/down 2023-06-28 17:51:27 -06:00
w-e-w 9c2a7f1e8b add callback after_extra_networks_activate 2023-06-29 02:08:21 +09:00
NoCrypt f74fb50495 Move change colors options to Saving images/grids 2023-06-28 20:24:57 +07:00
NoCrypt d22eb8a17f Fix lint 2023-06-28 17:57:34 +07:00
NoCrypt 45ab7475d6 Revision 2023-06-28 17:55:58 +07:00
catalpaaa 24d4475bdb fixing --subpath on newer gradio version 2023-06-28 03:15:01 -07:00
hako-mikan b0ec69b360 add 'before_hr callback' script callback 2023-06-28 18:37:08 +09:00
NoCrypt da14f6a663 Add options to change colors in grid 2023-06-28 10:16:44 +07:00
Beinsezii 9d8af4bd6a Merge branch 'AUTOMATIC1111:dev' into dev 2023-06-27 15:29:47 -07:00
AUTOMATIC1111 fab73f2e7d Merge pull request #11325 from stablegeniusdiffuser/dev-batch-grid-metadata
Add parameter to differentiate between batch run grids or ordinary images to write proper metadata
2023-06-27 14:23:39 +03:00
AUTOMATIC1111 1bf01b73f4 Merge pull request #11046 from akx/ded-code
Remove a bunch of unused/vestigial code
2023-06-27 11:25:55 +03:00
AUTOMATIC d06af4e517 fix and rework #11113 2023-06-27 09:26:18 +03:00
AUTOMATIC1111 a96687682a Merge pull request #11113 from stevensu1977/master
add model exists status check /sdapi/v1/options  #11112
2023-06-27 09:24:12 +03:00
AUTOMATIC1111 0b97ae2832 Merge branch 'dev' into master 2023-06-27 09:23:15 +03:00
AUTOMATIC1111 3cd4fd51ef Merge pull request #10823 from akx/model-loady
Upscaler model loading cleanup
2023-06-27 09:20:49 +03:00
AUTOMATIC1111 d4f9250c5a Merge pull request #11201 from akx/ruff-upg
Upgrade Ruff to 0.0.272
2023-06-27 09:19:55 +03:00
AUTOMATIC 24129368f1 send tensors to the correct device when loading from safetensors file with memmap disabled for #11260 2023-06-27 09:19:04 +03:00
AUTOMATIC1111 14196548c5 Merge pull request #11260 from dhwz/dev
fix very slow loading speed of .safetensors files
2023-06-27 09:11:08 +03:00
AUTOMATIC1111 d35e246111 Merge pull request #11227 from deckar01/10141-gradio-user-exif
Add Gradio User to Metadata
2023-06-27 09:06:03 +03:00
AUTOMATIC1111 4147fd6b2f Merge branch 'dev' into 10141-gradio-user-exif 2023-06-27 09:05:53 +03:00
AUTOMATIC1111 bedcd2f377 Merge pull request #11264 from huchenlei/meta_class
🐛 Allow Script to have custom metaclass
2023-06-27 09:02:51 +03:00
AUTOMATIC1111 58a9a261c4 Merge branch 'dev' into meta_class 2023-06-27 09:02:38 +03:00
AUTOMATIC1111 2c43dd766d Merge pull request #11226 from AUTOMATIC1111/git-clone-progress
show Git clone progress
2023-06-27 09:01:04 +03:00
AUTOMATIC 9bb1fcfad4 alternate fix for catch errors when retrieving extension index #11290 2023-06-27 08:59:35 +03:00
AUTOMATIC1111 fa31dd80f5 Merge pull request #11315 from guming3d/master
fix: adding elem_id for img2img resize to and resize by tabs
2023-06-27 08:53:10 +03:00
AUTOMATIC1111 2b247f3533 Merge pull request #11415 from netux/extensions-toggle-all
Add checkbox to check/uncheck all extensions in the Installed tab
2023-06-27 08:44:37 +03:00
AUTOMATIC1111 3e76ae5f50 Merge pull request #11146 from AUTOMATIC1111/api-quit-restart
api quit restart
2023-06-27 08:41:36 +03:00
AUTOMATIC f005efae72 Merge branch 'master' into dev 2023-06-27 08:39:34 +03:00
AUTOMATIC 394ffa7b0a Merge branch 'release_candidate' 2023-06-27 08:38:14 +03:00
AUTOMATIC 6ac247317d Merge branch 'release_candidate' into dev 2023-06-27 08:37:46 +03:00
AUTOMATIC1111 dbc88c9645 Merge pull request #11189 from daswer123/dev
Zoom and pan: More options in the settings and improved error output
2023-06-27 08:34:51 +03:00
AUTOMATIC1111 cd7c03e1f6 Merge pull request #11136 from arch-fan/typo
fixed typos
2023-06-27 06:40:43 +03:00
AUTOMATIC1111 a9e7a3db3e Merge pull request #11199 from akx/makedirs
Use os.makedirs(..., exist_ok=True)
2023-06-27 06:39:51 +03:00
AUTOMATIC1111 001cbd369d Merge pull request #11294 from zhtttylz/Fix_Typo_of_hints.js
Fix Typo of hints.js
2023-06-27 06:35:22 +03:00
AUTOMATIC1111 820bbb5b7b Merge pull request #11408 from wfjsw/patch-1
Strip whitespaces from URL and dirname prior to extension installation
2023-06-27 06:20:59 +03:00
AUTOMATIC 4bd490c28d add missing infotext entry for the pad cond/uncond option 2023-06-27 06:18:43 +03:00
Martín (Netux) Rodríguez dd268c48c9 feat(extensions): add toggle all checkbox to Installed tab
Small QoL addition.

While there is the option to disable all extensions with the radio buttons at the top, that only acts as an added flag and doesn't really change the state of the extensions in the UI.

An use case for this checkbox is to disable all extensions except for a few, which is important for debugging extensions.
You could do that before, but you'd have to uncheck and recheck every extension one by one.
2023-06-25 00:48:46 -03:00
Jabasukuriputo Wang d5a5f2f29f Strip whitespaces from URL and dirname prior to extension installation
This avoid some cryptic errors brought by accidental spaces around urls
2023-06-25 01:31:02 +08:00
Ferdinand Weynschenk c4c63dd5e4 resolve linter 2023-06-20 14:03:42 +02:00
Ferdinand Weynschenk 7ad48120d4 use ui params when retreiving png info fails
Don't want to interrupt the process since batches can be huge. This makes more sense to me than using the previous images parameters
2023-06-20 13:50:02 +02:00
Ferdinand Weynschenk 928bd42da4 PNG info support at img2img batch 2023-06-20 13:33:36 +02:00
stablegeniusdiffuser 27e9e3f6fa Add use_main_prompt parameter to use proper metadata for batch run grids or individual images 2023-06-19 20:36:44 +02:00
George Gu d2ccdcdc97 fix: adding elem_id for img2img resize to and resize by tabs 2023-06-19 10:16:18 +08:00
zhtttylz f7ae0e68c9 Fix Typo of hints.js 2023-06-18 16:42:39 +08:00
w-e-w 2e1710d88e update the description of --add-stop-rout 2023-06-18 14:07:41 +09:00
huchenlei 373ff5a217 🐛 Allow Script to have metaclass 2023-06-16 15:17:17 -04:00
dhwz 41363e0d27 fix very slow loading speed of .safetensors files 2023-06-16 18:10:15 +02:00
XiaoMeng Mai e9bd18c57b Update call method 2023-06-16 00:09:54 +08:00
Jared Deckard f603275d84 Add an opt-in infotext user name setting 2023-06-15 11:00:20 -05:00
Jared Deckard 8f18e67243 Add a user pattern to the filename generator 2023-06-15 11:00:11 -05:00
XiaoMeng Mai de022c4c80 Update code style 2023-06-15 22:59:46 +08:00
XiaoMeng Mai 9ec2ba2d28 Add github mirror for the download extension 2023-06-15 22:43:09 +08:00
Jared Deckard d3c86e5178 Note the Gradio user in the Exif data 2023-06-14 17:15:52 -05:00
Beinsezii 1d7c51fb9f WEBUI.SH Navi 3 Support
Navi 3 card now defaults to nightly torch to utilize rocm 5.5
for out-of-the-box support.

https://download.pytorch.org/whl/nightly/

While its not yet on the main pytorch "get started" site,
it still seems perfectly indexable via pip which is all we need.

With this I'm able to clone a fresh repo and immediately run ./webui.sh
on my 7900 XTX without any problems.
2023-06-14 13:07:22 -07:00
w-e-w 376f793bde git clone show progress 2023-06-15 04:23:52 +09:00
Jared Deckard fa9d2ac2ff Fix gradio special args in the call queue 2023-06-14 13:53:13 -05:00
w-e-w 6091c4e4aa terminate -> stop 2023-06-14 19:53:08 +09:00
w-e-w 49fb2a3376 response 501 if not a able to restart 2023-06-14 19:52:12 +09:00
w-e-w 6387f0e85d update workflow kill test server 2023-06-14 18:51:54 +09:00
w-e-w 5be6c026f5 rename routes 2023-06-14 18:51:47 +09:00
Danil Boldyrev 3a41d7c551 Formatting code with Prettier 2023-06-14 00:31:36 +03:00
Danil Boldyrev 9b687f013d Reworked the disabling of functions, refactored part of the code 2023-06-14 00:24:25 +03:00
Aarni Koskela d807164776 textual_inversion/logging.py: clean up duplicate key from sets (and sort them) (Ruff B033) 2023-06-13 13:07:39 +03:00
Aarni Koskela 8ce9b36e0f Upgrade ruff to 272 2023-06-13 13:07:06 +03:00
Aarni Koskela 2667f47ffb Remove stray space from SwinIR model URL 2023-06-13 13:00:05 +03:00
Aarni Koskela bf67a5dcf4 Upscaler.load_model: don't return None, just use exceptions 2023-06-13 12:44:25 +03:00
Aarni Koskela e3a973a68d Add TODO comments to sus model loads 2023-06-13 12:38:29 +03:00
Aarni Koskela 0afbc0c235 Fix up if "http" in ...: to be more sensible startswiths 2023-06-13 12:38:29 +03:00
Aarni Koskela 89352a2f52 Move load_file_from_url to modelloader 2023-06-13 12:38:28 +03:00
Aarni Koskela 165ab44f03 Use os.makedirs(..., exist_ok=True) 2023-06-13 12:35:43 +03:00
Danil Boldyrev 9a2da597c5 remove console.log 2023-06-12 22:21:42 +03:00
Danil Boldyrev ee029a8cad Improved error output, improved settings menu 2023-06-12 22:19:22 +03:00
w-e-w d80962681a remove fastapi.Response 2023-06-12 18:21:01 +09:00
w-e-w b9664ab615 move _stop route to api 2023-06-12 18:15:27 +09:00
Su Wei 7e2d39a2d1 update model checkpoint switch code 2023-06-12 15:22:49 +08:00
w-e-w 9142be0a0d quit restart 2023-06-10 23:36:34 +09:00
arch-fan 5576a72322 fixed typos 2023-06-09 19:59:27 +00:00
AUTOMATIC 3b11f17a37 Merge branch 'dev' into release_candidate 2023-06-09 22:48:18 +03:00
Su Wei 8ca34ad6d8 add model exists status check to modeuls/api/api.py , /sdapi/v1/options [POST] 2023-06-09 13:14:20 +08:00
Aarni Koskela ba70a220e3 Remove a bunch of unused/vestigial code
As found by Vulture and some eyes
2023-06-05 22:43:57 +03:00
missionfloyd 6645f23c4c Merge branch 'dev' into reorder-hotkeys 2023-05-25 18:53:33 -06:00
missionfloyd 43bdaa2f0e Make ctrl+left/right optional 2023-05-25 18:49:28 -06:00
missionfloyd dafe519363 Fix lint errors 2023-05-22 21:23:39 -06:00
missionfloyd 468056958b Add reorder hotkeys
Shifts selected items with ctrl+left/right
2023-05-22 20:46:25 -06:00
lenankamp ff6acd35d0 Update img2img.py
Hopefully corrected the white space issue
2023-05-19 03:20:19 -04:00
lenankamp bbce167305 Recursive batch img2img.py
Searches sub directories and performs img2img batch processing, also limits inputs to jpg, webp, and png. Then saves to putput directory with relative paths.
2023-05-16 14:37:45 -04:00
254 changed files with 24287 additions and 11521 deletions
+9 -2
View File
@@ -74,9 +74,12 @@ module.exports = {
create_submit_args: "readonly", create_submit_args: "readonly",
restart_reload: "readonly", restart_reload: "readonly",
updateInput: "readonly", updateInput: "readonly",
onEdit: "readonly",
//extraNetworks.js //extraNetworks.js
requestGet: "readonly", requestGet: "readonly",
popup: "readonly", popup: "readonly",
// profilerVisualization.js
createVisualizationTable: "readonly",
// from python // from python
localization: "readonly", localization: "readonly",
// progrssbar.js // progrssbar.js
@@ -85,7 +88,11 @@ module.exports = {
// imageviewer.js // imageviewer.js
modalPrevImage: "readonly", modalPrevImage: "readonly",
modalNextImage: "readonly", modalNextImage: "readonly",
// token-counters.js // localStorage.js
setupTokenCounters: "readonly", localSet: "readonly",
localGet: "readonly",
localRemove: "readonly",
// resizeHandle.js
setupResizeHandle: "writable"
} }
}; };
+51 -84
View File
@@ -1,35 +1,55 @@
name: Bug Report name: Bug Report
description: You think somethings is broken in the UI description: You think something is broken in the UI
title: "[Bug]: " title: "[Bug]: "
labels: ["bug-report"] labels: ["bug-report"]
body: 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 - type: markdown
attributes: attributes:
value: | 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 - type: textarea
id: what-did id: what-did
attributes: attributes:
label: What happened? label: What happened?
description: Tell us what happened in a very clear and simple way description: Tell us what happened in a very clear and simple way
placeholder: |
txt2img is not working as intended.
validations: validations:
required: true required: true
- type: textarea - type: textarea
id: steps id: steps
attributes: attributes:
label: Steps to reproduce the problem label: Steps to reproduce the problem
description: Please provide us with precise step by step information on how to reproduce the bug description: Please provide us with precise step by step instructions on how to reproduce the bug
value: | placeholder: |
1. Go to .... 1. Go to ...
2. Press .... 2. Press ...
3. ... 3. ...
validations: validations:
required: true required: true
@@ -37,64 +57,9 @@ body:
id: what-should id: what-should
attributes: attributes:
label: What should have happened? label: What should have happened?
description: Tell what you think the normal behavior should be description: Tell us what you think the normal behavior should be
validations: placeholder: |
required: true WebUI should ...
- 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 "
validations: validations:
required: true required: true
- type: dropdown - type: dropdown
@@ -108,26 +73,25 @@ body:
- Brave - Brave
- Apple Safari - Apple Safari
- Microsoft Edge - Microsoft Edge
- Android
- iOS
- Other
- type: textarea - type: textarea
id: cmdargs id: sysinfo
attributes: attributes:
label: Command Line Arguments label: Sysinfo
description: Are you using any launching parameters/command line arguments (modified webui-user .bat/.sh) ? If yes, please write them below. Write "No" otherwise. 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.
render: Shell placeholder: |
validations: 1. Go to WebUI Settings -> Sysinfo -> Download system info.
required: true If WebUI fails to launch, use --dump-sysinfo commandline argument to generate the file
- type: textarea 2. Upload the Sysinfo as a attached file, Do NOT paste it in as plain text.
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.
validations: validations:
required: true required: true
- type: textarea - type: textarea
id: logs id: logs
attributes: attributes:
label: Console logs 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 render: Shell
validations: validations:
required: true required: true
@@ -135,4 +99,7 @@ body:
id: misc id: misc
attributes: attributes:
label: Additional information 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.
+10 -6
View File
@@ -1,4 +1,4 @@
name: Run Linting/Formatting on Pull Requests name: Linter
on: on:
- push - push
@@ -6,11 +6,13 @@ on:
jobs: jobs:
lint-python: lint-python:
name: ruff
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v3 uses: actions/checkout@v4
- uses: actions/setup-python@v4 - uses: actions/setup-python@v5
with: with:
python-version: 3.11 python-version: 3.11
# NB: there's no cache: pip here since we're not installing anything # NB: there's no cache: pip here since we're not installing anything
@@ -18,16 +20,18 @@ jobs:
# not to have GHA download an (at the time of writing) 4 GB cache # not to have GHA download an (at the time of writing) 4 GB cache
# of PyTorch and other dependencies. # of PyTorch and other dependencies.
- name: Install Ruff - name: Install Ruff
run: pip install ruff==0.0.265 run: pip install ruff==0.3.3
- name: Run Ruff - name: Run Ruff
run: ruff . run: ruff .
lint-js: lint-js:
name: eslint
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 18
- run: npm i --ci - run: npm i --ci
+19 -8
View File
@@ -1,4 +1,4 @@
name: Run basic features tests on CPU with empty SD model name: Tests
on: on:
- push - push
@@ -6,18 +6,26 @@ on:
jobs: jobs:
test: test:
name: tests on CPU with empty model
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Set up Python 3.10 - name: Set up Python 3.10
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: 3.10.6 python-version: 3.10.6
cache: pip cache: pip
cache-dependency-path: | cache-dependency-path: |
**/requirements*txt **/requirements*txt
launch.py launch.py
- name: Cache models
id: cache-models
uses: actions/cache@v4
with:
path: models
key: "2023-12-30"
- name: Install test dependencies - name: Install test dependencies
run: pip install wait-for-it -r requirements-test.txt run: pip install wait-for-it -r requirements-test.txt
env: env:
@@ -31,6 +39,8 @@ jobs:
TORCH_INDEX_URL: https://download.pytorch.org/whl/cpu TORCH_INDEX_URL: https://download.pytorch.org/whl/cpu
WEBUI_LAUNCH_LIVE_OUTPUT: "1" WEBUI_LAUNCH_LIVE_OUTPUT: "1"
PYTHONUNBUFFERED: "1" PYTHONUNBUFFERED: "1"
- name: Print installed packages
run: pip freeze
- name: Start test server - name: Start test server
run: > run: >
python -m coverage run python -m coverage run
@@ -39,31 +49,32 @@ jobs:
--skip-prepare-environment --skip-prepare-environment
--skip-torch-cuda-test --skip-torch-cuda-test
--test-server --test-server
--do-not-download-clip
--no-half --no-half
--disable-opt-split-attention --disable-opt-split-attention
--use-cpu all --use-cpu all
--add-stop-route --api-server-stop
2>&1 | tee output.txt & 2>&1 | tee output.txt &
- name: Run tests - name: Run tests
run: | 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 python -m pytest -vv --junitxml=test/results.xml --cov . --cov-report=xml --verify-base-url test
- name: Kill test server - name: Kill test server
if: always() if: always()
run: curl -vv -XPOST http://127.0.0.1:7860/_stop && sleep 10 run: curl -vv -XPOST http://127.0.0.1:7860/sdapi/v1/server-stop && sleep 10
- name: Show coverage - name: Show coverage
run: | run: |
python -m coverage combine .coverage* python -m coverage combine .coverage*
python -m coverage report -i python -m coverage report -i
python -m coverage html -i python -m coverage html -i
- name: Upload main app output - name: Upload main app output
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: output name: output
path: output.txt path: output.txt
- name: Upload coverage HTML - name: Upload coverage HTML
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: htmlcov name: htmlcov
+19
View File
@@ -0,0 +1,19 @@
name: Pull requests can't target master branch
"on":
pull_request:
types:
- opened
- synchronize
- reopened
branches:
- master
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Warning marge into master
run: |
echo -e "::warning::This pull request directly merge into \"master\" branch, normally development happens on \"dev\" branch."
exit 1
+5
View File
@@ -2,6 +2,7 @@ __pycache__
*.ckpt *.ckpt
*.safetensors *.safetensors
*.pth *.pth
.DS_Store
/ESRGAN/* /ESRGAN/*
/SwinIR/* /SwinIR/*
/repositories /repositories
@@ -37,3 +38,7 @@ notification.mp3
/node_modules /node_modules
/package-lock.json /package-lock.json
/.coverage* /.coverage*
/test/test_outputs
/cache
trace.json
/sysinfo-????-??-??-??-??.json
+831 -3
View File
@@ -1,3 +1,831 @@
## 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:
* support parsing text encoder blocks in some new LoRAs
* delete scale checker script due to user demand
### Extensions and API:
* add postprocess_batch_list script callback
### Bug Fixes:
* fix TI training for SD1
* fix reload altclip model error
* prepend the pythonpath instead of overriding it
* fix typo in SD_WEBUI_RESTARTING
* if txt2img/img2img raises an exception, finally call state.end()
* fix composable diffusion weight parsing
* restyle Startup profile for black users
* fix webui not launching with --nowebui
* catch exception for non git extensions
* fix some options missing from /sdapi/v1/options
* fix for extension update status always saying "unknown"
* fix display of extra network cards that have `<>` in the name
* update lora extension to work with python 3.8
## 1.5.0
### Features:
* SD XL support
* 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 extensions
* img2img batch mode can read extra stuff from png info
* img2img batch works with subdirectories
* hotkeys to move prompt elements: alt+left/right
* restyle time taken/VRAM display
* add textual inversion hashes to infotext
* optimization: cache git extension repo information
* move generate button next to the generated picture for mobile clients
* hide cards for networks of incompatible Stable Diffusion version in Lora extra networks interface
* skip installing packages with pip if they all are already installed - startup speedup of about 2 seconds
### Minor:
* checkbox to check/uncheck all extensions in the Installed tab
* add gradio user to infotext and to filename patterns
* allow gif for extra network previews
* add options to change colors in grid
* use natural sort for items in extra networks
* Mac: use empty_cache() from torch 2 to clear VRAM
* added automatic support for installing the right libraries for Navi3 (AMD)
* add option SWIN_torch_compile to accelerate SwinIR upscale
* suppress printing TI embedding info at start to console by default
* speedup extra networks listing
* added `[none]` filename token.
* removed thumbs extra networks view mode (use settings tab to change width/height/scale to get thumbs)
* add always_discard_next_to_last_sigma option to XYZ plot
* automatically switch to 32-bit float VAE if the generated picture has NaNs without the need for `--no-half-vae` commandline flag.
### Extensions and API:
* api endpoints: /sdapi/v1/server-kill, /sdapi/v1/server-restart, /sdapi/v1/server-stop
* allow Script to have custom metaclass
* add model exists status check /sdapi/v1/options
* rename --add-stop-route to --api-server-stop
* add `before_hr` script callback
* add callback `after_extra_networks_activate`
* disable rich exception output in console for API by default, use WEBUI_RICH_EXCEPTIONS env var to enable
* return http 404 when thumb file not found
* allow replacing extensions index with environment variable
### Bug Fixes:
* fix for catch errors when retrieving extension index #11290
* fix very slow loading speed of .safetensors files when reading from network drives
* API cache cleanup
* fix UnicodeEncodeError when writing to file CLIP Interrogator batch mode
* fix warning of 'has_mps' deprecated from PyTorch
* fix problem with extra network saving images as previews losing generation info
* fix throwing exception when trying to resize image with I;16 mode
* fix for #11534: canvas zoom and pan extension hijacking shortcut keys
* fixed launch script to be runnable from any directory
* don't add "Seed Resize: -1x-1" to API image metadata
* correctly remove end parenthesis with ctrl+up/down
* fixing --subpath on newer gradio version
* fix: check fill size none zero when resize (fixes #11425)
* use submit and blur for quick settings textbox
* save img2img batch with images.save_image()
* prevent running preload.py for disabled extensions
* fix: previously, model name was added together with directory name to infotext and to [model_name] filename pattern; directory name is now not included
## 1.4.1
### Bug Fixes:
* add queue lock for refresh-checkpoints
## 1.4.0 ## 1.4.0
### Features: ### Features:
@@ -154,7 +982,7 @@
* do not wait for Stable Diffusion model to load at startup * do not wait for Stable Diffusion model to load at startup
* add filename patterns: `[denoising]` * add filename patterns: `[denoising]`
* directory hiding for extra networks: dirs starting with `.` will hide their cards on extra network tabs unless specifically searched for * 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: 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: 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) * LoRA: add an option to use old method of applying LoRAs (producing same results as with kohya-ss)
@@ -184,7 +1012,7 @@
* fix gamepad navigation * fix gamepad navigation
* make the lightbox fullscreen image function properly * make the lightbox fullscreen image function properly
* fix squished thumbnails in extras tab * 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 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 bug with upscalers not working properly
* fix MPS on PyTorch 2.0.1, Intel Macs * fix MPS on PyTorch 2.0.1, Intel Macs
@@ -202,7 +1030,7 @@
* switch to PyTorch 2.0.0 (except for AMD GPUs) * switch to PyTorch 2.0.0 (except for AMD GPUs)
* visual improvements to custom code scripts * visual improvements to custom code scripts
* add filename patterns: `[clip_skip]`, `[hasprompt<>]`, `[batch_number]`, `[generation_number]` * 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 * automatically select current word when adjusting weight with ctrl+up/down
* add dropdowns for X/Y/Z plot * 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 * 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
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"
+50 -14
View File
@@ -1,5 +1,5 @@
# Stable Diffusion web UI # 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) ![](screenshot.png)
@@ -78,7 +78,7 @@ A browser interface based on Gradio library for Stable Diffusion.
- Clip skip - Clip skip
- Hypernetworks - Hypernetworks
- Loras (same as Hypernetworks but more pretty) - 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 - Can select to load a different VAE from settings screen
- Estimated completion time in progress bar - Estimated completion time in progress bar
- API - 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 - [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! - Now without any bad letters!
- Load checkpoints in safetensors format - 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! - Now with a license!
- Reorder elements in the UI from settings screen - Reorder elements in the UI from settings screen
- [Segmind Stable Diffusion](https://huggingface.co/segmind/SSD-1B) support
## Installation and Running ## 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): Alternatively, use online services (like Google Colab):
- [List of Online Services](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Online-Services) - [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 ### 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`. 2. Run `update.bat`.
3. Run `run.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) > 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: 1. Install the dependencies:
```bash ```bash
# Debian-based: # 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: # 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: # Arch-based:
sudo pacman -S wget git python3 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: 2. Navigate to the directory you would like the webui to be installed and execute the following command:
```bash ```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`. 3. Run `webui.sh`.
4. Check `webui-user.sh` for options. 4. Check `webui-user.sh` for options.
### Installation on Apple Silicon ### Installation on Apple Silicon
@@ -135,18 +164,22 @@ Find the instructions [here](https://github.com/AUTOMATIC1111/stable-diffusion-w
Here's how to add code to this repo: [Contributing](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Contributing) Here's how to add code to this repo: [Contributing](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Contributing)
## Documentation ## Documentation
The documentation was moved from this README over to the project's [wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki). The documentation was moved from this README over to the project's [wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki).
For the purposes of getting Google and other search engines to crawl the wiki, here's a link to the (not for humans) [crawlable wiki](https://github-wiki-see.page/m/AUTOMATIC1111/stable-diffusion-webui/wiki).
## Credits ## Credits
Licenses for borrowed code can be found in `Settings -> Licenses` screen, and also in `html/licenses.html` file. 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 - k-diffusion - https://github.com/crowsonkb/k-diffusion.git
- GFPGAN - https://github.com/TencentARC/GFPGAN.git - Spandrel - https://github.com/chaiNNer-org/spandrel implementing
- CodeFormer - https://github.com/sczhou/CodeFormer - GFPGAN - https://github.com/TencentARC/GFPGAN.git
- ESRGAN - https://github.com/xinntao/ESRGAN - CodeFormer - https://github.com/sczhou/CodeFormer
- SwinIR - https://github.com/JingyunLiang/SwinIR - ESRGAN - https://github.com/xinntao/ESRGAN
- Swin2SR - https://github.com/mv-lab/swin2sr - SwinIR - https://github.com/JingyunLiang/SwinIR
- Swin2SR - https://github.com/mv-lab/swin2sr
- LDSR - https://github.com/Hafiidz/latent-diffusion - LDSR - https://github.com/Hafiidz/latent-diffusion
- MiDaS - https://github.com/isl-org/MiDaS - MiDaS - https://github.com/isl-org/MiDaS
- Ideas for optimizations - https://github.com/basujindal/stable-diffusion - Ideas for optimizations - https://github.com/basujindal/stable-diffusion
@@ -165,5 +198,8 @@ Licenses for borrowed code can be found in `Settings -> Licenses` screen, and al
- Security advice - RyotaK - Security advice - RyotaK
- UniPC sampler - Wenliang Zhao - https://github.com/wl-zhao/UniPC - UniPC sampler - Wenliang Zhao - https://github.com/wl-zhao/UniPC
- TAESD - Ollin Boer Bohan - https://github.com/madebyollin/taesd - 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. - Initial Gradio script - posted on 4chan by an Anonymous user. Thank you Anonymous user.
- (You) - (You)
+5
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"
+1 -1
View File
@@ -40,7 +40,7 @@ model:
use_spatial_transformer: True use_spatial_transformer: True
transformer_depth: 1 transformer_depth: 1
context_dim: 768 context_dim: 768
use_checkpoint: True use_checkpoint: False
legacy: False legacy: False
first_stage_config: first_stage_config:
+73
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"
+1 -1
View File
@@ -45,7 +45,7 @@ model:
use_spatial_transformer: True use_spatial_transformer: True
transformer_depth: 1 transformer_depth: 1
context_dim: 768 context_dim: 768
use_checkpoint: True use_checkpoint: False
legacy: False legacy: False
first_stage_config: first_stage_config:
+5
View File
@@ -0,0 +1,5 @@
model:
target: modules.models.sd3.sd3_model.SD3Inferencer
params:
shift: 3
state_dict: null
+98
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
+1 -1
View File
@@ -40,7 +40,7 @@ model:
use_spatial_transformer: True use_spatial_transformer: True
transformer_depth: 1 transformer_depth: 1
context_dim: 768 context_dim: 768
use_checkpoint: True use_checkpoint: False
legacy: False legacy: False
first_stage_config: first_stage_config:
+1 -1
View File
@@ -40,7 +40,7 @@ model:
use_spatial_transformer: True use_spatial_transformer: True
transformer_depth: 1 transformer_depth: 1
context_dim: 768 context_dim: 768
use_checkpoint: True use_checkpoint: False
legacy: False legacy: False
first_stage_config: first_stage_config:
+3 -5
View File
@@ -12,7 +12,7 @@ import safetensors.torch
from ldm.models.diffusion.ddim import DDIMSampler from ldm.models.diffusion.ddim import DDIMSampler
from ldm.util import instantiate_from_config, ismap from ldm.util import instantiate_from_config, ismap
from modules import shared, sd_hijack from modules import shared, sd_hijack, devices
cached_ldsr_model: torch.nn.Module = None cached_ldsr_model: torch.nn.Module = None
@@ -112,8 +112,7 @@ class LDSR:
gc.collect() gc.collect()
if torch.cuda.is_available: devices.torch_gc()
torch.cuda.empty_cache()
im_og = image im_og = image
width_og, height_og = im_og.size width_og, height_og = im_og.size
@@ -150,8 +149,7 @@ class LDSR:
del model del model
gc.collect() gc.collect()
if torch.cuda.is_available: devices.torch_gc()
torch.cuda.empty_cache()
return a return a
+8 -12
View File
@@ -1,7 +1,6 @@
import os import os
from basicsr.utils.download_util import load_file_from_url from modules.modelloader import load_file_from_url
from modules.upscaler import Upscaler, UpscalerData from modules.upscaler import Upscaler, UpscalerData
from ldsr_model_arch import LDSR from ldsr_model_arch import LDSR
from modules import shared, script_callbacks, errors from modules import shared, script_callbacks, errors
@@ -43,20 +42,17 @@ class UpscalerLDSR(Upscaler):
if local_safetensors_path is not None and os.path.exists(local_safetensors_path): if local_safetensors_path is not None and os.path.exists(local_safetensors_path):
model = local_safetensors_path model = local_safetensors_path
else: else:
model = local_ckpt_path if local_ckpt_path is not None else load_file_from_url(url=self.model_url, model_dir=self.model_download_path, file_name="model.ckpt", progress=True) model = local_ckpt_path or load_file_from_url(self.model_url, model_dir=self.model_download_path, file_name="model.ckpt")
yaml = local_yaml_path if local_yaml_path is not None else load_file_from_url(url=self.yaml_url, model_dir=self.model_download_path, file_name="project.yaml", progress=True) yaml = local_yaml_path or load_file_from_url(self.yaml_url, model_dir=self.model_download_path, file_name="project.yaml")
try: return LDSR(model, yaml)
return LDSR(model, yaml)
except Exception:
errors.report("Error importing LDSR", exc_info=True)
return None
def do_upscale(self, img, path): def do_upscale(self, img, path):
ldsr = self.load_model(path) try:
if ldsr is None: ldsr = self.load_model(path)
print("NO LDSR!") except Exception:
errors.report(f"Failed loading LDSR model {path}", exc_info=True)
return img return img
ddim_steps = shared.opts.ldsr_steps ddim_steps = shared.opts.ldsr_steps
return ldsr.super_resolution(img, ddim_steps, self.scale) return ldsr.super_resolution(img, ddim_steps, self.scale)
+5 -5
View File
@@ -301,7 +301,7 @@ class DDPMV1(pl.LightningModule):
elif self.parameterization == "x0": elif self.parameterization == "x0":
target = x_start target = x_start
else: 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]) 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 h: height
:param w: width :param w: width
:return: normalized distance to image border, :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) lower_right_corner = torch.tensor([h - 1, w - 1]).view(1, 1, 2)
arr = self.meshgrid(h, w) / lower_right_corner 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): def apply_model(self, x_noisy, t, cond, return_ids=False):
if isinstance(cond, dict): if isinstance(cond, dict):
# hybrid case, cond is exptected to be a dict # hybrid case, cond is expected to be a dict
pass pass
else: else:
if not isinstance(cond, list): 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])] cond_list = [{c_key: [c[:, :, :, :, i]]} for i in range(c.shape[-1])]
elif self.cond_stage_key == 'coordinates_bbox': 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 # assuming padding of unfold is always 0 and its dilation is always 1
n_patches_per_row = int((w - ks[0]) / stride[0] + 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 num_downs = self.first_stage_model.encoder.num_resolutions - 1
rescale_latent = 2 ** (num_downs) 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) # 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, 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) rescale_latent * stride[1] * (patch_nr // n_patches_per_row) / full_img_h)
+38 -21
View File
@@ -1,45 +1,62 @@
from modules import extra_networks, shared from modules import extra_networks, shared
import lora import networks
class ExtraNetworkLora(extra_networks.ExtraNetwork): class ExtraNetworkLora(extra_networks.ExtraNetwork):
def __init__(self): def __init__(self):
super().__init__('lora') 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): def activate(self, p, params_list):
additional = shared.opts.sd_lora additional = shared.opts.sd_lora
if additional != "None" and additional in lora.available_loras and not any(x for x in params_list if x.items[0] == additional): 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] 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])) params_list.append(extra_networks.ExtraNetworkParams(items=[additional, shared.opts.extra_networks_default_multiplier]))
names = [] names = []
multipliers = [] te_multipliers = []
unet_multipliers = []
dyn_dims = []
for params in params_list: for params in params_list:
assert params.items assert params.items
names.append(params.items[0]) names.append(params.positional[0])
multipliers.append(float(params.items[1]) if len(params.items) > 1 else 1.0)
lora.load_loras(names, multipliers) te_multiplier = float(params.positional[1]) if len(params.positional) > 1 else 1.0
te_multiplier = float(params.named.get("te", te_multiplier))
unet_multiplier = float(params.positional[2]) if len(params.positional) > 2 else te_multiplier
unet_multiplier = float(params.named.get("unet", unet_multiplier))
dyn_dim = int(params.positional[3]) if len(params.positional) > 3 else None
dyn_dim = int(params.named["dyn"]) if "dyn" in params.named else dyn_dim
te_multipliers.append(te_multiplier)
unet_multipliers.append(unet_multiplier)
dyn_dims.append(dyn_dim)
networks.load_networks(names, te_multipliers, unet_multipliers, dyn_dims)
if shared.opts.lora_add_hashes_to_infotext: if shared.opts.lora_add_hashes_to_infotext:
lora_hashes = [] if not getattr(p, "is_hr_pass", False) or not hasattr(p, "lora_hashes"):
for item in lora.loaded_loras: p.lora_hashes = {}
shorthash = item.lora_on_disk.shorthash
if not shorthash:
continue
alias = item.mentioned_name for item in networks.loaded_networks:
if not alias: if item.network_on_disk.shorthash and item.mentioned_name:
continue p.lora_hashes[item.mentioned_name.translate(self.remove_symbols)] = item.network_on_disk.shorthash
alias = alias.replace(":", "").replace(",", "") if p.lora_hashes:
p.extra_generation_params["Lora hashes"] = ', '.join(f'{k}: {v}' for k, v in p.lora_hashes.items())
lora_hashes.append(f"{alias}: {shorthash}")
if lora_hashes:
p.extra_generation_params["Lora hashes"] = ", ".join(lora_hashes)
def deactivate(self, p): 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()
+7 -504
View File
@@ -1,506 +1,9 @@
import os import networks
import re
import torch
from typing import Union
from modules import shared, devices, sd_models, errors, scripts, sd_hijack, hashes list_available_loras = networks.list_available_networks
metadata_tags_order = {"ss_sd_model_name": 1, "ss_resolution": 2, "ss_clip_skip": 3, "ss_num_train_images": 10, "ss_tag_frequency": 20} available_loras = networks.available_networks
available_lora_aliases = networks.available_network_aliases
re_digits = re.compile(r"\d+") available_lora_hash_lookup = networks.available_network_hash_lookup
re_x_proj = re.compile(r"(.*)_([qkv]_proj)$") forbidden_lora_aliases = networks.forbidden_network_aliases
re_compiled = {} loaded_loras = networks.loaded_networks
suffix_conversion = {
"attentions": {},
"resnets": {
"conv1": "in_layers_2",
"conv2": "out_layers_3",
"time_emb_proj": "emb_layers_1",
"conv_shortcut": "skip_connection",
}
}
def convert_diffusers_name_to_compvis(key, is_sd2):
def match(match_list, regex_text):
regex = re_compiled.get(regex_text)
if regex is None:
regex = re.compile(regex_text)
re_compiled[regex_text] = regex
r = re.match(regex, key)
if not r:
return False
match_list.clear()
match_list.extend([int(x) if re.match(re_digits, x) else x for x in r.groups()])
return True
m = []
if match(m, r"lora_unet_down_blocks_(\d+)_(attentions|resnets)_(\d+)_(.+)"):
suffix = suffix_conversion.get(m[1], {}).get(m[3], m[3])
return f"diffusion_model_input_blocks_{1 + m[0] * 3 + m[2]}_{1 if m[1] == 'attentions' else 0}_{suffix}"
if match(m, r"lora_unet_mid_block_(attentions|resnets)_(\d+)_(.+)"):
suffix = suffix_conversion.get(m[0], {}).get(m[2], m[2])
return f"diffusion_model_middle_block_{1 if m[0] == 'attentions' else m[1] * 2}_{suffix}"
if match(m, r"lora_unet_up_blocks_(\d+)_(attentions|resnets)_(\d+)_(.+)"):
suffix = suffix_conversion.get(m[1], {}).get(m[3], m[3])
return f"diffusion_model_output_blocks_{m[0] * 3 + m[2]}_{1 if m[1] == 'attentions' else 0}_{suffix}"
if match(m, r"lora_unet_down_blocks_(\d+)_downsamplers_0_conv"):
return f"diffusion_model_input_blocks_{3 + m[0] * 3}_0_op"
if match(m, r"lora_unet_up_blocks_(\d+)_upsamplers_0_conv"):
return f"diffusion_model_output_blocks_{2 + m[0] * 3}_{2 if m[0]>0 else 1}_conv"
if match(m, r"lora_te_text_model_encoder_layers_(\d+)_(.+)"):
if is_sd2:
if 'mlp_fc1' in m[1]:
return f"model_transformer_resblocks_{m[0]}_{m[1].replace('mlp_fc1', 'mlp_c_fc')}"
elif 'mlp_fc2' in m[1]:
return f"model_transformer_resblocks_{m[0]}_{m[1].replace('mlp_fc2', 'mlp_c_proj')}"
else:
return f"model_transformer_resblocks_{m[0]}_{m[1].replace('self_attn', 'attn')}"
return f"transformer_text_model_encoder_layers_{m[0]}_{m[1]}"
return key
class LoraOnDisk:
def __init__(self, name, filename):
self.name = name
self.filename = filename
self.metadata = {}
self.is_safetensors = os.path.splitext(filename)[1].lower() == ".safetensors"
if self.is_safetensors:
try:
self.metadata = sd_models.read_metadata_from_safetensors(filename)
except Exception as e:
errors.display(e, f"reading lora {filename}")
if self.metadata:
m = {}
for k, v in sorted(self.metadata.items(), key=lambda x: metadata_tags_order.get(x[0], 999)):
m[k] = v
self.metadata = m
self.ssmd_cover_images = self.metadata.pop('ssmd_cover_images', None) # those are cover images and they are too big to display in UI as text
self.alias = self.metadata.get('ss_output_name', self.name)
self.hash = None
self.shorthash = None
self.set_hash(
self.metadata.get('sshs_model_hash') or
hashes.sha256_from_cache(self.filename, "lora/" + self.name, use_addnet_hash=self.is_safetensors) or
''
)
def set_hash(self, v):
self.hash = v
self.shorthash = self.hash[0:12]
if self.shorthash:
available_lora_hash_lookup[self.shorthash] = self
def read_hash(self):
if not self.hash:
self.set_hash(hashes.sha256(self.filename, "lora/" + self.name, use_addnet_hash=self.is_safetensors) or '')
def get_alias(self):
if shared.opts.lora_preferred_name == "Filename" or self.alias.lower() in forbidden_lora_aliases:
return self.name
else:
return self.alias
class LoraModule:
def __init__(self, name, lora_on_disk: LoraOnDisk):
self.name = name
self.lora_on_disk = lora_on_disk
self.multiplier = 1.0
self.modules = {}
self.mtime = None
self.mentioned_name = None
"""the text that was used to add lora to prompt - can be either name or an alias"""
class LoraUpDownModule:
def __init__(self):
self.up = None
self.down = None
self.alpha = None
def assign_lora_names_to_compvis_modules(sd_model):
lora_layer_mapping = {}
for name, module in shared.sd_model.cond_stage_model.wrapped.named_modules():
lora_name = name.replace(".", "_")
lora_layer_mapping[lora_name] = module
module.lora_layer_name = lora_name
for name, module in shared.sd_model.model.named_modules():
lora_name = name.replace(".", "_")
lora_layer_mapping[lora_name] = module
module.lora_layer_name = lora_name
sd_model.lora_layer_mapping = lora_layer_mapping
def load_lora(name, lora_on_disk):
lora = LoraModule(name, lora_on_disk)
lora.mtime = os.path.getmtime(lora_on_disk.filename)
sd = sd_models.read_state_dict(lora_on_disk.filename)
# this should not be needed but is here as an emergency fix for an unknown error people are experiencing in 1.2.0
if not hasattr(shared.sd_model, 'lora_layer_mapping'):
assign_lora_names_to_compvis_modules(shared.sd_model)
keys_failed_to_match = {}
is_sd2 = 'model_transformer_resblocks' in shared.sd_model.lora_layer_mapping
for key_diffusers, weight in sd.items():
key_diffusers_without_lora_parts, lora_key = key_diffusers.split(".", 1)
key = convert_diffusers_name_to_compvis(key_diffusers_without_lora_parts, is_sd2)
sd_module = shared.sd_model.lora_layer_mapping.get(key, None)
if sd_module is None:
m = re_x_proj.match(key)
if m:
sd_module = shared.sd_model.lora_layer_mapping.get(m.group(1), None)
if sd_module is None:
keys_failed_to_match[key_diffusers] = key
continue
lora_module = lora.modules.get(key, None)
if lora_module is None:
lora_module = LoraUpDownModule()
lora.modules[key] = lora_module
if lora_key == "alpha":
lora_module.alpha = weight.item()
continue
if type(sd_module) == torch.nn.Linear:
module = torch.nn.Linear(weight.shape[1], weight.shape[0], bias=False)
elif type(sd_module) == torch.nn.modules.linear.NonDynamicallyQuantizableLinear:
module = torch.nn.Linear(weight.shape[1], weight.shape[0], bias=False)
elif type(sd_module) == torch.nn.MultiheadAttention:
module = torch.nn.Linear(weight.shape[1], weight.shape[0], bias=False)
elif type(sd_module) == torch.nn.Conv2d and weight.shape[2:] == (1, 1):
module = torch.nn.Conv2d(weight.shape[1], weight.shape[0], (1, 1), bias=False)
elif type(sd_module) == torch.nn.Conv2d and weight.shape[2:] == (3, 3):
module = torch.nn.Conv2d(weight.shape[1], weight.shape[0], (3, 3), bias=False)
else:
print(f'Lora layer {key_diffusers} matched a layer with unsupported type: {type(sd_module).__name__}')
continue
raise AssertionError(f"Lora layer {key_diffusers} matched a layer with unsupported type: {type(sd_module).__name__}")
with torch.no_grad():
module.weight.copy_(weight)
module.to(device=devices.cpu, dtype=devices.dtype)
if lora_key == "lora_up.weight":
lora_module.up = module
elif lora_key == "lora_down.weight":
lora_module.down = module
else:
raise AssertionError(f"Bad Lora layer name: {key_diffusers} - must end in lora_up.weight, lora_down.weight or alpha")
if keys_failed_to_match:
print(f"Failed to match keys when loading Lora {lora_on_disk.filename}: {keys_failed_to_match}")
return lora
def load_loras(names, multipliers=None):
already_loaded = {}
for lora in loaded_loras:
if lora.name in names:
already_loaded[lora.name] = lora
loaded_loras.clear()
loras_on_disk = [available_lora_aliases.get(name, None) for name in names]
if any(x is None for x in loras_on_disk):
list_available_loras()
loras_on_disk = [available_lora_aliases.get(name, None) for name in names]
failed_to_load_loras = []
for i, name in enumerate(names):
lora = already_loaded.get(name, None)
lora_on_disk = loras_on_disk[i]
if lora_on_disk is not None:
if lora is None or os.path.getmtime(lora_on_disk.filename) > lora.mtime:
try:
lora = load_lora(name, lora_on_disk)
except Exception as e:
errors.display(e, f"loading Lora {lora_on_disk.filename}")
continue
lora.mentioned_name = name
lora_on_disk.read_hash()
if lora is None:
failed_to_load_loras.append(name)
print(f"Couldn't find Lora with name {name}")
continue
lora.multiplier = multipliers[i] if multipliers else 1.0
loaded_loras.append(lora)
if failed_to_load_loras:
sd_hijack.model_hijack.comments.append("Failed to find Loras: " + ", ".join(failed_to_load_loras))
def lora_calc_updown(lora, module, target):
with torch.no_grad():
up = module.up.weight.to(target.device, dtype=target.dtype)
down = module.down.weight.to(target.device, dtype=target.dtype)
if up.shape[2:] == (1, 1) and down.shape[2:] == (1, 1):
updown = (up.squeeze(2).squeeze(2) @ down.squeeze(2).squeeze(2)).unsqueeze(2).unsqueeze(3)
elif up.shape[2:] == (3, 3) or down.shape[2:] == (3, 3):
updown = torch.nn.functional.conv2d(down.permute(1, 0, 2, 3), up).permute(1, 0, 2, 3)
else:
updown = up @ down
updown = updown * lora.multiplier * (module.alpha / module.up.weight.shape[1] if module.alpha else 1.0)
return updown
def lora_restore_weights_from_backup(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.MultiheadAttention]):
weights_backup = getattr(self, "lora_weights_backup", None)
if weights_backup is None:
return
if isinstance(self, torch.nn.MultiheadAttention):
self.in_proj_weight.copy_(weights_backup[0])
self.out_proj.weight.copy_(weights_backup[1])
else:
self.weight.copy_(weights_backup)
def lora_apply_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.MultiheadAttention]):
"""
Applies the currently selected set of Loras to the weights of torch layer self.
If weights already have this particular set of loras applied, does nothing.
If not, restores orginal weights from backup and alters weights according to loras.
"""
lora_layer_name = getattr(self, 'lora_layer_name', None)
if lora_layer_name is None:
return
current_names = getattr(self, "lora_current_names", ())
wanted_names = tuple((x.name, x.multiplier) for x in loaded_loras)
weights_backup = getattr(self, "lora_weights_backup", None)
if weights_backup is None:
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))
else:
weights_backup = self.weight.to(devices.cpu, copy=True)
self.lora_weights_backup = weights_backup
if current_names != wanted_names:
lora_restore_weights_from_backup(self)
for lora in loaded_loras:
module = lora.modules.get(lora_layer_name, None)
if module is not None and hasattr(self, 'weight'):
self.weight += lora_calc_updown(lora, module, self.weight)
continue
module_q = lora.modules.get(lora_layer_name + "_q_proj", None)
module_k = lora.modules.get(lora_layer_name + "_k_proj", None)
module_v = lora.modules.get(lora_layer_name + "_v_proj", None)
module_out = lora.modules.get(lora_layer_name + "_out_proj", None)
if isinstance(self, torch.nn.MultiheadAttention) and module_q and module_k and module_v and module_out:
updown_q = lora_calc_updown(lora, module_q, self.in_proj_weight)
updown_k = lora_calc_updown(lora, module_k, self.in_proj_weight)
updown_v = lora_calc_updown(lora, module_v, self.in_proj_weight)
updown_qkv = torch.vstack([updown_q, updown_k, updown_v])
self.in_proj_weight += updown_qkv
self.out_proj.weight += lora_calc_updown(lora, module_out, self.out_proj.weight)
continue
if module is None:
continue
print(f'failed to calculate lora weights for layer {lora_layer_name}')
self.lora_current_names = wanted_names
def lora_forward(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_loras) == 0:
return original_forward(module, input)
input = devices.cond_cast_unet(input)
lora_restore_weights_from_backup(module)
lora_reset_cached_weight(module)
res = original_forward(module, input)
lora_layer_name = getattr(module, 'lora_layer_name', None)
for lora in loaded_loras:
module = lora.modules.get(lora_layer_name, None)
if module is None:
continue
module.up.to(device=devices.device)
module.down.to(device=devices.device)
res = res + module.up(module.down(input)) * lora.multiplier * (module.alpha / module.up.weight.shape[1] if module.alpha else 1.0)
return res
def lora_reset_cached_weight(self: Union[torch.nn.Conv2d, torch.nn.Linear]):
self.lora_current_names = ()
self.lora_weights_backup = None
def lora_Linear_forward(self, input):
if shared.opts.lora_functional:
return lora_forward(self, input, torch.nn.Linear_forward_before_lora)
lora_apply_weights(self)
return torch.nn.Linear_forward_before_lora(self, input)
def lora_Linear_load_state_dict(self, *args, **kwargs):
lora_reset_cached_weight(self)
return torch.nn.Linear_load_state_dict_before_lora(self, *args, **kwargs)
def lora_Conv2d_forward(self, input):
if shared.opts.lora_functional:
return lora_forward(self, input, torch.nn.Conv2d_forward_before_lora)
lora_apply_weights(self)
return torch.nn.Conv2d_forward_before_lora(self, input)
def lora_Conv2d_load_state_dict(self, *args, **kwargs):
lora_reset_cached_weight(self)
return torch.nn.Conv2d_load_state_dict_before_lora(self, *args, **kwargs)
def lora_MultiheadAttention_forward(self, *args, **kwargs):
lora_apply_weights(self)
return torch.nn.MultiheadAttention_forward_before_lora(self, *args, **kwargs)
def lora_MultiheadAttention_load_state_dict(self, *args, **kwargs):
lora_reset_cached_weight(self)
return torch.nn.MultiheadAttention_load_state_dict_before_lora(self, *args, **kwargs)
def list_available_loras():
available_loras.clear()
available_lora_aliases.clear()
forbidden_lora_aliases.clear()
available_lora_hash_lookup.clear()
forbidden_lora_aliases.update({"none": 1, "Addams": 1})
os.makedirs(shared.cmd_opts.lora_dir, exist_ok=True)
candidates = list(shared.walk_files(shared.cmd_opts.lora_dir, allowed_extensions=[".pt", ".ckpt", ".safetensors"]))
for filename in sorted(candidates, key=str.lower):
if os.path.isdir(filename):
continue
name = os.path.splitext(os.path.basename(filename))[0]
try:
entry = LoraOnDisk(name, filename)
except OSError: # should catch FileNotFoundError and PermissionError etc.
errors.report(f"Failed to load LoRA {name} from {filename}", exc_info=True)
continue
available_loras[name] = entry
if entry.alias in available_lora_aliases:
forbidden_lora_aliases[entry.alias.lower()] = 1
available_lora_aliases[name] = entry
available_lora_aliases[entry.alias] = entry
re_lora_name = re.compile(r"(.*)\s*\([0-9a-fA-F]+\)")
def infotext_pasted(infotext, params):
if "AddNet Module 1" in [x[1] for x in scripts.scripts_txt2img.infotext_fields]:
return # if the other extension is active, it will handle those fields, no need to do anything
added = []
for k in params:
if not k.startswith("AddNet Model "):
continue
num = k[13:]
if params.get("AddNet Module " + num) != "LoRA":
continue
name = params.get("AddNet Model " + num)
if name is None:
continue
m = re_lora_name.match(name)
if m:
name = m.group(1)
multiplier = params.get("AddNet Weight A " + num, "1.0")
added.append(f"<lora:{name}:{multiplier}>")
if added:
params["Prompt"] += "\n" + "".join(added)
available_loras = {}
available_lora_aliases = {}
available_lora_hash_lookup = {}
forbidden_lora_aliases = {}
loaded_loras = []
list_available_loras()
+33
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)
+31
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')
+68
View File
@@ -0,0 +1,68 @@
import torch
def make_weight_cp(t, wa, wb):
temp = torch.einsum('i j k l, j r -> i r k l', t, wb)
return torch.einsum('i j k l, i r -> r j k l', temp, wa)
def rebuild_conventional(up, down, shape, dyn_dim=None):
up = up.reshape(up.size(0), -1)
down = down.reshape(down.size(0), -1)
if dyn_dim is not None:
up = up[:, :dyn_dim]
down = down[:dyn_dim, :]
return (up @ down).reshape(shape)
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, A⊗B ≠ B⊗A. 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
+228
View File
@@ -0,0 +1,228 @@
from __future__ import annotations
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'])
metadata_tags_order = {"ss_sd_model_name": 1, "ss_resolution": 2, "ss_clip_skip": 3, "ss_num_train_images": 10, "ss_tag_frequency": 20}
class SdVersion(enum.Enum):
Unknown = 1
SD1 = 2
SD2 = 3
SDXL = 4
class NetworkOnDisk:
def __init__(self, name, filename):
self.name = name
self.filename = filename
self.metadata = {}
self.is_safetensors = os.path.splitext(filename)[1].lower() == ".safetensors"
def read_metadata():
metadata = sd_models.read_metadata_from_safetensors(filename)
return metadata
if self.is_safetensors:
try:
self.metadata = cache.cached_data_for_file('safetensors-metadata', "lora/" + self.name, filename, read_metadata)
except Exception as e:
errors.display(e, f"reading lora {filename}")
if self.metadata:
m = {}
for k, v in sorted(self.metadata.items(), key=lambda x: metadata_tags_order.get(x[0], 999)):
m[k] = v
self.metadata = m
self.alias = self.metadata.get('ss_output_name', self.name)
self.hash = None
self.shorthash = None
self.set_hash(
self.metadata.get('sshs_model_hash') or
hashes.sha256_from_cache(self.filename, "lora/" + self.name, use_addnet_hash=self.is_safetensors) or
''
)
self.sd_version = self.detect_version()
def detect_version(self):
if str(self.metadata.get('ss_base_model_version', "")).startswith("sdxl_"):
return SdVersion.SDXL
elif str(self.metadata.get('ss_v2', "")) == "True":
return SdVersion.SD2
elif len(self.metadata):
return SdVersion.SD1
return SdVersion.Unknown
def set_hash(self, v):
self.hash = v
self.shorthash = self.hash[0:12]
if self.shorthash:
import networks
networks.available_network_hash_lookup[self.shorthash] = self
def read_hash(self):
if not self.hash:
self.set_hash(hashes.sha256(self.filename, "lora/" + self.name, use_addnet_hash=self.is_safetensors) or '')
def get_alias(self):
import networks
if shared.opts.lora_preferred_name == "Filename" or self.alias.lower() in networks.forbidden_network_aliases:
return self.name
else:
return self.alias
class Network: # LoraModule
def __init__(self, name, network_on_disk: NetworkOnDisk):
self.name = name
self.network_on_disk = network_on_disk
self.te_multiplier = 1.0
self.unet_multiplier = 1.0
self.dyn_dim = None
self.modules = {}
self.bundle_embeddings = {}
self.mtime = None
self.mentioned_name = None
"""the text that was used to add the network to prompt - can be either name or an alias"""
class ModuleType:
def create_module(self, net: Network, weights: NetworkWeights) -> Network | None:
return None
class NetworkModule:
def __init__(self, net: Network, weights: NetworkWeights):
self.network = net
self.network_key = weights.network_key
self.sd_key = weights.sd_key
self.sd_module = weights.sd_module
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
else:
return self.network.unet_multiplier
def calc_scale(self):
if self.scale is not None:
return self.scale
if self.dim is not None and self.alpha is not None:
return self.alpha / self.dim
return 1.0
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=updown.dtype)
updown = updown.reshape(output_shape)
if len(output_shape) == 4:
updown = updown.reshape(output_shape)
if orig_weight.size().numel() == updown.size().numel():
updown = updown.reshape(orig_weight.shape)
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):
"""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)
+27
View File
@@ -0,0 +1,27 @@
import network
class ModuleTypeFull(network.ModuleType):
def create_module(self, net: network.Network, weights: network.NetworkWeights):
if all(x in weights.w for x in ["diff"]):
return NetworkModuleFull(net, weights)
return None
class NetworkModuleFull(network.NetworkModule):
def __init__(self, net: network.Network, weights: network.NetworkWeights):
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)
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, ex_bias)
+33
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)
+55
View File
@@ -0,0 +1,55 @@
import lyco_helpers
import network
class ModuleTypeHada(network.ModuleType):
def create_module(self, net: network.Network, weights: network.NetworkWeights):
if all(x in weights.w for x in ["hada_w1_a", "hada_w1_b", "hada_w2_a", "hada_w2_b"]):
return NetworkModuleHada(net, weights)
return None
class NetworkModuleHada(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["hada_w1_a"]
self.w1b = weights.w["hada_w1_b"]
self.dim = self.w1b.shape[0]
self.w2a = weights.w["hada_w2_a"]
self.w2b = weights.w["hada_w2_b"]
self.t1 = weights.w.get("hada_t1")
self.t2 = weights.w.get("hada_t2")
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)]
if self.t1 is not None:
output_shape = [w1a.size(1), w1b.size(1)]
t1 = self.t1.to(orig_weight.device)
updown1 = lyco_helpers.make_weight_cp(t1, w1a, w1b)
output_shape += t1.shape[2:]
else:
if len(w1b.shape) == 4:
output_shape += w1b.shape[2:]
updown1 = lyco_helpers.rebuild_conventional(w1a, w1b, output_shape)
if self.t2 is not None:
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)
updown = updown1 * updown2
return self.finalize_updown(updown, orig_weight, output_shape)
+30
View File
@@ -0,0 +1,30 @@
import network
class ModuleTypeIa3(network.ModuleType):
def create_module(self, net: network.Network, weights: network.NetworkWeights):
if all(x in weights.w for x in ["weight"]):
return NetworkModuleIa3(net, weights)
return None
class NetworkModuleIa3(network.NetworkModule):
def __init__(self, net: network.Network, weights: network.NetworkWeights):
super().__init__(net, weights)
self.w = weights.w["weight"]
self.on_input = weights.w["on_input"].item()
def calc_updown(self, orig_weight):
w = self.w.to(orig_weight.device)
output_shape = [w.size(0), orig_weight.size(1)]
if self.on_input:
output_shape.reverse()
else:
w = w.reshape(-1, 1)
updown = orig_weight * w
return self.finalize_updown(updown, orig_weight, output_shape)
+64
View File
@@ -0,0 +1,64 @@
import torch
import lyco_helpers
import network
class ModuleTypeLokr(network.ModuleType):
def create_module(self, net: network.Network, weights: network.NetworkWeights):
has_1 = "lokr_w1" in weights.w or ("lokr_w1_a" in weights.w and "lokr_w1_b" in weights.w)
has_2 = "lokr_w2" in weights.w or ("lokr_w2_a" in weights.w and "lokr_w2_b" in weights.w)
if has_1 and has_2:
return NetworkModuleLokr(net, weights)
return None
def make_kron(orig_shape, w1, w2):
if len(w2.shape) == 4:
w1 = w1.unsqueeze(2).unsqueeze(2)
w2 = w2.contiguous()
return torch.kron(w1, w2).reshape(orig_shape)
class NetworkModuleLokr(network.NetworkModule):
def __init__(self, net: network.Network, weights: network.NetworkWeights):
super().__init__(net, weights)
self.w1 = weights.w.get("lokr_w1")
self.w1a = weights.w.get("lokr_w1_a")
self.w1b = weights.w.get("lokr_w1_b")
self.dim = self.w1b.shape[0] if self.w1b is not None else self.dim
self.w2 = weights.w.get("lokr_w2")
self.w2a = weights.w.get("lokr_w2_a")
self.w2b = weights.w.get("lokr_w2_b")
self.dim = self.w2b.shape[0] if self.w2b is not None else self.dim
self.t2 = weights.w.get("lokr_t2")
def calc_updown(self, orig_weight):
if self.w1 is not None:
w1 = self.w1.to(orig_weight.device)
else:
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)
elif self.t2 is None:
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)
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)]
if len(orig_weight.shape) == 4:
output_shape = orig_weight.shape
updown = make_kron(output_shape, w1, w2)
return self.finalize_updown(updown, orig_weight, output_shape)
+94
View File
@@ -0,0 +1,94 @@
import torch
import lyco_helpers
import modules.models.sd3.mmdit
import network
from modules import devices
class ModuleTypeLora(network.ModuleType):
def create_module(self, net: network.Network, weights: network.NetworkWeights):
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
class NetworkModuleLora(network.NetworkModule):
def __init__(self, net: network.Network, weights: network.NetworkWeights):
super().__init__(net, weights)
self.up_model = self.create_module(weights.w, "lora_up.weight")
self.down_model = self.create_module(weights.w, "lora_down.weight")
self.mid_model = self.create_module(weights.w, "lora_mid.weight", none_ok=True)
self.dim = weights.w["lora_down.weight"].shape[0]
def create_module(self, weights, key, none_ok=False):
weight = weights.get(key)
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, modules.models.sd3.mmdit.QkvLinear]
is_conv = type(self.sd_module) in [torch.nn.Conv2d]
if is_linear:
weight = weight.reshape(weight.shape[0], -1)
module = torch.nn.Linear(weight.shape[1], weight.shape[0], bias=False)
elif is_conv and key == "lora_down.weight" or key == "dyn_up":
if len(weight.shape) == 2:
weight = weight.reshape(weight.shape[0], -1, 1, 1)
if weight.shape[2] != 1 or weight.shape[3] != 1:
module = torch.nn.Conv2d(weight.shape[1], weight.shape[0], self.sd_module.kernel_size, self.sd_module.stride, self.sd_module.padding, bias=False)
else:
module = torch.nn.Conv2d(weight.shape[1], weight.shape[0], (1, 1), bias=False)
elif is_conv and key == "lora_mid.weight":
module = torch.nn.Conv2d(weight.shape[1], weight.shape[0], self.sd_module.kernel_size, self.sd_module.stride, self.sd_module.padding, bias=False)
elif is_conv and key == "lora_up.weight" or key == "dyn_down":
module = torch.nn.Conv2d(weight.shape[1], weight.shape[0], (1, 1), bias=False)
else:
raise AssertionError(f'Lora layer {self.network_key} matched a layer with unsupported type: {type(self.sd_module).__name__}')
with torch.no_grad():
if weight.shape != module.weight.shape:
weight = weight.reshape(module.weight.shape)
module.weight.copy_(weight)
module.to(device=devices.cpu, dtype=devices.dtype)
module.weight.requires_grad_(False)
return module
def calc_updown(self, orig_weight):
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)
updown = lyco_helpers.rebuild_cp_decomposition(up, down, mid)
output_shape += mid.shape[2:]
else:
if len(down.shape) == 4:
output_shape += down.shape[2:]
updown = lyco_helpers.rebuild_conventional(up, down, output_shape, self.network.dyn_dim)
return self.finalize_updown(updown, orig_weight, output_shape)
def forward(self, x, y):
self.up_model.to(device=devices.device)
self.down_model.to(device=devices.device)
return y + self.up_model(self.down_model(x)) * self.multiplier() * self.calc_scale()
+28
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)
+118
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)
+737
View File
@@ -0,0 +1,737 @@
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(),
network_hada.ModuleTypeHada(),
network_ia3.ModuleTypeIa3(),
network_lokr.ModuleTypeLokr(),
network_full.ModuleTypeFull(),
network_norm.ModuleTypeNorm(),
network_glora.ModuleTypeGLora(),
network_oft.ModuleTypeOFT(),
]
re_digits = re.compile(r"\d+")
re_x_proj = re.compile(r"(.*)_([qkv]_proj)$")
re_compiled = {}
suffix_conversion = {
"attentions": {},
"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",
}
}
def convert_diffusers_name_to_compvis(key, is_sd2):
def match(match_list, regex_text):
regex = re_compiled.get(regex_text)
if regex is None:
regex = re.compile(regex_text)
re_compiled[regex_text] = regex
r = re.match(regex, key)
if not r:
return False
match_list.clear()
match_list.extend([int(x) if re.match(re_digits, x) else x for x in r.groups()])
return True
m = []
if match(m, r"lora_unet_conv_in(.*)"):
return f'diffusion_model_input_blocks_0_0{m[0]}'
if match(m, r"lora_unet_conv_out(.*)"):
return f'diffusion_model_out_2{m[0]}'
if match(m, r"lora_unet_time_embedding_linear_(\d+)(.*)"):
return f"diffusion_model_time_embed_{m[0] * 2 - 2}{m[1]}"
if match(m, r"lora_unet_down_blocks_(\d+)_(attentions|resnets)_(\d+)_(.+)"):
suffix = suffix_conversion.get(m[1], {}).get(m[3], m[3])
return f"diffusion_model_input_blocks_{1 + m[0] * 3 + m[2]}_{1 if m[1] == 'attentions' else 0}_{suffix}"
if match(m, r"lora_unet_mid_block_(attentions|resnets)_(\d+)_(.+)"):
suffix = suffix_conversion.get(m[0], {}).get(m[2], m[2])
return f"diffusion_model_middle_block_{1 if m[0] == 'attentions' else m[1] * 2}_{suffix}"
if match(m, r"lora_unet_up_blocks_(\d+)_(attentions|resnets)_(\d+)_(.+)"):
suffix = suffix_conversion.get(m[1], {}).get(m[3], m[3])
return f"diffusion_model_output_blocks_{m[0] * 3 + m[2]}_{1 if m[1] == 'attentions' else 0}_{suffix}"
if match(m, r"lora_unet_down_blocks_(\d+)_downsamplers_0_conv"):
return f"diffusion_model_input_blocks_{3 + m[0] * 3}_0_op"
if match(m, r"lora_unet_up_blocks_(\d+)_upsamplers_0_conv"):
return f"diffusion_model_output_blocks_{2 + m[0] * 3}_{2 if m[0]>0 else 1}_conv"
if match(m, r"lora_te_text_model_encoder_layers_(\d+)_(.+)"):
if is_sd2:
if 'mlp_fc1' in m[1]:
return f"model_transformer_resblocks_{m[0]}_{m[1].replace('mlp_fc1', 'mlp_c_fc')}"
elif 'mlp_fc2' in m[1]:
return f"model_transformer_resblocks_{m[0]}_{m[1].replace('mlp_fc2', 'mlp_c_proj')}"
else:
return f"model_transformer_resblocks_{m[0]}_{m[1].replace('self_attn', 'attn')}"
return f"transformer_text_model_encoder_layers_{m[0]}_{m[1]}"
if match(m, r"lora_te2_text_model_encoder_layers_(\d+)_(.+)"):
if 'mlp_fc1' in m[1]:
return f"1_model_transformer_resblocks_{m[0]}_{m[1].replace('mlp_fc1', 'mlp_c_fc')}"
elif 'mlp_fc2' in m[1]:
return f"1_model_transformer_resblocks_{m[0]}_{m[1].replace('mlp_fc2', 'mlp_c_proj')}"
else:
return f"1_model_transformer_resblocks_{m[0]}_{m[1].replace('self_attn', 'attn')}"
return key
def assign_network_names_to_compvis_modules(sd_model):
network_layer_mapping = {}
if shared.sd_model.is_sdxl:
for i, embedder in enumerate(shared.sd_model.conditioner.embedders):
if not hasattr(embedder, 'wrapped'):
continue
for name, module in embedder.wrapped.named_modules():
network_name = f'{i}_{name.replace(".", "_")}'
network_layer_mapping[network_name] = module
module.network_layer_name = network_name
else:
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
for name, module in shared.sd_model.model.named_modules():
network_name = name.replace(".", "_")
network_layer_mapping[network_name] = module
module.network_layer_name = network_name
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)
sd = sd_models.read_state_dict(network_on_disk.filename)
# this should not be needed but is here as an emergency fix for an unknown error people are experiencing in 1.2.0
if not hasattr(shared.sd_model, 'network_layer_mapping'):
assign_network_names_to_compvis_modules(shared.sd_model)
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():
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:
m = re_x_proj.match(key)
if m:
sd_module = shared.sd_model.network_layer_mapping.get(m.group(1), None)
# SDXL loras seem to already have correct compvis keys, so only need to replace "lora_unet" with "diffusion_model"
if sd_module is None and "lora_unet" in key_network_without_network_parts:
key = key_network_without_network_parts.replace("lora_unet", "diffusion_model")
sd_module = shared.sd_model.network_layer_mapping.get(key, None)
elif sd_module is None and "lora_te1_text_model" in key_network_without_network_parts:
key = key_network_without_network_parts.replace("lora_te1_text_model", "0_transformer_text_model")
sd_module = shared.sd_model.network_layer_mapping.get(key, None)
# some SD1 Loras also have correct compvis keys
if sd_module is None:
key = key_network_without_network_parts.replace("lora_te1_text_model", "transformer_text_model")
sd_module = shared.sd_model.network_layer_mapping.get(key, None)
# 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
if key not in matched_networks:
matched_networks[key] = network.NetworkWeights(network_key=key_network, sd_key=key, w={}, sd_module=sd_module)
matched_networks[key].w[network_part] = weight
for key, weights in matched_networks.items():
net_module = None
for nettype in module_types:
net_module = nettype.create_module(net, weights)
if net_module is not None:
break
if net_module is None:
raise AssertionError(f"Could not find a module type (out of {', '.join([x.__class__.__name__ for x in module_types])}) that would accept those keys: {', '.join(weights.w)}")
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:
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()
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_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, (network_on_disk, name) in enumerate(zip(networks_on_disk, names)):
net = already_loaded.get(name, None)
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
net.mentioned_name = name
network_on_disk.read_hash()
if net is None:
failed_to_load_networks.append(name)
logging.info(f"Couldn't find network with name {name}")
continue
net.te_multiplier = te_multipliers[i] if te_multipliers else 1.0
net.unet_multiplier = unet_multipliers[i] if unet_multipliers else 1.0
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:
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 allowed_layer_without_weight(layer):
if isinstance(layer, torch.nn.LayerNorm) and not layer.elementwise_affine:
return True
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):
restore_weights_backup(self.out_proj, 'bias', bias_backup)
else:
restore_weights_backup(self, 'bias', bias_backup)
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 original weights from backup and alters weights according to networks.
"""
network_layer_name = getattr(self, 'network_layer_name', None)
if network_layer_name is None:
return
current_names = getattr(self, "network_current_names", ())
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 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 = (store_weights_backup(self.in_proj_weight), store_weights_backup(self.out_proj.weight))
else:
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') 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(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.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)
module_v = net.modules.get(network_layer_name + "_v_proj", None)
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:
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
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
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(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(org_module, input)
input = devices.cond_cast_unet(input)
network_restore_weights_from_backup(org_module)
network_reset_cached_weight(org_module)
y = original_forward(org_module, input)
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(input, y)
return y
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, originals.Linear_forward)
network_apply_weights(self)
return originals.Linear_forward(self, input)
def network_Linear_load_state_dict(self, *args, **kwargs):
network_reset_cached_weight(self)
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, originals.Conv2d_forward)
network_apply_weights(self)
return originals.Conv2d_forward(self, input)
def network_Conv2d_load_state_dict(self, *args, **kwargs):
network_reset_cached_weight(self)
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 originals.MultiheadAttention_forward(self, *args, **kwargs)
def network_MultiheadAttention_load_state_dict(self, *args, **kwargs):
network_reset_cached_weight(self)
return originals.MultiheadAttention_load_state_dict(self, *args, **kwargs)
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.
errors.report(f"Failed to load network {name} from {filename}", exc_info=True)
continue
available_networks[name] = entry
if entry.alias in available_network_aliases:
forbidden_network_aliases[entry.alias.lower()] = 1
available_network_aliases[name] = entry
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]+\)")
def infotext_pasted(infotext, params):
if "AddNet Module 1" in [x[1] for x in scripts.scripts_txt2img.infotext_fields]:
return # if the other extension is active, it will handle those fields, no need to do anything
added = []
for k in params:
if not k.startswith("AddNet Model "):
continue
num = k[13:]
if params.get("AddNet Module " + num) != "LoRA":
continue
name = params.get("AddNet Model " + num)
if name is None:
continue
m = re_network_name.match(name)
if m:
name = m.group(1)
multiplier = params.get("AddNet Weight A " + num, "1.0")
added.append(f"<lora:{name}:{multiplier}>")
if added:
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 = {}
list_available_networks()
+3 -1
View File
@@ -1,6 +1,8 @@
import os import os
from modules import paths from modules import paths
from modules.paths_internal import normalized_filepath
def preload(parser): 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("--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'))
+33 -47
View File
@@ -1,72 +1,56 @@
import re import re
import torch
import gradio as gr import gradio as gr
from fastapi import FastAPI from fastapi import FastAPI
import lora import network
import networks
import lora # noqa:F401
import lora_patches
import extra_networks_lora import extra_networks_lora
import ui_extra_networks_lora import ui_extra_networks_lora
from modules import script_callbacks, ui_extra_networks, extra_networks, shared from modules import script_callbacks, ui_extra_networks, extra_networks, shared
def unload(): def unload():
torch.nn.Linear.forward = torch.nn.Linear_forward_before_lora networks.originals.undo()
torch.nn.Linear._load_from_state_dict = torch.nn.Linear_load_state_dict_before_lora
torch.nn.Conv2d.forward = torch.nn.Conv2d_forward_before_lora
torch.nn.Conv2d._load_from_state_dict = torch.nn.Conv2d_load_state_dict_before_lora
torch.nn.MultiheadAttention.forward = torch.nn.MultiheadAttention_forward_before_lora
torch.nn.MultiheadAttention._load_from_state_dict = torch.nn.MultiheadAttention_load_state_dict_before_lora
def before_ui(): def before_ui():
ui_extra_networks.register_page(ui_extra_networks_lora.ExtraNetworksPageLora()) ui_extra_networks.register_page(ui_extra_networks_lora.ExtraNetworksPageLora())
extra_networks.register_extra_network(extra_networks_lora.ExtraNetworkLora())
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_lora'): networks.originals = lora_patches.LoraPatches()
torch.nn.Linear_forward_before_lora = torch.nn.Linear.forward
if not hasattr(torch.nn, 'Linear_load_state_dict_before_lora'): script_callbacks.on_model_loaded(networks.assign_network_names_to_compvis_modules)
torch.nn.Linear_load_state_dict_before_lora = torch.nn.Linear._load_from_state_dict
if not hasattr(torch.nn, 'Conv2d_forward_before_lora'):
torch.nn.Conv2d_forward_before_lora = torch.nn.Conv2d.forward
if not hasattr(torch.nn, 'Conv2d_load_state_dict_before_lora'):
torch.nn.Conv2d_load_state_dict_before_lora = torch.nn.Conv2d._load_from_state_dict
if not hasattr(torch.nn, 'MultiheadAttention_forward_before_lora'):
torch.nn.MultiheadAttention_forward_before_lora = torch.nn.MultiheadAttention.forward
if not hasattr(torch.nn, 'MultiheadAttention_load_state_dict_before_lora'):
torch.nn.MultiheadAttention_load_state_dict_before_lora = torch.nn.MultiheadAttention._load_from_state_dict
torch.nn.Linear.forward = lora.lora_Linear_forward
torch.nn.Linear._load_from_state_dict = lora.lora_Linear_load_state_dict
torch.nn.Conv2d.forward = lora.lora_Conv2d_forward
torch.nn.Conv2d._load_from_state_dict = lora.lora_Conv2d_load_state_dict
torch.nn.MultiheadAttention.forward = lora.lora_MultiheadAttention_forward
torch.nn.MultiheadAttention._load_from_state_dict = lora.lora_MultiheadAttention_load_state_dict
script_callbacks.on_model_loaded(lora.assign_lora_names_to_compvis_modules)
script_callbacks.on_script_unloaded(unload) script_callbacks.on_script_unloaded(unload)
script_callbacks.on_before_ui(before_ui) script_callbacks.on_before_ui(before_ui)
script_callbacks.on_infotext_pasted(lora.infotext_pasted) script_callbacks.on_infotext_pasted(networks.infotext_pasted)
shared.options_templates.update(shared.options_section(('extra_networks', "Extra Networks"), { shared.options_templates.update(shared.options_section(('extra_networks', "Extra Networks"), {
"sd_lora": shared.OptionInfo("None", "Add Lora to prompt", gr.Dropdown, lambda: {"choices": ["None", *lora.available_loras]}, refresh=lora.list_available_loras), "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_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_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"),
})) }))
shared.options_templates.update(shared.options_section(('compatibility', "Compatibility"), { shared.options_templates.update(shared.options_section(('compatibility', "Compatibility"), {
"lora_functional": shared.OptionInfo(False, "Lora: use old method that takes longer when you have multiple Loras active and produces same results as kohya-ss/sd-webui-additional-networks extension"), "lora_functional": shared.OptionInfo(False, "Lora/Networks: use old method that takes longer when you have multiple Loras active and produces same results as kohya-ss/sd-webui-additional-networks extension"),
})) }))
def create_lora_json(obj: lora.LoraOnDisk): def create_lora_json(obj: network.NetworkOnDisk):
return { return {
"name": obj.name, "name": obj.name,
"alias": obj.alias, "alias": obj.alias,
@@ -75,17 +59,17 @@ def create_lora_json(obj: lora.LoraOnDisk):
} }
def api_loras(_: gr.Blocks, app: FastAPI): def api_networks(_: gr.Blocks, app: FastAPI):
@app.get("/sdapi/v1/loras") @app.get("/sdapi/v1/loras")
async def get_loras(): async def get_loras():
return [create_lora_json(obj) for obj in lora.available_loras.values()] return [create_lora_json(obj) for obj in networks.available_networks.values()]
@app.post("/sdapi/v1/refresh-loras") @app.post("/sdapi/v1/refresh-loras")
async def refresh_loras(): async def refresh_loras():
return lora.list_available_loras() return networks.list_available_networks()
script_callbacks.on_app_started(api_loras) script_callbacks.on_app_started(api_networks)
re_lora = re.compile("<lora:([^:]+):") re_lora = re.compile("<lora:([^:]+):")
@@ -98,19 +82,21 @@ def infotext_pasted(infotext, d):
hashes = [x.strip().split(':', 1) for x in hashes.split(",")] hashes = [x.strip().split(':', 1) for x in hashes.split(",")]
hashes = {x[0].strip().replace(",", ""): x[1].strip() for x in hashes} hashes = {x[0].strip().replace(",", ""): x[1].strip() for x in hashes}
def lora_replacement(m): def network_replacement(m):
alias = m.group(1) alias = m.group(1)
shorthash = hashes.get(alias) shorthash = hashes.get(alias)
if shorthash is None: if shorthash is None:
return m.group(0) return m.group(0)
lora_on_disk = lora.available_lora_hash_lookup.get(shorthash) network_on_disk = networks.available_network_hash_lookup.get(shorthash)
if lora_on_disk is None: if network_on_disk is None:
return m.group(0) return m.group(0)
return f'<lora:{lora_on_disk.get_alias()}:' return f'<lora:{network_on_disk.get_alias()}:'
d["Prompt"] = re.sub(re_lora, lora_replacement, d["Prompt"]) d["Prompt"] = re.sub(re_lora, network_replacement, d["Prompt"])
script_callbacks.on_infotext_pasted(infotext_pasted) script_callbacks.on_infotext_pasted(infotext_pasted)
shared.opts.onchange("lora_in_memory_limit", networks.purge_networks_from_memory)
@@ -0,0 +1,226 @@
import datetime
import html
import random
import gradio as gr
import re
from modules import ui_extra_networks_user_metadata
def is_non_comma_tagset(tags):
average_tag_length = sum(len(x) for x in tags.keys()) / len(tags)
return average_tag_length >= 16
re_word = re.compile(r"[-_\w']+")
re_comma = re.compile(r" *, *")
def build_tags(metadata):
tags = {}
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 = {}
for text, text_count in tags.items():
for word in re.findall(re_word, text):
if len(word) < 3:
continue
new_tags[word] = new_tags.get(word, 0) + text_count
tags = new_tags
ordered_tags = sorted(tags.keys(), key=tags.get, reverse=True)
return [(tag, tags[tag]) for tag in ordered_tags]
class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor):
def __init__(self, ui, tabname, page):
super().__init__(ui, tabname, page)
self.select_sd_version = None
self.taginfo = None
self.edit_activation_text = None
self.slider_preferred_weight = None
self.edit_notes = None
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)
def get_metadata_table(self, name):
table = super().get_metadata_table(name)
item = self.page.items.get(name, {})
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:",
}
for key, label in keys.items():
value = metadata.get(key, None)
if value is not None and str(value) != "None":
table.append((label, html.escape(value)))
ss_training_started_at = metadata.get('ss_training_started_at')
if ss_training_started_at:
table.append(("Date trained:", datetime.datetime.utcfromtimestamp(float(ss_training_started_at)).strftime('%Y-%m-%d %H:%M')))
ss_bucket_info = metadata.get("ss_bucket_info")
if ss_bucket_info and "buckets" in ss_bucket_info:
resolutions = {}
for _, bucket in ss_bucket_info["buckets"].items():
resolution = bucket["resolution"]
resolution = f'{resolution[1]}x{resolution[0]}'
resolutions[resolution] = resolutions.get(resolution, 0) + int(bucket["count"])
resolutions_list = sorted(resolutions.keys(), key=resolutions.get, reverse=True)
resolutions_text = html.escape(", ".join(resolutions_list[0:4]))
if len(resolutions) > 4:
resolutions_text += ", ..."
resolutions_text = f"<span title='{html.escape(', '.join(resolutions_list))}'>{resolutions_text}</span>"
table.append(('Resolutions:' if len(resolutions_list) > 1 else 'Resolution:', resolutions_text))
image_count = 0
for _, params in metadata.get("ss_dataset_dirs", {}).items():
image_count += int(params.get("img_count", 0))
if image_count:
table.append(("Dataset size:", image_count))
return table
def put_values_into_components(self, name):
user_metadata = self.get_user_metadata(name)
values = super().put_values_into_components(name)
item = self.page.items.get(name, {})
metadata = item.get("metadata") or {}
tags = build_tags(metadata)
gradio_tags = [(tag, str(count)) for tag, count in tags[0:24]]
return [
*values[0:5],
item.get("sd_version", "Unknown"),
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),
]
def generate_random_prompt(self, name):
item = self.page.items.get(name, {})
metadata = item.get("metadata") or {}
tags = build_tags(metadata)
return self.generate_random_prompt_from_tags(tags)
def generate_random_prompt_from_tags(self, tags):
max_count = None
res = []
for tag, count in tags:
if not max_count:
max_count = count
v = random.random() * max_count
if count > v:
for x in "({[]})":
tag = tag.replace(x, '\\' + x)
res.append(tag)
return ", ".join(sorted(res))
def create_extra_default_items_in_left_column(self):
# this would be a lot better as gr.Radio but I can't make it work
self.select_sd_version = gr.Dropdown(['SD1', 'SD2', 'SDXL', 'Unknown'], value='Unknown', label='Stable Diffusion version', interactive=True)
def create_editor(self):
self.create_default_editor_elems()
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', size="lg", scale=1)
self.edit_notes = gr.TextArea(label='Notes', lines=4)
generate_random_prompt.click(fn=self.generate_random_prompt, inputs=[self.edit_name_input], outputs=[random_prompt], show_progress=False)
def select_tag(activation_text, evt: gr.SelectData):
tag = evt.value[0]
words = re.split(re_comma, activation_text)
if tag in words:
words = [x for x in words if x != tag and x.strip()]
return ", ".join(words)
return activation_text + ", " + tag if activation_text else tag
self.taginfo.select(fn=select_tag, inputs=[self.edit_activation_text], outputs=[self.edit_activation_text], show_progress=False)
self.create_default_buttons()
viewed_components = [
self.edit_name,
self.edit_description,
self.html_filedata,
self.html_preview,
self.edit_notes,
self.select_sd_version,
self.taginfo,
self.edit_activation_text,
self.slider_preferred_weight,
self.edit_negative_text,
row_random_prompt,
random_prompt,
]
self.button_edit\
.click(fn=self.put_values_into_components, inputs=[self.edit_name_input], outputs=viewed_components)\
.then(fn=lambda: gr.update(visible=True), inputs=[], outputs=[self.box])
edited_components = [
self.edit_description,
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)
@@ -1,8 +1,11 @@
import json
import os import os
import lora
import network
import networks
from modules import shared, ui_extra_networks from modules import shared, ui_extra_networks
from modules.ui_extra_networks import quote_js
from ui_edit_user_metadata import LoraUserMetadataEditor
class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage): class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
@@ -10,27 +13,78 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
super().__init__('Lora') super().__init__('Lora')
def refresh(self): def refresh(self):
lora.list_available_loras() networks.list_available_networks()
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,
"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_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)},
"sd_version": lora_on_disk.sd_version.name,
}
self.read_user_metadata(item)
activation_text = item["user_metadata"].get("activation text")
preferred_weight = item["user_metadata"].get("preferred weight", 0.0)
item["prompt"] = quote_js(f"<lora:{alias}:") + " + " + (str(preferred_weight) if preferred_weight else "opts.extra_networks_default_multiplier") + " + " + quote_js(">")
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
sd_version = network.SdVersion[sd_version]
else:
sd_version = lora_on_disk.sd_version
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
if model_version.name in shared.opts.lora_hide_unknown_for_versions:
return None
elif shared.sd_model.is_sdxl and sd_version != network.SdVersion.SDXL:
return None
elif shared.sd_model.is_sd2 and sd_version != network.SdVersion.SD2:
return None
elif shared.sd_model.is_sd1 and sd_version != network.SdVersion.SD1:
return None
return item
def list_items(self): def list_items(self):
for index, (name, lora_on_disk) in enumerate(lora.available_loras.items()): # instantiate a list to protect against concurrent modification
path, ext = os.path.splitext(lora_on_disk.filename) names = list(networks.available_networks)
for index, name in enumerate(names):
alias = lora_on_disk.get_alias() item = self.create_item(name, index)
if item is not None:
yield { yield item
"name": name,
"filename": path,
"preview": self.find_preview(path),
"description": self.find_description(path),
"search_term": self.search_terms_from_path(lora_on_disk.filename),
"prompt": json.dumps(f"<lora:{alias}:") + " + opts.extra_networks_default_multiplier + " + json.dumps(">"),
"local_preview": f"{path}.{shared.opts.samples_format}",
"metadata": json.dumps(lora_on_disk.metadata, indent=4) if lora_on_disk.metadata else None,
"sort_keys": {'default': index, **self.get_sort_keys(lora_on_disk.filename)},
}
def allowed_directories_for_previews(self): def allowed_directories_for_previews(self):
return [shared.cmd_opts.lora_dir] return [shared.cmd_opts.lora_dir, shared.cmd_opts.lyco_dir_backcompat]
def create_user_metadata_editor(self, ui, tabname):
return LoraUserMetadataEditor(ui, tabname, self)
@@ -1,18 +1,9 @@
import os.path
import sys import sys
import PIL.Image import PIL.Image
import numpy as np
import torch
from tqdm import tqdm
from basicsr.utils.download_util import load_file_from_url
import modules.upscaler import modules.upscaler
from modules import devices, modelloader, script_callbacks, errors from modules import devices, errors, modelloader, script_callbacks, shared, upscaler_utils
from scunet_model_arch import SCUNet as net
from modules.shared import opts
class UpscalerScuNET(modules.upscaler.Upscaler): class UpscalerScuNET(modules.upscaler.Upscaler):
@@ -28,7 +19,7 @@ class UpscalerScuNET(modules.upscaler.Upscaler):
scalers = [] scalers = []
add_model2 = True add_model2 = True
for file in model_paths: for file in model_paths:
if "http" in file: if file.startswith("http"):
name = self.model_name name = self.model_name
else: else:
name = modelloader.friendly_name(file) name = modelloader.friendly_name(file)
@@ -44,102 +35,37 @@ class UpscalerScuNET(modules.upscaler.Upscaler):
scalers.append(scaler_data2) scalers.append(scaler_data2)
self.scalers = scalers 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): def do_upscale(self, img: PIL.Image.Image, selected_file):
devices.torch_gc()
torch.cuda.empty_cache() try:
model = self.load_model(selected_file)
model = self.load_model(selected_file) except Exception as e:
if model is None: print(f"ScuNET: Unable to load model from {selected_file}: {e}", file=sys.stderr)
print(f"ScuNET: Unable to load model from {selected_file}", file=sys.stderr)
return img return img
device = devices.get_device_for('scunet') img = upscaler_utils.upscale_2(
tile = opts.SCUNET_tile img,
h, w = img.height, img.width model,
np_img = np.array(img) tile_size=shared.opts.SCUNET_tile,
np_img = np_img[:, :, ::-1] # RGB to BGR tile_overlap=shared.opts.SCUNET_tile_overlap,
np_img = np_img.transpose((2, 0, 1)) / 255 # HWC to CHW scale=1, # ScuNET is a denoising model, not an upscaler
torch_img = torch.from_numpy(np_img).float().unsqueeze(0).to(device) # type: ignore desc='ScuNET',
)
if tile > h or tile > w: devices.torch_gc()
_img = torch.zeros(1, 3, max(h, tile), max(w, tile), dtype=torch_img.dtype, device=torch_img.device) return img
_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
torch.cuda.empty_cache()
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))
def load_model(self, path: str): def load_model(self, path: str):
device = devices.get_device_for('scunet') device = devices.get_device_for('scunet')
if "http" in path: if path.startswith("http"):
filename = load_file_from_url(url=self.model_url, model_dir=self.model_download_path, file_name="%s.pth" % self.name, progress=True) # TODO: this doesn't use `path` at all?
filename = modelloader.load_file_from_url(self.model_url, model_dir=self.model_download_path, file_name=f"{self.name}.pth")
else: else:
filename = path filename = path
if not os.path.exists(os.path.join(self.model_path, filename)) or filename is None: return modelloader.load_spandrel_model(filename, device=device, expected_architecture='SCUNet')
print(f"ScuNET: Unable to load model from {filename}", file=sys.stderr)
return None
model = net(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
def on_ui_settings(): def on_ui_settings():
import gradio as gr 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", 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")) 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"))
@@ -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)
+53 -135
View File
@@ -1,34 +1,30 @@
import os import logging
import sys
import numpy as np
import torch import torch
from PIL import Image from PIL import Image
from basicsr.utils.download_util import load_file_from_url
from tqdm import tqdm
from modules import modelloader, devices, script_callbacks, shared from modules import devices, modelloader, script_callbacks, shared, upscaler_utils
from modules.shared import opts, state
from swinir_model_arch import SwinIR as net
from swinir_model_arch_v2 import Swin2SR as net2
from modules.upscaler import Upscaler, UpscalerData 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): class UpscalerSwinIR(Upscaler):
def __init__(self, dirname): def __init__(self, dirname):
self._cached_model = None # keep the model when SWIN_torch_compile is on to prevent re-compile every runs
self._cached_model_config = None # to clear '_cached_model' when changing model (v1/v2) or settings
self.name = "SwinIR" self.name = "SwinIR"
self.model_url = "https://github.com/JingyunLiang/SwinIR/releases/download/v0.0" \ self.model_url = SWINIR_MODEL_URL
"/003_realSR_BSRGAN_DFOWMFC_s64w8_SwinIR" \
"-L_x4_GAN.pth "
self.model_name = "SwinIR 4x" self.model_name = "SwinIR 4x"
self.user_path = dirname self.user_path = dirname
super().__init__() super().__init__()
scalers = [] scalers = []
model_files = self.find_models(ext_filter=[".pt", ".pth"]) model_files = self.find_models(ext_filter=[".pt", ".pth"])
for model in model_files: for model in model_files:
if "http" in model: if model.startswith("http"):
name = self.model_name name = self.model_name
else: else:
name = modelloader.friendly_name(model) name = modelloader.friendly_name(model)
@@ -36,135 +32,56 @@ class UpscalerSwinIR(Upscaler):
scalers.append(model_data) scalers.append(model_data)
self.scalers = scalers self.scalers = scalers
def do_upscale(self, img, model_file): def do_upscale(self, img: Image.Image, model_file: str) -> Image.Image:
model = self.load_model(model_file) current_config = (model_file, shared.opts.SWIN_tile)
if model is None:
return img if self._cached_model_config == current_config:
model = model.to(device_swinir, dtype=devices.dtype) model = self._cached_model
img = upscale(img, model) else:
try: try:
torch.cuda.empty_cache() model = self.load_model(model_file)
except Exception: except Exception as e:
pass print(f"Failed loading SwinIR model {model_file}: {e}", file=sys.stderr)
return img
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 return img
def load_model(self, path, scale=4): def load_model(self, path, scale=4):
if "http" in path: if path.startswith("http"):
dl_name = "%s%s" % (self.model_name.replace(" ", "_"), ".pth") filename = modelloader.load_file_from_url(
filename = load_file_from_url(url=path, model_dir=self.model_download_path, file_name=dl_name, progress=True) url=path,
model_dir=self.model_download_path,
file_name=f"{self.model_name.replace(' ', '_')}.pth",
)
else: else:
filename = path filename = path
if filename is None or not os.path.exists(filename):
return None
if filename.endswith(".v2.pth"):
model = net2(
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 = net(
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) model_descriptor = modelloader.load_spandrel_model(
if params is not None: filename,
model.load_state_dict(pretrained_model[params], strict=True) device=self._get_device(),
else: prefer_half=(devices.dtype == torch.float16),
model.load_state_dict(pretrained_model, strict=True) expected_architecture="SwinIR",
return model )
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 _get_device(self):
def upscale( return devices.get_device_for('swinir')
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 on_ui_settings(): def on_ui_settings():
@@ -172,6 +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", 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"))) 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")))
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) script_callbacks.on_ui_settings(on_ui_settings)
@@ -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
@@ -4,17 +4,32 @@ onUiLoaded(async() => {
inpaint: "#img2maskimg", inpaint: "#img2maskimg",
inpaintSketch: "#inpaint_sketch", inpaintSketch: "#inpaint_sketch",
rangeGroup: "#img2img_column_size", rangeGroup: "#img2img_column_size",
sketch: "#img2img_sketch", sketch: "#img2img_sketch"
}; };
const tabNameToElementId = { const tabNameToElementId = {
"Inpaint sketch": elementIDs.inpaintSketch, "Inpaint sketch": elementIDs.inpaintSketch,
"Inpaint": elementIDs.inpaint, "Inpaint": elementIDs.inpaint,
"Sketch": elementIDs.sketch, "Sketch": elementIDs.sketch
}; };
// Helper functions // Helper functions
// Get active tab // 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) { function getActiveTab(elements, all = false) {
if (!elements.img2imgTabs) return null;
const tabs = elements.img2imgTabs.querySelectorAll("button"); const tabs = elements.img2imgTabs.querySelectorAll("button");
if (all) return tabs; if (all) return tabs;
@@ -29,12 +44,13 @@ onUiLoaded(async() => {
// Get tab ID // Get tab ID
function getTabId(elements) { function getTabId(elements) {
const activeTab = getActiveTab(elements); const activeTab = getActiveTab(elements);
if (!activeTab) return null;
return tabNameToElementId[activeTab.innerText]; return tabNameToElementId[activeTab.innerText];
} }
// Wait until opts loaded // Wait until opts loaded
async function waitForOpts() { async function waitForOpts() {
for (;;) { for (; ;) {
if (window.opts && Object.keys(window.opts).length) { if (window.opts && Object.keys(window.opts).length) {
return window.opts; return window.opts;
} }
@@ -42,43 +58,115 @@ onUiLoaded(async() => {
} }
} }
// Check is hotkey valid // Detect whether the element has a horizontal scroll bar
function isSingleLetter(value) { function hasHorizontalScrollbar(element) {
return element.scrollWidth > element.clientWidth;
}
// Function for defining the "Ctrl", "Shift" and "Alt" keys
function isModifierKey(event, key) {
switch (key) {
case "Ctrl":
return event.ctrlKey;
case "Shift":
return event.shiftKey;
case "Alt":
return event.altKey;
default:
return false;
}
}
// Check if hotkey is valid
function isValidHotkey(value) {
const specialKeys = ["Ctrl", "Alt", "Shift", "Disable"];
return ( return (
typeof value === "string" && value.length === 1 && /[a-z]/i.test(value) (typeof value === "string" &&
value.length === 1 &&
/[a-z]/i.test(value)) ||
specialKeys.includes(value)
); );
} }
// Create hotkeyConfig from opts // Normalize hotkey
function createHotkeyConfig(defaultHotkeysConfig, hotkeysConfigOpts) { function normalizeHotkey(hotkey) {
const result = {}; return hotkey.length === 1 ? "Key" + hotkey.toUpperCase() : hotkey;
const usedKeys = new Set(); }
// Format hotkey for display
function formatHotkeyForDisplay(hotkey) {
return hotkey.startsWith("Key") ? hotkey.slice(3) : hotkey;
}
// Create hotkey configuration with the provided options
function createHotkeyConfig(defaultHotkeysConfig, hotkeysConfigOpts) {
const result = {}; // Resulting hotkey configuration
const usedKeys = new Set(); // Set of used hotkeys
// Iterate through defaultHotkeysConfig keys
for (const key in defaultHotkeysConfig) { for (const key in defaultHotkeysConfig) {
if (typeof hotkeysConfigOpts[key] === "boolean") { const userValue = hotkeysConfigOpts[key]; // User-provided hotkey value
result[key] = hotkeysConfigOpts[key]; const defaultValue = defaultHotkeysConfig[key]; // Default hotkey value
continue;
} // Apply appropriate value for undefined, boolean, or object userValue
if ( if (
hotkeysConfigOpts[key] && userValue === undefined ||
isSingleLetter(hotkeysConfigOpts[key]) && typeof userValue === "boolean" ||
!usedKeys.has(hotkeysConfigOpts[key].toUpperCase()) typeof userValue === "object" ||
userValue === "disable"
) { ) {
// If the property passed the test and has not yet been used, add 'Key' before it and save it result[key] =
result[key] = "Key" + hotkeysConfigOpts[key].toUpperCase(); userValue === undefined ? defaultValue : userValue;
usedKeys.add(hotkeysConfigOpts[key].toUpperCase()); } else if (isValidHotkey(userValue)) {
const normalizedUserValue = normalizeHotkey(userValue);
// Check for conflicting hotkeys
if (!usedKeys.has(normalizedUserValue)) {
usedKeys.add(normalizedUserValue);
result[key] = normalizedUserValue;
} else {
console.error(
`Hotkey: ${formatHotkeyForDisplay(
userValue
)} for ${key} is repeated and conflicts with another hotkey. The default hotkey is used: ${formatHotkeyForDisplay(
defaultValue
)}`
);
result[key] = defaultValue;
}
} else { } else {
// If the property does not pass the test or has already been used, we keep the default value
console.error( console.error(
`Hotkey: ${hotkeysConfigOpts[key]} for ${key} is repeated and conflicts with another hotkey or is not 1 letter. The default hotkey is used: ${defaultHotkeysConfig[key][3]}` `Hotkey: ${formatHotkeyForDisplay(
userValue
)} for ${key} is not valid. The default hotkey is used: ${formatHotkeyForDisplay(
defaultValue
)}`
); );
result[key] = defaultHotkeysConfig[key]; result[key] = defaultValue;
} }
} }
return result; return result;
} }
// Disables functions in the config object based on the provided list of function names
function disableFunctions(config, disabledFunctions) {
// Bind the hasOwnProperty method to the functionMap object to avoid errors
const hasOwnProperty =
Object.prototype.hasOwnProperty.bind(functionMap);
// Loop through the disabledFunctions array and disable the corresponding functions in the config object
disabledFunctions.forEach(funcName => {
if (hasOwnProperty(funcName)) {
const key = functionMap[funcName];
config[key] = "disable";
}
});
// Return the updated config object
return config;
}
/** /**
* The restoreImgRedMask function displays a red mask around an image to indicate the aspect ratio. * The restoreImgRedMask function displays a red mask around an image to indicate the aspect ratio.
* If the image display property is set to 'none', the mask breaks. To fix this, the function * If the image display property is set to 'none', the mask breaks. To fix this, the function
@@ -100,7 +188,9 @@ onUiLoaded(async() => {
imageARPreview.style.transform = ""; imageARPreview.style.transform = "";
if (parseFloat(mainTab.style.width) > 865) { if (parseFloat(mainTab.style.width) > 865) {
const transformString = mainTab.style.transform; const transformString = mainTab.style.transform;
const scaleMatch = transformString.match(/scale\(([-+]?[0-9]*\.?[0-9]+)\)/); const scaleMatch = transformString.match(
/scale\(([-+]?[0-9]*\.?[0-9]+)\)/
);
let zoom = 1; // default zoom let zoom = 1; // default zoom
if (scaleMatch && scaleMatch[1]) { if (scaleMatch && scaleMatch[1]) {
@@ -124,31 +214,59 @@ onUiLoaded(async() => {
// Default config // Default config
const defaultHotkeysConfig = { const defaultHotkeysConfig = {
canvas_hotkey_zoom: "Alt",
canvas_hotkey_adjust: "Ctrl",
canvas_hotkey_reset: "KeyR", canvas_hotkey_reset: "KeyR",
canvas_hotkey_fullscreen: "KeyS", canvas_hotkey_fullscreen: "KeyS",
canvas_hotkey_move: "KeyF", canvas_hotkey_move: "KeyF",
canvas_hotkey_overlap: "KeyO", canvas_hotkey_overlap: "KeyO",
canvas_hotkey_shrink_brush: "KeyQ",
canvas_hotkey_grow_brush: "KeyW",
canvas_disabled_functions: [],
canvas_show_tooltip: true, canvas_show_tooltip: true,
canvas_swap_controls: false canvas_auto_expand: true,
canvas_blur_prompt: false,
}; };
// swap the actions for ctr + wheel and shift + wheel
const hotkeysConfig = createHotkeyConfig( 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",
"Overlap": "canvas_hotkey_overlap"
};
// Loading the configuration from opts
const preHotkeysConfig = createHotkeyConfig(
defaultHotkeysConfig, defaultHotkeysConfig,
hotkeysConfigOpts hotkeysConfigOpts
); );
// Disable functions that are not needed by the user
const hotkeysConfig = disableFunctions(
preHotkeysConfig,
preHotkeysConfig.canvas_disabled_functions
);
let isMoving = false; let isMoving = false;
let mouseX, mouseY; let mouseX, mouseY;
let activeElement; let activeElement;
let interactedWithAltKey = false;
const elements = Object.fromEntries(Object.keys(elementIDs).map((id) => [ const elements = Object.fromEntries(
id, Object.keys(elementIDs).map(id => [
gradioApp().querySelector(elementIDs[id]), id,
])); gradioApp().querySelector(elementIDs[id])
])
);
const elemData = {}; const elemData = {};
// Apply functionality to the range inputs. Restore redmask and correct for long images. // Apply functionality to the range inputs. Restore redmask and correct for long images.
const rangeInputs = elements.rangeGroup ? Array.from(elements.rangeGroup.querySelectorAll("input")) : const rangeInputs = elements.rangeGroup ?
Array.from(elements.rangeGroup.querySelectorAll("input")) :
[ [
gradioApp().querySelector("#img2img_width input[type='range']"), gradioApp().querySelector("#img2img_width input[type='range']"),
gradioApp().querySelector("#img2img_height input[type='range']") gradioApp().querySelector("#img2img_height input[type='range']")
@@ -158,11 +276,11 @@ onUiLoaded(async() => {
input?.addEventListener("input", () => restoreImgRedMask(elements)); input?.addEventListener("input", () => restoreImgRedMask(elements));
} }
function applyZoomAndPan(elemId) { function applyZoomAndPan(elemId, isExtension = true) {
const targetElement = gradioApp().querySelector(elemId); const targetElement = gradioApp().querySelector(elemId);
if (!targetElement) { if (!targetElement) {
console.log("Element not found"); console.log("Element not found", elemId);
return; return;
} }
@@ -177,41 +295,59 @@ onUiLoaded(async() => {
// Create tooltip // Create tooltip
function createTooltip() { function createTooltip() {
const toolTipElemnt = const toolTipElement =
targetElement.querySelector(".image-container"); targetElement.querySelector(".image-container");
const tooltip = document.createElement("div"); const tooltip = document.createElement("div");
tooltip.className = "tooltip"; tooltip.className = "canvas-tooltip";
// Creating an item of information // Creating an item of information
const info = document.createElement("i"); const info = document.createElement("i");
info.className = "tooltip-info"; info.className = "canvas-tooltip-info";
info.textContent = ""; info.textContent = "";
// Create a container for the contents of the tooltip // Create a container for the contents of the tooltip
const tooltipContent = document.createElement("div"); const tooltipContent = document.createElement("div");
tooltipContent.className = "tooltip-content"; tooltipContent.className = "canvas-tooltip-content";
// Add info about hotkeys // Define an array with hotkey information and their actions
const zoomKey = hotkeysConfig.canvas_swap_controls ? "Ctrl" : "Shift"; const hotkeysInfo = [
const adjustKey = hotkeysConfig.canvas_swap_controls ? "Shift" : "Ctrl";
const hotkeys = [
{key: `${zoomKey} + wheel`, action: "Zoom canvas"},
{key: `${adjustKey} + wheel`, action: "Adjust brush size"},
{ {
key: hotkeysConfig.canvas_hotkey_reset.charAt(hotkeysConfig.canvas_hotkey_reset.length - 1), configKey: "canvas_hotkey_zoom",
action: "Reset zoom" action: "Zoom canvas",
keySuffix: " + wheel"
}, },
{ {
key: hotkeysConfig.canvas_hotkey_fullscreen.charAt(hotkeysConfig.canvas_hotkey_fullscreen.length - 1), configKey: "canvas_hotkey_adjust",
action: "Adjust brush size",
keySuffix: " + wheel"
},
{configKey: "canvas_hotkey_reset", action: "Reset zoom"},
{
configKey: "canvas_hotkey_fullscreen",
action: "Fullscreen mode" action: "Fullscreen mode"
}, },
{ {configKey: "canvas_hotkey_move", action: "Move canvas"},
key: hotkeysConfig.canvas_hotkey_move.charAt(hotkeysConfig.canvas_hotkey_move.length - 1), {configKey: "canvas_hotkey_overlap", action: "Overlap"}
action: "Move canvas"
}
]; ];
// Create hotkeys array with disabled property based on the config values
const hotkeys = hotkeysInfo.map(info => {
const configValue = hotkeysConfig[info.configKey];
const key = info.keySuffix ?
`${configValue}${info.keySuffix}` :
configValue.charAt(configValue.length - 1);
return {
key,
action: info.action,
disabled: configValue === "disable"
};
});
for (const hotkey of hotkeys) { for (const hotkey of hotkeys) {
if (hotkey.disabled) {
continue;
}
const p = document.createElement("p"); const p = document.createElement("p");
p.innerHTML = `<b>${hotkey.key}</b> - ${hotkey.action}`; p.innerHTML = `<b>${hotkey.key}</b> - ${hotkey.action}`;
tooltipContent.appendChild(p); tooltipContent.appendChild(p);
@@ -222,7 +358,7 @@ onUiLoaded(async() => {
tooltip.appendChild(tooltipContent); tooltip.appendChild(tooltipContent);
// Add a hint element to the target element // Add a hint element to the target element
toolTipElemnt.appendChild(tooltip); toolTipElement.appendChild(tooltip);
} }
//Show tool tip if setting enable //Show tool tip if setting enable
@@ -232,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. // 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() { 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`); const img = targetElement.querySelector(`${elemId} img`);
if (img && img.style.display !== "none") { if (img && img.style.display !== "none") {
@@ -252,6 +388,12 @@ onUiLoaded(async() => {
panY: 0 panY: 0
}; };
if (isExtension) {
targetElement.style.overflow = "hidden";
}
targetElement.isZoomed = false;
fixCanvas(); fixCanvas();
targetElement.style.transform = `scale(${elemData[elemId].zoomLevel}) translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px)`; targetElement.style.transform = `scale(${elemData[elemId].zoomLevel}) translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px)`;
@@ -262,8 +404,27 @@ onUiLoaded(async() => {
toggleOverlap("off"); toggleOverlap("off");
fullScreenMode = false; 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 ( if (
canvas && canvas &&
!isExtension &&
parseFloat(canvas.style.width) > 865 && parseFloat(canvas.style.width) > 865 &&
parseFloat(targetElement.style.width) > 865 parseFloat(targetElement.style.width) > 865
) { ) {
@@ -272,9 +433,6 @@ onUiLoaded(async() => {
} }
targetElement.style.width = ""; 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 // Toggle the zIndex of the target element between two values, allowing it to overlap or be overlapped by other elements
@@ -330,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 // 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) { 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 += elemData[elemId].panX +=
mouseX - (mouseX * newZoomLevel) / elemData[elemId].zoomLevel; mouseX - (mouseX * newZoomLevel) / elemData[elemId].zoomLevel;
@@ -341,17 +499,22 @@ onUiLoaded(async() => {
targetElement.style.transform = `translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px) scale(${newZoomLevel})`; targetElement.style.transform = `translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px) scale(${newZoomLevel})`;
toggleOverlap("on"); toggleOverlap("on");
if (isExtension) {
targetElement.style.overflow = "visible";
}
return newZoomLevel; return newZoomLevel;
} }
// Change the zoom level based on user interaction // Change the zoom level based on user interaction
function changeZoomLevel(operation, e) { function changeZoomLevel(operation, e) {
if ( if (isModifierKey(e, hotkeysConfig.canvas_hotkey_zoom)) {
(!hotkeysConfig.canvas_swap_controls && e.shiftKey) ||
(hotkeysConfig.canvas_swap_controls && e.ctrlKey)
) {
e.preventDefault(); e.preventDefault();
if (hotkeysConfig.canvas_hotkey_zoom === "Alt") {
interactedWithAltKey = true;
}
let zoomPosX, zoomPosY; let zoomPosX, zoomPosY;
let delta = 0.2; let delta = 0.2;
if (elemData[elemId].zoomLevel > 7) { if (elemData[elemId].zoomLevel > 7) {
@@ -366,10 +529,12 @@ onUiLoaded(async() => {
fullScreenMode = false; fullScreenMode = false;
elemData[elemId].zoomLevel = updateZoom( elemData[elemId].zoomLevel = updateZoom(
elemData[elemId].zoomLevel + elemData[elemId].zoomLevel +
(operation === "+" ? delta : -delta), (operation === "+" ? delta : -delta),
zoomPosX - targetElement.getBoundingClientRect().left, zoomPosX - targetElement.getBoundingClientRect().left,
zoomPosY - targetElement.getBoundingClientRect().top zoomPosY - targetElement.getBoundingClientRect().top
); );
targetElement.isZoomed = true;
} }
} }
@@ -383,10 +548,19 @@ onUiLoaded(async() => {
//Reset Zoom //Reset Zoom
targetElement.style.transform = `translate(${0}px, ${0}px) scale(${1})`; 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 // Get element and screen dimensions
const elementWidth = targetElement.offsetWidth; const elementWidth = targetElement.offsetWidth;
const elementHeight = targetElement.offsetHeight; const elementHeight = targetElement.offsetHeight;
const parentElement = targetElement.parentElement;
const screenWidth = parentElement.clientWidth; const screenWidth = parentElement.clientWidth;
const screenHeight = parentElement.clientHeight; const screenHeight = parentElement.clientHeight;
@@ -439,8 +613,12 @@ onUiLoaded(async() => {
if (!canvas) return; if (!canvas) return;
if (canvas.offsetWidth > 862) { if (canvas.offsetWidth > 862 || isExtension) {
targetElement.style.width = canvas.offsetWidth + "px"; targetElement.style.width = (canvas.offsetWidth + 2) + "px";
}
if (isExtension) {
targetElement.style.overflow = "visible";
} }
if (fullScreenMode) { if (fullScreenMode) {
@@ -503,10 +681,25 @@ onUiLoaded(async() => {
// Handle keydown events // Handle keydown events
function handleKeyDown(event) { function handleKeyDown(event) {
// Disable key locks to make pasting from the buffer work correctly
if ((event.ctrlKey && event.code === 'KeyV') || (event.ctrlKey && event.code === 'KeyC') || event.code === "F5") {
return;
}
// before activating shortcut, ensure user is not actively typing in an input field
if (!hotkeysConfig.canvas_blur_prompt) {
if (event.target.nodeName === 'TEXTAREA' || event.target.nodeName === 'INPUT') {
return;
}
}
const hotkeyActions = { const hotkeyActions = {
[hotkeysConfig.canvas_hotkey_reset]: resetZoom, [hotkeysConfig.canvas_hotkey_reset]: resetZoom,
[hotkeysConfig.canvas_hotkey_overlap]: toggleOverlap, [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]; const action = hotkeyActions[event.code];
@@ -514,6 +707,13 @@ onUiLoaded(async() => {
event.preventDefault(); event.preventDefault();
action(event); action(event);
} }
if (
isModifierKey(event, hotkeysConfig.canvas_hotkey_zoom) ||
isModifierKey(event, hotkeysConfig.canvas_hotkey_adjust)
) {
event.preventDefault();
}
} }
// Get Mouse position // Get Mouse position
@@ -522,8 +722,48 @@ onUiLoaded(async() => {
mouseY = e.offsetY; 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); 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 // Handle events only inside the targetElement
let isKeyDownHandlerAttached = false; let isKeyDownHandlerAttached = false;
@@ -550,27 +790,29 @@ onUiLoaded(async() => {
targetElement.addEventListener("mouseleave", handleMouseLeave); targetElement.addEventListener("mouseleave", handleMouseLeave);
// Reset zoom when click on another tab // Reset zoom when click on another tab
elements.img2imgTabs.addEventListener("click", resetZoom); if (elements.img2imgTabs) {
elements.img2imgTabs.addEventListener("click", () => { elements.img2imgTabs.addEventListener("click", resetZoom);
// targetElement.style.width = ""; elements.img2imgTabs.addEventListener("click", () => {
if (parseInt(targetElement.style.width) > 865) { // targetElement.style.width = "";
setTimeout(fitToElement, 0); if (parseInt(targetElement.style.width) > 865) {
} setTimeout(fitToElement, 0);
}); }
});
}
targetElement.addEventListener("wheel", e => { targetElement.addEventListener("wheel", e => {
// change zoom level // change zoom level
const operation = e.deltaY > 0 ? "-" : "+"; const operation = (e.deltaY || -e.wheelDelta) > 0 ? "-" : "+";
changeZoomLevel(operation, e); changeZoomLevel(operation, e);
// Handle brush size adjustment with ctrl key pressed // Handle brush size adjustment with ctrl key pressed
if ( if (isModifierKey(e, hotkeysConfig.canvas_hotkey_adjust)) {
(hotkeysConfig.canvas_swap_controls && e.shiftKey) ||
(!hotkeysConfig.canvas_swap_controls &&
(e.ctrlKey || e.metaKey))
) {
e.preventDefault(); e.preventDefault();
if (hotkeysConfig.canvas_hotkey_adjust === "Alt") {
interactedWithAltKey = true;
}
// Increase or decrease brush size based on scroll direction // Increase or decrease brush size based on scroll direction
adjustBrushSize(elemId, e.deltaY); adjustBrushSize(elemId, e.deltaY);
} }
@@ -578,6 +820,20 @@ onUiLoaded(async() => {
// Handle the move event for pan functionality. Updates the panX and panY variables and applies the new transform to the target element. // Handle the move event for pan functionality. Updates the panX and panY variables and applies the new transform to the target element.
function handleMoveKeyDown(e) { function handleMoveKeyDown(e) {
// Disable key locks to make pasting from the buffer work correctly
if ((e.ctrlKey && e.code === 'KeyV') || (e.ctrlKey && event.code === 'KeyC') || e.code === "F5") {
return;
}
// before activating shortcut, ensure user is not actively typing in an input field
if (!hotkeysConfig.canvas_blur_prompt) {
if (e.target.nodeName === 'TEXTAREA' || e.target.nodeName === 'INPUT') {
return;
}
}
if (e.code === hotkeysConfig.canvas_hotkey_move) { if (e.code === hotkeysConfig.canvas_hotkey_move) {
if (!e.ctrlKey && !e.metaKey && isKeyDownHandlerAttached) { if (!e.ctrlKey && !e.metaKey && isKeyDownHandlerAttached) {
e.preventDefault(); e.preventDefault();
@@ -596,6 +852,20 @@ onUiLoaded(async() => {
document.addEventListener("keydown", handleMoveKeyDown); document.addEventListener("keydown", handleMoveKeyDown);
document.addEventListener("keyup", handleMoveKeyUp); 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. // Detect zoom level and update the pan speed.
function updatePanPosition(movementX, movementY) { function updatePanPosition(movementX, movementY) {
let panSpeed = 2; let panSpeed = 2;
@@ -618,6 +888,11 @@ onUiLoaded(async() => {
if (isMoving && elemId === activeElement) { if (isMoving && elemId === activeElement) {
updatePanPosition(e.movementX, e.movementY); updatePanPosition(e.movementX, e.movementY);
targetElement.style.pointerEvents = "none"; targetElement.style.pointerEvents = "none";
if (isExtension) {
targetElement.style.overflow = "visible";
}
} else { } else {
targetElement.style.pointerEvents = "auto"; targetElement.style.pointerEvents = "auto";
} }
@@ -628,13 +903,93 @@ onUiLoaded(async() => {
isMoving = false; 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); gradioApp().addEventListener("mousemove", handleMoveByKey);
} }
applyZoomAndPan(elementIDs.sketch); applyZoomAndPan(elementIDs.sketch, false);
applyZoomAndPan(elementIDs.inpaint); applyZoomAndPan(elementIDs.inpaint, false);
applyZoomAndPan(elementIDs.inpaintSketch); applyZoomAndPan(elementIDs.inpaintSketch, false);
// Make the function global so that other extensions can take advantage of this solution // 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"]);
}); });
@@ -1,10 +1,17 @@
import gradio as gr
from modules import shared from modules import shared
shared.options_templates.update(shared.options_section(('canvas_hotkey', "Canvas Hotkeys"), { shared.options_templates.update(shared.options_section(('canvas_hotkey', "Canvas Hotkeys"), {
"canvas_hotkey_move": shared.OptionInfo("F", "Moving the canvas"), "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_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_reset": shared.OptionInfo("R", "Reset zoom and canvas position"),
"canvas_hotkey_overlap": shared.OptionInfo("O", "Toggle overlap ( Technical button, neededs for testing )"), "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_show_tooltip": shared.OptionInfo(True, "Enable tooltip on the canvas"),
"canvas_swap_controls": shared.OptionInfo(False, "Swap hotkey combinations for Zoom and Adjust brush resize"), "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","Hotkey enlarge brush","Hotkey shrink brush","Moving canvas","Fullscreen","Reset Zoom","Overlap"]}),
})) }))
@@ -1,4 +1,4 @@
.tooltip-info { .canvas-tooltip-info {
position: absolute; position: absolute;
top: 10px; top: 10px;
left: 10px; left: 10px;
@@ -15,7 +15,7 @@
z-index: 100; z-index: 100;
} }
.tooltip-info::after { .canvas-tooltip-info::after {
content: ''; content: '';
display: block; display: block;
width: 2px; width: 2px;
@@ -24,7 +24,7 @@
margin-top: 2px; margin-top: 2px;
} }
.tooltip-info::before { .canvas-tooltip-info::before {
content: ''; content: '';
display: block; display: block;
width: 2px; width: 2px;
@@ -32,7 +32,7 @@
background-color: white; background-color: white;
} }
.tooltip-content { .canvas-tooltip-content {
display: none; display: none;
background-color: #f9f9f9; background-color: #f9f9f9;
color: #333; color: #333;
@@ -50,7 +50,7 @@
z-index: 100; z-index: 100;
} }
.tooltip:hover .tooltip-content { .canvas-tooltip:hover .canvas-tooltip-content {
display: block; display: block;
animation: fadeIn 0.5s; animation: fadeIn 0.5s;
opacity: 1; opacity: 1;
@@ -61,3 +61,6 @@
to {opacity: 1;} to {opacity: 1;}
} }
.styler {
overflow:inherit !important;
}
@@ -1,5 +1,7 @@
import math
import gradio as gr 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 from modules.ui_components import FormColumn
@@ -19,18 +21,43 @@ class ExtraOptionsSection(scripts.Script):
def ui(self, is_img2img): def ui(self, is_img2img):
self.comps = [] self.comps = []
self.setting_names = [] 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.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(): 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):
for setting_name in shared.opts.extra_options:
with FormColumn():
comp = ui_settings.create_setting_component(setting_name)
self.comps.append(comp) row_count = math.ceil(len(extra_options) / shared.opts.extra_options_cols)
self.setting_names.append(setting_name)
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(): 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) 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 p.override_settings[name] = value
shared.options_templates.update(shared.options_section(('ui', "User interface"), { shared.options_templates.update(shared.options_section(('settings_in_ui', "Settings in UI", "ui"), {
"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(), "settings_in_ui": shared.OptionHTML("""
"extra_options_accordion": shared.OptionInfo(False, "Place options in main UI into an accordion") 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()
})) }))
+351
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
@@ -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)
@@ -0,0 +1,34 @@
var isSetupForMobile = false;
function isMobile() {
for (var tab of ["txt2img", "img2img"]) {
var imageTab = gradioApp().getElementById(tab + '_results');
if (imageTab && imageTab.offsetParent && imageTab.offsetLeft == 0) {
return true;
}
}
return false;
}
function reportWindowSize() {
if (gradioApp().querySelector('.toprow-compact-tools')) return; // not applicable for compact prompt layout
var currentlyMobile = isMobile();
if (currentlyMobile == isSetupForMobile) return;
isSetupForMobile = currentlyMobile;
for (var tab of ["txt2img", "img2img"]) {
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();
});
@@ -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)")
@@ -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])
@@ -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))
@@ -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]
@@ -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]
@@ -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]
+6 -11
View File
@@ -1,14 +1,9 @@
<div class='card' style={style} onclick={card_clicked} {sort_keys}> <div class="card" style="{style}" onclick="{card_clicked}" data-name="{name}" {sort_keys}>
{background_image} {background_image}
{metadata_button} <div class="button-row">{copy_path_button}{metadata_button}{edit_button}</div>
<div class='actions'> <div class="actions">
<div class='additional'> <div class="additional">{search_terms}</div>
<ul> <span class="name">{name}</span>
<a href="#" title="replace preview image with currently selected in gallery" onclick={save_card_preview}>replace preview</a> <span class="description">{description}</span>
</ul>
<span style="display:none" class='search_term{search_only}'>{search_term}</span>
</div>
<span class='name'>{name}</span>
<span class='description'>{description}</span>
</div> </div>
</div> </div>
@@ -0,0 +1,5 @@
<div class="copy-path-button card-button"
title="Copy path to clipboard"
onclick="extraNetworksCopyCardPath(event)"
data-clipboard-text="{filename}">
</div>
@@ -0,0 +1,4 @@
<div class="edit-button card-button"
title="Edit metadata"
onclick="extraNetworksEditUserMetadata(event, '{tabname}', '{extra_networks_tabname}')">
</div>
+4
View File
@@ -0,0 +1,4 @@
<div class="metadata-button card-button"
title="Show internal metadata"
onclick="extraNetworksRequestMetadata(event, '{extra_networks_tabname}')">
</div>
+8
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>
+8
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>
+81
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>
+23
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>
-7
View File
@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<filter id='shadow' color-interpolation-filters="sRGB">
<feDropShadow flood-color="black" dx="0" dy="0" flood-opacity="0.9" stdDeviation="0.5"/>
<feDropShadow flood-color="black" dx="0" dy="0" flood-opacity="0.9" stdDeviation="0.5"/>
</filter>
<path style="filter:url(#shadow);" fill="#FFFFFF" d="M13.18 19C13.35 19.72 13.64 20.39 14.03 21H5C3.9 21 3 20.11 3 19V5C3 3.9 3.9 3 5 3H19C20.11 3 21 3.9 21 5V11.18C20.5 11.07 20 11 19.5 11C19.33 11 19.17 11 19 11.03V5H5V19H13.18M11.21 15.83L9.25 13.47L6.5 17H13.03C13.14 15.54 13.73 14.22 14.64 13.19L13.96 12.29L11.21 15.83M19 13.5V12L16.75 14.25L19 16.5V15C20.38 15 21.5 16.12 21.5 17.5C21.5 17.9 21.41 18.28 21.24 18.62L22.33 19.71C22.75 19.08 23 18.32 23 17.5C23 15.29 21.21 13.5 19 13.5M19 20C17.62 20 16.5 18.88 16.5 17.5C16.5 17.1 16.59 16.72 16.76 16.38L15.67 15.29C15.25 15.92 15 16.68 15 17.5C15 19.71 16.79 21.5 19 21.5V23L21.25 20.75L19 18.5V20Z" />
</svg>

Before

Width:  |  Height:  |  Size: 989 B

+1 -309
View File
@@ -4,107 +4,6 @@
#licenses pre { margin: 1em 0 2em 0;} #licenses pre { margin: 1em 0 2em 0;}
</style> </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> <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> <small>Some code for compatibility with OSX is taken from lstein's repository.</small>
<pre> <pre>
@@ -183,213 +82,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
</pre> </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> <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> <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> <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, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
</pre> </pre>
+6 -6
View File
@@ -50,17 +50,17 @@ function dimensionChange(e, is_width, is_height) {
var scaledx = targetElement.naturalWidth * viewportscale; var scaledx = targetElement.naturalWidth * viewportscale;
var scaledy = targetElement.naturalHeight * viewportscale; var scaledy = targetElement.naturalHeight * viewportscale;
var cleintRectTop = (viewportOffset.top + window.scrollY); var clientRectTop = (viewportOffset.top + window.scrollY);
var cleintRectLeft = (viewportOffset.left + window.scrollX); var clientRectLeft = (viewportOffset.left + window.scrollX);
var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2); var clientRectCentreY = clientRectTop + (targetElement.clientHeight / 2);
var cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth / 2); var clientRectCentreX = clientRectLeft + (targetElement.clientWidth / 2);
var arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight); var arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight);
var arscaledx = currentWidth * arscale; var arscaledx = currentWidth * arscale;
var arscaledy = currentHeight * arscale; var arscaledy = currentHeight * arscale;
var arRectTop = cleintRectCentreY - (arscaledy / 2); var arRectTop = clientRectCentreY - (arscaledy / 2);
var arRectLeft = cleintRectCentreX - (arscaledx / 2); var arRectLeft = clientRectCentreX - (arscaledx / 2);
var arRectWidth = arscaledx; var arRectWidth = arscaledx;
var arRectHeight = arscaledy; var arRectHeight = arscaledy;
+18 -31
View File
@@ -8,9 +8,6 @@ var contextMenuInit = function() {
}; };
function showContextMenu(event, element, menuEntries) { 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'); let oldMenu = gradioApp().querySelector('#context-menu');
if (oldMenu) { if (oldMenu) {
oldMenu.remove(); oldMenu.remove();
@@ -23,10 +20,8 @@ var contextMenuInit = function() {
contextMenu.style.background = baseStyle.background; contextMenu.style.background = baseStyle.background;
contextMenu.style.color = baseStyle.color; contextMenu.style.color = baseStyle.color;
contextMenu.style.fontFamily = baseStyle.fontFamily; contextMenu.style.fontFamily = baseStyle.fontFamily;
contextMenu.style.top = posy + 'px'; contextMenu.style.top = event.pageY + 'px';
contextMenu.style.left = posx + 'px'; contextMenu.style.left = event.pageX + 'px';
const contextMenuList = document.createElement('ul'); const contextMenuList = document.createElement('ul');
contextMenuList.className = 'context-menu-items'; contextMenuList.className = 'context-menu-items';
@@ -43,21 +38,6 @@ var contextMenuInit = function() {
}); });
gradioApp().appendChild(contextMenu); 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) { function appendContextMenuOption(targetElementSelector, entryName, entryFunction) {
@@ -107,16 +87,23 @@ var contextMenuInit = function() {
oldMenu.remove(); oldMenu.remove();
} }
}); });
gradioApp().addEventListener("contextmenu", function(e) { ['contextmenu', 'touchstart'].forEach((eventType) => {
let oldMenu = gradioApp().querySelector('#context-menu'); gradioApp().addEventListener(eventType, function(e) {
if (oldMenu) { let ev = e;
oldMenu.remove(); if (eventType.startsWith('touch')) {
} if (e.touches.length !== 2) return;
menuSpecs.forEach(function(v, k) { ev = e.touches[0];
if (e.composedPath()[0].matches(k)) {
showContextMenu(e, e.composedPath()[0], v);
e.preventDefault();
} }
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; eventListenerApplied = true;
+32 -6
View File
@@ -56,6 +56,15 @@ function eventHasFiles(e) {
return false; return false;
} }
function isURL(url) {
try {
const _ = new URL(url);
return true;
} catch {
return false;
}
}
function dragDropTargetIsPrompt(target) { function dragDropTargetIsPrompt(target) {
if (target?.placeholder && target?.placeholder.indexOf("Prompt") >= 0) return true; if (target?.placeholder && target?.placeholder.indexOf("Prompt") >= 0) return true;
if (target?.parentNode?.parentNode?.className?.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'; e.dataTransfer.dropEffect = 'copy';
}); });
window.document.addEventListener('drop', e => { window.document.addEventListener('drop', async e => {
const target = e.composedPath()[0]; 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)) { if (dragDropTargetIsPrompt(target)) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); 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 files = e.dataTransfer.files;
const fileInput = imgParent.querySelector('input[type="file"]'); const fileInput = imgParent.querySelector('input[type="file"]');
if (fileInput) { if (eventHasFiles(e) && fileInput) {
fileInput.files = files; fileInput.files = files;
fileInput.dispatchEvent(new Event('change')); 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 const firstFreeImageField = visibleImageFields
.filter(el => el.querySelector('input[type=file]'))?.[0]; .filter(el => !el.querySelector('img'))?.[0];
dropReplaceImage( dropReplaceImage(
firstFreeImageField ? firstFreeImageField ?
+63 -27
View File
@@ -18,37 +18,43 @@ function keyupEditAttention(event) {
const before = text.substring(0, selectionStart); const before = text.substring(0, selectionStart);
let beforeParen = before.lastIndexOf(OPEN); let beforeParen = before.lastIndexOf(OPEN);
if (beforeParen == -1) return false; if (beforeParen == -1) return false;
let beforeParenClose = before.lastIndexOf(CLOSE);
while (beforeParenClose !== -1 && beforeParenClose > beforeParen) { let beforeClosingParen = before.lastIndexOf(CLOSE);
beforeParen = before.lastIndexOf(OPEN, beforeParen - 1); if (beforeClosingParen != -1 && beforeClosingParen > beforeParen) return false;
beforeParenClose = before.lastIndexOf(CLOSE, beforeParenClose - 1);
}
// Find closing parenthesis around current cursor // Find closing parenthesis around current cursor
const after = text.substring(selectionStart); const after = text.substring(selectionStart);
let afterParen = after.indexOf(CLOSE); let afterParen = after.indexOf(CLOSE);
if (afterParen == -1) return false; if (afterParen == -1) return false;
let afterParenOpen = after.indexOf(OPEN);
while (afterParenOpen !== -1 && afterParen > afterParenOpen) { let afterOpeningParen = after.indexOf(OPEN);
afterParen = after.indexOf(CLOSE, afterParen + 1); if (afterOpeningParen != -1 && afterOpeningParen < afterParen) return false;
afterParenOpen = after.indexOf(OPEN, afterParenOpen + 1);
}
if (beforeParen === -1 || afterParen === -1) return false;
// Set the selection to the text between the parenthesis // Set the selection to the text between the parenthesis
const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen); const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen);
const lastColon = parenContent.lastIndexOf(":"); if (/.*:-?[\d.]+/s.test(parenContent)) {
selectionStart = beforeParen + 1; const lastColon = parenContent.lastIndexOf(":");
selectionEnd = selectionStart + lastColon; selectionStart = beforeParen + 1;
selectionEnd = selectionStart + lastColon;
} else {
selectionStart = beforeParen + 1;
selectionEnd = selectionStart + parenContent.length;
}
target.setSelectionRange(selectionStart, selectionEnd); target.setSelectionRange(selectionStart, selectionEnd);
return true; return true;
} }
function selectCurrentWord() { function selectCurrentWord() {
if (selectionStart !== selectionEnd) return false; 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) { while (!delimiters.includes(text[selectionStart - 1]) && selectionStart > 0) {
selectionStart--; selectionStart--;
} }
@@ -58,12 +64,20 @@ function keyupEditAttention(event) {
selectionEnd++; selectionEnd++;
} }
// deselect surrounding whitespace
while (text[selectionStart] == " " && selectionStart < selectionEnd) {
selectionStart++;
}
while (text[selectionEnd - 1] == " " && selectionEnd > selectionStart) {
selectionEnd--;
}
target.setSelectionRange(selectionStart, selectionEnd); target.setSelectionRange(selectionStart, selectionEnd);
return true; return true;
} }
// If the user hasn't selected anything, let's select their current parenthesis block or word // If the user hasn't selected anything, let's select their current parenthesis block or word
if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')')) { if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')') && !selectCurrentParenthesisBlock('[', ']')) {
selectCurrentWord(); selectCurrentWord();
} }
@@ -71,40 +85,62 @@ function keyupEditAttention(event) {
var closeCharacter = ')'; var closeCharacter = ')';
var delta = opts.keyedit_precision_attention; 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 = '>'; closeCharacter = '>';
delta = opts.keyedit_precision_extra; 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 // do not include spaces at the end
while (selectionEnd > selectionStart && text[selectionEnd - 1] == ' ') { while (selectionEnd > selectionStart && text[selectionEnd - 1] == ' ') {
selectionEnd -= 1; selectionEnd--;
} }
if (selectionStart == selectionEnd) { if (selectionStart == selectionEnd) {
return; return;
} }
text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd); text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd);
selectionStart += 1; selectionStart++;
selectionEnd += 1; selectionEnd++;
} }
var end = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1; if (text[selectionEnd] != ':') return;
var weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + 1 + end)); var weightLength = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1;
var weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + weightLength));
if (isNaN(weight)) return; if (isNaN(weight)) return;
weight += isPlus ? delta : -delta; weight += isPlus ? delta : -delta;
weight = parseFloat(weight.toPrecision(12)); weight = parseFloat(weight.toPrecision(12));
if (String(weight).length == 1) weight += ".0"; if (Number.isInteger(weight)) weight += ".0";
if (closeCharacter == ')' && weight == 1) { if (closeCharacter == ')' && weight == 1) {
text = text.slice(0, selectionStart - 1) + text.slice(selectionStart, selectionEnd) + text.slice(selectionEnd + 5); var endParenPos = text.substring(selectionEnd).indexOf(')');
text = text.slice(0, selectionStart - 1) + text.slice(selectionStart, selectionEnd) + text.slice(selectionEnd + endParenPos + 1);
selectionStart--; selectionStart--;
selectionEnd--; selectionEnd--;
} else { } else {
text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + 1 + end - 1); text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + weightLength);
} }
target.focus(); target.focus();
+41
View File
@@ -0,0 +1,41 @@
/* alt+left/right moves text in prompt */
function keyupEditOrder(event) {
if (!opts.keyedit_move) return;
let target = event.originalTarget || event.composedPath()[0];
if (!target.matches("*:is([id*='_toprow'] [id*='_prompt'], .prompt) textarea")) return;
if (!event.altKey) return;
let isLeft = event.key == "ArrowLeft";
let isRight = event.key == "ArrowRight";
if (!isLeft && !isRight) return;
event.preventDefault();
let selectionStart = target.selectionStart;
let selectionEnd = target.selectionEnd;
let text = target.value;
let items = text.split(",");
let indexStart = (text.slice(0, selectionStart).match(/,/g) || []).length;
let indexEnd = (text.slice(0, selectionEnd).match(/,/g) || []).length;
let range = indexEnd - indexStart + 1;
if (isLeft && indexStart > 0) {
items.splice(indexStart - 1, 0, ...items.splice(indexStart, range));
target.value = items.join();
target.selectionStart = items.slice(0, indexStart - 1).join().length + (indexStart == 1 ? 0 : 1);
target.selectionEnd = items.slice(0, indexEnd).join().length;
} else if (isRight && indexEnd < items.length - 1) {
items.splice(indexStart + 1, 0, ...items.splice(indexStart, range));
target.value = items.join();
target.selectionStart = items.slice(0, indexStart + 1).join().length + 1;
target.selectionEnd = items.slice(0, indexEnd + 2).join().length;
}
event.preventDefault();
updateInput(target);
}
addEventListener('keydown', (event) => {
keyupEditOrder(event);
});
+24 -3
View File
@@ -2,8 +2,11 @@
function extensions_apply(_disabled_list, _update_list, disable_all) { function extensions_apply(_disabled_list, _update_list, disable_all) {
var disable = []; var disable = [];
var update = []; var update = [];
const extensions_input = gradioApp().querySelectorAll('#extensions input[type="checkbox"]');
gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x) { if (extensions_input.length == 0) {
throw Error("Extensions page not yet loaded.");
}
extensions_input.forEach(function(x) {
if (x.name.startsWith("enable_") && !x.checked) { if (x.name.startsWith("enable_") && !x.checked) {
disable.push(x.name.substring(7)); disable.push(x.name.substring(7));
} }
@@ -33,7 +36,7 @@ function extensions_check() {
var id = randomId(); var id = randomId();
requestProgress(id, gradioApp().getElementById('extensions_installed_top'), null, function() { requestProgress(id, gradioApp().getElementById('extensions_installed_html'), null, function() {
}); });
@@ -72,3 +75,21 @@ function config_state_confirm_restore(_, config_state_name, config_restore_type)
} }
return [confirmed, config_state_name, config_restore_type]; return [confirmed, config_state_name, config_restore_type];
} }
function toggle_all_extensions(event) {
gradioApp().querySelectorAll('#extensions .extension_toggle').forEach(function(checkbox_el) {
checkbox_el.checked = event.target.checked;
});
}
function toggle_extension() {
let all_extensions_toggled = true;
for (const checkbox_el of gradioApp().querySelectorAll('#extensions .extension_toggle')) {
if (!checkbox_el.checked) {
all_extensions_toggled = false;
break;
}
}
gradioApp().querySelector('#extensions .all_extensions_toggle').checked = all_extensions_toggled;
}
+578 -131
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) { 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) { function registerPrompt(tabname, id) {
var textarea = gradioApp().querySelector("#" + id + " > label > textarea"); var textarea = gradioApp().querySelector("#" + id + " > label > textarea");
@@ -105,39 +28,213 @@ function setupExtraNetworks() {
}); });
} }
registerPrompt('txt2img', 'txt2img_prompt'); var tabnav = gradioApp().querySelector('#' + tabname + '_extra_tabs > div.tab-nav');
registerPrompt('txt2img', 'txt2img_neg_prompt'); var controlsDiv = document.createElement('DIV');
registerPrompt('img2img', 'img2img_prompt'); controlsDiv.classList.add('extra-networks-controls-div');
registerPrompt('img2img', 'img2img_neg_prompt'); 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 promptContainer = gradioApp().getElementById(tabname + '_prompt_container');
var re_extranet_g = /\s+<([^:]+:[^:]+):[\d.]+>/g; 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) { if (showNegativePrompt && elem) {
var m = text.match(re_extranet); 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 replaced = false;
var newTextareaText; var newTextareaText;
var extraTextBeforeNet = opts.extra_networks_add_text_separator;
if (m) { if (m) {
var extraTextAfterNet = m[2];
var partToSearch = m[1]; var partToSearch = m[1];
newTextareaText = textarea.value.replaceAll(re_extranet_g, function(found) { var foundAtPosition = -1;
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) { if (m[1] == partToSearch) {
replaced = true; replaced = true;
foundAtPosition = pos;
return ""; return "";
} }
return found; return found;
}); });
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 { } else {
newTextareaText = textarea.value.replaceAll(new RegExp(text, "g"), function(found) { newTextareaText = textarea.value.replaceAll(new RegExp(`((?:${extraTextBeforeNet})?${text})`, "g"), "");
if (found == text) { replaced = (newTextareaText != textarea.value);
replaced = true;
return "";
}
return found;
});
} }
if (replaced) { if (replaced) {
@@ -148,14 +245,22 @@ function tryToRemoveExtraNetworkFromPrompt(textarea, text) {
return false; return false;
} }
function cardClicked(tabname, textToAdd, allowNegativePrompt) { function updatePromptArea(text, textArea, isNeg) {
var textarea = allowNegativePrompt ? activePromptTextarea[tabname] : gradioApp().querySelector("#" + tabname + "_prompt > label > textarea"); if (!tryToRemoveExtraNetworkFromPrompt(textArea, text, isNeg)) {
textArea.value = textArea.value + opts.extra_networks_add_text_separator + text;
if (!tryToRemoveExtraNetworkFromPrompt(textarea, textToAdd)) {
textarea.value = textarea.value + opts.extra_networks_add_text_separator + textToAdd;
} }
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) { function saveCardPreview(event, tabname, filename) {
@@ -171,8 +276,8 @@ function saveCardPreview(event, tabname, filename) {
event.preventDefault(); event.preventDefault();
} }
function extraNetworksSearchButton(tabs_id, event) { function extraNetworksSearchButton(tabname, extra_networks_tabname, event) {
var searchTextarea = gradioApp().querySelector("#" + tabs_id + ' > div > textarea'); var searchTextarea = gradioApp().querySelector("#" + tabname + "_" + extra_networks_tabname + "_extra_search");
var button = event.target; var button = event.target;
var text = button.classList.contains("search-all") ? "" : button.textContent.trim(); var text = button.classList.contains("search-all") ? "" : button.textContent.trim();
@@ -180,32 +285,211 @@ function extraNetworksSearchButton(tabs_id, event) {
updateInput(searchTextarea); 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 globalPopup = null;
var globalPopupInner = null; var globalPopupInner = null;
function closePopup() {
if (!globalPopup) return;
globalPopup.style.display = "none";
}
function popup(contents) { function popup(contents) {
if (!globalPopup) { if (!globalPopup) {
globalPopup = document.createElement('div'); globalPopup = document.createElement('div');
globalPopup.onclick = function() {
globalPopup.style.display = "none";
};
globalPopup.classList.add('global-popup'); globalPopup.classList.add('global-popup');
var close = document.createElement('div'); var close = document.createElement('div');
close.classList.add('global-popup-close'); close.classList.add('global-popup-close');
close.onclick = function() { close.addEventListener("click", closePopup);
globalPopup.style.display = "none";
};
close.title = "Close"; close.title = "Close";
globalPopup.appendChild(close); globalPopup.appendChild(close);
globalPopupInner = document.createElement('div'); globalPopupInner = document.createElement('div');
globalPopupInner.onclick = function(event) {
event.stopPropagation(); return false;
};
globalPopupInner.classList.add('global-popup-inner'); globalPopupInner.classList.add('global-popup-inner');
globalPopup.appendChild(globalPopupInner); globalPopup.appendChild(globalPopupInner);
gradioApp().appendChild(globalPopup); gradioApp().querySelector('.main').appendChild(globalPopup);
} }
globalPopupInner.innerHTML = ''; globalPopupInner.innerHTML = '';
@@ -214,12 +498,85 @@ function popup(contents) {
globalPopup.style.display = "flex"; 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) { 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'); var elem = document.createElement('pre');
elem.classList.add('popup-metadata'); elem.classList.add('popup-metadata');
elem.textContent = text; elem.textContent = text;
popup(elem); popup(elem);
return;
} }
function requestGet(url, data, handler, errorHandler) { function requestGet(url, data, handler, errorHandler) {
@@ -248,11 +605,18 @@ function requestGet(url, data, handler, errorHandler) {
xhr.send(js); 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() { var showError = function() {
extraNetworksShowMetadata("there was an error getting metadata"); 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) { requestGet("./sd_extra_networks/metadata", {page: extraPage, item: cardName}, function(data) {
if (data && data.metadata) { if (data && data.metadata) {
extraNetworksShowMetadata(data.metadata); extraNetworksShowMetadata(data.metadata);
@@ -263,3 +627,86 @@ function extraNetworksRequestMetadata(event, extraPage, cardName) {
event.stopPropagation(); event.stopPropagation();
} }
var extraPageUserMetadataEditors = {};
function extraNetworksEditUserMetadata(event, tabname, extraPage) {
var id = tabname + '_' + extraPage + '_edit_user_metadata';
var editor = extraPageUserMetadataEditors[id];
if (!editor) {
editor = {};
editor.page = gradioApp().getElementById(id);
editor.nameTextarea = gradioApp().querySelector("#" + id + "_name" + ' textarea');
editor.button = gradioApp().querySelector("#" + id + "_button");
extraPageUserMetadataEditors[id] = editor;
}
var cardName = event.target.parentElement.parentElement.getAttribute("data-name");
editor.nameTextarea.value = cardName;
updateInput(editor.nameTextarea);
editor.button.click();
popup(editor.page);
event.stopPropagation();
}
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(`#${tabname}_${page.replace(" ", "_")}_cards > .card[data-name="${name}"]`);
var newDiv = document.createElement('DIV');
newDiv.innerHTML = data.html;
var newCard = newDiv.firstElementChild;
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);
+13 -5
View File
@@ -15,7 +15,7 @@ var titles = {
"CFG Scale": "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results", "CFG Scale": "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results",
"Seed": "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result", "Seed": "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result",
"\u{1f3b2}\ufe0f": "Set seed to -1, which will cause a new random number to be used every time", "\u{1f3b2}\ufe0f": "Set seed to -1, which will cause a new random number to be used every time",
"\u267b\ufe0f": "Reuse seed from last generation, mostly useful if it was randomed", "\u267b\ufe0f": "Reuse seed from last generation, mostly useful if it was randomized",
"\u2199\ufe0f": "Read generation parameters from prompt or last generation if prompt is empty into user interface.", "\u2199\ufe0f": "Read generation parameters from prompt or last generation if prompt is empty into user interface.",
"\u{1f4c2}": "Open images output directory", "\u{1f4c2}": "Open images output directory",
"\u{1f4be}": "Save style", "\u{1f4be}": "Save style",
@@ -84,8 +84,6 @@ var titles = {
"Checkpoint name": "Loads weights from checkpoint before making images. You can either use hash or a part of filename (as seen in settings) for checkpoint name. Recommended to use with Y axis for less switching.", "Checkpoint name": "Loads weights from checkpoint before making images. You can either use hash or a part of filename (as seen in settings) for checkpoint name. Recommended to use with Y axis for less switching.",
"Inpainting conditioning mask strength": "Only applies to inpainting models. Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked, which is the default behaviour. 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes.", "Inpainting conditioning mask strength": "Only applies to inpainting models. Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked, which is the default behaviour. 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes.",
"vram": "Torch active: Peak amount of VRAM used by Torch during generation, excluding cached data.\nTorch reserved: Peak amount of VRAM allocated by Torch, including all active and cached data.\nSys VRAM: Peak amount of VRAM allocation across all applications / total GPU VRAM (peak utilization%).",
"Eta noise seed delta": "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.", "Eta noise seed delta": "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.",
"Filename word regex": "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.", "Filename word regex": "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.",
@@ -110,9 +108,8 @@ var titles = {
"Upscale by": "Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero.", "Upscale by": "Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero.",
"Resize width to": "Resizes image to this width. If 0, width is inferred from either of two nearby sliders.", "Resize width to": "Resizes image to this width. If 0, width is inferred from either of two nearby sliders.",
"Resize height to": "Resizes image to this height. If 0, height is inferred from either of two nearby sliders.", "Resize height to": "Resizes image to this height. If 0, height is inferred from either of two nearby sliders.",
"Multiplier for extra networks": "When adding extra network such as Hypernetwork or Lora to prompt, use this multiplier for it.",
"Discard weights with matching name": "Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights.", "Discard weights with matching name": "Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights.",
"Extra networks tab order": "Comma-separated list of tab names; tabs listed here will appear in the extra networks UI first and in order lsited.", "Extra networks tab order": "Comma-separated list of tab names; tabs listed here will appear in the extra networks UI first and in order listed.",
"Negative Guidance minimum sigma": "Skip negative prompt for steps where image is already mostly denoised; the higher this value, the more skips there will be; provides increased performance in exchange for minor quality reduction." "Negative Guidance minimum sigma": "Skip negative prompt for steps where image is already mostly denoised; the higher this value, the more skips there will be; provides increased performance in exchange for minor quality reduction."
}; };
@@ -193,3 +190,14 @@ onUiUpdate(function(mutationRecords) {
tooltipCheckTimer = setTimeout(processTooltipCheckNodes, 1000); 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;
}
}
}
});
+31 -17
View File
@@ -6,6 +6,8 @@ function closeModal() {
function showModal(event) { function showModal(event) {
const source = event.target || event.srcElement; const source = event.target || event.srcElement;
const modalImage = gradioApp().getElementById("modalImage"); 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"); const lb = gradioApp().getElementById("lightboxModal");
modalImage.src = source.src; modalImage.src = source.src;
if (modalImage.style.display === 'none') { if (modalImage.style.display === 'none') {
@@ -33,8 +35,11 @@ function updateOnBackgroundChange() {
const modalImage = gradioApp().getElementById("modalImage"); const modalImage = gradioApp().getElementById("modalImage");
if (modalImage && modalImage.offsetParent) { if (modalImage && modalImage.offsetParent) {
let currentButton = selected_gallery_button(); let currentButton = selected_gallery_button();
let preview = gradioApp().querySelectorAll('.livePreview > img');
if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) { 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; modalImage.src = currentButton.children[0].src;
if (modalImage.style.display === 'none') { if (modalImage.style.display === 'none') {
const modal = gradioApp().getElementById("lightboxModal"); const modal = gradioApp().getElementById("lightboxModal");
@@ -48,14 +53,7 @@ function modalImageSwitch(offset) {
var galleryButtons = all_gallery_buttons(); var galleryButtons = all_gallery_buttons();
if (galleryButtons.length > 1) { if (galleryButtons.length > 1) {
var currentButton = selected_gallery_button(); var result = selected_gallery_index();
var result = -1;
galleryButtons.forEach(function(v, i) {
if (v == currentButton) {
result = i;
}
});
if (result != -1) { if (result != -1) {
var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)]; var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)];
@@ -128,14 +126,15 @@ function setupImageForLightbox(e) {
e.style.cursor = 'pointer'; e.style.cursor = 'pointer';
e.style.userSelect = 'none'; 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. e.addEventListener('click', function(evt) {
// 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) {
if (!opts.js_modal_lightbox || evt.button != 0) return; if (!opts.js_modal_lightbox || evt.button != 0) return;
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed); modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed);
@@ -155,6 +154,13 @@ function modalZoomToggle(event) {
event.stopPropagation(); 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) { function modalTileImageToggle(event) {
const modalImage = gradioApp().getElementById("modalImage"); const modalImage = gradioApp().getElementById("modalImage");
const modal = gradioApp().getElementById("lightboxModal"); const modal = gradioApp().getElementById("lightboxModal");
@@ -212,6 +218,14 @@ document.addEventListener("DOMContentLoaded", function() {
modalSave.title = "Save Image(s)"; modalSave.title = "Save Image(s)";
modalControls.appendChild(modalSave); 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'); const modalClose = document.createElement('span');
modalClose.className = 'modalClose cursor'; modalClose.className = 'modalClose cursor';
modalClose.innerHTML = '&times;'; modalClose.innerHTML = '&times;';
+68
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);
}
});
+26
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}`);
}
}
+36 -7
View File
@@ -11,11 +11,11 @@ var ignore_ids_for_localization = {
train_hypernetwork: 'OPTION', train_hypernetwork: 'OPTION',
txt2img_styles: 'OPTION', txt2img_styles: 'OPTION',
img2img_styles: 'OPTION', img2img_styles: 'OPTION',
setting_random_artist_categories: 'SPAN', setting_random_artist_categories: 'OPTION',
setting_face_restoration_model: 'SPAN', setting_face_restoration_model: 'OPTION',
setting_realesrgan_enabled_models: 'SPAN', setting_realesrgan_enabled_models: 'OPTION',
extras_upscaler_1: 'SPAN', extras_upscaler_1: 'OPTION',
extras_upscaler_2: 'SPAN', extras_upscaler_2: 'OPTION',
}; };
var re_num = /^[.\d]+$/; 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() { function dumpTranslations() {
if (!hasLocalization()) { if (!hasLocalization()) {
// If we don't have any localization, // If we don't have any localization,
// we will not have traversed the app to find // we will not have traversed the app to find
// original_lines, so do that now. // original_lines, so do that now.
processNode(gradioApp()); localizeWholePage();
} }
var dumped = {}; var dumped = {};
if (localization.rtl) { 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, if (localization.rtl) { // if the language is from right to left,
(new MutationObserver((mutations, observer) => { // wait for the style to load (new MutationObserver((mutations, observer) => { // wait for the style to load
+6 -2
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; if (galleryPreviews == null) return;
@@ -26,7 +26,11 @@ onAfterUiUpdate(function() {
lastHeadImg = headImg; lastHeadImg = headImg;
// play notification sound if available // 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; if (document.hasFocus()) return;
+113 -92
View File
@@ -33,120 +33,141 @@ function createRow(table, cellName, items) {
return res; return res;
} }
function showProfile(path, cutoff = 0.05) { function createVisualizationTable(data, cutoff = 0, sort = "") {
requestGet(path, {}, function(data) { var table = document.createElement('table');
var table = document.createElement('table'); table.className = 'popup-table';
table.className = 'popup-table';
data.records['total'] = data.total; var keys = Object.keys(data);
var keys = Object.keys(data.records).sort(function(a, b) { if (sort === "number") {
return data.records[b] - data.records[a]; keys = keys.sort(function(a, b) {
return data[b] - data[a];
}); });
var items = keys.map(function(x) { } else {
return {key: x, parts: x.split('/'), time: data.records[x]}; 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) { if (sort === "number") {
return Math.max(a, b.parts.length); matching = matching.sort(function(a, b) {
}, 0); return b.value - a.value;
});
var cols = createRow(table, 'th', ['record', 'seconds']); } else {
cols[0].colSpan = maxLength; matching = matching.sort();
function arraysEqual(a, b) {
return !(a < b || b < a);
} }
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 cells = [];
var matching = items.filter(function(x) { for (var i = 0; i < maxLength; i++) {
return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent); cells.push(x.parts[i]);
}); }
var sorted = matching.sort(function(a, b) { cells.push(cutoff === 0 ? x.value : x.value.toFixed(3));
return b.time - a.time; var cols = createRow(table, 'td', cells);
}); for (i = 0; i < level; i++) {
var othersTime = 0; cols[i].className = 'muted';
var othersList = []; }
var othersRows = [];
var childrenRows = [];
sorted.forEach(function(x) {
var visible = x.time >= cutoff && !hide;
var cells = []; var tr = cols[0].parentNode;
for (var i = 0; i < maxLength; i++) { if (!visible) {
cells.push(x.parts[i]); tr.classList.add("hidden");
} }
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 (cutoff === 0 || x.value >= cutoff) {
if (!visible) { childrenRows.push(tr);
tr.classList.add("hidden"); } else {
} othersTime += x.value;
othersList.push(x.parts[level]);
if (x.time >= cutoff) { othersRows.push(tr);
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';
}
var children = addLevel(level + 1, parent.concat([x.parts[level]]), true);
if (children.length > 0) {
var cell = cols[level]; var cell = cols[level];
var tr = cell.parentNode;
var onclick = function() { var onclick = function() {
tr.classList.add("hidden");
cell.classList.remove("link"); cell.classList.remove("link");
cell.removeEventListener("click", onclick); cell.removeEventListener("click", onclick);
othersRows.forEach(function(x) { children.forEach(function(x) {
x.classList.remove("hidden"); x.classList.remove("hidden");
}); });
}; };
cell.title = othersList.join(", ");
cell.classList.add("link"); cell.classList.add("link");
cell.addEventListener("click", onclick); cell.addEventListener("click", onclick);
}
});
if (hide) { if (othersTime > 0) {
tr.classList.add("hidden"); var cells = [];
} for (var i = 0; i < maxLength; i++) {
cells.push(parent[i]);
childrenRows.push(tr); }
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); popup(table);
}); });
} }
+68 -30
View File
@@ -45,8 +45,15 @@ function formatTime(secs) {
} }
} }
var originalAppTitle = undefined;
onUiLoaded(function() {
originalAppTitle = document.title;
});
function setTitle(progress) { function setTitle(progress) {
var title = 'Stable Diffusion'; var title = originalAppTitle;
if (opts.show_progress_in_title && progress) { if (opts.show_progress_in_title && progress) {
title = '[' + progress.trim() + '] ' + title; title = '[' + progress.trim() + '] ' + title;
@@ -69,7 +76,26 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre
var dateStart = new Date(); var dateStart = new Date();
var wasEverActive = false; var wasEverActive = false;
var parentProgressbar = progressbarContainer.parentNode; 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'); var divProgress = document.createElement('div');
divProgress.className = 'progressDiv'; divProgress.className = 'progressDiv';
@@ -80,32 +106,28 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre
divProgress.appendChild(divInner); divProgress.appendChild(divInner);
parentProgressbar.insertBefore(divProgress, progressbarContainer); parentProgressbar.insertBefore(divProgress, progressbarContainer);
if (parentGallery) { var livePreview = null;
var livePreview = document.createElement('div');
livePreview.className = 'livePreview';
parentGallery.insertBefore(livePreview, gallery);
}
var removeProgressBar = function() { var removeProgressBar = function() {
releaseWakeLock();
if (!divProgress) return;
setTitle(""); setTitle("");
parentProgressbar.removeChild(divProgress); parentProgressbar.removeChild(divProgress);
if (parentGallery) parentGallery.removeChild(livePreview); if (gallery && livePreview) gallery.removeChild(livePreview);
atEnd(); atEnd();
divProgress = null;
}; };
var fun = function(id_task, id_live_preview) { var funProgress = function(id_task) {
request("./internal/progress", {id_task: id_task, id_live_preview: id_live_preview}, function(res) { requestWakeLock();
request("./internal/progress", {id_task: id_task, live_preview: false}, function(res) {
if (res.completed) { if (res.completed) {
removeProgressBar(); removeProgressBar();
return; return;
} }
var rect = progressbarContainer.getBoundingClientRect();
if (rect.width) {
divProgress.style.width = rect.width + "px";
}
let progressText = ""; let progressText = "";
divInner.style.width = ((res.progress || 0) * 100.0) + '%'; 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); progressText += " ETA: " + formatTime(res.eta);
} }
setTitle(progressText); setTitle(progressText);
if (res.textinfo && res.textinfo.indexOf("\n") == -1) { if (res.textinfo && res.textinfo.indexOf("\n") == -1) {
@@ -142,16 +163,33 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre
return; 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) { 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(); var img = new Image();
img.onload = function() { img.onload = function() {
if (!livePreview) {
livePreview = document.createElement('div');
livePreview.className = 'livePreview';
gallery.insertBefore(livePreview, gallery.firstElementChild);
}
livePreview.appendChild(img); livePreview.appendChild(img);
if (livePreview.childElementCount > 2) { if (livePreview.childElementCount > 2) {
livePreview.removeChild(livePreview.firstElementChild); livePreview.removeChild(livePreview.firstElementChild);
@@ -160,18 +198,18 @@ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgre
img.src = res.live_preview; img.src = res.live_preview;
} }
if (onProgress) {
onProgress(res);
}
setTimeout(() => { setTimeout(() => {
fun(id_task, res.id_live_preview); funLivePreview(id_task, res.id_live_preview);
}, opts.live_preview_refresh_period || 500); }, opts.live_preview_refresh_period || 500);
}, function() { }, function() {
removeProgressBar(); removeProgressBar();
}); });
}; };
fun(id_task, 0); funProgress(id_task, 0);
if (gallery) {
funLivePreview(id_task, 0);
}
} }
+205
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
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);
});
});
+31 -27
View File
@@ -1,10 +1,9 @@
let promptTokenCountDebounceTime = 800; let promptTokenCountUpdateFunctions = {};
let promptTokenCountTimeouts = {};
var promptTokenCountUpdateFunctions = {};
function update_txt2img_tokens(...args) { function update_txt2img_tokens(...args) {
// Called from Gradio // Called from Gradio
update_token_counter("txt2img_token_button"); update_token_counter("txt2img_token_button");
update_token_counter("txt2img_negative_token_button");
if (args.length == 2) { if (args.length == 2) {
return args[0]; return args[0];
} }
@@ -14,6 +13,7 @@ function update_txt2img_tokens(...args) {
function update_img2img_tokens(...args) { function update_img2img_tokens(...args) {
// Called from Gradio // Called from Gradio
update_token_counter("img2img_token_button"); update_token_counter("img2img_token_button");
update_token_counter("img2img_negative_token_button");
if (args.length == 2) { if (args.length == 2) {
return args[0]; return args[0];
} }
@@ -21,16 +21,7 @@ function update_img2img_tokens(...args) {
} }
function update_token_counter(button_id) { function update_token_counter(button_id) {
if (opts.disable_token_counters) { promptTokenCountUpdateFunctions[button_id]?.();
return;
}
if (promptTokenCountTimeouts[button_id]) {
clearTimeout(promptTokenCountTimeouts[button_id]);
}
promptTokenCountTimeouts[button_id] = setTimeout(
() => gradioApp().getElementById(button_id)?.click(),
promptTokenCountDebounceTime,
);
} }
@@ -57,11 +48,6 @@ function setupTokenCounting(id, id_counter, id_button) {
var counter = gradioApp().getElementById(id_counter); var counter = gradioApp().getElementById(id_counter);
var textarea = gradioApp().querySelector(`#${id} > label > textarea`); var textarea = gradioApp().querySelector(`#${id} > label > textarea`);
if (opts.disable_token_counters) {
counter.style.display = "none";
return;
}
if (counter.parentElement == prompt.parentElement) { if (counter.parentElement == prompt.parentElement) {
return; return;
} }
@@ -69,15 +55,33 @@ function setupTokenCounting(id, id_counter, id_button) {
prompt.parentElement.insertBefore(counter, prompt); prompt.parentElement.insertBefore(counter, prompt);
prompt.parentElement.style.position = "relative"; prompt.parentElement.style.position = "relative";
promptTokenCountUpdateFunctions[id] = function() { var func = onEdit(id, textarea, 800, function() {
update_token_counter(id_button); if (counter.classList.contains("token-counter-visible")) {
}; gradioApp().getElementById(id_button)?.click();
textarea.addEventListener("input", promptTokenCountUpdateFunctions[id]); }
});
promptTokenCountUpdateFunctions[id] = func;
promptTokenCountUpdateFunctions[id_button] = func;
} }
function setupTokenCounters() { function toggleTokenCountingVisibility(id, id_counter, id_button) {
setupTokenCounting('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button'); var counter = gradioApp().getElementById(id_counter);
setupTokenCounting('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button');
setupTokenCounting('img2img_prompt', 'img2img_token_counter', 'img2img_token_button'); counter.style.display = opts.disable_token_counters ? "none" : "block";
setupTokenCounting('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button'); 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);
});
+98 -49
View File
@@ -19,28 +19,19 @@ function all_gallery_buttons() {
} }
function selected_gallery_button() { function selected_gallery_button() {
var allCurrentButtons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery].gradio-gallery .thumbnail-item.thumbnail-small.selected'); return all_gallery_buttons().find(elem => elem.classList.contains('selected')) ?? null;
var visibleCurrentButton = null;
allCurrentButtons.forEach(function(elem) {
if (elem.parentElement.offsetParent) {
visibleCurrentButton = elem;
}
});
return visibleCurrentButton;
} }
function selected_gallery_index() { function selected_gallery_index() {
var buttons = all_gallery_buttons(); return all_gallery_buttons().findIndex(elem => elem.classList.contains('selected'));
var button = selected_gallery_button(); }
var result = -1; function gallery_container_buttons(gallery_container) {
buttons.forEach(function(v, i) { return gradioApp().querySelectorAll(`#${gallery_container} .thumbnail-item.thumbnail-small`);
if (v == button) { }
result = i;
}
});
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) { function extract_image_from_gallery(gallery) {
@@ -136,27 +127,35 @@ function create_submit_args(args) {
return res; 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) { function showSubmitButtons(tabname, show) {
gradioApp().getElementById(tabname + '_interrupt').style.display = show ? "none" : "block"; setSubmitButtonsVisibility(tabname, !show, !show, false);
gradioApp().getElementById(tabname + '_skip').style.display = show ? "none" : "block"; }
function showSubmitInterruptingPlaceholder(tabname) {
setSubmitButtonsVisibility(tabname, false, true, true);
} }
function showRestoreProgressButton(tabname, show) { function showRestoreProgressButton(tabname, show) {
var button = gradioApp().getElementById(tabname + "_restore_progress"); var button = gradioApp().getElementById(tabname + "_restore_progress");
if (!button) return; if (!button) return;
button.style.setProperty('display', show ? 'flex' : 'none', 'important');
button.style.display = show ? "flex" : "none";
} }
function submit() { function submit() {
showSubmitButtons('txt2img', false); showSubmitButtons('txt2img', false);
var id = randomId(); 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() { requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() {
showSubmitButtons('txt2img', true); showSubmitButtons('txt2img', true);
localStorage.removeItem("txt2img_task_id"); localRemove("txt2img_task_id");
showRestoreProgressButton('txt2img', false); showRestoreProgressButton('txt2img', false);
}); });
@@ -167,15 +166,23 @@ function submit() {
return res; return res;
} }
function submit_txt2img_upscale() {
var res = submit(...arguments);
res[2] = selected_gallery_index();
return res;
}
function submit_img2img() { function submit_img2img() {
showSubmitButtons('img2img', false); showSubmitButtons('img2img', false);
var id = randomId(); 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() { requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() {
showSubmitButtons('img2img', true); showSubmitButtons('img2img', true);
localStorage.removeItem("img2img_task_id"); localRemove("img2img_task_id");
showRestoreProgressButton('img2img', false); showRestoreProgressButton('img2img', false);
}); });
@@ -187,13 +194,29 @@ function submit_img2img() {
return res; 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() { function restoreProgressTxt2img() {
showRestoreProgressButton("txt2img", false); showRestoreProgressButton("txt2img", false);
var id = localStorage.getItem("txt2img_task_id"); var id = localGet("txt2img_task_id");
id = localStorage.getItem("txt2img_task_id");
if (id) { if (id) {
showSubmitInterruptingPlaceholder('txt2img');
requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() { requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() {
showSubmitButtons('txt2img', true); showSubmitButtons('txt2img', true);
}, null, 0); }, null, 0);
@@ -205,9 +228,10 @@ function restoreProgressTxt2img() {
function restoreProgressImg2img() { function restoreProgressImg2img() {
showRestoreProgressButton("img2img", false); showRestoreProgressButton("img2img", false);
var id = localStorage.getItem("img2img_task_id"); var id = localGet("img2img_task_id");
if (id) { if (id) {
showSubmitInterruptingPlaceholder('img2img');
requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() { requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() {
showSubmitButtons('img2img', true); showSubmitButtons('img2img', true);
}, null, 0); }, 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() { onUiLoaded(function() {
showRestoreProgressButton('txt2img', localStorage.getItem("txt2img_task_id")); showRestoreProgressButton('txt2img', localGet("txt2img_task_id"));
showRestoreProgressButton('img2img', localStorage.getItem("img2img_task_id")); showRestoreProgressButton('img2img', localGet("img2img_task_id"));
setupResolutionPasting('txt2img');
setupResolutionPasting('img2img');
}); });
@@ -259,6 +307,7 @@ onAfterUiUpdate(function() {
var jsdata = textarea.value; var jsdata = textarea.value;
opts = JSON.parse(jsdata); opts = JSON.parse(jsdata);
executeCallbacks(optionsAvailableCallbacks); /*global optionsAvailableCallbacks*/
executeCallbacks(optionsChangedCallbacks); /*global optionsChangedCallbacks*/ executeCallbacks(optionsChangedCallbacks); /*global optionsChangedCallbacks*/
Object.defineProperty(textarea, 'value', { Object.defineProperty(textarea, 'value', {
@@ -280,23 +329,6 @@ onAfterUiUpdate(function() {
}); });
json_elem.parentElement.style.display = "none"; 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() { onOptionsChanged(function() {
@@ -314,8 +346,8 @@ onOptionsChanged(function() {
let txt2img_textarea, img2img_textarea = undefined; let txt2img_textarea, img2img_textarea = undefined;
function restart_reload() { 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>'; document.body.innerHTML = '<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>';
var requestPing = function() { var requestPing = function() {
requestGet("./internal/ping", {}, function(data) { requestGet("./internal/ping", {}, function(data) {
location.reload(); location.reload();
@@ -385,3 +417,20 @@ function switchWidthHeight(tabname) {
updateInput(height); updateInput(height);
return []; 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;
}
+13 -3
View File
@@ -1,6 +1,5 @@
from modules import launch_utils from modules import launch_utils
args = launch_utils.args args = launch_utils.args
python = launch_utils.python python = launch_utils.python
git = launch_utils.git git = launch_utils.git
@@ -18,6 +17,7 @@ run_pip = launch_utils.run_pip
check_run_python = launch_utils.check_run_python check_run_python = launch_utils.check_run_python
git_clone = launch_utils.git_clone git_clone = launch_utils.git_clone
git_pull_recursive = launch_utils.git_pull_recursive git_pull_recursive = launch_utils.git_pull_recursive
list_extensions = launch_utils.list_extensions
run_extension_installer = launch_utils.run_extension_installer run_extension_installer = launch_utils.run_extension_installer
prepare_environment = launch_utils.prepare_environment prepare_environment = launch_utils.prepare_environment
configure_for_tests = launch_utils.configure_for_tests configure_for_tests = launch_utils.configure_for_tests
@@ -25,8 +25,18 @@ start = launch_utils.start
def main(): def main():
if not args.skip_prepare_environment: if args.dump_sysinfo:
prepare_environment() 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: if args.test_server:
configure_for_tests() configure_for_tests()
+339 -128
View File
@@ -1,8 +1,11 @@
import base64 import base64
import io import io
import os
import time import time
import datetime import datetime
import uvicorn import uvicorn
import ipaddress
import requests
import gradio as gr import gradio as gr
from threading import Lock from threading import Lock
from io import BytesIO from io import BytesIO
@@ -14,30 +17,21 @@ from fastapi.encoders import jsonable_encoder
from secrets import compare_digest from secrets import compare_digest
import modules.shared as shared import modules.shared as shared
from modules import sd_samplers, deepbooru, sd_hijack, images, scripts, ui, postprocessing, errors 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.api import models
from modules.shared import opts from modules.shared import opts
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
from modules.textual_inversion.textual_inversion import create_embedding, train_embedding 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 modules.hypernetworks.hypernetwork import create_hypernetwork, train_hypernetwork
from PIL import PngImagePlugin,Image from PIL import PngImagePlugin
from modules.sd_models import checkpoints_list, unload_model_weights, reload_model_weights
from modules.sd_vae import vae_dict
from modules.sd_models_config import find_checkpoint_config_near_filename from modules.sd_models_config import find_checkpoint_config_near_filename
from modules.realesrgan_model import get_realesrgan_models from modules.realesrgan_model import get_realesrgan_models
from modules import devices from modules import devices
from typing import Dict, List, Any from typing import Any
import piexif import piexif
import piexif.helper 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 upscaler_to_index(name: str):
try:
return [x.name.lower() for x in shared.sd_upscalers].index(name.lower())
except Exception as e:
raise HTTPException(status_code=400, detail=f"Invalid upscaler, needs to be one of these: {' , '.join([x.name for x in shared.sd_upscalers])}") from e
def script_name_to_index(name, scripts): def script_name_to_index(name, scripts):
try: try:
@@ -49,7 +43,7 @@ def script_name_to_index(name, scripts):
def validate_sampler_name(name): def validate_sampler_name(name):
config = sd_samplers.all_samplers_map.get(name, None) config = sd_samplers.all_samplers_map.get(name, None)
if config is 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 return name
@@ -61,11 +55,45 @@ def setUpscalers(req: dict):
return reqDict 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): 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/"): if encoding.startswith("data:image/"):
encoding = encoding.split(";")[1].split(",")[1] encoding = encoding.split(";")[1].split(",")[1]
try: try:
image = Image.open(BytesIO(base64.b64decode(encoding))) image = images.read(BytesIO(base64.b64decode(encoding)))
return image return image
except Exception as e: except Exception as e:
raise HTTPException(status_code=500, detail="Invalid encoded image") from e raise HTTPException(status_code=500, detail="Invalid encoded image") from e
@@ -73,7 +101,8 @@ def decode_base64_to_image(encoding):
def encode_pil_to_base64(image): def encode_pil_to_base64(image):
with io.BytesIO() as output_bytes: with io.BytesIO() as output_bytes:
if isinstance(image, str):
return image
if opts.samples_format.lower() == 'png': if opts.samples_format.lower() == 'png':
use_metadata = False use_metadata = False
metadata = PngImagePlugin.PngInfo() metadata = PngImagePlugin.PngInfo()
@@ -84,6 +113,8 @@ def encode_pil_to_base64(image):
image.save(output_bytes, format="PNG", pnginfo=(metadata if use_metadata else None), quality=opts.jpeg_quality) 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"): elif opts.samples_format.lower() in ("jpg", "jpeg", "webp"):
if image.mode in ("RGBA", "P"):
image = image.convert("RGB")
parameters = image.info.get('parameters', None) parameters = image.info.get('parameters', None)
exif_bytes = piexif.dump({ exif_bytes = piexif.dump({
"Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(parameters or "", encoding="unicode") } "Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(parameters or "", encoding="unicode") }
@@ -102,14 +133,16 @@ def encode_pil_to_base64(image):
def api_middleware(app: FastAPI): def api_middleware(app: FastAPI):
rich_available = True rich_available = False
try: try:
import anyio # importing just so it can be placed on silent list if os.environ.get('WEBUI_RICH_EXCEPTIONS', None) is not None:
import starlette # importing just so it can be placed on silent list import anyio # importing just so it can be placed on silent list
from rich.console import Console import starlette # importing just so it can be placed on silent list
console = Console() from rich.console import Console
console = Console()
rich_available = True
except Exception: except Exception:
rich_available = False pass
@app.middleware("http") @app.middleware("http")
async def log_and_time(req: Request, call_next): async def log_and_time(req: Request, call_next):
@@ -120,14 +153,14 @@ def api_middleware(app: FastAPI):
endpoint = req.scope.get('path', 'err') endpoint = req.scope.get('path', 'err')
if shared.cmd_opts.api_log and endpoint.startswith('/sdapi'): if shared.cmd_opts.api_log and endpoint.startswith('/sdapi'):
print('API {t} {code} {prot}/{ver} {method} {endpoint} {cli} {duration}'.format( print('API {t} {code} {prot}/{ver} {method} {endpoint} {cli} {duration}'.format(
t = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), t=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"),
code = res.status_code, code=res.status_code,
ver = req.scope.get('http_version', '0.0'), ver=req.scope.get('http_version', '0.0'),
cli = req.scope.get('client', ('0:0.0.0', 0))[0], cli=req.scope.get('client', ('0:0.0.0', 0))[0],
prot = req.scope.get('scheme', 'err'), prot=req.scope.get('scheme', 'err'),
method = req.scope.get('method', 'err'), method=req.scope.get('method', 'err'),
endpoint = endpoint, endpoint=endpoint,
duration = duration, duration=duration,
)) ))
return res return res
@@ -138,7 +171,7 @@ def api_middleware(app: FastAPI):
"body": vars(e).get('body', ''), "body": vars(e).get('body', ''),
"errors": str(e), "errors": str(e),
} }
if not isinstance(e, HTTPException): # do not print backtrace on known httpexceptions if not isinstance(e, HTTPException): # do not print backtrace on known httpexceptions
message = f"API error: {request.method}: {request.url} {err}" message = f"API error: {request.method}: {request.url} {err}"
if rich_available: if rich_available:
print(message) print(message)
@@ -187,31 +220,57 @@ 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.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/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/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/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/schedulers", self.get_schedulers, methods=["GET"], response_model=list[models.SchedulerItem])
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/upscalers", self.get_upscalers, methods=["GET"], response_model=list[models.UpscalerItem])
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/latent-upscale-modes", self.get_latent_upscale_modes, methods=["GET"], response_model=list[models.LatentUpscalerModeItem])
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/sd-models", self.get_sd_models, methods=["GET"], response_model=list[models.SDModelItem])
self.add_api_route("/sdapi/v1/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=List[models.HypernetworkItem]) 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/face-restorers", self.get_face_restorers, methods=["GET"], response_model=List[models.FaceRestorerItem]) self.add_api_route("/sdapi/v1/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=list[models.HypernetworkItem])
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/face-restorers", self.get_face_restorers, methods=["GET"], response_model=list[models.FaceRestorerItem])
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/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/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-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/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/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/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/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/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/unload-checkpoint", self.unloadapi, methods=["POST"])
self.add_api_route("/sdapi/v1/reload-checkpoint", self.reloadapi, 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/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"])
self.add_api_route("/sdapi/v1/server-restart", self.restart_webui, methods=["POST"])
self.add_api_route("/sdapi/v1/server-stop", self.stop_webui, methods=["POST"])
self.default_script_arg_txt2img = [] self.default_script_arg_txt2img = []
self.default_script_arg_img2img = [] 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): def add_api_route(self, path: str, endpoint, **kwargs):
if shared.cmd_opts.api_auth: if shared.cmd_opts.api_auth:
return self.app.add_api_route(path, endpoint, dependencies=[Depends(self.auth)], **kwargs) return self.app.add_api_route(path, endpoint, dependencies=[Depends(self.auth)], **kwargs)
@@ -273,8 +332,13 @@ class Api:
script_args[script.args_from:script.args_to] = ui_default_values script_args[script.args_from:script.args_to] = ui_default_values
return script_args 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() 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() # 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: if selectable_scripts:
script_args[selectable_scripts.args_from:selectable_scripts.args_to] = request.script_args script_args[selectable_scripts.args_from:selectable_scripts.args_to] = request.script_args
@@ -296,53 +360,138 @@ class Api:
script_args[alwayson_script.args_from + idx] = request.alwayson_scripts[alwayson_script_name]["args"][idx] script_args[alwayson_script.args_from + idx] = request.alwayson_scripts[alwayson_script_name]["args"][idx]
return script_args 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): def text2imgapi(self, txt2imgreq: models.StableDiffusionTxt2ImgProcessingAPI):
task_id = txt2imgreq.force_task_id or create_task_id("txt2img")
script_runner = scripts.scripts_txt2img script_runner = scripts.scripts_txt2img
if not script_runner.scripts:
script_runner.initialize_scripts(False) infotext_script_args = {}
ui.create_ui() self.apply_infotext(txt2imgreq, "txt2img", script_runner=script_runner, mentioned_script_args=infotext_script_args)
if not self.default_script_arg_txt2img:
self.default_script_arg_txt2img = self.init_default_script_args(script_runner)
selectable_scripts, selectable_script_idx = self.get_selectable_script(txt2imgreq.script_name, script_runner) 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 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_samples": not txt2imgreq.save_images,
"do_not_save_grid": not txt2imgreq.save_images, "do_not_save_grid": not txt2imgreq.save_images,
}) })
if populate.sampler_name: if populate.sampler_name:
populate.sampler_index = None # prevent a warning later on populate.sampler_index = None # prevent a warning later on
if not populate.scheduler and scheduler != "Automatic":
populate.scheduler = scheduler
args = vars(populate) args = vars(populate)
args.pop('script_name', None) args.pop('script_name', None)
args.pop('script_args', None) # will refeed them to the pipeline directly after initializing them args.pop('script_args', None) # will refeed them to the pipeline directly after initializing them
args.pop('alwayson_scripts', None) 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) send_images = args.pop('send_images', True)
args.pop('save_images', None) args.pop('save_images', None)
with self.queue_lock: add_task_to_queue(task_id)
p = StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **args)
p.scripts = script_runner
p.outpath_grids = opts.outdir_txt2img_grids
p.outpath_samples = opts.outdir_txt2img_samples
shared.state.begin() with self.queue_lock:
if selectable_scripts is not None: with closing(StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **args)) as p:
p.script_args = script_args p.is_api = True
processed = scripts.scripts_txt2img.run(p, *p.script_args) # Need to pass args as list here p.scripts = script_runner
else: p.outpath_grids = opts.outdir_txt2img_grids
p.script_args = tuple(script_args) # Need to pass args as tuple here p.outpath_samples = opts.outdir_txt2img_samples
processed = process_images(p)
shared.state.end() 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 [] b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
return models.TextToImageResponse(images=b64images, parameters=vars(txt2imgreq), info=processed.js()) return models.TextToImageResponse(images=b64images, parameters=vars(txt2imgreq), info=processed.js())
def img2imgapi(self, img2imgreq: models.StableDiffusionImg2ImgProcessingAPI): def img2imgapi(self, img2imgreq: models.StableDiffusionImg2ImgProcessingAPI):
task_id = img2imgreq.force_task_id or create_task_id("img2img")
init_images = img2imgreq.init_images init_images = img2imgreq.init_images
if init_images is None: if init_images is None:
raise HTTPException(status_code=404, detail="Init image not found") raise HTTPException(status_code=404, detail="Init image not found")
@@ -352,15 +501,15 @@ class Api:
mask = decode_base64_to_image(mask) mask = decode_base64_to_image(mask)
script_runner = scripts.scripts_img2img script_runner = scripts.scripts_img2img
if not script_runner.scripts:
script_runner.initialize_scripts(True) infotext_script_args = {}
ui.create_ui() self.apply_infotext(img2imgreq, "img2img", script_runner=script_runner, mentioned_script_args=infotext_script_args)
if not self.default_script_arg_img2img:
self.default_script_arg_img2img = self.init_default_script_args(script_runner)
selectable_scripts, selectable_script_idx = self.get_selectable_script(img2imgreq.script_name, script_runner) 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 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_samples": not img2imgreq.save_images,
"do_not_save_grid": not img2imgreq.save_images, "do_not_save_grid": not img2imgreq.save_images,
"mask": mask, "mask": mask,
@@ -368,32 +517,44 @@ class Api:
if populate.sampler_name: if populate.sampler_name:
populate.sampler_index = None # prevent a warning later on populate.sampler_index = None # prevent a warning later on
if not populate.scheduler and scheduler != "Automatic":
populate.scheduler = scheduler
args = vars(populate) 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('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_name', None)
args.pop('script_args', None) # will refeed them to the pipeline directly after initializing them args.pop('script_args', None) # will refeed them to the pipeline directly after initializing them
args.pop('alwayson_scripts', None) 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) send_images = args.pop('send_images', True)
args.pop('save_images', None) args.pop('save_images', None)
with self.queue_lock: add_task_to_queue(task_id)
p = StableDiffusionProcessingImg2Img(sd_model=shared.sd_model, **args)
p.init_images = [decode_base64_to_image(x) for x in init_images]
p.scripts = script_runner
p.outpath_grids = opts.outdir_img2img_grids
p.outpath_samples = opts.outdir_img2img_samples
shared.state.begin() with self.queue_lock:
if selectable_scripts is not None: with closing(StableDiffusionProcessingImg2Img(sd_model=shared.sd_model, **args)) as p:
p.script_args = script_args p.init_images = [decode_base64_to_image(x) for x in init_images]
processed = scripts.scripts_img2img.run(p, *p.script_args) # Need to pass args as list here p.is_api = True
else: p.scripts = script_runner
p.script_args = tuple(script_args) # Need to pass args as tuple here p.outpath_grids = opts.outdir_img2img_grids
processed = process_images(p) p.outpath_samples = opts.outdir_img2img_samples
shared.state.end()
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 [] b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
@@ -425,9 +586,6 @@ class Api:
return models.ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1]) return models.ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1])
def pnginfoapi(self, req: models.PNGInfoRequest): def pnginfoapi(self, req: models.PNGInfoRequest):
if(not req.image.strip()):
return models.PNGInfoResponse(info="")
image = decode_base64_to_image(req.image.strip()) image = decode_base64_to_image(req.image.strip())
if image is None: if image is None:
return models.PNGInfoResponse(info="") return models.PNGInfoResponse(info="")
@@ -436,9 +594,10 @@ class Api:
if geninfo is None: if geninfo is None:
geninfo = "" 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()): def progressapi(self, req: models.ProgressRequest = Depends()):
# copy from check_progress_call of ui.py # copy from check_progress_call of ui.py
@@ -466,7 +625,7 @@ class Api:
if shared.state.current_image and not req.skip_current_image: if shared.state.current_image and not req.skip_current_image:
current_image = encode_pil_to_base64(shared.state.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): def interrogateapi(self, interrogatereq: models.InterrogateRequest):
image_b64 = interrogatereq.image image_b64 = interrogatereq.image
@@ -493,12 +652,12 @@ class Api:
return {} return {}
def unloadapi(self): def unloadapi(self):
unload_model_weights() sd_models.unload_model_weights()
return {} return {}
def reloadapi(self): def reloadapi(self):
reload_model_weights() sd_models.send_model_to_device(shared.sd_model)
return {} return {}
@@ -516,9 +675,13 @@ class Api:
return options 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 sd_models.checkpoint_aliases:
raise RuntimeError(f"model {checkpoint_name!r} not found")
for k, v in req.items(): 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) shared.opts.save(shared.config_filename)
return return
@@ -529,6 +692,17 @@ class Api:
def get_samplers(self): def get_samplers(self):
return [{"name": sampler[0], "aliases":sampler[2], "options":sampler[3]} for sampler in sd_samplers.all_samplers] 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): def get_upscalers(self):
return [ return [
{ {
@@ -550,10 +724,12 @@ class Api:
] ]
def get_sd_models(self): 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): 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): def get_hypernetworks(self):
return [{"name": name, "path": shared.hypernetworks[name]} for name in shared.hypernetworks] return [{"name": name, "path": shared.hypernetworks[name]} for name in shared.hypernetworks]
@@ -592,49 +768,43 @@ class Api:
"skipped": convert_embeddings(db.skipped_embeddings), "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): def refresh_checkpoints(self):
shared.refresh_checkpoints() 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): def create_embedding(self, args: dict):
try: try:
shared.state.begin() shared.state.begin(job="create_embedding")
filename = create_embedding(**args) # create empty embedding filename = create_embedding(**args) # create empty embedding
sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings() # reload embeddings so new one can be immediately used sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings() # reload embeddings so new one can be immediately used
shared.state.end()
return models.CreateResponse(info=f"create embedding filename: {filename}") return models.CreateResponse(info=f"create embedding filename: {filename}")
except AssertionError as e: except AssertionError as e:
shared.state.end()
return models.TrainResponse(info=f"create embedding error: {e}") return models.TrainResponse(info=f"create embedding error: {e}")
finally:
shared.state.end()
def create_hypernetwork(self, args: dict): def create_hypernetwork(self, args: dict):
try: try:
shared.state.begin() shared.state.begin(job="create_hypernetwork")
filename = create_hypernetwork(**args) # create empty embedding filename = create_hypernetwork(**args) # create empty embedding
shared.state.end()
return models.CreateResponse(info=f"create hypernetwork filename: {filename}") return models.CreateResponse(info=f"create hypernetwork filename: {filename}")
except AssertionError as e: except AssertionError as e:
shared.state.end()
return models.TrainResponse(info=f"create hypernetwork error: {e}") return models.TrainResponse(info=f"create hypernetwork error: {e}")
finally:
def preprocess(self, args: dict):
try:
shared.state.begin()
preprocess(**args) # quick operation unless blip/booru interrogation is enabled
shared.state.end() shared.state.end()
return models.PreprocessResponse(info = 'preprocess complete')
except KeyError as e:
shared.state.end()
return models.PreprocessResponse(info=f"preprocess error: invalid token: {e}")
except AssertionError as e:
shared.state.end()
return models.PreprocessResponse(info=f"preprocess error: {e}")
except FileNotFoundError as e:
shared.state.end()
return models.PreprocessResponse(info=f'preprocess error: {e}')
def train_embedding(self, args: dict): def train_embedding(self, args: dict):
try: try:
shared.state.begin() shared.state.begin(job="train_embedding")
apply_optimizations = shared.opts.training_xattention_optimizations apply_optimizations = shared.opts.training_xattention_optimizations
error = None error = None
filename = '' filename = ''
@@ -647,15 +817,15 @@ class Api:
finally: finally:
if not apply_optimizations: if not apply_optimizations:
sd_hijack.apply_optimizations() sd_hijack.apply_optimizations()
shared.state.end()
return models.TrainResponse(info=f"train embedding complete: filename: {filename} error: {error}") return models.TrainResponse(info=f"train embedding complete: filename: {filename} error: {error}")
except AssertionError as msg: except Exception as msg:
shared.state.end()
return models.TrainResponse(info=f"train embedding error: {msg}") return models.TrainResponse(info=f"train embedding error: {msg}")
finally:
shared.state.end()
def train_hypernetwork(self, args: dict): def train_hypernetwork(self, args: dict):
try: try:
shared.state.begin() shared.state.begin(job="train_hypernetwork")
shared.loaded_hypernetworks = [] shared.loaded_hypernetworks = []
apply_optimizations = shared.opts.training_xattention_optimizations apply_optimizations = shared.opts.training_xattention_optimizations
error = None error = None
@@ -673,9 +843,10 @@ class Api:
sd_hijack.apply_optimizations() sd_hijack.apply_optimizations()
shared.state.end() shared.state.end()
return models.TrainResponse(info=f"train embedding complete: filename: {filename} error: {error}") return models.TrainResponse(info=f"train embedding complete: filename: {filename} error: {error}")
except AssertionError: except Exception as exc:
return models.TrainResponse(info=f"train embedding error: {exc}")
finally:
shared.state.end() shared.state.end()
return models.TrainResponse(info=f"train embedding error: {error}")
def get_memory(self): def get_memory(self):
try: try:
@@ -712,6 +883,46 @@ class Api:
cuda = {'error': f'{err}'} cuda = {'error': f'{err}'}
return models.MemoryResponse(ram=ram, cuda=cuda) return models.MemoryResponse(ram=ram, cuda=cuda)
def launch(self, server_name, port): 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) self.app.include_router(self.router)
uvicorn.run(self.app, host=server_name, port=port, timeout_keep_alive=0) 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()
def restart_webui(self):
if restart.is_restartable():
restart.restart_program()
return Response(status_code=501)
def stop_webui(request):
shared.state.server_command = "stop"
return Response("Stopping.")
+43 -30
View File
@@ -1,11 +1,10 @@
import inspect import inspect
from pydantic import BaseModel, Field, create_model from pydantic import BaseModel, Field, create_model
from typing import Any, Optional from typing import Any, Optional, Literal
from typing_extensions import Literal
from inflection import underscore from inflection import underscore
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img
from modules.shared import sd_upscalers, opts, parser from modules.shared import sd_upscalers, opts, parser
from typing import Dict, List
API_NOT_ALLOWED = [ API_NOT_ALLOWED = [
"self", "self",
@@ -49,10 +48,12 @@ class PydanticModelGenerator:
additional_fields = None, additional_fields = None,
): ):
def field_type_generator(k, v): 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 field_type = v.annotation
if field_type == 'Image':
# images are sent as base64 strings via API
field_type = 'str'
return Optional[field_type] return Optional[field_type]
def merge_class_params(class_): def merge_class_params(class_):
@@ -62,7 +63,6 @@ class PydanticModelGenerator:
parameters = {**parameters, **inspect.signature(classes.__init__).parameters} parameters = {**parameters, **inspect.signature(classes.__init__).parameters}
return parameters return parameters
self._model_name = model_name self._model_name = model_name
self._class_data = merge_class_params(class_instance) self._class_data = merge_class_params(class_instance)
@@ -71,7 +71,7 @@ class PydanticModelGenerator:
field=underscore(k), field=underscore(k),
field_alias=k, field_alias=k,
field_type=field_type_generator(k, v), 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 for (k,v) in self._class_data.items() if k not in API_NOT_ALLOWED
] ]
@@ -107,6 +107,8 @@ StableDiffusionTxt2ImgProcessingAPI = PydanticModelGenerator(
{"key": "send_images", "type": bool, "default": True}, {"key": "send_images", "type": bool, "default": True},
{"key": "save_images", "type": bool, "default": False}, {"key": "save_images", "type": bool, "default": False},
{"key": "alwayson_scripts", "type": dict, "default": {}}, {"key": "alwayson_scripts", "type": dict, "default": {}},
{"key": "force_task_id", "type": str, "default": None},
{"key": "infotext", "type": str, "default": None},
] ]
).generate_model() ).generate_model()
@@ -124,16 +126,18 @@ StableDiffusionImg2ImgProcessingAPI = PydanticModelGenerator(
{"key": "send_images", "type": bool, "default": True}, {"key": "send_images", "type": bool, "default": True},
{"key": "save_images", "type": bool, "default": False}, {"key": "save_images", "type": bool, "default": False},
{"key": "alwayson_scripts", "type": dict, "default": {}}, {"key": "alwayson_scripts", "type": dict, "default": {}},
{"key": "force_task_id", "type": str, "default": None},
{"key": "infotext", "type": str, "default": None},
] ]
).generate_model() ).generate_model()
class TextToImageResponse(BaseModel): 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 parameters: dict
info: str info: str
class ImageToImageResponse(BaseModel): 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 parameters: dict
info: str info: str
@@ -143,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.") 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_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.") 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_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_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?") upscaling_crop: bool = Field(default=True, title="Crop to fit", description="Should the upscaler crop the image to fit in the chosen size?")
@@ -166,17 +170,18 @@ class FileData(BaseModel):
name: str = Field(title="File name") name: str = Field(title="File name")
class ExtrasBatchImagesRequest(ExtrasBaseRequest): 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): 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): class PNGInfoRequest(BaseModel):
image: str = Field(title="Image", description="The base64 encoded PNG image") image: str = Field(title="Image", description="The base64 encoded PNG image")
class PNGInfoResponse(BaseModel): class PNGInfoResponse(BaseModel):
info: str = Field(title="Image info", description="A string with the parameters used to generate the image") 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): class ProgressRequest(BaseModel):
skip_current_image: bool = Field(default=False, title="Skip current image", description="Skip current image serialization") skip_current_image: bool = Field(default=False, title="Skip current image", description="Skip current image serialization")
@@ -201,17 +206,13 @@ class TrainResponse(BaseModel):
class CreateResponse(BaseModel): class CreateResponse(BaseModel):
info: str = Field(title="Create info", description="Response string from create embedding or hypernetwork task.") 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 = {} fields = {}
for key, metadata in opts.data_labels.items(): for key, metadata in opts.data_labels.items():
value = opts.data.get(key) value = opts.data.get(key)
optType = opts.typemap.get(type(metadata.default), type(value)) optType = opts.typemap.get(type(metadata.default), type(metadata.default)) if metadata.default else Any
if (metadata is not None): if metadata is not None:
fields.update({key: (Optional[optType], Field( fields.update({key: (Optional[optType], Field(default=metadata.default, description=metadata.label))})
default=metadata.default ,description=metadata.label))})
else: else:
fields.update({key: (Optional[optType], Field())}) fields.update({key: (Optional[optType], Field())})
@@ -231,8 +232,15 @@ FlagsModel = create_model("Flags", **flags)
class SamplerItem(BaseModel): class SamplerItem(BaseModel):
name: str = Field(title="Name") name: str = Field(title="Name")
aliases: List[str] = Field(title="Aliases") aliases: list[str] = Field(title="Aliases")
options: Dict[str, str] = Field(title="Options") 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): class UpscalerItem(BaseModel):
name: str = Field(title="Name") name: str = Field(title="Name")
@@ -274,10 +282,6 @@ class PromptStyleItem(BaseModel):
prompt: Optional[str] = Field(title="Prompt") prompt: Optional[str] = Field(title="Prompt")
negative_prompt: Optional[str] = Field(title="Negative Prompt") negative_prompt: Optional[str] = Field(title="Negative Prompt")
class ArtistItem(BaseModel):
name: str = Field(title="Name")
score: float = Field(title="Score")
category: str = Field(title="Category")
class EmbeddingItem(BaseModel): class EmbeddingItem(BaseModel):
step: Optional[int] = Field(title="Step", description="The number of steps that were used to train this embedding, if available") step: Optional[int] = Field(title="Step", description="The number of steps that were used to train this embedding, if available")
@@ -287,8 +291,8 @@ class EmbeddingItem(BaseModel):
vectors: int = Field(title="Vectors", description="The number of vectors in the embedding") vectors: int = Field(title="Vectors", description="The number of vectors in the embedding")
class EmbeddingsResponse(BaseModel): class EmbeddingsResponse(BaseModel):
loaded: Dict[str, EmbeddingItem] = Field(title="Loaded", description="Embeddings loaded for the current model") 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)") skipped: dict[str, EmbeddingItem] = Field(title="Skipped", description="Embeddings skipped for the current model (likely due to architecture incompatibility)")
class MemoryResponse(BaseModel): class MemoryResponse(BaseModel):
ram: dict = Field(title="RAM", description="System memory stats") ram: dict = Field(title="RAM", description="System memory stats")
@@ -306,11 +310,20 @@ class ScriptArg(BaseModel):
minimum: Optional[Any] = Field(default=None, title="Minimum", description="Minimum allowed value for the argumentin UI") 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") 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") 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): class ScriptInfo(BaseModel):
name: str = Field(default=None, title="Name", description="Script name") 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_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") 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")
+123
View File
@@ -0,0 +1,123 @@
import json
import os
import os.path
import threading
import diskcache
import tqdm
from modules.paths import data_path, script_path
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()
def dump_cache():
"""old function for dumping cache to disk; does nothing since diskcache."""
pass
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
)
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
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):
"""
Retrieves or initializes a cache for a specific subsection.
Parameters:
subsection (str): The subsection identifier for the cache.
Returns:
diskcache.Cache: The cache data for the specified subsection.
"""
cache_obj = caches.get(subsection)
if not cache_obj:
with cache_lock:
if not os.path.exists(cache_dir) and os.path.isfile(cache_filename):
convert_old_cached_data()
cache_obj = caches.get(subsection)
if not cache_obj:
cache_obj = make_cache(subsection)
caches[subsection] = cache_obj
return cache_obj
def cached_data_for_file(subsection, title, filename, func):
"""
Retrieves or generates data for a specific file, using a caching mechanism.
Parameters:
subsection (str): The subsection of the cache to use.
title (str): The title of the data entry in the subsection of the cache.
filename (str): The path to the file to be checked for modifications.
func (callable): A function that generates the data if it is not available in the cache.
Returns:
dict or None: The cached or generated data, or None if data generation fails.
The `cached_data_for_file` function implements a caching mechanism for data stored in files.
It checks if the data associated with the given `title` is present in the cache and compares the
modification time of the file with the cached modification time. If the file has been modified,
the cache is considered invalid and the data is regenerated using the provided `func`.
Otherwise, the cached data is returned.
If the data generation fails, None is returned to indicate the failure. Otherwise, the generated
or cached data is returned as a dictionary.
"""
existing_cache = cache(subsection)
ondisk_mtime = os.path.getmtime(filename)
entry = existing_cache.get(title)
if entry:
cached_mtime = entry.get("mtime", 0)
if ondisk_mtime > cached_mtime:
entry = None
if not entry or 'value' not in entry:
value = func()
if value is None:
return None
entry = {'mtime': ondisk_mtime, 'value': value}
existing_cache[title] = entry
dump_cache()
return entry['value']
+43 -15
View File
@@ -1,10 +1,11 @@
import os.path
from functools import wraps
import html import html
import threading
import time 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): def wrap_queued_call(func):
@@ -18,6 +19,7 @@ def wrap_queued_call(func):
def wrap_gradio_gpu_call(func, extra_outputs=None): def wrap_gradio_gpu_call(func, extra_outputs=None):
@wraps(func)
def f(*args, **kwargs): def f(*args, **kwargs):
# if the first argument is a string that says "task(...)", it is treated as a job id # if the first argument is a string that says "task(...)", it is treated as a job id
@@ -28,7 +30,7 @@ def wrap_gradio_gpu_call(func, extra_outputs=None):
id_task = None id_task = None
with queue_lock: with queue_lock:
shared.state.begin() shared.state.begin(job=id_task)
progress.start_task(id_task) progress.start_task(id_task)
try: try:
@@ -45,6 +47,23 @@ def wrap_gradio_gpu_call(func, extra_outputs=None):
def wrap_gradio_call(func, extra_outputs=None, add_stats=False): 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): 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 run_memmon = shared.opts.memmon_poll_rate > 0 and not shared.mem_mon.disabled and add_stats
if run_memmon: if run_memmon:
@@ -63,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)" 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) errors.report(f"{message}\n{arg_str}", exc_info=True)
shared.state.job = ""
shared.state.job_count = 0
if extra_outputs_array is None: if extra_outputs_array is None:
extra_outputs_array = [None, ''] extra_outputs_array = [None, '']
error_message = f'{type(e).__name__}: {e}' error_message = f'{type(e).__name__}: {e}'
res = extra_outputs_array + [f"<div class='error'>{html.escape(error_message)}</div>"] res = extra_outputs_array + [f"<div class='error'>{html.escape(error_message)}</div>"]
shared.state.skipped = False devices.torch_gc()
shared.state.interrupted = False
shared.state.job_count = 0
if not add_stats: if not add_stats:
return tuple(res) return tuple(res)
@@ -82,9 +96,9 @@ def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
elapsed = time.perf_counter() - t elapsed = time.perf_counter() - t
elapsed_m = int(elapsed // 60) elapsed_m = int(elapsed // 60)
elapsed_s = elapsed % 60 elapsed_s = elapsed % 60
elapsed_text = f"{elapsed_s:.2f}s" elapsed_text = f"{elapsed_s:.1f} sec."
if elapsed_m > 0: if elapsed_m > 0:
elapsed_text = f"{elapsed_m}m "+elapsed_text elapsed_text = f"{elapsed_m} min. "+elapsed_text
if run_memmon: if run_memmon:
mem_stats = {k: -(v//-(1024*1024)) for k, v in shared.mem_mon.stop().items()} mem_stats = {k: -(v//-(1024*1024)) for k, v in shared.mem_mon.stop().items()}
@@ -92,15 +106,29 @@ def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
reserved_peak = mem_stats['reserved_peak'] reserved_peak = mem_stats['reserved_peak']
sys_peak = mem_stats['system_peak'] sys_peak = mem_stats['system_peak']
sys_total = mem_stats['total'] sys_total = mem_stats['total']
sys_pct = round(sys_peak/max(sys_total, 1) * 100, 2) sys_pct = sys_peak/max(sys_total, 1) * 100
vram_html = f"<p class='vram'>Torch active/reserved: {active_peak}/{reserved_peak} MiB, <wbr>Sys VRAM: {sys_peak}/{sys_total} MiB ({sys_pct}%)</p>" toltip_a = "Active: peak amount of video memory used during generation (excluding cached data)"
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>"
text_sys = f"<abbr title='{toltip_sys}'>Sys</abbr>: <span class='measurement'>{sys_peak/1024:.1f}/{sys_total/1024:g} GB</span> ({sys_pct:.1f}%)"
vram_html = f"<p class='vram'>{text_a}, <wbr>{text_r}, <wbr>{text_sys}</p>"
else: else:
vram_html = '' 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 # last item is always HTML
res[-1] += f"<div class='performance'><p class='time'>Time taken: <wbr>{elapsed_text}</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 tuple(res)
return f return f
+48 -29
View File
@@ -1,7 +1,7 @@
import argparse import argparse
import json import json
import os 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() parser = argparse.ArgumentParser()
@@ -13,42 +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("--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("--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("--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-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("--skip-install", action='store_true', help="launch.py argument: skip installation of packages")
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("--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("--config", type=str, default=sd_default_config, help="path to config which constructs model",) parser.add_argument("--loglevel", type=str, help="log level; one of: CRITICAL, ERROR, WARNING, INFO, DEBUG", default=None)
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("--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("--ckpt-dir", type=str, default=None, help="Path to directory with stable diffusion checkpoints") 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("--vae-dir", type=str, default=None, help="Path to directory with VAE files") parser.add_argument("--models-dir", type=normalized_filepath, default=None, help="base path where models are stored; overrides --data-dir")
parser.add_argument("--gfpgan-dir", type=str, help="GFPGAN directory", default=('./src/gfpgan' if os.path.exists('./src/gfpgan') else './GFPGAN')) parser.add_argument("--config", type=normalized_filepath, default=sd_default_config, help="path to config which constructs model",)
parser.add_argument("--gfpgan-model", type=str, help="GFPGAN model file name", default=None) 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", 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-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("--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("--max-batch-count", type=int, default=16, help="does not do anything")
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("--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=str, default=os.path.join(script_path, 'textual_inversion_templates'), help="directory with textual inversion templates") 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=str, default=os.path.join(models_path, 'hypernetworks'), help="hypernetwork directory") parser.add_argument("--hypernetwork-dir", type=normalized_filepath, 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("--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("--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", 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("--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("--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("--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("--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("--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", 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-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("--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("--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("--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=str, help="Path to directory with GFPGAN model file(s).", default=os.path.join(models_path, 'GFPGAN')) 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=str, help="Path to directory with ESRGAN model file(s).", default=os.path.join(models_path, 'ESRGAN')) 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=str, help="Path to directory with BSRGAN model file(s).", default=os.path.join(models_path, 'BSRGAN')) 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=str, help="Path to directory with RealESRGAN model file(s).", default=os.path.join(models_path, 'RealESRGAN')) 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("--clip-models-path", type=str, help="Path to directory with CLIP model file(s).", default=None) 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("--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("--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)") 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)")
@@ -65,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-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("--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-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("--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("--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("--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("--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("--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("--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-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", 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-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-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("--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("--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("--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("--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("--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("--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=str, help='Checkpoint to use as VAE; setting this argument disables all settings related to VAE', default=None) 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("--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", 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) 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)
@@ -101,9 +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("--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("--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("--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("--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-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("--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('--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")
-276
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
-435
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)
+49 -123
View File
@@ -1,138 +1,64 @@
import os from __future__ import annotations
import logging
import cv2
import torch import torch
import modules.face_restoration from modules import (
import modules.shared devices,
from modules import shared, devices, modelloader, errors errors,
from modules.paths import models_path 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_url = 'https://github.com/sczhou/CodeFormer/releases/download/v0.1.0/codeformer.pth'
model_download_name = 'codeformer-v0.1.0.pth'
have_codeformer = False # used by e.g. postprocessing_codeformer.py
codeformer = None codeformer: face_restoration.FaceRestoration | None = None
def setup_model(dirname): class FaceRestorerCodeFormer(face_restoration_utils.CommonFaceRestoration):
global model_path def name(self):
if not os.path.exists(model_path): return "CodeFormer"
os.makedirs(model_path)
path = modules.paths.paths.get("CodeFormer", None) def load_net(self) -> torch.Module:
if path is None: for model_path in modelloader.load_models(
return 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: 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
torch.cuda.empty_cache()
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 have_codeformer
have_codeformer = True
global codeformer
codeformer = FaceRestorerCodeFormer(dirname) codeformer = FaceRestorerCodeFormer(dirname)
shared.face_restorers.append(codeformer) shared.face_restorers.append(codeformer)
except Exception: except Exception:
errors.report("Error setting up CodeFormer", exc_info=True) errors.report("Error setting up CodeFormer", exc_info=True)
# sys.path = stored_sys_path
+10 -9
View File
@@ -4,18 +4,15 @@ Supports saving and restoring webui and extensions from a known working set of c
import os import os
import json import json
import time
import tqdm import tqdm
from datetime import datetime from datetime import datetime
from collections import OrderedDict
import git import git
from modules import shared, extensions, errors from modules import shared, extensions, errors
from modules.paths_internal import script_path, config_states_dir from modules.paths_internal import script_path, config_states_dir
all_config_states = {}
all_config_states = OrderedDict()
def list_config_states(): def list_config_states():
@@ -28,15 +25,19 @@ def list_config_states():
for filename in os.listdir(config_states_dir): for filename in os.listdir(config_states_dir):
if filename.endswith(".json"): if filename.endswith(".json"):
path = os.path.join(config_states_dir, filename) path = os.path.join(config_states_dir, filename)
with open(path, "r", encoding="utf-8") as f: try:
j = json.load(f) with open(path, "r", encoding="utf-8") as f:
j["filepath"] = path j = json.load(f)
config_states.append(j) 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) config_states = sorted(config_states, key=lambda cs: cs["created_at"], reverse=True)
for cs in config_states: 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") name = cs.get("name", "Config")
full_name = f"{name}: {timestamp}" full_name = f"{name}: {timestamp}"
all_config_states[full_name] = cs all_config_states[full_name] = cs
+79
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,
),
]
+1 -1
View File
@@ -57,7 +57,7 @@ class DeepDanbooru:
a = np.expand_dims(np.array(pic, dtype=np.float32), 0) / 255 a = np.expand_dims(np.array(pic, dtype=np.float32), 0) / 255
with torch.no_grad(), devices.autocast(): 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() y = self.model(x)[0].detach().cpu().numpy()
probability_dict = {} probability_dict = {}
+162 -41
View File
@@ -3,11 +3,18 @@ import contextlib
from functools import lru_cache from functools import lru_cache
import torch import torch
from modules import errors from modules import errors, shared, npu_specific
if sys.platform == "darwin": if sys.platform == "darwin":
from modules import mac_specific 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: def has_mps() -> bool:
if sys.platform != "darwin": if sys.platform != "darwin":
@@ -15,17 +22,25 @@ def has_mps() -> bool:
else: else:
return mac_specific.has_mps return mac_specific.has_mps
def extract_device_id(args, name):
for x in range(len(args)):
if name in args[x]:
return args[x + 1]
return None 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(): def get_cuda_device_string():
from modules import shared
if shared.cmd_opts.device_id is not None: if shared.cmd_opts.device_id is not None:
return f"cuda:{shared.cmd_opts.device_id}" return f"cuda:{shared.cmd_opts.device_id}"
@@ -39,6 +54,12 @@ def get_optimal_device_name():
if has_mps(): if has_mps():
return "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" return "cpu"
@@ -47,45 +68,70 @@ def get_optimal_device():
def get_device_for(task): def get_device_for(task):
from modules import shared if task in shared.cmd_opts.use_cpu or "all" in shared.cmd_opts.use_cpu:
if task in shared.cmd_opts.use_cpu:
return cpu return cpu
return get_optimal_device() return get_optimal_device()
def torch_gc(): def torch_gc():
if torch.cuda.is_available(): if torch.cuda.is_available():
with torch.cuda.device(get_cuda_device_string()): with torch.cuda.device(get_cuda_device_string()):
torch.cuda.empty_cache() torch.cuda.empty_cache()
torch.cuda.ipc_collect() torch.cuda.ipc_collect()
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(): def enable_tf32():
if torch.cuda.is_available(): if torch.cuda.is_available():
# enabling benchmark option seems to enable a range of cards to do fp16 when they otherwise can't # 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 # 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.cudnn.benchmark = True
torch.backends.cuda.matmul.allow_tf32 = True torch.backends.cuda.matmul.allow_tf32 = True
torch.backends.cudnn.allow_tf32 = True torch.backends.cudnn.allow_tf32 = True
errors.run(enable_tf32, "Enabling TF32") errors.run(enable_tf32, "Enabling TF32")
cpu = torch.device("cpu") cpu: torch.device = torch.device("cpu")
device = device_interrogate = device_gfpgan = device_esrgan = device_codeformer = None fp8: bool = False
dtype = torch.float16 # Force fp16 for all models in inference. No casting during inference.
dtype_vae = torch.float16 # This flag is controlled by "--precision half" command line arg.
dtype_unet = torch.float16 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 unet_needs_upcast = False
def cond_cast_unet(input): def cond_cast_unet(input):
if force_fp16:
return input.to(torch.float16)
return input.to(dtype_unet) if unet_needs_upcast else input return input.to(dtype_unet) if unet_needs_upcast else input
@@ -93,32 +139,95 @@ def cond_cast_float(input):
return input.float() if unet_needs_upcast else input return input.float() if unet_needs_upcast else input
def randn(seed, shape): nv_rng = None
from modules.shared import opts patch_module_list = [
torch.nn.Linear,
torch.manual_seed(seed) torch.nn.Conv2d,
if opts.randn_source == "CPU" or device.type == 'mps': torch.nn.MultiheadAttention,
return torch.randn(shape, device=cpu).to(device) torch.nn.GroupNorm,
return torch.randn(shape, device=device) torch.nn.LayerNorm,
]
def randn_without_seed(shape): def manual_cast_forward(target_dtype):
from modules.shared import opts 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': org_dtype = target_dtype
return torch.randn(shape, device=cpu).to(device) for param in self.parameters():
return torch.randn(shape, device=device) 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): def autocast(disable=False):
from modules import shared
if disable: if disable:
return contextlib.nullcontext() 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() 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") return torch.autocast("cuda")
@@ -131,27 +240,25 @@ class NansException(Exception):
def test_for_nans(x, where): def test_for_nans(x, where):
from modules import shared
if shared.cmd_opts.disable_nan_check: if shared.cmd_opts.disable_nan_check:
return return
if not torch.all(torch.isnan(x)).item(): if not torch.isnan(x[(0, ) * len(x.shape)]):
return return
if where == "unet": 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: 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." 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": 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: 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." 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: 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." message += " Use --disable-nan-check commandline argument to disable this check."
@@ -161,8 +268,8 @@ def test_for_nans(x, where):
@lru_cache @lru_cache
def first_time_calculation(): def first_time_calculation():
""" """
just do any calculation with pytorch layers - the first time this is done it allocaltes about 700MB of memory and 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 wih NVidia. spends about 2.7 seconds doing that, at least with NVidia.
""" """
x = torch.zeros((1, 1)).to(device, dtype) x = torch.zeros((1, 1)).to(device, dtype)
@@ -172,3 +279,17 @@ def first_time_calculation():
x = torch.zeros((1, 1, 3, 3)).to(device, dtype) x = torch.zeros((1, 1, 3, 3)).to(device, dtype)
conv2d = torch.nn.Conv2d(1, 1, (3, 3)).to(device, dtype) conv2d = torch.nn.Conv2d(1, 1, (3, 3)).to(device, dtype)
conv2d(x) 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`.")
+66 -1
View File
@@ -6,6 +6,21 @@ import traceback
exception_records = [] 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(): def record_exception():
_, e, tb = sys.exc_info() _, e, tb = sys.exc_info()
if e is None: if e is None:
@@ -14,7 +29,7 @@ def record_exception():
if exception_records and exception_records[-1] == e: if exception_records and exception_records[-1] == e:
return return
exception_records.append((e, tb)) exception_records.append(format_exception(e, tb))
if len(exception_records) > 5: if len(exception_records) > 5:
exception_records.pop(0) exception_records.pop(0)
@@ -83,3 +98,53 @@ def run(code, task):
code() code()
except Exception as e: except Exception as e:
display(task, 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())

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