Compare commits

...

2782 Commits

Author SHA1 Message Date
Kohaku-Blueleaf 9adeed18f1 Fix unload of bundled emb 2023-10-22 17:57:59 +08: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
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
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
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
王秋文/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
AUTOMATIC1111 59544321aa initial work on sd_unet for SDXL 2023-09-11 21:17:40 +03: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
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 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
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
uservar a51721cb09 Fix bug with sigma min/max overrides. 2023-09-02 11:35:30 +00: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 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
AUTOMATIC 59419bd64a add changelog for 1.4.0 2023-06-09 22:47:58 +03:00
AUTOMATIC cfdd1b9418 linter 2023-06-09 22:47:27 +03:00
AUTOMATIC1111 89e6c60546 Merge pull request #11092 from AUTOMATIC1111/Generate-Forever-during-generation
Allow activation of Generate Forever during generation
2023-06-09 22:33:23 +03:00
AUTOMATIC1111 d00139eea8 Merge pull request #11087 from AUTOMATIC1111/persistent_conds_cache
persistent conds cache
2023-06-09 22:32:49 +03:00
AUTOMATIC1111 b8d7506ebe Merge pull request #11123 from akx/dont-die-on-bad-symlink-lora
Don't die when a LoRA is a broken symlink
2023-06-09 22:31:49 +03:00
AUTOMATIC1111 f9606b8826 Merge pull request #10295 from Splendide-Imaginarius/mk2-blur-mask
Split mask blur into X and Y components, patch Outpainting MK2 accordingly
2023-06-09 22:31:29 +03:00
AUTOMATIC1111 741bd71873 Merge pull request #11048 from DGdev91/force_python1_navi_renoir
Forcing Torch Version to 1.13.1 for RX 5000 series GPUs
2023-06-09 22:30:54 +03:00
Aarni Koskela d75ed52bfc Don't die when a LoRA is a broken symlink
Fixes #11098
2023-06-09 13:26:36 +03:00
Splendide Imaginarius 72815c0211 Split Outpainting MK2 mask blur into X and Y components
Fixes unexpected noise in non-outpainted borders when using MK2 script.
2023-06-09 08:37:26 +00:00
Splendide Imaginarius 1503af60b0 Split mask blur into X and Y components
Prequisite to fixing Outpainting MK2 mask blur bug.
2023-06-09 08:36:33 +00: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
w-e-w 46e4777fd6 Generate Forever during generation
Generate Forever during generation
2023-06-08 17:56:03 +09:00
w-e-w 7f2214aa2b persistent conds cache
Update shared.py
2023-06-08 14:27:22 +09:00
AUTOMATIC1111 cf28aed1a7 Merge pull request #11058 from AUTOMATIC1111/api-wiki
link footer API to Wiki when API is not active
2023-06-07 07:49:59 +03:00
AUTOMATIC1111 806ea639e6 Merge pull request #11066 from aljungberg/patch-1
Fix upcast attention dtype error.
2023-06-07 07:48:52 +03:00
Alexander Ljungberg d9cc0910c8 Fix upcast attention dtype error.
Without this fix, enabling the "Upcast cross attention layer to float32" option while also using `--opt-sdp-attention` breaks generation with an error:

```
  File "/ext3/automatic1111/stable-diffusion-webui/modules/sd_hijack_optimizations.py", line 612, in sdp_attnblock_forward
    out = torch.nn.functional.scaled_dot_product_attention(q, k, v, dropout_p=0.0, is_causal=False)
RuntimeError: Expected query, key, and value to have the same dtype, but got query.dtype: float key.dtype: float and value.dtype: c10::Half instead.
```

The fix is to make sure to upcast the value tensor too.
2023-06-06 21:45:30 +01:00
DGdev91 62860c221e Skip force pyton and pytorch ver if TORCH_COMMAND already set 2023-06-06 15:43:32 +02:00
w-e-w 96e446218c link footer API to Wiki when API is not active 2023-06-06 18:58:44 +09:00
DGdev91 8646768801 Write "RX 5000 Series" instead of "Navi" in err 2023-06-06 10:03:20 +02:00
DGdev91 95d4d650d4 Check python version for Navi 1 only 2023-06-06 09:59:13 +02:00
DGdev91 e0d923bdf8 Force python1 for Navi1 only, use python_cmd for python 2023-06-06 09:55:49 +02:00
DGdev91 2788ce8c7b Fix error in webui.sh 2023-06-06 01:51:35 +02:00
DGdev91 8d98532b65 Forcing Torch Version to 1.13.1 for Navi and Renoir GPUs 2023-06-06 01:05:31 +02:00
AUTOMATIC1111 a009fe15fd Merge pull request #11047 from AUTOMATIC1111/parse_generation_parameters_with_error
handles exception when parsing generation parameters from png info
2023-06-06 00:13:27 +03:00
w-e-w 851bf43520 print error and continue
print error and continue
2023-06-06 05:50:43 +09: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
AUTOMATIC1111 0895c2369c Merge pull request #11037 from AUTOMATIC1111/restart-autolaunch
fix rework-disable-autolaunch for new restart method
2023-06-05 20:57:31 +03:00
w-e-w c2808f3040 SD_WEBUI_RESTARTING 2023-06-06 02:52:05 +09:00
w-e-w eaace155ce restore old disable --autolaunch 2023-06-06 02:47:18 +09:00
AUTOMATIC1111 e89a248e2e Merge pull request #11031 from akx/zoom-and-pan-namespace
Zoom and pan: namespace & simplify
2023-06-05 20:40:31 +03:00
AUTOMATIC1111 1dd8d571a4 Merge pull request #11043 from akx/restart-envvar
Restart: only do restart if running via the wrapper script
2023-06-05 20:06:40 +03:00
Aarni Koskela 46a5bd64ed Restart: only do restart if running via the wrapper script 2023-06-05 20:04:28 +03:00
w-e-w 1411a6e74b rework-disable-autolaunch 2023-06-06 01:09:30 +09:00
AUTOMATIC 18acc0b30d revert the message to how it was 2023-06-05 11:08:57 +03:00
AUTOMATIC1111 7a7a201d81 Merge pull request #10956 from akx/len
Simplify a bunch of `len(x) > 0`/`len(x) == 0` style expressions
2023-06-05 11:06:37 +03:00
Aarni Koskela 2d4c66f7b5 Zoom and Pan: simplify waitForOpts 2023-06-05 10:40:42 +03:00
Aarni Koskela 6163b38ad9 Zoom and Pan: use for instead of forEach 2023-06-05 10:37:00 +03:00
Aarni Koskela afbb0b5f86 Zoom and Pan: simplify getElements (it's not actually async) 2023-06-05 10:37:00 +03:00
Aarni Koskela 68cda4f213 Zoom and Pan: use elementIDs from closure scope 2023-06-05 10:37:00 +03:00
Aarni Koskela 8fd20bd4c3 Zoom and Pan: move helpers into its namespace to avoid littering global scope 2023-06-05 10:36:55 +03:00
AUTOMATIC 9781f31f74 Merge branch 'master' into dev 2023-06-05 06:16:03 +03:00
AUTOMATIC baf6946e06 Merge branch 'release_candidate' 2023-06-05 06:13:41 +03:00
AUTOMATIC1111 1e7e34337f Merge pull request #11013 from ramyma/get_latent_upscale_modes_api
Get latent upscale modes API endpoint
2023-06-04 18:20:36 +03:00
ramyma 4faaf3e723 Add endpoint to get latent_upscale_modes for hires fix 2023-06-04 17:05:29 +03:00
AUTOMATIC fbf88343de prevent calculating cons for second pass of hires fix when they are the same as for the first pass 2023-06-04 16:29:02 +03:00
AUTOMATIC 1ca5e76f7b fix for conds of second hires fox pass being calculated using first pass's networks, and add an option to revert to old behavior 2023-06-04 13:07:31 +03:00
AUTOMATIC1111 1c6dca9383 Merge pull request #10997 from AUTOMATIC1111/fix-conds-caching-with-extra-network
fix conds caching with extra network
2023-06-04 12:07:41 +03:00
AUTOMATIC1111 56bf522913 Merge pull request #10990 from vkage/sd_hijack_optimizations_bugfix
torch.cuda.is_available() check for SdOptimizationXformers
2023-06-04 11:34:32 +03:00
AUTOMATIC 2e23c9c568 fix the broken line for #10990 2023-06-04 11:33:51 +03:00
AUTOMATIC1111 0819383de0 Merge pull request #10975 from AUTOMATIC1111/restart3
A yet another method to restart webui.
2023-06-04 11:17:20 +03:00
AUTOMATIC1111 efc4c79b5e Merge pull request #10980 from AUTOMATIC1111/sysinfo
Added sysinfo tab to settings
2023-06-04 11:16:32 +03:00
AUTOMATIC aeba3cadd5 add whitelist for environment in the report
add extra link to view the report instead of downloading it
2023-06-04 11:16:00 +03:00
AUTOMATIC1111 b4b7e6e5f7 Merge pull request #11005 from daswer123/dev
Fixed bugs in the zoom builtin extensions and made the zoom function global
2023-06-04 10:59:25 +03:00
AUTOMATIC1111 7f28e8c445 Merge pull request #11006 from Vesnica/patch-1
Make save_pil_to_file to have same parameters with gradio's function
2023-06-04 10:58:14 +03:00
AUTOMATIC f98f4f73aa infer styles from prompts, and an option to control the behavior 2023-06-04 10:56:48 +03:00
Vesnica 08f93da17c Update ui_tempdir.py
Make override function have the same input parameters with original function
2023-06-04 14:20:23 +08:00
Danil Boldyrev 0432e37843 Correct definition zoom level
I changed the regular expression and now I always have to select scale from style.transfo
2023-06-04 04:17:55 +03:00
Danil Boldyrev ad3d6d9a22 Fixed visual bugs 2023-06-04 03:38:21 +03:00
Danil Boldyrev 1a49178330 Made a function applyZoomAndPan isolated each instance
Isolated each instance of applyZoomAndPan, now if you add another element to the page, they will work correctly
2023-06-04 03:04:46 +03:00
Danil Boldyrev dc273f7473 Fixed the redmask bug 2023-06-04 01:18:27 +03:00
w-e-w 0a277ab591 remove redone compare 2023-06-04 05:19:47 +09:00
w-e-w 1c9d1b0ee0 simplify self.extra_network_data 2023-06-04 05:19:34 +09:00
w-e-w f098e726d3 fix conds caching with extra network 2023-06-04 04:24:44 +09:00
Vivek K. Vasishtha b1a72bc7e2 torch.cuda.is_available() check for SdOptimizationXformers 2023-06-03 21:54:27 +05:30
Danil Boldyrev 3e3635b114 Made the applyZoomAndPan function global for other extensions 2023-06-03 19:24:05 +03:00
AUTOMATIC1111 30bbb8bce3 Merge pull request #10987 from off99555/dev
Fix missing ext_filter kwarg
2023-06-03 18:57:10 +03:00
Chanchana Sornsoontorn 68d8423288 Fix missing ext_filter kwarg 2023-06-03 22:28:00 +07:00
AUTOMATIC1111 b2fa0a921d Merge pull request #10838 from breengles/img2img-batch-processing
Img2img batch processing
2023-06-03 17:23:41 +03:00
AUTOMATIC1111 80ae378f34 Merge pull request #10942 from ramyma/round-upscale-result-dims
Round upscaled dimensions only when not divisible by 8
2023-06-03 14:50:46 +03:00
ramyma 8c8c3617a7 Use a more concise calculation for dest dims 2023-06-03 14:41:12 +03:00
ramyma 31f57455dd Round upscaled dimensions only when not divisible by 8 2023-06-03 14:36:10 +03:00
AUTOMATIC cd7ec5f728 lint 2023-06-03 14:00:37 +03:00
AUTOMATIC 7393c1f99c Added sysinfo tab to settings 2023-06-03 13:55:35 +03:00
AUTOMATIC 333e63c091 a yet another method to restart webui 2023-06-03 09:59:56 +03:00
AUTOMATIC1111 9d953c0e03 Merge pull request #10917 from AUTOMATIC1111/bug_template_cross_attention_optimization
Bug template cross attention optimization
2023-06-03 09:25:21 +03:00
AUTOMATIC1111 e0d8ce3d2b Merge pull request #10946 from AUTOMATIC1111/fix-duplicate-optimizers
Fix duplicate Cross attention optimization after UI reload
2023-06-03 09:24:54 +03:00
AUTOMATIC1111 7fd53815d3 Merge pull request #10967 from waltercool/master
Added support for workarounds on Navi external GPU.
2023-06-03 09:09:25 +03:00
AUTOMATIC1111 b1fd2aaa8b Merge pull request #10943 from catboxanon/sort
Allow dynamically sorting extra networks in UI
2023-06-03 09:05:22 +03:00
AUTOMATIC1111 08109b9bc0 Merge pull request #10902 from daswer123/dev
Improvement for zoom builtin extension
2023-06-03 09:02:40 +03:00
AUTOMATIC1111 58779b289e Merge pull request #10957 from AUTOMATIC1111/fallback_version_info
fallback version info form CHANGELOG.md
2023-06-03 09:01:05 +03:00
w-e-w df5a3cbefe fallback version info form CHANGELOG.md 2023-06-03 13:33:23 +09:00
w-e-w d1bfc86ffc Update modules/launch_utils.py
Co-authored-by: Aarni Koskela <akx@iki.fi>
2023-06-03 13:07:07 +09:00
Danil Boldyrev 5b682be59a small ui fix
In the error the user will see R instead of KeyR
2023-06-03 02:24:57 +03:00
Danil Boldyrev 1e0ab4015d Added the ability to swap the zoom hotkeys and resize the brush 2023-06-03 02:18:49 +03:00
catboxanon 9009e25cb1 Apply suggestions from code review
Co-authored-by: Aarni Koskela <akx@iki.fi>
2023-06-02 16:12:24 -04:00
Pablo Cholaky 8d970a4a97 Added support for workarounds on external GPU.
lspci detects VGA for main/integrated videocards and Display
for external videocards.

This commit should apply workarounds on computers with more than
one GPU. Useful for most laptops using weak iGPU and good dGPU.

Signed-off-by: Pablo Cholaky <waltercool@slash.cl>
2023-06-02 15:04:58 -04:00
Danil Boldyrev d306d25e56 Made tooltip optional.
You can disable it in the settings.
Enabled by default
2023-06-02 19:10:28 +03:00
w-e-w 0dd6bca4f1 fallback version info form CHANGELOG.md 2023-06-02 22:02:21 +09:00
Aarni Koskela 51864790fd Simplify a bunch of len(x) > 0/len(x) == 0 style expressions 2023-06-02 15:07:10 +03:00
AUTOMATIC1111 6f754ab98b Merge pull request #10780 from akx/image-emb-fonts
Mark caption_image_overlay's textfont as deprecated; fix #10778
2023-06-02 14:36:22 +03:00
w-e-w 8f8405274c remove redundant 2023-06-02 17:18:42 +09:00
w-e-w 2bbe3f5f0a remove redundant call list_optimizers() 2023-06-02 16:51:15 +09:00
AUTOMATIC eed7b2776e add changelog 2023-06-02 10:39:16 +03:00
AUTOMATIC1111 cbc38a903b Merge pull request #10905 from AUTOMATIC1111/fix-10896-pnginfo-parameters
fix 10896 pnginfo parameters
2023-06-02 10:37:35 +03:00
AUTOMATIC eeb685b0e5 bump gradio version to fix tmp filenames for images 2023-06-02 10:34:59 +03:00
w-e-w b617c634a8 Cross attention optimization
Cross attention optimization

cross attention optimization
2023-06-02 14:14:15 +09:00
catboxanon 4cc0cede6d lint fixes 2023-06-02 04:12:08 +00:00
catboxanon 7dca8e7698 Support dynamic sort of extra networks 2023-06-02 04:08:45 +00:00
Danil Boldyrev 38aca6f605 Added a hotkey repeat check to avoid bugs 2023-06-02 01:26:25 +03:00
Danil Boldyrev 68c4beab46 Added the ability to configure hotkeys via webui
Now you can configure the hotkeys directly through the settings

JS and Python scripts are tested and code style compliant
2023-06-02 01:04:17 +03:00
AUTOMATIC cbe1799797 Merge branch 'master' into release_candidate 2023-06-01 21:36:48 +03:00
AUTOMATIC 3e995778fc Merge branch 'master' into dev 2023-06-01 21:36:06 +03:00
AUTOMATIC b6af0a3809 Merge branch 'release_candidate' 2023-06-01 21:35:14 +03:00
AUTOMATIC a9674359ca revert the erroneous change for model setting added in df02498d 2023-06-01 19:52:04 +03:00
Artem Kotov ba110bf093 fallback to original file retrieving; skip img if mask not found
usage of `shared.walk_files` breaks controlnet extension
images are processed in different order 
which leads to unmatched img file used for img2img and img file used for controlnet 
(if no folder is specified for control net
or the same as img2img input dir used for it)
2023-06-01 15:44:55 +04:00
Artem Kotov 49f4b4be67 add subdir support for images, masks and output; search mask only in subdir 2023-06-01 11:29:56 +04:00
AUTOMATIC a5e851028e add hiding and a colspans to startup profile table 2023-06-01 10:01:42 +03:00
AUTOMATIC b3390a9840 Merge branch 'dev' into startup-profile 2023-06-01 08:42:50 +03:00
AUTOMATIC 8c3e64f4f6 update readme 2023-06-01 08:13:09 +03:00
AUTOMATIC 3ee1238630 revert default cross attention optimization to Doggettx
make --disable-opt-split-attention command line option work again
2023-06-01 08:12:21 +03:00
AUTOMATIC 36888092af revert default cross attention optimization to Doggettx
make --disable-opt-split-attention command line option work again
2023-06-01 08:12:06 +03:00
AUTOMATIC 17a66931da update readme 2023-06-01 07:29:52 +03:00
AUTOMATIC 915d1da1cd assign devices.dtype early because it's needed before the model is loaded 2023-06-01 07:28:46 +03:00
AUTOMATIC f1533de982 assign devices.dtype early because it's needed before the model is loaded 2023-06-01 07:28:20 +03:00
AUTOMATIC1111 e980a4bd88 Merge pull request #10905 from AUTOMATIC1111/fix-10896-pnginfo-parameters
fix 10896 pnginfo parameters
2023-06-01 06:54:19 +03:00
w-e-w 0bf09c30c6 remove redundant 2023-06-01 06:34:53 +09:00
w-e-w 72f6367b9b fix 10896 pnginfo parameters 2023-06-01 06:24:37 +09:00
AUTOMATIC 884435796a add changelog 2023-05-31 23:08:31 +03:00
AUTOMATIC 8a561d94e6 use ui_reorder_list rather than ui_reorder for UI reorder option to make the program not break when reverting to old version 2023-05-31 23:05:44 +03:00
Danil Boldyrev c5d70fe1d3 Fixed the problem with sticking to the mouse, created a tooltip 2023-05-31 23:02:49 +03:00
AUTOMATIC 3690e4e82c fix [Bug]: LoRA don't apply on dropdown list sd_lora #10880 2023-05-31 22:57:27 +03:00
AUTOMATIC1111 6427ffde4d Merge pull request #10808 from AUTOMATIC1111/fix-disable-png-info
fix disable png info
2023-05-31 22:56:56 +03:00
AUTOMATIC1111 c63d46ceb8 Merge pull request #10804 from AUTOMATIC1111/fix-xyz-clip
Fix get_conds_with_caching()
2023-05-31 22:54:51 +03:00
AUTOMATIC1111 fae8bdfa48 Merge pull request #10785 from nyqui/fix-hires.fix
fix "hires. fix" prompt sharing same labels with txt2img_prompt
2023-05-31 22:54:24 +03:00
AUTOMATIC 10dbee0d59 add quoting for infotext values that have a colon in them 2023-05-31 22:54:00 +03:00
AUTOMATIC 48875af7a1 fix [Bug]: LoRA don't apply on dropdown list sd_lora #10880 2023-05-31 22:45:16 +03:00
AUTOMATIC df02498d03 add an option to show selected setting in main txt2img/img2img UI
split some code from ui.py into ui_settings.py ui_gradio_edxtensions.py
add before_process callback for scripts
add ability for alwayson scripts to specify section and let user reorder those sections
2023-05-31 22:40:09 +03:00
AUTOMATIC 583fb9f066 change UI reorder setting to multiselect 2023-05-31 20:31:17 +03:00
AUTOMATIC 05933840f0 rename print_error to report, use it with together with package name 2023-05-31 19:56:37 +03:00
AUTOMATIC1111 d67ef01f62 Merge pull request #10780 from akx/image-emb-fonts
Mark caption_image_overlay's textfont as deprecated; fix #10778
2023-05-31 19:37:58 +03:00
AUTOMATIC1111 726f3feb2b Merge pull request #10863 from akx/ui-current-tab-top-level
Frontend: only look at top-level tabs, not nested tabs
2023-05-31 19:34:59 +03:00
AUTOMATIC1111 e72013ea67 Merge pull request #10638 from catboxanon/patch/revert-10586
Revert discarding penultimate sigma for DPM-Solver++(2M) SDE
2023-05-31 19:34:20 +03:00
AUTOMATIC1111 80583263a2 Merge pull request #10784 from AUTOMATIC1111/update-deps
Update xformers to 0.0.20
2023-05-31 19:32:13 +03:00
AUTOMATIC1111 9013559eef Merge pull request #10783 from akx/sync-req
Sync requirements files
2023-05-31 19:31:27 +03:00
AUTOMATIC1111 177d4b6828 Merge branch 'dev' into sync-req 2023-05-31 19:31:19 +03:00
AUTOMATIC1111 881de0df38 Merge pull request #10803 from klimaleksus/refactoring-for-embedding-merge
Refactor EmbeddingDatabase.register_embedding() to allow unregistering
2023-05-31 19:29:47 +03:00
AUTOMATIC1111 670195d720 Merge pull request #10808 from AUTOMATIC1111/fix-disable-png-info
fix disable png info
2023-05-31 19:20:19 +03:00
AUTOMATIC1111 003ed0f087 Merge pull request #10813 from AUTOMATIC1111/clarify-issue-template
clarify issue template
2023-05-31 19:18:49 +03:00
AUTOMATIC1111 8598587f1c Merge pull request #10806 from akx/upgrade-transformers
Upgrade transformers from 4.25.1 to 4.29.2
2023-05-31 19:17:43 +03:00
AUTOMATIC1111 d9bd7ada76 Merge pull request #10820 from akx/report-error
Add & use modules.errors.print_error
2023-05-31 19:16:14 +03:00
AUTOMATIC1111 52b8752e62 Merge branch 'dev' into report-error 2023-05-31 19:15:21 +03:00
AUTOMATIC1111 78a602ae8c Merge pull request #10796 from ramyma/round-upscale-result-dims
Round down scale destination dimensions to nearest multiple of 8
2023-05-31 19:06:07 +03:00
AUTOMATIC1111 2fcd64b9e8 Merge pull request #10805 from akx/gitpython-no-persistent-processes
Patch GitPython to not use leaky persistent processes
2023-05-31 19:05:03 +03:00
AUTOMATIC1111 741ab6bed1 Merge pull request #10788 from yoinked-h/patch-1
typo
2023-05-31 18:58:06 +03:00
AUTOMATIC1111 11a6a669d1 Merge pull request #10814 from missionfloyd/gamepad-disconnect
Only poll gamepads while connected
2023-05-31 18:57:38 +03:00
AUTOMATIC1111 58dbd0ea4d Merge pull request #10759 from daswer123/dev
Add the ability to zoom and move the canvas
2023-05-31 18:52:22 +03:00
AUTOMATIC1111 3e48f7d30c Merge pull request #10804 from AUTOMATIC1111/fix-xyz-clip
Fix get_conds_with_caching()
2023-05-31 18:47:24 +03:00
AUTOMATIC1111 0b0f60f954 Merge pull request #10856 from akx/untamed
Remove taming_transformers dependency
2023-05-31 18:46:15 +03:00
AUTOMATIC1111 69f49a935a Merge pull request #10845 from DragonHawkAlpha/master
Added VAE listing to web API. Via: /sdapi/v1/sd-vae
2023-05-31 18:44:46 +03:00
AUTOMATIC1111 fec089d8f1 Merge pull request #10878 from willfrey/patch-1
Fix typo in `--update-check` help message
2023-05-31 18:41:05 +03:00
AUTOMATIC1111 c3a61425b8 Merge pull request #10848 from DavidQChuang/master
Fix s_min_uncond default type int
2023-05-31 18:40:27 +03:00
AUTOMATIC1111 e7439b5cbe Merge pull request #10785 from nyqui/fix-hires.fix
fix "hires. fix" prompt sharing same labels with txt2img_prompt
2023-05-31 18:40:00 +03:00
Will Frey fb1cb6d364 Fix typo in --update-check help message
Change `chck` to `check`
2023-05-30 22:05:12 -04:00
Aarni Koskela f81931c591 Frontend: only look at top-level tabs, not nested tabs
Refs https://github.com/adieyal/sd-dynamic-prompts/issues/459#issuecomment-1568543926
2023-05-30 17:54:29 +03:00
Danil Boldyrev c928c228af a small fix for very wide images, because of the scroll bar was the wrong zoom 2023-05-30 16:35:52 +03:00
Aarni Koskela 5fcdaa6a7f Vendor in the single module used from taming_transformers; remove taming_transformers dependency
(and fix the two ruff complaints)
2023-05-30 12:47:57 +03:00
missionfloyd baa81126c4 Move gamepaddisconnected listener 2023-05-29 23:52:19 -06:00
David Chuang 3fc8aeb48d Fix s_min_uncond default type int 2023-05-29 20:17:25 -04:00
James 42e020c1c1 Added VAE listing to web API. 2023-05-29 22:25:43 +01:00
Danil Boldyrev 8ab4e55fe3 Moved the script to the extension build-in 2023-05-29 21:39:10 +03:00
Artem Kotov 23314a6e27 ruffed 2023-05-29 21:38:49 +04:00
Artem Kotov 6c610a8a95 add scale_by to batch processing 2023-05-29 20:47:20 +04:00
Artem Kotov c8e67b6732 improve filename matching for mask
we should not rely that mask filename will be of the same extension
as the image filename so better pattern matching is added
2023-05-29 20:39:24 +04:00
w-e-w 4a449375a2 fix get_conds_with_caching() 2023-05-30 01:07:35 +09:00
w-e-w 123641e4ec Revert "fix xyz clip"
This reverts commit edd766e70a.
2023-05-30 01:06:23 +09:00
Aarni Koskela 00dfe27f59 Add & use modules.errors.print_error where currently printing exception info by hand 2023-05-29 09:17:30 +03:00
Aarni Koskela 77a10c62c9 Patch GitPython to not use leaky persistent processes 2023-05-29 08:31:11 +03:00
missionfloyd 679e873875 Update imageviewerGamepad.js 2023-05-28 20:49:46 -06:00
missionfloyd df59b74ced Only poll gamepads while connected 2023-05-28 20:42:47 -06:00
w-e-w 7dfee8a3bd clarify issue template 2023-05-29 11:01:58 +09:00
w-e-w 2aca613a61 fix disable png info 2023-05-29 07:30:32 +09:00
Aarni Koskela 018f77f0b8 Upgrade transformers
Refs https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/9035#issuecomment-1485461039
2023-05-29 00:58:52 +03:00
w-e-w edd766e70a fix xyz clip 2023-05-29 05:40:38 +09:00
klimaleksus 4635f31270 Refactor EmbeddingDatabase.register_embedding() to allow unregistering 2023-05-29 01:09:59 +05:00
ramyma 3539885f0e Round down scale destination dimensions to nearest multiple of 8 2023-05-28 21:41:54 +03:00
Danil Boldyrev 4d7b63f489 changed the document to gradioApp() 2023-05-28 20:32:21 +03:00
Danil Boldyrev f48bce5f68 Corrected the code according to Code style 2023-05-28 20:22:35 +03:00
yoinked 905c3fe23e typo
vidocard -> videocard
2023-05-28 08:39:00 -07:00
nyqui bae2fca523 fix "hires. fix" prompt/neg sharing same labels as txt2img_prompt/negative_prompt 2023-05-28 22:59:29 +09:00
Aarni Koskela c1a5068ebe Synchronize requirements/requirements_versions
* Remove deps not listed in _versions from requirements

* Omit versions when they don't match _versions
2023-05-28 16:42:39 +03:00
Sakura-Luna cf07983a6e Upgrade xformers 2023-05-28 20:42:19 +08:00
Aarni Koskela 3d42411c3d Sort requirements files 2023-05-28 15:40:14 +03:00
Aarni Koskela 1013758933 Mark caption_image_overlay's textfont as deprecated; fix #10778 2023-05-28 14:48:50 +03:00
AUTOMATIC b957dcfece add quoting for infotext values that have a colon in them 2023-05-28 10:39:57 +03:00
AUTOMATIC f9809e6e40 Merge branch 'master' into dev 2023-05-28 06:59:20 +03:00
Danil Boldyrev 9e69009d1b Improve reset zoom when toggle tabs 2023-05-28 01:56:48 +03:00
Danil Boldyrev 433c70b403 Formatted Prettier added fullscreen mode canvas expansion function 2023-05-28 01:31:23 +03:00
Danil Boldyrev 662af75973 Ability to zoom and move the canvas 2023-05-27 22:54:45 +03:00
AUTOMATIC 20ae71faa8 fix linter issue for 1.3.0 2023-05-27 20:23:16 +03:00
AUTOMATIC 6095ade147 fix serving images that have already been saved without temp files function that broke after updating gradio 2023-05-27 20:19:10 +03:00
AUTOMATIC dd377637ca update the changelog to mention 1.3.0 version 2023-05-27 20:16:33 +03:00
AUTOMATIC 50906bf78b Merge branch 'release_candidate' 2023-05-27 20:13:26 +03:00
AUTOMATIC1111 9bc037d045 Merge pull request #10655 from fumitakayano/fumitakayano
Added format to specify VAE filename for generated image filenames
2023-05-27 20:11:21 +03:00
AUTOMATIC1111 d0e8fa627d Merge pull request #10569 from strelokhalfer/pr
Change 'images.zip' to pattern settings
2023-05-27 20:10:17 +03:00
AUTOMATIC1111 2fc2fbb4ea Merge pull request #10708 from akx/on-ui-update-throttled
Add onAfterUiUpdate callback
2023-05-27 20:09:15 +03:00
AUTOMATIC1111 5d29672b32 Merge pull request #10697 from catboxanon/patch/image-info
Cleaner image metadata read
2023-05-27 20:07:51 +03:00
AUTOMATIC1111 d92a6acf0e Merge pull request #10739 from linkoid/fix-ui-debug-mode-exit
Fix --ui-debug-mode exit
2023-05-27 20:02:07 +03:00
AUTOMATIC1111 348abeb99d Merge pull request #10722 from maybe-hello-world/master
Download ROCm for AMD GPU only if NVIDIA is not presented
2023-05-27 19:56:18 +03:00
AUTOMATIC1111 ba812b4495 Merge pull request #10718 from kernelmethod/libtcmalloc_fixes
Small fixes to prepare_tcmalloc for Debian/Ubuntu compatibility
2023-05-27 19:55:02 +03:00
AUTOMATIC1111 0666f7c597 Merge pull request #10694 from akx/tooltipsies
Tooltip fixes & optimizations
2023-05-27 19:54:09 +03:00
AUTOMATIC e8e7fe11e9 updates for the noise schedule settings 2023-05-27 19:53:09 +03:00
AUTOMATIC 654234ec56 Merge remote-tracking branch 'KohakuBlueleaf/custom-k-sched-settings' into dev 2023-05-27 19:08:02 +03:00
AUTOMATIC 633867ecc6 fix serving images that have already been saved without temp files function that broke after updating gradio 2023-05-27 19:06:49 +03:00
AUTOMATIC 339b531570 custom unet support 2023-05-27 15:47:33 +03:00
linkoid 1f0fdede17 Show full traceback in get_sd_model()
to reveal if an error is caused by an extension
2023-05-26 15:25:31 -04:00
linkoid 3829afec36 Remove exit() from select_checkpoint()
Raising a FileNotFoundError instead.
2023-05-26 15:08:53 -04:00
Roman Beltiukov bdc371983e Update webui.sh 2023-05-26 02:09:09 -07: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
Roman Beltiukov b2530c965c Merge branch 'dev' into master 2023-05-25 15:10:10 -07:00
Roman Beltiukov 09d9c3d287 change to AMD only if NVIDIA is not presented 2023-05-25 14:45:05 -07:00
kernelmethod d29fe44e46 Small fixes to prepare_tcmalloc for Debian/Ubuntu compatibility
- /usr/sbin (where ldconfig is usually located) is not typically on users' PATHs by default, so we set that variable before trying to run ldconfig.
- The libtcmalloc library is called libtcmalloc_minimal on Debian/Ubuntu systems. We now check whether libtcmalloc_minimal exists when running prepare_tcmalloc.
2023-05-25 14:51:47 -04:00
catboxanon 60062b51d8 Remove try/except in img metadata read 2023-05-25 08:33:40 -04:00
Aarni Koskela dc7a1bbb1c Use onAfterUiUpdate where possible 2023-05-25 09:09:13 +03:00
Aarni Koskela bc53ecf298 Add onAfterUiUpdate callback 2023-05-25 09:09:01 +03:00
Aarni Koskela 54696dce05 Document on* handlers (for extension authors' sake) 2023-05-25 09:03:14 +03:00
Aarni Koskela 9574ebe212 Merge executeCallbacks and runCallback, simplify + optimize 2023-05-25 09:02:41 +03:00
Aarni Koskela f661fb0fd3 Just use console.error, it's in all browsers 2023-05-25 09:00:45 +03:00
catboxanon 7a1bbf99da Cleaner image metadata read 2023-05-24 16:41:22 -04:00
Aarni Koskela 32b0f7c9bb Add support for tooltips on dropdown options 2023-05-24 20:45:05 +03:00
Aarni Koskela b82d4a65fe Restore support for dropdown tooltips 2023-05-24 20:42:47 +03:00
Aarni Koskela d66c64b9d7 Optimize tooltip checks
* Instead of traversing tens of thousands of text nodes, only look at elements and their children
* Debounce the checks to happen only every one second
2023-05-24 20:42:46 +03:00
strelokhalfer fb5d0ef209 Changed 'images.zip' to generation by pattern 2023-05-24 18:17:02 +03:00
Kohaku-Blueleaf a69b71a37f use Schedule instead of Sched 2023-05-24 20:40:37 +08:00
Kohaku-Blueleaf 4b88e24ebe improvements
See:
https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/10649#issuecomment-1561047723
2023-05-24 20:35:58 +08:00
Kohaku-Blueleaf 1601fccebc Use automatic instead of None/default 2023-05-24 00:18:09 +08:00
Kohaku-Blueleaf 27962ded4a Fix ruff error 2023-05-23 23:50:19 +08:00
AUTOMATIC a6e653be26 possible fix for empty list of optimizations #10605 2023-05-23 18:49:15 +03:00
AUTOMATIC 0e1c41998a fix bad styling for thumbs view in extra networks #10639 2023-05-23 18:49:15 +03:00
Kohaku-Blueleaf 72377b0251 Use type to determine if it is enable 2023-05-23 23:48:23 +08:00
AUTOMATIC b186045fee possible fix for empty list of optimizations #10605 2023-05-23 18:02:09 +03:00
AUTOMATIC 3f50b7d71c fix bad styling for thumbs view in extra networks #10639 2023-05-23 14:07:00 +03:00
fumitaka.yano 1db7d21283 Subject:.
Improvements to handle VAE filenames in generated image filenames

Body:.
1) Added new line 24 to import sd_vae module.
2) Added new method get_vae_filename at lines 340-349 to obtain the VAE filename to be used for image generation and further process it to extract only the filename by splitting it with a dot symbol.
3) Added a new lambda function 'vae_filename' at line 373 to handle VAE filenames.

Reason:.
A function was needed to get the VAE filename and handle it in the program.

Test:.
We tested whether we could use this new functionality to get the expected file names.
The correct behaviour was confirmed for the following commonly distributed VAE files.
vae-ft-mse-840000-ema-pruned.safetensors -> vae-ft-mse-840000-ema-pruned
anything-v4.0.vae.pt -> anything-v4.0

ruff response:.
There were no problems with the code I added.

There was a minor configuration error in a line I did not modify, but I did not modify it as it was not relevant to this modification.
Logged.
images.py:426:56: F841 [*] Local variable `_` is assigned to but never used
images.py:432:43: F841 [*] Local variable `_` is assigned to but never used

Impact:.
This change makes it easier to retrieve the VAE filename used for image generation and use it in the programme.
2023-05-23 15:56:08 +09:00
Kohaku-Blueleaf 78aed1fa4a Fix xyz 2023-05-23 11:47:32 +08:00
Kohaku-Blueleaf 70650f87a4 Use better way to impl 2023-05-23 11:34:51 +08:00
missionfloyd dafe519363 Fix lint errors 2023-05-22 21:23:39 -06:00
Kohaku-Blueleaf 1846ad36a3 Use settings instead of main interface 2023-05-23 10:58:57 +08:00
missionfloyd 468056958b Add reorder hotkeys
Shifts selected items with ctrl+left/right
2023-05-22 20:46:25 -06:00
Kohaku-Blueleaf ec1608308c Merge branch 'custom-k-sched' of https://github.com/KohakuBlueleaf/stable-diffusion-webui into custom-k-sched 2023-05-23 09:55:31 +08:00
Kohaku-Blueleaf 89c44bbc15 Add hint for custom k_diffusion scheduler 2023-05-23 09:52:15 +08:00
Kohaku-Blueleaf 38aaad654b Better hint for user
Co-authored-by: catboxanon <122327233+catboxanon@users.noreply.github.com>
2023-05-23 09:38:30 +08:00
AUTOMATIC1111 80a723cbcf Merge pull request #10644 from ArthurHeitmann/fix-inpainting-canvas-noise
Fix for #10643 (Inpainting mask sometimes not working)
2023-05-22 23:22:34 +03:00
ArthurHeitmann e1c44267ea Fix for #10643 (pixel noise in webui inpainting canvas breaking inpainting, so that it behaves like plain img2img) 2023-05-22 21:56:26 +02:00
AUTOMATIC1111 809001fe41 Merge pull request #10623 from akx/bump-gradio
Bump gradio to 3.32
2023-05-22 22:18:05 +03:00
AUTOMATIC1111 d77ba18d5d Merge pull request #10635 from prodialabs/master
disable `timeout_keep_alive`: fixes #10625 #10510 #10474
2023-05-22 22:17:25 +03:00
catboxanon 51d672890d Revert #10586 2023-05-22 13:06:57 -04:00
Kohaku-Blueleaf 403b304162 use sigma_max/min in model if sigma_max/min is 0 2023-05-23 00:29:38 +08:00
Kohaku-Blueleaf 65a87ccc9b Add error information for recursion error 2023-05-23 00:09:49 +08:00
Kohaku-Blueleaf 302d95c726 Minor naming fixes 2023-05-22 23:43:06 +08:00
Kohaku-Blueleaf 4365c35bf9 Avoid loop import 2023-05-22 23:41:14 +08:00
Kohaku-Blueleaf 5dfb1f597b remove not related code 2023-05-22 23:36:16 +08:00
Kohaku-Blueleaf 7dc9d9e27e only add metadata when k_sched is actually been used 2023-05-22 23:34:16 +08:00
Kohaku-Blueleaf 7882f76da4 Replace karras by k_diffusion, fix gen info 2023-05-22 23:26:28 +08:00
Kohaku-Blueleaf f821051443 Change karras to kdiffusion 2023-05-22 23:09:03 +08:00
Kohaku-Blueleaf e6269cba7f Add dropdown for scheduler type 2023-05-22 23:02:05 +08:00
Monty Anderson efc9853059 modules/api/api.py: disable timeout_keep_alive 2023-05-22 15:52:44 +01:00
Kohaku-Blueleaf 90ec557d60 remove debug print 2023-05-22 22:06:13 +08:00
Kohaku-Blueleaf a104879869 Add custom karras scheduler 2023-05-22 21:52:46 +08:00
AUTOMATIC cc2f6e3b7b fix error in dragdrop logic 2023-05-22 15:40:10 +03:00
Aarni Koskela 47b669bc9f Upgrade Gradio, remove docs URL hack 2023-05-22 09:53:24 +03:00
AUTOMATIC ee65e72931 repair file paste for Firefox from #10615
remove animation when pasting files into prompt
rework two dragdrop js files into one
2023-05-22 09:49:59 +03:00
AUTOMATIC1111 0cbcc4d828 Merge pull request #10611 from akx/disable-token-counters
Add option to disable token counters
2023-05-22 08:09:48 +03:00
AUTOMATIC1111 ee2f4fb92d Merge pull request #10615 from missionfloyd/text-drag-fix
Fix dragging text to prompt
2023-05-22 07:15:44 +03:00
AUTOMATIC1111 8137bdba61 Merge branch 'dev' into text-drag-fix 2023-05-22 07:15:34 +03:00
missionfloyd a862428902 Fix dragging text to prompt 2023-05-21 18:17:32 -06:00
AUTOMATIC 3366e494a1 option to pad prompt/neg prompt to be same length 2023-05-22 00:13:53 +03:00
Aarni Koskela 618c59b01d Add option to disable prompt token counters 2023-05-21 23:25:06 +03:00
Aarni Koskela 5ed970b949 Move token counters to separate JS file, fix names 2023-05-21 23:25:06 +03:00
AUTOMATIC 8faac8b963 run basic torch calculation at startup in parallel to reduce the performance impact of first generation 2023-05-21 21:55:14 +03:00
AUTOMATIC 1f3182924b Merge branch 'dev' into release_candidate 2023-05-21 17:37:09 +03:00
AUTOMATIC fdaf0147b6 update readme 2023-05-21 17:36:40 +03:00
AUTOMATIC fe73d6439a Revert "change width/heights slider steps to 64 from 8"
This reverts commit 9a86932c8b.
2023-05-21 17:35:19 +03:00
AUTOMATIC f9fe5e5f9d reworking launch.py: add references to renamed file 2023-05-21 16:27:34 +03:00
AUTOMATIC 4b07984d1b reworking launch.py: rename 2023-05-21 16:27:34 +03:00
AUTOMATIC1111 38a2324dc3 Merge pull request #10580 from akx/add-some-future-annotations
Add some future annotations
2023-05-21 13:43:29 +03:00
AUTOMATIC1111 6fe85e8d5b Merge pull request #10581 from shinshin86/readme-mac-shortcut
[README] Update keyboard shortcut instructions for MacOS users
2023-05-21 13:42:34 +03:00
AUTOMATIC 696f16e901 revert git describe --always --tags for extensions because it seems to be causing issues 2023-05-21 13:30:09 +03:00
AUTOMATIC1111 8e9188aa5a Merge pull request #10564 from AUTOMATIC1111/extensions-clone-depth-1
extensions clone --filter=blob:none
2023-05-21 11:06:26 +03:00
w-e-w cd03317c05 --filter=blob:none
Co-Authored-By: Aarni Koskela <akx@iki.fi>
Co-Authored-By: catboxanon <122327233+catboxanon@users.noreply.github.com>
2023-05-21 16:42:54 +09:00
AUTOMATIC1111 40a61f54e6 Merge pull request #10586 from catboxanon/patch/fix-dpmpp_2m_sde
Discard penultimate sigma for DPM-Solver++(2M) SDE
2023-05-21 10:08:41 +03:00
catboxanon 9a442702d1 Discard penultimate sigma for dpmpp_2m_sde 2023-05-21 01:01:59 -04:00
AUTOMATIC 31545abe14 add DPM-Solver++(2M) SDE from new k-diffusion 2023-05-21 07:31:51 +03:00
AUTOMATIC 0cc05fc492 work on startup profile display 2023-05-21 00:41:41 +03:00
Aarni Koskela df004be2fc Add a couple from __future__ import annotationses for Py3.9 compat 2023-05-21 00:26:16 +03:00
AUTOMATIC1111 3605407033 Merge pull request #10576 from catboxanon/patch/hires-prompt-edit-attn
Support edit attention keyboard shortcuts in hires fix prompts
2023-05-20 23:23:53 +03:00
catboxanon 373903d851 hiresfix prompt: add classes, update css sel 2023-05-20 19:34:50 +00:00
AUTOMATIC 05e6fc9aa9 Merge branch 'ui-selection-for-cross-attention-optimization' into dev 2023-05-20 22:29:51 +03:00
AUTOMATIC1111 cc6c0fc70a Merge pull request #10557 from akx/dedupe-webui-boot
Refactor & deduplicate web UI boot code
2023-05-20 22:24:15 +03:00
AUTOMATIC1111 db1ce5aa26 Merge pull request #10578 from anonCantCode/dev
Preserve Python 3.9 compatibility
2023-05-20 22:11:03 +03:00
catboxanon b2b06eee02 Support edit attn shortcut in hires fix prompts 2023-05-20 13:31:18 -04:00
shinshin86 6a676cc185 Update keyboard shortcut instructions for MacOS users in text selection guidance 2023-05-20 23:14:47 +09:00
w-e-w bf5e5f4269 extensions clone depth 1 2023-05-20 15:08:08 +09:00
anonCantCode 0b6ca8e77b preserve declarations 2023-05-20 11:13:03 +05:30
anonCantCode 3758744eb6 Use Optional[] to preserve Python 3.9 compatability 2023-05-20 06:27:12 +05:30
AUTOMATIC 39ec4f06ff calculate hashes for Lora
add lora hashes to infotext
when pasting infotext, use infotext's lora hashes to find local loras for <lora:xxx:1> entries whose hashes match loras the user has
2023-05-19 22:59:29 +03:00
AUTOMATIC 87702febe0 allow hiding buttons in ui-config.json 2023-05-19 19:04:20 +03:00
AUTOMATIC1111 0d84055eb6 Merge pull request #10291 from akx/test-overhaul
Test overhaul
2023-05-19 18:59:31 +03:00
AUTOMATIC 9a86932c8b change width/heights slider steps to 64 from 8 2023-05-19 18:49:39 +03:00
AUTOMATIC 78dd988e12 simplify PR page 2023-05-19 18:47:19 +03:00
Aarni Koskela 793a491923 Overhaul tests to use py.test 2023-05-19 17:42:34 +03:00
Aarni Koskela 71f4a4afdf Deduplicate webui.py initial-load/reload code 2023-05-19 17:38:42 +03:00
Aarni Koskela 0f28aee9cd Refactor gradio auth 2023-05-19 17:35:51 +03:00
Aarni Koskela 674e80c625 Note pending PR for app_kwargs 2023-05-19 17:35:51 +03:00
Aarni Koskela 8a178e6717 Refactor configure opts_onchange out 2023-05-19 17:35:51 +03:00
Aarni Koskela 8200e0c27b Refactor configure_sigint_handler out 2023-05-19 17:35:51 +03:00
Aarni Koskela 1482c89376 Refactor validate_tls_options out, fix typo (keyfile was there twice) 2023-05-19 17:35:51 +03:00
AUTOMATIC1111 d41a31a508 Merge pull request #10552 from akx/eslint-moar
More Eslint fixes
2023-05-19 16:34:27 +03:00
AUTOMATIC1111 a6bf4aae30 Merge pull request #10550 from akx/git-blame-ignore-revs
Add .git-blame-ignore-revs
2023-05-19 16:28:22 +03:00
Aarni Koskela 4897e5277b Make load_scripts create new runners (removes reload_scripts) 2023-05-19 15:49:53 +03:00
Aarni Koskela a0005121ae Simplify CORS middleware configuration 2023-05-19 15:37:13 +03:00
Aarni Koskela 21ee46eea7 Deduplicate default extra network registration 2023-05-19 15:35:16 +03:00
Aarni Koskela de3abc29ae Fix typo "intialize" 2023-05-19 15:27:23 +03:00
Aarni Koskela 67d4360453 get_tab_index(): use a for loop with early-exit for performance 2023-05-19 13:06:12 +03:00
Aarni Koskela 563e88dd91 Replace args_to_array (and facsimiles) with Array.from 2023-05-19 13:05:26 +03:00
Aarni Koskela 3909c2b2a0 eslintrc: enable no-redeclare but with builtinGlobals: false 2023-05-19 12:57:38 +03:00
Aarni Koskela 247f371d3e eslintrc: mark most globals read-only 2023-05-19 12:57:38 +03:00
Aarni Koskela 958d68fb14 eslintrc: Use a file-local global comment for module 2023-05-19 12:46:44 +03:00
Aarni Koskela 208f066e0e eslintrc: Sort eslint rules 2023-05-19 12:46:41 +03:00
Aarni Koskela 2725dfd8a6 Fix ruff lint 2023-05-19 12:37:34 +03:00
Aarni Koskela 330f14d27a Add .git-blame-ignore-revs 2023-05-19 12:34:06 +03:00
lenankamp ff6acd35d0 Update img2img.py
Hopefully corrected the white space issue
2023-05-19 03:20:19 -04:00
AUTOMATIC 2140bd1c10 make it actually work after suggestions 2023-05-19 10:05:07 +03:00
AUTOMATIC 994f56c3f9 linter fixes 2023-05-19 09:54:55 +03:00
AUTOMATIC1111 fe7bcbe340 Merge pull request #10534 from thot-experiment/dev
rewrite uiElementIsVisible
2023-05-19 09:53:02 +03:00
Thottyottyotty 7b61acbd35 split visibility method and sort instead
split out the visibility method for pasting and use a sort inside the paste handler to prioritize on-screen fields rather than targeting ONLY on screen fields
2023-05-18 23:43:01 -07:00
AUTOMATIC1111 1e5afd4fa9 Apply suggestions from code review
Co-authored-by: Aarni Koskela <akx@iki.fi>
2023-05-19 09:17:36 +03:00
AUTOMATIC1111 8c1148b9ea Merge pull request #10548 from akx/spel-chek-changelog
Spel chek changelog some
2023-05-19 09:14:23 +03:00
AUTOMATIC df6fffb054 change upscalers to download models into user-specified directory (from commandline args) rather than the default models/<...> 2023-05-19 09:09:18 +03:00
AUTOMATIC 379fd6204d make links to http://<...>.git git extensions work in the extension tab 2023-05-19 09:09:17 +03:00
Aarni Koskela 7569677e9e Spel chek changelog some 2023-05-19 08:35:16 +03:00
AUTOMATIC1111 e38e7dbfb9 Merge pull request #10529 from ryankashi/master
Added /sdapi/v1/refresh-loras api checkpoint post request
2023-05-19 08:04:13 +03:00
Thottyottyotty e373fd0c00 rewrite uiElementIsVisible
rewrite visibility checking to be more generic/cleaner as well as add functionality to check if the element is scrolled on screen for more intuitive paste-target selection
2023-05-18 16:09:09 -07:00
ryankashi 4dd5559162 Added the refresh-loras post request 2023-05-18 14:12:01 -07:00
AUTOMATIC 8a3d232839 fix linter issues 2023-05-19 00:03:27 +03:00
AUTOMATIC a375acdd26 update CHANGELOG 2023-05-19 00:01:52 +03:00
AUTOMATIC a6bbc6aa8c set Navigate image viewer with gamepad option to false by default, by request 2023-05-18 23:59:31 +03:00
AUTOMATIC1111 4f42acd9ba Merge pull request #10524 from kamnxt/fix-xyz-hashes
Use name in xyz_grid
2023-05-18 23:46:39 +03:00
Kamil Krzyżanowski 161b2944b8 Use name instead of hash in xyz_grid
X/Y/Z grid was still using the old hash, prone to collisions. This changes it to use the name instead.

Should fix #10521.
2023-05-18 22:27:04 +02:00
AUTOMATIC 3d959f5b49 Merge remote-tracking branch 'missionfloyd/extra-network-preview-lazyload' into dev 2023-05-18 23:23:13 +03:00
AUTOMATIC1111 6837cf6a8d Merge pull request #10520 from catboxanon/dev
Remove blinking effect from text in hires fix and scale resolution preview
2023-05-18 22:58:20 +03:00
AUTOMATIC bd877d7b5a rework #10519 2023-05-18 22:49:00 +03:00
AUTOMATIC 2582a0fd3b make it possible for scripts to add cross attention optimizations
add UI selection for cross attention optimization
2023-05-18 22:48:28 +03:00
catboxanon 36791cb6af Fix blinking text of hr and scale res
goodbye
2023-05-18 14:04:55 -04:00
AUTOMATIC1111 2e006fa500 Merge pull request #10519 from catboxanon/patch/hires-input-release-event
Improve width/height slider responsiveness
2023-05-18 20:32:21 +03:00
AUTOMATIC b5a0c6da37 Revert "Merge pull request #10440 from grimatoma/increaseModelPickerWidth"
This reverts commit 4b07f2f584, reversing
changes made to 4071fa4a12.
2023-05-18 20:25:33 +03:00
catboxanon 57275da903 Reorder variable assignment 2023-05-18 13:25:32 -04:00
AUTOMATIC 92902e180e bump gradio 2023-05-18 20:25:07 +03:00
AUTOMATIC ff0e17174f rework hires prompts/sampler code to among other things support different extra networks in first/second pass
rework quoting for infotext items that have commas in them to use json (should be backwards compatible except for cases where it didn't work previously)
add some locals from processing function into the Processing class as fields
2023-05-18 20:16:09 +03:00
catboxanon 63c02314cc .change -> .release for hires input
Improves overall UI responsiveness.
2023-05-18 13:06:13 -04:00
AUTOMATIC 5ec2c294ee Merge remote-tracking branch 'InvincibleDude/improved-hr-conflict-test' into hires-fix-ext 2023-05-18 17:57:16 +03:00
AUTOMATIC1111 3885f8a63e Merge pull request #10381 from AUTOMATIC1111/minor-fix
Minor fix
2023-05-18 17:51:58 +03:00
AUTOMATIC 44c37f94e1 add messages about Loras that failed to load to UI 2023-05-18 16:36:30 +03:00
AUTOMATIC cd8a510ca9 if sd_model is None, do not always try to load it 2023-05-18 15:47:43 +03:00
Sakura-Luna 96cba45d71 Modify xformers instead of pytorch 2023-05-18 17:29:47 +08:00
AUTOMATIC ae252cd5bc add --gradio-allowed-path commandline option 2023-05-18 10:37:25 +03:00
AUTOMATIC1111 7fd80951ad Merge pull request #10465 from baptisterajaut/master
Bump pytorch to 2.0 for AMD Users on Linux
2023-05-18 10:26:57 +03:00
AUTOMATIC1111 97e1cf69c0 Merge branch 'dev' into master 2023-05-18 10:26:35 +03:00
AUTOMATIC bb431df52b python linter fixes 2023-05-18 10:16:33 +03:00
AUTOMATIC f9be4dc498 keep old option for ngrok 2023-05-18 10:14:04 +03:00
AUTOMATIC1111 b4b42de9d5 Merge pull request #10438 from bobzilladev/ngrok-py
Use ngrok-py library
2023-05-18 10:12:41 +03:00
AUTOMATIC1111 182330ae40 Merge branch 'dev' into ngrok-py 2023-05-18 10:12:17 +03:00
AUTOMATIC1111 983f2c494a Merge pull request #10499 from dongweiming/error-improvement
Error improvement for install torch
2023-05-18 10:09:23 +03:00
AUTOMATIC bb80eea9d4 eslint the merged code 2023-05-18 10:03:48 +03:00
AUTOMATIC c08f229318 Merge branch 'eslint' into dev 2023-05-18 10:02:17 +03:00
AUTOMATIC 57b75f4a03 eslint related file edits 2023-05-18 09:59:10 +03:00
AUTOMATIC f88169a9e7 extend eslint config 2023-05-18 09:58:49 +03:00
Weiming aa6e98e43c Error Improvement for install torch 2023-05-18 13:25:48 +08:00
AUTOMATIC1111 1ceb82bc74 Merge pull request #8665 from Vespinian/fix_img2img_scriptrunner_for_gui
fix [Bug]: Changed gui's img2img p.scripts from scripts_txt2img to scripts_img2img
2023-05-18 00:05:01 +03:00
AUTOMATIC 3694379f26 rework #8863 to work with all img2img tabs 2023-05-18 00:03:16 +03:00
AUTOMATIC 973ae87309 Merge remote-tracking branch 'pieresimakp/img2img-detect-image-size' into dev 2023-05-17 23:49:39 +03:00
AUTOMATIC 61ee563df9 option to specify editor height for img2img 2023-05-17 23:42:01 +03:00
AUTOMATIC e5dd4b4ebf remove some code duplication from #9348 2023-05-17 23:27:06 +03:00
AUTOMATIC1111 1d1b5da4bf Merge pull request #9348 from space-nuko/improve-frontend-responsiveness
Improve frontend responsiveness for some buttons
2023-05-17 23:19:08 +03:00
AUTOMATIC1111 04b4508a66 Merge branch 'dev' into improve-frontend-responsiveness 2023-05-17 23:18:56 +03:00
AUTOMATIC b397f63e00 add option to reorder tabs
fix Reload UI not working
2023-05-17 23:11:33 +03:00
AUTOMATIC 30410fd355 simplify name pattern setting tooltips 2023-05-17 22:54:45 +03:00
AUTOMATIC1111 6a13c416f6 Merge pull request #10222 from AUTOMATIC1111/readme-simple-installation-method
add documentation for simple installation method using release package
2023-05-17 22:51:17 +03:00
AUTOMATIC ad3a7f2ab9 alternative solution to fix styles load when edited by human #9765 as suggested by akx 2023-05-17 22:50:08 +03:00
AUTOMATIC f6fc7916c4 add /sdapi/v1/script-info api 2023-05-17 22:43:24 +03:00
AUTOMATIC 8fe9ea7f4d add options to show/hide hidden files and dirs, and to not list models/files in hidden directories 2023-05-17 21:45:26 +03:00
AUTOMATIC a6b618d072 use a single function for saving images with metadata both in extra networks and main mode for #10395 2023-05-17 21:03:41 +03:00
AUTOMATIC1111 9c91a86720 Merge pull request #10395 from wk5ovc/patch-4
Fix extra networks save preview image geninfo
2023-05-17 20:42:37 +03:00
AUTOMATIC1111 6b51cc7530 Merge pull request #10400 from AUTOMATIC1111/Sakura-Luna-patch-1
Add Python version
2023-05-17 20:34:45 +03:00
AUTOMATIC f6a622bcef isn't there something you forgot, #10483? 2023-05-17 20:27:48 +03:00
AUTOMATIC1111 987c1f7d9f Merge pull request #10483 from Iheuzio/syntax-search
Fix typo in syntax
2023-05-17 20:27:14 +03:00
AUTOMATIC 9fd6c1e343 move some settings to the new Optimization page
add slider for token merging for img2img
rework StableDiffusionProcessing to have the token_merging_ratio field
fix a bug with applying png optimizations for live previews when they shouldn't be applied
2023-05-17 20:22:54 +03:00
Iheuzio f5092164e8 Fix typo in syntax 2023-05-17 12:51:54 -04:00
AUTOMATIC1111 f6c06e3ed2 Merge pull request #10458 from akx/graceful-stop
Graceful server stopping
2023-05-17 18:45:40 +03:00
AUTOMATIC 216b0fa6c9 when adding tooltips, do not scan whole document and instead only scan added elements 2023-05-17 18:26:53 +03:00
AUTOMATIC1111 3c81d184c0 Merge pull request #10414 from AUTOMATIC1111/xyz-token-merging
xyz token merging
2023-05-17 18:06:55 +03:00
AUTOMATIC 76ebf750a4 use a local variable instead of dictionary entry for sd_merge_models in merge model metadata code 2023-05-17 17:44:07 +03:00
AUTOMATIC1111 36c14831b3 Merge pull request #10473 from dongweiming/fix-10460
Fix #10460
2023-05-17 17:42:25 +03:00
Weiming 95cb492e41 Fixed: #10460 2023-05-17 22:35:59 +08:00
AUTOMATIC f8ca37b903 fix inability to run with --freeze-settings 2023-05-17 17:07:11 +03:00
Aarni Koskela 9c54b78d9d Run eslint --fix (and normalize tabs to spaces) 2023-05-17 16:09:06 +03:00
Aarni Koskela 4f11f285f9 Add ESLint to CI 2023-05-17 16:09:06 +03:00
Aarni Koskela 13f4c62ba3 Add basic ESLint configuration for formatting
This doesn't enable any of ESLint's actual possible-issue linting,
but just style normalization based on the Prettier configuration (but without line length limits).
2023-05-17 16:09:06 +03:00
AUTOMATIC1111 b4703b788b Merge pull request #10461 from akx/processed-s-min-uncond
Copy s_min_uncond to Processed
2023-05-17 15:08:14 +03:00
AUTOMATIC 1210548cba simplify single_sample_to_image 2023-05-17 14:53:39 +03:00
AUTOMATIC1111 875ccc27f6 Merge pull request #10467 from Sakura-Luna/taesd-a
Tiny AE fix
2023-05-17 14:45:38 +03:00
Sakura-Luna 7a13a3f4ba TAESD fix 2023-05-17 17:39:07 +08:00
Baptiste Rajaut 484948f5c0 Fixing webui.sh
If only i proofread what i wrote
2023-05-17 11:10:57 +02:00
Baptiste Rajaut b3397c2492 Bump pytorch for AMD Users
So apparently it works now? Before you would get "Pytorch cant use the GPU" but not anymore.
2023-05-17 11:01:33 +02:00
Aarni Koskela 315f109427 Copy s_min_uncond to Processed
Should fix #10416
2023-05-17 10:26:32 +03:00
Aarni Koskela 875990a232 Add option for /_stop route (for graceful shutdown) 2023-05-17 10:15:08 +03:00
Aarni Koskela 85b4f89926 Replace state.need_restart with state.server_command + replace poll loop with signal 2023-05-17 10:15:03 +03:00
AUTOMATIC1111 9ac85b8b73 Merge pull request #10365 from Sakura-Luna/taesd-a
Add Tiny AE live preview
2023-05-17 09:26:50 +03:00
AUTOMATIC1111 85232a5b26 Merge branch 'dev' into taesd-a 2023-05-17 09:26:26 +03:00
AUTOMATIC 56a2672831 return live preview defaults to how they were
only download TAESD model when it's needed
return calculations in single_sample_to_image to just if/elif/elif blocks
keep taesd model in its own directory
2023-05-17 09:24:01 +03:00
AUTOMATIC b217ebc490 add credits 2023-05-17 08:41:21 +03:00
AUTOMATIC1111 4b07f2f584 Merge pull request #10440 from grimatoma/increaseModelPickerWidth
Remove max width for model dropdown
2023-05-17 08:27:25 +03:00
AUTOMATIC1111 4071fa4a12 Merge pull request #10451 from dennissheng/master
not clear checkpoints cache when config changes
2023-05-17 08:24:56 +03:00
AUTOMATIC1111 0003b29044 Merge pull request #10452 from dongweiming/fix-neg
Fix remove `textual inversion` prompt
2023-05-17 08:18:54 +03:00
dennissheng 54f657ffbc not clear checkpoints cache when config changes 2023-05-17 10:47:02 +08:00
Weiming e378590d33 Fix remove textual inversion prompt 2023-05-17 10:20:11 +08:00
grimatoma a4d5fdd3c2 Remove max width for model dropdown
Removing the max width for the model dropdown allows the user to see the full name of a model especially when it is long.
Model names are getting more complex and longer and the current width almost always cuts off model names.
If a user leverages folders than it pretty much always cuts off the name...
2023-05-16 13:32:32 -07:00
bobzilladev 0d31f20cbd Use ngrok-py library 2023-05-16 16:09:41 -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
Sakura-Luna 4fb2cc0f06 Minor change 2023-05-17 00:32:32 +08:00
AUTOMATIC ce38ee8f26 add info link for Negative Guidance minimum sigma 2023-05-16 15:41:49 +03:00
AUTOMATIC 6302978ff8 restore nqsp in footer that was lost during linting 2023-05-16 15:14:44 +03:00
AUTOMATIC a61cbef02c add second_order field to sampler config 2023-05-16 12:36:15 +03:00
AUTOMATIC cdac5ace14 suppress ENSD infotext for samplers that don't use it 2023-05-16 11:54:02 +03:00
AUTOMATIC 3d76eabbca add visual progress for extension installation from URL 2023-05-16 07:59:43 +03:00
AUTOMATIC a47abe1b7b update extensions table: show branch, show date in separate column, and show version from tags if available 2023-05-15 21:22:35 +03:00
AUTOMATIC 0d2a4b608c load extensions' git metadata in parallel to loading the main program to save a ton of time during startup 2023-05-15 20:57:11 +03:00
AUTOMATIC 0d3a80e269 Show "Loading..." for extra networks when displaying for the first time 2023-05-15 20:33:44 +03:00
w-e-w 9e90907532 xyz token merging 2023-05-16 02:02:51 +09:00
Sakura-Luna 32af211f4c Add Python version
Many users still use unverified versions of Python and file version-specific issues, often without mentioning version information, making troubleshooting difficult.
2023-05-15 15:42:37 +08:00
Keith f517838c75 Fix extra networks save preview image geninfo 2023-05-15 10:47:01 +08:00
Sakura-Luna 742da31932 Minor changes 2023-05-15 03:04:34 +08:00
Sakura-Luna 9a9557ecfc Change to extra-index-url 2023-05-15 03:00:23 +08:00
Sakura-Luna 38583be7af Revert Gradio version 2023-05-15 02:37:43 +08:00
AUTOMATIC1111 f6a2a98f1a Merge pull request #10379 from AUTOMATIC1111/Sakura-Luna-patch-1
Add GPU device
2023-05-14 21:18:55 +03:00
AUTOMATIC1111 d7d378eda1 Merge pull request #10384 from akx/no-shell
launch.py: Don't involve shell for running Python or getting Git output
2023-05-14 21:18:09 +03:00
Aarni Koskela d9968e6108 launch.py: Don't involve shell for running Python or Git for output
Fixes Linux regression in 451d255b58
2023-05-14 20:39:19 +03:00
AUTOMATIC1111 1b7e787733 Merge pull request #10382 from AUTOMATIC1111/fix_xyz_checkpoint
fix xyz checkpoint
2023-05-14 19:01:36 +03:00
w-e-w a98ae89bde fix xyz checkpoint 2023-05-15 00:31:34 +09:00
Sakura-Luna b023940032 Update bug_report.yml 2023-05-14 22:39:38 +08:00
Sakura-Luna f29c41bf6d Modify pytorch command 2023-05-14 22:29:28 +08:00
Sakura-Luna ef046fae39 Downgrade Gradio 2023-05-14 22:26:43 +08:00
Sakura-Luna efe81620a0 Add GPU device
Add GPU option to troubleshoot.
2023-05-14 22:17:36 +08:00
AUTOMATIC 7001e1ed61 Merge branch 'master' into dev 2023-05-14 13:36:16 +03:00
AUTOMATIC 89f9faa633 Merge branch 'release_candidate' 2023-05-14 13:35:07 +03:00
AUTOMATIC dbd13dee3a update readme for release 2023-05-14 13:34:50 +03:00
AUTOMATIC b9abdb50a3 add a possible fix for 'LatentDiffusion' object has no attribute 'lora_layer_mapping' 2023-05-14 13:31:03 +03:00
AUTOMATIC 1a43524018 fix model loading twice in some situations 2023-05-14 13:27:50 +03:00
AUTOMATIC1111 5f5435eb1a Merge pull request #10218 from micky2be/find_vae
Files in vae folder with same name as a checkpoint can be found too
2023-05-14 11:46:36 +03:00
AUTOMATIC1111 80adb6979d Merge branch 'dev' into find_vae 2023-05-14 11:46:27 +03:00
AUTOMATIC1111 3ddc763422 Merge pull request #10367 from AUTOMATIC1111/jpeg-extra-network-preview
allow jpeg for extra network preview
2023-05-14 11:40:03 +03:00
AUTOMATIC a58ae0b717 remove auto live previews format option, fix slow PNG generation 2023-05-14 11:15:15 +03:00
AUTOMATIC a00e42556f add a bunch of descriptions and reword a lot of settings (sorry, localizers) 2023-05-14 11:04:21 +03:00
w-e-w a423f23d28 allow jpeg for extra network preview 2023-05-14 16:22:40 +09:00
AUTOMATIC ce515b81c5 set up a system to provide extra info for settings elements in python rather than js
add a bit of spacing/styling to settings elements
add link info for token merging
2023-05-14 10:02:51 +03:00
Sakura-Luna bd9b9d425a Add live preview mode check 2023-05-14 14:06:02 +08:00
Sakura-Luna e14b586d04 Add Tiny AE live preview 2023-05-14 14:06:01 +08:00
AUTOMATIC 2cfaffb239 updates for #9256 2023-05-14 08:30:37 +03:00
AUTOMATIC1111 7f6ef764b9 Merge pull request #9256 from papuSpartan/tomesd
Integrate optional speed and memory improvements by token merging (via dbolya/tomesd)
2023-05-14 08:21:02 +03:00
AUTOMATIC 005849331e remove output_altered flag from AfterCFGCallbackParams 2023-05-14 08:15:22 +03:00
AUTOMATIC1111 cb9a3a7809 Merge pull request #10357 from catboxanon/sag
Add/modify CFG callbacks for Self-Attention Guidance extension
2023-05-14 08:06:45 +03:00
AUTOMATIC1111 4051d51caf Merge pull request #10292 from akx/smol-bump
Bump some versions to avoid downgrading them
2023-05-14 07:59:28 +03:00
Sakura-Luna 8abfc95013 Update script_callbacks.py 2023-05-14 12:56:34 +08:00
catboxanon 3078001439 Add/modify CFG callbacks
Required by self-attn guidance extension
https://github.com/ashen-sensored/sd_webui_SAG
2023-05-14 01:49:41 +00:00
AUTOMATIC d7e9ac2aff update readme 2023-05-13 20:47:32 +03:00
AUTOMATIC1111 86ff43b930 Merge pull request #10335 from akx/l10n-dis-take-2
Localization fixes
2023-05-13 20:46:50 +03:00
AUTOMATIC e8eea1bb7a Merge branch 'release_candidate' into dev 2023-05-13 20:26:13 +03:00
AUTOMATIC 2053745c8f Merge branch 'v1.2.0-hotfix' into release_candidate 2023-05-13 20:25:03 +03:00
AUTOMATIC 27f7fbf35c update readme 2023-05-13 20:24:48 +03:00
AUTOMATIC1111 12c78138dd Merge pull request #10324 from catboxanon/offline
Allow web UI to be ran fully offline
2023-05-13 20:22:09 +03:00
AUTOMATIC1111 063848798c Merge pull request #10339 from catboxanon/bf16
Allow bf16 in safe unpickler
2023-05-13 20:21:39 +03:00
AUTOMATIC 7e3539df6f fix upscalers disappearing after the user reloads UI 2023-05-13 20:21:11 +03:00
AUTOMATIC 477199357f add an option to always refer to lora by filenames
never refer to lora by an alias if multiple loras have same alias or the alias is called none
2023-05-13 20:15:37 +03:00
AUTOMATIC1111 d70c3a807b Merge pull request #10339 from catboxanon/bf16
Allow bf16 in safe unpickler
2023-05-13 19:45:18 +03:00
AUTOMATIC1111 cdb1ffb2f4 Merge pull request #10335 from akx/l10n-dis-take-2
Localization fixes
2023-05-13 19:44:55 +03:00
AUTOMATIC1111 23b62afc72 Merge pull request #10324 from catboxanon/offline
Allow web UI to be ran fully offline
2023-05-13 19:43:15 +03:00
Aarni Koskela cd6990c243 Make dump translations work again 2023-05-13 19:22:39 +03:00
Aarni Koskela 1f57b948b7 Move localization to its own script block and load it first 2023-05-13 19:15:13 +03:00
papuSpartan c2fdb44880 fix for img2img 2023-05-13 11:11:02 -05:00
papuSpartan 917faa5325 move to stable-diffusion tab 2023-05-13 10:26:09 -05:00
papuSpartan ac83627a31 heavily simplify 2023-05-13 10:23:42 -05:00
catboxanon cb5f61281a Allow bf16 in safe unpickler 2023-05-13 11:04:26 -04:00
papuSpartan 55e52c878a remove command line option 2023-05-13 09:24:56 -05:00
catboxanon 867c8a1083 minor fix 2023-05-13 12:59:00 +00:00
catboxanon 5afc44aab1 Requested changes 2023-05-13 12:57:32 +00:00
Aarni Koskela 999a03e4a7 Wait for DOMContentLoaded until checking whether localization should be disabled
Refs https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/9955#issuecomment-1546587143
2023-05-13 15:12:30 +03:00
AUTOMATIC 2b3fc246b0 Merge branch 'master' into dev 2023-05-13 08:19:21 +03:00
AUTOMATIC 4135937876 update changelog for release 2023-05-13 08:18:49 +03:00
AUTOMATIC d274b8297e fix broken prompts from file 2023-05-13 08:18:49 +03:00
AUTOMATIC b08500cec8 Merge branch 'release_candidate' 2023-05-13 08:16:37 +03:00
AUTOMATIC 231562ea13 update changelog for release 2023-05-13 08:16:20 +03:00
catboxanon 867be74244 Define default fonts for Gradio theme
Allows web UI to (almost) be ran fully offline.
The web UI will hang on load if offline when
these fonts are not manually defined, as it will attempt (and fail)
to pull from Google Fonts.
2023-05-12 18:08:34 +00:00
catboxanon b14e23529f Redirect Gradio phone home request
This request is sent regardless of Gradio analytics being
enabled or not via the env var.
Idea from text-generation-webui.
2023-05-12 18:06:13 +00:00
AUTOMATIC1111 9080af56dd Merge pull request #10321 from akx/fix-launch-git-get
launch.py: fix git_tag() & fix commit_hash() & simplify
2023-05-12 21:01:37 +03:00
AUTOMATIC1111 b4ad31ddd4 Merge pull request #10318 from brkirch/set-pytorch-201-mac
Set PyTorch version to 2.0.1 for macOS
2023-05-12 20:56:42 +03:00
Aarni Koskela 451d255b58 Get rid of check_run + run_python 2023-05-12 20:54:06 +03:00
Aarni Koskela 55d222a9f4 launch.py: make git_tag() and commit_hash() work even when WEBUI_LAUNCH_LIVE_OUTPUT 2023-05-12 20:54:06 +03:00
brkirch 0cab07b2f1 Set PyTorch version to 2.0.1 for macOS 2023-05-12 11:15:43 -04:00
AUTOMATIC1111 54c84e63b3 Merge pull request #10317 from AUTOMATIC1111/fix-COMMANDLINE_ARGS--data-dir
fix --data-dir ignored when launching via webui-user.bat COMMANDLINE_ARGS
2023-05-12 16:50:42 +03:00
w-e-w 681c16dd1e fix --data-dir for COMMANDLINE_ARGS
move reading of COMMANDLINE_ARGS into paths_internal.py so --data-dir can be properly read
2023-05-12 22:33:21 +09:00
papuSpartan 75b3692920 Merge branch 'dev' of https://github.com/AUTOMATIC1111/stable-diffusion-webui into tomesd 2023-05-11 22:40:17 -05:00
Aarni Koskela d4bd67bd67 Bump versions to avoid downgrading them 2023-05-11 23:12:43 +03:00
AUTOMATIC1111 abe32cefa3 Merge pull request #10285 from akx/ruff-spacing
Indentation + ruff whitespace fixes
2023-05-11 21:25:15 +03:00
AUTOMATIC1111 b4aaa339d5 Merge pull request #10290 from akx/smart-live-preview-format
Make live previews use JPEG only for large images
2023-05-11 21:24:44 +03:00
Aarni Koskela da10de022f Make live previews use JPEG only when the image is lorge enough 2023-05-11 20:54:40 +03:00
Aarni Koskela 49a55b410b Autofix Ruff W (not W605) (mostly whitespace) 2023-05-11 20:29:11 +03:00
AUTOMATIC1111 ba7ae7b948 Merge pull request #10286 from catboxanon/patch/extra-networks-symlinks
Fix symlink scanning for extra networks
2023-05-11 19:47:15 +03:00
catboxanon cb3f8ff59f Fix symlink scanning 2023-05-11 15:55:43 +00:00
Aarni Koskela 431bc5a297 Reindent utils_test with 4 spaces 2023-05-11 18:26:34 +03:00
Aarni Koskela 098d2fda52 Reindent autocrop with 4 spaces 2023-05-11 18:26:04 +03:00
AUTOMATIC 8ca50f8240 fix broken prompts from file 2023-05-11 14:49:14 +03:00
AUTOMATIC 483545252f fix broken prompts from file 2023-05-11 14:24:22 +03:00
AUTOMATIC 0bfaf613a8 put the star where it belongs 2023-05-11 13:31:56 +03:00
AUTOMATIC1111 fb366891ab Merge pull request #10274 from akx/torch-cpu-for-tests
Use CPU Torch in CI, etc.
2023-05-11 12:50:00 +03:00
Aarni Koskela 5b592669f9 CI: use launch.py for dependencies too 2023-05-11 11:57:46 +03:00
Aarni Koskela c702010e57 CI: use CPU wheel repo for PyTorch 2023-05-11 11:57:46 +03:00
Aarni Koskela dd3ca9adf7 launch.py: make torch_index_url an envvar 2023-05-11 11:57:46 +03:00
Aarni Koskela a09e1e6e18 launch.py: Use GitHub archive URLs for gfpgan, clip, openclip instead of git clones 2023-05-11 11:57:43 +03:00
Aarni Koskela 875bc27009 launch.py: Simplify run() 2023-05-11 11:57:41 +03:00
Aarni Koskela 49db24ce27 launch.py: Add debugging envvar to see install output 2023-05-11 11:57:36 +03:00
AUTOMATIC1111 4445314c68 Merge pull request #10273 from AUTOMATIC1111/roboto-without-a-dep
Vendor Roboto font
2023-05-11 11:25:23 +03:00
AUTOMATIC 87c3aa7389 return wrap_gradio_gpu_call to webui.py for extensions 2023-05-11 10:09:42 +03:00
Aarni Koskela 1332c46b71 Drop fonts + font-roboto deps since we only use the single regular cut of Roboto 2023-05-11 10:07:28 +03:00
Aarni Koskela df7070eca2 Deduplicate get_font code 2023-05-11 10:06:19 +03:00
Aarni Koskela 16e4d79122 paths_internal: deduplicate modules_path 2023-05-11 10:05:39 +03:00
AUTOMATIC1111 3bb964d806 Merge pull request #10272 from AUTOMATIC1111/clean-fid
Update clean-fid to loosen transitive dependency pins
2023-05-11 09:36:08 +03:00
Sakura-Luna 1dcd672324 Update sd_vae.py
There is no need to use split.
2023-05-11 14:29:52 +08:00
Aarni Koskela ef11c197b3 Update clean-fid to loosen transitive dependency pins
Diff: https://github.com/GaParmar/clean-fid/compare/bd92e684ff06819058083c5a9fddc6f712045d46...c8ffa420a3923e8fd87c1e75170de2cf59d2644b
2023-05-11 08:48:08 +03:00
AUTOMATIC1111 fe5d988947 Merge pull request #10268 from Sakura-Luna/pbar
UniPC progress bar adjustment
2023-05-11 08:16:36 +03:00
AUTOMATIC b7e160a87d change live preview format to jpeg to prevent unreasonably slow previews for large images, and add an option to let user select the format 2023-05-11 08:14:45 +03:00
AUTOMATIC e334758ec2 repair #10266 2023-05-11 07:45:05 +03:00
Sakura-Luna ae17e97898 UniPC progress bar adjustment 2023-05-11 12:28:26 +08:00
AUTOMATIC1111 c9e5b92106 Merge pull request #10266 from nero-dv/dev
Update sub_quadratic_attention.py
2023-05-11 07:21:18 +03:00
Louis Del Valle c8732dfa6f Update sub_quadratic_attention.py
1. Determine the number of query chunks.
2. Calculate the final shape of the res tensor.
3. Initialize the tensor with the calculated shape and dtype, (same dtype as the input tensors, usually)

Can initialize the tensor as a zero-filled tensor with the correct shape and dtype, then compute the attention scores for each query chunk and fill the corresponding slice of tensor.
2023-05-10 22:05:18 -05:00
AUTOMATIC 8aa87c564a add UI to edit defaults
allow setting defaults for elements in extensions' tabs
fix a problem with ESRGAN upscalers disappearing after UI reload
implicit change: HTML element id for train tab from tab_ti to tab_train (will this break things?)
2023-05-10 23:41:08 +03:00
AUTOMATIC1111 5abecea34c Merge pull request #10259 from AUTOMATIC1111/ruff
Ruff
2023-05-10 21:24:18 +03:00
AUTOMATIC 3ec7b705c7 suggestions and fixes from the PR 2023-05-10 21:21:32 +03:00
AUTOMATIC d25219b7e8 manual fixes for some C408 2023-05-10 11:55:09 +03:00
AUTOMATIC a5121e7a06 fixes for B007 2023-05-10 11:37:18 +03:00
AUTOMATIC 550256db1c ruff manual fixes 2023-05-10 11:19:16 +03:00
AUTOMATIC 028d3f6425 ruff auto fixes 2023-05-10 11:05:02 +03:00
AUTOMATIC e42de4b8a2 update ruff config with more stuff 2023-05-10 11:00:07 +03:00
AUTOMATIC 57ef617251 integrate the PR's config 2023-05-10 09:09:41 +03:00
AUTOMATIC1111 837d3a94b7 Merge pull request #10233 from akx/fix-lint-ci
Replace pylint CI with ruff
2023-05-10 09:06:54 +03:00
AUTOMATIC 4b854806d9 F401 fixes for ruff 2023-05-10 09:02:23 +03:00
AUTOMATIC f741a98bac imports cleanup for ruff 2023-05-10 08:43:42 +03:00
AUTOMATIC 96d6ca4199 manual fixes for ruff 2023-05-10 08:25:25 +03:00
AUTOMATIC 762265eab5 autofixes from ruff 2023-05-10 07:52:45 +03:00
AUTOMATIC a617d64882 add ruff config 2023-05-10 07:43:55 +03:00
AUTOMATIC f5ea1e9d92 bump torch version 2023-05-10 07:26:42 +03:00
AUTOMATIC d50b95b5a3 fix an issue preventing the program from starting if the user specifies a bad gradio theme 2023-05-10 07:14:13 +03:00
AUTOMATIC 921dc4639b Merge branch 'dev' into release_candidate 2023-05-10 06:53:25 +03:00
AUTOMATIC f07af8db64 bump gradio version for all suffering musicians 2023-05-10 06:52:51 +03:00
Aarni Koskela 990ca80cb6 Replace pylint CI with ruff 2023-05-09 23:13:47 +03:00
AUTOMATIC c8791c1d37 Merge branch 'dev' into release_candidate 2023-05-09 22:42:37 +03:00
AUTOMATIC 31397986e7 changelog 2023-05-09 22:42:02 +03:00
AUTOMATIC1111 d6a9b22c19 Merge pull request #10232 from akx/eff
Fix up string formatting/concatenation to f-strings where feasible
2023-05-09 22:40:51 +03:00
AUTOMATIC1111 ccbb361845 Merge pull request #10209 from AUTOMATIC1111/quicksettings-migration
1.1.1 quicksettings list migration
2023-05-09 22:29:08 +03:00
Aarni Koskela 3ba6c3c83c Fix up string formatting/concatenation to f-strings where feasible 2023-05-09 22:25:39 +03:00
w-e-w 81bbe31d9f add documentation for simple installation method using release package 2023-05-10 00:04:36 +09:00
Micky Brunetti 749a93295e remove logs 2023-05-09 15:43:58 +02:00
Micky Brunetti 7fd3a4e6d7 files in vae folder with same name as a checkpoint can be found too 2023-05-09 15:35:57 +02:00
AUTOMATIC1111 8fb16ceb28 Merge pull request #10214 from AUTOMATIC1111/refresh-fix
Refresh fix
2023-05-09 15:29:48 +03:00
Sakura-Luna e7dbefc340 refresh fix 2023-05-09 19:06:00 +08:00
w-e-w d1ff57e1cb 1.1.1 quicksettings list migration 2023-05-09 18:14:12 +09:00
AUTOMATIC ad6ec02261 prevent Reload UI button/link from reloading the page when it's not yet ready 2023-05-09 11:42:47 +03:00
AUTOMATIC eb95809501 rework loras api 2023-05-09 11:25:46 +03:00
AUTOMATIC1111 7e02a00c81 Merge pull request #10194 from DumoeDss/dev
Add api method to get LoRA models with prompt
2023-05-09 11:12:13 +03:00
AUTOMATIC 11ae5399f6 make it so that custom context menu from contextMenu.js only disappears after user's click, ignoring non-user click events 2023-05-09 10:52:14 +03:00
AUTOMATIC1111 ea05ddfec8 Merge pull request #10201 from brkirch/mps-nan-fixes
Fix MPS on PyTorch 2.0.1, Intel Macs
2023-05-09 10:28:24 +03:00
brkirch de401d8ffb Fix generation with k-diffusion/UniPC on x64 Macs 2023-05-09 01:10:13 -04:00
brkirch 9efb809f7c Remove PyTorch 2.0 check
Apparently the commit in the main branch of pytorch/pytorch that fixes this issue didn't make it into PyTorch 2.0.1, and since it is unclear exactly which release will have it we'll just always apply the workaround so a crash doesn't occur regardless.
2023-05-09 01:10:13 -04:00
AUTOMATIC 2b96a7b694 add links to wiki for filename pattern settings
add extended info for quicksettings setting
2023-05-08 16:46:35 +03:00
AUTOMATIC 5edb0acfeb use multiselect for quicksettings (this also resets the existing setting) 2023-05-08 15:38:25 +03:00
Sayo f9abe4cddc Add api method to get LoRA models with prompt 2023-05-08 20:38:10 +08:00
AUTOMATIC fc966c0299 do not show licenses page when user selects Show all pages in settings 2023-05-08 15:30:32 +03:00
AUTOMATIC eabea24eb8 put infotext options into their own category in settings tab 2023-05-08 15:26:23 +03:00
AUTOMATIC ab4ab4e595 add version to infotext, footer and console output when starting 2023-05-08 15:23:49 +03:00
brkirch 7aab389d6f Fix for Unet NaNs 2023-05-08 08:16:56 -04:00
AUTOMATIC 505a10ad92 use file modification time instead of current time for #9760 2023-05-08 15:09:20 +03:00
AUTOMATIC1111 879ed5422c Merge pull request #9760 from Sakura-Luna/refresh
Fix gallery not being refreshed correctly
2023-05-08 15:06:02 +03:00
AUTOMATIC1111 b3a44385b1 Merge pull request #10025 from acncagua/Upscaler_initialization
Initialize the upscalers
2023-05-08 15:03:59 +03:00
Sayo 34a82a345a Add api method to get LoRA models 2023-05-08 19:55:05 +08:00
AUTOMATIC 6a5901a3fd update changelog 2023-05-08 12:45:22 +03:00
AUTOMATIC f62540b2d2 Revert "add mtime to served images in gallery to prevent cache from showing old images"
This reverts commit 669b518cbd.
2023-05-08 12:18:22 +03:00
AUTOMATIC 18fb2162a4 disable useless progress display when pasting infotext using the blur button 2023-05-08 12:17:36 +03:00
AUTOMATIC ec0da07236 Lora: add an option to use old method of applying loras 2023-05-08 12:07:43 +03:00
AUTOMATIC 083dc3c76a directory hiding for extra networks: dirs starting with . will hide their cards on extra network tabs unless specifically searched for
create HTML for extra network pages only on demand
allow directories starting with . to still list their models for lora, checkpoints, etc
keep "search" filter for extra networks when user refreshes the page
2023-05-08 11:33:45 +03:00
AUTOMATIC1111 855f83f92c Merge pull request #10041 from AUTOMATIC1111/print-exception-#9219
print PIL.UnidentifiedImageError
2023-05-08 09:12:56 +03:00
AUTOMATIC1111 d1d7dd2a44 Merge pull request #10067 from dongweiming/x-y-z-plot
Add extra `None` option for VAE
2023-05-08 09:03:59 +03:00
AUTOMATIC1111 fa21e6ae63 Merge pull request #9616 from Sakura-Luna/tooltip
Tooltip localization support
2023-05-08 09:01:33 +03:00
AUTOMATIC1111 73d956454f Merge branch 'dev' into tooltip 2023-05-08 09:01:25 +03:00
AUTOMATIC1111 b15bbef798 Merge pull request #10089 from AUTOMATIC1111/LoraFix
Fix some Lora's not working
2023-05-08 08:45:26 +03:00
AUTOMATIC1111 67c884196d Merge pull request #9955 from akx/noop-localization-unless-required
Make localization.js do nothing if there's no localization to do
2023-05-08 08:43:11 +03:00
AUTOMATIC 669b518cbd add mtime to served images in gallery to prevent cache from showing old images 2023-05-08 08:36:24 +03:00
AUTOMATIC e4a66bb8e3 make lightbox properly display whole picture without cutting of parts when the picture is very wide. 2023-05-08 08:21:38 +03:00
AUTOMATIC1111 a6529a78c3 Merge pull request #10113 from missionfloyd/extras-thumbnails
Fix stretched thumbnails on extras tab
2023-05-08 08:21:24 +03:00
AUTOMATIC1111 0141ab1387 Merge pull request #10140 from Archeb/patch-1
style.css: Make the image in the ImageViewer be resized correctly
2023-05-08 08:15:36 +03:00
AUTOMATIC1111 66428667c5 Merge pull request #10146 from missionfloyd/gamepad-option
Fix gamepad navigation
2023-05-08 08:09:12 +03:00
AUTOMATIC1111 6ac33fe9d1 Merge pull request #10133 from AUTOMATIC1111/filename-pattern-denoising_strength
Filename pattern denoising strength
2023-05-08 08:04:02 +03:00
AUTOMATIC 160780283a put all code for /docs in same place and make it work properly with UI reloads 2023-05-08 07:57:17 +03:00
AUTOMATIC1111 064eda930c Merge pull request #10168 from mouhao/master
Fix missing /docs endpoint in newer gradio versions
2023-05-08 07:47:06 +03:00
AUTOMATIC 2473bafa67 read infotext params from the other extension for Lora if it's not active 2023-05-08 07:28:30 +03:00
mouhao 0cb582b50c Merge pull request #1 from mouhao/mouhao-patch-1
Update webui.py
2023-05-07 21:03:28 +08:00
mouhao 5427b7128d Update webui.py
Fix missing /docs endpoint in newer gradio versions
Newer versions of gradio (>=3.27.1) have removed the /docs endpoint by default. This commit adds it back to enable accessing the API documentation.
2023-05-07 20:54:48 +08:00
AUTOMATIC 2cb3b0be1d if present, use Lora's "ss_output_name" field to refer to it in prompt 2023-05-07 08:25:34 +03:00
missionfloyd 85bd9b3d31 Work with multiple gamepads 2023-05-06 22:47:35 -06:00
missionfloyd 99f3bf07d2 gamepad repeat option 2023-05-06 22:16:51 -06:00
missionfloyd cca5782d18 Improve joypad performance 2023-05-06 22:00:13 -06:00
missionfloyd 5cbc1c5d43 Fix spelling 2023-05-05 23:03:32 -06:00
missionfloyd a46c23b10f Make gamepad navigation optional 2023-05-05 22:48:27 -06:00
蚊子 8462d07116 style.css: Make the image in the ImageViewer be resized correctly 2023-05-06 01:17:39 +01:00
w-e-w 381674739e add denoising strength filename pattern 2023-05-06 02:24:33 +09:00
w-e-w cde0d642f3 add denoising strength filename pattern 2023-05-06 02:20:33 +09:00
missionfloyd 79a6c5a666 Fix stretched thumbnails on extras tab 2023-05-05 03:51:51 -06:00
Sakura-Luna a3cdf9aaf8 Reopen image fix 2023-05-05 15:52:34 +08:00
Aarni Koskela 16f0739db0 Make localization.js do nothing if there's no localization to do 2023-05-04 20:18:01 +03:00
Leo Mozoloa c3eced22fc Fix some Lora's not working 2023-05-04 16:14:33 +02:00
Sakura-Luna 8bc4a3a2a8 Refresh fix 2023-05-04 15:59:42 +08:00
Sakura-Luna 91a15dca80 Use a new way to solve webpage refresh 2023-05-04 14:38:15 +08:00
Sakura-Luna 5c66fedb64 Revert "Fix gallery not being refreshed correctly"
This reverts commit 2c24e09dfc.
2023-05-04 14:08:22 +08:00
Sakura-Luna 35e5916af9 Revert "Add img2img refreshed correctly"
This reverts commit 988dd02632.
2023-05-04 14:08:21 +08:00
Sakura-Luna 29e13867bf Revert "Refresh bug fix"
This reverts commit eff00413ae.
2023-05-04 14:08:20 +08:00
Acncagua Slt 1bebb50da9 No double calls will be made
Do not call load_upscalers in list_builtin_upscalers
2023-05-04 11:59:22 +09:00
papuSpartan f0efc8c211 not being cast properly every time, swap to ints 2023-05-03 21:10:31 -05:00
Weiming Dong 251be61a80 Add extra None option for VAE 2023-05-04 07:59:52 +08:00
papuSpartan e960781511 fix maximum downsampling option 2023-05-03 13:12:43 -05:00
papuSpartan f08ae96115 resolve merge conflicts and swap to dev branch for now 2023-05-03 02:21:50 -05:00
w-e-w 14e55a3301 print PIL.UnidentifiedImageError 2023-05-03 14:28:59 +09:00
Acncagua Slt efe98ca090 Initialize the upscalers
Add modelloader.load_upscalers to def initialize()
2023-05-03 00:44:16 +09:00
AUTOMATIC1111 335428c2c8 Merge pull request #9140 from yedpodtrzitko/yed/reuse-existing-venv
feat: use existing virtualenv if already active
2023-05-02 11:05:00 +03:00
AUTOMATIC 14b70aa97b revert unwanted change from #9865 2023-05-02 11:03:11 +03:00
AUTOMATIC1111 4b6808f6ed Merge pull request #9865 from catalpaaa/subpath-support
add subpath support
2023-05-02 11:01:27 +03:00
AUTOMATIC 4499bead4c Merge branch 'master' into dev 2023-05-02 09:25:47 +03:00
AUTOMATIC 5ab7f213be fix an error that prevents running webui on torch<2.0 without --disable-safe-unpickle 2023-05-02 09:20:35 +03:00
AUTOMATIC b1717c0a48 do not load wait for shared.sd_model to load at startup 2023-05-02 09:08:00 +03:00
catalpaaa 9eb5b3e90f Merge branch 'experimental' into subpath-support 2023-05-01 11:59:21 -07:00
AUTOMATIC1111 696c338ee2 Merge pull request #9953 from akx/js-misc-fixes
Miscellaneous JS fixes
2023-05-01 14:39:52 +03:00
AUTOMATIC1111 50f63e2247 Merge branch 'dev' into js-misc-fixes 2023-05-01 14:39:46 +03:00
AUTOMATIC 72cd27a135 update changelog 2023-05-01 14:33:44 +03:00
AUTOMATIC fe8a10d428 Merge branch 'release_candidate' 2023-05-01 14:27:53 +03:00
AUTOMATIC b463b8a126 Merge branch 'release_candidate' into dev 2023-05-01 14:09:53 +03:00
AUTOMATIC1111 6fbd85dd0c Merge pull request #9969 from AUTOMATIC1111/restore_progress_fix
restore_progress fix
2023-05-01 14:09:32 +03:00
AUTOMATIC f57445f7c4 Merge branch 'release_candidate' into dev 2023-05-01 14:01:29 +03:00
w-e-w 33e6bc34ff restore_progress fix
id wrong type
2023-05-01 19:59:52 +09:00
AUTOMATIC 67f5c2abb0 make it impossible to press the restore progress button after pressing it once 2023-05-01 13:58:10 +03:00
AUTOMATIC f15b7e52e3 Add a comment and partial fix for the issue when the inpaint UI is unresponsive after using it. 2023-05-01 13:47:46 +03:00
AUTOMATIC 74d249f6dd Merge branch 'release_candidate' into dev 2023-05-01 12:48:28 +03:00
AUTOMATIC 94754c60c5 attempt to fix broken github CI 2023-05-01 12:47:52 +03:00
AUTOMATIC1111 a7aa046016 Merge pull request #9965 from AUTOMATIC1111/xyz_checkpoint_override
XYZ checkpoint switch via Override
2023-05-01 12:47:30 +03:00
AUTOMATIC1111 97b9800bc6 Merge pull request #9958 from AUTOMATIC1111/model_override_enhancement
override setting "model override" enhancement
2023-05-01 12:46:09 +03:00
w-e-w cfbe68184c use override to apply checkpoint 2023-05-01 17:47:31 +09:00
w-e-w 0d1ef296b9 checkpoint override enhancement 2023-05-01 05:22:53 +09:00
Aarni Koskela c714300265 Use substring instead of deprecated substr 2023-04-30 22:26:11 +03:00
Aarni Koskela 4bb441bb08 Remove redundant return 2023-04-30 22:26:11 +03:00
Aarni Koskela b7269f781c Mark Notification.requestPermission's retval as purposely ignored 2023-04-30 22:26:11 +03:00
Aarni Koskela f6a40a2ffa Fix unused variables 2023-04-30 22:26:11 +03:00
Aarni Koskela 8ccc27127b Fix a whole bunch of implicit globals 2023-04-30 22:08:52 +03:00
Aarni Koskela 34a6ad80d5 Use classList.toggle wherever possible 2023-04-30 14:48:02 +03:00
Aarni Koskela ee973dcf1d imageMaskFix.js: fix event listeners to not use anonymous trampoline 2023-04-30 14:46:03 +03:00
Aarni Koskela 13d8d65ef9 hints: don't process elements that already have a title 2023-04-30 14:46:03 +03:00
AUTOMATIC 5e4a0e3d24 attempt to fix broken github CI 2023-04-29 23:02:23 +03:00
AUTOMATIC 06b6d2f2e2 Merge branch 'dev' into release_candidate 2023-04-29 22:50:49 +03:00
AUTOMATIC ab287682bf add changelog 2023-04-29 22:50:34 +03:00
AUTOMATIC e23063610f Merge branch 'dev' into release_candidate 2023-04-29 22:23:21 +03:00
AUTOMATIC cd7f2b19f4 increase extra networks UI height to fit two rows of cards. 2023-04-29 22:17:32 +03:00
AUTOMATIC c48ab36cb9 alternate restore progress button implementation 2023-04-29 22:16:54 +03:00
AUTOMATIC bd9700405a Revert "Merge pull request #7595 from siutin/feature/restore-progress"
This reverts commit 80987c36f9, reversing
changes made to 2e78e65a22.
2023-04-29 22:15:20 +03:00
AUTOMATIC1111 80987c36f9 Merge pull request #7595 from siutin/feature/restore-progress
restore the progress from session lost / tab reload
2023-04-29 22:13:48 +03:00
AUTOMATIC1111 15c4e78b44 Merge branch 'dev' into feature/restore-progress 2023-04-29 22:13:40 +03:00
AUTOMATIC1111 2e78e65a22 Merge pull request #9907 from garrettsutula/master
Add disable_tls_verify arg for use with self-signed certs
2023-04-29 20:29:38 +03:00
AUTOMATIC1111 0d32cb2cf5 Merge branch 'dev' into master 2023-04-29 20:29:23 +03:00
AUTOMATIC 90e4659822 bump gradio to 3.28.1 2023-04-29 20:28:30 +03:00
AUTOMATIC f9253cee66 do not fail all Loras if some have failed to load when making a picture 2023-04-29 20:28:30 +03:00
AUTOMATIC1111 3baeefd30a Merge pull request #9933 from w-e-w/dev
add missing filename pattern hints
2023-04-29 20:13:58 +03:00
AUTOMATIC1111 45371704f6 Merge pull request #7632 from papuSpartan/gamepad
Image viewer scrolling via analog stick
2023-04-29 19:43:34 +03:00
AUTOMATIC e40b2d947d change gradio callback from change to release in a bunch of places now that it's fixed in gradio 2023-04-29 19:39:22 +03:00
AUTOMATIC a95dc02535 remove unwanted changes from #8789 2023-04-29 19:05:43 +03:00
AUTOMATIC1111 f96e6fbd0c Merge pull request #8789 from Rucadi/master
Add polling and reload callback for extensions.
2023-04-29 19:03:10 +03:00
AUTOMATIC1111 0e0e70c273 Merge pull request #8924 from kurilee/master
Add option "keep original size" to textual inversion images preprocess
2023-04-29 18:51:12 +03:00
AUTOMATIC1111 b615a2ed11 Merge pull request #9108 from AUTOMATIC1111/img2img-scale-by
add "resize by" and "resize to" tabs to img2img
2023-04-29 18:21:28 +03:00
AUTOMATIC1111 eabecc21ec Update modules/ui.py
Co-authored-by: missionfloyd <missionfloyd@users.noreply.github.com>
2023-04-29 18:20:11 +03:00
AUTOMATIC1111 103fc062a5 Merge pull request #8999 from Reibies/patch-1
Changed: extra network height css
2023-04-29 18:18:43 +03:00
AUTOMATIC e30502a64b Remove NVidia URL for OSX torch installation on OSX. 2023-04-29 18:00:51 +03:00
AUTOMATIC 1a50272e7c revert some questionable changes from #9159 2023-04-29 17:45:22 +03:00
AUTOMATIC1111 f685fe7250 Merge pull request #9159 from space-nuko/ui-config-tabs
Make selected tab configurable with UI config
2023-04-29 17:43:07 +03:00
AUTOMATIC1111 88c7debb02 Merge branch 'dev' into ui-config-tabs 2023-04-29 17:42:57 +03:00
AUTOMATIC1111 97167a5768 Merge pull request #9165 from Ming424/update-readme
Small update for readme
2023-04-29 17:39:02 +03:00
AUTOMATIC1111 609b8933a2 Merge pull request #9258 from wywywywy/bug-outpainting-mk2-file-format
bug: Outpainting Mk2 & Poorman should use the SAMPLE file format to save images, not GRID file format
2023-04-29 17:23:22 +03:00
AUTOMATIC1111 5524301ab8 Merge pull request #9169 from space-nuko/extension-settings-backup
Extension settings backup/restore feature
2023-04-29 17:22:42 +03:00
AUTOMATIC1111 78d0ee3bba Merge branch 'dev' into extension-settings-backup 2023-04-29 17:22:24 +03:00
AUTOMATIC1111 c018eefe91 Merge pull request #8563 from ParityError/master
Update webui.sh
2023-04-29 17:16:57 +03:00
AUTOMATIC1111 1185bf3981 Merge branch 'dev' into master 2023-04-29 17:16:52 +03:00
AUTOMATIC1111 8987764395 Merge pull request #9312 from space-nuko/save-merge-recipe
Embed model merge metadata in .safetensors file
2023-04-29 17:15:01 +03:00
AUTOMATIC1111 31dbec6b76 Merge pull request #9315 from GeorgLegato/get_uiCurrentTab_Gr3.23_wrong
get_uiCurrentTab() wrong with Gradio 3.23.0
2023-04-29 17:09:04 +03:00
AUTOMATIC 1bab1797c0 use parsed commandline args for --skip-install 2023-04-29 17:07:21 +03:00
AUTOMATIC1111 ad7fd488bc Merge pull request #9330 from micky2be/patch-1
Fix skip-install bug (see #8935)
2023-04-29 17:04:48 +03:00
AUTOMATIC1111 ce64cab397 Merge branch 'dev' into patch-1 2023-04-29 17:04:37 +03:00
AUTOMATIC1111 c89cad2b9a Merge pull request #9314 from Pluventi/master
Fix "Bug batch process"  on extras tab , even with a clean install of "stable diffusion webui"
2023-04-29 17:02:24 +03:00
AUTOMATIC1111 3894609b52 Merge branch 'dev' into master 2023-04-29 17:02:14 +03:00
AUTOMATIC1111 17cce45613 Merge pull request #8948 from hitomi/master
Fix --realesrgan-models-path and --ldsr-models-path not working
2023-04-29 17:00:24 +03:00
AUTOMATIC1111 f2af6dad71 Merge pull request #9351 from nart4hire/fix-ngrok-recreate-tunnel
Fix Ngrok recreating tunnels every reload
2023-04-29 16:56:20 +03:00
AUTOMATIC1111 78b5bed374 Merge pull request #9407 from GoulartNogueira/master
Fix orientation bug on preprocess
2023-04-29 16:53:17 +03:00
AUTOMATIC1111 1142a87c6a Merge pull request #9219 from Z-nonymous/master
Fix #9185
2023-04-29 16:52:39 +03:00
AUTOMATIC1111 579e13df7c Merge pull request #8847 from space-nuko/remove-watermark-option
Remove "do not add watermark to images" option
2023-04-29 16:50:58 +03:00
AUTOMATIC1111 263f0fb59c Merge branch 'dev' into remove-watermark-option 2023-04-29 16:50:52 +03:00
AUTOMATIC faff08f396 rework [batch_number]/[generation_number] filename patterns 2023-04-29 16:48:43 +03:00
w-e-w 7749f2d8ad hints [batch_number] [generation_number] 2023-04-29 22:47:38 +09:00
AUTOMATIC1111 8651943cf9 Merge pull request #9445 from gakada/master
Add [batch_number] and [generation_number] filename patterns
2023-04-29 16:41:19 +03:00
AUTOMATIC1111 e7d624574d Merge branch 'dev' into master 2023-04-29 16:41:01 +03:00
AUTOMATIC 7428fb5176 add is_hr_pass field for processing 2023-04-29 16:28:51 +03:00
AUTOMATIC1111 e10ee96272 Merge pull request #9334 from gmasil/prepare-simpler-docker-integration-for-styles-csv
allow styles.csv to be symlinked or mounted in docker
2023-04-29 16:14:55 +03:00
AUTOMATIC1111 dae82c69a6 Merge pull request #9365 from bluelovers/pr/xyz-sort-001
feat(xyz): try sort Checkpoint name values
2023-04-29 16:10:20 +03:00
AUTOMATIC1111 725a3849d2 Merge branch 'dev' into pr/xyz-sort-001 2023-04-29 16:10:16 +03:00
AUTOMATIC 8863b31d83 use correct images for previews when using AND (see #9491) 2023-04-29 16:06:20 +03:00
AUTOMATIC 737b73a820 some extra lines I forgot to add for previous commit 2023-04-29 16:05:20 +03:00
AUTOMATIC 1d11e89698 rework Negative Guidance minimum sigma to work with AND, add infotext and copypaste parameters support 2023-04-29 15:57:09 +03:00
w-e-w 720fc88273 hints [clip_skip] 2023-04-29 20:55:01 +09:00
AUTOMATIC1111 3591eefedf Merge pull request #9177 from devNegative-asm/master
(Optimization) Option to remove negative conditioning at low sigma values
2023-04-29 14:38:25 +03:00
AUTOMATIC1111 7b02b17a01 Merge pull request #9404 from DGdev91/master
Forcing PyTorch version for AMD GPUs automatic install
2023-04-29 14:09:51 +03:00
AUTOMATIC1111 967fb51df2 Merge branch 'dev' into master 2023-04-29 14:09:45 +03:00
AUTOMATIC1111 fdac486835 Merge pull request #9484 from infinitewarp/sort-embeddings
sort embeddings by name (case insensitive)
2023-04-29 14:03:02 +03:00
AUTOMATIC cb940a583d fix extension installation broken by #9518 2023-04-29 13:45:14 +03:00
AUTOMATIC1111 376e99f681 Merge pull request #9592 from liamkerr/generation_params_fix
Fixed generation params in gallery
2023-04-29 13:24:58 +03:00
AUTOMATIC1111 43dd2378af Merge branch 'dev' into generation_params_fix 2023-04-29 13:24:50 +03:00
AUTOMATIC1111 32c3b97669 Merge pull request #9628 from catboxanon/patch/9092
Fix image mask/composite for weird resolutions
2023-04-29 13:21:32 +03:00
AUTOMATIC1111 43925add0a Merge pull request #9643 from tqwuliao/Branch_AddNewFilenameGen
Add new FilenameGenerator replacements [hasprompt<prompt1|default><prompt2>..]
2023-04-29 13:10:51 +03:00
AUTOMATIC1111 87535fcf29 Merge branch 'dev' into Branch_AddNewFilenameGen 2023-04-29 13:10:46 +03:00
AUTOMATIC1111 1ffb44b0b2 Merge pull request #9593 from gakada/tcmalloc
Try using TCMalloc on Linux by default
2023-04-29 13:02:00 +03:00
AUTOMATIC1111 e847df7ee9 Merge pull request #9609 from akx/bracket-fix
prompt-bracket-checker: Simplify code + improve error reporting
2023-04-29 12:58:20 +03:00
AUTOMATIC1111 d6a3988b86 Merge pull request #9669 from catboxanon/patch/sampler-schedule-fix
Fix prompt schedule for second order samplers
2023-04-29 12:56:57 +03:00
AUTOMATIC1111 fc6eeda69c Merge pull request #9130 from Vespinian/fix-api-alwayson_scripts-less-then-requiered-args
[Fix] Prevent alwayson_scripts args param resizing script_arg list when they are inserted in it
2023-04-29 12:55:19 +03:00
AUTOMATIC1111 1dc21d7950 Merge pull request #9677 from weidongkl/master
fix install_dir error
2023-04-29 12:53:11 +03:00
AUTOMATIC b06205eaf6 Allow user input for gradio theme selection 2023-04-29 12:52:09 +03:00
AUTOMATIC1111 e018c8a391 Merge pull request #8945 from space-nuko/gradio-theme-support
Support Gradio's theme API
2023-04-29 12:45:50 +03:00
AUTOMATIC1111 e6cbfcfe5b Merge branch 'dev' into gradio-theme-support 2023-04-29 12:45:43 +03:00
AUTOMATIC1111 2c935d8eb0 Merge pull request #9518 from yike5460/master
add branch support for extension installation
2023-04-29 12:41:30 +03:00
AUTOMATIC aee6d9bb74 remove unneeded warning filter 2023-04-29 12:39:05 +03:00
AUTOMATIC ee71eee181 stuff related to torch version change 2023-04-29 12:36:50 +03:00
AUTOMATIC1111 9eb49b04e3 Merge pull request #9191 from vladmandic/torch
update torch base environment
2023-04-29 11:59:12 +03:00
AUTOMATIC1111 f54cd3f158 Merge branch 'dev' into torch 2023-04-29 11:58:54 +03:00
AUTOMATIC1111 e55cb92067 Merge pull request #9737 from AdjointOperator/master
add tiled inference support for ScuNET
2023-04-29 11:34:35 +03:00
AUTOMATIC 5fe0dd79be rename CPU RNG to RNG source in settings, add infotext and parameters copypaste support to RNG source 2023-04-29 11:29:37 +03:00
AUTOMATIC1111 cb9571e37f Merge pull request #9734 from deciare/cpu-randn
Option to make images generated from a given manual seed consistent across CUDA and MPS devices
2023-04-29 11:16:06 +03:00
AUTOMATIC1111 09069918e8 Merge pull request #9750 from TFWol/patch-1
Remove old code roll random artists
2023-04-29 11:15:26 +03:00
AUTOMATIC1111 71322400fd Merge pull request #9392 from pangbo13/xyz-plot-dropdown
Add dropdown for X/Y/Z plot
2023-04-29 11:09:04 +03:00
AUTOMATIC1111 dda839f686 Merge pull request #9693 from racinmat/hidable_buttons
adds label to buttons to make them hide
2023-04-29 11:05:51 +03:00
AUTOMATIC1111 cc067555fb Merge pull request #9813 from arrix/interrogate_download
fix: couldn't remove interrogate_tmp dir while downloading interrogate categories
2023-04-29 10:46:58 +03:00
AUTOMATIC1111 7393fdefd5 Merge pull request #9060 from AlUlkesh/master
fix: lightboxModal, selectedTab
2023-04-29 10:46:10 +03:00
AUTOMATIC1111 d2f3f40a86 Merge pull request #9227 from bbonvi/master
fix disappearing live previews and progressbar during slow tasks
2023-04-29 10:29:47 +03:00
AUTOMATIC1111 1f6aabbd55 Merge pull request #9839 from dennissheng/master
fix ui img2img scripts
2023-04-29 10:26:47 +03:00
AUTOMATIC 86bafb625a put asyncio fix into a function to make it more obvious where it starts and ends 2023-04-29 10:21:01 +03:00
AUTOMATIC1111 24dec9c832 Merge pull request #9319 from wk5ovc/patch-1
Fix #9046 /sdapi/v1/txt2img endpoint not working
2023-04-29 10:14:19 +03:00
AUTOMATIC1111 840d1854cd Merge pull request #9862 from missionfloyd/extras-sliders-main
Change extras "scale to" to sliders
2023-04-29 10:07:01 +03:00
AUTOMATIC1111 5b4bcea956 Merge pull request #9757 from missionfloyd/editattention-selectcurrentword
Automatically select current word when adjusting weight with ctrl+up/down
2023-04-29 10:05:37 +03:00
AUTOMATIC 642d96dcc8 use exist_ok=True instead of checking if directory exists 2023-04-29 10:04:01 +03:00
AUTOMATIC1111 39654cc905 Merge pull request #9867 from darnell8/master
Fix CLIP FileExistsError
2023-04-29 10:03:07 +03:00
AUTOMATIC1111 b0f55d374e Merge pull request #9429 from forsurefr/save-init-images
Add support for saving init images in img2img
2023-04-29 10:01:33 +03:00
AUTOMATIC1111 b0ad46676b Merge pull request #9884 from aniaan/fix/remove-dup-code
perf(webui): Remove duplicate code
2023-04-29 09:59:40 +03:00
AUTOMATIC1111 cf5bd93200 Merge pull request #9657 from Filexor/master
Add filename pattern for CLIP_stop_at_last_layers (clip skip).
2023-04-29 09:43:43 +03:00
AUTOMATIC 1514add559 remove unneded imports and type signature 2023-04-29 09:42:49 +03:00
AUTOMATIC1111 37c59c2710 Merge pull request #9723 from missionfloyd/extra-network-none
Add "None" option to extra networks dropdowns
2023-04-29 09:42:07 +03:00
AUTOMATIC1111 38f1c8183b Merge pull request #9513 from ilya-khadykin/fix_batch_processing
fix(extras): fix batch image processing on 'Extras\Batch Process' tab
2023-04-29 09:30:46 +03:00
AUTOMATIC1111 a33d49cc57 Merge branch 'dev' into fix_batch_processing 2023-04-29 09:30:33 +03:00
AUTOMATIC1111 7fc10e0445 Merge pull request #9134 from space-nuko/improve-custom-code-extension
Improve custom code script
2023-04-29 09:25:39 +03:00
AUTOMATIC 5a666f3904 bump gradio to 3.27 2023-04-29 09:21:31 +03:00
AUTOMATIC 101a18fc84 bump gradio to 3.27 2023-04-29 09:17:35 +03:00
catalpaaa ecdc6471e7 bump gradio to 3.28 2023-04-28 12:23:53 -07:00
Garrett Sutula aac478cb9d Should be "utils" 2023-04-27 21:40:16 -04:00
Garrett Sutula ed46abea35 fix for method moved to gradio_client 2023-04-27 21:30:55 -04:00
Garrett Sutula d1e62b2961 Improve param semantics, 2023-04-27 21:30:19 -04:00
Garrett Sutula fa74daacbd Update gradio version to version that adds ssl_verify 2023-04-27 20:31:17 -04:00
Garrett Sutula 43186ad084 Add tls_verify arg for use with self-signed certs 2023-04-27 20:29:21 -04:00
aniaan 7ea5be3e29 perf(webui): Remove duplicate code 2023-04-26 20:59:55 +08:00
darnell8 bb426de1cd Fix CLIP FileExistsError 2023-04-25 22:53:06 +08:00
catalpaaa b2f6e0704e add subpath support 2023-04-25 07:27:24 -07:00
missionfloyd 0e071ae504 Custom delimiters 2023-04-25 08:08:57 -06:00
missionfloyd 84c5b0801a Update postprocessing_upscale.py 2023-04-24 20:07:24 -06:00
dennissheng bbc7a778d8 fix ui img2img scripts 2023-04-24 17:36:16 +08:00
bbonvi 8ae8aeca75 pull progress for 40 seconds
for some extreme network conditions 20 seconds may not be enough
2023-04-24 13:12:49 +06:00
arrix 05d7a63bbb fix: couldn't remove interrogate_tmp dir 2023-04-23 12:44:12 +08:00
missionfloyd c1fdba5904 Remove hyphen, underscore delimiters 2023-04-21 13:44:31 -06:00
missionfloyd 27d02597c7 Remove parentheses if weight == 1 2023-04-21 01:37:29 -06:00
Sakura-Luna eff00413ae Refresh bug fix 2023-04-21 12:34:38 +08:00
missionfloyd 7ef5551634 Update delimiters 2023-04-20 02:24:38 -06:00
missionfloyd ee172c0fc1 Simplify finding word boundaries
This also makes it work with prompts without spaces between words
2023-04-20 01:34:13 -06:00
missionfloyd fbd34a6847 Use string.contains() instead of regex 2023-04-20 01:12:59 -06:00
Sakura-Luna 988dd02632 Add img2img refreshed correctly 2023-04-20 15:09:19 +08:00
Sakura-Luna 2c24e09dfc Fix gallery not being refreshed correctly 2023-04-20 14:53:37 +08:00
missionfloyd e735be8b5b Automatically select current word 2023-04-19 22:04:34 -06:00
TFWol 33365f15bf Remove old code roll random artists
Removed context menu entry that used to be for rolling artists from the now removed artists.csv.

It was probably meant to be removed at commit 6d805b6.
2023-04-19 14:23:46 -07:00
AdjointOperator dec5cdd9b8 add tiled inference support for ScuNET 2023-04-19 15:35:50 +08:00
Deciare d40e44ade4 Option to use CPU for random number generation.
Makes a given manual seed generate the same images across different
platforms, independently of the GPU architecture in use.

Fixes #9613.
2023-04-18 23:27:46 -04:00
missionfloyd f4b332f041 Add "None" option to extra networks dropdowns 2023-04-18 17:01:46 -06:00
Matěj Račinský eddcdb8061 adds label to buttons to make them hide 2023-04-17 23:48:28 +02:00
weidong 152ed34ccc fix install_dir error
When the user's home directory and username are inconsistent, an error message stating that the directory cannot be found will appear. Directly default the installation directory to the user's home directory
2023-04-17 17:17:10 +08:00
siutin 3e5b3c79e4 replace with #wrap_session_call 2023-04-17 13:53:41 +08:00
catboxanon 9de7298898 Update processing.py 2023-04-16 21:06:37 -04:00
catboxanon 234fa9a57d Update shared.py 2023-04-16 21:06:22 -04:00
catboxanon 4d0c816303 Modify step multiplier flow 2023-04-16 20:39:45 -04:00
catboxanon 81b276a1ea Add second order samplers compat option 2023-04-16 20:39:18 -04:00
catboxanon 56f8a6b081 Fix sampler schedules with step multiplier 2023-04-16 20:34:52 -04:00
siutin 984970068c multi users support 2023-04-17 01:06:28 +08:00
File_xor acbec22554 Add self argument that is mandatory to [clip_skip] filename pattern. 2023-04-16 17:14:11 +09:00
File_xor 596556162e Add filename pattern for CLIP_stop_at_last_layers. 2023-04-16 16:49:21 +09:00
tqwuliao 02e3518807 Add new FilenameGenerator [hasprompt<prompt1|default><prompt2>..] 2023-04-15 23:20:08 +08:00
catboxanon fbab3fc6d1 Only handle image mask if any option enabled 2023-04-14 17:24:55 -04:00
catboxanon 3af152d488 Fix image mask composite for weird resolutions 2023-04-14 17:17:14 -04:00
Sakura-Luna 57a3d146e3 Tooltip localization support 2023-04-14 14:09:33 +08:00
Brad Smith dab5002c59 sort self.word_embeddings without instantiating it a new dict 2023-04-13 23:19:10 -04:00
Aarni Koskela fcc194afad prompt-bracket-checker: Simplify + improve error reporting 2023-04-13 23:00:32 +03:00
Vladimir Mandic 7fb72edaff change index url 2023-04-13 06:47:48 -04:00
gk 8af4b3bbe4 Try using TCMalloc on Linux by default 2023-04-13 10:19:03 +09:00
DGdev91 9edd4b6e51 Using --index-url instead of --extra-index-url following new PyTorch install command 2023-04-11 11:22:28 +02:00
papuSpartan dff60e2e74 Update sd_models.py 2023-04-10 04:10:50 -05:00
papuSpartan a9902ca331 Update generation_parameters_copypaste.py 2023-04-10 04:03:01 -05:00
papuSpartan c510cfd24b Update shared.py
fix typo
2023-04-10 03:43:56 -05:00
papuSpartan 1c11062603 add token merging options to infotext when necessary. Bump tomesd
version
2023-04-10 03:41:05 -05:00
yike5460 7c62bb2788 fix: support for default branch 2023-04-10 09:38:26 +08:00
bluelovers c84118d70d feat(xyz): try sort Checkpoint name values 2023-04-10 05:03:02 +08:00
Ilya Khadykin c19618f370 fix(extras): fix batch image processing on 'Extras\Batch Process' tab
This change fixes an issue where an incorrect type was passed to the PIL.Image.open() function that caused the whole process to fail.

Scope of this change is limited to only batch image processing, and it shouldn't affect other functionality.
2023-04-09 21:33:09 +02:00
yike5460 1aba8d82cb feat: add branch support for extension installation 2023-04-09 22:22:43 +08:00
Brad Smith 27b9ec60e4 sort embeddings by name (case insensitive) 2023-04-08 15:58:00 -04:00
gk d609f6030e Add [batch_number] and [generation_number] filename patterns 2023-04-07 21:04:46 +09:00
forsurefr 63a6f9b4d9 Do not save init image by default 2023-04-07 12:13:51 +03:00
For Sure b3593d0997 Add support for saving init images in img2img 2023-04-06 19:42:26 +03:00
Andre Ubuntu 48c06af8dc Pythonic way to achieve it 2023-04-05 20:51:29 -03:00
DGdev91 3a5b47e26e Forcing PyTorch version for AMD GPUs automatic install
The old code tries to install the newest versions of pytorch, wich is currently 2.0. Forcing it to 1.13.1
2023-04-06 01:36:27 +02:00
Andre Ubuntu 52a8f286ef fix preprocess orientation 2023-04-05 20:28:00 -03:00
pangbo13 3ac5f9c471 fix axis swap and infotxt 2023-04-05 21:43:27 +08:00
pangbo13 c01dc1cb30 add dropdown for X/Y/Z plot 2023-04-05 19:22:51 +08:00
Vladimir Mandic 80752f43b2 revert xformers 2023-04-04 17:27:27 -04:00
hitomi 2ba42bfbd2 fix --ldsr-models-path not working 2023-04-04 20:39:51 +08:00
hitomi 539a69860b fix --realesrgan-models-path not working 2023-04-04 20:39:51 +08:00
Nathanael Santoso 3158d17ccf fixed an issue with using ngrok for other connections and also ngrok not using auth_token 2023-04-04 07:41:55 +00:00
papuSpartan cf5a5773bf :p 2023-04-04 02:39:13 -05:00
papuSpartan ab195ab0da bump tomesd package version 2023-04-04 02:31:57 -05:00
papuSpartan 5c8e53d5e9 Allow different merge ratios to be used for each pass. Make toggle cmd flag work again. Remove ratio flag. Remove warning about controlnet being incompatible 2023-04-04 02:26:44 -05:00
Nathanael Santoso 2edf73b38f Improved message clarity 2023-04-04 06:57:39 +00:00
Nathanael Santoso 5ebe3b2504 Added guard clause to prevent multiple tunnel creations 2023-04-04 06:50:29 +00:00
space-nuko 7201d940a4 Improve frontend responsiveness for some buttons 2023-04-03 21:27:48 -05:00
Vladimir Mandic 4fa59b045a update xformers 2023-04-03 15:23:35 -04:00
Liam 54fd00ff8f fixed logic for updating the displayed generation params when the image modal is closed 2023-04-03 13:28:20 -04:00
gmasil f7215906af allow styles.csv to be symlinked or mounted in docker without moving the file around 2023-04-03 18:19:57 +02:00
Micky Brunetti d537a1f1b6 Fix skip-install bug (see #8935) 2023-04-04 00:14:20 +09:00
keith aef42bfec0 Fix #9046 /sdapi/v1/txt2img endpoint not working
**Describe what this pull request is trying to achieve.**

Fix https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/9046

**Environment this was tested in**

* OS: Linux
* Browser: chrome
* Graphics card: RTX 3090
2023-04-03 17:05:49 +08:00
GeorgLegato d9fdb52149 Update script.js
updated how tabs are presented in DOM with Gradio 3.23.
2023-04-03 04:53:29 +02:00
space-nuko fbaf6e4fd8 Namespace metadata fields 2023-04-02 21:41:23 -05:00
Pluventi 9a4e650800 Update postprocessing.py
Solution for anyone getting an error when batching on extras, even with a clean install of "stable diffusion webui"
2023-04-03 03:32:48 +02:00
space-nuko 7c016dd642 Calculate shorthash on merge if not exist 2023-04-02 19:06:39 -05:00
space-nuko afc349c2c0 Add field for model merge type
Incase this is supported by other merge extensions
2023-04-02 18:40:33 -05:00
space-nuko d132481058 Embed model merge metadata in .safetensors file 2023-04-02 17:41:55 -05:00
ParityError 5225393bde Merge branch 'AUTOMATIC1111:master' into master 2023-04-01 22:15:12 -07:00
papuSpartan c707b7df95 remove excess condition 2023-04-01 23:47:10 -05:00
papuSpartan a609bd56b4 Transition to using settings through UI instead of cmd line args. Added feature to only apply to hr-fix. Install package using requirements_versions.txt 2023-04-01 22:18:35 -05:00
papuSpartan 8c88bf4006 use pypi package for tomesd intead of manually cloning repo 2023-04-01 14:12:12 -05:00
wywywywy 80b847e72d bug: poorman use sample file format not grid 2023-04-01 10:47:49 +01:00
wywywywy 9dc722bcf2 bug: outpaint-mk2 use sample file format not grid 2023-04-01 10:39:50 +01:00
papuSpartan 26ab018253 delay import 2023-04-01 03:31:22 -05:00
papuSpartan ef8c044051 forgot to add reinstall arg back earlier since args moved out of shared 2023-04-01 03:21:23 -05:00
papuSpartan 56680cd84a first 2023-04-01 02:07:08 -05:00
bbonvi c938b172a4 fix missing live preview and progress during certain tasks
Sometimes tasks take longer than 5 seconds to start,
resulting in missing progress bar and livepreviews,
so we have to keep pulling for progress a bit longer (5s -> 20s).
2023-03-31 19:34:58 +06:00
Z_nonymous 18e4ca4694 Fix #9185 2023-03-31 10:54:42 +02:00
missionfloyd 3ebdd2afd3 Don't return upscaling_res_switch_btn 2023-03-31 00:56:38 -06:00
missionfloyd 69ad46b047 Import switch_values_symbol 2023-03-30 23:25:39 -06:00
missionfloyd a73f3bf0cf Change extras "scale to" to sliders 2023-03-30 23:19:40 -06:00
Vladimir Mandic d5063e07e8 update torch 2023-03-30 10:57:54 -04:00
siutin 70ab21e67d keep randomId simpler 2023-03-30 17:20:09 +08:00
siutin 90366b8d85 tool button 2023-03-30 17:20:09 +08:00
siutin e0b58527ff use condition to wait for result 2023-03-30 17:20:09 +08:00
siutin 4242e194e4 add a button to restore the current progress 2023-03-30 17:20:09 +08:00
siutin 9407f1731a store the last generated result 2023-03-30 17:20:09 +08:00
siutin dbca512154 add an internal API for obtaining current task id 2023-03-30 17:20:09 +08:00
devdn 44e8e9c368 fix live preview & alternate uncond guidance for better quality 2023-03-30 00:54:28 -04:00
space-nuko 3ccf6f5ae8 Add webui link 2023-03-29 19:26:52 -05:00
space-nuko 563d048780 Squelch warning if no config restore 2023-03-29 19:22:45 -05:00
space-nuko 1c0544abdb Add links for commits in table, if remote is from GitHub 2023-03-29 19:21:57 -05:00
space-nuko 64bbd3bf03 Make into divs 2023-03-29 19:00:51 -05:00
space-nuko 9b1fa82981 Add filename to UI and config name to filename 2023-03-29 18:55:57 -05:00
space-nuko f3320b802c Various UI fixes in config state tab 2023-03-29 18:35:25 -05:00
space-nuko f22d0dde4e Better checking of extension state from Git info 2023-03-29 18:32:29 -05:00
space-nuko ad5afcaae0 Save/restore working webui/extension configs 2023-03-29 16:55:33 -05:00
Thierry 384bfe22cd Update launch.py 2023-03-29 17:00:20 -04:00
Thierry baef594e4a Update README.md 2023-03-29 16:58:56 -04:00
Thierry 3c7b928914 Update README.md 2023-03-29 16:52:45 -04:00
space-nuko 67955ca9e5 Make selected tab configurable with UI config 2023-03-29 13:07:12 -05:00
yedpodtrzitko 0d2cf9ac18 feat: use existing virtualenv if already active 2023-03-29 16:35:37 +07:00
space-nuko 79d57d02f1 Improve custom code extension
- Uses `gr.Code` component
- Includes example
- Can return out of body
2023-03-29 01:52:34 -05:00
AUTOMATIC 22bcc7be42 attempted fix for infinite loading for settings that some people experience 2023-03-29 08:58:29 +03:00
Vespinian 70a0a11783 Changed behavior that puts the args from alwayson_script request in the script_args, so don't accidently resize the arg list if we get less arg then or default list has 2023-03-28 23:52:51 -04:00
ParityError f867d7b429 Update README.md
Updated to reflect change in webui.sh, so that the installation directory is not absolute (/home/user).
2023-03-28 18:34:02 -07:00
ParityError f69acfe9a4 Merge branch 'AUTOMATIC1111:master' into master 2023-03-28 18:29:59 -07:00
ParityError fb68d93b6a Update webui-user.sh 2023-03-28 18:27:44 -07:00
devdn bc90592031 increase range of negative guidance minimum sigma option 2023-03-28 20:59:31 -04:00
devdn 42082e8a32 performance increase 2023-03-28 20:56:01 -04:00
AlUlkesh 5a25826d84 try both versions of appendChild 2023-03-28 23:28:46 +02:00
AUTOMATIC d667fc435f add "resize by" and "resize to" tabs to img2img 2023-03-28 22:23:40 +03:00
AUTOMATIC 3856ada5cc do not add mask blur to infotext if there is no mask 2023-03-28 22:20:31 +03:00
AUTOMATIC 433b3ab701 Revert "Merge pull request #7931 from space-nuko/img2img-enhance"
This reverts commit 4268759370, reversing
changes made to 1b63afbedc.
2023-03-28 20:36:57 +03:00
AUTOMATIC1111 4268759370 Merge pull request #7931 from space-nuko/img2img-enhance
Add `Upscale by` and `Upscaler` options to img2img
2023-03-28 20:21:25 +03:00
AUTOMATIC 1b63afbedc sort hypernetworks and checkpoints by name 2023-03-28 20:03:57 +03:00
AUTOMATIC1111 8c69bd08c5 Merge pull request #9065 from missionfloyd/quicksettings-alignment
Fix quicksettings alignment
2023-03-28 19:53:30 +03:00
AUTOMATIC1111 daa5a83bb7 Merge pull request #9052 from space-nuko/temp-disable-extensions
Temporary disable extensions option
2023-03-28 19:42:09 +03:00
AUTOMATIC1111 cb3e1ba9bd Merge pull request #9061 from zetclansu/patch-1
fix [Bug]: very wide image doesn't fit in inpaint. Update style.css
2023-03-28 19:40:52 +03:00
AUTOMATIC1111 f1db987e6a Merge pull request #8958 from MrCheeze/variations-model
Add support for the unclip (Variations) models, unclip-h and unclip-l
2023-03-28 19:39:20 +03:00
AUTOMATIC1111 e49c479819 Merge pull request #9031 from AUTOMATIC1111/serve-css-as-files
serve css as independent files
2023-03-28 19:38:43 +03:00
space-nuko 4414d36bf6 Merge branch 'master' into img2img-enhance 2023-03-28 10:59:12 -04:00
missionfloyd b3e593edcb Fix quicksettings alignment 2023-03-27 16:38:42 -06:00
space-nuko 082613036a Merge branch 'master' into remove-watermark-option 2023-03-27 16:26:23 -05:00
space-nuko 56f62d3851 Skip extension installers if all disabled 2023-03-27 17:23:20 -04:00
zetclansu 4b49020506 Update style.css
Fix for wide width image in img2img_sketch, img2maskimg, inpaint_sketch
2023-03-27 21:05:56 +03:00
AlUlkesh 9ecf347133 fix: lightboxModal, selectedTab 2023-03-27 20:01:19 +02:00
Reimoo 6f77567e13 Update style.css 2023-03-27 10:08:42 -07:00
Reimoo 527680cd70 Update style.css
Co-authored-by: missionfloyd <missionfloyd@users.noreply.github.com>
2023-03-27 10:00:01 -07:00
space-nuko fc8e1008ea Make disable configurable between builtin/extra extensions 2023-03-27 12:44:49 -04:00
space-nuko 2a4d3d2124 Add temporary "disable all extensions" option for debugging use 2023-03-27 12:04:45 -04:00
AUTOMATIC 77f9db3b08 serve css as independent files 2023-03-27 12:59:12 +03:00
AUTOMATIC1111 955df7751e Merge pull request #9021 from pieresimakp/pr-dev
Fix the style box dropdown not wrapping in txt2img and img2img
2023-03-27 10:28:13 +03:00
AUTOMATIC 9e82896d5f remove an extra unneeded row in outputs 2023-03-27 10:20:01 +03:00
AUTOMATIC 5fcd4bfa3d do not read extensions' git stuff at startup 2023-03-27 10:02:30 +03:00
AUTOMATIC 5cf3822e46 Revert "Merge pull request #8651 from vladmandic/flicker"
This reverts commit 8402682118, reversing
changes made to e8bbc344c3.
2023-03-27 08:18:28 +03:00
AUTOMATIC1111 c7daba71de Merge pull request #8669 from Vespinian/fix-api-running-unwanted_scripts
Fix for API running unwanted alwayson scripts
2023-03-27 08:11:34 +03:00
AUTOMATIC1111 769def1e41 Merge pull request #8944 from SirFrags/extra_save_geninfo
Transfer generation parameters to previews
2023-03-27 08:06:54 +03:00
AUTOMATIC a70ae917ea update button pressed down style for #8569 2023-03-27 08:05:55 +03:00
AUTOMATIC1111 a7d6fc3b42 Merge pull request #8569 from missionfloyd/extra-networks-toggle
Make extra networks button togglable
2023-03-27 07:35:39 +03:00
AUTOMATIC1111 c5e1efb4ca Merge pull request #8525 from bluelovers/pr/sort-001
feat: try sort as ignore-case
2023-03-27 07:34:18 +03:00
AUTOMATIC b40538a7fe reformat css from latest commits, change color for dropdown selection to more neutral one 2023-03-27 07:30:38 +03:00
AUTOMATIC1111 8a454dab33 Merge pull request #8959 from missionfloyd/dropdown-width
Fix dropdown width
2023-03-27 07:16:37 +03:00
AUTOMATIC 3d09b4e99f remove -y, bring back -f 2023-03-27 07:12:40 +03:00
AUTOMATIC ff0d97c1e3 bring back -y 2023-03-27 07:11:39 +03:00
AUTOMATIC1111 e8f34e3b41 Merge pull request #8938 from space-nuko/fix-image-ar-overlay
Fix img2img aspect ratio overlay in Gradio 3.23.0
2023-03-27 07:06:24 +03:00
AUTOMATIC1111 c19036d3fe Merge pull request #8615 from gmikhail/readme-improvement
Minor README improvement
2023-03-27 06:56:38 +03:00
pieresimakp 68a5604cac Merge remote-tracking branch 'upstream/master' into pr-dev 2023-03-27 11:53:15 +08:00
missionfloyd 8410b1351e Merge branch 'AUTOMATIC1111:master' into extra-network-preview-lazyload 2023-03-26 21:50:22 -06:00
missionfloyd cb8c447f0d Update extra-networks-card.html 2023-03-26 21:47:48 -06:00
missionfloyd efac2cf1ab Merge branch 'extra-network-preview-lazyload' of https://github.com/missionfloyd/stable-diffusion-webui into extra-network-preview-lazyload 2023-03-26 21:47:05 -06:00
AUTOMATIC1111 3b5a3fab91 Merge pull request #8943 from space-nuko/fix-accordion-padding
Fix padding on accordion/dropdown list elements
2023-03-27 06:45:39 +03:00
AUTOMATIC1111 a89af2325d Merge pull request #8940 from space-nuko/fix-send-to-img2img
Fix Send to img2img buttons
2023-03-27 06:41:19 +03:00
AUTOMATIC1111 a336c7fe23 Merge pull request #9017 from camenduru/dev
convert to python v3.9
2023-03-27 06:38:17 +03:00
pieresimakp 774c691df8 fixed style box wrapping 2023-03-27 11:31:56 +08:00
camenduru 6a147db128 convert to python v3.9 2023-03-27 04:40:31 +03:00
camenduru 9d7390d2d1 convert to python v3.9 2023-03-27 04:28:40 +03:00
MrCheeze 1f08600345 overwrite xformers in the unclip model config if not available 2023-03-26 16:55:29 -04:00
Reimoo 88515267b9 Changed: extra network height css
Changed it so cards take up a set amount of vertical space but added the ability to scroll and resize.
2023-03-26 10:29:19 -07:00
AUTOMATIC 4c1ad743e3 for img2img, use None as upscaler instead of erroring out if the desired upscaler is not found 2023-03-26 11:01:32 +03:00
AUTOMATIC 532ac22b38 Merge branch 'lora_inplace' 2023-03-26 10:44:37 +03:00
AUTOMATIC 650ddc9dd3 Lora support for SD2 2023-03-26 10:44:20 +03:00
AUTOMATIC b705c9b72b Merge branch 'lora_sd2' into lora_inplace 2023-03-26 07:04:43 +03:00
AUTOMATIC1111 64da5c46ef Merge pull request #8931 from LipeCarmel/patch-1
loopback.py Colab compatibility and bug fix
2023-03-26 06:48:29 +03:00
missionfloyd d286df0a71 Fix dropdown width 2023-03-25 21:00:02 -06:00
MrCheeze 8a34671fe9 Add support for the Variations models (unclip-h and unclip-l) 2023-03-25 21:03:07 -04:00
bluelovers d64ff4248b remove changes in textual_inversion.py 2023-03-26 06:15:09 +08:00
missionfloyd 254ad09ef3 Update style.css 2023-03-25 15:01:10 -06:00
missionfloyd 6f18c9b13f Merge branch 'master' into extra-networks-toggle 2023-03-25 14:51:25 -06:00
space-nuko c9647c8d23 Support Gradio's theme API 2023-03-25 16:11:41 -04:00
AUTOMATIC 80b26d2a69 apply Lora by altering layer's weights instead of adding more calculations in forward() 2023-03-25 23:06:33 +03:00
SirFrags abc4d3a693 preview replace save params 2023-03-25 15:59:50 -04:00
space-nuko d3b188c82d Fix padding on accordion/dropdown list elements 2023-03-25 15:52:06 -04:00
space-nuko 5eb7ff7768 Fix Send to img2img buttons 2023-03-25 14:52:47 -04:00
AUTOMATIC1111 a0d07fb580 Merge pull request #8936 from space-nuko/fix-notifications
Fix notifications not triggering
2023-03-25 21:45:40 +03:00
space-nuko 945f6e5e99 Fix img2img aspect ratio overlay in Gradio 3.23.0 2023-03-25 14:44:41 -04:00
space-nuko 9377092a89 Fix notifications not triggering 2023-03-25 14:28:20 -04:00
space-nuko c5f9f7c237 Use .success() callback on img2img preview inputs change 2023-03-25 14:26:36 -04:00
Vespinian 23f6dfce4c Reworked this PR, now we have 2 default arg list (one for each tab) that will be initialized on the first api request and then reused afterwards. The init_script_args copies the corresponding default list and applies the modifications asked by the api request. 2023-03-25 14:16:35 -04:00
Vespinian f371579571 Revert "Made copies of global scriptrunners, now we clear the copied scriptrunner of alwayson_scripts and only add back the ones that that were requested"
This reverts commit dfa258de5f.
2023-03-25 14:11:46 -04:00
Vespinian db602b100e Revert "Comment fix"
This reverts commit f04bd037a5.
2023-03-25 14:11:38 -04:00
LipeCarmel 5c7ab90a4e loopback.py Colab compatibility and bug fix
This code (suggested by @abvgdeabvgde2 ) literally does the same thing and it does not break with Python 3.9, making it helpful for Google Colab users (me included).
fixes #8927
Also a partial fix for #8902 but it does not resolve the unresponsive UI problem faced by @Archon332
2023-03-25 14:48:22 -03:00
space-nuko 75e7eb9172 img2img resolution preview should use currently selected tab's image 2023-03-25 12:53:03 -04:00
space-nuko 7ea5d395c4 Add upscaler to img2img 2023-03-25 12:52:43 -04:00
space-nuko 68999d0b15 Add upscale slider to img2img 2023-03-25 12:52:35 -04:00
pieresimakp fb72066ef6 fixed button position 2023-03-25 23:03:22 +08:00
pieresimakp e3b9d0e3e8 Merge branch 'master' into img2img-detect-image-size 2023-03-25 23:00:45 +08:00
kurilee 993c11549c Merge branch 'AUTOMATIC1111:master' into master 2023-03-25 22:47:05 +08:00
kurilee b2fc7dba2e Add option "keep original size" to textual inversion images preprocess 2023-03-25 22:45:41 +08:00
AUTOMATIC1111 91ae48fd7e Merge pull request #8921 from remixer-dec/fix-callstack-loop
fix overriding getElementById on document
2023-03-25 17:41:42 +03:00
AUTOMATIC 69eb2a9ee8 add missing extensions_dir, extensions_builtin_dir to extensions.py 2023-03-25 17:39:53 +03:00
Remixer Dec 22bfcf135f fix overriding getElementById on document 2023-03-25 18:23:34 +04:00
AUTOMATIC1111 b2c428a095 Merge pull request #8839 from pieresimakp/master
Add search textbox to filter available extensions by name/description
2023-03-25 16:15:42 +03:00
AUTOMATIC1111 9b2dcb04bc Merge branch 'master' into master 2023-03-25 16:15:29 +03:00
AUTOMATIC 68953a4705 specify the tests dir in automated tests 2023-03-25 16:12:50 +03:00
AUTOMATIC 8c801362b4 split commandline args into its own file
make launch.py use the same command line argument parser as the main program
2023-03-25 16:05:25 +03:00
Andrey 3ec7e19f2b Split history: mv temp modules/shared.py 2023-03-25 14:30:50 +03:00
Andrey 932dbfe7d9 Split history: merge 2023-03-25 14:30:50 +03:00
Andrey 0450d90605 Split history: mv modules/shared.py temp 2023-03-25 14:30:50 +03:00
Andrey a5cef4932f Split history: mv modules/shared.py modules/cmd_args.py 2023-03-25 14:30:49 +03:00
AUTOMATIC1111 aba5d639fb Merge pull request #8547 from vladmandic/image-size
disable pil checks
2023-03-25 14:04:46 +03:00
AUTOMATIC1111 d9b9bf78b3 Merge pull request #8508 from vladmandic/lightning
allow usage of latest pytorch_lighning
2023-03-25 14:03:59 +03:00
AUTOMATIC1111 009bc9f534 Merge pull request #8698 from Narsil/update_safetensors
Updating safetensors version (fully backward compatible)
2023-03-25 13:06:05 +03:00
AUTOMATIC1111 6b00d876f7 Merge pull request #7936 from EllangoK/master
Custom height and width settings for Extra Networks cards
2023-03-25 13:01:49 +03:00
AUTOMATIC1111 a03536f213 Merge pull request #8662 from vladmandic/api-handler
api error handler
2023-03-25 12:47:32 +03:00
EllangoK 38335e1b8f readds metadata_button 2023-03-25 05:47:06 -04:00
AUTOMATIC 616cc13b6b update overflow-wrap: break-word; for gradio 3.23 2023-03-25 12:43:14 +03:00
AUTOMATIC1111 bb851e84c1 Merge pull request #8723 from whwlsfb/patch-1
fix output-html text overflow.
2023-03-25 12:36:43 +03:00
AUTOMATIC1111 db7caf9b9c Merge branch 'master' into patch-1 2023-03-25 12:36:35 +03:00
AUTOMATIC c1294d849a make it possible for user to enable gradio analytics by setting GRADIO_ANALYTICS_ENABLED=True 2023-03-25 12:21:18 +03:00
AUTOMATIC1111 501f40d834 Merge pull request #8658 from hananbeer/disable_gradio_analytics
preserve privacy by disabling gradio analytics globally
2023-03-25 12:19:40 +03:00
AUTOMATIC1111 983d48a921 Merge pull request #8772 from mcmonkey4eva/img2img-alt-sd2-fix
Fix img2img-alternative-test script for SD v2.x
2023-03-25 12:16:09 +03:00
Karun 63a2f8d822 Merge branch 'master' into master 2023-03-25 05:12:55 -04:00
AUTOMATIC b7c14ed041 final part of merging #8749 2023-03-25 12:10:03 +03:00
AUTOMATIC1111 e442b73633 Merge pull request #8749 from missionfloyd/extra-network-info
Don't bubble when metadata_button is clicked
2023-03-25 12:09:05 +03:00
AUTOMATIC1111 8dbe793af5 Merge branch 'master' into extra-network-info 2023-03-25 12:08:24 +03:00
AUTOMATIC1111 70615448b2 Merge pull request #8717 from nonnonstop/fix-installpy
Fix problem of install.py when data-dir is specified
2023-03-25 12:05:44 +03:00
AUTOMATIC1111 956ed9a737 Merge pull request #8780 from Brawlence/master
Unload and re-load checkpoint to VRAM on request (API & Manual)
2023-03-25 12:03:26 +03:00
AUTOMATIC1111 8d2c582e3e Merge pull request #8797 from ArrowM/master
Move `load_file_from_url` import
2023-03-25 11:34:07 +03:00
AUTOMATIC1111 c0a7ff8055 Merge pull request #8803 from mlhub-action/fix_scripts_load_order
Fix scripts load order
2023-03-25 11:23:41 +03:00
AUTOMATIC1111 90410e212f Merge pull request #8814 from catboxanon/inpaint-mask
Add ability to display and/or save inpainting mask and masked composite
2023-03-25 11:21:45 +03:00
AUTOMATIC1111 8402682118 Merge pull request #8651 from vladmandic/flicker
disable gradio css transitions
2023-03-25 11:05:50 +03:00
AUTOMATIC1111 e8bbc344c3 Merge pull request #8824 from zimkjh/fix-variable-typo
fix variable typo
2023-03-25 11:04:46 +03:00
AUTOMATIC1111 9d2551d593 Merge pull request #8647 from Tps-F/add_submodule
Support git submodule for extension and Fix Windows PermissionError
2023-03-25 11:02:41 +03:00
AUTOMATIC1111 442f710d94 Merge pull request #8799 from JaRail/master
Loopback Script Updates
2023-03-25 10:41:24 +03:00
AUTOMATIC1111 2664198584 Merge pull request #8801 from EllangoK/xyz-values
Fixes xyz extra_generation_params not being saved (previously worked)
2023-03-25 10:39:19 +03:00
AUTOMATIC1111 275834ca97 Merge pull request #8731 from jokker87/master
fixed typo in prompt-bracket-checker.js which leads to js error
2023-03-25 10:29:27 +03:00
AUTOMATIC 9ed04e759d use HTTP request to fetch metadata for Lora cards instead of including it into the main page 2023-03-25 10:11:04 +03:00
AUTOMATIC1111 724a63714d Merge pull request #8878 from butaixianran/master
Fix None type error for TI module
2023-03-25 09:20:43 +03:00
AUTOMATIC1111 89ea746f7c Merge pull request #8866 from brkirch/mps-torch-2-0-nn-linear-workarounds
Add PyTorch 2.0 support for macOS, fix image generation on macOS 13.2.X
2023-03-25 09:17:09 +03:00
AUTOMATIC1111 03c8eefbcc Merge pull request #8782 from FNSpd/master
--upcast-sampling support for CUDA
2023-03-25 09:10:01 +03:00
AUTOMATIC b0b777e64d Merge branch 'gradio-3-22' 2023-03-25 09:00:51 +03:00
AUTOMATIC 58c3144d2b fix generate forever and other context menus 2023-03-25 09:00:38 +03:00
AUTOMATIC 133fd7bea5 restore interrupt/stop button styling 2023-03-25 09:00:38 +03:00
AUTOMATIC 889f5e38a1 fix clipping in lightbox image viewer 2023-03-25 09:00:38 +03:00
AUTOMATIC 4697def235 bump gradio to 3.23
fix broken image dragging
2023-03-25 09:00:37 +03:00
AUTOMATIC ff216820fd fix extra networks ui 2023-03-25 09:00:37 +03:00
AUTOMATIC af2db25c84 enable queue by default
more stylistic changes
2023-03-25 09:00:37 +03:00
AUTOMATIC 43a0912a07 hide delete button for single-item dropdown
more stylistic changes
2023-03-25 09:00:37 +03:00
AUTOMATIC 9b2f205400 fix ctrl+up/down attention edit
fix dropdown obscured by live preview
stylistic changes
2023-03-25 09:00:36 +03:00
AUTOMATIC 9f0da9f6ed initial gradio 3.22 support 2023-03-25 09:00:36 +03:00
AUTOMATIC 23d68bfc9a fix generate forever and other context menus 2023-03-25 08:54:01 +03:00
AUTOMATIC 82905f520c restore interrupt/stop button styling 2023-03-25 08:48:34 +03:00
AUTOMATIC 1bfa1be6dd fix clipping in lightbox image viewer 2023-03-25 08:28:21 +03:00
AUTOMATIC 9e1afa9eb4 bump gradio to 3.23
fix broken image dragging
2023-03-25 07:29:51 +03:00
FNSpd a9eab236d7 Update devices.py 2023-03-24 23:08:30 +04:00
butaixianran 803d44c474 Fix None type error for TI module
When user using model_name.png as a preview image, textural_inversion.py still treat it as an embeding, and didn't handle its error, just let python throw out an None type error like following:
```bash
  File "D:\Work\Dev\AI\stable-diffusion-webui\modules\textual_inversion\textual_inversion.py", line 155, in load_from_file
    name = data.get('name', name)
AttributeError: 'NoneType' object has no attribute 'get'
```

With just a simple `if data:` checking as following, there will be no error, breaks nothing, and now this module can works fine with user's preview images.
Old code:  
```python
                data = extract_image_data_embed(embed_image)
                name = data.get('name', name)
```
New code:  
```python
                data = extract_image_data_embed(embed_image)
                if data:
                    name = data.get('name', name)
                else:
                    # if data is None, means this is not an embeding, just a preview image
                    return
```

Also, since there is no more errors on textual inversion module, from now on, extra network can set "model_name.png" as preview image for embedings.
2023-03-25 02:05:00 +08:00
FNSpd 280ed8f00f Update sd_hijack_optimizations.py 2023-03-24 16:29:16 +04:00
FNSpd beb7dda5d6 Update sd_hijack_unet.py 2023-03-24 16:25:42 +04:00
brkirch 27fe3eb6a9 Add workaround for MPS layer_norm on PyTorch 2.0
On PyTorch 2.0, with MPS layer_norm only accepts float32 inputs. This was fixed shortly after 2.0 was finalized so the workaround can be applied with an exact version match.
2023-03-24 04:04:22 -04:00
brkirch c5142e2fbe Add workaround for broken nn.Linear on macOS 13.2
Credit to danieldk (https://github.com/explosion/curated-transformers/pull/124) for the workaround this is based on.
2023-03-24 04:04:20 -04:00
pieresimakp 771ea212de added button to grab the width and height from the loaded image in img2img 2023-03-24 12:41:17 +08:00
space-nuko d86beb8228 Remove "do not add watermark to images" option 2023-03-23 17:09:59 -04:00
pieresimakp 252f15e046 added search textbox to filter available extensions 2023-03-23 23:43:00 +08:00
James Railton a9eef1fbb1 Fix "masked content" in loopback script
The loopback script did not set masked content to original after first loop. So each loop would apply a fill, or latent mask. This would essentially reset progress each loop.

The desired behavior is to use the mask for the first loop, then continue to iterate on the results of the previous loop.
2023-03-23 10:44:25 -04:00
carat-johyun 92e173d414 fix variable typo 2023-03-23 14:28:08 +09:00
catboxanon caf84e8233 Expose inpainting mask and composite
For inpainting, this exposes the mask and masked composite and gives
the user the ability to display these in the web UI,
save to disk, or both.
2023-03-22 17:51:40 +00:00
sumof2primes cd3cd0fca0 Fix scripts load order
- 1st webui, 2nd extensions-builtin, 3rd extensions
 - to load scripts independent of --data-dir
 - change load order key [x.basedir, x.filename, x.path] to [orderby(x.basedir), x.filename, x.path]

e.g., scripts/xyz_grid.py dependent extentions should loaded later
extensions\sd-webui-controlnet\scripts\xyz_grid_support.py
extensions\sd-webui-additional-networks\scripts\xyz_grid_support.py
2023-03-23 01:28:09 +09:00
sumof2primes 64b7e83823 Fix scripts load order
- 1st webui, 2nd extensions-builtin, 3rd extensions
 - to load scripts independent of --data-dir
 - change load order key [x.basedir, x.filename, x.path] to [orderby(x.basedir), x.filename, x.path]

e.g., scripts/xyz_grid.py dependent extentions should loaded later
extensions\sd-webui-controlnet\scripts\xyz_grid_support.py
extensions\sd-webui-additional-networks\scripts\xyz_grid_support.py
2023-03-22 18:24:11 +09:00
EllangoK e7ac09b25a fixes xyz extra_generation_params not being saved 2023-03-22 02:11:38 -04:00
ArrowM 00bd271faf Move load_file_from_url
Why?
one of the internal calls of `load_file_from_url` import cv2, which locks the cv2 site-package, which extensions may (and in our case, is) breaking the installation of some libraries. The base project should be limiting its import of unnecessary libraries when possible during the installation phase.
2023-03-21 21:13:30 -05:00
James Railton 33b8539147 Loopback Script Updates
- Improved user experience. You can now pick the denoising strength of the final loop and one of three curves. Previously you picked a multiplier such as 0.98 or 1.03 to define the change to the denoising strength for each loop. You had to do a ton of math in your head to visualize what was happening. The new UX makes it very easy to understand what's going on and tweak.
- For batch sizes over 1, intermediate images no longer returned. For a batch size of 1, intermediate images from each loop will continue to be returned. When more than 1 image is returned, a grid will also be generated. Previously for larger jobs, you'd get back a mess of many grids and potentially hundreds of images with no organization. To make large jobs usable, only final images are returned.
- Added support for skipping current image. Fixed interrupt to cleanly end and return images. Previously these would throw.
- Improved tooltip descriptions
- Fix some edge cases
2023-03-21 21:07:33 -04:00
missionfloyd 1d096ed145 Lazy load extra network images 2023-03-21 16:07:24 -06:00
Rucadi a80d7d090c Update script_callbacks.py 2023-03-21 18:47:05 +01:00
FNSpd 2f0181405f Update lora.py 2023-03-21 14:53:51 +04:00
FNSpd c84c9df737 Update sd_hijack_optimizations.py 2023-03-21 14:50:22 +04:00
FNSpd 91cfa9718c Update sd_hijack_unet.py 2023-03-21 14:47:43 +04:00
FNSpd 254d994643 Update devices.py 2023-03-21 14:45:39 +04:00
Φφ 4cbbb881ee Unload checkpoints on Request
…to free VRAM.

New Action buttons in the settings to manually free and reload checkpoints, essentially
juggling models between RAM and VRAM.
2023-03-21 09:28:50 +03:00
AUTOMATIC d3dcb05904 fix extra networks ui 2023-03-21 09:24:19 +03:00
AUTOMATIC 6eacaad4a9 enable queue by default
more stylistic changes
2023-03-21 08:49:08 +03:00
AUTOMATIC f93547be18 hide delete button for single-item dropdown
more stylistic changes
2023-03-21 08:18:14 +03:00
AUTOMATIC 46482decd5 fix ctrl+up/down attention edit
fix dropdown obscured by live preview
stylistic changes
2023-03-21 06:49:19 +03:00
missionfloyd 8e3ced73a8 Add event.stopPropagation() to extraNetworksShowMetadata()
Prevent bubbling the same way "replace preview" does
2023-03-20 18:04:22 -06:00
Alex "mcmonkey" Goodwin c9c692c4d9 cleanup the img2img alt file a bit 2023-03-20 15:43:01 -07:00
Alex "mcmonkey" Goodwin 05ec128ca9 fix img2img alt for SD v2.x 2023-03-20 15:42:36 -07:00
AUTOMATIC 8ea8e712c4 initial gradio 3.22 support 2023-03-20 16:09:36 +03:00
missionfloyd 64fc936738 Don't bubble when metadata_button is clicked 2023-03-19 19:30:28 -06:00
Michael Bachmann cf17dfcd64 fixed typo in prompt-bracket-checker.js which leads to js error 2023-03-19 14:50:44 +01:00
whw1sfb e5dd5d7335 fix output-html text overflow. 2023-03-19 14:05:01 +08:00
nonnonstop b9a66b02d0 Fix problem of install.py when data-dir is specified 2023-03-19 01:17:04 +09:00
Nicolas Patry 4f415ad639 Updating safetensors version (fully backward compatible)
- Main takeaway is that the newly created files should load better
  because pointer alignment is forced
2023-03-17 09:02:36 +01:00
ParityError 34c0f499c5 Merge branch 'AUTOMATIC1111:master' into master 2023-03-17 00:36:17 -07:00
Ftps 6f5a5ad205 Delete settings.json 2023-03-16 12:36:11 +09:00
Ftps 147d2922ff Cross device link 2023-03-16 12:35:48 +09:00
Vespinian f04bd037a5 Comment fix 2023-03-15 22:27:54 -04:00
Vespinian dfa258de5f Made copies of global scriptrunners, now we clear the copied scriptrunner of alwayson_scripts and only add back the ones that that were requested 2023-03-15 22:17:32 -04:00
missionfloyd 575c17a8f9 Update tooltip per Kilvoctu's suggestion 2023-03-15 16:56:27 -06:00
Vespinian f6374934db Changed img2img scriptrunner for gui request from scripts_txt2img to scripts_img2img 2023-03-15 17:53:32 -04:00
Vladimir Mandic 5387576c59 api error handler 2023-03-15 15:11:04 -04:00
high_byte 79d261b7d4 disable gradio analytics globally 2023-03-15 19:44:30 +02:00
Vladimir Mandic 250193ee93 disable gradio css transitions 2023-03-15 10:14:40 -04:00
Ftps 79ed567b12 remove unused library
I'm sorry I forgot.
2023-03-15 22:42:53 +09:00
Ftps 4845db4e32 Update ui_extensions.py
Add git submodule and Fix WinError
2023-03-15 20:29:50 +09:00
unknown 54291f9d63 remove redundant load 2023-03-15 04:33:38 -05:00
bluelovers fd672a79af fix: remove cmp
by ChatGPT
2023-03-15 13:17:09 +08:00
InvincibleDude f5e4436453 Merge branch 'master' into improved-hr-conflict-test 2023-03-14 16:55:59 +03:00
Vladimir Mandic f2ed6295b9 make it module specific 2023-03-14 07:46:09 -04:00
Mikhail Gribanov 1823526c10 Update README.md 2023-03-14 13:05:45 +02:00
AUTOMATIC1111 a9fed7c364 Merge pull request #8503 from mcmonkey4eva/filename-length-limit-fix
Add correction file filename length limits on *nix systems
2023-03-14 11:28:13 +03:00
AUTOMATIC 6a04a7f20f fix an error loading Lora with empty values in metadata 2023-03-14 11:22:29 +03:00
AUTOMATIC1111 8b35b64e11 Merge pull request #8589 from vladmandic/unipc
add progressbar to unipc sampler
2023-03-14 11:19:21 +03:00
AUTOMATIC1111 f9b0465c8b Merge pull request #8588 from hananbeer/fix/undefined_extra_network_data
initialize extra_network_data before use
2023-03-14 11:18:30 +03:00
AUTOMATIC1111 58c4777cc0 Merge pull request #8607 from willtakasan/patch-2
Update ui_extra_networks.py
2023-03-14 11:12:31 +03:00
willtakasan 4281432594 Update ui_extra_networks.py
I updated it so that no error message is displayed when setting a webp for the preview image.
2023-03-14 15:36:08 +09:00
AUTOMATIC c19530f1a5 Add view metadata button for Lora cards. 2023-03-14 09:10:26 +03:00
Vladimir Mandic 03a80f198e add pbar to unipc 2023-03-13 12:35:30 -04:00
high_byte 4d26c7da57 initialize extra_network_data before use 2023-03-13 17:37:29 +02:00
unknown 40dc0132df modularize 2023-03-13 03:39:02 -05:00
missionfloyd 9e23bacfbc Make extra networks button togglable 2023-03-12 17:07:03 -06:00
ParityError 5c051c0618 Update webui.sh
Installation should not be assumed to be located within ~/home directory. User should be expected to install project anywhere and run the startup scripts while in stable-diffusion-webui directory.

See issue #8534
2023-03-12 15:10:44 -07:00
ParityError 6439e72df2 Update webui.sh
Installation should not be assumed to be located within ~/home directory. User should be expected to install project anywhere and run the startup scripts while in stable-diffusion-webui directory.

See issue #8534
2023-03-12 15:08:26 -07:00
ParityError d78c437583 Update webui-user.sh
Installation should not be assumed to be located within ~/home directory. User should expected to install project anywhere and run the startup scripts while in stable-diffusion-webui directory.
2023-03-12 12:41:27 -07:00
Alex "mcmonkey" Goodwin af9158a8c7 update fullfn properly 2023-03-12 12:36:04 -07:00
Alex "mcmonkey" Goodwin 48df6d66ea add safety check in case of short extensions
so eg if a two-letter or empty extension is used, `.txt` would break, this `max` call protects that.
2023-03-12 12:33:29 -07:00
Alex "mcmonkey" Goodwin a71b7b5ec0 relocate filename length limit to better spot 2023-03-12 12:30:31 -07:00
AUTOMATIC dfeee786f9 display correct timings after restarting UI 2023-03-12 21:25:22 +03:00
AUTOMATIC a00cd8b9c1 attempt to fix memory monitor with multiple CUDA devices 2023-03-12 21:04:17 +03:00
AUTOMATIC 6033de18bf revert webui.sh from #8492 2023-03-12 20:50:02 +03:00
AUTOMATIC 27eedb6966 change extension index link to the new dedicated repo instead of wiki 2023-03-12 17:20:17 +03:00
AUTOMATIC1111 806aa5e8e7 Merge pull request #8548 from vladmandic/total-tqdm
force refresh tqdm before close
2023-03-12 16:51:30 +03:00
Vladimir Mandic bd67c41f54 force refresh tqdm before close 2023-03-12 09:19:23 -04:00
Vladimir Mandic 8179901f9c disable pil checks 2023-03-12 09:12:54 -04:00
Vladimir Mandic fc4d593b4e fix import 2023-03-12 08:51:12 -04:00
AUTOMATIC 3c922d983b fix #8492 breaking the program when the directory with code contains spaces. 2023-03-12 12:11:51 +03:00
AUTOMATIC 5c9f2bbb74 do not import modules.paths in launch.py 2023-03-12 08:58:58 +03:00
AUTOMATIC1111 adf723a9b2 Merge pull request #8492 from zhanghua000/absolute-path
fix: gradio's ValueError about fetching extensions files
2023-03-12 08:55:15 +03:00
AUTOMATIC1111 ddc503d14c Merge pull request #8509 from vladmandic/fastapi
allow usage of latest fastapi
2023-03-12 08:26:57 +03:00
AUTOMATIC1111 6106f6d0a0 Merge pull request #7965 from Kilvoctu/extranet-buttons
Use emojis for extra network buttons
2023-03-12 08:25:03 +03:00
AUTOMATIC1111 beb96bd115 Merge pull request #8515 from EllangoK/unipc-typo
Fix dims typo in unipc
2023-03-12 08:24:17 +03:00
AUTOMATIC1111 bbc4b0478a Merge pull request #8518 from brkirch/remove-bool-test
Fix image generation on macOS 13.3 betas
2023-03-12 08:14:26 +03:00
AUTOMATIC1111 55ccc8fe6f Merge pull request #8523 from hananbeer/feature/xyz_face_restore
add face restoration option to xyz_grid
2023-03-12 08:12:47 +03:00
AUTOMATIC1111 3e2ac603e9 Merge pull request #8156 from bluelovers/pr/lightbox-001
feat: better lightbox when not enable zoom
2023-03-12 08:06:27 +03:00
AUTOMATIC1111 ab0b0e1e76 Merge pull request #8187 from Vespinian/master
Add a way for API txt2img and img2img requests to pass args to always on scripts
2023-03-12 08:00:55 +03:00
bluelovers db85421da1 feat: better lightbox when not enable zoom 2023-03-12 10:25:42 +08:00
bluelovers 0492424121 feat: try sort as ignore-case
https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/8368
2023-03-12 10:18:33 +08:00
high_byte 5ed5e95fb8 add face restoration option to xyz_grid 2023-03-12 03:29:07 +02:00
brkirch a4cb96d4ae Remove test, use bool tensor fix by default
The test isn't working correctly on macOS 13.3 and the bool tensor fix for cumsum is currently always needed anyway, so enable the fix by default.
2023-03-11 17:35:17 -05:00
EllangoK 48f4abd2e6 fix dims typo in unipc 2023-03-11 15:52:14 -05:00
Vespinian 64efb3d9e0 Merge branch 'master' of https://github.com/AUTOMATIC1111/stable-diffusion-webui 2023-03-11 14:35:20 -05:00
Vespinian 49bbdbe447 small diff whitespace cleanup 2023-03-11 14:34:56 -05:00
Kilvoctu 247a34498b restore text, remove 'close'
don't use emojis for extra network buttons; remove 'close'
2023-03-11 13:11:26 -06:00
AUTOMATIC 27e319dc4f alternative solution for #8089 2023-03-11 21:22:52 +03:00
Vespinian 5546e71a10 Fixed whitespace 2023-03-11 12:35:20 -05:00
Vespinian 46f9fe3cd6 Merge branch 'master' of https://github.com/AUTOMATIC1111/stable-diffusion-webui 2023-03-11 12:33:35 -05:00
Vespinian 2174f58dae Changed alwayson_script_name and alwayson_script_args api params to 1 alwayson_scripts param dict 2023-03-11 12:21:33 -05:00
Vladimir Mandic 29ce0bf4f2 allow usage of latest fastapi 2023-03-11 12:01:08 -05:00
Vladimir Mandic fb088bfb64 all usage of newer pytorch_lighning 2023-03-11 11:13:21 -05:00
AUTOMATIC 94ffa9fc53 emergency fix for xyz plot 2023-03-11 18:55:48 +03:00
Alex "mcmonkey" Goodwin 7fd19fa4e7 initial fix for filename length limits on *nix systems 2023-03-11 07:22:22 -08:00
AUTOMATIC 5cea278d3a bump GitPython to 3.1.30 because some people would be upset about it being below that version #8118 2023-03-11 17:51:55 +03:00
AUTOMATIC1111 e0ca78509a Merge pull request #8118 from adam-huganir/8116-gitpython-api-breaking-change
git 3.1.30 api change, issue #8116
2023-03-11 17:47:51 +03:00
Adam Huganir 1e1a32b130 Update requirements_versions.txt
revert back to .27
2023-03-11 09:34:17 -05:00
AUTOMATIC1111 d3dd6cc01c Merge pull request #8175 from vladmandic/image_size
adds checks for resulting image size to avoid memory issues
2023-03-11 16:45:35 +03:00
AUTOMATIC1111 76bc72116e Merge pull request #7818 from space-nuko/extension-paste-field-names
Allow extensions to declare paste fields for "Send to X" buttons
2023-03-11 16:44:20 +03:00
AUTOMATIC1111 ef9efb61aa Merge pull request #7954 from EllangoK/xyz-newline
Fixes newlines within checkpoints being detected as its own entry
2023-03-11 16:37:51 +03:00
AUTOMATIC1111 b9fd9c81de Merge pull request #7963 from xSinStarx/patch-1
Bug Fix: Fixes img2img Negative Token Counter
2023-03-11 16:34:34 +03:00
Vladimir Mandic a47c18297e use assert instead of return 2023-03-11 08:33:55 -05:00
AUTOMATIC 52dcf0f0c7 record startup time 2023-03-11 16:27:58 +03:00
AUTOMATIC1111 f968270fec Merge pull request #7812 from vladmandic/hide_ui_tabs
allow configurable hiding of ui tabs
2023-03-11 16:00:43 +03:00
AUTOMATIC1111 4637116341 Merge pull request #8021 from 112292454/master
continue fix prompt_matrix.py when high-res
2023-03-11 15:59:13 +03:00
AUTOMATIC 6da2027213 save previews for extra networks in the selected format 2023-03-11 15:46:20 +03:00
AUTOMATIC 9320139bd8 support three extensions for preview instead of one: png, jpg, webp 2023-03-11 15:33:24 +03:00
AUTOMATIC ce68ab8d0d remove underscores from function names in #8366
remove LRU from #8366 because I don't know why it's there
2023-03-11 15:27:42 +03:00
AUTOMATIC1111 c239b3d7a8 Merge pull request #8366 from akx/extra-net-descs
Extra network description files
2023-03-11 15:20:34 +03:00
AUTOMATIC1111 92bb54720f Merge pull request #8031 from DrakeRichards/notification-fix
Bug fix: Added results selector for notifications
2023-03-11 15:19:03 +03:00
AUTOMATIC1111 e15c4f31e3 Merge pull request #8042 from fkunn1326/master
Add .mjs support for extensions
2023-03-11 15:18:05 +03:00
AUTOMATIC f36ba9949a add credit for UniPC sampler into the readme 2023-03-11 15:02:58 +03:00
Zhang Hua d25c4b13e4 test/basic_features/{extras,img2img}_test.py: use absolute path 2023-03-11 20:00:12 +08:00
Zhang Hua 9abe2f5e74 test/server_poll.py: use absolute path for test
test/server_poll.py: fix absolute path
2023-03-11 20:00:12 +08:00
Zhang Hua 8e0d16e746 modules/sd_vae_approx.py: fix VAE-approx path 2023-03-11 20:00:12 +08:00
Zhang Hua 8106117a47 models/ui.py: make the path of script.js absolute 2023-03-11 20:00:11 +08:00
Zhang Hua 1fa1ab5249 launch.py: fix failure because webui.sh's changes
launch.py: using getcwd() instead curdir

launch.py: use absolute path for preparing

also remove chdir()

launch.py: use absolute path for test

launch.py: add default script_path and data_path
2023-03-11 20:00:11 +08:00
Zhang Hua d006108d75 webui.sh: remove all cd related code
This may be helpful for
https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/7028,
because we won't change working directory to the repo now, instead,
we will use any working directory. If we set working directory to
a path contains repo and the custom --data-dir, the problem in this
issue should be solved.

Howewer, this may be treated as an incompatible change if some code
assume the working directory is always the repo.

Also, there may be another solution that always let --data-dir be the
subdirectory of the repo, but personally I think this may not be what
we actually need.

As this issue mainly influent on Docker and I am not familiar with
.bat files, updating webui.bat is skipped.

webui.sh: source env from repo instead $PWD
2023-03-11 20:00:11 +08:00
AUTOMATIC1111 98695c1885 Merge pull request #8050 from Tpinion/master
Bugfix: Filter out temporary files that will be generated if the download fails.
2023-03-11 14:58:45 +03:00
AUTOMATIC 7f2005127f rename CFGDenoiserParams fields for #8064 2023-03-11 14:52:29 +03:00
AUTOMATIC1111 af416a2dbd Merge pull request #8064 from laksjdjf/master
Add cond and uncond hidden states to CFGDenoiserParams
2023-03-11 14:48:55 +03:00
AUTOMATIC1111 2b0ef2c4e6 Merge pull request #8112 from vladmandic/progressbar
fix progressbar
2023-03-11 14:36:23 +03:00
AUTOMATIC1111 45905b92a9 Merge pull request #8100 from missionfloyd/webp-lossless
Add lossless webp option
2023-03-11 14:35:53 +03:00
AUTOMATIC1111 da3f942ab2 Merge pull request #8017 from space-nuko/before-process-batch
Add `before_process_batch` script callback
2023-03-11 14:33:38 +03:00
AUTOMATIC aaa367e35c new setting: Extra text to add before <...> when adding extra network to prompt 2023-03-11 14:18:18 +03:00
AUTOMATIC1111 5fd1158b9e Merge pull request #8496 from butaixianran/master
update "replace preview" link button's css
2023-03-11 14:10:25 +03:00
AUTOMATIC1111 9df72be90e Merge pull request #8202 from Ju1-js/master
Gradio auth logic fix - Handle empty/newlines
2023-03-11 14:02:07 +03:00
AUTOMATIC1111 9860a6acda Merge pull request #8326 from DejitaruJin/xyz-order-fix
Xyz order fix
2023-03-11 13:51:35 +03:00
AUTOMATIC1111 6705b1764a Merge pull request #8092 from infinitewarp/sort-upscalers
sort upscalers by name
2023-03-11 13:44:41 +03:00
AUTOMATIC1111 8ec0442dcd Merge pull request #8322 from yeataro/master
add: /sdapi/v1/scripts in API
2023-03-11 13:43:34 +03:00
butaixianran 946797b01d update "replace preview" link button's css
modify css
`.extra-network-thumbs .card:hover .additional a` 's value from `block` to `inline-block`.
So, extensions can add more buttons to extra network's thumbnail card.
2023-03-11 18:42:14 +08:00
AUTOMATIC 3531a50080 rename fields for API for saving/sending images
save images to correct directories
2023-03-11 13:22:59 +03:00
AUTOMATIC1111 bb3ecc3285 Merge pull request #8287 from vladmandic/save-images
Allow saving of images generated via API
2023-03-11 13:03:23 +03:00
AUTOMATIC1111 d81c503918 Merge pull request #8367 from pamparamm/scaled-dot-product-attention
Add scaled dot product attention
2023-03-11 12:24:03 +03:00
AUTOMATIC 1ace16e799 use path to git from env variable for git_pull_recursive 2023-03-11 12:21:53 +03:00
AUTOMATIC1111 f0a917c990 Merge pull request #8425 from vladlearns/master
feat: auto update all extensions using flag
2023-03-11 12:20:30 +03:00
AUTOMATIC 58b5b7c2f1 add UniPC options to infotext 2023-03-11 12:09:36 +03:00
AUTOMATIC f261a4a53c use selected device instead of always cuda for UniPC sampler 2023-03-11 11:56:05 +03:00
AUTOMATIC1111 a11ce2b96c Merge pull request #7710 from space-nuko/unipc
Implement UniPC sampler
2023-03-11 11:45:31 +03:00
space-nuko 5fef67f6ee Requested changes 2023-03-10 19:56:14 -05:00
space-nuko ac38ad7e60 Merge remote-tracking branch 'origin/master' into unipc 2023-03-10 19:42:46 -05:00
Pam 8d7fa2f67c sdp_attnblock_forward hijack 2023-03-10 22:48:41 +05:00
Vladimir Mandic 1226028b9c fix silly math error 2023-03-10 11:21:48 -05:00
InvincibleDude f6e2737840 Negative prompt fix 2023-03-10 12:13:55 +00:00
Pam 0981dea948 sdp refactoring 2023-03-10 12:58:10 +05:00
Pam 37acba2633 argument to disable memory efficient for sdp 2023-03-10 12:19:36 +05:00
vladlearns 13081dd45e chore: added autostash flag to pull 2023-03-09 16:56:06 +02:00
vladlearns b07b7057f0 chore: removed scripts and added a flag to launch.py 2023-03-09 16:29:07 +02:00
vladlearns 09c73710c9 chore: auto update all extensions using scripts 2023-03-08 23:00:55 +02:00
Yea Chen f85a192f99 Update modules/api/api.py
Suggested change by @akx

Co-authored-by: Aarni Koskela <akx@iki.fi>
2023-03-07 04:04:35 +08:00
Pam fec0a89511 scaled dot product attention 2023-03-07 00:33:13 +05:00
Aarni Koskela 06f167da37 Extra networks: support .txt description sidecar file 2023-03-06 21:15:33 +02:00
Aarni Koskela 49b1dc5e07 Deduplicate extra network preview-search code 2023-03-06 21:00:34 +02:00
Brad Smith d118cb6ea3 use lowercase name for sorting; keep UpscalerLanczos and UpscalerNearest at the start of the list with UpscalerNone
Co-authored-by: catboxanon <122327233+catboxanon@users.noreply.github.com>
2023-03-06 13:21:42 -05:00
DejitaruJin c8b52c7975 Short-circuit error handling 2023-03-04 19:32:09 -05:00
Vladimir Mandic b012d70f15 update using original defaults 2023-03-04 17:51:37 -05:00
DejitaruJin eb29ff211a Add files via upload 2023-03-04 16:06:40 -05:00
DejitaruJin fe7d7dfd5a Add files via upload 2023-03-04 15:40:35 -05:00
InvincibleDude b9fdb9f701 Fix crash when hr is disabled 2023-03-04 18:09:05 +00:00
DejitaruJin 2ba880704b Add files via upload 2023-03-04 13:00:27 -05:00
DejitaruJin 2d9635cce5 Fix display and save order for X/Y/Z Grid script 2023-03-04 12:51:55 -05:00
Yea chen c48bbccf12 add: /sdapi/v1/scripts in API
API for get scripts list
2023-03-04 11:46:07 +08:00
InvincibleDude e97b83bdbb Merge branch 'master' into improved-hr-conflict-test 2023-03-03 19:49:24 +03:00
InvincibleDude 51f81efb02 Image processing changes
Image processing changes
2023-03-03 19:45:33 +03:00
Vladimir Mandic f8e219bad9 allow api requests to specify do not send images in response 2023-03-03 09:00:52 -05:00
Vladimir Mandic 23d4fb5bf2 allow saving of images via api 2023-03-03 08:29:10 -05:00
Ju1-js fc3063d9b9 Remove unnecessary line 2023-03-01 18:25:23 -08:00
Adam Huganir b14d8b61bd version bump for git python due to CVE-2022-24439
required version for CVE-2022-24439 is >= 3.130
2023-03-01 13:07:37 -05:00
Ju1-js 7990ed92be Slash was facing the wrong way 2023-02-28 22:05:47 -08:00
Ju1-js 1e30e4d9eb Gradio auth logic fix - Handle empty/newlines
When the massive one-liner was split into multiple lines, it lost the ability to handle newlines. This removes empty strings & newline characters from the logins. It also closes the file so it's more robust if the garbage collection function is ever changed.
2023-02-28 15:55:12 -08:00
Vespinian c6c2a59333 comment clarification 2023-02-27 23:45:59 -05:00
Vespinian a39c4cf766 small refactor of api.py 2023-02-27 23:27:33 -05:00
Vespinian 3b6de96467 Added alwayson_script_name and alwayson_script_args to api
Added 2 additional possible entries in the api request: alwayson_script_name, a string list, and, alwayson_script_args, a list of list containing the args of each script. This allows us to send args to always on script and keep backwards compatibility with old script_name and script_arg api params
2023-02-27 21:51:20 -05:00
Vladimir Mandic 3c6459154f add check for resulting image size 2023-02-27 17:28:04 -05:00
Adam Huganir 6d92d95a33 git 3.1.30 api change 2023-02-25 19:15:06 +00:00
Vladimir Mandic ed43a822b2 fix progressbar 2023-02-25 12:56:03 -05:00
missionfloyd aa108bd02a Add lossless webp option 2023-02-24 20:57:18 -07:00
Brad Smith b15bc73c99 sort upscalers by name 2023-02-24 14:45:08 -05:00
laksjdjf 534cf60afb Update script_callbacks.py 2023-02-24 14:26:55 +09:00
laksjdjf 9a1435946c Update sd_samplers_kdiffusion.py 2023-02-24 14:04:23 +09:00
laksjdjf 327186b484 Update script_callbacks.py 2023-02-24 14:03:46 +09:00
Tpinion ac4c7f05cd Filter out temporary files that will be generated if the download fails. 2023-02-24 00:42:29 +08:00
fkunn1326@users.noreply.github.com b90cad7f31 Add .mjs support for extensions 2023-02-23 03:29:22 +00:00
Thomas Young 6825de7bc8 Added results selector
This causes the querySelectorAll function to only select images in a results div, ignoring images that might be in an extension's gallery.
2023-02-22 15:31:49 -06:00
112292454 2fa91cbee6 Update prompt_matrix.py
1
2023-02-23 01:55:07 +08:00
112292454 2c58d373dd Update prompt_matrix.py
this file last commit fixed common situation when using both prompts matrix and high-res。
but if we just open matrix option,but not use ‘|’,we will only get one pic,and `processed.images[0].width, processed.images[1].height` will cause a index out of bounds exception
2023-02-22 21:40:42 +08:00
space-nuko a2d635ad13 Add before_process_batch script callback 2023-02-22 01:52:53 -08:00
Kilvoctu 32a4c8d961 use emojis for extra network buttons
🔄 for refresh
 for close
2023-02-20 15:14:06 -06:00
xSinStarx b0f2653541 Fixes img2img Negative Token Counter
The img2img negative token counter is counting the txt2img negative prompt.
2023-02-20 12:39:38 -08:00
EllangoK bab972ff8a fixes newline being detected as its own entry 2023-02-20 10:16:55 -05:00
AUTOMATIC1111 0cc0ee1bcb Merge pull request #7945 from w-e-w/fix-image-downscale
Fix broken image downscale TypeError
2023-02-20 14:45:54 +03:00
w-e-w f71a3c9c3a convert resolution to int using round() 2023-02-20 17:47:20 +09:00
EllangoK ca2b8faa83 custom height, width settings for extra networks 2023-02-19 14:38:22 -05:00
AUTOMATIC 65995a2ea3 possible fix for #7804 2023-02-19 18:31:51 +03:00
Vladimir Mandic 83829471de make ui as multiselect instead of string list 2023-02-19 09:21:44 -05:00
Vladimir Mandic 8affa42588 Merge branch 'AUTOMATIC1111:master' into hide_ui_tabs 2023-02-19 09:19:25 -05:00
AUTOMATIC1111 076d624a29 Merge pull request #7933 from w-e-w/fix-auto-sd-download
Fix issue with auto sd1.5 download
2023-02-19 15:04:03 +03:00
w-e-w 014e7323f6 when exists 2023-02-19 20:49:07 +09:00
w-e-w c77f01ff31 fix auto sd download issue 2023-02-19 20:37:40 +09:00
AUTOMATIC1111 7202213358 Merge pull request #7571 from mezotaken/int_loop
Optionally append interrogated prompt in loopback script
2023-02-19 14:23:31 +03:00
AUTOMATIC d84f3cf7a7 split #7300 into multiple lines 2023-02-19 13:11:48 +03:00
AUTOMATIC1111 c3d5a6ed37 Merge pull request #7300 from Ju1-js/master
Gradio Auth - Read from External File
2023-02-19 13:02:05 +03:00
AUTOMATIC 11183b4d90 fix for #6700 2023-02-19 12:44:56 +03:00
AUTOMATIC1111 e452facef4 Merge pull request #6700 from Shondoit/weighted-learning
Weighted learning of TIs and HNs
2023-02-19 12:41:35 +03:00
AUTOMATIC1111 dfb3b8f398 Merge branch 'master' into weighted-learning 2023-02-19 12:41:29 +03:00
AUTOMATIC1111 4313777322 Merge pull request #7703 from minux302/hotfix/fix_hn_api_arg
fix arg for train_hypernetwork api
2023-02-19 12:36:01 +03:00
AUTOMATIC1111 75a508ab53 Merge pull request #7430 from Einlar/6866-fix-hires-prompt-matrix
Fix prompt matrix #rows/#cols when using hires
2023-02-19 12:31:06 +03:00
AUTOMATIC1111 cfc9849f3f Merge branch 'master' into 6866-fix-hires-prompt-matrix 2023-02-19 12:30:58 +03:00
AUTOMATIC1111 d99bd04b3f Merge pull request #7568 from Klace/XYZ-ImageCFG
Add Image CFG Scale to XYZ Grid
2023-02-19 12:29:26 +03:00
AUTOMATIC1111 e0ced6696e Merge pull request #7525 from w-e-w/master
Fix: show correct help message on --help
2023-02-19 12:29:09 +03:00
AUTOMATIC1111 09835363ab Merge pull request #7572 from CurtisDS/fix-id-handle-in-extra-networks
Update ui_extra_networks.py to fix div id's that have spaces in them
2023-02-19 12:26:11 +03:00
AUTOMATIC1111 c46eea221f Merge pull request #7573 from mezotaken/batch-tooltip
Update batch count/size hints
2023-02-19 12:25:44 +03:00
AUTOMATIC 48d171bbb3 fix incorrectly named args for gr.Slider in prompt matrix and xyz grid 2023-02-19 12:25:05 +03:00
AUTOMATIC b908bed883 remove unneeded return from #7583 2023-02-19 12:23:40 +03:00
AUTOMATIC1111 563724f6e9 Merge pull request #7583 from EllangoK/master
Calls modules.sd_vae.refresh_vae_list(), fixes VAE list not updating
2023-02-19 12:23:06 +03:00
AUTOMATIC1111 b63a13c5ed Merge pull request #7651 from vladmandic/missing-imports
Add missing imports
2023-02-19 12:16:58 +03:00
AUTOMATIC1111 e287d9b294 Merge pull request #7650 from vladmandic/img2img-fix
Convert image from RGBA to RGB before saving
2023-02-19 12:15:27 +03:00
AUTOMATIC fe46a08f52 add slash to non-empty dirs in extra networks interface 2023-02-19 12:09:25 +03:00
AUTOMATIC 66cfd1dcfc Expose xyz_grid's values to other extensions for #7721 2023-02-19 11:45:04 +03:00
AUTOMATIC1111 226bc04653 Merge pull request #7637 from brkirch/fix-hypernetworks-pix2pix
Fix hypernetworks and instruct pix2pix not working with `--upcast-sampling`
2023-02-19 11:15:41 +03:00
AUTOMATIC1111 3fcc087317 Merge pull request #7731 from opparco/master
Add cfg_denoised_callback
2023-02-19 11:09:47 +03:00
AUTOMATIC1111 f04f4b28a2 Merge pull request #7925 from AUTOMATIC1111/revert-7601-aspect_ratio_sliders
Revert "Aspect ratio sliders"
2023-02-19 10:57:34 +03:00
AUTOMATIC1111 fd4ac5187a Revert "Aspect ratio sliders" 2023-02-19 10:55:39 +03:00
AUTOMATIC1111 b20f28eea9 Merge pull request #7601 from Gerschel/aspect_ratio_sliders
Aspect ratio sliders
2023-02-19 10:53:18 +03:00
AUTOMATIC1111 9c4eaac61f Merge pull request #7691 from missionfloyd/16bit-convert
Convert 16-bit greyscale to 8-bit when saving as JPEG
2023-02-19 10:15:49 +03:00
AUTOMATIC1111 2a4f893570 Merge pull request #7727 from missionfloyd/face-restore-setting
Fix face restorers setting
2023-02-19 10:14:42 +03:00
AUTOMATIC fb2354cb2a reword settings for 4chan export, remove unneded try/excepts, add try/except for actually saving JPG 2023-02-19 10:12:45 +03:00
AUTOMATIC1111 e572c3ed38 Merge pull request #7564 from w-e-w/configurable_image_downscale
Configurable JPG downscale threshold
2023-02-19 10:01:42 +03:00
AUTOMATIC 1646991637 display 8 (rather than 7) characters of the extension commit hash in the installed extensions table 2023-02-19 09:54:04 +03:00
AUTOMATIC1111 d023532c55 Merge pull request #7798 from vladmandic/extensions
add version to extensions table
2023-02-19 09:52:19 +03:00
AUTOMATIC 15f4b217b1 fix the a merge conflict resolve i did that entirely breaks image generation 2023-02-19 09:50:14 +03:00
AUTOMATIC1111 a77ac2eeaa Merge pull request #7730 from CCRcmcpe/fix-dpm-sde-batch
Fix DPM++ SDE not deterministic across different batch sizes (#5210)
2023-02-19 09:38:15 +03:00
AUTOMATIC a742facd95 make PNG info tab work properly with parameter overrides 2023-02-19 09:30:57 +03:00
AUTOMATIC1111 d7bcc942ff Merge pull request #7868 from space-nuko/fix-save-params-2
Fix params.txt saving for infotexts modified by process_batch
2023-02-19 09:15:51 +03:00
AUTOMATIC1111 6911deb242 Merge branch 'master' into fix-save-params-2 2023-02-19 09:15:45 +03:00
AUTOMATIC 75e03785fe remove download instruction 2023-02-19 09:12:01 +03:00
AUTOMATIC1111 9f113a84eb Merge pull request #7850 from asdfire1/instructionfix
Fixed missing part in the Linux installation instructions
2023-02-19 09:11:31 +03:00
AUTOMATIC1111 c69494673d Merge pull request #7824 from missionfloyd/download-model
Download model if none are found
2023-02-19 09:00:48 +03:00
AUTOMATIC1111 b66b6829aa Merge pull request #7789 from space-nuko/extra-networks-per-batch
Apply extra networks per-batch instead of per-session (fixes wildcards)
2023-02-19 08:44:40 +03:00
AUTOMATIC b5f69ad6af simply long version display for torch in UI 2023-02-19 08:38:38 +03:00
AUTOMATIC1111 aa7ddb8b0c Merge pull request #7911 from vladmandic/torch-version
store and print real torch version
2023-02-19 08:33:40 +03:00
Vladimir Mandic 9c7e6d5bba store and print real torch version 2023-02-18 11:31:02 -05:00
space-nuko b20737815a Fix params.txt saving for infotexts modified by process_batch 2023-02-16 21:44:46 -08:00
asdfire1 9691ca5f59 Fixed the Linux installation instructions 2023-02-16 11:59:14 +01:00
missionfloyd c4ea16a03f Add ".vae.ckpt" to ext_blacklist 2023-02-15 19:47:30 -07:00
Shondoit edb10092de Add ability to choose using weighted loss or not 2023-02-15 10:03:59 +01:00
Shondoit bc50936745 Call weighted_forward during training 2023-02-15 10:03:59 +01:00
Shondoit 21642000b3 Add PNG alpha channel as weight maps to data entries 2023-02-15 10:03:59 +01:00
Shondoit c4bfd20f31 Hijack to add weighted_forward to model: return loss * weight map 2023-02-15 10:03:59 +01:00
RcINS f55a7e04d8 Fix error when batch count > 1 2023-02-15 16:57:18 +08:00
missionfloyd 1615f786ee Download model if none are found 2023-02-14 20:54:02 -07:00
space-nuko 7df7e4d227 Allow extensions to declare paste fields for "Send to X" buttons 2023-02-14 03:55:42 -08:00
Vladimir Mandic a320d157ec all hiding of ui tabs 2023-02-13 20:26:47 -05:00
Vladimir Mandic 7893533674 add version to extensions table 2023-02-13 11:04:34 -05:00
space-nuko 0a4917ac40 Apply extra networks per-batch instead of per-session (fixes wildcards) 2023-02-13 03:33:28 -08:00
missionfloyd ceb8a4b222 Merge branch 'AUTOMATIC1111:master' into face-restore-setting 2023-02-12 23:31:19 -07:00
missionfloyd 02e52567bc Merge branch 'AUTOMATIC1111:master' into 16bit-convert 2023-02-12 23:31:08 -07:00
AUTOMATIC1111 3715ece0ad Merge pull request #7717 from zijiren233/master
Fix: v0.91.0 of fastapi Cannot add middleware after an application ha…
2023-02-13 08:12:51 +03:00
space-nuko 716a69237c support SD2.X models 2023-02-11 06:18:34 -08:00
Gerschel 742d86eed4 Merge pull request #2 from w-e-w/badge_style
remove Badge background and ⚠️ ->📏
2023-02-10 20:44:12 -08:00
opparco b78c5e87ba Add cfg_denoised_callback 2023-02-11 11:18:38 +09:00
RcINS 9e27af76d1 Fix DPM++ SDE not deterministic across different batch sizes (#5210) 2023-02-11 10:12:16 +08:00
space-nuko fb274229b2 bug fix 2023-02-10 14:30:35 -08:00
missionfloyd bf9b1d64a3 Fix face restorers setting 2023-02-10 15:27:08 -07:00
zijiren233 4f4debbadb Fix: v0.91.0 of fastapi Cannot add middleware after an application has started 2023-02-11 00:28:20 +08:00
space-nuko 06cb0dc920 Fix UniPC order 2023-02-10 05:36:41 -08:00
space-nuko 79ffb9453f Add UniPC sampler settings 2023-02-10 05:27:05 -08:00
space-nuko c88dcc20d4 UniPC does not support img2img (for now) 2023-02-10 05:00:54 -08:00
space-nuko 21880eb9e5 Fix logspam and live previews 2023-02-10 04:47:08 -08:00
space-nuko 1253199889 Working UniPC (for batch size 1) 2023-02-10 03:30:20 -08:00
minux302 33947a3c66 fix arg for hypernetwork train api 2023-02-10 17:58:35 +09:00
missionfloyd 73a97cac11 Use RGB for webp
Doesn't support greyscale (L)
2023-02-09 17:04:55 -07:00
w-e-w b313221ca6 remove Badge color and ⚠️ ->📏 2023-02-10 08:34:21 +09:00
missionfloyd 463ab84180 Convert 16-bit greyscale to 8-bit when saving as JPEG 2023-02-09 02:13:49 -07:00
Gerschel 374fe636b8 Squashed commit of the following:
commit b030b67ad005bfe29bcda692238a00042dcae816
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Wed Feb 8 16:38:56 2023 -0800

    styling adjustements

commit 80a2acb0230dd77489b0eb466f2efe827a053f6d
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Wed Feb 8 10:49:47 2023 -0800

    badge indicator toggles visibility by selection

commit 898922e025a6422ac947fb45c1fa4f1109882f0a
Merge: 745382a0 31bbfa72
Author: Gerschel <9631031+Gerschel@users.noreply.github.com>
Date:   Wed Feb 8 08:35:26 2023 -0800

    Merge pull request #1 from w-e-w/Rounding-Method

    Rounding Method

commit 31bbfa729a15ef35fa1f905345d3ba2b17b26ab9
Author: w-e-w <40751091+w-e-w@users.noreply.github.com>
Date:   Wed Feb 8 19:41:45 2023 +0900

    use switch

commit 85dbe511c33521d3ac62224bf0e0f3a48194ce63
Author: w-e-w <40751091+w-e-w@users.noreply.github.com>
Date:   Wed Feb 8 16:47:52 2023 +0900

    Rounding Method

commit 745382a0f4b8d16241545a3460d5206915959255
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Tue Feb 7 21:19:20 2023 -0800

    default set to round

commit 728579c618af30ec98a5af0991bd3f28bdaca399
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Tue Feb 7 21:17:03 2023 -0800

    cleaned some commented code out; added indicator

commit 5b288c24a1edd8a5c2f35214b9634316d05b8dae
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Tue Feb 7 18:19:00 2023 -0800

    needs cleaning; attempt at rounding

commit d9f18ae92b929576b0b8c5f1ef8b3b38e441e381
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Tue Feb 7 15:46:25 2023 -0800

    add rounding option in setting for aspect ratio

commit af22106802c9e42205649e4c71c23fcf5b8c62f6
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Tue Feb 7 13:18:45 2023 -0800

    added some ratios, sorted ratios by commonality

commit 11e2fba73cffe8cdbf4cd0860641b94428ca0e74
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Tue Feb 7 10:46:53 2023 -0800

    snaps to mulitples of 8 and along ratio

commit fa00387e07460b10ee82671a1bfa8687e00ee60b
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Mon Feb 6 14:54:59 2023 -0800

    updated slidercomponentcontroller

commit 8059bc111c3e2d1edb3314e05ab21b65120fa1dd
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Mon Feb 6 14:29:11 2023 -0800

    added step size adjustment on number field

commit 641157b9f27a874a24ee7b0a854a092e9eac3eec
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Mon Feb 6 14:12:03 2023 -0800

    added return step size to default when ratio is disabled

commit 5fb75ad28f2476f36100ec93922a8199adbd2a68
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Mon Feb 6 14:09:34 2023 -0800

    added step size adjustment

commit e33532883bc4709cd41c3775cbb646d1d5ab0584
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Mon Feb 6 11:56:15 2023 -0800

    adjusted dropdown size, padding, text-align

commit 81937329cee77f466c5a5b23c268d0c810128f84
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Mon Feb 6 11:39:57 2023 -0800

    added positioning and styling

commit 86eb4583782d92880a9a113a54ffbac9d92f3753
Author: Gerschel <Gerschel_Payne@hotmail.com>
Date:   Mon Feb 6 08:54:45 2023 -0800

    fix typo in defaults; added preventDefault in event
2023-02-08 18:57:32 -08:00
Vladimir Mandic 3ca41dbded add missing import
used later in line 70
2023-02-08 07:10:13 -05:00
Vladimir Mandic 3ee9ca5cb0 add missing import
used later in line 418
2023-02-08 07:08:09 -05:00
Vladimir Mandic 4c562a9832 convert rgba to rgb
some image format (e.g. jpg) do not support rgba
2023-02-08 07:03:36 -05:00
brkirch 2016733814 Apply hijacks in ddpm_edit for upcast sampling
To avoid import errors, ddpm_edit hijacks are done after an instruct pix2pix model is loaded.
2023-02-07 22:53:45 -05:00
unknown bfa14db2cb enable gallery scrolling functionality for horizontal scroll and gamepads 2023-02-07 16:54:12 -06:00
brkirch 4738486d8f Support for hypernetworks with --upcast-sampling 2023-02-06 18:10:55 -05:00
Gerschel 5d483bf307 aspect ratio for dim's; sliders adjust by ratio
Default choices added to settings in user interface section
Choices are editable by user

User selects from dropdown.
When you move one slider, the other adjusts according to the ratio
chosen.
Vice versa for the other slider.

Number fields for changes work as well.

For disabling ratio, an unlock pad "🔓" is available as a default.
This string can be changed to anything to serve as a disable,
as long as there is no colon ":".

Ratios are entered in this format, floats or ints with a colon "1:1".
The string is split at the colon, parses left and right as floats to
perform the math.
2023-02-06 08:18:04 -08:00
EllangoK 9a22c63f47 call modules.sd_vae.refresh_vae_list() 2023-02-06 00:52:31 -05:00
Vladimir Repin df8ee5f6b0 Update batch count/size hints 2023-02-06 00:52:57 +03:00
CurtisDS 584f782391 Update ui_extra_networks.py
update the string used to build the ID handle to replace spaces with underscore
2023-02-05 16:42:45 -05:00
Vladimir Repin 7dd23973f7 Optionally append interrogated prompt in loopback script 2023-02-06 00:28:31 +03:00
Kyle 67303fd5fc Img2Img Only
Will still show up as an option with regular img2img models, but outputs no changes.
2023-02-05 15:34:26 -05:00
Kyle c8109f0dea Add Image CFG Scale to XYZ Grid 2023-02-05 15:18:18 -05:00
InvincibleDude c3bd113a0b Image info fix 2023-02-05 15:24:41 +00:00
InvincibleDude f4b78e73a4 Merge branch 'AUTOMATIC1111:master' into improved-hr-conflict-test 2023-02-05 18:02:44 +03:00
w-e-w fe33be6cac use Default if ValueError 2023-02-05 23:33:05 +09:00
w-e-w 6d11cda418 configurable image downscale
allowing the user to configure the image downscale parameters in setting
2023-02-05 23:12:42 +09:00
w-e-w 47b298d58a Merge branch 'AUTOMATIC1111:master' into master 2023-02-05 22:02:30 +08:00
unknown 501d4e9cf1 Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui into gamepad 2023-02-05 07:24:57 -06:00
AUTOMATIC1111 ea9bd9fc74 Merge pull request #7556 from EllangoK/master
Adds options for grid margins to XYZ Plot and Prompt Matrix
2023-02-05 13:34:36 +03:00
EllangoK 0ca1a64cfc adds grid margins to xyz plot and prompt matrix 2023-02-05 03:44:56 -05:00
AUTOMATIC1111 3993aa43e9 Merge pull request #7535 from mcmonkey4eva/fix-symlink-extra-network
fix symlinks in extra networks ui
2023-02-05 11:28:30 +03:00
AUTOMATIC1111 27a50d4b38 Merge pull request #7554 from techneconn/feature/prompt_hash_option
Add prompt_hash option for file/dir name pattern
2023-02-05 11:27:05 +03:00
AUTOMATIC1111 475095f50a Merge pull request #7528 from spezialspezial/patch-1
Catch broken model symlinks early | Quickfix modelloader.py
2023-02-05 11:24:32 +03:00
AUTOMATIC 668d7e9b9a make it possible to load SD1 checkpoints without CLIP 2023-02-05 11:21:00 +03:00
techneconn 5a1b62e9f8 Add prompt_hash option for file/dir name pattern 2023-02-05 15:48:51 +09:00
Alex "mcmonkey" Goodwin 88a46e8427 fix symlinks in extra networks ui
'absolute' and 'resolve' are equivalent, but 'resolve' resolves symlinks (which is an obscure specialty behavior usually not wanted) whereas 'absolute' treats symlinks as folders (which is the expected behavior). This commit allows you to symlink folders within your models/embeddings/etc. dirs and have preview images load as expected without issue.
2023-02-04 09:10:00 -08:00
spezialspezial 6524478850 Update modelloader.py
os.path.getmtime(filename) throws exception later in codepath when meeting broken symlink. For now catch it here early but more checks could be added for robustness.
2023-02-04 16:52:15 +01:00
w-e-w dd20fc0fda fix --help
show correct help message
2023-02-04 23:23:20 +09:00
AUTOMATIC 3e0f9a7543 fix issue with switching back to checkpoint that had its checksum calculated during runtime mentioned in #7506 2023-02-04 15:23:16 +03:00
AUTOMATIC 40e51fd6ef add margin parameter to draw_grid_annotations 2023-02-04 13:29:04 +03:00
AUTOMATIC1111 21593c8082 Merge pull request #7466 from ctwrs/master
Add .jpg to allowed thumb formats
2023-02-04 12:07:45 +03:00
AUTOMATIC1111 c0e0b5844d Merge pull request #7470 from cbrownstein-lambda/update-error-message-no-checkpoint
Update error message WRT missing checkpoint file
2023-02-04 12:07:12 +03:00
AUTOMATIC1111 dca632ab90 Merge pull request #7509 from mezotaken/fix-img2imgalt
Fix img2imgalt after samplers separation
2023-02-04 11:41:29 +03:00
AUTOMATIC 81823407d9 add --no-hashing 2023-02-04 11:38:56 +03:00
AUTOMATIC1111 30228c67ca Merge pull request #7461 from brkirch/mac-fixes
Move Mac related code to separate file
2023-02-04 11:22:52 +03:00
AUTOMATIC c4b9ed1a27 make Image CFG Scale only show if instrutpix2pix model is loaded 2023-02-04 11:18:44 +03:00
AUTOMATIC 72dd5785d9 merge CFGDenoiserEdit and CFGDenoiser into single object 2023-02-04 11:06:17 +03:00
brkirch 4306659c4d Remove unused code 2023-02-04 01:22:06 -05:00
AUTOMATIC1111 127bfb6c41 Merge pull request #7481 from Klace/master
img2img instruct-pix2pix support
2023-02-04 09:05:21 +03:00
unknown 5e1f4f7464 Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui into gamepad 2023-02-03 20:39:42 -06:00
Kyle ba6a4e7e94 Use original CFGDenoiser if image_cfg_scale = 1
If image_cfg_scale is =1 then the original image is not used for the output. We can then use the original CFGDenoiser to get the same result to support AND functionality.

Maybe in the future AND can be supported with "Image CFG Scale"
2023-02-03 19:46:13 -05:00
Kyle c27c0de0f7 txt2img Hires Fix 2023-02-03 19:15:32 -05:00
Kyle 6c6c6636bb Image CFG Added (Full Implementation)
Uses separate denoiser for edit (instruct-pix2pix) models

No impact to txt2img or regular img2img

"Image CFG Scale" will only apply to instruct-pix2pix models and metadata will only be added if using such model
2023-02-03 18:19:56 -05:00
Vladimir Repin 982295aee5 Fix img2imgalt after samplers separation 2023-02-04 01:50:38 +03:00
Kyle 3b2ad20ac1 Processing only, no CFGDenoiser change
Allows instruct-pix2pix
2023-02-02 19:19:45 -05:00
Kyle cf0cfefe91 Revert "instruct-pix2pix support"
This reverts commit 269833067d.
2023-02-02 19:15:38 -05:00
rucadi 5ca4230524 Merge branch 'master' of https://github.com/Rucadi/stable-diffusion-webui-polling 2023-02-02 20:12:08 +01:00
rucadi eb5eb8aa11 Add a callback called before reloading the server 2023-02-02 20:10:47 +01:00
rucadi 3662a274e2 Add polling callback 2023-02-02 20:10:47 +01:00
Kyle 269833067d instruct-pix2pix support 2023-02-02 09:37:01 -05:00
Cody Brownstein fb97acef63 Update error message WRT missing checkpoint file
The Safetensors format is also supported.
2023-02-01 14:51:06 -08:00
ctwrs 92bae77b88 Add .jpg to allowed thumb formats 2023-02-01 22:28:39 +01:00
Francesco Manzali 5afd9e82c3 Use the real images size, not the process
- Use the width/height of the first image in processed.images
- No more need for rounding in prompt_matrix
2023-02-01 21:16:52 +01:00
brkirch 1b8af15f13 Refactor Mac specific code to a separate file
Move most Mac related code to a separate file, don't even load it unless web UI is run under macOS.
2023-02-01 14:05:56 -05:00
AUTOMATIC1111 226d840e84 Merge pull request #7334 from EllangoK/master
X/Y/Z plot now saves sub grids if opts.grid_save and honors draw_legend
2023-02-01 16:30:28 +03:00
AUTOMATIC1111 07edf57409 Merge pull request #7357 from EllangoK/btn-fix
Fixes switch height/width btn unbound error
2023-02-01 16:29:58 +03:00
AUTOMATIC1111 fa4fe45403 Merge pull request #7371 from hoblin/master
[Prompt Matrix] Support for negative prompt + delimiter selector
2023-02-01 16:28:27 +03:00
AUTOMATIC1111 814600f298 Merge pull request #7412 from Pomierski/master
Fix missing tooltip for 'Clear prompt' button
2023-02-01 16:22:36 +03:00
AUTOMATIC1111 30a64504b1 Merge pull request #7414 from joecodecreations/master
Changes use_original_name_batch to default to True
2023-02-01 16:22:16 +03:00
AUTOMATIC1111 b1873dbb77 Merge pull request #7455 from brkirch/put-fix-back
Refactor MPS PyTorch fixes, add fix still required for PyTorch nightly builds back
2023-02-01 16:11:40 +03:00
brkirch 2217331cd1 Refactor MPS fixes to CondFunc 2023-02-01 06:36:22 -05:00
brkirch 7738c057ce MPS fix is still needed :(
Apparently I did not test with large enough images to trigger the bug with torch.narrow on MPS
2023-02-01 05:23:58 -05:00
Francesco Manzali 17b24e45e8 Fix prompt matrix #rows/#cols when using hires
- images.draw_prompt_matrix() should be called with the final width/height
  of the generated images, after upscaling.
  Otherwise, the number of rows/cols computed in images.draw_grid_annotations
  will increase by the upscaling factor.
- Round the number of cols/rows in images.draw_grid_annotations, since
  the final images width may be a bit less than the required
  hr_upscale_to_x/y
2023-01-31 18:58:36 +01:00
unknown ade40aa1a0 Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui into gamepad 2023-01-31 02:33:10 -06:00
Joey Sanchez 0426b34789 Adding default true to use_original_name_batch as images should by default hold the same name to help keep sequenced images in their correct order 2023-01-30 21:46:52 -05:00
Piotr Pomierski bfe7e7f15f Fix missing tooltip for 'Clear prompt' button 2023-01-31 01:51:07 +01:00
AUTOMATIC 2c1bb46c7a amend the error in previous commit 2023-01-30 18:48:10 +03:00
AUTOMATIC 19de2a626b make linux launch.py use XFORMERS_PACKAGE var too; thanks, acncagua 2023-01-30 15:48:09 +03:00
InvincibleDude 3ec2eb8bf1 Merge branch 'master' into improved-hr-conflict-test 2023-01-30 15:35:13 +03:00
AUTOMATIC ee9fdf7f62 Add --skip-version-check to disable messages asking users to upgrade torch. 2023-01-30 14:56:28 +03:00
unknown 21766a0898 Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui into gamepad 2023-01-30 05:12:31 -06:00
AUTOMATIC aa4688eb83 disable EMA weights for instructpix2pix model, whcih should get memory usage as well as image quality to what it was before d2ac95fa7b 2023-01-30 13:29:44 +03:00
AUTOMATIC ab059b6e48 make the program read Discard penultimate sigma from generation parameters 2023-01-30 10:52:15 +03:00
AUTOMATIC 040ec7a80e make the program read Eta and Eta DDIM from generation parameters 2023-01-30 10:47:09 +03:00
AUTOMATIC 4df63d2d19 split samplers into one more files for k-diffusion 2023-01-30 10:11:30 +03:00
Andrey 274474105a Split history sd_samplers.py to sd_samplers_kdiffusion.py 2023-01-30 09:51:23 +03:00
Andrey 95916e3777 Split history sd_samplers.py to sd_samplers_kdiffusion.py 2023-01-30 09:51:23 +03:00
Andrey 2db8ed32cd Split history sd_samplers.py to sd_samplers_kdiffusion.py 2023-01-30 09:51:23 +03:00
Andrey f4d0538bf2 Split history sd_samplers.py to sd_samplers_kdiffusion.py 2023-01-30 09:51:23 +03:00
AUTOMATIC aa54a9d416 split compvis sampler and shared sampler stuff into their own files 2023-01-30 09:51:06 +03:00
Andrey f8fcad502e Split history sd_samplers.py to sd_samplers_common.py 2023-01-30 09:37:51 +03:00
Andrey 58ae93b954 Split history sd_samplers.py to sd_samplers_common.py 2023-01-30 09:37:50 +03:00
Andrey 6e78f6a896 Split history sd_samplers.py to sd_samplers_common.py 2023-01-30 09:37:50 +03:00
Andrey 5feae71dd2 Split history sd_samplers.py to sd_samplers_common.py 2023-01-30 09:37:50 +03:00
Andrey 449531a6c5 Split history sd_samplers.py to sd_samplers_compvis.py 2023-01-30 09:35:53 +03:00
Andrey 9b8ed7f8ec Split history sd_samplers.py to sd_samplers_compvis.py 2023-01-30 09:35:53 +03:00
Andrey 9118b08606 Split history sd_samplers.py to sd_samplers_compvis.py 2023-01-30 09:35:52 +03:00
Andrey 0c7c36a6c6 Split history sd_samplers.py to sd_samplers_compvis.py 2023-01-30 09:35:52 +03:00
AUTOMATIC cbd6329488 add an environment variable for selecting xformers package 2023-01-30 09:12:43 +03:00
AUTOMATIC c81b52ffbd add override settings component to img2img 2023-01-30 02:40:26 +03:00
AUTOMATIC 847ceae1f7 make it possible to search checkpoint by its hash 2023-01-30 01:41:23 +03:00
AUTOMATIC 399720dac2 update prompt token counts after using the paste params button 2023-01-30 01:03:31 +03:00
AUTOMATIC f91068f426 change disable_weights_auto_swap to true by default 2023-01-30 00:37:26 +03:00
AUTOMATIC 938578e8a9 make it so that setting options in pasted infotext (like Clip Skip and ENSD) do not get applied directly and instead are added as temporary overrides 2023-01-30 00:25:30 +03:00
InvincibleDude 0d834b9394 Merge pull request #2 from InvincibleDude/extra-networks-test
Extra networks test
2023-01-29 20:40:06 +03:00
invincibledude 425eab3464 Extra network in hr abomination fix 2023-01-29 19:26:31 +03:00
invincibledude 9beeef6267 Extra networks loading fix 2023-01-29 19:16:17 +03:00
invincibledude 6127d2ff1b Extra networks loading fix 2023-01-29 19:13:27 +03:00
invincibledude c92ec3a925 Extra networks loading fix 2023-01-29 19:07:00 +03:00
Yevhenii Hurin 1e2b10d2dc Cleanup changes made by formatter 2023-01-29 17:14:46 +02:00
Yevhenii Hurin 5997457fd4 Compact options UI for Prompt Matrix 2023-01-29 16:23:29 +02:00
Yevhenii Hurin edabd92729 Add delimiter selector to the Prompt Matrix script 2023-01-29 16:05:59 +02:00
Yevhenii Hurin c46f3ad98b Merge branch 'master' of https://github.com/AUTOMATIC1111/stable-diffusion-webui 2023-01-29 15:47:14 +02:00
Yevhenii Hurin 7c53f81caf Prompt selector for Prompt Matrix script 2023-01-29 15:29:03 +02:00
InvincibleDude ee3d63b6be Merge branch 'master' into master 2023-01-29 14:36:10 +03:00
AUTOMATIC 00dab8f10d remove Batch size and Batch pos from textinfo (goodbye) 2023-01-29 11:53:24 +03:00
AUTOMATIC aa6e55e001 do not display the message for TI unless the list of loaded embeddings changed 2023-01-29 11:53:05 +03:00
EllangoK 920fe8057c fixes #7284 btn unbound error 2023-01-29 03:36:16 -05:00
AUTOMATIC 8d7382ab24 add buttons for auto-search in subdirectories for extra tabs 2023-01-29 11:34:58 +03:00
AUTOMATIC 7cb31a278e initial work on SD2 Lora support 2023-01-29 10:45:46 +03:00
AUTOMATIC1111 e8efd2ec47 Merge pull request #7353 from EllangoK/preview-fix
Fixes thumbnail cards not loading the preview image
2023-01-29 10:41:36 +03:00
EllangoK 659d602dce only returns ckpt directories if they are not none 2023-01-29 02:32:53 -05:00
AUTOMATIC f6b7768f84 support for searching subdirectory names for extra networks 2023-01-29 10:20:19 +03:00
AUTOMATIC1111 1d24665229 Merge pull request #7344 from glop102/master
Reduce grid rows if larger than number of images available
2023-01-29 09:29:23 +03:00
glop102 09a142a05a Reduce grid rows if larger than number of images available
When a set number of grid rows is specified in settings, then it leads
to situations where an entire row in the grid is empty.
The most noticable example is the processing preview when the row count
is set to 2, where it shows the preview just fine but with a black
rectangle under it.
2023-01-28 19:25:52 -05:00
EllangoK fb58fa6240 xyz plot now saves sub grids if opts.grid_save
also fixed no draw legend for z grid
2023-01-28 15:37:01 -05:00
AUTOMATIC 0a8515085e make it so that clicking on hypernet/lora card one more time removes the related from the prompt 2023-01-28 23:31:48 +03:00
AUTOMATIC 1d8e06d542 add checkpoints tab for extra networks UI 2023-01-28 22:52:27 +03:00
AUTOMATIC 2abd89acc6 index on master: 91c8d0d Merge pull request #7231 from EllangoK/master 2023-01-28 20:04:35 +03:00
AUTOMATIC1111 91c8d0dcfc Merge pull request #7231 from EllangoK/master
Fixes X/Y/Z Plot parameters not being restored from images
2023-01-28 18:45:38 +03:00
AUTOMATIC1111 fecb990deb Merge pull request #7309 from brkirch/fix-embeddings
Fix embeddings, upscalers, and refactor `--upcast-sampling`
2023-01-28 18:44:36 +03:00
AUTOMATIC1111 41e76d1209 Merge pull request #7258 from ItsOlegDm/master
Css fixes
2023-01-28 18:41:58 +03:00
ItsOlegDm 29d2d6a094 Train tab fix 2023-01-28 17:21:59 +02:00
AUTOMATIC e2c71a4bd4 make prevent the browser from using cached version of scripts when they change 2023-01-28 18:13:03 +03:00
ItsOlegDm 1e22f48f4d img2img styled padding fix 2023-01-28 17:08:38 +02:00
ItsOlegDm f4eeff659e Removed buttons centering 2023-01-28 17:05:08 +02:00
EllangoK 591b68e56c uses autos new regex, checks len of re_param 2023-01-28 10:04:09 -05:00
AUTOMATIC1111 cd7e8fb42b Merge pull request #7319 from Thurion/img2img_batch_fix
Fix error when using img2img batch without masks
2023-01-28 17:31:39 +03:00
AUTOMATIC b7d2af8c7f add dropdowns in settings for hypernets and loras 2023-01-28 17:18:47 +03:00
Thurion 1421e95960 allow empty mask dir 2023-01-28 14:42:24 +01:00
AUTOMATIC 5d14f282c2 fixed a bug where after switching to a checkpoint with unknown hash, you'd get empty space instead of checkpoint name in UI
fixed a bug where if you update a selected checkpoint on disk and then restart the program, a different checkpoint loads, but the name is shown for the the old one.
2023-01-28 16:23:49 +03:00
AUTOMATIC f8feeaaedb add progressbar to extension update check; do not check for updates for disabled extensions 2023-01-28 15:57:56 +03:00
AUTOMATIC d04e3e921e automatically detect v-parameterization for SD2 checkpoints 2023-01-28 15:24:41 +03:00
AUTOMATIC 4aa7f5b5b9 update image parameters regex for #7231 2023-01-28 15:24:40 +03:00
unknown e79b7db4b4 Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui into gamepad 2023-01-28 03:40:51 -06:00
unknown b921a52071 basic image next and prev control with joystick 2023-01-28 03:19:10 -06:00
brkirch f9edd578e9 Remove MPS fix no longer needed for PyTorch
The torch.narrow fix was required for nightly PyTorch builds for a while to prevent a hard crash, but newer nightly builds don't have this issue.
2023-01-28 04:16:27 -05:00
brkirch 02b8b957d7 Add --no-half-vae to default macOS arguments
Apparently the version of PyTorch macOS users are currently at doesn't always handle half precision VAEs correctly. We will probably want to update the default PyTorch version to 2.0 when it comes out which should fix that, and at this point nightly builds of PyTorch 2.0 are going to be recommended for most Mac users. Unfortunately someone has already reported that their M2 Mac doesn't work with the nightly PyTorch 2.0 build currently, so we can add --no-half-vae for now and give users that can install nightly PyTorch 2.0 builds a webui-user.sh configuration that overrides the default.
2023-01-28 04:16:27 -05:00
brkirch ada17dbd7c Refactor conditional casting, fix upscalers 2023-01-28 04:16:25 -05:00
AUTOMATIC1111 e8a41df49f Merge pull request #7217 from mezotaken/master
Ask user to clarify conditions
2023-01-28 10:52:53 +03:00
AUTOMATIC1111 bea31e849a Merge pull request #7240 from Unstackd/master
Allow users to convert models to Instruct-pix2pix models by supporting merging Instruct-pix2pix models with regular ones in the merge tab
2023-01-28 10:52:28 +03:00
AUTOMATIC1111 60061eb8d4 Merge pull request #7303 from szhublox/pathshelp
don't replace regular --help with new paths.py parser help
2023-01-28 10:48:33 +03:00
AUTOMATIC bd52a6d899 some more changes for python version warning; add a commandline flag to disable 2023-01-28 10:48:08 +03:00
Mackerel 3752aad23d don't replace regular --help with new paths.py parser help 2023-01-28 02:44:12 -05:00
AUTOMATIC 7d1f2a3a49 remove waiting for input on version mismatch warning, change supported versions 2023-01-28 10:21:31 +03:00
AUTOMATIC1111 28c4c9b907 Merge pull request #7200 from Spaceginner/master
Add a Python version check
2023-01-28 10:13:56 +03:00
Ju1-js dc25a31d1a Gradio Auth Read from External File
Usage: `--gradio-auth-path {PATH}`
It adds the credentials to the already existing `--gradio-auth` credentials. It can also handle line breaks.
The file should look like:
`{u1}:{p1},{u2}:{p2}`
or
```
{u1}:{p1},
{u2}:{p2}
```
Will gradio handle duplicate credentials if it happens?
2023-01-27 22:43:10 -08:00
AUTOMATIC1111 ce72af87d3 Merge pull request #7199 from maxaudron/feature/configurable-data-dir
Add flag to store user data sepperate from source code
2023-01-28 09:24:40 +03:00
AUTOMATIC 0834d4ce37 simplify #7284 2023-01-28 08:41:15 +03:00
AUTOMATIC1111 c99d705e57 Merge pull request #7284 from Gazzoo-byte/patch-1
Add button to switch width and height
2023-01-28 08:33:43 +03:00
AUTOMATIC1111 38d83665d9 Merge pull request #7285 from EllangoK/xyz-fixes
Allows for multiple Styles axii in X/Y/Z Plot
2023-01-28 08:31:23 +03:00
AUTOMATIC 4c52dfe4ac make the detection for -v models less broad 2023-01-28 08:30:17 +03:00
AUTOMATIC1111 41975c375c Merge pull request #7294 from MrCheeze/model-detection
add v2-inpainting model detection, and broaden v-model detection to include anything with 768 in the name
2023-01-28 08:29:01 +03:00
AUTOMATIC1111 8ce0ccf336 Merge pull request #7295 from askaliuk/askaliuk-inpaint-batch-support
Basic inpainting batch support
2023-01-28 08:27:37 +03:00
Andrii Skaliuk 2aac1d9778 Basic inpainting batch support
Modifies batch UI to add optional inpainting support
2023-01-27 17:32:31 -08:00
MrCheeze 6b82efd737 add v2-inpainting model detection, and broaden v-model detection to include anything with 768 in the name 2023-01-27 20:06:19 -05:00
AUTOMATIC cc8c9b7474 fix broken calls to find_checkpoint_config 2023-01-27 22:43:08 +03:00
EllangoK 32d389ef0f changes remaining text from X/Y -> X/Y/Z 2023-01-27 14:04:23 -05:00
EllangoK a6a5bfb155 deepcopy pc.styles, allows for multiple style axis 2023-01-27 13:48:39 -05:00
Gazzoo-byte eafaf14167 Add button to switch width and height
Adds a button to switch width and height, allowing quick and easy switching between landscape and portrait.
2023-01-27 18:34:41 +00:00
Max Audron 23a9d5e273 create user extensions directory if not exists 2023-01-27 14:44:34 +01:00
Max Audron 6b3981c068 clean up unused script_path imports 2023-01-27 14:44:34 +01:00
Max Audron 14c0884fd0 use python importlib to load and execute extension modules
previously module attributes like __file__ where not set correctly,
leading to scripts getting the directory of the stable-diffusion repo
location instead of their own script.

This causes problem when loading user data from an external location
using the --data-dir flag, as extensions would look for their own code
in the stable-diffusion repo location instead of the data dir location.

Using pythons importlib functions sets the modules specs correctly and
executes them. But this will break extensions if they build paths based
on the previously incorrect __file__ attribute.
2023-01-27 14:44:34 +01:00
Max Audron 5eee2ac398 add data-dir flag and set all user data directories based on it 2023-01-27 14:44:30 +01:00
Spaceginner 56c83e453a Merge remote-tracking branch 'origin/master' 2023-01-27 17:35:54 +05:00
Spaceginner 9ecf1e827c Made it only a warning 2023-01-27 17:35:24 +05:00
Ivan 63391419c1 Merge branch 'AUTOMATIC1111:master' into master 2023-01-27 17:21:48 +05:00
AUTOMATIC 9beb794e0b clarify the option to disable NaN check. 2023-01-27 13:08:00 +03:00
AUTOMATIC 6f31d2210c support detecting midas model
fix broken api for checkpoint list
2023-01-27 11:54:19 +03:00
AUTOMATIC d2ac95fa7b remove the need to place configs near models 2023-01-27 11:28:12 +03:00
ItsOlegDm a43fafb481 css fixes 2023-01-26 23:25:48 +02:00
AUTOMATIC 7a14c8ab45 add an option to enable sections from extras tab in txt2img/img2img
fix some style inconsistenices
2023-01-26 23:31:32 +03:00
ULTRANOX\Chris cdc2fa209a Changed filename addition from "instrpix2pix" to the more readable ".instruct-pix2pix" for newly generated instruct pix2pix models. 2023-01-26 11:27:07 -05:00
brkirch c4b9b07db6 Fix embeddings dtype mismatch 2023-01-26 09:00:15 -05:00
AUTOMATIC1111 645f4e7ef8 Merge pull request #7234 from brkirch/fix-full-previews
Fix full previews and--no-half-vae to work correctly with --upcast-sampling
2023-01-26 14:48:43 +03:00
ULTRANOX\Chris 9e72dc7434 Changed all references to "pix2pix" to the more precise name "instruct pix2pix". Also changed extension to instrpix2pix at least for now. 2023-01-26 06:05:40 -05:00
ULTRANOX\Chris f90798c6b6 Added error check for the rare case a user merges a pix2pix model with a normal model using weighted sum. Also removed bad print message that interfered with merging progress bar. 2023-01-26 04:38:04 -05:00
ULTRANOX\Chris f4ec411f2c Allow checkpoint merger to merge pix2pix models in the same way that it currently supports inpainting models. 2023-01-26 03:45:16 -05:00
Spaceginner 1619233a74 Only Linux will have max 3.11 2023-01-26 12:52:44 +05:00
brkirch 10421f93c3 Fix full previews, --no-half-vae 2023-01-26 01:43:35 -05:00
EllangoK 4d634dc592 adds components to infotext_fields
allows for loading script params
2023-01-26 00:18:41 -05:00
EllangoK e57b5f7c55 re_param captures quotes with commas properly
and removes unnecessary regex
2023-01-25 22:36:14 -05:00
Vladimir Repin d82d471bf7 Ask user to clarify conditions 2023-01-26 02:52:33 +03:00
AUTOMATIC 6cff440182 fix prompt editing break after first batch in img2img 2023-01-25 23:25:40 +03:00
AUTOMATIC d1d6ce2983 add edit_image_conditioning from my earlier edits in case there's an attempt to inegrate pix2pix properly
this allows to use pix2pix model in img2img though it won't work well this way
2023-01-25 23:25:25 +03:00
AUTOMATIC1111 3cead6983e Merge pull request #7197 from mcmonkey4eva/fix-ti-symlinks
allow symlinks in the textual inversion embeddings folder
2023-01-25 22:59:12 +03:00
AUTOMATIC1111 a85e22a127 Merge pull request #7201 from brkirch/update-macos-defaults
Update default Mac command line arguments to use --upcast-sampling instead of --no-half
2023-01-25 22:57:17 +03:00
brkirch e0df864b8c Update arguments to use --upcast-sampling 2023-01-25 13:19:06 -05:00
Spaceginner f5d73b6a66 Fixed typo 2023-01-25 22:56:09 +05:00
Spaceginner 0cc5f380d5 even more clarifications(?)
i have no idea what commit message should be
2023-01-25 22:41:51 +05:00
Spaceginner 2de99d62dd some clarification 2023-01-25 22:38:28 +05:00
Ivan dc0f05c57c Merge branch 'AUTOMATIC1111:master' into master 2023-01-25 22:34:19 +05:00
Spaceginner 57096823fa Remove a stacktrace from an assertion to not scare people 2023-01-25 22:33:35 +05:00
AUTOMATIC 15e89ef0f6 fix for unet hijack breaking the train tab 2023-01-25 20:11:01 +03:00
Ivan 2d92d05ca2 Merge branch 'AUTOMATIC1111:master' into master 2023-01-25 22:10:34 +05:00
Spaceginner e425b9812b Added Python version check 2023-01-25 22:07:48 +05:00
AUTOMATIC 789d47f832 make clicking extra networks button one more time close the extra networks UI 2023-01-25 19:55:31 +03:00
Alex "mcmonkey" Goodwin e179b6098a allow symlinks in the textual inversion embeddings folder 2023-01-25 08:48:40 -08:00
AUTOMATIC 635499e832 add pix2pix credits 2023-01-25 19:42:26 +03:00
AUTOMATIC1111 1574e96729 Merge pull request #6510 from brkirch/unet16-upcast-precision
Add upcast options, full precision sampling from float16 UNet and upcasting attention for inference using SD 2.1 models without --no-half
2023-01-25 19:12:29 +03:00
AUTOMATIC1111 1982ef6890 Merge pull request #7138 from mykeehu/patch-4
Fix extra network thumbs label color
2023-01-25 18:59:11 +03:00
AUTOMATIC 57c1baa774 change to code for live preview fix on OSX to be bit more obvious 2023-01-25 18:56:23 +03:00
AUTOMATIC1111 23dafe6d86 Merge pull request #7151 from brkirch/fix-approx-nn
Fix Approx NN previews changing first generation result
2023-01-25 18:48:25 +03:00
AUTOMATIC1111 11485659dc Merge pull request #7195 from Klace/instruct-pix2pix_model_load
Add instruct-pix2pix hijack
2023-01-25 18:33:15 +03:00
Kyle bd9b55ee90 Update requirements transformers==4.25.1
Update requirement for transformers to version 4.25.1 to allow instruct-pix2pix demo code to work
2023-01-25 09:41:41 -05:00
Kyle ee0a0da324 Add instruct-pix2pix hijack
Allows loading instruct-pix2pix models via same method as inpainting models in sd_models.py and sd_hijack_ip2p.py

Adds ddpm_edit.py necessary for instruct-pix2pix
2023-01-25 08:53:23 -05:00
AUTOMATIC1111 d5ce044bcd Merge pull request #7146 from EllangoK/master
Adds X/Y/Z Grid Script
2023-01-25 11:56:26 +03:00
AUTOMATIC 1bfec873fa add an experimental option to apply loras to outputs rather than inputs 2023-01-25 11:29:46 +03:00
brkirch e3b53fd295 Add UI setting for upcasting attention to float32
Adds "Upcast cross attention layer to float32" option in Stable Diffusion settings. This allows for generating images using SD 2.1 models without --no-half or xFormers.

In order to make upcasting cross attention layer optimizations possible it is necessary to indent several sections of code in sd_hijack_optimizations.py so that a context manager can be used to disable autocast. Also, even though Stable Diffusion (and Diffusers) only upcast q and k, unfortunately my findings were that most of the cross attention layer optimizations could not function unless v is upcast also.
2023-01-25 01:13:04 -05:00
brkirch 84d9ce30cb Add option for float32 sampling with float16 UNet
This also handles type casting so that ROCm and MPS torch devices work correctly without --no-half. One cast is required for deepbooru in deepbooru_model.py, some explicit casting is required for img2img and inpainting. depth_model can't be converted to float16 or it won't work correctly on some systems (it's known to have issues on MPS) so in sd_models.py model.depth_model is removed for model.half().
2023-01-25 01:13:02 -05:00
AUTOMATIC 48a15821de remove the pip install stuff because it does not work as i hoped it would 2023-01-25 00:49:16 +03:00
AUTOMATIC bef1931895 add fastapi to requirements 2023-01-24 23:50:04 +03:00
InvincibleDude 44c0e6b993 Merge branch 'AUTOMATIC1111:master' into master 2023-01-24 15:44:09 +03:00
EllangoK ec8774729e swaps xyz axes internally if one costs more 2023-01-24 02:53:35 -05:00
EllangoK e46bfa5a9e handling sub grids and merging into one 2023-01-24 02:24:32 -05:00
EllangoK 9fc354e130 implements most of xyz grid script 2023-01-24 02:22:40 -05:00
EllangoK d30ac02f28 renamed xy to xyz grid
this is mostly just so git can detect it properly
2023-01-24 02:21:32 -05:00
brkirch f64af77adc Fix different first gen with Approx NN previews
The loading of the model for approx nn live previews can change the internal state of PyTorch, resulting in a different image. This can be avoided by preloading the approx nn model in advance.
2023-01-23 22:49:20 -05:00
Mykeehu 82a28bfe35 Fix extra network thumbs label color
Added white color for labels.
2023-01-23 22:36:27 +01:00
invincibledude 3bc8ee998d Gen params paste improvement 2023-01-22 16:35:42 +03:00
invincibledude 7f62300f7d Gen params paste improvement 2023-01-22 16:29:08 +03:00
invincibledude fccc39834a Gen params paste improvement 2023-01-22 16:17:55 +03:00
invincibledude d261bec1ec Gen params paste improvement 2023-01-22 16:14:28 +03:00
invincibledude 1fa777c1d7 Gen params paste improvement 2023-01-22 16:03:42 +03:00
invincibledude 2aaee73633 Gen params paste improvement 2023-01-22 16:00:35 +03:00
invincibledude a5c2b5ed89 UI and PNG info improvements 2023-01-22 15:50:20 +03:00
invincibledude bbb1e35ea2 UI and PNG info improvements 2023-01-22 15:44:59 +03:00
invincibledude b0ae92d605 UI improvements 2023-01-22 15:43:12 +03:00
invincibledude 34f6d66742 hr conditioning 2023-01-22 15:32:47 +03:00
invincibledude 125d5c8d96 hr conditioning 2023-01-22 15:31:11 +03:00
invincibledude 2ab2bce74d hr conditioning 2023-01-22 15:28:38 +03:00
invincibledude c5d4c87c02 hr conditioning 2023-01-22 15:17:43 +03:00
invincibledude 4e0cf7d4ed hr conditioning 2023-01-22 15:15:08 +03:00
invincibledude a9f0e7d536 hr conditioning 2023-01-22 15:12:00 +03:00
invincibledude f774a8d24e Hr-fix separate prompt experimentation 2023-01-22 14:52:01 +03:00
invincibledude 81e0723d65 Logging for debugging 2023-01-22 14:41:41 +03:00
invincibledude b331ca784a Fix 2023-01-22 14:35:34 +03:00
invincibledude 8114959e7e Hr separate prompt test 2023-01-22 14:28:53 +03:00
InvincibleDude cd14e7e8fd Revert 2023-01-22 00:33:21 +03:00
InvincibleDude 35b4104daf Change to run workflow 2023-01-22 00:32:48 +03:00
invincibledude f7b38c4841 Style fix 2023-01-22 00:18:26 +03:00
invincibledude 0f6862ef30 PLMS edge-case handling fix 5 2023-01-22 00:11:05 +03:00
invincibledude 6cd7bf9f86 PLMS edge-case handling fix 3 2023-01-22 00:08:58 +03:00
invincibledude 3ffe2e768b PLMS edge-case handling fix 2 2023-01-22 00:07:46 +03:00
invincibledude 9e1f49c4e5 PLMS edge-case handling fix 2023-01-22 00:03:16 +03:00
invincibledude 8bec3a2aa1 Index fix 2023-01-21 23:31:36 +03:00
invincibledude 6c0566f937 Type mismatch fix 2023-01-21 23:25:36 +03:00
invincibledude 3bd898b6ce First test of different sampler for hi-res fix 2023-01-21 23:14:59 +03:00
unknown 876da12599 Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui 2022-12-25 02:03:55 -06:00
rucadi 0c8825b2be Add a callback called before reloading the server 2022-12-16 18:31:20 +01:00
rucadi 1742c04bab Add polling callback 2022-12-16 17:10:13 +01:00
unknown d6fdfde9d7 Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui 2022-12-12 09:12:26 -06:00
unknown 4005cd66e0 Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui 2022-12-10 04:57:12 -06:00
unknown 4a3d05b657 Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui 2022-12-10 02:30:31 -06:00
246 changed files with 25308 additions and 8726 deletions
+4
View File
@@ -0,0 +1,4 @@
extensions
extensions-disabled
repositories
venv
+98
View File
@@ -0,0 +1,98 @@
/* global module */
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: "eslint:recommended",
parserOptions: {
ecmaVersion: "latest",
},
rules: {
"arrow-spacing": "error",
"block-spacing": "error",
"brace-style": "error",
"comma-dangle": ["error", "only-multiline"],
"comma-spacing": "error",
"comma-style": ["error", "last"],
"curly": ["error", "multi-line", "consistent"],
"eol-last": "error",
"func-call-spacing": "error",
"function-call-argument-newline": ["error", "consistent"],
"function-paren-newline": ["error", "consistent"],
"indent": ["error", 4],
"key-spacing": "error",
"keyword-spacing": "error",
"linebreak-style": ["error", "unix"],
"no-extra-semi": "error",
"no-mixed-spaces-and-tabs": "error",
"no-multi-spaces": "error",
"no-redeclare": ["error", {builtinGlobals: false}],
"no-trailing-spaces": "error",
"no-unused-vars": "off",
"no-whitespace-before-property": "error",
"object-curly-newline": ["error", {consistent: true, multiline: true}],
"object-curly-spacing": ["error", "never"],
"operator-linebreak": ["error", "after"],
"quote-props": ["error", "consistent-as-needed"],
"semi": ["error", "always"],
"semi-spacing": "error",
"semi-style": ["error", "last"],
"space-before-blocks": "error",
"space-before-function-paren": ["error", "never"],
"space-in-parens": ["error", "never"],
"space-infix-ops": "error",
"space-unary-ops": "error",
"switch-colon-spacing": "error",
"template-curly-spacing": ["error", "never"],
"unicode-bom": "error",
},
globals: {
//script.js
gradioApp: "readonly",
executeCallbacks: "readonly",
onAfterUiUpdate: "readonly",
onOptionsChanged: "readonly",
onUiLoaded: "readonly",
onUiUpdate: "readonly",
uiCurrentTab: "writable",
uiElementInSight: "readonly",
uiElementIsVisible: "readonly",
//ui.js
opts: "writable",
all_gallery_buttons: "readonly",
selected_gallery_button: "readonly",
selected_gallery_index: "readonly",
switch_to_txt2img: "readonly",
switch_to_img2img_tab: "readonly",
switch_to_img2img: "readonly",
switch_to_sketch: "readonly",
switch_to_inpaint: "readonly",
switch_to_inpaint_sketch: "readonly",
switch_to_extras: "readonly",
get_tab_index: "readonly",
create_submit_args: "readonly",
restart_reload: "readonly",
updateInput: "readonly",
onEdit: "readonly",
//extraNetworks.js
requestGet: "readonly",
popup: "readonly",
// from python
localization: "readonly",
// progrssbar.js
randomId: "readonly",
requestProgress: "readonly",
// imageviewer.js
modalPrevImage: "readonly",
modalNextImage: "readonly",
// token-counters.js
setupTokenCounters: "readonly",
// localStorage.js
localSet: "readonly",
localGet: "readonly",
localRemove: "readonly",
// resizeHandle.js
setupResizeHandle: "writable"
}
};
+2
View File
@@ -0,0 +1,2 @@
# Apply ESlint
9c54b78d9dde5601e916f308d9a9d6953ec39430
+14 -23
View File
@@ -26,7 +26,7 @@ body:
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: | value: |
1. Go to .... 1. Go to ....
2. Press .... 2. Press ....
@@ -37,28 +37,16 @@ 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: validations:
required: true required: true
- type: input - type: textarea
id: commit id: sysinfo
attributes: attributes:
label: Commit where the problem happens label: Sysinfo
description: Which 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 **Commit hash** shown in the cmd/terminal when you launch the UI) 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.
validations: validations:
required: true required: true
- type: dropdown
id: platforms
attributes:
label: What platforms do you use to access UI ?
multiple: true
options:
- Windows
- Linux
- MacOS
- iOS
- Android
- Other/Cloud
- type: dropdown - type: dropdown
id: browsers id: browsers
attributes: attributes:
@@ -70,14 +58,17 @@ body:
- Brave - Brave
- Apple Safari - Apple Safari
- Microsoft Edge - Microsoft Edge
- Other
- type: textarea - type: textarea
id: cmdargs id: logs
attributes: attributes:
label: Command Line Arguments label: Console logs
description: Are you using any launching parameters/command line arguments (modified webui-user.py) ? If yes, please write them below 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.
render: Shell render: Shell
validations:
required: true
- type: textarea - type: textarea
id: misc id: misc
attributes: attributes:
label: Additional information, context and logs label: Additional information
description: Please provide us with any relevant additional info, context or log output. description: Please provide us with any relevant additional info or context.
+10 -23
View File
@@ -1,28 +1,15 @@
# Please read the [contributing wiki page](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Contributing) before submitting a pull request! ## Description
If you have a large change, pay special attention to this paragraph: * a simple description of what you're trying to accomplish
* a summary of changes in code
* which issues it fixes, if any
> Before making changes, if you think that your feature will result in more than 100 lines changing, find me and talk to me about the feature you are proposing. It pains me to reject the hard work someone else did, but I won't add everything to the repo, and it's better if the rejection happens before you have to waste time working on the feature. ## Screenshots/videos:
Otherwise, after making sure you're following the rules described in wiki page, remove this section and continue on.
**Describe what this pull request is trying to achieve.** ## Checklist:
A clear and concise description of what you're trying to accomplish with this, so your intent doesn't have to be extracted from your code. - [ ] I have read [contributing wiki page](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Contributing)
- [ ] I have performed a self-review of my own code
**Additional notes and description of your changes** - [ ] My code follows the [style guidelines](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Contributing#code-style)
- [ ] My code passes [tests](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Tests)
More technical discussion about your changes go here, plus anything that a maintainer might have to specifically take a look at, or be wary of.
**Environment this was tested in**
List the environment you have developed / tested this on. As per the contributing page, changes should be able to work on Windows out of the box.
- OS: [e.g. Windows, Linux]
- Browser: [e.g. chrome, safari]
- Graphics card: [e.g. NVIDIA RTX 2080 8GB, AMD RX 6600 8GB]
**Screenshots or videos of your changes**
If applicable, screenshots or a video showing off your changes. If it edits an existing UI, it should ideally contain a comparison of what used to be there, before your changes were made.
This is **required** for anything that touches the user interface.
+27 -28
View File
@@ -1,39 +1,38 @@
# See https://github.com/actions/starter-workflows/blob/1067f16ad8a1eac328834e4b0ae24f7d206f810d/ci/pylint.yml for original reference file name: Linter
name: Run Linting/Formatting on Pull Requests
on: on:
- push - push
- pull_request - pull_request
# See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpull_requestpull_request_targetbranchesbranches-ignore for syntax docs
# if you want to filter out branches, delete the `- pull_request` and uncomment these lines :
# pull_request:
# branches:
# - master
# branches-ignore:
# - development
jobs: jobs:
lint: 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@v3
- name: Set up Python 3.10 - uses: actions/setup-python@v4
uses: actions/setup-python@v4
with: with:
python-version: 3.10.6 python-version: 3.11
cache: pip # NB: there's no cache: pip here since we're not installing anything
cache-dependency-path: | # from the requirements.txt file(s) in the repository; it's faster
**/requirements*txt # not to have GHA download an (at the time of writing) 4 GB cache
- name: Install PyLint # of PyTorch and other dependencies.
run: | - name: Install Ruff
python -m pip install --upgrade pip run: pip install ruff==0.0.272
pip install pylint - name: Run Ruff
# This lets PyLint check to see if it can resolve imports run: ruff .
- name: Install dependencies lint-js:
run: | name: eslint
export COMMANDLINE_ARGS="--skip-torch-cuda-test --exit" runs-on: ubuntu-latest
python launch.py if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
- name: Analysing the code with pylint steps:
run: | - name: Checkout Code
pylint $(git ls-files '*.py') uses: actions/checkout@v3
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- run: npm i --ci
- run: npm run lint
+51 -7
View File
@@ -1,4 +1,4 @@
name: Run basic features tests on CPU with empty SD model name: Tests
on: on:
- push - push
@@ -6,7 +6,9 @@ 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@v3
@@ -17,13 +19,55 @@ jobs:
cache: pip cache: pip
cache-dependency-path: | cache-dependency-path: |
**/requirements*txt **/requirements*txt
launch.py
- name: Install test dependencies
run: pip install wait-for-it -r requirements-test.txt
env:
PIP_DISABLE_PIP_VERSION_CHECK: "1"
PIP_PROGRESS_BAR: "off"
- name: Setup environment
run: python launch.py --skip-torch-cuda-test --exit
env:
PIP_DISABLE_PIP_VERSION_CHECK: "1"
PIP_PROGRESS_BAR: "off"
TORCH_INDEX_URL: https://download.pytorch.org/whl/cpu
WEBUI_LAUNCH_LIVE_OUTPUT: "1"
PYTHONUNBUFFERED: "1"
- name: Start test server
run: >
python -m coverage run
--data-file=.coverage.server
launch.py
--skip-prepare-environment
--skip-torch-cuda-test
--test-server
--do-not-download-clip
--no-half
--disable-opt-split-attention
--use-cpu all
--api-server-stop
2>&1 | tee output.txt &
- name: Run tests - name: Run tests
run: python launch.py --tests --no-half --disable-opt-split-attention --use-cpu all --skip-torch-cuda-test run: |
- name: Upload main app stdout-stderr wait-for-it --service 127.0.0.1:7860 -t 600
python -m pytest -vv --junitxml=test/results.xml --cov . --cov-report=xml --verify-base-url test
- name: Kill test server
if: always()
run: curl -vv -XPOST http://127.0.0.1:7860/sdapi/v1/server-stop && sleep 10
- name: Show coverage
run: |
python -m coverage combine .coverage*
python -m coverage report -i
python -m coverage html -i
- name: Upload main app output
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
if: always() if: always()
with: with:
name: stdout-stderr name: output
path: | path: output.txt
test/stdout.txt - name: Upload coverage HTML
test/stderr.txt uses: actions/upload-artifact@v3
if: always()
with:
name: htmlcov
path: 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 -1
View File
@@ -32,4 +32,8 @@ notification.mp3
/extensions /extensions
/test/stdout.txt /test/stdout.txt
/test/stderr.txt /test/stderr.txt
/cache.json /cache.json*
/config_states/
/node_modules
/package-lock.json
/.coverage*
+507
View File
@@ -0,0 +1,507 @@
## 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 posssible (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 extenstions
* 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
### Features:
* zoom controls for inpainting
* run basic torch calculation at startup in parallel to reduce the performance impact of first generation
* option to pad prompt/neg prompt to be same length
* remove taming_transformers dependency
* custom k-diffusion scheduler settings
* add an option to show selected settings in main txt2img/img2img UI
* sysinfo tab in settings
* infer styles from prompts when pasting params into the UI
* an option to control the behavior of the above
### Minor:
* bump Gradio to 3.32.0
* bump xformers to 0.0.20
* Add option to disable token counters
* tooltip fixes & optimizations
* make it possible to configure filename for the zip download
* `[vae_filename]` pattern for filenames
* Revert discarding penultimate sigma for DPM-Solver++(2M) SDE
* change UI reorder setting to multiselect
* read version info form CHANGELOG.md if git version info is not available
* link footer API to Wiki when API is not active
* persistent conds cache (opt-in optimization)
### Extensions:
* After installing extensions, webui properly restarts the process rather than reloads the UI
* Added VAE listing to web API. Via: /sdapi/v1/sd-vae
* custom unet support
* Add onAfterUiUpdate callback
* refactor EmbeddingDatabase.register_embedding() to allow unregistering
* add before_process callback for scripts
* add ability for alwayson scripts to specify section and let user reorder those sections
### Bug Fixes:
* Fix dragging text to prompt
* fix incorrect quoting for infotext values with colon in them
* fix "hires. fix" prompt sharing same labels with txt2img_prompt
* Fix s_min_uncond default type int
* Fix for #10643 (Inpainting mask sometimes not working)
* fix bad styling for thumbs view in extra networks #10639
* fix for empty list of optimizations #10605
* small fixes to prepare_tcmalloc for Debian/Ubuntu compatibility
* fix --ui-debug-mode exit
* patch GitPython to not use leaky persistent processes
* fix duplicate Cross attention optimization after UI reload
* torch.cuda.is_available() check for SdOptimizationXformers
* fix hires fix using wrong conds in second pass if using Loras.
* handle exception when parsing generation parameters from png info
* fix upcast attention dtype error
* forcing Torch Version to 1.13.1 for RX 5000 series GPUs
* split mask blur into X and Y components, patch Outpainting MK2 accordingly
* don't die when a LoRA is a broken symlink
* allow activation of Generate Forever during generation
## 1.3.2
### Bug Fixes:
* fix files served out of tmp directory even if they are saved to disk
* fix postprocessing overwriting parameters
## 1.3.1
### Features:
* revert default cross attention optimization to Doggettx
### Bug Fixes:
* fix bug: LoRA don't apply on dropdown list sd_lora
* fix png info always added even if setting is not enabled
* fix some fields not applying in xyz plot
* fix "hires. fix" prompt sharing same labels with txt2img_prompt
* fix lora hashes not being added properly to infotex if there is only one lora
* fix --use-cpu failing to work properly at startup
* make --disable-opt-split-attention command line option work again
## 1.3.0
### Features:
* add UI to edit defaults
* token merging (via dbolya/tomesd)
* settings tab rework: add a lot of additional explanations and links
* load extensions' Git metadata in parallel to loading the main program to save a ton of time during startup
* update extensions table: show branch, show date in separate column, and show version from tags if available
* TAESD - another option for cheap live previews
* allow choosing sampler and prompts for second pass of hires fix - hidden by default, enabled in settings
* calculate hashes for Lora
* add lora hashes to infotext
* when pasting infotext, use infotext's lora hashes to find local loras for `<lora:xxx:1>` entries whose hashes match loras the user has
* select cross attention optimization from UI
### Minor:
* bump Gradio to 3.31.0
* bump PyTorch to 2.0.1 for macOS and Linux AMD
* allow setting defaults for elements in extensions' tabs
* allow selecting file type for live previews
* show "Loading..." for extra networks when displaying for the first time
* suppress ENSD infotext for samplers that don't use it
* clientside optimizations
* add options to show/hide hidden files and dirs in extra networks, and to not list models/files in hidden directories
* allow whitespace in styles.csv
* add option to reorder tabs
* move some functionality (swap resolution and set seed to -1) to client
* option to specify editor height for img2img
* button to copy image resolution into img2img width/height sliders
* switch from pyngrok to ngrok-py
* lazy-load images in extra networks UI
* set "Navigate image viewer with gamepad" option to false by default, by request
* change upscalers to download models into user-specified directory (from commandline args) rather than the default models/<...>
* allow hiding buttons in ui-config.json
### Extensions:
* add /sdapi/v1/script-info api
* use Ruff to lint Python code
* use ESlint to lint Javascript code
* add/modify CFG callbacks for Self-Attention Guidance extension
* add command and endpoint for graceful server stopping
* add some locals (prompts/seeds/etc) from processing function into the Processing class as fields
* rework quoting for infotext items that have commas in them to use JSON (should be backwards compatible except for cases where it didn't work previously)
* add /sdapi/v1/refresh-loras api checkpoint post request
* tests overhaul
### Bug Fixes:
* fix an issue preventing the program from starting if the user specifies a bad Gradio theme
* fix broken prompts from file script
* fix symlink scanning for extra networks
* fix --data-dir ignored when launching via webui-user.bat COMMANDLINE_ARGS
* allow web UI to be ran fully offline
* fix inability to run with --freeze-settings
* fix inability to merge checkpoint without adding metadata
* fix extra networks' save preview image not adding infotext for jpeg/webm
* remove blinking effect from text in hires fix and scale resolution preview
* make links to `http://<...>.git` extensions work in the extension tab
* fix bug with webui hanging at startup due to hanging git process
## 1.2.1
### Features:
* add an option to always refer to LoRA by filenames
### Bug Fixes:
* never refer to LoRA by an alias if multiple LoRAs have same alias or the alias is called none
* fix upscalers disappearing after the user reloads UI
* allow bf16 in safe unpickler (resolves problems with loading some LoRAs)
* allow web UI to be ran fully offline
* fix localizations not working
* fix error for LoRAs: `'LatentDiffusion' object has no attribute 'lora_layer_mapping'`
## 1.2.0
### Features:
* do not wait for Stable Diffusion model to load at startup
* add filename patterns: `[denoising]`
* directory hiding for extra networks: dirs starting with `.` will hide their cards on extra network tabs unless specifically searched for
* LoRA: for the `<...>` text in prompt, use name of LoRA that is in the metdata of the file, if present, instead of filename (both can be used to activate LoRA)
* LoRA: read infotext params from kohya-ss's extension parameters if they are present and if his extension is not active
* LoRA: fix some LoRAs not working (ones that have 3x3 convolution layer)
* LoRA: add an option to use old method of applying LoRAs (producing same results as with kohya-ss)
* add version to infotext, footer and console output when starting
* add links to wiki for filename pattern settings
* add extended info for quicksettings setting and use multiselect input instead of a text field
### Minor:
* bump Gradio to 3.29.0
* bump PyTorch to 2.0.1
* `--subpath` option for gradio for use with reverse proxy
* Linux/macOS: use existing virtualenv if already active (the VIRTUAL_ENV environment variable)
* do not apply localizations if there are none (possible frontend optimization)
* add extra `None` option for VAE in XYZ plot
* print error to console when batch processing in img2img fails
* create HTML for extra network pages only on demand
* allow directories starting with `.` to still list their models for LoRA, checkpoints, etc
* put infotext options into their own category in settings tab
* do not show licenses page when user selects Show all pages in settings
### Extensions:
* tooltip localization support
* add API method to get LoRA models with prompt
### Bug Fixes:
* re-add `/docs` endpoint
* fix gamepad navigation
* make the lightbox fullscreen image function properly
* fix squished thumbnails in extras tab
* keep "search" filter for extra networks when user refreshes the tab (previously it showed everthing after you refreshed)
* fix webui showing the same image if you configure the generation to always save results into same file
* fix bug with upscalers not working properly
* fix MPS on PyTorch 2.0.1, Intel Macs
* make it so that custom context menu from contextMenu.js only disappears after user's click, ignoring non-user click events
* prevent Reload UI button/link from reloading the page when it's not yet ready
* fix prompts from file script failing to read contents from a drag/drop file
## 1.1.1
### Bug Fixes:
* fix an error that prevents running webui on PyTorch<2.0 without --disable-safe-unpickle
## 1.1.0
### Features:
* switch to PyTorch 2.0.0 (except for AMD GPUs)
* visual improvements to custom code scripts
* add filename patterns: `[clip_skip]`, `[hasprompt<>]`, `[batch_number]`, `[generation_number]`
* add support for saving init images in img2img, and record their hashes in infotext for reproducability
* automatically select current word when adjusting weight with ctrl+up/down
* add dropdowns for X/Y/Z plot
* add setting: Stable Diffusion/Random number generator source: makes it possible to make images generated from a given manual seed consistent across different GPUs
* support Gradio's theme API
* use TCMalloc on Linux by default; possible fix for memory leaks
* add optimization option to remove negative conditioning at low sigma values #9177
* embed model merge metadata in .safetensors file
* extension settings backup/restore feature #9169
* add "resize by" and "resize to" tabs to img2img
* add option "keep original size" to textual inversion images preprocess
* image viewer scrolling via analog stick
* button to restore the progress from session lost / tab reload
### Minor:
* bump Gradio to 3.28.1
* change "scale to" to sliders in Extras tab
* add labels to tool buttons to make it possible to hide them
* add tiled inference support for ScuNET
* add branch support for extension installation
* change Linux installation script to install into current directory rather than `/home/username`
* sort textual inversion embeddings by name (case-insensitive)
* allow styles.csv to be symlinked or mounted in docker
* remove the "do not add watermark to images" option
* make selected tab configurable with UI config
* make the extra networks UI fixed height and scrollable
* add `disable_tls_verify` arg for use with self-signed certs
### Extensions:
* add reload callback
* add `is_hr_pass` field for processing
### Bug Fixes:
* fix broken batch image processing on 'Extras/Batch Process' tab
* add "None" option to extra networks dropdowns
* fix FileExistsError for CLIP Interrogator
* fix /sdapi/v1/txt2img endpoint not working on Linux #9319
* fix disappearing live previews and progressbar during slow tasks
* fix fullscreen image view not working properly in some cases
* prevent alwayson_scripts args param resizing script_arg list when they are inserted in it
* fix prompt schedule for second order samplers
* fix image mask/composite for weird resolutions #9628
* use correct images for previews when using AND (see #9491)
* one broken image in img2img batch won't stop all processing
* fix image orientation bug in train/preprocess
* fix Ngrok recreating tunnels every reload
* fix `--realesrgan-models-path` and `--ldsr-models-path` not working
* fix `--skip-install` not working
* use SAMPLE file format in Outpainting Mk2 & Poorman
* do not fail all LoRAs if some have failed to load when making a picture
## 1.0.0
* everything
+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"
+36 -19
View File
@@ -13,11 +13,11 @@ A browser interface based on Gradio library for Stable Diffusion.
- Prompt Matrix - Prompt Matrix
- Stable Diffusion Upscale - Stable Diffusion Upscale
- Attention, specify parts of text that the model should pay more attention to - Attention, specify parts of text that the model should pay more attention to
- a man in a ((tuxedo)) - will pay more attention to tuxedo - a man in a `((tuxedo))` - will pay more attention to tuxedo
- a man in a (tuxedo:1.21) - alternative syntax - a man in a `(tuxedo:1.21)` - alternative syntax
- select text and press ctrl+up or ctrl+down to automatically adjust attention to selected text (code contributed by anonymous user) - select text and press `Ctrl+Up` or `Ctrl+Down` (or `Command+Up` or `Command+Down` if you're on a MacOS) to automatically adjust attention to selected text (code contributed by anonymous user)
- Loopback, run img2img processing multiple times - Loopback, run img2img processing multiple times
- X/Y plot, a way to draw a 2 dimensional plot of images with different parameters - X/Y/Z plot, a way to draw a 3 dimensional plot of images with different parameters
- Textual Inversion - Textual Inversion
- have as many embeddings as you want and use any names you like for them - have as many embeddings as you want and use any names you like for them
- use multiple embeddings with different numbers of vectors per token - use multiple embeddings with different numbers of vectors per token
@@ -28,7 +28,7 @@ A browser interface based on Gradio library for Stable Diffusion.
- CodeFormer, face restoration tool as an alternative to GFPGAN - CodeFormer, face restoration tool as an alternative to GFPGAN
- RealESRGAN, neural network upscaler - RealESRGAN, neural network upscaler
- ESRGAN, neural network upscaler with a lot of third party models - ESRGAN, neural network upscaler with a lot of third party models
- SwinIR and Swin2SR([see here](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/2092)), neural network upscalers - SwinIR and Swin2SR ([see here](https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/2092)), neural network upscalers
- LDSR, Latent diffusion super resolution upscaling - LDSR, Latent diffusion super resolution upscaling
- Resizing aspect ratio options - Resizing aspect ratio options
- Sampling method selection - Sampling method selection
@@ -46,7 +46,7 @@ A browser interface based on Gradio library for Stable Diffusion.
- drag and drop an image/text-parameters to promptbox - drag and drop an image/text-parameters to promptbox
- Read Generation Parameters Button, loads parameters in promptbox to UI - Read Generation Parameters Button, loads parameters in promptbox to UI
- Settings page - Settings page
- Running arbitrary python code from UI (must run with --allow-code to enable) - Running arbitrary python code from UI (must run with `--allow-code` to enable)
- Mouseover hints for most UI elements - Mouseover hints for most UI elements
- Possible to change defaults/mix/max/step values for UI elements via text config - Possible to change defaults/mix/max/step values for UI elements via text config
- Tiling support, a checkbox to create images that can be tiled like textures - Tiling support, a checkbox to create images that can be tiled like textures
@@ -69,7 +69,7 @@ A browser interface based on Gradio library for Stable Diffusion.
- also supports weights for prompts: `a cat :1.2 AND a dog AND a penguin :2.2` - also supports weights for prompts: `a cat :1.2 AND a dog AND a penguin :2.2`
- No token limit for prompts (original stable diffusion lets you use up to 75 tokens) - No token limit for prompts (original stable diffusion lets you use up to 75 tokens)
- DeepDanbooru integration, creates danbooru style tags for anime prompts - DeepDanbooru integration, creates danbooru style tags for anime prompts
- [xformers](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers), major speed increase for select cards: (add --xformers to commandline args) - [xformers](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers), major speed increase for select cards: (add `--xformers` to commandline args)
- via extension: [History tab](https://github.com/yfszzx/stable-diffusion-webui-images-browser): view, direct and delete images conveniently within the UI - via extension: [History tab](https://github.com/yfszzx/stable-diffusion-webui-images-browser): view, direct and delete images conveniently within the UI
- Generate forever option - Generate forever option
- Training tab - Training tab
@@ -78,50 +78,58 @@ 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
- Support for dedicated [inpainting model](https://github.com/runwayml/stable-diffusion#inpainting-with-stable-diffusion) by RunwayML. - Support for dedicated [inpainting model](https://github.com/runwayml/stable-diffusion#inpainting-with-stable-diffusion) by RunwayML
- via extension: [Aesthetic Gradients](https://github.com/AUTOMATIC1111/stable-diffusion-webui-aesthetic-gradients), a way to generate images with a specific aesthetic by using clip images embeds (implementation of [https://github.com/vicgalle/stable-diffusion-aesthetic-gradients](https://github.com/vicgalle/stable-diffusion-aesthetic-gradients)) - via extension: [Aesthetic Gradients](https://github.com/AUTOMATIC1111/stable-diffusion-webui-aesthetic-gradients), a way to generate images with a specific aesthetic by using clip images embeds (implementation of [https://github.com/vicgalle/stable-diffusion-aesthetic-gradients](https://github.com/vicgalle/stable-diffusion-aesthetic-gradients))
- [Stable Diffusion 2.0](https://github.com/Stability-AI/stablediffusion) support - see [wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#stable-diffusion-20) for instructions - [Stable Diffusion 2.0](https://github.com/Stability-AI/stablediffusion) support - see [wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#stable-diffusion-20) 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 - [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
-
## 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)
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
1. Download `sd.webui.zip` from [v1.0.0-pre](https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases/tag/v1.0.0-pre) and extract its contents.
2. Run `update.bat`.
3. Run `run.bat`.
> For more details see [Install-and-Run-on-NVidia-GPUs](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-NVidia-GPUs)
### Automatic Installation on Windows ### Automatic Installation on Windows
1. Install [Python 3.10.6](https://www.python.org/downloads/windows/), checking "Add Python to PATH" 1. Install [Python 3.10.6](https://www.python.org/downloads/release/python-3106/) (Newer version of Python does not support torch), checking "Add Python to PATH".
2. Install [git](https://git-scm.com/download/win). 2. Install [git](https://git-scm.com/download/win).
3. Download the stable-diffusion-webui repository, for example by running `git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git`. 3. Download the stable-diffusion-webui repository, for example by running `git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git`.
4. Place stable diffusion checkpoint (`model.ckpt`) in the `models/Stable-diffusion` directory (see [dependencies](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Dependencies) for where to get it). 4. Run `webui-user.bat` from Windows Explorer as normal, non-administrator, user.
5. Run `webui-user.bat` from Windows Explorer as normal, non-administrator, user.
### Automatic Installation on Linux ### Automatic Installation on Linux
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
# Arch-based: # Arch-based:
sudo pacman -S wget git python3 sudo pacman -S wget git python3
``` ```
2. To install in `/home/$(whoami)/stable-diffusion-webui/`, run: 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
``` ```
3. Run `webui.sh`.
4. Check `webui-user.sh` for options.
### Installation on Apple Silicon ### Installation on Apple Silicon
Find the instructions [here](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Installation-on-Apple-Silicon). Find the instructions [here](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Installation-on-Apple-Silicon).
@@ -130,8 +138,11 @@ 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.
@@ -155,6 +166,12 @@ Licenses for borrowed code can be found in `Settings -> Licenses` screen, and al
- Idea for Composable Diffusion - https://github.com/energy-based-model/Compositional-Visual-Generation-with-Composable-Diffusion-Models-PyTorch - Idea for Composable Diffusion - https://github.com/energy-based-model/Compositional-Visual-Generation-with-Composable-Diffusion-Models-PyTorch
- xformers - https://github.com/facebookresearch/xformers - xformers - https://github.com/facebookresearch/xformers
- DeepDanbooru - interrogator for anime diffusers https://github.com/KichangKim/DeepDanbooru - DeepDanbooru - interrogator for anime diffusers https://github.com/KichangKim/DeepDanbooru
- Sampling in float32 precision from a float16 UNet - marunine for the idea, Birch-san for the example Diffusers implementation (https://github.com/Birch-san/diffusers-play/tree/92feee6)
- Instruct pix2pix - Tim Brooks (star), Aleksander Holynski (star), Alexei A. Efros (no star) - https://github.com/timothybrooks/instruct-pix2pix
- Security advice - RyotaK - Security advice - RyotaK
- UniPC sampler - Wenliang Zhao - https://github.com/wl-zhao/UniPC
- TAESD - Ollin Boer Bohan - https://github.com/madebyollin/taesd
- LyCORIS - KohakuBlueleaf
- Restart sampling - lambertae - https://github.com/Newbeeer/diffusion_restart_sampling
- 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)
+98
View File
@@ -0,0 +1,98 @@
# File modified by authors of InstructPix2Pix from original (https://github.com/CompVis/stable-diffusion).
# See more details in LICENSE.
model:
base_learning_rate: 1.0e-04
target: modules.models.diffusion.ddpm_edit.LatentDiffusion
params:
linear_start: 0.00085
linear_end: 0.0120
num_timesteps_cond: 1
log_every_t: 200
timesteps: 1000
first_stage_key: edited
cond_stage_key: edit
# image_size: 64
# image_size: 32
image_size: 16
channels: 4
cond_stage_trainable: false # Note: different from the one we trained before
conditioning_key: hybrid
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: [ 0 ]
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: 8
out_channels: 4
model_channels: 320
attention_resolutions: [ 4, 2, 1 ]
num_res_blocks: 2
channel_mult: [ 1, 2, 4, 4 ]
num_heads: 8
use_spatial_transformer: True
transformer_depth: 1
context_dim: 768
use_checkpoint: True
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: ldm.modules.encoders.modules.FrozenCLIPEmbedder
data:
target: main.DataModuleFromConfig
params:
batch_size: 128
num_workers: 1
wrap: false
validation:
target: edit_dataset.EditDataset
params:
path: data/clip-filtered-dataset
cache_dir: data/
cache_name: data_10k
split: val
min_text_sim: 0.2
min_image_sim: 0.75
min_direction_sim: 0.2
max_samples_per_prompt: 1
min_resize_res: 512
max_resize_res: 512
crop_res: 512
output_as_edit: False
real_input: True
@@ -1,8 +1,7 @@
model: model:
base_learning_rate: 1.0e-4 base_learning_rate: 7.5e-05
target: ldm.models.diffusion.ddpm.LatentDiffusion target: ldm.models.diffusion.ddpm.LatentInpaintDiffusion
params: params:
parameterization: "v"
linear_start: 0.00085 linear_start: 0.00085
linear_end: 0.0120 linear_end: 0.0120
num_timesteps_cond: 1 num_timesteps_cond: 1
@@ -12,29 +11,36 @@ model:
cond_stage_key: "txt" cond_stage_key: "txt"
image_size: 64 image_size: 64
channels: 4 channels: 4
cond_stage_trainable: false cond_stage_trainable: false # Note: different from the one we trained before
conditioning_key: crossattn conditioning_key: hybrid # important
monitor: val/loss_simple_ema monitor: val/loss_simple_ema
scale_factor: 0.18215 scale_factor: 0.18215
use_ema: False # we set this to false because this is an inference only config finetune_keys: null
scheduler_config: # 10000 warmup steps
target: ldm.lr_scheduler.LambdaLinearScheduler
params:
warm_up_steps: [ 2500 ] # NOTE for resuming. use 10000 if starting from scratch
cycle_lengths: [ 10000000000000 ] # incredibly large number to prevent corner cases
f_start: [ 1.e-6 ]
f_max: [ 1. ]
f_min: [ 1. ]
unet_config: unet_config:
target: ldm.modules.diffusionmodules.openaimodel.UNetModel target: ldm.modules.diffusionmodules.openaimodel.UNetModel
params: params:
use_checkpoint: True
use_fp16: True
image_size: 32 # unused image_size: 32 # unused
in_channels: 4 in_channels: 9 # 4 data + 4 downscaled image + 1 mask
out_channels: 4 out_channels: 4
model_channels: 320 model_channels: 320
attention_resolutions: [ 4, 2, 1 ] attention_resolutions: [ 4, 2, 1 ]
num_res_blocks: 2 num_res_blocks: 2
channel_mult: [ 1, 2, 4, 4 ] channel_mult: [ 1, 2, 4, 4 ]
num_head_channels: 64 # need to fix for flash-attn num_heads: 8
use_spatial_transformer: True use_spatial_transformer: True
use_linear_in_transformer: True
transformer_depth: 1 transformer_depth: 1
context_dim: 1024 context_dim: 768
use_checkpoint: True
legacy: False legacy: False
first_stage_config: first_stage_config:
@@ -43,7 +49,6 @@ model:
embed_dim: 4 embed_dim: 4
monitor: val/rec_loss monitor: val/rec_loss
ddconfig: ddconfig:
#attn_type: "vanilla-xformers"
double_z: true double_z: true
z_channels: 4 z_channels: 4
resolution: 256 resolution: 256
@@ -62,7 +67,4 @@ model:
target: torch.nn.Identity target: torch.nn.Identity
cond_stage_config: cond_stage_config:
target: ldm.modules.encoders.modules.FrozenOpenCLIPEmbedder target: ldm.modules.encoders.modules.FrozenCLIPEmbedder
params:
freeze: True
layer: "penultimate"
+5 -5
View File
@@ -4,8 +4,8 @@ channels:
- defaults - defaults
dependencies: dependencies:
- python=3.10 - python=3.10
- pip=22.2.2 - pip=23.0
- cudatoolkit=11.3 - cudatoolkit=11.8
- pytorch=1.12.1 - pytorch=2.0
- torchvision=0.13.1 - torchvision=0.15
- numpy=1.23.1 - numpy=1.23
+9 -12
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
@@ -88,7 +88,7 @@ class LDSR:
x_t = None x_t = None
logs = None logs = None
for n in range(n_runs): for _ in range(n_runs):
if custom_shape is not None: if custom_shape is not None:
x_t = torch.randn(1, custom_shape[1], custom_shape[2], custom_shape[3]).to(model.device) x_t = torch.randn(1, custom_shape[1], custom_shape[2], custom_shape[3]).to(model.device)
x_t = repeat(x_t, '1 c h w -> b c h w', b=custom_shape[0]) x_t = repeat(x_t, '1 c h w -> b c h w', b=custom_shape[0])
@@ -110,11 +110,9 @@ class LDSR:
diffusion_steps = int(steps) diffusion_steps = int(steps)
eta = 1.0 eta = 1.0
down_sample_method = 'Lanczos'
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
@@ -131,11 +129,11 @@ class LDSR:
im_og = im_og.resize((width_downsampled_pre, height_downsampled_pre), Image.LANCZOS) im_og = im_og.resize((width_downsampled_pre, height_downsampled_pre), Image.LANCZOS)
else: else:
print(f"Down sample rate is 1 from {target_scale} / 4 (Not downsampling)") print(f"Down sample rate is 1 from {target_scale} / 4 (Not downsampling)")
# pad width and height to multiples of 64, pads with the edge values of image to avoid artifacts # pad width and height to multiples of 64, pads with the edge values of image to avoid artifacts
pad_w, pad_h = np.max(((2, 2), np.ceil(np.array(im_og.size) / 64).astype(int)), axis=0) * 64 - im_og.size pad_w, pad_h = np.max(((2, 2), np.ceil(np.array(im_og.size) / 64).astype(int)), axis=0) * 64 - im_og.size
im_padded = Image.fromarray(np.pad(np.array(im_og), ((0, pad_h), (0, pad_w), (0, 0)), mode='edge')) im_padded = Image.fromarray(np.pad(np.array(im_og), ((0, pad_h), (0, pad_w), (0, 0)), mode='edge'))
logs = self.run(model["model"], im_padded, diffusion_steps, eta) logs = self.run(model["model"], im_padded, diffusion_steps, eta)
sample = logs["sample"] sample = logs["sample"]
@@ -151,14 +149,13 @@ 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
def get_cond(selected_path): def get_cond(selected_path):
example = dict() example = {}
up_f = 4 up_f = 4
c = selected_path.convert('RGB') c = selected_path.convert('RGB')
c = torch.unsqueeze(torchvision.transforms.ToTensor()(c), 0) c = torch.unsqueeze(torchvision.transforms.ToTensor()(c), 0)
@@ -196,7 +193,7 @@ def convsample_ddim(model, cond, steps, shape, eta=1.0, callback=None, normals_s
@torch.no_grad() @torch.no_grad()
def make_convolutional_sample(batch, model, custom_steps=None, eta=1.0, quantize_x0=False, custom_shape=None, temperature=1., noise_dropout=0., corrector=None, def make_convolutional_sample(batch, model, custom_steps=None, eta=1.0, quantize_x0=False, custom_shape=None, temperature=1., noise_dropout=0., corrector=None,
corrector_kwargs=None, x_T=None, ddim_use_x0_pred=False): corrector_kwargs=None, x_T=None, ddim_use_x0_pred=False):
log = dict() log = {}
z, c, x, xrec, xc = model.get_input(batch, model.first_stage_key, z, c, x, xrec, xc = model.get_input(batch, model.first_stage_key,
return_first_stage_outputs=True, return_first_stage_outputs=True,
@@ -244,7 +241,7 @@ def make_convolutional_sample(batch, model, custom_steps=None, eta=1.0, quantize
x_sample_noquant = model.decode_first_stage(sample, force_not_quantize=True) x_sample_noquant = model.decode_first_stage(sample, force_not_quantize=True)
log["sample_noquant"] = x_sample_noquant log["sample_noquant"] = x_sample_noquant
log["sample_diff"] = torch.abs(x_sample_noquant - x_sample) log["sample_diff"] = torch.abs(x_sample_noquant - x_sample)
except: except Exception:
pass pass
log["sample"] = x_sample log["sample"] = x_sample
+21 -22
View File
@@ -1,13 +1,11 @@
import os import os
import sys
import traceback
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 from modules import shared, script_callbacks, errors
import sd_hijack_autoencoder, sd_hijack_ddpm_v1 import sd_hijack_autoencoder # noqa: F401
import sd_hijack_ddpm_v1 # noqa: F401
class UpscalerLDSR(Upscaler): class UpscalerLDSR(Upscaler):
@@ -25,35 +23,36 @@ class UpscalerLDSR(Upscaler):
yaml_path = os.path.join(self.model_path, "project.yaml") yaml_path = os.path.join(self.model_path, "project.yaml")
old_model_path = os.path.join(self.model_path, "model.pth") old_model_path = os.path.join(self.model_path, "model.pth")
new_model_path = os.path.join(self.model_path, "model.ckpt") new_model_path = os.path.join(self.model_path, "model.ckpt")
safetensors_model_path = os.path.join(self.model_path, "model.safetensors")
local_model_paths = self.find_models(ext_filter=[".ckpt", ".safetensors"])
local_ckpt_path = next(iter([local_model for local_model in local_model_paths if local_model.endswith("model.ckpt")]), None)
local_safetensors_path = next(iter([local_model for local_model in local_model_paths if local_model.endswith("model.safetensors")]), None)
local_yaml_path = next(iter([local_model for local_model in local_model_paths if local_model.endswith("project.yaml")]), None)
if os.path.exists(yaml_path): if os.path.exists(yaml_path):
statinfo = os.stat(yaml_path) statinfo = os.stat(yaml_path)
if statinfo.st_size >= 10485760: if statinfo.st_size >= 10485760:
print("Removing invalid LDSR YAML file.") print("Removing invalid LDSR YAML file.")
os.remove(yaml_path) os.remove(yaml_path)
if os.path.exists(old_model_path): if os.path.exists(old_model_path):
print("Renaming model from model.pth to model.ckpt") print("Renaming model from model.pth to model.ckpt")
os.rename(old_model_path, new_model_path) os.rename(old_model_path, new_model_path)
if os.path.exists(safetensors_model_path):
model = safetensors_model_path if local_safetensors_path is not None and os.path.exists(local_safetensors_path):
model = local_safetensors_path
else: else:
model = load_file_from_url(url=self.model_url, model_dir=self.model_path, model = local_ckpt_path or load_file_from_url(self.model_url, model_dir=self.model_download_path, file_name="model.ckpt")
file_name="model.ckpt", progress=True)
yaml = load_file_from_url(url=self.yaml_url, model_dir=self.model_path,
file_name="project.yaml", progress=True)
try: yaml = local_yaml_path or load_file_from_url(self.yaml_url, model_dir=self.model_download_path, file_name="project.yaml")
return LDSR(model, yaml)
except Exception: return LDSR(model, yaml)
print("Error importing LDSR:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
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)
@@ -1,16 +1,21 @@
# The content of this file comes from the ldm/models/autoencoder.py file of the compvis/stable-diffusion repo # The content of this file comes from the ldm/models/autoencoder.py file of the compvis/stable-diffusion repo
# The VQModel & VQModelInterface were subsequently removed from ldm/models/autoencoder.py when we moved to the stability-ai/stablediffusion repo # The VQModel & VQModelInterface were subsequently removed from ldm/models/autoencoder.py when we moved to the stability-ai/stablediffusion repo
# As the LDSR upscaler relies on VQModel & VQModelInterface, the hijack aims to put them back into the ldm.models.autoencoder # As the LDSR upscaler relies on VQModel & VQModelInterface, the hijack aims to put them back into the ldm.models.autoencoder
import numpy as np
import torch import torch
import pytorch_lightning as pl import pytorch_lightning as pl
import torch.nn.functional as F import torch.nn.functional as F
from contextlib import contextmanager from contextlib import contextmanager
from taming.modules.vqvae.quantize import VectorQuantizer2 as VectorQuantizer
from torch.optim.lr_scheduler import LambdaLR
from ldm.modules.ema import LitEma
from vqvae_quantize import VectorQuantizer2 as VectorQuantizer
from ldm.modules.diffusionmodules.model import Encoder, Decoder from ldm.modules.diffusionmodules.model import Encoder, Decoder
from ldm.util import instantiate_from_config from ldm.util import instantiate_from_config
import ldm.models.autoencoder import ldm.models.autoencoder
from packaging import version
class VQModel(pl.LightningModule): class VQModel(pl.LightningModule):
def __init__(self, def __init__(self,
@@ -19,7 +24,7 @@ class VQModel(pl.LightningModule):
n_embed, n_embed,
embed_dim, embed_dim,
ckpt_path=None, ckpt_path=None,
ignore_keys=[], ignore_keys=None,
image_key="image", image_key="image",
colorize_nlabels=None, colorize_nlabels=None,
monitor=None, monitor=None,
@@ -57,7 +62,7 @@ class VQModel(pl.LightningModule):
print(f"Keeping EMAs of {len(list(self.model_ema.buffers()))}.") print(f"Keeping EMAs of {len(list(self.model_ema.buffers()))}.")
if ckpt_path is not None: if ckpt_path is not None:
self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys) self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys or [])
self.scheduler_config = scheduler_config self.scheduler_config = scheduler_config
self.lr_g_factor = lr_g_factor self.lr_g_factor = lr_g_factor
@@ -76,18 +81,19 @@ class VQModel(pl.LightningModule):
if context is not None: if context is not None:
print(f"{context}: Restored training weights") print(f"{context}: Restored training weights")
def init_from_ckpt(self, path, ignore_keys=list()): def init_from_ckpt(self, path, ignore_keys=None):
sd = torch.load(path, map_location="cpu")["state_dict"] sd = torch.load(path, map_location="cpu")["state_dict"]
keys = list(sd.keys()) keys = list(sd.keys())
for k in keys: for k in keys:
for ik in ignore_keys: for ik in ignore_keys or []:
if k.startswith(ik): if k.startswith(ik):
print("Deleting key {} from state_dict.".format(k)) print("Deleting key {} from state_dict.".format(k))
del sd[k] del sd[k]
missing, unexpected = self.load_state_dict(sd, strict=False) missing, unexpected = self.load_state_dict(sd, strict=False)
print(f"Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys") print(f"Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys")
if len(missing) > 0: if missing:
print(f"Missing Keys: {missing}") print(f"Missing Keys: {missing}")
if unexpected:
print(f"Unexpected Keys: {unexpected}") print(f"Unexpected Keys: {unexpected}")
def on_train_batch_end(self, *args, **kwargs): def on_train_batch_end(self, *args, **kwargs):
@@ -165,7 +171,7 @@ class VQModel(pl.LightningModule):
def validation_step(self, batch, batch_idx): def validation_step(self, batch, batch_idx):
log_dict = self._validation_step(batch, batch_idx) log_dict = self._validation_step(batch, batch_idx)
with self.ema_scope(): with self.ema_scope():
log_dict_ema = self._validation_step(batch, batch_idx, suffix="_ema") self._validation_step(batch, batch_idx, suffix="_ema")
return log_dict return log_dict
def _validation_step(self, batch, batch_idx, suffix=""): def _validation_step(self, batch, batch_idx, suffix=""):
@@ -232,7 +238,7 @@ class VQModel(pl.LightningModule):
return self.decoder.conv_out.weight return self.decoder.conv_out.weight
def log_images(self, batch, only_inputs=False, plot_ema=False, **kwargs): def log_images(self, batch, only_inputs=False, plot_ema=False, **kwargs):
log = dict() log = {}
x = self.get_input(batch, self.image_key) x = self.get_input(batch, self.image_key)
x = x.to(self.device) x = x.to(self.device)
if only_inputs: if only_inputs:
@@ -249,7 +255,8 @@ class VQModel(pl.LightningModule):
if plot_ema: if plot_ema:
with self.ema_scope(): with self.ema_scope():
xrec_ema, _ = self(x) xrec_ema, _ = self(x)
if x.shape[1] > 3: xrec_ema = self.to_rgb(xrec_ema) if x.shape[1] > 3:
xrec_ema = self.to_rgb(xrec_ema)
log["reconstructions_ema"] = xrec_ema log["reconstructions_ema"] = xrec_ema
return log return log
@@ -264,7 +271,7 @@ class VQModel(pl.LightningModule):
class VQModelInterface(VQModel): class VQModelInterface(VQModel):
def __init__(self, embed_dim, *args, **kwargs): def __init__(self, embed_dim, *args, **kwargs):
super().__init__(embed_dim=embed_dim, *args, **kwargs) super().__init__(*args, embed_dim=embed_dim, **kwargs)
self.embed_dim = embed_dim self.embed_dim = embed_dim
def encode(self, x): def encode(self, x):
@@ -282,5 +289,5 @@ class VQModelInterface(VQModel):
dec = self.decoder(quant) dec = self.decoder(quant)
return dec return dec
setattr(ldm.models.autoencoder, "VQModel", VQModel) ldm.models.autoencoder.VQModel = VQModel
setattr(ldm.models.autoencoder, "VQModelInterface", VQModelInterface) ldm.models.autoencoder.VQModelInterface = VQModelInterface
+32 -38
View File
@@ -48,7 +48,7 @@ class DDPMV1(pl.LightningModule):
beta_schedule="linear", beta_schedule="linear",
loss_type="l2", loss_type="l2",
ckpt_path=None, ckpt_path=None,
ignore_keys=[], ignore_keys=None,
load_only_unet=False, load_only_unet=False,
monitor="val/loss", monitor="val/loss",
use_ema=True, use_ema=True,
@@ -100,7 +100,7 @@ class DDPMV1(pl.LightningModule):
if monitor is not None: if monitor is not None:
self.monitor = monitor self.monitor = monitor
if ckpt_path is not None: if ckpt_path is not None:
self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys, only_model=load_only_unet) self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys or [], only_model=load_only_unet)
self.register_schedule(given_betas=given_betas, beta_schedule=beta_schedule, timesteps=timesteps, self.register_schedule(given_betas=given_betas, beta_schedule=beta_schedule, timesteps=timesteps,
linear_start=linear_start, linear_end=linear_end, cosine_s=cosine_s) linear_start=linear_start, linear_end=linear_end, cosine_s=cosine_s)
@@ -182,22 +182,22 @@ class DDPMV1(pl.LightningModule):
if context is not None: if context is not None:
print(f"{context}: Restored training weights") print(f"{context}: Restored training weights")
def init_from_ckpt(self, path, ignore_keys=list(), only_model=False): def init_from_ckpt(self, path, ignore_keys=None, only_model=False):
sd = torch.load(path, map_location="cpu") sd = torch.load(path, map_location="cpu")
if "state_dict" in list(sd.keys()): if "state_dict" in list(sd.keys()):
sd = sd["state_dict"] sd = sd["state_dict"]
keys = list(sd.keys()) keys = list(sd.keys())
for k in keys: for k in keys:
for ik in ignore_keys: for ik in ignore_keys or []:
if k.startswith(ik): if k.startswith(ik):
print("Deleting key {} from state_dict.".format(k)) print("Deleting key {} from state_dict.".format(k))
del sd[k] del sd[k]
missing, unexpected = self.load_state_dict(sd, strict=False) if not only_model else self.model.load_state_dict( missing, unexpected = self.load_state_dict(sd, strict=False) if not only_model else self.model.load_state_dict(
sd, strict=False) sd, strict=False)
print(f"Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys") print(f"Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys")
if len(missing) > 0: if missing:
print(f"Missing Keys: {missing}") print(f"Missing Keys: {missing}")
if len(unexpected) > 0: if unexpected:
print(f"Unexpected Keys: {unexpected}") print(f"Unexpected Keys: {unexpected}")
def q_mean_variance(self, x_start, t): def q_mean_variance(self, x_start, t):
@@ -375,7 +375,7 @@ class DDPMV1(pl.LightningModule):
@torch.no_grad() @torch.no_grad()
def log_images(self, batch, N=8, n_row=2, sample=True, return_keys=None, **kwargs): def log_images(self, batch, N=8, n_row=2, sample=True, return_keys=None, **kwargs):
log = dict() log = {}
x = self.get_input(batch, self.first_stage_key) x = self.get_input(batch, self.first_stage_key)
N = min(x.shape[0], N) N = min(x.shape[0], N)
n_row = min(x.shape[0], n_row) n_row = min(x.shape[0], n_row)
@@ -383,7 +383,7 @@ class DDPMV1(pl.LightningModule):
log["inputs"] = x log["inputs"] = x
# get diffusion row # get diffusion row
diffusion_row = list() diffusion_row = []
x_start = x[:n_row] x_start = x[:n_row]
for t in range(self.num_timesteps): for t in range(self.num_timesteps):
@@ -444,13 +444,13 @@ class LatentDiffusionV1(DDPMV1):
conditioning_key = None conditioning_key = None
ckpt_path = kwargs.pop("ckpt_path", None) ckpt_path = kwargs.pop("ckpt_path", None)
ignore_keys = kwargs.pop("ignore_keys", []) ignore_keys = kwargs.pop("ignore_keys", [])
super().__init__(conditioning_key=conditioning_key, *args, **kwargs) super().__init__(*args, conditioning_key=conditioning_key, **kwargs)
self.concat_mode = concat_mode self.concat_mode = concat_mode
self.cond_stage_trainable = cond_stage_trainable self.cond_stage_trainable = cond_stage_trainable
self.cond_stage_key = cond_stage_key self.cond_stage_key = cond_stage_key
try: try:
self.num_downs = len(first_stage_config.params.ddconfig.ch_mult) - 1 self.num_downs = len(first_stage_config.params.ddconfig.ch_mult) - 1
except: except Exception:
self.num_downs = 0 self.num_downs = 0
if not scale_by_std: if not scale_by_std:
self.scale_factor = scale_factor self.scale_factor = scale_factor
@@ -460,7 +460,7 @@ class LatentDiffusionV1(DDPMV1):
self.instantiate_cond_stage(cond_stage_config) self.instantiate_cond_stage(cond_stage_config)
self.cond_stage_forward = cond_stage_forward self.cond_stage_forward = cond_stage_forward
self.clip_denoised = False self.clip_denoised = False
self.bbox_tokenizer = None self.bbox_tokenizer = None
self.restarted_from_ckpt = False self.restarted_from_ckpt = False
if ckpt_path is not None: if ckpt_path is not None:
@@ -792,7 +792,7 @@ class LatentDiffusionV1(DDPMV1):
z = z.view((z.shape[0], -1, ks[0], ks[1], z.shape[-1])) # (bn, nc, ks[0], ks[1], L ) z = z.view((z.shape[0], -1, ks[0], ks[1], z.shape[-1])) # (bn, nc, ks[0], ks[1], L )
# 2. apply model loop over last dim # 2. apply model loop over last dim
if isinstance(self.first_stage_model, VQModelInterface): if isinstance(self.first_stage_model, VQModelInterface):
output_list = [self.first_stage_model.decode(z[:, :, :, :, i], output_list = [self.first_stage_model.decode(z[:, :, :, :, i],
force_not_quantize=predict_cids or force_not_quantize) force_not_quantize=predict_cids or force_not_quantize)
for i in range(z.shape[-1])] for i in range(z.shape[-1])]
@@ -877,16 +877,6 @@ class LatentDiffusionV1(DDPMV1):
c = self.q_sample(x_start=c, t=tc, noise=torch.randn_like(c.float())) c = self.q_sample(x_start=c, t=tc, noise=torch.randn_like(c.float()))
return self.p_losses(x, c, t, *args, **kwargs) return self.p_losses(x, c, t, *args, **kwargs)
def _rescale_annotations(self, bboxes, crop_coordinates): # TODO: move to dataset
def rescale_bbox(bbox):
x0 = clamp((bbox[0] - crop_coordinates[0]) / crop_coordinates[2])
y0 = clamp((bbox[1] - crop_coordinates[1]) / crop_coordinates[3])
w = min(bbox[2] / crop_coordinates[2], 1 - x0)
h = min(bbox[3] / crop_coordinates[3], 1 - y0)
return x0, y0, w, h
return [rescale_bbox(b) for b in bboxes]
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):
@@ -900,7 +890,7 @@ class LatentDiffusionV1(DDPMV1):
if hasattr(self, "split_input_params"): if hasattr(self, "split_input_params"):
assert len(cond) == 1 # todo can only deal with one conditioning atm assert len(cond) == 1 # todo can only deal with one conditioning atm
assert not return_ids assert not return_ids
ks = self.split_input_params["ks"] # eg. (128, 128) ks = self.split_input_params["ks"] # eg. (128, 128)
stride = self.split_input_params["stride"] # eg. (64, 64) stride = self.split_input_params["stride"] # eg. (64, 64)
@@ -1126,7 +1116,7 @@ class LatentDiffusionV1(DDPMV1):
if cond is not None: if cond is not None:
if isinstance(cond, dict): if isinstance(cond, dict):
cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else
list(map(lambda x: x[:batch_size], cond[key])) for key in cond} [x[:batch_size] for x in cond[key]] for key in cond}
else: else:
cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size] cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size]
@@ -1157,8 +1147,10 @@ class LatentDiffusionV1(DDPMV1):
if i % log_every_t == 0 or i == timesteps - 1: if i % log_every_t == 0 or i == timesteps - 1:
intermediates.append(x0_partial) intermediates.append(x0_partial)
if callback: callback(i) if callback:
if img_callback: img_callback(img, i) callback(i)
if img_callback:
img_callback(img, i)
return img, intermediates return img, intermediates
@torch.no_grad() @torch.no_grad()
@@ -1205,8 +1197,10 @@ class LatentDiffusionV1(DDPMV1):
if i % log_every_t == 0 or i == timesteps - 1: if i % log_every_t == 0 or i == timesteps - 1:
intermediates.append(img) intermediates.append(img)
if callback: callback(i) if callback:
if img_callback: img_callback(img, i) callback(i)
if img_callback:
img_callback(img, i)
if return_intermediates: if return_intermediates:
return img, intermediates return img, intermediates
@@ -1221,7 +1215,7 @@ class LatentDiffusionV1(DDPMV1):
if cond is not None: if cond is not None:
if isinstance(cond, dict): if isinstance(cond, dict):
cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else
list(map(lambda x: x[:batch_size], cond[key])) for key in cond} [x[:batch_size] for x in cond[key]] for key in cond}
else: else:
cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size] cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size]
return self.p_sample_loop(cond, return self.p_sample_loop(cond,
@@ -1253,7 +1247,7 @@ class LatentDiffusionV1(DDPMV1):
use_ddim = ddim_steps is not None use_ddim = ddim_steps is not None
log = dict() log = {}
z, c, x, xrec, xc = self.get_input(batch, self.first_stage_key, z, c, x, xrec, xc = self.get_input(batch, self.first_stage_key,
return_first_stage_outputs=True, return_first_stage_outputs=True,
force_c_encode=True, force_c_encode=True,
@@ -1280,7 +1274,7 @@ class LatentDiffusionV1(DDPMV1):
if plot_diffusion_rows: if plot_diffusion_rows:
# get diffusion row # get diffusion row
diffusion_row = list() diffusion_row = []
z_start = z[:n_row] z_start = z[:n_row]
for t in range(self.num_timesteps): for t in range(self.num_timesteps):
if t % self.log_every_t == 0 or t == self.num_timesteps - 1: if t % self.log_every_t == 0 or t == self.num_timesteps - 1:
@@ -1322,7 +1316,7 @@ class LatentDiffusionV1(DDPMV1):
if inpaint: if inpaint:
# make a simple center square # make a simple center square
b, h, w = z.shape[0], z.shape[2], z.shape[3] h, w = z.shape[2], z.shape[3]
mask = torch.ones(N, h, w).to(self.device) mask = torch.ones(N, h, w).to(self.device)
# zeros will be filled in # zeros will be filled in
mask[:, h // 4:3 * h // 4, w // 4:3 * w // 4] = 0. mask[:, h // 4:3 * h // 4, w // 4:3 * w // 4] = 0.
@@ -1424,10 +1418,10 @@ class Layout2ImgDiffusionV1(LatentDiffusionV1):
# TODO: move all layout-specific hacks to this class # TODO: move all layout-specific hacks to this class
def __init__(self, cond_stage_key, *args, **kwargs): def __init__(self, cond_stage_key, *args, **kwargs):
assert cond_stage_key == 'coordinates_bbox', 'Layout2ImgDiffusion only for cond_stage_key="coordinates_bbox"' assert cond_stage_key == 'coordinates_bbox', 'Layout2ImgDiffusion only for cond_stage_key="coordinates_bbox"'
super().__init__(cond_stage_key=cond_stage_key, *args, **kwargs) super().__init__(*args, cond_stage_key=cond_stage_key, **kwargs)
def log_images(self, batch, N=8, *args, **kwargs): def log_images(self, batch, N=8, *args, **kwargs):
logs = super().log_images(batch=batch, N=N, *args, **kwargs) logs = super().log_images(*args, batch=batch, N=N, **kwargs)
key = 'train' if self.training else 'validation' key = 'train' if self.training else 'validation'
dset = self.trainer.datamodule.datasets[key] dset = self.trainer.datamodule.datasets[key]
@@ -1443,7 +1437,7 @@ class Layout2ImgDiffusionV1(LatentDiffusionV1):
logs['bbox_image'] = cond_img logs['bbox_image'] = cond_img
return logs return logs
setattr(ldm.models.diffusion.ddpm, "DDPMV1", DDPMV1) ldm.models.diffusion.ddpm.DDPMV1 = DDPMV1
setattr(ldm.models.diffusion.ddpm, "LatentDiffusionV1", LatentDiffusionV1) ldm.models.diffusion.ddpm.LatentDiffusionV1 = LatentDiffusionV1
setattr(ldm.models.diffusion.ddpm, "DiffusionWrapperV1", DiffusionWrapperV1) ldm.models.diffusion.ddpm.DiffusionWrapperV1 = DiffusionWrapperV1
setattr(ldm.models.diffusion.ddpm, "Layout2ImgDiffusionV1", Layout2ImgDiffusionV1) ldm.models.diffusion.ddpm.Layout2ImgDiffusionV1 = Layout2ImgDiffusionV1
+147
View File
@@ -0,0 +1,147 @@
# Vendored from https://raw.githubusercontent.com/CompVis/taming-transformers/24268930bf1dce879235a7fddd0b2355b84d7ea6/taming/modules/vqvae/quantize.py,
# where the license is as follows:
#
# Copyright (c) 2020 Patrick Esser and Robin Rombach and Björn Ommer
#
# 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./
import torch
import torch.nn as nn
import numpy as np
from einops import rearrange
class VectorQuantizer2(nn.Module):
"""
Improved version over VectorQuantizer, can be used as a drop-in replacement. Mostly
avoids costly matrix multiplications and allows for post-hoc remapping of indices.
"""
# NOTE: due to a bug the beta term was applied to the wrong term. for
# backwards compatibility we use the buggy version by default, but you can
# specify legacy=False to fix it.
def __init__(self, n_e, e_dim, beta, remap=None, unknown_index="random",
sane_index_shape=False, legacy=True):
super().__init__()
self.n_e = n_e
self.e_dim = e_dim
self.beta = beta
self.legacy = legacy
self.embedding = nn.Embedding(self.n_e, self.e_dim)
self.embedding.weight.data.uniform_(-1.0 / self.n_e, 1.0 / self.n_e)
self.remap = remap
if self.remap is not None:
self.register_buffer("used", torch.tensor(np.load(self.remap)))
self.re_embed = self.used.shape[0]
self.unknown_index = unknown_index # "random" or "extra" or integer
if self.unknown_index == "extra":
self.unknown_index = self.re_embed
self.re_embed = self.re_embed + 1
print(f"Remapping {self.n_e} indices to {self.re_embed} indices. "
f"Using {self.unknown_index} for unknown indices.")
else:
self.re_embed = n_e
self.sane_index_shape = sane_index_shape
def remap_to_used(self, inds):
ishape = inds.shape
assert len(ishape) > 1
inds = inds.reshape(ishape[0], -1)
used = self.used.to(inds)
match = (inds[:, :, None] == used[None, None, ...]).long()
new = match.argmax(-1)
unknown = match.sum(2) < 1
if self.unknown_index == "random":
new[unknown] = torch.randint(0, self.re_embed, size=new[unknown].shape).to(device=new.device)
else:
new[unknown] = self.unknown_index
return new.reshape(ishape)
def unmap_to_all(self, inds):
ishape = inds.shape
assert len(ishape) > 1
inds = inds.reshape(ishape[0], -1)
used = self.used.to(inds)
if self.re_embed > self.used.shape[0]: # extra token
inds[inds >= self.used.shape[0]] = 0 # simply set to zero
back = torch.gather(used[None, :][inds.shape[0] * [0], :], 1, inds)
return back.reshape(ishape)
def forward(self, z, temp=None, rescale_logits=False, return_logits=False):
assert temp is None or temp == 1.0, "Only for interface compatible with Gumbel"
assert rescale_logits is False, "Only for interface compatible with Gumbel"
assert return_logits is False, "Only for interface compatible with Gumbel"
# reshape z -> (batch, height, width, channel) and flatten
z = rearrange(z, 'b c h w -> b h w c').contiguous()
z_flattened = z.view(-1, self.e_dim)
# distances from z to embeddings e_j (z - e)^2 = z^2 + e^2 - 2 e * z
d = torch.sum(z_flattened ** 2, dim=1, keepdim=True) + \
torch.sum(self.embedding.weight ** 2, dim=1) - 2 * \
torch.einsum('bd,dn->bn', z_flattened, rearrange(self.embedding.weight, 'n d -> d n'))
min_encoding_indices = torch.argmin(d, dim=1)
z_q = self.embedding(min_encoding_indices).view(z.shape)
perplexity = None
min_encodings = None
# compute loss for embedding
if not self.legacy:
loss = self.beta * torch.mean((z_q.detach() - z) ** 2) + \
torch.mean((z_q - z.detach()) ** 2)
else:
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()
# reshape back to match original input shape
z_q = rearrange(z_q, 'b h w c -> b c h w').contiguous()
if self.remap is not None:
min_encoding_indices = min_encoding_indices.reshape(z.shape[0], -1) # add batch axis
min_encoding_indices = self.remap_to_used(min_encoding_indices)
min_encoding_indices = min_encoding_indices.reshape(-1, 1) # flatten
if self.sane_index_shape:
min_encoding_indices = min_encoding_indices.reshape(
z_q.shape[0], z_q.shape[2], z_q.shape[3])
return z_q, loss, (perplexity, min_encodings, min_encoding_indices)
def get_codebook_entry(self, indices, shape):
# shape specifying (batch, height, width, channel)
if self.remap is not None:
indices = indices.reshape(shape[0], -1) # add batch axis
indices = self.unmap_to_all(indices)
indices = indices.reshape(-1) # flatten again
# get quantized latent vectors
z_q = self.embedding(indices)
if shape is not None:
z_q = z_q.view(shape)
# reshape back to match original input shape
z_q = z_q.permute(0, 3, 1, 2).contiguous()
return z_q
+55 -8
View File
@@ -1,20 +1,67 @@
from modules import extra_networks 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"""
def activate(self, p, params_list): def activate(self, p, params_list):
additional = shared.opts.sd_lora
self.errors.clear()
if additional != "None" and additional in networks.available_networks and not any(x for x in params_list if x.items[0] == additional):
p.all_prompts = [x + f"<lora:{additional}:{shared.opts.extra_networks_default_multiplier}>" for x in p.all_prompts]
params_list.append(extra_networks.ExtraNetworkParams(items=[additional, shared.opts.extra_networks_default_multiplier]))
names = [] names = []
multipliers = [] te_multipliers = []
unet_multipliers = []
dyn_dims = []
for params in params_list: for params in params_list:
assert len(params.items) > 0 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:
network_hashes = []
for item in networks.loaded_networks:
shorthash = item.network_on_disk.shorthash
if not shorthash:
continue
alias = item.mentioned_name
if not alias:
continue
alias = alias.replace(":", "").replace(",", "")
network_hashes.append(f"{alias}: {shorthash}")
if network_hashes:
p.extra_generation_params["Lora hashes"] = ", ".join(network_hashes)
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 -202
View File
@@ -1,204 +1,9 @@
import glob import networks
import os
import re
import torch
from modules import shared, devices, sd_models list_available_loras = networks.list_available_networks
re_digits = re.compile(r"\d+") available_loras = networks.available_networks
re_unet_down_blocks = re.compile(r"lora_unet_down_blocks_(\d+)_attentions_(\d+)_(.+)") available_lora_aliases = networks.available_network_aliases
re_unet_mid_blocks = re.compile(r"lora_unet_mid_block_attentions_(\d+)_(.+)") available_lora_hash_lookup = networks.available_network_hash_lookup
re_unet_up_blocks = re.compile(r"lora_unet_up_blocks_(\d+)_attentions_(\d+)_(.+)") forbidden_lora_aliases = networks.forbidden_network_aliases
re_text_block = re.compile(r"lora_te_text_model_encoder_layers_(\d+)_(.+)") loaded_loras = networks.loaded_networks
def convert_diffusers_name_to_compvis(key):
def match(match_list, 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, re_unet_down_blocks):
return f"diffusion_model_input_blocks_{1 + m[0] * 3 + m[1]}_1_{m[2]}"
if match(m, re_unet_mid_blocks):
return f"diffusion_model_middle_block_1_{m[1]}"
if match(m, re_unet_up_blocks):
return f"diffusion_model_output_blocks_{m[0] * 3 + m[1]}_1_{m[2]}"
if match(m, re_text_block):
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
class LoraModule:
def __init__(self, name):
self.name = name
self.multiplier = 1.0
self.modules = {}
self.mtime = None
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, filename):
lora = LoraModule(name)
lora.mtime = os.path.getmtime(filename)
sd = sd_models.read_state_dict(filename)
keys_failed_to_match = []
for key_diffusers, weight in sd.items():
fullkey = convert_diffusers_name_to_compvis(key_diffusers)
key, lora_key = fullkey.split(".", 1)
sd_module = shared.sd_model.lora_layer_mapping.get(key, None)
if sd_module is None:
keys_failed_to_match.append(key_diffusers)
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.Conv2d:
module = torch.nn.Conv2d(weight.shape[1], weight.shape[0], (1, 1), bias=False)
else:
assert False, 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.device, dtype=devices.dtype)
if lora_key == "lora_up.weight":
lora_module.up = module
elif lora_key == "lora_down.weight":
lora_module.down = module
else:
assert False, f'Bad Lora layer name: {key_diffusers} - must end in lora_up.weight, lora_down.weight or alpha'
if len(keys_failed_to_match) > 0:
print(f"Failed to match keys when loading Lora {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_loras.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_loras.get(name, None) for name in names]
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:
lora = load_lora(name, lora_on_disk.filename)
if lora is None:
print(f"Couldn't find Lora with name {name}")
continue
lora.multiplier = multipliers[i] if multipliers else 1.0
loaded_loras.append(lora)
def lora_forward(module, input, res):
if len(loaded_loras) == 0:
return res
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 not None:
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_Linear_forward(self, input):
return lora_forward(self, input, torch.nn.Linear_forward_before_lora(self, input))
def lora_Conv2d_forward(self, input):
return lora_forward(self, input, torch.nn.Conv2d_forward_before_lora(self, input))
def list_available_loras():
available_loras.clear()
os.makedirs(shared.cmd_opts.lora_dir, exist_ok=True)
candidates = \
glob.glob(os.path.join(shared.cmd_opts.lora_dir, '**/*.pt'), recursive=True) + \
glob.glob(os.path.join(shared.cmd_opts.lora_dir, '**/*.safetensors'), recursive=True) + \
glob.glob(os.path.join(shared.cmd_opts.lora_dir, '**/*.ckpt'), recursive=True)
for filename in sorted(candidates):
if os.path.isdir(filename):
continue
name = os.path.splitext(os.path.basename(filename))[0]
available_loras[name] = LoraOnDisk(name, filename)
available_loras = {}
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')
+21
View File
@@ -0,0 +1,21 @@
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)
+159
View File
@@ -0,0 +1,159 @@
from __future__ import annotations
import os
from collections import namedtuple
import enum
from modules import sd_models, cache, errors, hashes, shared
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)
metadata.pop('ssmd_cover_images', None) # those are cover images, and they are too big to display in UI as text
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 hasattr(self.sd_module, 'weight'):
self.shape = self.sd_module.weight.shape
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
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 finalize_updown(self, updown, orig_weight, output_shape, ex_bias=None):
if self.bias is not None:
updown = updown.reshape(self.bias.shape)
updown += self.bias.to(orig_weight.device, dtype=orig_weight.dtype)
updown = 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()
return updown * self.calc_scale() * self.multiplier(), ex_bias
def calc_updown(self, target):
raise NotImplementedError()
def forward(self, x, y):
raise NotImplementedError()
+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, dtype=orig_weight.dtype)
if self.ex_bias is not None:
ex_bias = self.ex_bias.to(orig_weight.device, dtype=orig_weight.dtype)
else:
ex_bias = None
return self.finalize_updown(updown, orig_weight, output_shape, ex_bias)
+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, dtype=orig_weight.dtype)
w1b = self.w1b.to(orig_weight.device, dtype=orig_weight.dtype)
w2a = self.w2a.to(orig_weight.device, dtype=orig_weight.dtype)
w2b = self.w2b.to(orig_weight.device, dtype=orig_weight.dtype)
output_shape = [w1a.size(0), w1b.size(1)]
if self.t1 is not None:
output_shape = [w1a.size(1), w1b.size(1)]
t1 = self.t1.to(orig_weight.device, dtype=orig_weight.dtype)
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, dtype=orig_weight.dtype)
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, dtype=orig_weight.dtype)
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, dtype=orig_weight.dtype)
else:
w1a = self.w1a.to(orig_weight.device, dtype=orig_weight.dtype)
w1b = self.w1b.to(orig_weight.device, dtype=orig_weight.dtype)
w1 = w1a @ w1b
if self.w2 is not None:
w2 = self.w2.to(orig_weight.device, dtype=orig_weight.dtype)
elif self.t2 is None:
w2a = self.w2a.to(orig_weight.device, dtype=orig_weight.dtype)
w2b = self.w2b.to(orig_weight.device, dtype=orig_weight.dtype)
w2 = w2a @ w2b
else:
t2 = self.t2.to(orig_weight.device, dtype=orig_weight.dtype)
w2a = self.w2a.to(orig_weight.device, dtype=orig_weight.dtype)
w2b = self.w2b.to(orig_weight.device, dtype=orig_weight.dtype)
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)
+86
View File
@@ -0,0 +1,86 @@
import torch
import lyco_helpers
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)
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]
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, dtype=orig_weight.dtype)
down = self.down_model.weight.to(orig_weight.device, dtype=orig_weight.dtype)
output_shape = [up.size(0), down.size(1)]
if self.mid_model is not None:
# cp-decomposition
mid = self.mid_model.weight.to(orig_weight.device, dtype=orig_weight.dtype)
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, dtype=orig_weight.dtype)
if self.b_norm is not None:
ex_bias = self.b_norm.to(orig_weight.device, dtype=orig_weight.dtype)
else:
ex_bias = None
return self.finalize_updown(updown, orig_weight, output_shape, ex_bias)
+641
View File
@@ -0,0 +1,641 @@
import logging
import os
import re
import lora_patches
import network
import network_lora
import network_hada
import network_ia3
import network_lokr
import network_full
import network_norm
import torch
from typing import Union
from modules import shared, devices, sd_models, errors, scripts, sd_hijack
from modules.textual_inversion.textual_inversion import Embedding
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(),
]
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:
for name, module in shared.sd_model.cond_stage_model.wrapped.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
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
matched_networks = {}
bundle_embeddings = {}
for key_network, weight in sd.items():
key_network_without_network_parts, network_part = key_network.split(".", 1)
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
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)
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():
# textual inversion embeddings
if 'string_to_param' in data:
param_dict = data['string_to_param']
param_dict = getattr(param_dict, '_parameters', param_dict) # fix for torch 1.12.1 loading saved file from torch 1.11
assert len(param_dict) == 1, 'embedding file has multiple terms in it'
emb = next(iter(param_dict.items()))[1]
vec = emb.detach().to(devices.device, dtype=torch.float32)
shape = vec.shape[-1]
vectors = vec.shape[0]
elif type(data) == dict and 'clip_g' in data and 'clip_l' in data: # SDXL embedding
vec = {k: v.detach().to(devices.device, dtype=torch.float32) for k, v in data.items()}
shape = data['clip_g'].shape[-1] + data['clip_l'].shape[-1]
vectors = data['clip_g'].shape[0]
elif type(data) == dict and type(next(iter(data.values()))) == torch.Tensor: # diffuser concepts
assert len(data.keys()) == 1, 'embedding file has multiple terms in it'
emb = next(iter(data.values()))
if len(emb.shape) == 1:
emb = emb.unsqueeze(0)
vec = emb.detach().to(devices.device, dtype=torch.float32)
shape = vec.shape[-1]
vectors = vec.shape[0]
else:
raise Exception(f"Couldn't identify {emb_name} in lora: {name} as neither textual inversion embedding nor diffuser concept.")
embedding = Embedding(vec, emb_name)
embedding.vectors = vectors
embedding.shape = shape
embedding.loaded = None
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:
embedding.loaded = None
emb_db.register_embedding_by_name(None, shared.sd_model, emb_name)
loaded_networks.clear()
networks_on_disk = [available_network_aliases.get(name, None) for name in names]
if any(x is None for x in networks_on_disk):
list_available_networks()
networks_on_disk = [available_network_aliases.get(name, None) for name in names]
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:
sd_hijack.model_hijack.comments.append("Networks not found: " + ", ".join(failed_to_load_networks))
purge_networks_from_memory()
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):
self.in_proj_weight.copy_(weights_backup[0])
self.out_proj.weight.copy_(weights_backup[1])
else:
self.weight.copy_(weights_backup)
if bias_backup is not None:
if isinstance(self, torch.nn.MultiheadAttention):
self.out_proj.bias.copy_(bias_backup)
else:
self.bias.copy_(bias_backup)
else:
if isinstance(self, torch.nn.MultiheadAttention):
self.out_proj.bias = None
else:
self.bias = None
def network_apply_weights(self: Union[torch.nn.Conv2d, torch.nn.Linear, torch.nn.GroupNorm, torch.nn.LayerNorm, torch.nn.MultiheadAttention]):
"""
Applies the currently selected set of networks to the weights of torch layer self.
If weights already have this particular set of networks applied, does nothing.
If not, restores orginal weights from backup and alters weights according to networks.
"""
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 != ():
raise RuntimeError("no backup weights found and current weights are not unchanged")
if isinstance(self, torch.nn.MultiheadAttention):
weights_backup = (self.in_proj_weight.to(devices.cpu, copy=True), self.out_proj.weight.to(devices.cpu, copy=True))
else:
weights_backup = self.weight.to(devices.cpu, copy=True)
self.network_weights_backup = weights_backup
bias_backup = getattr(self, "network_bias_backup", None)
if bias_backup is None:
if isinstance(self, torch.nn.MultiheadAttention) and self.out_proj.bias is not None:
bias_backup = self.out_proj.bias.to(devices.cpu, copy=True)
elif getattr(self, 'bias', None) is not None:
bias_backup = self.bias.to(devices.cpu, copy=True)
else:
bias_backup = None
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'):
try:
with torch.no_grad():
updown, ex_bias = module.calc_updown(self.weight)
if len(self.weight.shape) == 4 and self.weight.shape[1] == 9:
# inpainting model. zero pad updown to make channel[1] 4 to 9
updown = torch.nn.functional.pad(updown, (0, 0, 0, 0, 0, 5))
self.weight += updown
if ex_bias is not None and hasattr(self, 'bias'):
if self.bias is None:
self.bias = torch.nn.Parameter(ex_bias)
else:
self.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
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():
updown_q, _ = module_q.calc_updown(self.in_proj_weight)
updown_k, _ = module_k.calc_updown(self.in_proj_weight)
updown_v, _ = module_v.calc_updown(self.in_proj_weight)
updown_qkv = torch.vstack([updown_q, updown_k, updown_v])
updown_out, 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 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(module, input, original_forward):
"""
Old way of applying Lora by executing operations during layer's forward.
Stacking many loras this way results in big performance degradation.
"""
if len(loaded_networks) == 0:
return original_forward(module, input)
input = devices.cond_cast_unet(input)
network_restore_weights_from_backup(module)
network_reset_cached_weight(module)
y = original_forward(module, input)
network_layer_name = getattr(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 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)
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]
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
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()
+1
View File
@@ -4,3 +4,4 @@ from modules import paths
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=str, help="Path to directory with Lora networks.", default=os.path.join(paths.models_path, 'Lora'))
parser.add_argument("--lyco-dir-backcompat", type=str, help="Path to directory with LyCORIS networks (for backawards compatibility; can also use --lyco-dir).", default=os.path.join(paths.models_path, 'LyCORIS'))
+84 -15
View File
@@ -1,30 +1,99 @@
import torch import re
import lora import gradio as gr
from fastapi import FastAPI
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 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.Conv2d.forward = torch.nn.Conv2d_forward_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, 'Conv2d_forward_before_lora'): script_callbacks.on_model_loaded(networks.assign_network_names_to_compvis_modules)
torch.nn.Conv2d_forward_before_lora = torch.nn.Conv2d.forward
torch.nn.Linear.forward = lora.lora_Linear_forward
torch.nn.Conv2d.forward = lora.lora_Conv2d_forward
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(networks.infotext_pasted)
shared.options_templates.update(shared.options_section(('extra_networks', "Extra Networks"), {
"sd_lora": shared.OptionInfo("None", "Add network to prompt", gr.Dropdown, lambda: {"choices": ["None", *networks.available_networks]}, refresh=networks.list_available_networks),
"lora_preferred_name": shared.OptionInfo("Alias from file", "When adding to prompt, refer to Lora by", gr.Radio, {"choices": ["Alias from file", "Filename"]}),
"lora_add_hashes_to_infotext": shared.OptionInfo(True, "Add Lora hashes to infotext"),
"lora_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}),
}))
shared.options_templates.update(shared.options_section(('compatibility', "Compatibility"), {
"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: network.NetworkOnDisk):
return {
"name": obj.name,
"alias": obj.alias,
"path": obj.filename,
"metadata": obj.metadata,
}
def api_networks(_: gr.Blocks, app: FastAPI):
@app.get("/sdapi/v1/loras")
async def get_loras():
return [create_lora_json(obj) for obj in networks.available_networks.values()]
@app.post("/sdapi/v1/refresh-loras")
async def refresh_loras():
return networks.list_available_networks()
script_callbacks.on_app_started(api_networks)
re_lora = re.compile("<lora:([^:]+):")
def infotext_pasted(infotext, d):
hashes = d.get("Lora hashes")
if not hashes:
return
hashes = [x.strip().split(':', 1) for x in hashes.split(",")]
hashes = {x[0].strip().replace(",", ""): x[1].strip() for x in hashes}
def network_replacement(m):
alias = m.group(1)
shorthash = hashes.get(alias)
if shorthash is None:
return m.group(0)
network_on_disk = networks.available_network_hash_lookup.get(shorthash)
if network_on_disk is None:
return m.group(0)
return f'<lora:{network_on_disk.get_alias()}:'
d["Prompt"] = re.sub(re_lora, network_replacement, d["Prompt"])
script_callbacks.on_infotext_pasted(infotext_pasted)
shared.opts.onchange("lora_in_memory_limit", networks.purge_networks_from_memory)
@@ -0,0 +1,217 @@
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 = {}
for _, tags_dict in metadata.get("ss_tag_frequency", {}).items():
for tag, tag_count in tags_dict.items():
tag = tag.strip()
tags[tag] = tags.get(tag, 0) + int(tag_count)
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, 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["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)),
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:
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)
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,
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_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,67 @@ 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)
path, ext = os.path.splitext(lora_on_disk.filename)
alias = lora_on_disk.get_alias()
item = {
"name": name,
"filename": lora_on_disk.filename,
"shorthash": lora_on_disk.shorthash,
"preview": self.find_preview(path),
"description": self.find_description(path),
"search_term": self.search_terms_from_path(lora_on_disk.filename) + " " + (lora_on_disk.hash or ""),
"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)
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:
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 name, lora_on_disk in lora.available_loras.items(): for index, name in enumerate(networks.available_networks):
path, ext = os.path.splitext(lora_on_disk.filename) item = self.create_item(name, index)
previews = [path + ".png", path + ".preview.png"]
preview = None if item is not None:
for file in previews: yield item
if os.path.isfile(file):
preview = "./file=" + file.replace('\\', '/') + "?mtime=" + str(os.path.getmtime(file))
break
yield {
"name": name,
"filename": path,
"preview": preview,
"prompt": json.dumps(f"<lora:{name}:") + " + opts.extra_networks_default_multiplier + " + json.dumps(">"),
"local_preview": path + ".png",
}
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,15 +1,16 @@
import os.path
import sys import sys
import traceback
import PIL.Image import PIL.Image
import numpy as np import numpy as np
import torch import torch
from basicsr.utils.download_util import load_file_from_url from tqdm import tqdm
import modules.upscaler import modules.upscaler
from modules import devices, modelloader from modules import devices, modelloader, script_callbacks, errors
from scunet_model_arch import SCUNet as net from scunet_model_arch import SCUNet
from modules.modelloader import load_file_from_url
from modules.shared import opts
class UpscalerScuNET(modules.upscaler.Upscaler): class UpscalerScuNET(modules.upscaler.Upscaler):
@@ -25,7 +26,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)
@@ -35,53 +36,109 @@ class UpscalerScuNET(modules.upscaler.Upscaler):
scaler_data = modules.upscaler.UpscalerData(name, file, self, 4) scaler_data = modules.upscaler.UpscalerData(name, file, self, 4)
scalers.append(scaler_data) scalers.append(scaler_data)
except Exception: except Exception:
print(f"Error loading ScuNET model: {file}", file=sys.stderr) errors.report(f"Error loading ScuNET model: {file}", exc_info=True)
print(traceback.format_exc(), file=sys.stderr)
if add_model2: if add_model2:
scaler_data2 = modules.upscaler.UpscalerData(self.model_name2, self.model_url2, self) scaler_data2 = modules.upscaler.UpscalerData(self.model_name2, self.model_url2, self)
scalers.append(scaler_data2) scalers.append(scaler_data2)
self.scalers = scalers self.scalers = scalers
def do_upscale(self, img: PIL.Image, selected_file): @staticmethod
torch.cuda.empty_cache() @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)
model = self.load_model(selected_file) device = devices.get_device_for('scunet')
if model is None: assert tile % 8 == 0, "tile size should be a multiple of window_size"
sf = 1
stride = tile - tile_overlap
h_idx_list = list(range(0, h - tile, stride)) + [h - tile]
w_idx_list = list(range(0, w - tile, stride)) + [w - tile]
E = torch.zeros(1, 3, h * sf, w * sf, dtype=img.dtype, device=device)
W = torch.zeros_like(E, dtype=devices.dtype, device=device)
with tqdm(total=len(h_idx_list) * len(w_idx_list), desc="ScuNET tiles") as pbar:
for h_idx in h_idx_list:
for w_idx in w_idx_list:
in_patch = img[..., h_idx: h_idx + tile, w_idx: w_idx + tile]
out_patch = model(in_patch)
out_patch_mask = torch.ones_like(out_patch)
E[
..., h_idx * sf: (h_idx + tile) * sf, w_idx * sf: (w_idx + tile) * sf
].add_(out_patch)
W[
..., h_idx * sf: (h_idx + tile) * sf, w_idx * sf: (w_idx + tile) * sf
].add_(out_patch_mask)
pbar.update(1)
output = E.div_(W)
return output
def do_upscale(self, img: PIL.Image.Image, selected_file):
devices.torch_gc()
try:
model = self.load_model(selected_file)
except Exception as e:
print(f"ScuNET: Unable to load model from {selected_file}: {e}", file=sys.stderr)
return img return img
device = devices.get_device_for('scunet') device = devices.get_device_for('scunet')
img = np.array(img) tile = opts.SCUNET_tile
img = img[:, :, ::-1] h, w = img.height, img.width
img = np.moveaxis(img, 2, 0) / 255 np_img = np.array(img)
img = torch.from_numpy(img).float() np_img = np_img[:, :, ::-1] # RGB to BGR
img = img.unsqueeze(0).to(device) np_img = np_img.transpose((2, 0, 1)) / 255 # HWC to CHW
torch_img = torch.from_numpy(np_img).float().unsqueeze(0).to(device) # type: ignore
with torch.no_grad(): if tile > h or tile > w:
output = model(img) _img = torch.zeros(1, 3, max(h, tile), max(w, tile), dtype=torch_img.dtype, device=torch_img.device)
output = output.squeeze().float().cpu().clamp_(0, 1).numpy() _img[:, :, :h, :w] = torch_img # pad image
output = 255. * np.moveaxis(output, 0, 2) torch_img = _img
output = output.astype(np.uint8)
output = output[:, :, ::-1] torch_output = self.tiled_inference(torch_img, model).squeeze(0)
torch.cuda.empty_cache() torch_output = torch_output[:, :h * 1, :w * 1] # remove padding, if any
return PIL.Image.fromarray(output, 'RGB') np_output: np.ndarray = torch_output.float().cpu().clamp_(0, 1).numpy()
del torch_img, torch_output
devices.torch_gc()
output = np_output.transpose((1, 2, 0)) # CHW to HWC
output = output[:, :, ::-1] # BGR to RGB
return PIL.Image.fromarray((output * 255).astype(np.uint8))
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_path, file_name="%s.pth" % self.name, # TODO: this doesn't use `path` at all?
progress=True) filename = 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: model = SCUNet(in_nc=3, config=[4, 4, 4, 4, 4, 4, 4], dim=64)
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.load_state_dict(torch.load(filename), strict=True)
model.eval() model.eval()
for k, v in model.named_parameters(): for _, v in model.named_parameters():
v.requires_grad = False v.requires_grad = False
model = model.to(device) model = model.to(device)
return model return model
def on_ui_settings():
import gradio as gr
from modules import shared
shared.opts.add_option("SCUNET_tile", shared.OptionInfo(256, "Tile size for SCUNET upscalers.", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}, section=('upscaling', "Upscaling")).info("0 = no tiling"))
shared.opts.add_option("SCUNET_tile_overlap", shared.OptionInfo(8, "Tile overlap for SCUNET upscalers.", gr.Slider, {"minimum": 0, "maximum": 64, "step": 1}, section=('upscaling', "Upscaling")).info("Low values = visible seam"))
script_callbacks.on_ui_settings(on_ui_settings)
@@ -61,7 +61,9 @@ class WMSA(nn.Module):
Returns: Returns:
output: tensor shape [b h w c] 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)) 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) 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) h_windows = x.size(1)
w_windows = x.size(2) w_windows = x.size(2)
@@ -85,8 +87,9 @@ class WMSA(nn.Module):
output = self.linear(output) 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) 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), if self.type != 'W':
dims=(1, 2)) output = torch.roll(output, shifts=(self.window_size // 2, self.window_size // 2), dims=(1, 2))
return output return output
def relative_embedding(self): def relative_embedding(self):
@@ -262,4 +265,4 @@ class SCUNet(nn.Module):
nn.init.constant_(m.bias, 0) nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.LayerNorm): elif isinstance(m, nn.LayerNorm):
nn.init.constant_(m.bias, 0) nn.init.constant_(m.bias, 0)
nn.init.constant_(m.weight, 1.0) nn.init.constant_(m.weight, 1.0)
@@ -1,35 +1,35 @@
import contextlib import sys
import os import platform
import numpy as np 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 tqdm import tqdm
from modules import modelloader, devices, script_callbacks, shared from modules import modelloader, devices, script_callbacks, shared
from modules.shared import cmd_opts, opts, state from modules.shared import opts, state
from swinir_model_arch import SwinIR as net from swinir_model_arch import SwinIR
from swinir_model_arch_v2 import Swin2SR as net2 from swinir_model_arch_v2 import Swin2SR
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') device_swinir = devices.get_device_for('swinir')
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)
@@ -38,42 +38,54 @@ class UpscalerSwinIR(Upscaler):
self.scalers = scalers self.scalers = scalers
def do_upscale(self, img, model_file): def do_upscale(self, img, model_file):
model = self.load_model(model_file) use_compile = hasattr(opts, 'SWIN_torch_compile') and opts.SWIN_torch_compile \
if model is None: and int(torch.__version__.split('.')[0]) >= 2 and platform.system() != "Windows"
return img current_config = (model_file, opts.SWIN_tile)
model = model.to(device_swinir, dtype=devices.dtype)
if use_compile and self._cached_model_config == current_config:
model = self._cached_model
else:
self._cached_model = None
try:
model = self.load_model(model_file)
except Exception as e:
print(f"Failed loading SwinIR model {model_file}: {e}", file=sys.stderr)
return img
model = model.to(device_swinir, dtype=devices.dtype)
if use_compile:
model = torch.compile(model)
self._cached_model = model
self._cached_model_config = current_config
img = upscale(img, model) img = upscale(img, model)
try: devices.torch_gc()
torch.cuda.empty_cache()
except:
pass
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_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"): if filename.endswith(".v2.pth"):
model = net2( model = Swin2SR(
upscale=scale, upscale=scale,
in_chans=3, in_chans=3,
img_size=64, img_size=64,
window_size=8, window_size=8,
img_range=1.0, img_range=1.0,
depths=[6, 6, 6, 6, 6, 6], depths=[6, 6, 6, 6, 6, 6],
embed_dim=180, embed_dim=180,
num_heads=[6, 6, 6, 6, 6, 6], num_heads=[6, 6, 6, 6, 6, 6],
mlp_ratio=2, mlp_ratio=2,
upsampler="nearest+conv", upsampler="nearest+conv",
resi_connection="1conv", resi_connection="1conv",
) )
params = None params = None
else: else:
model = net( model = SwinIR(
upscale=scale, upscale=scale,
in_chans=3, in_chans=3,
img_size=64, img_size=64,
@@ -151,7 +163,7 @@ def inference(img, model, tile, tile_overlap, window_size, scale):
for w_idx in w_idx_list: for w_idx in w_idx_list:
if state.interrupted or state.skipped: if state.interrupted or state.skipped:
break break
in_patch = img[..., h_idx: h_idx + tile, w_idx: w_idx + tile] in_patch = img[..., h_idx: h_idx + tile, w_idx: w_idx + tile]
out_patch = model(in_patch) out_patch = model(in_patch)
out_patch_mask = torch.ones_like(out_patch) out_patch_mask = torch.ones_like(out_patch)
@@ -173,6 +185,8 @@ 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")))
if int(torch.__version__.split('.')[0]) >= 2 and platform.system() != "Windows": # torch.compile() require pytorch 2.0 or above, and not on Windows
shared.opts.add_option("SWIN_torch_compile", shared.OptionInfo(False, "Use torch.compile to accelerate SwinIR.", gr.Checkbox, {"interactive": True}, section=('upscaling', "Upscaling")).info("Takes longer on first run"))
script_callbacks.on_ui_settings(on_ui_settings) script_callbacks.on_ui_settings(on_ui_settings)
@@ -644,7 +644,7 @@ class SwinIR(nn.Module):
""" """
def __init__(self, img_size=64, patch_size=1, in_chans=3, 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], 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, window_size=7, mlp_ratio=4., qkv_bias=True, qk_scale=None,
drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1, drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1,
norm_layer=nn.LayerNorm, ape=False, patch_norm=True, norm_layer=nn.LayerNorm, ape=False, patch_norm=True,
@@ -805,7 +805,7 @@ class SwinIR(nn.Module):
def forward(self, x): def forward(self, x):
H, W = x.shape[2:] H, W = x.shape[2:]
x = self.check_image_size(x) x = self.check_image_size(x)
self.mean = self.mean.type_as(x) self.mean = self.mean.type_as(x)
x = (x - self.mean) * self.img_range x = (x - self.mean) * self.img_range
@@ -844,7 +844,7 @@ class SwinIR(nn.Module):
H, W = self.patches_resolution H, W = self.patches_resolution
flops += H * W * 3 * self.embed_dim * 9 flops += H * W * 3 * self.embed_dim * 9
flops += self.patch_embed.flops() flops += self.patch_embed.flops()
for i, layer in enumerate(self.layers): for layer in self.layers:
flops += layer.flops() flops += layer.flops()
flops += H * W * 3 * self.embed_dim * self.embed_dim flops += H * W * 3 * self.embed_dim * self.embed_dim
flops += self.upsample.flops() flops += self.upsample.flops()
@@ -74,7 +74,7 @@ class WindowAttention(nn.Module):
""" """
def __init__(self, dim, window_size, num_heads, qkv_bias=True, attn_drop=0., proj_drop=0., def __init__(self, dim, window_size, num_heads, qkv_bias=True, attn_drop=0., proj_drop=0.,
pretrained_window_size=[0, 0]): pretrained_window_size=(0, 0)):
super().__init__() super().__init__()
self.dim = dim self.dim = dim
@@ -241,7 +241,7 @@ class SwinTransformerBlock(nn.Module):
attn_mask = None attn_mask = None
self.register_buffer("attn_mask", attn_mask) self.register_buffer("attn_mask", attn_mask)
def calculate_mask(self, x_size): def calculate_mask(self, x_size):
# calculate attention mask for SW-MSA # calculate attention mask for SW-MSA
H, W = x_size H, W = x_size
@@ -263,7 +263,7 @@ class SwinTransformerBlock(nn.Module):
attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2) 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)) attn_mask = attn_mask.masked_fill(attn_mask != 0, float(-100.0)).masked_fill(attn_mask == 0, float(0.0))
return attn_mask return attn_mask
def forward(self, x, x_size): def forward(self, x, x_size):
H, W = x_size H, W = x_size
@@ -288,7 +288,7 @@ class SwinTransformerBlock(nn.Module):
attn_windows = self.attn(x_windows, mask=self.attn_mask) # nW*B, window_size*window_size, C attn_windows = self.attn(x_windows, mask=self.attn_mask) # nW*B, window_size*window_size, C
else: else:
attn_windows = self.attn(x_windows, mask=self.calculate_mask(x_size).to(x.device)) attn_windows = self.attn(x_windows, mask=self.calculate_mask(x_size).to(x.device))
# merge windows # merge windows
attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C) 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 shifted_x = window_reverse(attn_windows, self.window_size, H, W) # B H' W' C
@@ -369,7 +369,7 @@ class PatchMerging(nn.Module):
H, W = self.input_resolution H, W = self.input_resolution
flops = (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim flops = (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim
flops += H * W * self.dim // 2 flops += H * W * self.dim // 2
return flops return flops
class BasicLayer(nn.Module): class BasicLayer(nn.Module):
""" A basic Swin Transformer layer for one stage. """ A basic Swin Transformer layer for one stage.
@@ -447,7 +447,7 @@ class BasicLayer(nn.Module):
nn.init.constant_(blk.norm1.weight, 0) nn.init.constant_(blk.norm1.weight, 0)
nn.init.constant_(blk.norm2.bias, 0) nn.init.constant_(blk.norm2.bias, 0)
nn.init.constant_(blk.norm2.weight, 0) nn.init.constant_(blk.norm2.weight, 0)
class PatchEmbed(nn.Module): class PatchEmbed(nn.Module):
r""" Image to Patch Embedding r""" Image to Patch Embedding
Args: Args:
@@ -492,7 +492,7 @@ class PatchEmbed(nn.Module):
flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1]) flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1])
if self.norm is not None: if self.norm is not None:
flops += Ho * Wo * self.embed_dim flops += Ho * Wo * self.embed_dim
return flops return flops
class RSTB(nn.Module): class RSTB(nn.Module):
"""Residual Swin Transformer Block (RSTB). """Residual Swin Transformer Block (RSTB).
@@ -531,7 +531,7 @@ class RSTB(nn.Module):
num_heads=num_heads, num_heads=num_heads,
window_size=window_size, window_size=window_size,
mlp_ratio=mlp_ratio, mlp_ratio=mlp_ratio,
qkv_bias=qkv_bias, qkv_bias=qkv_bias,
drop=drop, attn_drop=attn_drop, drop=drop, attn_drop=attn_drop,
drop_path=drop_path, drop_path=drop_path,
norm_layer=norm_layer, norm_layer=norm_layer,
@@ -622,7 +622,7 @@ class Upsample(nn.Sequential):
else: else:
raise ValueError(f'scale {scale} is not supported. ' 'Supported scales: 2^n and 3.') raise ValueError(f'scale {scale} is not supported. ' 'Supported scales: 2^n and 3.')
super(Upsample, self).__init__(*m) super(Upsample, self).__init__(*m)
class Upsample_hf(nn.Sequential): class Upsample_hf(nn.Sequential):
"""Upsample module. """Upsample module.
@@ -642,7 +642,7 @@ class Upsample_hf(nn.Sequential):
m.append(nn.PixelShuffle(3)) m.append(nn.PixelShuffle(3))
else: else:
raise ValueError(f'scale {scale} is not supported. ' 'Supported scales: 2^n and 3.') raise ValueError(f'scale {scale} is not supported. ' 'Supported scales: 2^n and 3.')
super(Upsample_hf, self).__init__(*m) super(Upsample_hf, self).__init__(*m)
class UpsampleOneStep(nn.Sequential): class UpsampleOneStep(nn.Sequential):
@@ -667,8 +667,8 @@ class UpsampleOneStep(nn.Sequential):
H, W = self.input_resolution H, W = self.input_resolution
flops = H * W * self.num_feat * 3 * 9 flops = H * W * self.num_feat * 3 * 9
return flops return flops
class Swin2SR(nn.Module): class Swin2SR(nn.Module):
r""" Swin2SR r""" Swin2SR
@@ -698,8 +698,8 @@ class Swin2SR(nn.Module):
""" """
def __init__(self, img_size=64, patch_size=1, in_chans=3, 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], embed_dim=96, depths=(6, 6, 6, 6), num_heads=(6, 6, 6, 6),
window_size=7, mlp_ratio=4., qkv_bias=True, window_size=7, mlp_ratio=4., qkv_bias=True,
drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1, drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1,
norm_layer=nn.LayerNorm, ape=False, patch_norm=True, norm_layer=nn.LayerNorm, ape=False, patch_norm=True,
use_checkpoint=False, upscale=2, img_range=1., upsampler='', resi_connection='1conv', use_checkpoint=False, upscale=2, img_range=1., upsampler='', resi_connection='1conv',
@@ -764,7 +764,7 @@ class Swin2SR(nn.Module):
num_heads=num_heads[i_layer], num_heads=num_heads[i_layer],
window_size=window_size, window_size=window_size,
mlp_ratio=self.mlp_ratio, mlp_ratio=self.mlp_ratio,
qkv_bias=qkv_bias, qkv_bias=qkv_bias,
drop=drop_rate, attn_drop=attn_drop_rate, 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 drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], # no impact on SR results
norm_layer=norm_layer, norm_layer=norm_layer,
@@ -776,7 +776,7 @@ class Swin2SR(nn.Module):
) )
self.layers.append(layer) self.layers.append(layer)
if self.upsampler == 'pixelshuffle_hf': if self.upsampler == 'pixelshuffle_hf':
self.layers_hf = nn.ModuleList() self.layers_hf = nn.ModuleList()
for i_layer in range(self.num_layers): for i_layer in range(self.num_layers):
@@ -787,7 +787,7 @@ class Swin2SR(nn.Module):
num_heads=num_heads[i_layer], num_heads=num_heads[i_layer],
window_size=window_size, window_size=window_size,
mlp_ratio=self.mlp_ratio, mlp_ratio=self.mlp_ratio,
qkv_bias=qkv_bias, qkv_bias=qkv_bias,
drop=drop_rate, attn_drop=attn_drop_rate, 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 drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], # no impact on SR results
norm_layer=norm_layer, norm_layer=norm_layer,
@@ -799,7 +799,7 @@ class Swin2SR(nn.Module):
) )
self.layers_hf.append(layer) self.layers_hf.append(layer)
self.norm = norm_layer(self.num_features) self.norm = norm_layer(self.num_features)
# build the last conv layer in deep feature extraction # build the last conv layer in deep feature extraction
@@ -829,10 +829,10 @@ class Swin2SR(nn.Module):
self.conv_aux = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1) self.conv_aux = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
self.conv_after_aux = nn.Sequential( self.conv_after_aux = nn.Sequential(
nn.Conv2d(3, num_feat, 3, 1, 1), nn.Conv2d(3, num_feat, 3, 1, 1),
nn.LeakyReLU(inplace=True)) nn.LeakyReLU(inplace=True))
self.upsample = Upsample(upscale, num_feat) self.upsample = Upsample(upscale, num_feat)
self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1) self.conv_last = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
elif self.upsampler == 'pixelshuffle_hf': elif self.upsampler == 'pixelshuffle_hf':
self.conv_before_upsample = nn.Sequential(nn.Conv2d(embed_dim, num_feat, 3, 1, 1), self.conv_before_upsample = nn.Sequential(nn.Conv2d(embed_dim, num_feat, 3, 1, 1),
nn.LeakyReLU(inplace=True)) nn.LeakyReLU(inplace=True))
@@ -846,7 +846,7 @@ class Swin2SR(nn.Module):
nn.Conv2d(embed_dim, num_feat, 3, 1, 1), nn.Conv2d(embed_dim, num_feat, 3, 1, 1),
nn.LeakyReLU(inplace=True)) nn.LeakyReLU(inplace=True))
self.conv_last_hf = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1) self.conv_last_hf = nn.Conv2d(num_feat, num_out_ch, 3, 1, 1)
elif self.upsampler == 'pixelshuffledirect': elif self.upsampler == 'pixelshuffledirect':
# for lightweight SR (to save parameters) # for lightweight SR (to save parameters)
self.upsample = UpsampleOneStep(upscale, embed_dim, num_out_ch, self.upsample = UpsampleOneStep(upscale, embed_dim, num_out_ch,
@@ -905,7 +905,7 @@ class Swin2SR(nn.Module):
x = self.patch_unembed(x, x_size) x = self.patch_unembed(x, x_size)
return x return x
def forward_features_hf(self, x): def forward_features_hf(self, x):
x_size = (x.shape[2], x.shape[3]) x_size = (x.shape[2], x.shape[3])
x = self.patch_embed(x) x = self.patch_embed(x)
@@ -919,7 +919,7 @@ class Swin2SR(nn.Module):
x = self.norm(x) # B L C x = self.norm(x) # B L C
x = self.patch_unembed(x, x_size) x = self.patch_unembed(x, x_size)
return x return x
def forward(self, x): def forward(self, x):
H, W = x.shape[2:] H, W = x.shape[2:]
@@ -951,7 +951,7 @@ class Swin2SR(nn.Module):
x = self.conv_after_body(self.forward_features(x)) + x x = self.conv_after_body(self.forward_features(x)) + x
x_before = self.conv_before_upsample(x) x_before = self.conv_before_upsample(x)
x_out = self.conv_last(self.upsample(x_before)) x_out = self.conv_last(self.upsample(x_before))
x_hf = self.conv_first_hf(x_before) x_hf = self.conv_first_hf(x_before)
x_hf = self.conv_after_body_hf(self.forward_features_hf(x_hf)) + x_hf x_hf = self.conv_after_body_hf(self.forward_features_hf(x_hf)) + x_hf
x_hf = self.conv_before_upsample_hf(x_hf) x_hf = self.conv_before_upsample_hf(x_hf)
@@ -977,15 +977,15 @@ class Swin2SR(nn.Module):
x_first = self.conv_first(x) x_first = self.conv_first(x)
res = self.conv_after_body(self.forward_features(x_first)) + x_first res = self.conv_after_body(self.forward_features(x_first)) + x_first
x = x + self.conv_last(res) x = x + self.conv_last(res)
x = x / self.img_range + self.mean x = x / self.img_range + self.mean
if self.upsampler == "pixelshuffle_aux": if self.upsampler == "pixelshuffle_aux":
return x[:, :, :H*self.upscale, :W*self.upscale], aux return x[:, :, :H*self.upscale, :W*self.upscale], aux
elif self.upsampler == "pixelshuffle_hf": elif self.upsampler == "pixelshuffle_hf":
x_out = x_out / self.img_range + self.mean x_out = x_out / self.img_range + self.mean
return x_out[:, :, :H*self.upscale, :W*self.upscale], x[:, :, :H*self.upscale, :W*self.upscale], x_hf[:, :, :H*self.upscale, :W*self.upscale] return x_out[:, :, :H*self.upscale, :W*self.upscale], x[:, :, :H*self.upscale, :W*self.upscale], x_hf[:, :, :H*self.upscale, :W*self.upscale]
else: else:
return x[:, :, :H*self.upscale, :W*self.upscale] return x[:, :, :H*self.upscale, :W*self.upscale]
@@ -994,7 +994,7 @@ class Swin2SR(nn.Module):
H, W = self.patches_resolution H, W = self.patches_resolution
flops += H * W * 3 * self.embed_dim * 9 flops += H * W * 3 * self.embed_dim * 9
flops += self.patch_embed.flops() flops += self.patch_embed.flops()
for i, layer in enumerate(self.layers): for layer in self.layers:
flops += layer.flops() flops += layer.flops()
flops += H * W * 3 * self.embed_dim * self.embed_dim flops += H * W * 3 * self.embed_dim * self.embed_dim
flops += self.upsample.flops() flops += self.upsample.flops()
@@ -1014,4 +1014,4 @@ if __name__ == '__main__':
x = torch.randn((1, 3, height, width)) x = torch.randn((1, 3, height, width))
x = model(x) x = model(x)
print(x.shape) print(x.shape)
@@ -0,0 +1,962 @@
onUiLoaded(async() => {
const elementIDs = {
img2imgTabs: "#mode_img2img .tab-nav",
inpaint: "#img2maskimg",
inpaintSketch: "#inpaint_sketch",
rangeGroup: "#img2img_column_size",
sketch: "#img2img_sketch"
};
const tabNameToElementId = {
"Inpaint sketch": elementIDs.inpaintSketch,
"Inpaint": elementIDs.inpaint,
"Sketch": elementIDs.sketch
};
// Helper functions
// Get active tab
/**
* Waits for an element to be present in the DOM.
*/
const waitForElement = (id) => new Promise(resolve => {
const checkForElement = () => {
const element = document.querySelector(id);
if (element) return resolve(element);
setTimeout(checkForElement, 100);
};
checkForElement();
});
function getActiveTab(elements, all = false) {
const tabs = elements.img2imgTabs.querySelectorAll("button");
if (all) return tabs;
for (let tab of tabs) {
if (tab.classList.contains("selected")) {
return tab;
}
}
}
// Get tab ID
function getTabId(elements) {
const activeTab = getActiveTab(elements);
return tabNameToElementId[activeTab.innerText];
}
// Wait until opts loaded
async function waitForOpts() {
for (; ;) {
if (window.opts && Object.keys(window.opts).length) {
return window.opts;
}
await new Promise(resolve => setTimeout(resolve, 100));
}
}
// Detect whether the element has a horizontal scroll bar
function hasHorizontalScrollbar(element) {
return element.scrollWidth > element.clientWidth;
}
// Function for defining the "Ctrl", "Shift" and "Alt" keys
function isModifierKey(event, key) {
switch (key) {
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 (
(typeof value === "string" &&
value.length === 1 &&
/[a-z]/i.test(value)) ||
specialKeys.includes(value)
);
}
// Normalize hotkey
function normalizeHotkey(hotkey) {
return hotkey.length === 1 ? "Key" + hotkey.toUpperCase() : hotkey;
}
// 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) {
const userValue = hotkeysConfigOpts[key]; // User-provided hotkey value
const defaultValue = defaultHotkeysConfig[key]; // Default hotkey value
// Apply appropriate value for undefined, boolean, or object userValue
if (
userValue === undefined ||
typeof userValue === "boolean" ||
typeof userValue === "object" ||
userValue === "disable"
) {
result[key] =
userValue === undefined ? defaultValue : userValue;
} 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 {
console.error(
`Hotkey: ${formatHotkeyForDisplay(
userValue
)} for ${key} is not valid. The default hotkey is used: ${formatHotkeyForDisplay(
defaultValue
)}`
);
result[key] = defaultValue;
}
}
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.
* If the image display property is set to 'none', the mask breaks. To fix this, the function
* temporarily sets the display property to 'block' and then hides the mask again after 300 milliseconds
* to avoid breaking the canvas. Additionally, the function adjusts the mask to work correctly on
* very long images.
*/
function restoreImgRedMask(elements) {
const mainTabId = getTabId(elements);
if (!mainTabId) return;
const mainTab = gradioApp().querySelector(mainTabId);
const img = mainTab.querySelector("img");
const imageARPreview = gradioApp().querySelector("#imageARPreview");
if (!img || !imageARPreview) return;
imageARPreview.style.transform = "";
if (parseFloat(mainTab.style.width) > 865) {
const transformString = mainTab.style.transform;
const scaleMatch = transformString.match(
/scale\(([-+]?[0-9]*\.?[0-9]+)\)/
);
let zoom = 1; // default zoom
if (scaleMatch && scaleMatch[1]) {
zoom = Number(scaleMatch[1]);
}
imageARPreview.style.transformOrigin = "0 0";
imageARPreview.style.transform = `scale(${zoom})`;
}
if (img.style.display !== "none") return;
img.style.display = "block";
setTimeout(() => {
img.style.display = "none";
}, 400);
}
const hotkeysConfigOpts = await waitForOpts();
// Default config
const defaultHotkeysConfig = {
canvas_hotkey_zoom: "Alt",
canvas_hotkey_adjust: "Ctrl",
canvas_hotkey_reset: "KeyR",
canvas_hotkey_fullscreen: "KeyS",
canvas_hotkey_move: "KeyF",
canvas_hotkey_overlap: "KeyO",
canvas_disabled_functions: [],
canvas_show_tooltip: true,
canvas_auto_expand: true,
canvas_blur_prompt: false,
};
const functionMap = {
"Zoom": "canvas_hotkey_zoom",
"Adjust brush size": "canvas_hotkey_adjust",
"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,
hotkeysConfigOpts
);
// Disable functions that are not needed by the user
const hotkeysConfig = disableFunctions(
preHotkeysConfig,
preHotkeysConfig.canvas_disabled_functions
);
let isMoving = false;
let mouseX, mouseY;
let activeElement;
const elements = Object.fromEntries(
Object.keys(elementIDs).map(id => [
id,
gradioApp().querySelector(elementIDs[id])
])
);
const elemData = {};
// Apply functionality to the range inputs. Restore redmask and correct for long images.
const rangeInputs = elements.rangeGroup ?
Array.from(elements.rangeGroup.querySelectorAll("input")) :
[
gradioApp().querySelector("#img2img_width input[type='range']"),
gradioApp().querySelector("#img2img_height input[type='range']")
];
for (const input of rangeInputs) {
input?.addEventListener("input", () => restoreImgRedMask(elements));
}
function applyZoomAndPan(elemId, isExtension = true) {
const targetElement = gradioApp().querySelector(elemId);
if (!targetElement) {
console.log("Element not found");
return;
}
targetElement.style.transformOrigin = "0 0";
elemData[elemId] = {
zoom: 1,
panX: 0,
panY: 0
};
let fullScreenMode = false;
// Create tooltip
function createTooltip() {
const toolTipElemnt =
targetElement.querySelector(".image-container");
const tooltip = document.createElement("div");
tooltip.className = "canvas-tooltip";
// Creating an item of information
const info = document.createElement("i");
info.className = "canvas-tooltip-info";
info.textContent = "";
// Create a container for the contents of the tooltip
const tooltipContent = document.createElement("div");
tooltipContent.className = "canvas-tooltip-content";
// Define an array with hotkey information and their actions
const hotkeysInfo = [
{
configKey: "canvas_hotkey_zoom",
action: "Zoom canvas",
keySuffix: " + wheel"
},
{
configKey: "canvas_hotkey_adjust",
action: "Adjust brush size",
keySuffix: " + wheel"
},
{configKey: "canvas_hotkey_reset", action: "Reset zoom"},
{
configKey: "canvas_hotkey_fullscreen",
action: "Fullscreen mode"
},
{configKey: "canvas_hotkey_move", action: "Move canvas"},
{configKey: "canvas_hotkey_overlap", action: "Overlap"}
];
// 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) {
if (hotkey.disabled) {
continue;
}
const p = document.createElement("p");
p.innerHTML = `<b>${hotkey.key}</b> - ${hotkey.action}`;
tooltipContent.appendChild(p);
}
// Add information and content elements to the tooltip element
tooltip.appendChild(info);
tooltip.appendChild(tooltipContent);
// Add a hint element to the target element
toolTipElemnt.appendChild(tooltip);
}
//Show tool tip if setting enable
if (hotkeysConfig.canvas_show_tooltip) {
createTooltip();
}
// In the course of research, it was found that the tag img is very harmful when zooming and creates white canvases. This hack allows you to almost never think about this problem, it has no effect on webui.
function fixCanvas() {
const activeTab = getActiveTab(elements).textContent.trim();
if (activeTab !== "img2img") {
const img = targetElement.querySelector(`${elemId} img`);
if (img && img.style.display !== "none") {
img.style.display = "none";
img.style.visibility = "hidden";
}
}
}
// Reset the zoom level and pan position of the target element to their initial values
function resetZoom() {
elemData[elemId] = {
zoomLevel: 1,
panX: 0,
panY: 0
};
if (isExtension) {
targetElement.style.overflow = "hidden";
}
targetElement.isZoomed = false;
fixCanvas();
targetElement.style.transform = `scale(${elemData[elemId].zoomLevel}) translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px)`;
const canvas = gradioApp().querySelector(
`${elemId} canvas[key="interface"]`
);
toggleOverlap("off");
fullScreenMode = false;
const closeBtn = targetElement.querySelector("button[aria-label='Remove Image']");
if (closeBtn) {
closeBtn.addEventListener("click", resetZoom);
}
if (canvas && isExtension) {
const parentElement = targetElement.closest('[id^="component-"]');
if (
canvas &&
parseFloat(canvas.style.width) > parentElement.offsetWidth &&
parseFloat(targetElement.style.width) > parentElement.offsetWidth
) {
fitToElement();
return;
}
}
if (
canvas &&
!isExtension &&
parseFloat(canvas.style.width) > 865 &&
parseFloat(targetElement.style.width) > 865
) {
fitToElement();
return;
}
targetElement.style.width = "";
}
// Toggle the zIndex of the target element between two values, allowing it to overlap or be overlapped by other elements
function toggleOverlap(forced = "") {
const zIndex1 = "0";
const zIndex2 = "998";
targetElement.style.zIndex =
targetElement.style.zIndex !== zIndex2 ? zIndex2 : zIndex1;
if (forced === "off") {
targetElement.style.zIndex = zIndex1;
} else if (forced === "on") {
targetElement.style.zIndex = zIndex2;
}
}
// Adjust the brush size based on the deltaY value from a mouse wheel event
function adjustBrushSize(
elemId,
deltaY,
withoutValue = false,
percentage = 5
) {
const input =
gradioApp().querySelector(
`${elemId} input[aria-label='Brush radius']`
) ||
gradioApp().querySelector(
`${elemId} button[aria-label="Use brush"]`
);
if (input) {
input.click();
if (!withoutValue) {
const maxValue =
parseFloat(input.getAttribute("max")) || 100;
const changeAmount = maxValue * (percentage / 100);
const newValue =
parseFloat(input.value) +
(deltaY > 0 ? -changeAmount : changeAmount);
input.value = Math.min(Math.max(newValue, 0), maxValue);
input.dispatchEvent(new Event("change"));
}
}
}
// Reset zoom when uploading a new image
const fileInput = gradioApp().querySelector(
`${elemId} input[type="file"][accept="image/*"].svelte-116rqfv`
);
fileInput.addEventListener("click", resetZoom);
// Update the zoom level and pan position of the target element based on the values of the zoomLevel, panX and panY variables
function updateZoom(newZoomLevel, mouseX, mouseY) {
newZoomLevel = Math.max(0.1, Math.min(newZoomLevel, 15));
elemData[elemId].panX +=
mouseX - (mouseX * newZoomLevel) / elemData[elemId].zoomLevel;
elemData[elemId].panY +=
mouseY - (mouseY * newZoomLevel) / elemData[elemId].zoomLevel;
targetElement.style.transformOrigin = "0 0";
targetElement.style.transform = `translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px) scale(${newZoomLevel})`;
toggleOverlap("on");
if (isExtension) {
targetElement.style.overflow = "visible";
}
return newZoomLevel;
}
// Change the zoom level based on user interaction
function changeZoomLevel(operation, e) {
if (isModifierKey(e, hotkeysConfig.canvas_hotkey_zoom)) {
e.preventDefault();
let zoomPosX, zoomPosY;
let delta = 0.2;
if (elemData[elemId].zoomLevel > 7) {
delta = 0.9;
} else if (elemData[elemId].zoomLevel > 2) {
delta = 0.6;
}
zoomPosX = e.clientX;
zoomPosY = e.clientY;
fullScreenMode = false;
elemData[elemId].zoomLevel = updateZoom(
elemData[elemId].zoomLevel +
(operation === "+" ? delta : -delta),
zoomPosX - targetElement.getBoundingClientRect().left,
zoomPosY - targetElement.getBoundingClientRect().top
);
targetElement.isZoomed = true;
}
}
/**
* This function fits the target element to the screen by calculating
* the required scale and offsets. It also updates the global variables
* zoomLevel, panX, and panY to reflect the new state.
*/
function fitToElement() {
//Reset Zoom
targetElement.style.transform = `translate(${0}px, ${0}px) scale(${1})`;
let parentElement;
if (isExtension) {
parentElement = targetElement.closest('[id^="component-"]');
} else {
parentElement = targetElement.parentElement;
}
// Get element and screen dimensions
const elementWidth = targetElement.offsetWidth;
const elementHeight = targetElement.offsetHeight;
const screenWidth = parentElement.clientWidth;
const screenHeight = parentElement.clientHeight;
// Get element's coordinates relative to the parent element
const elementRect = targetElement.getBoundingClientRect();
const parentRect = parentElement.getBoundingClientRect();
const elementX = elementRect.x - parentRect.x;
// Calculate scale and offsets
const scaleX = screenWidth / elementWidth;
const scaleY = screenHeight / elementHeight;
const scale = Math.min(scaleX, scaleY);
const transformOrigin =
window.getComputedStyle(targetElement).transformOrigin;
const [originX, originY] = transformOrigin.split(" ");
const originXValue = parseFloat(originX);
const originYValue = parseFloat(originY);
const offsetX =
(screenWidth - elementWidth * scale) / 2 -
originXValue * (1 - scale);
const offsetY =
(screenHeight - elementHeight * scale) / 2.5 -
originYValue * (1 - scale);
// Apply scale and offsets to the element
targetElement.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
// Update global variables
elemData[elemId].zoomLevel = scale;
elemData[elemId].panX = offsetX;
elemData[elemId].panY = offsetY;
fullScreenMode = false;
toggleOverlap("off");
}
/**
* This function fits the target element to the screen by calculating
* the required scale and offsets. It also updates the global variables
* zoomLevel, panX, and panY to reflect the new state.
*/
// Fullscreen mode
function fitToScreen() {
const canvas = gradioApp().querySelector(
`${elemId} canvas[key="interface"]`
);
if (!canvas) return;
if (canvas.offsetWidth > 862 || isExtension) {
targetElement.style.width = (canvas.offsetWidth + 2) + "px";
}
if (isExtension) {
targetElement.style.overflow = "visible";
}
if (fullScreenMode) {
resetZoom();
fullScreenMode = false;
return;
}
//Reset Zoom
targetElement.style.transform = `translate(${0}px, ${0}px) scale(${1})`;
// Get scrollbar width to right-align the image
const scrollbarWidth =
window.innerWidth - document.documentElement.clientWidth;
// Get element and screen dimensions
const elementWidth = targetElement.offsetWidth;
const elementHeight = targetElement.offsetHeight;
const screenWidth = window.innerWidth - scrollbarWidth;
const screenHeight = window.innerHeight;
// Get element's coordinates relative to the page
const elementRect = targetElement.getBoundingClientRect();
const elementY = elementRect.y;
const elementX = elementRect.x;
// Calculate scale and offsets
const scaleX = screenWidth / elementWidth;
const scaleY = screenHeight / elementHeight;
const scale = Math.min(scaleX, scaleY);
// Get the current transformOrigin
const computedStyle = window.getComputedStyle(targetElement);
const transformOrigin = computedStyle.transformOrigin;
const [originX, originY] = transformOrigin.split(" ");
const originXValue = parseFloat(originX);
const originYValue = parseFloat(originY);
// Calculate offsets with respect to the transformOrigin
const offsetX =
(screenWidth - elementWidth * scale) / 2 -
elementX -
originXValue * (1 - scale);
const offsetY =
(screenHeight - elementHeight * scale) / 2 -
elementY -
originYValue * (1 - scale);
// Apply scale and offsets to the element
targetElement.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
// Update global variables
elemData[elemId].zoomLevel = scale;
elemData[elemId].panX = offsetX;
elemData[elemId].panY = offsetY;
fullScreenMode = true;
toggleOverlap("on");
}
// Handle keydown events
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 = {
[hotkeysConfig.canvas_hotkey_reset]: resetZoom,
[hotkeysConfig.canvas_hotkey_overlap]: toggleOverlap,
[hotkeysConfig.canvas_hotkey_fullscreen]: fitToScreen
};
const action = hotkeyActions[event.code];
if (action) {
event.preventDefault();
action(event);
}
if (
isModifierKey(event, hotkeysConfig.canvas_hotkey_zoom) ||
isModifierKey(event, hotkeysConfig.canvas_hotkey_adjust)
) {
event.preventDefault();
}
}
// Get Mouse position
function getMousePosition(e) {
mouseX = e.offsetX;
mouseY = e.offsetY;
}
// Simulation of the function to put a long image into the screen.
// We detect if an image has a scroll bar or not, make a fullscreen to reveal the image, then reduce it to fit into the element.
// We hide the image and show it to the user when it is ready.
targetElement.isExpanded = false;
function autoExpand() {
const canvas = document.querySelector(`${elemId} canvas[key="interface"]`);
if (canvas) {
if (hasHorizontalScrollbar(targetElement) && targetElement.isExpanded === false) {
targetElement.style.visibility = "hidden";
setTimeout(() => {
fitToScreen();
resetZoom();
targetElement.style.visibility = "visible";
targetElement.isExpanded = true;
}, 10);
}
}
}
targetElement.addEventListener("mousemove", getMousePosition);
//observers
// Creating an observer with a callback function to handle DOM changes
const observer = new MutationObserver((mutationsList, observer) => {
for (let mutation of mutationsList) {
// If the style attribute of the canvas has changed, by observation it happens only when the picture changes
if (mutation.type === 'attributes' && mutation.attributeName === 'style' &&
mutation.target.tagName.toLowerCase() === 'canvas') {
targetElement.isExpanded = false;
setTimeout(resetZoom, 10);
}
}
});
// Apply auto expand if enabled
if (hotkeysConfig.canvas_auto_expand) {
targetElement.addEventListener("mousemove", autoExpand);
// Set up an observer to track attribute changes
observer.observe(targetElement, {attributes: true, childList: true, subtree: true});
}
// Handle events only inside the targetElement
let isKeyDownHandlerAttached = false;
function handleMouseMove() {
if (!isKeyDownHandlerAttached) {
document.addEventListener("keydown", handleKeyDown);
isKeyDownHandlerAttached = true;
activeElement = elemId;
}
}
function handleMouseLeave() {
if (isKeyDownHandlerAttached) {
document.removeEventListener("keydown", handleKeyDown);
isKeyDownHandlerAttached = false;
activeElement = null;
}
}
// Add mouse event handlers
targetElement.addEventListener("mousemove", handleMouseMove);
targetElement.addEventListener("mouseleave", handleMouseLeave);
// Reset zoom when click on another tab
elements.img2imgTabs.addEventListener("click", resetZoom);
elements.img2imgTabs.addEventListener("click", () => {
// targetElement.style.width = "";
if (parseInt(targetElement.style.width) > 865) {
setTimeout(fitToElement, 0);
}
});
targetElement.addEventListener("wheel", e => {
// change zoom level
const operation = e.deltaY > 0 ? "-" : "+";
changeZoomLevel(operation, e);
// Handle brush size adjustment with ctrl key pressed
if (isModifierKey(e, hotkeysConfig.canvas_hotkey_adjust)) {
e.preventDefault();
// Increase or decrease brush size based on scroll direction
adjustBrushSize(elemId, e.deltaY);
}
});
// 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) {
// 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.ctrlKey && !e.metaKey && isKeyDownHandlerAttached) {
e.preventDefault();
document.activeElement.blur();
isMoving = true;
}
}
}
function handleMoveKeyUp(e) {
if (e.code === hotkeysConfig.canvas_hotkey_move) {
isMoving = false;
}
}
document.addEventListener("keydown", handleMoveKeyDown);
document.addEventListener("keyup", handleMoveKeyUp);
// Detect zoom level and update the pan speed.
function updatePanPosition(movementX, movementY) {
let panSpeed = 2;
if (elemData[elemId].zoomLevel > 8) {
panSpeed = 3.5;
}
elemData[elemId].panX += movementX * panSpeed;
elemData[elemId].panY += movementY * panSpeed;
// Delayed redraw of an element
requestAnimationFrame(() => {
targetElement.style.transform = `translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px) scale(${elemData[elemId].zoomLevel})`;
toggleOverlap("on");
});
}
function handleMoveByKey(e) {
if (isMoving && elemId === activeElement) {
updatePanPosition(e.movementX, e.movementY);
targetElement.style.pointerEvents = "none";
if (isExtension) {
targetElement.style.overflow = "visible";
}
} else {
targetElement.style.pointerEvents = "auto";
}
}
// Prevents sticking to the mouse
window.onblur = function() {
isMoving = false;
};
// Checks for extension
function checkForOutBox() {
const parentElement = targetElement.closest('[id^="component-"]');
if (parentElement.offsetWidth < targetElement.offsetWidth && !targetElement.isExpanded) {
resetZoom();
targetElement.isExpanded = true;
}
if (parentElement.offsetWidth < targetElement.offsetWidth && elemData[elemId].zoomLevel == 1) {
resetZoom();
}
if (parentElement.offsetWidth < targetElement.offsetWidth && targetElement.offsetWidth * elemData[elemId].zoomLevel > parentElement.offsetWidth && elemData[elemId].zoomLevel < 1 && !targetElement.isZoomed) {
resetZoom();
}
}
if (isExtension) {
targetElement.addEventListener("mousemove", checkForOutBox);
}
window.addEventListener('resize', (e) => {
resetZoom();
if (isExtension) {
targetElement.isExpanded = false;
targetElement.isZoomed = false;
}
});
gradioApp().addEventListener("mousemove", handleMoveByKey);
}
applyZoomAndPan(elementIDs.sketch, false);
applyZoomAndPan(elementIDs.inpaint, false);
applyZoomAndPan(elementIDs.inpaintSketch, false);
// Make the function global so that other extensions can take advantage of this solution
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"]);
});
@@ -0,0 +1,15 @@
import gradio as gr
from modules import shared
shared.options_templates.update(shared.options_section(('canvas_hotkey', "Canvas Hotkeys"), {
"canvas_hotkey_zoom": shared.OptionInfo("Alt", "Zoom canvas", gr.Radio, {"choices": ["Shift","Ctrl", "Alt"]}).info("If you choose 'Shift' you cannot scroll horizontally, 'Alt' can cause a little trouble in firefox"),
"canvas_hotkey_adjust": shared.OptionInfo("Ctrl", "Adjust brush size", gr.Radio, {"choices": ["Shift","Ctrl", "Alt"]}).info("If you choose 'Shift' you cannot scroll horizontally, 'Alt' can cause a little trouble in firefox"),
"canvas_hotkey_move": shared.OptionInfo("F", "Moving the canvas").info("To work correctly in firefox, turn off 'Automatically search the page text when typing' in the browser settings"),
"canvas_hotkey_fullscreen": shared.OptionInfo("S", "Fullscreen Mode, maximizes the picture so that it fits into the screen and stretches it to its full width "),
"canvas_hotkey_reset": shared.OptionInfo("R", "Reset zoom and canvas positon"),
"canvas_hotkey_overlap": shared.OptionInfo("O", "Toggle overlap").info("Technical button, neededs for testing"),
"canvas_show_tooltip": shared.OptionInfo(True, "Enable tooltip on the canvas"),
"canvas_auto_expand": shared.OptionInfo(True, "Automatically expands an image that does not fit completely in the canvas area, similar to manually pressing the S and R buttons"),
"canvas_blur_prompt": shared.OptionInfo(False, "Take the focus off the prompt when working with a canvas"),
"canvas_disabled_functions": shared.OptionInfo(["Overlap"], "Disable function that you don't use", gr.CheckboxGroup, {"choices": ["Zoom","Adjust brush size", "Moving canvas","Fullscreen","Reset Zoom","Overlap"]}),
}))
@@ -0,0 +1,66 @@
.canvas-tooltip-info {
position: absolute;
top: 10px;
left: 10px;
cursor: help;
background-color: rgba(0, 0, 0, 0.3);
width: 20px;
height: 20px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
z-index: 100;
}
.canvas-tooltip-info::after {
content: '';
display: block;
width: 2px;
height: 7px;
background-color: white;
margin-top: 2px;
}
.canvas-tooltip-info::before {
content: '';
display: block;
width: 2px;
height: 2px;
background-color: white;
}
.canvas-tooltip-content {
display: none;
background-color: #f9f9f9;
color: #333;
border: 1px solid #ddd;
padding: 15px;
position: absolute;
top: 40px;
left: 10px;
width: 250px;
font-size: 16px;
opacity: 0;
border-radius: 8px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 100;
}
.canvas-tooltip:hover .canvas-tooltip-content {
display: block;
animation: fadeIn 0.5s;
opacity: 1;
}
@keyframes fadeIn {
from {opacity: 0;}
to {opacity: 1;}
}
.styler {
overflow:inherit !important;
}
@@ -0,0 +1,74 @@
import math
import gradio as gr
from modules import scripts, shared, ui_components, ui_settings, generation_parameters_copypaste
from modules.ui_components import FormColumn
class ExtraOptionsSection(scripts.Script):
section = "extra_options"
def __init__(self):
self.comps = None
self.setting_names = None
def title(self):
return "Extra options"
def show(self, is_img2img):
return scripts.AlwaysVisible
def ui(self, is_img2img):
self.comps = []
self.setting_names = []
self.infotext_fields = []
extra_options = shared.opts.extra_options_img2img if is_img2img else shared.opts.extra_options_txt2img
mapping = {k: v for v, k in generation_parameters_copypaste.infotext_to_setting_name_mapping}
with gr.Blocks() as interface:
with gr.Accordion("Options", open=False) if shared.opts.extra_options_accordion and extra_options else gr.Group():
row_count = math.ceil(len(extra_options) / shared.opts.extra_options_cols)
for row in range(row_count):
with gr.Row():
for col in range(shared.opts.extra_options_cols):
index = row * shared.opts.extra_options_cols + col
if index >= len(extra_options):
break
setting_name = extra_options[index]
with FormColumn():
comp = ui_settings.create_setting_component(setting_name)
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():
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)
return self.comps
def before_process(self, p, *args):
for name, value in zip(self.setting_names, args):
if name not in p.override_settings:
p.override_settings[name] = value
shared.options_templates.update(shared.options_section(('ui', "User interface"), {
"extra_options_txt2img": shared.OptionInfo([], "Options in main UI - 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([], "Options in main UI - 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, "Options in main UI - number of columns", gr.Number, {"precision": 0}).needs_reload_ui(),
"extra_options_accordion": shared.OptionInfo(False, "Options in main UI - place into an accordion").needs_reload_ui()
}))
@@ -0,0 +1,32 @@
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() {
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();
});
@@ -1,110 +1,42 @@
// Stable Diffusion WebUI - Bracket checker // Stable Diffusion WebUI - Bracket checker
// Version 1.0 // By Hingashi no Florin/Bwin4L & @akx
// By Hingashi no Florin/Bwin4L
// Counts open and closed brackets (round, square, curly) in the prompt and negative prompt text boxes in the txt2img and img2img tabs. // Counts open and closed brackets (round, square, curly) in the prompt and negative prompt text boxes in the txt2img and img2img tabs.
// If there's a mismatch, the keyword counter turns red and if you hover on it, a tooltip tells you what's wrong. // If there's a mismatch, the keyword counter turns red and if you hover on it, a tooltip tells you what's wrong.
function checkBrackets(evt, textArea, counterElt) { function checkBrackets(textArea, counterElt) {
errorStringParen = '(...) - Different number of opening and closing parentheses detected.\n'; var counts = {};
errorStringSquare = '[...] - Different number of opening and closing square brackets detected.\n'; (textArea.value.match(/[(){}[\]]/g) || []).forEach(bracket => {
errorStringCurly = '{...} - Different number of opening and closing curly brackets detected.\n'; counts[bracket] = (counts[bracket] || 0) + 1;
openBracketRegExp = /\(/g;
closeBracketRegExp = /\)/g;
openSquareBracketRegExp = /\[/g;
closeSquareBracketRegExp = /\]/g;
openCurlyBracketRegExp = /\{/g;
closeCurlyBracketRegExp = /\}/g;
totalOpenBracketMatches = 0;
totalCloseBracketMatches = 0;
totalOpenSquareBracketMatches = 0;
totalCloseSquareBracketMatches = 0;
totalOpenCurlyBracketMatches = 0;
totalCloseCurlyBracketMatches = 0;
openBracketMatches = textArea.value.match(openBracketRegExp);
if(openBracketMatches) {
totalOpenBracketMatches = openBracketMatches.length;
}
closeBracketMatches = textArea.value.match(closeBracketRegExp);
if(closeBracketMatches) {
totalCloseBracketMatches = closeBracketMatches.length;
}
openSquareBracketMatches = textArea.value.match(openSquareBracketRegExp);
if(openSquareBracketMatches) {
totalOpenSquareBracketMatches = openSquareBracketMatches.length;
}
closeSquareBracketMatches = textArea.value.match(closeSquareBracketRegExp);
if(closeSquareBracketMatches) {
totalCloseSquareBracketMatches = closeSquareBracketMatches.length;
}
openCurlyBracketMatches = textArea.value.match(openCurlyBracketRegExp);
if(openCurlyBracketMatches) {
totalOpenCurlyBracketMatches = openCurlyBracketMatches.length;
}
closeCurlyBracketMatches = textArea.value.match(closeCurlyBracketRegExp);
if(closeCurlyBracketMatches) {
totalCloseCurlyBracketMatches = closeCurlyBracketMatches.length;
}
if(totalOpenBracketMatches != totalCloseBracketMatches) {
if(!counterElt.title.includes(errorStringParen)) {
counterElt.title += errorStringParen;
}
} else {
counterElt.title = counterElt.title.replace(errorStringParen, '');
}
if(totalOpenSquareBracketMatches != totalCloseSquareBracketMatches) {
if(!counterElt.title.includes(errorStringSquare)) {
counterElt.title += errorStringSquare;
}
} else {
counterElt.title = counterElt.title.replace(errorStringSquare, '');
}
if(totalOpenCurlyBracketMatches != totalCloseCurlyBracketMatches) {
if(!counterElt.title.includes(errorStringCurly)) {
counterElt.title += errorStringCurly;
}
} else {
counterElt.title = counterElt.title.replace(errorStringCurly, '');
}
if(counterElt.title != '') {
counterElt.classList.add('error');
} else {
counterElt.classList.remove('error');
}
}
function setupBracketChecking(id_prompt, id_counter){
var textarea = gradioApp().querySelector("#" + id_prompt + " > label > textarea");
var counter = gradioApp().getElementById(id_counter)
textarea.addEventListener("input", function(evt){
checkBrackets(evt, textarea, counter)
}); });
var errors = [];
function checkPair(open, close, kind) {
if (counts[open] !== counts[close]) {
errors.push(
`${open}...${close} - Detected ${counts[open] || 0} opening and ${counts[close] || 0} closing ${kind}.`
);
}
}
checkPair('(', ')', 'round brackets');
checkPair('[', ']', 'square brackets');
checkPair('{', '}', 'curly brackets');
counterElt.title = errors.join('\n');
counterElt.classList.toggle('error', errors.length !== 0);
} }
var shadowRootLoaded = setInterval(function() { function setupBracketChecking(id_prompt, id_counter) {
var shadowRoot = document.querySelector('gradio-app').shadowRoot; var textarea = gradioApp().querySelector("#" + id_prompt + " > label > textarea");
if(! shadowRoot) return false; var counter = gradioApp().getElementById(id_counter);
var shadowTextArea = shadowRoot.querySelectorAll('#txt2img_prompt > label > textarea'); if (textarea && counter) {
if(shadowTextArea.length < 1) return false; textarea.addEventListener("input", () => checkBrackets(textarea, counter));
}
}
clearInterval(shadowRootLoaded); onUiLoaded(function() {
setupBracketChecking('txt2img_prompt', 'txt2img_token_counter');
setupBracketChecking('txt2img_prompt', 'txt2img_token_counter') setupBracketChecking('txt2img_neg_prompt', 'txt2img_negative_token_counter');
setupBracketChecking('txt2img_neg_prompt', 'txt2img_negative_token_counter') setupBracketChecking('img2img_prompt', 'img2img_token_counter');
setupBracketChecking('img2img_prompt', 'imgimg_token_counter') setupBracketChecking('img2img_neg_prompt', 'img2img_negative_token_counter');
setupBracketChecking('img2img_neg_prompt', 'img2img_negative_token_counter') });
}, 1000);
+8 -5
View File
@@ -1,11 +1,14 @@
<div class='card' {preview_html} onclick={card_clicked}> <div class='card' style={style} onclick={card_clicked} data-name="{name}" {sort_keys}>
{background_image}
<div class="button-row">
{metadata_button}
{edit_button}
</div>
<div class='actions'> <div class='actions'>
<div class='additional'> <div class='additional'>
<ul> <span style="display:none" class='search_term{search_only}'>{search_term}</span>
<a href="#" title="replace preview image with currently selected in gallery" onclick={save_card_preview}>replace preview</a>
</ul>
</div> </div>
<span class='name'>{name}</span> <span class='name'>{name}</span>
<span class='description'>{description}</span>
</div> </div>
</div> </div>
+3 -1
View File
@@ -1,10 +1,12 @@
<div> <div>
<a href="/docs">API</a> <a href="{api_docs}">API</a>
 •   • 
<a href="https://github.com/AUTOMATIC1111/stable-diffusion-webui">Github</a> <a href="https://github.com/AUTOMATIC1111/stable-diffusion-webui">Github</a>
 •   • 
<a href="https://gradio.app">Gradio</a> <a href="https://gradio.app">Gradio</a>
 •   • 
<a href="#" onclick="showProfile('./internal/profile-startup'); return false;">Startup profile</a>
 • 
<a href="/" onclick="javascript:gradioApp().getElementById('settings_restart_gradio').click(); return false">Reload UI</a> <a href="/" onclick="javascript:gradioApp().getElementById('settings_restart_gradio').click(); return false">Reload UI</a>
</div> </div>
<br /> <br />
-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

+271
View File
@@ -417,3 +417,274 @@ 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/huggingface/diffusers/blob/c7da8fd23359a22d0df2741688b5b4f33c26df21/LICENSE">Scaled Dot Product Attention</a></h2>
<small>Some small amounts of code borrowed and reworked.</small>
<pre>
Copyright 2023 The HuggingFace Team. All rights reserved.
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.
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 [yyyy] [name of copyright owner]
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/explosion/curated-transformers/blob/main/LICENSE">Curated transformers</a></h2>
<small>The MPS workaround for nn.Linear on macOS 13.2.X is based on the MPS workaround for nn.Linear created by danieldk for Curated transformers</small>
<pre>
The MIT License (MIT)
Copyright (C) 2021 ExplosionAI GmbH
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/madebyollin/taesd/blob/main/LICENSE">TAESD</a></h2>
<small>Tiny AutoEncoder for Stable Diffusion option for live previews</small>
<pre>
MIT License
Copyright (c) 2023 Ollin Boer Bohan
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>
+113 -113
View File
@@ -1,113 +1,113 @@
let currentWidth = null; let currentWidth = null;
let currentHeight = null; let currentHeight = null;
let arFrameTimeout = setTimeout(function(){},0); let arFrameTimeout = setTimeout(function() {}, 0);
function dimensionChange(e, is_width, is_height){ function dimensionChange(e, is_width, is_height) {
if(is_width){ if (is_width) {
currentWidth = e.target.value*1.0 currentWidth = e.target.value * 1.0;
} }
if(is_height){ if (is_height) {
currentHeight = e.target.value*1.0 currentHeight = e.target.value * 1.0;
} }
var inImg2img = Boolean(gradioApp().querySelector("button.rounded-t-lg.border-gray-200")) var inImg2img = gradioApp().querySelector("#tab_img2img").style.display == "block";
if(!inImg2img){ if (!inImg2img) {
return; return;
} }
var targetElement = null; var targetElement = null;
var tabIndex = get_tab_index('mode_img2img') var tabIndex = get_tab_index('mode_img2img');
if(tabIndex == 0){ // img2img if (tabIndex == 0) { // img2img
targetElement = gradioApp().querySelector('div[data-testid=image] img'); targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img');
} else if(tabIndex == 1){ //Sketch } else if (tabIndex == 1) { //Sketch
targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img'); targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img');
} else if(tabIndex == 2){ // Inpaint } else if (tabIndex == 2) { // Inpaint
targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img'); targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img');
} else if(tabIndex == 3){ // Inpaint sketch } else if (tabIndex == 3) { // Inpaint sketch
targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img'); targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img');
} }
if(targetElement){ if (targetElement) {
var arPreviewRect = gradioApp().querySelector('#imageARPreview'); var arPreviewRect = gradioApp().querySelector('#imageARPreview');
if(!arPreviewRect){ if (!arPreviewRect) {
arPreviewRect = document.createElement('div') arPreviewRect = document.createElement('div');
arPreviewRect.id = "imageARPreview"; arPreviewRect.id = "imageARPreview";
gradioApp().getRootNode().appendChild(arPreviewRect) gradioApp().appendChild(arPreviewRect);
} }
var viewportOffset = targetElement.getBoundingClientRect(); var viewportOffset = targetElement.getBoundingClientRect();
viewportscale = Math.min( targetElement.clientWidth/targetElement.naturalWidth, targetElement.clientHeight/targetElement.naturalHeight ) var viewportscale = Math.min(targetElement.clientWidth / targetElement.naturalWidth, targetElement.clientHeight / targetElement.naturalHeight);
scaledx = targetElement.naturalWidth*viewportscale var scaledx = targetElement.naturalWidth * viewportscale;
scaledy = targetElement.naturalHeight*viewportscale var scaledy = targetElement.naturalHeight * viewportscale;
cleintRectTop = (viewportOffset.top+window.scrollY) var cleintRectTop = (viewportOffset.top + window.scrollY);
cleintRectLeft = (viewportOffset.left+window.scrollX) var cleintRectLeft = (viewportOffset.left + window.scrollX);
cleintRectCentreY = cleintRectTop + (targetElement.clientHeight/2) var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2);
cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth/2) var cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth / 2);
viewRectTop = cleintRectCentreY-(scaledy/2) var arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight);
viewRectLeft = cleintRectCentreX-(scaledx/2) var arscaledx = currentWidth * arscale;
arRectWidth = scaledx var arscaledy = currentHeight * arscale;
arRectHeight = scaledy
var arRectTop = cleintRectCentreY - (arscaledy / 2);
arscale = Math.min( arRectWidth/currentWidth, arRectHeight/currentHeight ) var arRectLeft = cleintRectCentreX - (arscaledx / 2);
arscaledx = currentWidth*arscale var arRectWidth = arscaledx;
arscaledy = currentHeight*arscale var arRectHeight = arscaledy;
arRectTop = cleintRectCentreY-(arscaledy/2) arPreviewRect.style.top = arRectTop + 'px';
arRectLeft = cleintRectCentreX-(arscaledx/2) arPreviewRect.style.left = arRectLeft + 'px';
arRectWidth = arscaledx arPreviewRect.style.width = arRectWidth + 'px';
arRectHeight = arscaledy arPreviewRect.style.height = arRectHeight + 'px';
arPreviewRect.style.top = arRectTop+'px'; clearTimeout(arFrameTimeout);
arPreviewRect.style.left = arRectLeft+'px'; arFrameTimeout = setTimeout(function() {
arPreviewRect.style.width = arRectWidth+'px'; arPreviewRect.style.display = 'none';
arPreviewRect.style.height = arRectHeight+'px'; }, 2000);
clearTimeout(arFrameTimeout); arPreviewRect.style.display = 'block';
arFrameTimeout = setTimeout(function(){
arPreviewRect.style.display = 'none'; }
},2000);
}
arPreviewRect.style.display = 'block';
} onAfterUiUpdate(function() {
var arPreviewRect = gradioApp().querySelector('#imageARPreview');
} if (arPreviewRect) {
arPreviewRect.style.display = 'none';
}
onUiUpdate(function(){ var tabImg2img = gradioApp().querySelector("#tab_img2img");
var arPreviewRect = gradioApp().querySelector('#imageARPreview'); if (tabImg2img) {
if(arPreviewRect){ var inImg2img = tabImg2img.style.display == "block";
arPreviewRect.style.display = 'none'; if (inImg2img) {
} let inputs = gradioApp().querySelectorAll('input');
var inImg2img = Boolean(gradioApp().querySelector("button.rounded-t-lg.border-gray-200")) inputs.forEach(function(e) {
if(inImg2img){ var is_width = e.parentElement.id == "img2img_width";
let inputs = gradioApp().querySelectorAll('input'); var is_height = e.parentElement.id == "img2img_height";
inputs.forEach(function(e){
var is_width = e.parentElement.id == "img2img_width" if ((is_width || is_height) && !e.classList.contains('scrollwatch')) {
var is_height = e.parentElement.id == "img2img_height" e.addEventListener('input', function(e) {
dimensionChange(e, is_width, is_height);
if((is_width || is_height) && !e.classList.contains('scrollwatch')){ });
e.addEventListener('input', function(e){dimensionChange(e, is_width, is_height)} ) e.classList.add('scrollwatch');
e.classList.add('scrollwatch') }
} if (is_width) {
if(is_width){ currentWidth = e.value * 1.0;
currentWidth = e.value*1.0 }
} if (is_height) {
if(is_height){ currentHeight = e.value * 1.0;
currentHeight = e.value*1.0 }
} });
}) }
} }
}); });
+176 -177
View File
@@ -1,177 +1,176 @@
contextMenuInit = function(){ var contextMenuInit = function() {
let eventListenerApplied=false; let eventListenerApplied = false;
let menuSpecs = new Map(); let menuSpecs = new Map();
const uid = function(){ const uid = function() {
return Date.now().toString(36) + Math.random().toString(36).substr(2); return Date.now().toString(36) + Math.random().toString(36).substring(2);
} };
function showContextMenu(event,element,menuEntries){ function showContextMenu(event, element, menuEntries) {
let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; 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();
} }
let tabButton = uiCurrentTab let baseStyle = window.getComputedStyle(uiCurrentTab);
let baseStyle = window.getComputedStyle(tabButton)
const contextMenu = document.createElement('nav');
const contextMenu = document.createElement('nav') contextMenu.id = "context-menu";
contextMenu.id = "context-menu" 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 = posy+'px' contextMenu.style.left = posx + 'px';
contextMenu.style.left = posx+'px'
const contextMenuList = document.createElement('ul');
const contextMenuList = document.createElement('ul') contextMenuList.className = 'context-menu-items';
contextMenuList.className = 'context-menu-items'; contextMenu.append(contextMenuList);
contextMenu.append(contextMenuList);
menuEntries.forEach(function(entry) {
menuEntries.forEach(function(entry){ let contextMenuEntry = document.createElement('a');
let contextMenuEntry = document.createElement('a') contextMenuEntry.innerHTML = entry['name'];
contextMenuEntry.innerHTML = entry['name'] contextMenuEntry.addEventListener("click", function() {
contextMenuEntry.addEventListener("click", function(e) { entry['func']();
entry['func'](); });
}) contextMenuList.append(contextMenuEntry);
contextMenuList.append(contextMenuEntry);
});
})
gradioApp().appendChild(contextMenu);
gradioApp().getRootNode().appendChild(contextMenu)
let menuWidth = contextMenu.offsetWidth + 4;
let menuWidth = contextMenu.offsetWidth + 4; let menuHeight = contextMenu.offsetHeight + 4;
let menuHeight = contextMenu.offsetHeight + 4;
let windowWidth = window.innerWidth;
let windowWidth = window.innerWidth; let windowHeight = window.innerHeight;
let windowHeight = window.innerHeight;
if ((windowWidth - posx) < menuWidth) {
if ( (windowWidth - posx) < menuWidth ) { contextMenu.style.left = windowWidth - menuWidth + "px";
contextMenu.style.left = windowWidth - menuWidth + "px"; }
}
if ((windowHeight - posy) < menuHeight) {
if ( (windowHeight - posy) < menuHeight ) { contextMenu.style.top = windowHeight - menuHeight + "px";
contextMenu.style.top = windowHeight - menuHeight + "px"; }
}
}
}
function appendContextMenuOption(targetElementSelector, entryName, entryFunction) {
function appendContextMenuOption(targetElementSelector,entryName,entryFunction){
var currentItems = menuSpecs.get(targetElementSelector);
currentItems = menuSpecs.get(targetElementSelector)
if (!currentItems) {
if(!currentItems){ currentItems = [];
currentItems = [] menuSpecs.set(targetElementSelector, currentItems);
menuSpecs.set(targetElementSelector,currentItems); }
} let newItem = {
let newItem = {'id':targetElementSelector+'_'+uid(), id: targetElementSelector + '_' + uid(),
'name':entryName, name: entryName,
'func':entryFunction, func: entryFunction,
'isNew':true} isNew: true
};
currentItems.push(newItem)
return newItem['id'] currentItems.push(newItem);
} return newItem['id'];
}
function removeContextMenuOption(uid){
menuSpecs.forEach(function(v,k) { function removeContextMenuOption(uid) {
let index = -1 menuSpecs.forEach(function(v) {
v.forEach(function(e,ei){if(e['id']==uid){index=ei}}) let index = -1;
if(index>=0){ v.forEach(function(e, ei) {
v.splice(index, 1); if (e['id'] == uid) {
} index = ei;
}) }
} });
if (index >= 0) {
function addContextMenuEventListener(){ v.splice(index, 1);
if(eventListenerApplied){ }
return; });
} }
gradioApp().addEventListener("click", function(e) {
let source = e.composedPath()[0] function addContextMenuEventListener() {
if(source.id && source.id.indexOf('check_progress')>-1){ if (eventListenerApplied) {
return return;
} }
gradioApp().addEventListener("click", function(e) {
let oldMenu = gradioApp().querySelector('#context-menu') if (!e.isTrusted) {
if(oldMenu){ return;
oldMenu.remove() }
}
}); let oldMenu = gradioApp().querySelector('#context-menu');
gradioApp().addEventListener("contextmenu", function(e) { if (oldMenu) {
let oldMenu = gradioApp().querySelector('#context-menu') oldMenu.remove();
if(oldMenu){ }
oldMenu.remove() });
} gradioApp().addEventListener("contextmenu", function(e) {
menuSpecs.forEach(function(v,k) { let oldMenu = gradioApp().querySelector('#context-menu');
if(e.composedPath()[0].matches(k)){ if (oldMenu) {
showContextMenu(e,e.composedPath()[0],v) oldMenu.remove();
e.preventDefault() }
return menuSpecs.forEach(function(v, k) {
} if (e.composedPath()[0].matches(k)) {
}) showContextMenu(e, e.composedPath()[0], v);
}); e.preventDefault();
eventListenerApplied=true }
});
} });
eventListenerApplied = true;
return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener]
} }
initResponse = contextMenuInit(); return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener];
appendContextMenuOption = initResponse[0]; };
removeContextMenuOption = initResponse[1];
addContextMenuEventListener = initResponse[2]; var initResponse = contextMenuInit();
var appendContextMenuOption = initResponse[0];
(function(){ var removeContextMenuOption = initResponse[1];
//Start example Context Menu Items var addContextMenuEventListener = initResponse[2];
let generateOnRepeat = function(genbuttonid,interruptbuttonid){
let genbutton = gradioApp().querySelector(genbuttonid); (function() {
let interruptbutton = gradioApp().querySelector(interruptbuttonid); //Start example Context Menu Items
if(!interruptbutton.offsetParent){ let generateOnRepeat = function(genbuttonid, interruptbuttonid) {
genbutton.click(); let genbutton = gradioApp().querySelector(genbuttonid);
} let interruptbutton = gradioApp().querySelector(interruptbuttonid);
clearInterval(window.generateOnRepeatInterval) if (!interruptbutton.offsetParent) {
window.generateOnRepeatInterval = setInterval(function(){ genbutton.click();
if(!interruptbutton.offsetParent){ }
genbutton.click(); clearInterval(window.generateOnRepeatInterval);
} window.generateOnRepeatInterval = setInterval(function() {
}, if (!interruptbutton.offsetParent) {
500) genbutton.click();
} }
},
appendContextMenuOption('#txt2img_generate','Generate forever',function(){ 500);
generateOnRepeat('#txt2img_generate','#txt2img_interrupt'); };
})
appendContextMenuOption('#img2img_generate','Generate forever',function(){ let generateOnRepeat_txt2img = function() {
generateOnRepeat('#img2img_generate','#img2img_interrupt'); generateOnRepeat('#txt2img_generate', '#txt2img_interrupt');
}) };
let cancelGenerateForever = function(){ let generateOnRepeat_img2img = function() {
clearInterval(window.generateOnRepeatInterval) generateOnRepeat('#img2img_generate', '#img2img_interrupt');
} };
appendContextMenuOption('#txt2img_interrupt','Cancel generate forever',cancelGenerateForever) appendContextMenuOption('#txt2img_generate', 'Generate forever', generateOnRepeat_txt2img);
appendContextMenuOption('#txt2img_generate', 'Cancel generate forever',cancelGenerateForever) appendContextMenuOption('#txt2img_interrupt', 'Generate forever', generateOnRepeat_txt2img);
appendContextMenuOption('#img2img_interrupt','Cancel generate forever',cancelGenerateForever) appendContextMenuOption('#img2img_generate', 'Generate forever', generateOnRepeat_img2img);
appendContextMenuOption('#img2img_generate', 'Cancel generate forever',cancelGenerateForever) appendContextMenuOption('#img2img_interrupt', 'Generate forever', generateOnRepeat_img2img);
appendContextMenuOption('#roll','Roll three', let cancelGenerateForever = function() {
function(){ clearInterval(window.generateOnRepeatInterval);
let rollbutton = get_uiCurrentTabContent().querySelector('#roll'); };
setTimeout(function(){rollbutton.click()},100)
setTimeout(function(){rollbutton.click()},200) appendContextMenuOption('#txt2img_interrupt', 'Cancel generate forever', cancelGenerateForever);
setTimeout(function(){rollbutton.click()},300) appendContextMenuOption('#txt2img_generate', 'Cancel generate forever', cancelGenerateForever);
} appendContextMenuOption('#img2img_interrupt', 'Cancel generate forever', cancelGenerateForever);
) appendContextMenuOption('#img2img_generate', 'Cancel generate forever', cancelGenerateForever);
})();
//End example Context Menu Items })();
//End example Context Menu Items
onUiUpdate(function(){
addContextMenuEventListener() onAfterUiUpdate(addContextMenuEventListener);
});
+68 -35
View File
@@ -1,11 +1,11 @@
// allows drag-dropping files into gradio image elements, and also pasting images from clipboard // allows drag-dropping files into gradio image elements, and also pasting images from clipboard
function isValidImageList( files ) { function isValidImageList(files) {
return files && files?.length === 1 && ['image/png', 'image/gif', 'image/jpeg'].includes(files[0].type); return files && files?.length === 1 && ['image/png', 'image/gif', 'image/jpeg'].includes(files[0].type);
} }
function dropReplaceImage( imgWrap, files ) { function dropReplaceImage(imgWrap, files) {
if ( ! isValidImageList( files ) ) { if (!isValidImageList(files)) {
return; return;
} }
@@ -14,46 +14,61 @@ function dropReplaceImage( imgWrap, files ) {
imgWrap.querySelector('.modify-upload button + button, .touch-none + div button + button')?.click(); imgWrap.querySelector('.modify-upload button + button, .touch-none + div button + button')?.click();
const callback = () => { const callback = () => {
const fileInput = imgWrap.querySelector('input[type="file"]'); const fileInput = imgWrap.querySelector('input[type="file"]');
if ( fileInput ) { if (fileInput) {
if ( files.length === 0 ) { if (files.length === 0) {
files = new DataTransfer(); files = new DataTransfer();
files.items.add(tmpFile); files.items.add(tmpFile);
fileInput.files = files.files; fileInput.files = files.files;
} else { } else {
fileInput.files = files; fileInput.files = files;
} }
fileInput.dispatchEvent(new Event('change')); fileInput.dispatchEvent(new Event('change'));
} }
}; };
if ( imgWrap.closest('#pnginfo_image') ) { if (imgWrap.closest('#pnginfo_image')) {
// special treatment for PNG Info tab, wait for fetch request to finish // special treatment for PNG Info tab, wait for fetch request to finish
const oldFetch = window.fetch; const oldFetch = window.fetch;
window.fetch = async (input, options) => { window.fetch = async(input, options) => {
const response = await oldFetch(input, options); const response = await oldFetch(input, options);
if ( 'api/predict/' === input ) { if ('api/predict/' === input) {
const content = await response.text(); const content = await response.text();
window.fetch = oldFetch; window.fetch = oldFetch;
window.requestAnimationFrame( () => callback() ); window.requestAnimationFrame(() => callback());
return new Response(content, { return new Response(content, {
status: response.status, status: response.status,
statusText: response.statusText, statusText: response.statusText,
headers: response.headers headers: response.headers
}) });
} }
return response; return response;
}; };
} else { } else {
window.requestAnimationFrame( () => callback() ); window.requestAnimationFrame(() => callback());
} }
} }
function eventHasFiles(e) {
if (!e.dataTransfer || !e.dataTransfer.files) return false;
if (e.dataTransfer.files.length > 0) return true;
if (e.dataTransfer.items.length > 0 && e.dataTransfer.items[0].kind == "file") return true;
return false;
}
function dragDropTargetIsPrompt(target) {
if (target?.placeholder && target?.placeholder.indexOf("Prompt") >= 0) return true;
if (target?.parentNode?.parentNode?.className?.indexOf("prompt") > 0) return true;
return false;
}
window.document.addEventListener('dragover', e => { window.document.addEventListener('dragover', e => {
const target = e.composedPath()[0]; const target = e.composedPath()[0];
const imgWrap = target.closest('[data-testid="image"]'); if (!eventHasFiles(e)) return;
if ( !imgWrap && target.placeholder && target.placeholder.indexOf("Prompt") == -1) {
return; var targetImage = target.closest('[data-testid="image"]');
} if (!dragDropTargetIsPrompt(target) && !targetImage) return;
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
e.dataTransfer.dropEffect = 'copy'; e.dataTransfer.dropEffect = 'copy';
@@ -61,37 +76,55 @@ window.document.addEventListener('dragover', e => {
window.document.addEventListener('drop', e => { window.document.addEventListener('drop', e => {
const target = e.composedPath()[0]; const target = e.composedPath()[0];
if (target.placeholder.indexOf("Prompt") == -1) { if (!eventHasFiles(e)) return;
if (dragDropTargetIsPrompt(target)) {
e.stopPropagation();
e.preventDefault();
let prompt_target = get_tab_index('tabs') == 1 ? "img2img_prompt_image" : "txt2img_prompt_image";
const imgParent = gradioApp().getElementById(prompt_target);
const files = e.dataTransfer.files;
const fileInput = imgParent.querySelector('input[type="file"]');
if (fileInput) {
fileInput.files = files;
fileInput.dispatchEvent(new Event('change'));
}
}
var targetImage = target.closest('[data-testid="image"]');
if (targetImage) {
e.stopPropagation();
e.preventDefault();
const files = e.dataTransfer.files;
dropReplaceImage(targetImage, files);
return; return;
} }
const imgWrap = target.closest('[data-testid="image"]');
if ( !imgWrap ) {
return;
}
e.stopPropagation();
e.preventDefault();
const files = e.dataTransfer.files;
dropReplaceImage( imgWrap, files );
}); });
window.addEventListener('paste', e => { window.addEventListener('paste', e => {
const files = e.clipboardData.files; const files = e.clipboardData.files;
if ( ! isValidImageList( files ) ) { if (!isValidImageList(files)) {
return; return;
} }
const visibleImageFields = [...gradioApp().querySelectorAll('[data-testid="image"]')] const visibleImageFields = [...gradioApp().querySelectorAll('[data-testid="image"]')]
.filter(el => uiElementIsVisible(el)); .filter(el => uiElementIsVisible(el))
if ( ! visibleImageFields.length ) { .sort((a, b) => uiElementInSight(b) - uiElementInSight(a));
if (!visibleImageFields.length) {
return; return;
} }
const firstFreeImageField = visibleImageFields const firstFreeImageField = visibleImageFields
.filter(el => el.querySelector('input[type=file]'))?.[0]; .filter(el => !el.querySelector('img'))?.[0];
dropReplaceImage( dropReplaceImage(
firstFreeImageField ? firstFreeImageField ?
firstFreeImageField : firstFreeImageField :
visibleImageFields[visibleImageFields.length - 1] visibleImageFields[visibleImageFields.length - 1]
, files ); , files
);
}); });
+115 -96
View File
@@ -1,96 +1,115 @@
function keyupEditAttention(event){ function keyupEditAttention(event) {
let target = event.originalTarget || event.composedPath()[0]; let target = event.originalTarget || event.composedPath()[0];
if (!target.matches("[id*='_toprow'] textarea.gr-text-input[placeholder]")) return; if (!target.matches("*:is([id*='_toprow'] [id*='_prompt'], .prompt) textarea")) return;
if (! (event.metaKey || event.ctrlKey)) return; if (!(event.metaKey || event.ctrlKey)) return;
let isPlus = event.key == "ArrowUp" let isPlus = event.key == "ArrowUp";
let isMinus = event.key == "ArrowDown" let isMinus = event.key == "ArrowDown";
if (!isPlus && !isMinus) return; if (!isPlus && !isMinus) return;
let selectionStart = target.selectionStart; let selectionStart = target.selectionStart;
let selectionEnd = target.selectionEnd; let selectionEnd = target.selectionEnd;
let text = target.value; let text = target.value;
function selectCurrentParenthesisBlock(OPEN, CLOSE){ function selectCurrentParenthesisBlock(OPEN, CLOSE) {
if (selectionStart !== selectionEnd) return false; if (selectionStart !== selectionEnd) return false;
// Find opening parenthesis around current cursor // Find opening parenthesis around current cursor
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) { // Find closing parenthesis around current cursor
beforeParen = before.lastIndexOf(OPEN, beforeParen - 1); const after = text.substring(selectionStart);
beforeParenClose = before.lastIndexOf(CLOSE, beforeParenClose - 1); let afterParen = after.indexOf(CLOSE);
} if (afterParen == -1) return false;
// Find closing parenthesis around current cursor // Set the selection to the text between the parenthesis
const after = text.substring(selectionStart); const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen);
let afterParen = after.indexOf(CLOSE); const lastColon = parenContent.lastIndexOf(":");
if (afterParen == -1) return false; selectionStart = beforeParen + 1;
let afterParenOpen = after.indexOf(OPEN); selectionEnd = selectionStart + lastColon;
while (afterParenOpen !== -1 && afterParen > afterParenOpen) { target.setSelectionRange(selectionStart, selectionEnd);
afterParen = after.indexOf(CLOSE, afterParen + 1); return true;
afterParenOpen = after.indexOf(OPEN, afterParenOpen + 1); }
}
if (beforeParen === -1 || afterParen === -1) return false; function selectCurrentWord() {
if (selectionStart !== selectionEnd) return false;
// Set the selection to the text between the parenthesis const whitespace_delimiters = {"Tab": "\t", "Carriage Return": "\r", "Line Feed": "\n"};
const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen); let delimiters = opts.keyedit_delimiters;
const lastColon = parenContent.lastIndexOf(":");
selectionStart = beforeParen + 1; for (let i of opts.keyedit_delimiters_whitespace) {
selectionEnd = selectionStart + lastColon; delimiters += whitespace_delimiters[i];
target.setSelectionRange(selectionStart, selectionEnd); }
return true;
} // seek backward to find beginning
while (!delimiters.includes(text[selectionStart - 1]) && selectionStart > 0) {
// If the user hasn't selected anything, let's select their current parenthesis block selectionStart--;
if(! selectCurrentParenthesisBlock('<', '>')){ }
selectCurrentParenthesisBlock('(', ')')
} // seek forward to find end
while (!delimiters.includes(text[selectionEnd]) && selectionEnd < text.length) {
event.preventDefault(); selectionEnd++;
}
closeCharacter = ')'
delta = opts.keyedit_precision_attention target.setSelectionRange(selectionStart, selectionEnd);
return true;
if (selectionStart > 0 && text[selectionStart - 1] == '<'){ }
closeCharacter = '>'
delta = opts.keyedit_precision_extra // If the user hasn't selected anything, let's select their current parenthesis block or word
} else if (selectionStart == 0 || text[selectionStart - 1] != "(") { if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')')) {
selectCurrentWord();
// do not include spaces at the end }
while(selectionEnd > selectionStart && text[selectionEnd-1] == ' '){
selectionEnd -= 1; event.preventDefault();
}
if(selectionStart == selectionEnd){ var closeCharacter = ')';
return var delta = opts.keyedit_precision_attention;
}
if (selectionStart > 0 && text[selectionStart - 1] == '<') {
text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd); closeCharacter = '>';
delta = opts.keyedit_precision_extra;
selectionStart += 1; } else if (selectionStart == 0 || text[selectionStart - 1] != "(") {
selectionEnd += 1;
} // do not include spaces at the end
while (selectionEnd > selectionStart && text[selectionEnd - 1] == ' ') {
end = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1; selectionEnd -= 1;
weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + 1 + end)); }
if (isNaN(weight)) return; if (selectionStart == selectionEnd) {
return;
weight += isPlus ? delta : -delta; }
weight = parseFloat(weight.toPrecision(12));
if(String(weight).length == 1) weight += ".0" text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd);
text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + 1 + end - 1); selectionStart += 1;
selectionEnd += 1;
target.focus(); }
target.value = text;
target.selectionStart = selectionStart; var end = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1;
target.selectionEnd = selectionEnd; var weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + end));
if (isNaN(weight)) return;
updateInput(target)
} weight += isPlus ? delta : -delta;
weight = parseFloat(weight.toPrecision(12));
addEventListener('keydown', (event) => { if (String(weight).length == 1) weight += ".0";
keyupEditAttention(event);
}); if (closeCharacter == ')' && weight == 1) {
var endParenPos = text.substring(selectionEnd).indexOf(')');
text = text.slice(0, selectionStart - 1) + text.slice(selectionStart, selectionEnd) + text.slice(selectionEnd + endParenPos + 1);
selectionStart--;
selectionEnd--;
} else {
text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + end);
}
target.focus();
target.value = text;
target.selectionStart = selectionStart;
target.selectionEnd = selectionEnd;
updateInput(target);
}
addEventListener('keydown', (event) => {
keyupEditAttention(event);
});
+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);
});
+92 -35
View File
@@ -1,35 +1,92 @@
function extensions_apply(_, _){ function extensions_apply(_disabled_list, _update_list, disable_all) {
disable = [] var disable = [];
update = [] var update = [];
gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x){
if(x.name.startsWith("enable_") && ! x.checked) gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x) {
disable.push(x.name.substr(7)) if (x.name.startsWith("enable_") && !x.checked) {
disable.push(x.name.substring(7));
if(x.name.startsWith("update_") && x.checked) }
update.push(x.name.substr(7))
}) if (x.name.startsWith("update_") && x.checked) {
update.push(x.name.substring(7));
restart_reload() }
});
return [JSON.stringify(disable), JSON.stringify(update)]
} restart_reload();
function extensions_check(){ return [JSON.stringify(disable), JSON.stringify(update), disable_all];
gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x){ }
x.innerHTML = "Loading..."
}) function extensions_check() {
var disable = [];
return []
} gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x) {
if (x.name.startsWith("enable_") && !x.checked) {
function install_extension_from_index(button, url){ disable.push(x.name.substring(7));
button.disabled = "disabled" }
button.value = "Installing..." });
textarea = gradioApp().querySelector('#extension_to_install textarea') gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x) {
textarea.value = url x.innerHTML = "Loading...";
updateInput(textarea) });
gradioApp().querySelector('#install_extension_button').click()
} var id = randomId();
requestProgress(id, gradioApp().getElementById('extensions_installed_html'), null, function() {
});
return [id, JSON.stringify(disable)];
}
function install_extension_from_index(button, url) {
button.disabled = "disabled";
button.value = "Installing...";
var textarea = gradioApp().querySelector('#extension_to_install textarea');
textarea.value = url;
updateInput(textarea);
gradioApp().querySelector('#install_extension_button').click();
}
function config_state_confirm_restore(_, config_state_name, config_restore_type) {
if (config_state_name == "Current") {
return [false, config_state_name, config_restore_type];
}
let restored = "";
if (config_restore_type == "extensions") {
restored = "all saved extension versions";
} else if (config_restore_type == "webui") {
restored = "the webui version";
} else {
restored = "the webui version and all saved extension versions";
}
let confirmed = confirm("Are you sure you want to restore from this state?\nThis will reset " + restored + ".");
if (confirmed) {
restart_reload();
gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x) {
x.innerHTML = "Loading...";
});
}
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;
}
+352 -69
View File
@@ -1,69 +1,352 @@
function toggleCss(key, css, enable) {
function setupExtraNetworksForTab(tabname){ var style = document.getElementById(key);
gradioApp().querySelector('#'+tabname+'_extra_tabs').classList.add('extra-networks') if (enable && !style) {
style = document.createElement('style');
var tabs = gradioApp().querySelector('#'+tabname+'_extra_tabs > div') style.id = key;
var search = gradioApp().querySelector('#'+tabname+'_extra_search textarea') style.type = 'text/css';
var refresh = gradioApp().getElementById(tabname+'_extra_refresh') document.head.appendChild(style);
var close = gradioApp().getElementById(tabname+'_extra_close') }
if (style && !enable) {
search.classList.add('search') document.head.removeChild(style);
tabs.appendChild(search) }
tabs.appendChild(refresh) if (style) {
tabs.appendChild(close) style.innerHTML == '';
style.appendChild(document.createTextNode(css));
search.addEventListener("input", function(evt){ }
searchTerm = search.value.toLowerCase() }
gradioApp().querySelectorAll('#'+tabname+'_extra_tabs div.card').forEach(function(elem){ function setupExtraNetworksForTab(tabname) {
text = elem.querySelector('.name').textContent.toLowerCase() gradioApp().querySelector('#' + tabname + '_extra_tabs').classList.add('extra-networks');
elem.style.display = text.indexOf(searchTerm) == -1 ? "none" : ""
}) var tabs = gradioApp().querySelector('#' + tabname + '_extra_tabs > div');
}); var searchDiv = gradioApp().getElementById(tabname + '_extra_search');
} var search = searchDiv.querySelector('textarea');
var sort = gradioApp().getElementById(tabname + '_extra_sort');
var activePromptTextarea = {}; var sortOrder = gradioApp().getElementById(tabname + '_extra_sortorder');
var refresh = gradioApp().getElementById(tabname + '_extra_refresh');
function setupExtraNetworks(){ var showDirsDiv = gradioApp().getElementById(tabname + '_extra_show_dirs');
setupExtraNetworksForTab('txt2img') var showDirs = gradioApp().querySelector('#' + tabname + '_extra_show_dirs input');
setupExtraNetworksForTab('img2img')
sort.dataset.sortkey = 'sortDefault';
function registerPrompt(tabname, id){ tabs.appendChild(searchDiv);
var textarea = gradioApp().querySelector("#" + id + " > label > textarea"); tabs.appendChild(sort);
tabs.appendChild(sortOrder);
if (! activePromptTextarea[tabname]){ tabs.appendChild(refresh);
activePromptTextarea[tabname] = textarea tabs.appendChild(showDirsDiv);
}
var applyFilter = function() {
textarea.addEventListener("focus", function(){ var searchTerm = search.value.toLowerCase();
activePromptTextarea[tabname] = textarea;
}); 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();
registerPrompt('txt2img', 'txt2img_prompt')
registerPrompt('txt2img', 'txt2img_neg_prompt') var visible = text.indexOf(searchTerm) != -1;
registerPrompt('img2img', 'img2img_prompt')
registerPrompt('img2img', 'img2img_neg_prompt') if (searchOnly && searchTerm.length < 4) {
} visible = false;
}
onUiLoaded(setupExtraNetworks)
elem.style.display = visible ? "" : "none";
function cardClicked(tabname, textToAdd, allowNegativePrompt){ });
var textarea = allowNegativePrompt ? activePromptTextarea[tabname] : gradioApp().querySelector("#" + tabname + "_prompt > label > textarea") };
textarea.value = textarea.value + " " + textToAdd var applySort = function() {
updateInput(textarea) 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) : "";
function saveCardPreview(event, tabname, filename){ var sortKeyStore = sortKey ? sortKey + (reverse ? "Reverse" : "") : "";
var textarea = gradioApp().querySelector("#" + tabname + '_preview_filename > label > textarea') if (!sortKey || sortKeyStore == sort.dataset.sortkey) {
var button = gradioApp().getElementById(tabname + '_save_preview') return;
}
textarea.value = filename
updateInput(textarea) sort.dataset.sortkey = sortKeyStore;
button.click() var cards = gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card');
cards.forEach(function(card) {
event.stopPropagation() card.originalParentElement = card.parentElement;
event.preventDefault() });
} 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;
var showDirsUpdate = function() {
var css = '#' + tabname + '_extra_tabs .extra-network-subdirs { display: none; }';
toggleCss(tabname + '_extra_show_dirs_style', css, !showDirs.checked);
localSet('extra-networks-show-dirs', showDirs.checked ? 1 : 0);
};
showDirs.checked = localGet('extra-networks-show-dirs', 1) == 1;
showDirs.addEventListener("change", showDirsUpdate);
showDirsUpdate();
}
function applyExtraNetworkFilter(tabname) {
setTimeout(extraNetworksApplyFilter[tabname], 1);
}
var extraNetworksApplyFilter = {};
var activePromptTextarea = {};
function setupExtraNetworks() {
setupExtraNetworksForTab('txt2img');
setupExtraNetworksForTab('img2img');
function registerPrompt(tabname, id) {
var textarea = gradioApp().querySelector("#" + id + " > label > textarea");
if (!activePromptTextarea[tabname]) {
activePromptTextarea[tabname] = textarea;
}
textarea.addEventListener("focus", function() {
activePromptTextarea[tabname] = textarea;
});
}
registerPrompt('txt2img', 'txt2img_prompt');
registerPrompt('txt2img', 'txt2img_neg_prompt');
registerPrompt('img2img', 'img2img_prompt');
registerPrompt('img2img', 'img2img_neg_prompt');
}
onUiLoaded(setupExtraNetworks);
var re_extranet = /<([^:^>]+:[^:]+):[\d.]+>(.*)/;
var re_extranet_g = /<([^:^>]+:[^:]+):[\d.]+>/g;
function tryToRemoveExtraNetworkFromPrompt(textarea, text) {
var m = text.match(re_extranet);
var replaced = false;
var newTextareaText;
if (m) {
var extraTextBeforeNet = opts.extra_networks_add_text_separator;
var extraTextAfterNet = m[2];
var partToSearch = m[1];
var foundAtPosition = -1;
newTextareaText = textarea.value.replaceAll(re_extranet_g, function(found, net, pos) {
m = found.match(re_extranet);
if (m[1] == partToSearch) {
replaced = true;
foundAtPosition = pos;
return "";
}
return found;
});
if (foundAtPosition >= 0) {
if (newTextareaText.substr(foundAtPosition, extraTextAfterNet.length) == extraTextAfterNet) {
newTextareaText = newTextareaText.substr(0, foundAtPosition) + newTextareaText.substr(foundAtPosition + extraTextAfterNet.length);
}
if (newTextareaText.substr(foundAtPosition - extraTextBeforeNet.length, extraTextBeforeNet.length) == extraTextBeforeNet) {
newTextareaText = newTextareaText.substr(0, foundAtPosition - extraTextBeforeNet.length) + newTextareaText.substr(foundAtPosition);
}
}
} else {
newTextareaText = textarea.value.replaceAll(new RegExp(text, "g"), function(found) {
if (found == text) {
replaced = true;
return "";
}
return found;
});
}
if (replaced) {
textarea.value = newTextareaText;
return true;
}
return false;
}
function cardClicked(tabname, textToAdd, allowNegativePrompt) {
var textarea = allowNegativePrompt ? activePromptTextarea[tabname] : gradioApp().querySelector("#" + tabname + "_prompt > label > textarea");
if (!tryToRemoveExtraNetworkFromPrompt(textarea, textToAdd)) {
textarea.value = textarea.value + opts.extra_networks_add_text_separator + textToAdd;
}
updateInput(textarea);
}
function saveCardPreview(event, tabname, filename) {
var textarea = gradioApp().querySelector("#" + tabname + '_preview_filename > label > textarea');
var button = gradioApp().getElementById(tabname + '_save_preview');
textarea.value = filename;
updateInput(textarea);
button.click();
event.stopPropagation();
event.preventDefault();
}
function extraNetworksSearchButton(tabs_id, event) {
var searchTextarea = gradioApp().querySelector("#" + tabs_id + ' > label > textarea');
var button = event.target;
var text = button.classList.contains("search-all") ? "" : button.textContent.trim();
searchTextarea.value = text;
updateInput(searchTextarea);
}
var globalPopup = null;
var globalPopupInner = null;
function closePopup() {
if (!globalPopup) return;
globalPopup.style.display = "none";
}
function popup(contents) {
if (!globalPopup) {
globalPopup = document.createElement('div');
globalPopup.classList.add('global-popup');
var close = document.createElement('div');
close.classList.add('global-popup-close');
close.addEventListener("click", closePopup);
close.title = "Close";
globalPopup.appendChild(close);
globalPopupInner = document.createElement('div');
globalPopupInner.classList.add('global-popup-inner');
globalPopup.appendChild(globalPopupInner);
gradioApp().querySelector('.main').appendChild(globalPopup);
}
globalPopupInner.innerHTML = '';
globalPopupInner.appendChild(contents);
globalPopup.style.display = "flex";
}
var storedPopupIds = {};
function popupId(id) {
if (!storedPopupIds[id]) {
storedPopupIds[id] = gradioApp().getElementById(id);
}
popup(storedPopupIds[id]);
}
function extraNetworksShowMetadata(text) {
var elem = document.createElement('pre');
elem.classList.add('popup-metadata');
elem.textContent = text;
popup(elem);
}
function requestGet(url, data, handler, errorHandler) {
var xhr = new XMLHttpRequest();
var args = Object.keys(data).map(function(k) {
return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]);
}).join('&');
xhr.open("GET", url + "?" + args, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
var js = JSON.parse(xhr.responseText);
handler(js);
} catch (error) {
console.error(error);
errorHandler();
}
} else {
errorHandler();
}
}
};
var js = JSON.stringify(data);
xhr.send(js);
}
function extraNetworksRequestMetadata(event, extraPage, cardName) {
var showError = function() {
extraNetworksShowMetadata("there was an error getting metadata");
};
requestGet("./sd_extra_networks/metadata", {page: extraPage, item: cardName}, function(data) {
if (data && data.metadata) {
extraNetworksShowMetadata(data.metadata);
} else {
showError();
}
}, showError);
event.stopPropagation();
}
var extraPageUserMetadataEditors = {};
function extraNetworksEditUserMetadata(event, tabname, extraPage, cardName) {
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;
}
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);
}
});
}
+25 -23
View File
@@ -1,33 +1,35 @@
// attaches listeners to the txt2img and img2img galleries to update displayed generation param text when the image changes // attaches listeners to the txt2img and img2img galleries to update displayed generation param text when the image changes
let txt2img_gallery, img2img_gallery, modal = undefined; let txt2img_gallery, img2img_gallery, modal = undefined;
onUiUpdate(function(){ onAfterUiUpdate(function() {
if (!txt2img_gallery) { if (!txt2img_gallery) {
txt2img_gallery = attachGalleryListeners("txt2img") txt2img_gallery = attachGalleryListeners("txt2img");
} }
if (!img2img_gallery) { if (!img2img_gallery) {
img2img_gallery = attachGalleryListeners("img2img") img2img_gallery = attachGalleryListeners("img2img");
} }
if (!modal) { if (!modal) {
modal = gradioApp().getElementById('lightboxModal') modal = gradioApp().getElementById('lightboxModal');
modalObserver.observe(modal, { attributes : true, attributeFilter : ['style'] }); modalObserver.observe(modal, {attributes: true, attributeFilter: ['style']});
} }
}); });
let modalObserver = new MutationObserver(function(mutations) { let modalObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutationRecord) { mutations.forEach(function(mutationRecord) {
let selectedTab = gradioApp().querySelector('#tabs div button.bg-white')?.innerText let selectedTab = gradioApp().querySelector('#tabs div button.selected')?.innerText;
if (mutationRecord.target.style.display === 'none' && selectedTab === 'txt2img' || selectedTab === 'img2img') if (mutationRecord.target.style.display === 'none' && (selectedTab === 'txt2img' || selectedTab === 'img2img')) {
gradioApp().getElementById(selectedTab+"_generation_info_button").click() gradioApp().getElementById(selectedTab + "_generation_info_button")?.click();
}); }
});
}); });
function attachGalleryListeners(tab_name) { function attachGalleryListeners(tab_name) {
gallery = gradioApp().querySelector('#'+tab_name+'_gallery') var gallery = gradioApp().querySelector('#' + tab_name + '_gallery');
gallery?.addEventListener('click', () => gradioApp().getElementById(tab_name+"_generation_info_button").click()); gallery?.addEventListener('click', () => gradioApp().getElementById(tab_name + "_generation_info_button").click());
gallery?.addEventListener('keydown', (e) => { gallery?.addEventListener('keydown', (e) => {
if (e.keyCode == 37 || e.keyCode == 39) // left or right arrow if (e.keyCode == 37 || e.keyCode == 39) { // left or right arrow
gradioApp().getElementById(tab_name+"_generation_info_button").click() gradioApp().getElementById(tab_name + "_generation_info_button").click();
}); }
return gallery; });
return gallery;
} }
+108 -51
View File
@@ -1,27 +1,29 @@
// mouseover tooltips for various UI elements // mouseover tooltips for various UI elements
titles = { var titles = {
"Sampling steps": "How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results", "Sampling steps": "How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results",
"Sampling method": "Which algorithm to use to produce the image", "Sampling method": "Which algorithm to use to produce the image",
"GFPGAN": "Restore low quality faces using GFPGAN neural network", "GFPGAN": "Restore low quality faces using GFPGAN neural network",
"Euler a": "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help", "Euler a": "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help",
"DDIM": "Denoising Diffusion Implicit Models - best at inpainting", "DDIM": "Denoising Diffusion Implicit Models - best at inpainting",
"DPM adaptive": "Ignores step count - uses a number of steps determined by the CFG and resolution", "UniPC": "Unified Predictor-Corrector Framework for Fast Sampling of Diffusion Models",
"DPM adaptive": "Ignores step count - uses a number of steps determined by the CFG and resolution",
"Batch count": "How many batches of images to create", "\u{1F4D0}": "Auto detect size from img2img",
"Batch size": "How many image to create in a single batch", "Batch count": "How many batches of images to create (has no impact on generation performance or VRAM usage)",
"Batch size": "How many image to create in a single batch (increases generation performance at cost of higher VRAM usage)",
"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",
"\U0001F5D1": "Clear prompt", "\u{1f5d1}\ufe0f": "Clear prompt",
"\u{1f4cb}": "Apply selected styles to current prompt", "\u{1f4cb}": "Apply selected styles to current prompt",
"\u{1f4d2}": "Paste available values into the field", "\u{1f4d2}": "Paste available values into the field",
"\u{1f3b4}": "Show extra networks", "\u{1f3b4}": "Show/hide extra networks",
"\u{1f300}": "Restore progress",
"Inpaint a part of image": "Draw a mask over an image, and the script will regenerate the masked area with content according to prompt", "Inpaint a part of image": "Draw a mask over an image, and the script will regenerate the masked area with content according to prompt",
"SD upscale": "Upscale image normally, split result into tiles, improve each tile using img2img, merge whole image back", "SD upscale": "Upscale image normally, split result into tiles, improve each tile using img2img, merge whole image back",
@@ -39,7 +41,6 @@ titles = {
"Inpaint at full resolution": "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image", "Inpaint at full resolution": "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image",
"Denoising strength": "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.", "Denoising strength": "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.",
"Denoising strength change factor": "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.",
"Skip": "Stop processing current image and continue processing.", "Skip": "Stop processing current image and continue processing.",
"Interrupt": "Stop processing images and return any results accumulated so far.", "Interrupt": "Stop processing images and return any results accumulated so far.",
@@ -50,7 +51,7 @@ titles = {
"None": "Do not do anything special", "None": "Do not do anything special",
"Prompt matrix": "Separate prompts into parts using vertical pipe character (|) and the script will create a picture for every combination of them (except for the first part, which will be present in all combinations)", "Prompt matrix": "Separate prompts into parts using vertical pipe character (|) and the script will create a picture for every combination of them (except for the first part, which will be present in all combinations)",
"X/Y plot": "Create a grid where images will have different parameters. Use inputs below to specify which parameters will be shared by columns and rows", "X/Y/Z plot": "Create grid(s) where images will have different parameters. Use inputs below to specify which parameters will be shared by columns and rows",
"Custom code": "Run Python code. Advanced user only. Must run program with --allow-code for this to work", "Custom code": "Run Python code. Advanced user only. Must run program with --allow-code for this to work",
"Prompt S/R": "Separate a list of words with commas, and the first word will be used as a keyword: script will search for this word in the prompt, and replace it with others", "Prompt S/R": "Separate a list of words with commas, and the first word will be used as a keyword: script will search for this word in the prompt, and replace it with others",
@@ -66,12 +67,14 @@ titles = {
"Interrogate": "Reconstruct prompt from existing image and put it into the prompt field.", "Interrogate": "Reconstruct prompt from existing image and put it into the prompt field.",
"Images filename pattern": "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.", "Images filename pattern": "Use tags like [seed] and [date] to define how filenames for images are chosen. Leave empty for default.",
"Directory name pattern": "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.", "Directory name pattern": "Use tags like [seed] and [date] to define how subdirectories for images and grids are chosen. Leave empty for default.",
"Max prompt words": "Set the maximum number of words to be used in the [prompt_words] option; ATTENTION: If the words are too long, they may exceed the maximum length of the file path that the system can handle", "Max prompt words": "Set the maximum number of words to be used in the [prompt_words] option; ATTENTION: If the words are too long, they may exceed the maximum length of the file path that the system can handle",
"Loopback": "Process an image, use it as an input, repeat.", "Loopback": "Performs img2img processing multiple times. Output images are used as input for the next loop.",
"Loops": "How many times to repeat processing an image and using it as input for the next iteration", "Loops": "How many times to process an image. Each output is used as the input of the next loop. If set to 1, behavior will be as if this script were not used.",
"Final denoising strength": "The denoising strength for the final loop of each image in the batch.",
"Denoising strength curve": "The denoising curve controls the rate of denoising strength change each loop. Aggressive: Most of the change will happen towards the start of the loops. Linear: Change will be constant through all loops. Lazy: Most of the change will happen towards the end of the loops.",
"Style 1": "Style to apply; styles have components for both positive and negative prompts and apply to both", "Style 1": "Style to apply; styles have components for both positive and negative prompts and apply to both",
"Style 2": "Style to apply; styles have components for both positive and negative prompts and apply to both", "Style 2": "Style to apply; styles have components for both positive and negative prompts and apply to both",
@@ -81,10 +84,7 @@ 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.",
"Do not add watermark to images": "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.",
"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.",
"Filename join string": "This string will be used to join split words into a single line if the option above is enabled.", "Filename join string": "This string will be used to join split words into a single line if the option above is enabled.",
@@ -95,7 +95,7 @@ titles = {
"Add difference": "Result = A + (B - C) * M", "Add difference": "Result = A + (B - C) * M",
"No interpolation": "Result = A", "No interpolation": "Result = A",
"Initialization text": "If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors", "Initialization text": "If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors",
"Learning rate": "How fast should training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.", "Learning rate": "How fast should training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.",
"Clip skip": "Early stopping parameter for CLIP model; 1 is stop at last layer as usual, 2 is stop at penultimate layer, etc.", "Clip skip": "Early stopping parameter for CLIP model; 1 is stop at last layer as usual, 2 is stop at penultimate layer, etc.",
@@ -108,39 +108,96 @@ 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."
};
function updateTooltip(element) {
if (element.title) return; // already has a title
let text = element.textContent;
let tooltip = localization[titles[text]] || titles[text];
if (!tooltip) {
let value = element.value;
if (value) tooltip = localization[titles[value]] || titles[value];
}
if (!tooltip) {
// Gradio dropdown options have `data-value`.
let dataValue = element.dataset.value;
if (dataValue) tooltip = localization[titles[dataValue]] || titles[dataValue];
}
if (!tooltip) {
for (const c of element.classList) {
if (c in titles) {
tooltip = localization[titles[c]] || titles[c];
break;
}
}
}
if (tooltip) {
element.title = tooltip;
}
} }
// Nodes to check for adding tooltips.
const tooltipCheckNodes = new Set();
// Timer for debouncing tooltip check.
let tooltipCheckTimer = null;
onUiUpdate(function(){ function processTooltipCheckNodes() {
gradioApp().querySelectorAll('span, button, select, p').forEach(function(span){ for (const node of tooltipCheckNodes) {
tooltip = titles[span.textContent]; updateTooltip(node);
}
tooltipCheckNodes.clear();
}
if(!tooltip){ onUiUpdate(function(mutationRecords) {
tooltip = titles[span.value]; for (const record of mutationRecords) {
} if (record.type === "childList" && record.target.classList.contains("options")) {
// This smells like a Gradio dropdown menu having changed,
// so let's enqueue an update for the input element that shows the current value.
let wrap = record.target.parentNode;
let input = wrap?.querySelector("input");
if (input) {
input.title = ""; // So we'll even have a chance to update it.
tooltipCheckNodes.add(input);
}
}
for (const node of record.addedNodes) {
if (node.nodeType === Node.ELEMENT_NODE && !node.classList.contains("hide")) {
if (!node.title) {
if (
node.tagName === "SPAN" ||
node.tagName === "BUTTON" ||
node.tagName === "P" ||
node.tagName === "INPUT" ||
(node.tagName === "LI" && node.classList.contains("item")) // Gradio dropdown item
) {
tooltipCheckNodes.add(node);
}
}
node.querySelectorAll('span, button, p').forEach(n => tooltipCheckNodes.add(n));
}
}
}
if (tooltipCheckNodes.size) {
clearTimeout(tooltipCheckTimer);
tooltipCheckTimer = setTimeout(processTooltipCheckNodes, 1000);
}
});
if(!tooltip){ onUiLoaded(function() {
for (const c of span.classList) { for (var comp of window.gradio_config.components) {
if (c in titles) { if (comp.props.webui_tooltip && comp.props.elem_id) {
tooltip = titles[c]; var elem = gradioApp().getElementById(comp.props.elem_id);
break; if (elem) {
} elem.title = comp.props.webui_tooltip;
} }
} }
}
if(tooltip){ });
span.title = tooltip;
}
})
gradioApp().querySelectorAll('select').forEach(function(select){
if (select.onchange != null) return;
select.onchange = function(){
select.title = titles[select.value] || "";
}
})
})
+18 -22
View File
@@ -1,22 +1,18 @@
function setInactive(elem, inactive){ function onCalcResolutionHires(enable, width, height, hr_scale, hr_resize_x, hr_resize_y) {
if(inactive){ function setInactive(elem, inactive) {
elem.classList.add('inactive') elem.classList.toggle('inactive', !!inactive);
} else{ }
elem.classList.remove('inactive')
} var hrUpscaleBy = gradioApp().getElementById('txt2img_hr_scale');
} var hrResizeX = gradioApp().getElementById('txt2img_hr_resize_x');
var hrResizeY = gradioApp().getElementById('txt2img_hr_resize_y');
function onCalcResolutionHires(enable, width, height, hr_scale, hr_resize_x, hr_resize_y){
hrUpscaleBy = gradioApp().getElementById('txt2img_hr_scale') gradioApp().getElementById('txt2img_hires_fix_row2').style.display = opts.use_old_hires_fix_width_height ? "none" : "";
hrResizeX = gradioApp().getElementById('txt2img_hr_resize_x')
hrResizeY = gradioApp().getElementById('txt2img_hr_resize_y') setInactive(hrUpscaleBy, opts.use_old_hires_fix_width_height || hr_resize_x > 0 || hr_resize_y > 0);
setInactive(hrResizeX, opts.use_old_hires_fix_width_height || hr_resize_x == 0);
gradioApp().getElementById('txt2img_hires_fix_row2').style.display = opts.use_old_hires_fix_width_height ? "none" : "" setInactive(hrResizeY, opts.use_old_hires_fix_width_height || hr_resize_y == 0);
setInactive(hrUpscaleBy, opts.use_old_hires_fix_width_height || hr_resize_x > 0 || hr_resize_y > 0) return [enable, width, height, hr_scale, hr_resize_x, hr_resize_y];
setInactive(hrResizeX, opts.use_old_hires_fix_width_height || hr_resize_x == 0) }
setInactive(hrResizeY, opts.use_old_hires_fix_width_height || hr_resize_y == 0)
return [enable, width, height, hr_scale, hr_resize_x, hr_resize_y]
}
+12 -14
View File
@@ -2,20 +2,18 @@
* temporary fix for https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/668 * temporary fix for https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/668
* @see https://github.com/gradio-app/gradio/issues/1721 * @see https://github.com/gradio-app/gradio/issues/1721
*/ */
window.addEventListener( 'resize', () => imageMaskResize());
function imageMaskResize() { function imageMaskResize() {
const canvases = gradioApp().querySelectorAll('#img2maskimg .touch-none canvas'); const canvases = gradioApp().querySelectorAll('#img2maskimg .touch-none canvas');
if ( ! canvases.length ) { if (!canvases.length) {
canvases_fixed = false; window.removeEventListener('resize', imageMaskResize);
window.removeEventListener( 'resize', imageMaskResize ); return;
return;
} }
const wrapper = canvases[0].closest('.touch-none'); const wrapper = canvases[0].closest('.touch-none');
const previewImage = wrapper.previousElementSibling; const previewImage = wrapper.previousElementSibling;
if ( ! previewImage.complete ) { if (!previewImage.complete) {
previewImage.addEventListener( 'load', () => imageMaskResize()); previewImage.addEventListener('load', imageMaskResize);
return; return;
} }
@@ -24,22 +22,22 @@ function imageMaskResize() {
const nw = previewImage.naturalWidth; const nw = previewImage.naturalWidth;
const nh = previewImage.naturalHeight; const nh = previewImage.naturalHeight;
const portrait = nh > nw; const portrait = nh > nw;
const factor = portrait;
const wW = Math.min(w, portrait ? h/nh*nw : w/nw*nw); const wW = Math.min(w, portrait ? h / nh * nw : w / nw * nw);
const wH = Math.min(h, portrait ? h/nh*nh : w/nw*nh); const wH = Math.min(h, portrait ? h / nh * nh : w / nw * nh);
wrapper.style.width = `${wW}px`; wrapper.style.width = `${wW}px`;
wrapper.style.height = `${wH}px`; wrapper.style.height = `${wH}px`;
wrapper.style.left = `0px`; wrapper.style.left = `0px`;
wrapper.style.top = `0px`; wrapper.style.top = `0px`;
canvases.forEach( c => { canvases.forEach(c => {
c.style.width = c.style.height = ''; c.style.width = c.style.height = '';
c.style.maxWidth = '100%'; c.style.maxWidth = '100%';
c.style.maxHeight = '100%'; c.style.maxHeight = '100%';
c.style.objectFit = 'contain'; c.style.objectFit = 'contain';
}); });
} }
onUiUpdate(() => imageMaskResize()); onAfterUiUpdate(imageMaskResize);
window.addEventListener('resize', imageMaskResize);
-19
View File
@@ -1,19 +0,0 @@
window.onload = (function(){
window.addEventListener('drop', e => {
const target = e.composedPath()[0];
const idx = selected_gallery_index();
if (target.placeholder.indexOf("Prompt") == -1) return;
let prompt_target = get_tab_index('tabs') == 1 ? "img2img_prompt_image" : "txt2img_prompt_image";
e.stopPropagation();
e.preventDefault();
const imgParent = gradioApp().getElementById(prompt_target);
const files = e.dataTransfer.files;
const fileInput = imgParent.querySelector('input[type="file"]');
if ( fileInput ) {
fileInput.files = files;
fileInput.dispatchEvent(new Event('change'));
}
});
});
+127 -153
View File
@@ -5,24 +5,24 @@ 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 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') {
lb.style.setProperty('background-image', 'url(' + source.src + ')'); lb.style.setProperty('background-image', 'url(' + source.src + ')');
} }
lb.style.display = "block"; lb.style.display = "flex";
lb.focus() lb.focus();
const tabTxt2Img = gradioApp().getElementById("tab_txt2img") const tabTxt2Img = gradioApp().getElementById("tab_txt2img");
const tabImg2Img = gradioApp().getElementById("tab_img2img") const tabImg2Img = gradioApp().getElementById("tab_img2img");
// show the save button in modal only on txt2img or img2img tabs // show the save button in modal only on txt2img or img2img tabs
if (tabTxt2Img.style.display != "none" || tabImg2Img.style.display != "none") { if (tabTxt2Img.style.display != "none" || tabImg2Img.style.display != "none") {
gradioApp().getElementById("modal_save").style.display = "inline" gradioApp().getElementById("modal_save").style.display = "inline";
} else { } else {
gradioApp().getElementById("modal_save").style.display = "none" gradioApp().getElementById("modal_save").style.display = "none";
} }
event.stopPropagation() event.stopPropagation();
} }
function negmod(n, m) { function negmod(n, m) {
@@ -30,157 +30,134 @@ function negmod(n, m) {
} }
function updateOnBackgroundChange() { function updateOnBackgroundChange() {
const modalImage = gradioApp().getElementById("modalImage") const modalImage = gradioApp().getElementById("modalImage");
if (modalImage && modalImage.offsetParent) { if (modalImage && modalImage.offsetParent) {
let allcurrentButtons = gradioApp().querySelectorAll(".gallery-item.transition-all.\\!ring-2") let currentButton = selected_gallery_button();
let currentButton = null
allcurrentButtons.forEach(function(elem) {
if (elem.parentElement.offsetParent) {
currentButton = elem;
}
})
if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) { 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') {
modal.style.setProperty('background-image', `url(${modalImage.src})`) const modal = gradioApp().getElementById("lightboxModal");
modal.style.setProperty('background-image', `url(${modalImage.src})`);
} }
} }
} }
} }
function modalImageSwitch(offset) { function modalImageSwitch(offset) {
var allgalleryButtons = gradioApp().querySelectorAll(".gallery-item.transition-all") var galleryButtons = all_gallery_buttons();
var galleryButtons = []
allgalleryButtons.forEach(function(elem) {
if (elem.parentElement.offsetParent) {
galleryButtons.push(elem);
}
})
if (galleryButtons.length > 1) { if (galleryButtons.length > 1) {
var allcurrentButtons = gradioApp().querySelectorAll(".gallery-item.transition-all.\\!ring-2") var currentButton = selected_gallery_button();
var currentButton = null
allcurrentButtons.forEach(function(elem) {
if (elem.parentElement.offsetParent) {
currentButton = elem;
}
})
var result = -1 var result = -1;
galleryButtons.forEach(function(v, i) { galleryButtons.forEach(function(v, i) {
if (v == currentButton) { if (v == currentButton) {
result = i result = i;
} }
}) });
if (result != -1) { if (result != -1) {
nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)] var nextButton = galleryButtons[negmod((result + offset), galleryButtons.length)];
nextButton.click() nextButton.click();
const modalImage = gradioApp().getElementById("modalImage"); const modalImage = gradioApp().getElementById("modalImage");
const modal = gradioApp().getElementById("lightboxModal"); const modal = gradioApp().getElementById("lightboxModal");
modalImage.src = nextButton.children[0].src; modalImage.src = nextButton.children[0].src;
if (modalImage.style.display === 'none') { if (modalImage.style.display === 'none') {
modal.style.setProperty('background-image', `url(${modalImage.src})`) modal.style.setProperty('background-image', `url(${modalImage.src})`);
} }
setTimeout(function() { setTimeout(function() {
modal.focus() modal.focus();
}, 10) }, 10);
} }
} }
} }
function saveImage(){ function saveImage() {
const tabTxt2Img = gradioApp().getElementById("tab_txt2img") const tabTxt2Img = gradioApp().getElementById("tab_txt2img");
const tabImg2Img = gradioApp().getElementById("tab_img2img") const tabImg2Img = gradioApp().getElementById("tab_img2img");
const saveTxt2Img = "save_txt2img" const saveTxt2Img = "save_txt2img";
const saveImg2Img = "save_img2img" const saveImg2Img = "save_img2img";
if (tabTxt2Img.style.display != "none") { if (tabTxt2Img.style.display != "none") {
gradioApp().getElementById(saveTxt2Img).click() gradioApp().getElementById(saveTxt2Img).click();
} else if (tabImg2Img.style.display != "none") { } else if (tabImg2Img.style.display != "none") {
gradioApp().getElementById(saveImg2Img).click() gradioApp().getElementById(saveImg2Img).click();
} else { } else {
console.error("missing implementation for saving modal of this type") console.error("missing implementation for saving modal of this type");
} }
} }
function modalSaveImage(event) { function modalSaveImage(event) {
saveImage() saveImage();
event.stopPropagation() event.stopPropagation();
} }
function modalNextImage(event) { function modalNextImage(event) {
modalImageSwitch(1) modalImageSwitch(1);
event.stopPropagation() event.stopPropagation();
} }
function modalPrevImage(event) { function modalPrevImage(event) {
modalImageSwitch(-1) modalImageSwitch(-1);
event.stopPropagation() event.stopPropagation();
} }
function modalKeyHandler(event) { function modalKeyHandler(event) {
switch (event.key) { switch (event.key) {
case "s": case "s":
saveImage() saveImage();
break; break;
case "ArrowLeft": case "ArrowLeft":
modalPrevImage(event) modalPrevImage(event);
break; break;
case "ArrowRight": case "ArrowRight":
modalNextImage(event) modalNextImage(event);
break; break;
case "Escape": case "Escape":
closeModal(); closeModal();
break; break;
} }
} }
function showGalleryImage() { function setupImageForLightbox(e) {
setTimeout(function() { if (e.dataset.modded) {
fullImg_preview = gradioApp().querySelectorAll('img.w-full.object-contain') return;
}
if (fullImg_preview != null) { e.dataset.modded = true;
fullImg_preview.forEach(function function_name(e) { e.style.cursor = 'pointer';
if (e.dataset.modded) e.style.userSelect = 'none';
return;
e.dataset.modded = true;
if(e && e.parentElement.tagName == 'DIV'){
e.style.cursor='pointer'
e.style.userSelect='none'
var isFirefox = isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1 var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
// For Firefox, listening on click first switched to next image then shows the lightbox. // For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please. // 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. // For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click' var event = isFirefox ? 'mousedown' : 'click';
e.addEventListener(event, function (evt) { e.addEventListener(event, function(evt) {
if(!opts.js_modal_lightbox || evt.button != 0) return; if (evt.button == 1) {
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed) open(evt.target.src);
evt.preventDefault() evt.preventDefault();
showModal(evt) return;
}, true);
}
});
} }
if (!opts.js_modal_lightbox || evt.button != 0) return;
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed);
evt.preventDefault();
showModal(evt);
}, true);
}, 100);
} }
function modalZoomSet(modalImage, enable) { function modalZoomSet(modalImage, enable) {
if (enable) { if (modalImage) modalImage.classList.toggle('modalImageFullscreen', !!enable);
modalImage.classList.add('modalImageFullscreen');
} else {
modalImage.classList.remove('modalImageFullscreen');
}
} }
function modalZoomToggle(event) { function modalZoomToggle(event) {
modalImage = gradioApp().getElementById("modalImage"); var modalImage = gradioApp().getElementById("modalImage");
modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen')) modalZoomSet(modalImage, !modalImage.classList.contains('modalImageFullscreen'));
event.stopPropagation() event.stopPropagation();
} }
function modalTileImageToggle(event) { function modalTileImageToggle(event) {
@@ -189,97 +166,94 @@ function modalTileImageToggle(event) {
const isTiling = modalImage.style.display === 'none'; const isTiling = modalImage.style.display === 'none';
if (isTiling) { if (isTiling) {
modalImage.style.display = 'block'; modalImage.style.display = 'block';
modal.style.setProperty('background-image', 'none') modal.style.setProperty('background-image', 'none');
} else { } else {
modalImage.style.display = 'none'; modalImage.style.display = 'none';
modal.style.setProperty('background-image', `url(${modalImage.src})`) modal.style.setProperty('background-image', `url(${modalImage.src})`);
} }
event.stopPropagation() event.stopPropagation();
} }
function galleryImageHandler(e) { onAfterUiUpdate(function() {
if (e && e.parentElement.tagName == 'BUTTON') { var fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img');
e.onclick = showGalleryImage;
}
}
onUiUpdate(function() {
fullImg_preview = gradioApp().querySelectorAll('img.w-full')
if (fullImg_preview != null) { if (fullImg_preview != null) {
fullImg_preview.forEach(galleryImageHandler); fullImg_preview.forEach(setupImageForLightbox);
} }
updateOnBackgroundChange(); updateOnBackgroundChange();
}) });
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
const modalFragment = document.createDocumentFragment(); //const modalFragment = document.createDocumentFragment();
const modal = document.createElement('div') const modal = document.createElement('div');
modal.onclick = closeModal; modal.onclick = closeModal;
modal.id = "lightboxModal"; modal.id = "lightboxModal";
modal.tabIndex = 0 modal.tabIndex = 0;
modal.addEventListener('keydown', modalKeyHandler, true) modal.addEventListener('keydown', modalKeyHandler, true);
const modalControls = document.createElement('div') const modalControls = document.createElement('div');
modalControls.className = 'modalControls gradio-container'; modalControls.className = 'modalControls gradio-container';
modal.append(modalControls); modal.append(modalControls);
const modalZoom = document.createElement('span') const modalZoom = document.createElement('span');
modalZoom.className = 'modalZoom cursor'; modalZoom.className = 'modalZoom cursor';
modalZoom.innerHTML = '&#10529;' modalZoom.innerHTML = '&#10529;';
modalZoom.addEventListener('click', modalZoomToggle, true) modalZoom.addEventListener('click', modalZoomToggle, true);
modalZoom.title = "Toggle zoomed view"; modalZoom.title = "Toggle zoomed view";
modalControls.appendChild(modalZoom) modalControls.appendChild(modalZoom);
const modalTileImage = document.createElement('span') const modalTileImage = document.createElement('span');
modalTileImage.className = 'modalTileImage cursor'; modalTileImage.className = 'modalTileImage cursor';
modalTileImage.innerHTML = '&#8862;' modalTileImage.innerHTML = '&#8862;';
modalTileImage.addEventListener('click', modalTileImageToggle, true) modalTileImage.addEventListener('click', modalTileImageToggle, true);
modalTileImage.title = "Preview tiling"; modalTileImage.title = "Preview tiling";
modalControls.appendChild(modalTileImage) modalControls.appendChild(modalTileImage);
const modalSave = document.createElement("span") const modalSave = document.createElement("span");
modalSave.className = "modalSave cursor" modalSave.className = "modalSave cursor";
modalSave.id = "modal_save" modalSave.id = "modal_save";
modalSave.innerHTML = "&#x1F5AB;" modalSave.innerHTML = "&#x1F5AB;";
modalSave.addEventListener("click", modalSaveImage, true) modalSave.addEventListener("click", modalSaveImage, true);
modalSave.title = "Save Image(s)" modalSave.title = "Save Image(s)";
modalControls.appendChild(modalSave) modalControls.appendChild(modalSave);
const modalClose = document.createElement('span') const modalClose = document.createElement('span');
modalClose.className = 'modalClose cursor'; modalClose.className = 'modalClose cursor';
modalClose.innerHTML = '&times;' modalClose.innerHTML = '&times;';
modalClose.onclick = closeModal; modalClose.onclick = closeModal;
modalClose.title = "Close image viewer"; modalClose.title = "Close image viewer";
modalControls.appendChild(modalClose) modalControls.appendChild(modalClose);
const modalImage = document.createElement('img') const modalImage = document.createElement('img');
modalImage.id = 'modalImage'; modalImage.id = 'modalImage';
modalImage.onclick = closeModal; modalImage.onclick = closeModal;
modalImage.tabIndex = 0 modalImage.tabIndex = 0;
modalImage.addEventListener('keydown', modalKeyHandler, true) modalImage.addEventListener('keydown', modalKeyHandler, true);
modal.appendChild(modalImage) modal.appendChild(modalImage);
const modalPrev = document.createElement('a') const modalPrev = document.createElement('a');
modalPrev.className = 'modalPrev'; modalPrev.className = 'modalPrev';
modalPrev.innerHTML = '&#10094;' modalPrev.innerHTML = '&#10094;';
modalPrev.tabIndex = 0 modalPrev.tabIndex = 0;
modalPrev.addEventListener('click', modalPrevImage, true); modalPrev.addEventListener('click', modalPrevImage, true);
modalPrev.addEventListener('keydown', modalKeyHandler, true) modalPrev.addEventListener('keydown', modalKeyHandler, true);
modal.appendChild(modalPrev) modal.appendChild(modalPrev);
const modalNext = document.createElement('a') const modalNext = document.createElement('a');
modalNext.className = 'modalNext'; modalNext.className = 'modalNext';
modalNext.innerHTML = '&#10095;' modalNext.innerHTML = '&#10095;';
modalNext.tabIndex = 0 modalNext.tabIndex = 0;
modalNext.addEventListener('click', modalNextImage, true); modalNext.addEventListener('click', modalNextImage, true);
modalNext.addEventListener('keydown', modalKeyHandler, true) modalNext.addEventListener('keydown', modalKeyHandler, true);
modal.appendChild(modalNext) modal.appendChild(modalNext);
try {
gradioApp().appendChild(modal);
} catch (e) {
gradioApp().body.appendChild(modal);
}
gradioApp().getRootNode().appendChild(modal) document.body.appendChild(modal);
document.body.appendChild(modalFragment);
}); });
+63
View File
@@ -0,0 +1,63 @@
let gamepads = [];
window.addEventListener('gamepadconnected', (e) => {
const index = e.gamepad.index;
let isWaiting = false;
gamepads[index] = setInterval(async() => {
if (!opts.js_modal_lightbox_gamepad || isWaiting) return;
const gamepad = navigator.getGamepads()[index];
const xValue = gamepad.axes[0];
if (xValue <= -0.3) {
modalPrevImage(e);
isWaiting = true;
} else if (xValue >= 0.3) {
modalNextImage(e);
isWaiting = true;
}
if (isWaiting) {
await sleepUntil(() => {
const xValue = navigator.getGamepads()[index].axes[0];
if (xValue < 0.3 && xValue > -0.3) {
return true;
}
}, opts.js_modal_lightbox_gamepad_repeat);
isWaiting = false;
}
}, 10);
});
window.addEventListener('gamepaddisconnected', (e) => {
clearInterval(gamepads[e.gamepad.index]);
});
/*
Primarily for vr controller type pointer devices.
I use the wheel event because there's currently no way to do it properly with web xr.
*/
let isScrolling = false;
window.addEventListener('wheel', (e) => {
if (!opts.js_modal_lightbox_gamepad || isScrolling) return;
isScrolling = true;
if (e.deltaX <= -0.6) {
modalPrevImage(e);
} else if (e.deltaX >= 0.6) {
modalNextImage(e);
}
setTimeout(() => {
isScrolling = false;
}, opts.js_modal_lightbox_gamepad_repeat);
});
function sleepUntil(f, timeout) {
return new Promise((resolve) => {
const timeStart = new Date();
const wait = setInterval(function() {
if (f() || new Date() - timeStart > timeout) {
clearInterval(wait);
resolve();
}
}, 20);
});
}
+37
View File
@@ -0,0 +1,37 @@
var observerAccordionOpen = new MutationObserver(function(mutations) {
mutations.forEach(function(mutationRecord) {
var elem = mutationRecord.target;
var open = elem.classList.contains('open');
var accordion = elem.parentNode;
accordion.classList.toggle('input-accordion-open', open);
var checkbox = gradioApp().querySelector('#' + accordion.id + "-checkbox input");
checkbox.checked = open;
updateInput(checkbox);
var extra = gradioApp().querySelector('#' + accordion.id + "-extra");
if (extra) {
extra.style.display = open ? "" : "none";
}
});
});
function inputAccordionChecked(id, checked) {
var label = gradioApp().querySelector('#' + id + " .label-wrap");
if (label.classList.contains('open') != checked) {
label.click();
}
}
onUiLoaded(function() {
for (var accordion of gradioApp().querySelectorAll('.input-accordion')) {
var labelWrap = accordion.querySelector('.label-wrap');
observerAccordionOpen.observe(labelWrap, {attributes: true, attributeFilter: ['class']});
var extra = gradioApp().querySelector('#' + accordion.id + "-extra");
if (extra) {
labelWrap.insertBefore(extra, labelWrap.lastElementChild);
}
}
});
+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}`);
}
}
+205 -165
View File
@@ -1,165 +1,205 @@
// localization = {} -- the dict with translations is created by the backend // localization = {} -- the dict with translations is created by the backend
ignore_ids_for_localization={ var ignore_ids_for_localization = {
setting_sd_hypernetwork: 'OPTION', setting_sd_hypernetwork: 'OPTION',
setting_sd_model_checkpoint: 'OPTION', setting_sd_model_checkpoint: 'OPTION',
setting_realesrgan_enabled_models: 'OPTION', modelmerger_primary_model_name: 'OPTION',
modelmerger_primary_model_name: 'OPTION', modelmerger_secondary_model_name: 'OPTION',
modelmerger_secondary_model_name: 'OPTION', modelmerger_tertiary_model_name: 'OPTION',
modelmerger_tertiary_model_name: 'OPTION', train_embedding: 'OPTION',
train_embedding: 'OPTION', train_hypernetwork: 'OPTION',
train_hypernetwork: 'OPTION', txt2img_styles: 'OPTION',
txt2img_styles: 'OPTION', img2img_styles: 'OPTION',
img2img_styles: 'OPTION', setting_random_artist_categories: 'OPTION',
setting_random_artist_categories: 'SPAN', setting_face_restoration_model: 'OPTION',
setting_face_restoration_model: 'SPAN', setting_realesrgan_enabled_models: 'OPTION',
setting_realesrgan_enabled_models: 'SPAN', extras_upscaler_1: 'OPTION',
extras_upscaler_1: 'SPAN', extras_upscaler_2: 'OPTION',
extras_upscaler_2: 'SPAN', };
}
var re_num = /^[.\d]+$/;
re_num = /^[\.\d]+$/ var re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u;
re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u
var original_lines = {};
original_lines = {} var translated_lines = {};
translated_lines = {}
function hasLocalization() {
function textNodesUnder(el){ return window.localization && Object.keys(window.localization).length > 0;
var n, a=[], walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false); }
while(n=walk.nextNode()) a.push(n);
return a; function textNodesUnder(el) {
} var n, a = [], walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false);
while ((n = walk.nextNode())) a.push(n);
function canBeTranslated(node, text){ return a;
if(! text) return false; }
if(! node.parentElement) return false;
function canBeTranslated(node, text) {
parentType = node.parentElement.nodeName if (!text) return false;
if(parentType=='SCRIPT' || parentType=='STYLE' || parentType=='TEXTAREA') return false; if (!node.parentElement) return false;
if (parentType=='OPTION' || parentType=='SPAN'){ var parentType = node.parentElement.nodeName;
pnode = node if (parentType == 'SCRIPT' || parentType == 'STYLE' || parentType == 'TEXTAREA') return false;
for(var level=0; level<4; level++){
pnode = pnode.parentElement if (parentType == 'OPTION' || parentType == 'SPAN') {
if(! pnode) break; var pnode = node;
for (var level = 0; level < 4; level++) {
if(ignore_ids_for_localization[pnode.id] == parentType) return false; pnode = pnode.parentElement;
} if (!pnode) break;
}
if (ignore_ids_for_localization[pnode.id] == parentType) return false;
if(re_num.test(text)) return false; }
if(re_emoji.test(text)) return false; }
return true
} if (re_num.test(text)) return false;
if (re_emoji.test(text)) return false;
function getTranslation(text){ return true;
if(! text) return undefined }
if(translated_lines[text] === undefined){ function getTranslation(text) {
original_lines[text] = 1 if (!text) return undefined;
}
if (translated_lines[text] === undefined) {
tl = localization[text] original_lines[text] = 1;
if(tl !== undefined){ }
translated_lines[tl] = 1
} var tl = localization[text];
if (tl !== undefined) {
return tl translated_lines[tl] = 1;
} }
function processTextNode(node){ return tl;
text = node.textContent.trim() }
if(! canBeTranslated(node, text)) return function processTextNode(node) {
var text = node.textContent.trim();
tl = getTranslation(text)
if(tl !== undefined){ if (!canBeTranslated(node, text)) return;
node.textContent = tl
} var tl = getTranslation(text);
} if (tl !== undefined) {
node.textContent = tl;
function processNode(node){ }
if(node.nodeType == 3){ }
processTextNode(node)
return function processNode(node) {
} if (node.nodeType == 3) {
processTextNode(node);
if(node.title){ return;
tl = getTranslation(node.title) }
if(tl !== undefined){
node.title = tl if (node.title) {
} let tl = getTranslation(node.title);
} if (tl !== undefined) {
node.title = tl;
if(node.placeholder){ }
tl = getTranslation(node.placeholder) }
if(tl !== undefined){
node.placeholder = tl if (node.placeholder) {
} let tl = getTranslation(node.placeholder);
} if (tl !== undefined) {
node.placeholder = tl;
textNodesUnder(node).forEach(function(node){ }
processTextNode(node) }
})
} textNodesUnder(node).forEach(function(node) {
processTextNode(node);
function dumpTranslations(){ });
dumped = {} }
if (localization.rtl) {
dumped.rtl = true function localizeWholePage() {
} processNode(gradioApp());
Object.keys(original_lines).forEach(function(text){ function elem(comp) {
if(dumped[text] !== undefined) return var elem_id = comp.props.elem_id ? comp.props.elem_id : "component-" + comp.id;
return gradioApp().getElementById(elem_id);
dumped[text] = localization[text] || text }
})
for (var comp of window.gradio_config.components) {
return dumped if (comp.props.webui_tooltip) {
} let e = elem(comp);
onUiUpdate(function(m){ let tl = e ? getTranslation(e.title) : undefined;
m.forEach(function(mutation){ if (tl !== undefined) {
mutation.addedNodes.forEach(function(node){ e.title = tl;
processNode(node) }
}) }
}); if (comp.props.placeholder) {
}) let e = elem(comp);
let textbox = e ? e.querySelector('[placeholder]') : null;
document.addEventListener("DOMContentLoaded", function() { let tl = textbox ? getTranslation(textbox.placeholder) : undefined;
processNode(gradioApp()) if (tl !== undefined) {
textbox.placeholder = tl;
if (localization.rtl) { // if the language is from right to left, }
(new MutationObserver((mutations, observer) => { // wait for the style to load }
mutations.forEach(mutation => { }
mutation.addedNodes.forEach(node => { }
if (node.tagName === 'STYLE') {
observer.disconnect(); function dumpTranslations() {
if (!hasLocalization()) {
for (const x of node.sheet.rules) { // find all rtl media rules // If we don't have any localization,
if (Array.from(x.media || []).includes('rtl')) { // we will not have traversed the app to find
x.media.appendMedium('all'); // enable them // original_lines, so do that now.
} localizeWholePage();
} }
} var dumped = {};
}) if (localization.rtl) {
}); dumped.rtl = true;
})).observe(gradioApp(), { childList: true }); }
}
}) for (const text in original_lines) {
if (dumped[text] !== undefined) continue;
function download_localization() { dumped[text] = localization[text] || text;
text = JSON.stringify(dumpTranslations(), null, 4) }
var element = document.createElement('a'); return dumped;
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); }
element.setAttribute('download', "localization.json");
element.style.display = 'none'; function download_localization() {
document.body.appendChild(element); var text = JSON.stringify(dumpTranslations(), null, 4);
element.click(); var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
document.body.removeChild(element); element.setAttribute('download', "localization.json");
} element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
document.addEventListener("DOMContentLoaded", function() {
if (!hasLocalization()) {
return;
}
onUiUpdate(function(m) {
m.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
processNode(node);
});
});
});
localizeWholePage();
if (localization.rtl) { // if the language is from right to left,
(new MutationObserver((mutations, observer) => { // wait for the style to load
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.tagName === 'STYLE') {
observer.disconnect();
for (const x of node.sheet.rules) { // find all rtl media rules
if (Array.from(x.media || []).includes('rtl')) {
x.media.appendMedium('all'); // enable them
}
}
}
});
});
})).observe(gradioApp(), {childList: true});
}
});
+10 -10
View File
@@ -2,20 +2,20 @@
let lastHeadImg = null; let lastHeadImg = null;
notificationButton = null let notificationButton = null;
onUiUpdate(function(){ onAfterUiUpdate(function() {
if(notificationButton == null){ if (notificationButton == null) {
notificationButton = gradioApp().getElementById('request_notifications') notificationButton = gradioApp().getElementById('request_notifications');
if(notificationButton != null){ if (notificationButton != null) {
notificationButton.addEventListener('click', function (evt) { notificationButton.addEventListener('click', () => {
Notification.requestPermission(); void Notification.requestPermission();
},true); }, true);
} }
} }
const galleryPreviews = gradioApp().querySelectorAll('div[id^="tab_"][style*="display: block"] img.h-full.w-full.overflow-hidden'); const galleryPreviews = gradioApp().querySelectorAll('div[id^="tab_"] div[id$="_results"] .thumbnail-item > img');
if (galleryPreviews == null) return; if (galleryPreviews == null) return;
@@ -42,7 +42,7 @@ onUiUpdate(function(){
} }
); );
notification.onclick = function(_){ notification.onclick = function(_) {
parent.focus(); parent.focus();
this.close(); this.close();
}; };
+153
View File
@@ -0,0 +1,153 @@
function createRow(table, cellName, items) {
var tr = document.createElement('tr');
var res = [];
items.forEach(function(x, i) {
if (x === undefined) {
res.push(null);
return;
}
var td = document.createElement(cellName);
td.textContent = x;
tr.appendChild(td);
res.push(td);
var colspan = 1;
for (var n = i + 1; n < items.length; n++) {
if (items[n] !== undefined) {
break;
}
colspan += 1;
}
if (colspan > 1) {
td.colSpan = colspan;
}
});
table.appendChild(tr);
return res;
}
function showProfile(path, cutoff = 0.05) {
requestGet(path, {}, function(data) {
var table = document.createElement('table');
table.className = 'popup-table';
data.records['total'] = data.total;
var keys = Object.keys(data.records).sort(function(a, b) {
return data.records[b] - data.records[a];
});
var items = keys.map(function(x) {
return {key: x, parts: x.split('/'), time: data.records[x]};
});
var maxLength = items.reduce(function(a, b) {
return Math.max(a, b.parts.length);
}, 0);
var cols = createRow(table, 'th', ['record', 'seconds']);
cols[0].colSpan = maxLength;
function arraysEqual(a, b) {
return !(a < b || b < a);
}
var addLevel = function(level, parent, hide) {
var matching = items.filter(function(x) {
return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent);
});
var sorted = matching.sort(function(a, b) {
return b.time - a.time;
});
var othersTime = 0;
var othersList = [];
var othersRows = [];
var childrenRows = [];
sorted.forEach(function(x) {
var visible = x.time >= cutoff && !hide;
var cells = [];
for (var i = 0; i < maxLength; i++) {
cells.push(x.parts[i]);
}
cells.push(x.time.toFixed(3));
var cols = createRow(table, 'td', cells);
for (i = 0; i < level; i++) {
cols[i].className = 'muted';
}
var tr = cols[0].parentNode;
if (!visible) {
tr.classList.add("hidden");
}
if (x.time >= cutoff) {
childrenRows.push(tr);
} else {
othersTime += x.time;
othersList.push(x.parts[level]);
othersRows.push(tr);
}
var children = addLevel(level + 1, parent.concat([x.parts[level]]), true);
if (children.length > 0) {
var cell = cols[level];
var onclick = function() {
cell.classList.remove("link");
cell.removeEventListener("click", onclick);
children.forEach(function(x) {
x.classList.remove("hidden");
});
};
cell.classList.add("link");
cell.addEventListener("click", onclick);
}
});
if (othersTime > 0) {
var cells = [];
for (var i = 0; i < maxLength; i++) {
cells.push(parent[i]);
}
cells.push(othersTime.toFixed(3));
cells[level] = 'others';
var cols = createRow(table, 'td', cells);
for (i = 0; i < level; i++) {
cols[i].className = 'muted';
}
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");
});
};
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, []);
popup(table);
});
}
+117 -174
View File
@@ -1,95 +1,29 @@
// code related to showing and updating progressbar shown as the image is being made // code related to showing and updating progressbar shown as the image is being made
function rememberGallerySelection() {
galleries = {}
storedGallerySelections = {}
galleryObservers = {}
function rememberGallerySelection(id_gallery){
storedGallerySelections[id_gallery] = getGallerySelectedIndex(id_gallery)
} }
function getGallerySelectedIndex(id_gallery){ function getGallerySelectedIndex() {
let galleryButtons = gradioApp().querySelectorAll('#'+id_gallery+' .gallery-item')
let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
let currentlySelectedIndex = -1
galleryButtons.forEach(function(v, i){ if(v==galleryBtnSelected) { currentlySelectedIndex = i } })
return currentlySelectedIndex
} }
// this is a workaround for https://github.com/gradio-app/gradio/issues/2984 function request(url, data, handler, errorHandler) {
function check_gallery(id_gallery){
let gallery = gradioApp().getElementById(id_gallery)
// if gallery has no change, no need to setting up observer again.
if (gallery && galleries[id_gallery] !== gallery){
galleries[id_gallery] = gallery;
if(galleryObservers[id_gallery]){
galleryObservers[id_gallery].disconnect();
}
storedGallerySelections[id_gallery] = -1
galleryObservers[id_gallery] = new MutationObserver(function (){
let galleryButtons = gradioApp().querySelectorAll('#'+id_gallery+' .gallery-item')
let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
let currentlySelectedIndex = getGallerySelectedIndex(id_gallery)
prevSelectedIndex = storedGallerySelections[id_gallery]
storedGallerySelections[id_gallery] = -1
if (prevSelectedIndex !== -1 && galleryButtons.length>prevSelectedIndex && !galleryBtnSelected) {
// automatically re-open previously selected index (if exists)
activeElement = gradioApp().activeElement;
let scrollX = window.scrollX;
let scrollY = window.scrollY;
galleryButtons[prevSelectedIndex].click();
showGalleryImage();
// When the gallery button is clicked, it gains focus and scrolls itself into view
// We need to scroll back to the previous position
setTimeout(function (){
window.scrollTo(scrollX, scrollY);
}, 50);
if(activeElement){
// i fought this for about an hour; i don't know why the focus is lost or why this helps recover it
// if someone has a better solution please by all means
setTimeout(function (){
activeElement.focus({
preventScroll: true // Refocus the element that was focused before the gallery was opened without scrolling to it
})
}, 1);
}
}
})
galleryObservers[id_gallery].observe( gallery, { childList:true, subtree:false })
}
}
onUiUpdate(function(){
check_gallery('txt2img_gallery')
check_gallery('img2img_gallery')
})
function request(url, data, handler, errorHandler){
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
var url = url;
xhr.open("POST", url, true); xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () { xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { if (xhr.readyState === 4) {
if (xhr.status === 200) { if (xhr.status === 200) {
try { try {
var js = JSON.parse(xhr.responseText); var js = JSON.parse(xhr.responseText);
handler(js) handler(js);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
errorHandler() errorHandler();
} }
} else{ } else {
errorHandler() errorHandler();
} }
} }
}; };
@@ -97,147 +31,156 @@ function request(url, data, handler, errorHandler){
xhr.send(js); xhr.send(js);
} }
function pad2(x){ function pad2(x) {
return x<10 ? '0'+x : x return x < 10 ? '0' + x : x;
} }
function formatTime(secs){ function formatTime(secs) {
if(secs > 3600){ if (secs > 3600) {
return pad2(Math.floor(secs/60/60)) + ":" + pad2(Math.floor(secs/60)%60) + ":" + pad2(Math.floor(secs)%60) return pad2(Math.floor(secs / 60 / 60)) + ":" + pad2(Math.floor(secs / 60) % 60) + ":" + pad2(Math.floor(secs) % 60);
} else if(secs > 60){ } else if (secs > 60) {
return pad2(Math.floor(secs/60)) + ":" + pad2(Math.floor(secs)%60) return pad2(Math.floor(secs / 60)) + ":" + pad2(Math.floor(secs) % 60);
} else{ } else {
return Math.floor(secs) + "s" return Math.floor(secs) + "s";
} }
} }
function setTitle(progress){ function setTitle(progress) {
var title = 'Stable Diffusion' var title = 'Stable Diffusion';
if(opts.show_progress_in_title && progress){ if (opts.show_progress_in_title && progress) {
title = '[' + progress.trim() + '] ' + title; title = '[' + progress.trim() + '] ' + title;
} }
if(document.title != title){ if (document.title != title) {
document.title = title; document.title = title;
} }
} }
function randomId(){ function randomId() {
return "task(" + Math.random().toString(36).slice(2, 7) + Math.random().toString(36).slice(2, 7) + Math.random().toString(36).slice(2, 7)+")" return "task(" + Math.random().toString(36).slice(2, 7) + Math.random().toString(36).slice(2, 7) + Math.random().toString(36).slice(2, 7) + ")";
} }
// starts sending progress requests to "/internal/progress" uri, creating progressbar above progressbarContainer element and // starts sending progress requests to "/internal/progress" uri, creating progressbar above progressbarContainer element and
// preview inside gallery element. Cleans up all created stuff when the task is over and calls atEnd. // preview inside gallery element. Cleans up all created stuff when the task is over and calls atEnd.
// calls onProgress every time there is a progress update // calls onProgress every time there is a progress update
function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgress){ function requestProgress(id_task, progressbarContainer, gallery, atEnd, onProgress, inactivityTimeout = 40) {
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 divProgress = document.createElement('div') var divProgress = document.createElement('div');
divProgress.className='progressDiv' divProgress.className = 'progressDiv';
divProgress.style.display = opts.show_progressbar ? "" : "none" divProgress.style.display = opts.show_progressbar ? "block" : "none";
var divInner = document.createElement('div') var divInner = document.createElement('div');
divInner.className='progress' divInner.className = 'progress';
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() {
setTitle("") if (!divProgress) return;
parentProgressbar.removeChild(divProgress)
if(parentGallery) parentGallery.removeChild(livePreview)
atEnd()
}
var fun = function(id_task, id_live_preview){ setTitle("");
request("./internal/progress", {"id_task": id_task, "id_live_preview": id_live_preview}, function(res){ parentProgressbar.removeChild(divProgress);
if(res.completed){ if (gallery && livePreview) gallery.removeChild(livePreview);
removeProgressBar() atEnd();
return
divProgress = null;
};
var funProgress = function(id_task) {
request("./internal/progress", {id_task: id_task, live_preview: false}, function(res) {
if (res.completed) {
removeProgressBar();
return;
} }
var rect = progressbarContainer.getBoundingClientRect() let progressText = "";
if(rect.width){ divInner.style.width = ((res.progress || 0) * 100.0) + '%';
divProgress.style.width = rect.width + "px"; divInner.style.background = res.progress ? "" : "transparent";
if (res.progress > 0) {
progressText = ((res.progress || 0) * 100.0).toFixed(0) + '%';
} }
progressText = "" if (res.eta) {
progressText += " ETA: " + formatTime(res.eta);
divInner.style.width = ((res.progress || 0) * 100.0) + '%'
divInner.style.background = res.progress ? "" : "transparent"
if(res.progress > 0){
progressText = ((res.progress || 0) * 100.0).toFixed(0) + '%'
} }
if(res.eta){ setTitle(progressText);
progressText += " ETA: " + formatTime(res.eta)
if (res.textinfo && res.textinfo.indexOf("\n") == -1) {
progressText = res.textinfo + " " + progressText;
} }
divInner.textContent = progressText;
setTitle(progressText) var elapsedFromStart = (new Date() - dateStart) / 1000;
if(res.textinfo && res.textinfo.indexOf("\n") == -1){ if (res.active) wasEverActive = true;
progressText = res.textinfo + " " + progressText
if (!res.active && wasEverActive) {
removeProgressBar();
return;
} }
divInner.textContent = progressText if (elapsedFromStart > inactivityTimeout && !res.queued && !res.active) {
removeProgressBar();
var elapsedFromStart = (new Date() - dateStart) / 1000 return;
if(res.active) wasEverActive = true;
if(! res.active && wasEverActive){
removeProgressBar()
return
} }
if(elapsedFromStart > 5 && !res.queued && !res.active){ if (onProgress) {
removeProgressBar() onProgress(res);
return
}
if(res.live_preview && gallery){
var rect = gallery.getBoundingClientRect()
if(rect.width){
livePreview.style.width = rect.width + "px"
livePreview.style.height = rect.height + "px"
}
var img = new Image();
img.onload = function() {
livePreview.appendChild(img)
if(livePreview.childElementCount > 2){
livePreview.removeChild(livePreview.firstElementChild)
}
}
img.src = res.live_preview;
}
if(onProgress){
onProgress(res)
} }
setTimeout(() => { setTimeout(() => {
fun(id_task, res.id_live_preview); funProgress(id_task, res.id_live_preview);
}, opts.live_preview_refresh_period || 500) }, opts.live_preview_refresh_period || 500);
}, function(){ }, function() {
removeProgressBar() 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) {
var img = new Image();
img.onload = function() {
if (!livePreview) {
livePreview = document.createElement('div');
livePreview.className = 'livePreview';
gallery.insertBefore(livePreview, gallery.firstElementChild);
}
livePreview.appendChild(img);
if (livePreview.childElementCount > 2) {
livePreview.removeChild(livePreview.firstElementChild);
}
};
img.src = res.live_preview;
}
setTimeout(() => {
funLivePreview(id_task, res.id_live_preview);
}, opts.live_preview_refresh_period || 500);
}, function() {
removeProgressBar();
});
};
funProgress(id_task, 0);
if (gallery) {
funLivePreview(id_task, 0);
} }
fun(id_task, 0)
} }
+141
View File
@@ -0,0 +1,141 @@
(function() {
const GRADIO_MIN_WIDTH = 320;
const GRID_TEMPLATE_COLUMNS = '1fr 16px 1fr';
const PAD = 16;
const DEBOUNCE_TIME = 100;
const R = {
tracking: false,
parent: null,
parentWidth: null,
leftCol: null,
leftColStartWidth: null,
screenX: null,
};
let resizeTimer;
let parents = [];
function setLeftColGridTemplate(el, width) {
el.style.gridTemplateColumns = `${width}px 16px 1fr`;
}
function displayResizeHandle(parent) {
if (window.innerWidth < GRADIO_MIN_WIDTH * 2 + PAD * 4) {
parent.style.display = 'flex';
if (R.handle != null) {
R.handle.style.opacity = '0';
}
return false;
} else {
parent.style.display = 'grid';
if (R.handle != null) {
R.handle.style.opacity = '100';
}
return true;
}
}
function afterResize(parent) {
if (displayResizeHandle(parent) && parent.style.gridTemplateColumns != GRID_TEMPLATE_COLUMNS) {
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), GRADIO_MIN_WIDTH);
setLeftColGridTemplate(parent, newWidthL);
R.parentWidth = newParentWidth;
}
}
function setup(parent) {
const leftCol = parent.firstElementChild;
const rightCol = parent.lastElementChild;
parents.push(parent);
parent.style.display = 'grid';
parent.style.gap = '0';
parent.style.gridTemplateColumns = GRID_TEMPLATE_COLUMNS;
const resizeHandle = document.createElement('div');
resizeHandle.classList.add('resize-handle');
parent.insertBefore(resizeHandle, rightCol);
resizeHandle.addEventListener('mousedown', (evt) => {
if (evt.button !== 0) return;
evt.preventDefault();
evt.stopPropagation();
document.body.classList.add('resizing');
R.tracking = true;
R.parent = parent;
R.parentWidth = parent.offsetWidth;
R.handle = resizeHandle;
R.leftCol = leftCol;
R.leftColStartWidth = leftCol.offsetWidth;
R.screenX = evt.screenX;
});
resizeHandle.addEventListener('dblclick', (evt) => {
evt.preventDefault();
evt.stopPropagation();
parent.style.gridTemplateColumns = GRID_TEMPLATE_COLUMNS;
});
afterResize(parent);
}
window.addEventListener('mousemove', (evt) => {
if (evt.button !== 0) return;
if (R.tracking) {
evt.preventDefault();
evt.stopPropagation();
const delta = R.screenX - evt.screenX;
const leftColWidth = Math.max(Math.min(R.leftColStartWidth - delta, R.parent.offsetWidth - GRADIO_MIN_WIDTH - PAD), GRADIO_MIN_WIDTH);
setLeftColGridTemplate(R.parent, leftColWidth);
}
});
window.addEventListener('mouseup', (evt) => {
if (evt.button !== 0) 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;
})();
onUiLoaded(function() {
for (var elem of gradioApp().querySelectorAll('.resize-handle-row')) {
if (!elem.querySelector('.resize-handle')) {
setupResizeHandle(elem);
}
}
});
+46
View File
@@ -0,0 +1,46 @@
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);
});
+17 -17
View File
@@ -1,17 +1,17 @@
function start_training_textual_inversion(){ function start_training_textual_inversion() {
gradioApp().querySelector('#ti_error').innerHTML='' gradioApp().querySelector('#ti_error').innerHTML = '';
var id = randomId() var id = randomId();
requestProgress(id, gradioApp().getElementById('ti_output'), gradioApp().getElementById('ti_gallery'), function(){}, function(progress){ requestProgress(id, gradioApp().getElementById('ti_output'), gradioApp().getElementById('ti_gallery'), function() {}, function(progress) {
gradioApp().getElementById('ti_progress').innerHTML = progress.textinfo gradioApp().getElementById('ti_progress').innerHTML = progress.textinfo;
}) });
var res = args_to_array(arguments) var res = Array.from(arguments);
res[0] = id res[0] = id;
return res return res;
} }
+75
View File
@@ -0,0 +1,75 @@
let promptTokenCountUpdateFunctions = {};
function update_txt2img_tokens(...args) {
// Called from Gradio
update_token_counter("txt2img_token_button");
update_token_counter("txt2img_negative_token_button");
if (args.length == 2) {
return args[0];
}
return args;
}
function update_img2img_tokens(...args) {
// Called from Gradio
update_token_counter("img2img_token_button");
update_token_counter("img2img_negative_token_button");
if (args.length == 2) {
return args[0];
}
return args;
}
function update_token_counter(button_id) {
promptTokenCountUpdateFunctions[button_id]?.();
}
function recalculatePromptTokens(name) {
promptTokenCountUpdateFunctions[name]?.();
}
function recalculate_prompts_txt2img() {
// Called from Gradio
recalculatePromptTokens('txt2img_prompt');
recalculatePromptTokens('txt2img_neg_prompt');
return Array.from(arguments);
}
function recalculate_prompts_img2img() {
// Called from Gradio
recalculatePromptTokens('img2img_prompt');
recalculatePromptTokens('img2img_neg_prompt');
return Array.from(arguments);
}
function setupTokenCounting(id, id_counter, id_button) {
var prompt = gradioApp().getElementById(id);
var counter = gradioApp().getElementById(id_counter);
var textarea = gradioApp().querySelector(`#${id} > label > textarea`);
if (opts.disable_token_counters) {
counter.style.display = "none";
return;
}
if (counter.parentElement == prompt.parentElement) {
return;
}
prompt.parentElement.insertBefore(counter, prompt);
prompt.parentElement.style.position = "relative";
var func = onEdit(id, textarea, 800, function() {
gradioApp().getElementById(id_button)?.click();
});
promptTokenCountUpdateFunctions[id] = func;
promptTokenCountUpdateFunctions[id_button] = func;
}
function setupTokenCounters() {
setupTokenCounting('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button');
setupTokenCounting('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button');
setupTokenCounting('img2img_prompt', 'img2img_token_counter', 'img2img_token_button');
setupTokenCounting('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button');
}
+256 -197
View File
@@ -1,207 +1,246 @@
// various functions for interaction with ui.py not large enough to warrant putting them in separate files // various functions for interaction with ui.py not large enough to warrant putting them in separate files
function set_theme(theme){ function set_theme(theme) {
gradioURL = window.location.href var gradioURL = window.location.href;
if (!gradioURL.includes('?__theme=')) { if (!gradioURL.includes('?__theme=')) {
window.location.replace(gradioURL + '?__theme=' + theme); window.location.replace(gradioURL + '?__theme=' + theme);
} }
} }
function selected_gallery_index(){ function all_gallery_buttons() {
var buttons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery] .gallery-item') var allGalleryButtons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery].gradio-gallery .thumbnails > .thumbnail-item.thumbnail-small');
var button = gradioApp().querySelector('[style="display: block;"].tabitem div[id$=_gallery] .gallery-item.\\!ring-2') var visibleGalleryButtons = [];
allGalleryButtons.forEach(function(elem) {
var result = -1 if (elem.parentElement.offsetParent) {
buttons.forEach(function(v, i){ if(v==button) { result = i } }) visibleGalleryButtons.push(elem);
}
return result });
return visibleGalleryButtons;
} }
function extract_image_from_gallery(gallery){ function selected_gallery_button() {
if(gallery.length == 1){ return all_gallery_buttons().find(elem => elem.classList.contains('selected')) ?? null;
return [gallery[0]] }
function selected_gallery_index() {
return all_gallery_buttons().findIndex(elem => elem.classList.contains('selected'));
}
function extract_image_from_gallery(gallery) {
if (gallery.length == 0) {
return [null];
}
if (gallery.length == 1) {
return [gallery[0]];
} }
index = selected_gallery_index() var index = selected_gallery_index();
if (index < 0 || index >= gallery.length){ if (index < 0 || index >= gallery.length) {
return [null] // Use the first image in the gallery as the default
index = 0;
} }
return [gallery[index]]; return [gallery[index]];
} }
function args_to_array(args){ window.args_to_array = Array.from; // Compatibility with e.g. extensions that may expect this to be around
res = []
for(var i=0;i<args.length;i++){
res.push(args[i])
}
return res
}
function switch_to_txt2img(){ function switch_to_txt2img() {
gradioApp().querySelector('#tabs').querySelectorAll('button')[0].click(); gradioApp().querySelector('#tabs').querySelectorAll('button')[0].click();
return args_to_array(arguments); return Array.from(arguments);
} }
function switch_to_img2img_tab(no){ function switch_to_img2img_tab(no) {
gradioApp().querySelector('#tabs').querySelectorAll('button')[1].click(); gradioApp().querySelector('#tabs').querySelectorAll('button')[1].click();
gradioApp().getElementById('mode_img2img').querySelectorAll('button')[no].click(); gradioApp().getElementById('mode_img2img').querySelectorAll('button')[no].click();
} }
function switch_to_img2img(){ function switch_to_img2img() {
switch_to_img2img_tab(0); switch_to_img2img_tab(0);
return args_to_array(arguments); return Array.from(arguments);
} }
function switch_to_sketch(){ function switch_to_sketch() {
switch_to_img2img_tab(1); switch_to_img2img_tab(1);
return args_to_array(arguments); return Array.from(arguments);
} }
function switch_to_inpaint(){ function switch_to_inpaint() {
switch_to_img2img_tab(2); switch_to_img2img_tab(2);
return args_to_array(arguments); return Array.from(arguments);
} }
function switch_to_inpaint_sketch(){ function switch_to_inpaint_sketch() {
switch_to_img2img_tab(3); switch_to_img2img_tab(3);
return args_to_array(arguments); return Array.from(arguments);
} }
function switch_to_inpaint(){ function switch_to_extras() {
gradioApp().querySelector('#tabs').querySelectorAll('button')[1].click();
gradioApp().getElementById('mode_img2img').querySelectorAll('button')[2].click();
return args_to_array(arguments);
}
function switch_to_extras(){
gradioApp().querySelector('#tabs').querySelectorAll('button')[2].click(); gradioApp().querySelector('#tabs').querySelectorAll('button')[2].click();
return args_to_array(arguments); return Array.from(arguments);
} }
function get_tab_index(tabId){ function get_tab_index(tabId) {
var res = 0 let buttons = gradioApp().getElementById(tabId).querySelector('div').querySelectorAll('button');
for (let i = 0; i < buttons.length; i++) {
gradioApp().getElementById(tabId).querySelector('div').querySelectorAll('button').forEach(function(button, i){ if (buttons[i].classList.contains('selected')) {
if(button.className.indexOf('bg-white') != -1) return i;
res = i }
})
return res
}
function create_tab_index_args(tabId, args){
var res = []
for(var i=0; i<args.length; i++){
res.push(args[i])
} }
return 0;
}
res[0] = get_tab_index(tabId) function create_tab_index_args(tabId, args) {
var res = Array.from(args);
return res res[0] = get_tab_index(tabId);
return res;
} }
function get_img2img_tab_index() { function get_img2img_tab_index() {
let res = args_to_array(arguments) let res = Array.from(arguments);
res.splice(-2) res.splice(-2);
res[0] = get_tab_index('mode_img2img') res[0] = get_tab_index('mode_img2img');
return res return res;
} }
function create_submit_args(args){ function create_submit_args(args) {
res = [] var res = Array.from(args);
for(var i=0;i<args.length;i++){
res.push(args[i])
}
// As it is currently, txt2img and img2img send back the previous output args (txt2img_gallery, generation_info, html_info) whenever you generate a new image. // As it is currently, txt2img and img2img send back the previous output args (txt2img_gallery, generation_info, html_info) whenever you generate a new image.
// This can lead to uploading a huge gallery of previously generated images, which leads to an unnecessary delay between submitting and beginning to generate. // This can lead to uploading a huge gallery of previously generated images, which leads to an unnecessary delay between submitting and beginning to generate.
// I don't know why gradio is sending outputs along with inputs, but we can prevent sending the image gallery here, which seems to be an issue for some. // I don't know why gradio is sending outputs along with inputs, but we can prevent sending the image gallery here, which seems to be an issue for some.
// If gradio at some point stops sending outputs, this may break something // If gradio at some point stops sending outputs, this may break something
if(Array.isArray(res[res.length - 3])){ if (Array.isArray(res[res.length - 3])) {
res[res.length - 3] = null res[res.length - 3] = null;
} }
return res return res;
} }
function showSubmitButtons(tabname, show){ function showSubmitButtons(tabname, show) {
gradioApp().getElementById(tabname+'_interrupt').style.display = show ? "none" : "block" gradioApp().getElementById(tabname + '_interrupt').style.display = show ? "none" : "block";
gradioApp().getElementById(tabname+'_skip').style.display = show ? "none" : "block" gradioApp().getElementById(tabname + '_skip').style.display = show ? "none" : "block";
} }
function submit(){ function showRestoreProgressButton(tabname, show) {
rememberGallerySelection('txt2img_gallery') var button = gradioApp().getElementById(tabname + "_restore_progress");
showSubmitButtons('txt2img', false) if (!button) return;
var id = randomId() button.style.display = show ? "flex" : "none";
requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function(){
showSubmitButtons('txt2img', true)
})
var res = create_submit_args(arguments)
res[0] = id
return res
} }
function submit_img2img(){ function submit() {
rememberGallerySelection('img2img_gallery') showSubmitButtons('txt2img', false);
showSubmitButtons('img2img', false)
var id = randomId() var id = randomId();
requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function(){ localSet("txt2img_task_id", id);
showSubmitButtons('img2img', true)
})
var res = create_submit_args(arguments) requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() {
showSubmitButtons('txt2img', true);
localRemove("txt2img_task_id");
showRestoreProgressButton('txt2img', false);
});
res[0] = id var res = create_submit_args(arguments);
res[1] = get_tab_index('mode_img2img')
return res res[0] = id;
return res;
} }
function modelmerger(){ function submit_img2img() {
var id = randomId() showSubmitButtons('img2img', false);
requestProgress(id, gradioApp().getElementById('modelmerger_results_panel'), null, function(){})
var res = create_submit_args(arguments) var id = randomId();
res[0] = id localSet("img2img_task_id", id);
return res
requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() {
showSubmitButtons('img2img', true);
localRemove("img2img_task_id");
showRestoreProgressButton('img2img', false);
});
var res = create_submit_args(arguments);
res[0] = id;
res[1] = get_tab_index('mode_img2img');
return res;
}
function restoreProgressTxt2img() {
showRestoreProgressButton("txt2img", false);
var id = localGet("txt2img_task_id");
if (id) {
requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() {
showSubmitButtons('txt2img', true);
}, null, 0);
}
return id;
}
function restoreProgressImg2img() {
showRestoreProgressButton("img2img", false);
var id = localGet("img2img_task_id");
if (id) {
requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() {
showSubmitButtons('img2img', true);
}, null, 0);
}
return id;
}
onUiLoaded(function() {
showRestoreProgressButton('txt2img', localGet("txt2img_task_id"));
showRestoreProgressButton('img2img', localGet("img2img_task_id"));
});
function modelmerger() {
var id = randomId();
requestProgress(id, gradioApp().getElementById('modelmerger_results_panel'), null, function() {});
var res = create_submit_args(arguments);
res[0] = id;
return res;
} }
function ask_for_style_name(_, prompt_text, negative_prompt_text) { function ask_for_style_name(_, prompt_text, negative_prompt_text) {
name_ = prompt('Style name:') var name_ = prompt('Style name:');
return [name_, prompt_text, negative_prompt_text] return [name_, prompt_text, negative_prompt_text];
} }
function confirm_clear_prompt(prompt, negative_prompt) { function confirm_clear_prompt(prompt, negative_prompt) {
if(confirm("Delete prompt?")) { if (confirm("Delete prompt?")) {
prompt = "" prompt = "";
negative_prompt = "" negative_prompt = "";
} }
return [prompt, negative_prompt] return [prompt, negative_prompt];
} }
opts = {}
onUiUpdate(function(){
if(Object.keys(opts).length != 0) return;
json_elem = gradioApp().getElementById('settings_json') var opts = {};
if(json_elem == null) return; onAfterUiUpdate(function() {
if (Object.keys(opts).length != 0) return;
var textarea = json_elem.querySelector('textarea') var json_elem = gradioApp().getElementById('settings_json');
var jsdata = textarea.value if (json_elem == null) return;
opts = JSON.parse(jsdata)
executeCallbacks(optionsChangedCallbacks); var textarea = json_elem.querySelector('textarea');
var jsdata = textarea.value;
opts = JSON.parse(jsdata);
executeCallbacks(optionsChangedCallbacks); /*global optionsChangedCallbacks*/
Object.defineProperty(textarea, 'value', { Object.defineProperty(textarea, 'value', {
set: function(newValue) { set: function(newValue) {
@@ -210,7 +249,7 @@ onUiUpdate(function(){
valueProp.set.call(textarea, newValue); valueProp.set.call(textarea, newValue);
if (oldValue != newValue) { if (oldValue != newValue) {
opts = JSON.parse(textarea.value) opts = JSON.parse(textarea.value);
} }
executeCallbacks(optionsChangedCallbacks); executeCallbacks(optionsChangedCallbacks);
@@ -221,91 +260,111 @@ onUiUpdate(function(){
} }
}); });
json_elem.parentElement.style.display="none" json_elem.parentElement.style.display = "none";
function registerTextarea(id, id_counter, id_button){ setupTokenCounters();
var prompt = gradioApp().getElementById(id) });
var counter = gradioApp().getElementById(id_counter)
var textarea = gradioApp().querySelector("#" + id + " > label > textarea");
if(counter.parentElement == prompt.parentElement){ onOptionsChanged(function() {
return var elem = gradioApp().getElementById('sd_checkpoint_hash');
} var sd_checkpoint_hash = opts.sd_checkpoint_hash || "";
var shorthash = sd_checkpoint_hash.substring(0, 10);
if (elem && elem.textContent != shorthash) {
prompt.parentElement.insertBefore(counter, prompt) elem.textContent = shorthash;
counter.classList.add("token-counter") elem.title = sd_checkpoint_hash;
prompt.parentElement.style.position = "relative" elem.href = "https://google.com/search?q=" + sd_checkpoint_hash;
textarea.addEventListener("input", function(){
update_token_counter(id_button);
});
} }
});
registerTextarea('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button')
registerTextarea('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button')
registerTextarea('img2img_prompt', 'img2img_token_counter', 'img2img_token_button')
registerTextarea('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button')
show_all_pages = gradioApp().getElementById('settings_show_all_pages')
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){
elem.style.display = "block";
})
}
}
})
onOptionsChanged(function(){
elem = gradioApp().getElementById('sd_checkpoint_hash')
sd_checkpoint_hash = opts.sd_checkpoint_hash || ""
shorthash = sd_checkpoint_hash.substr(0,10)
if(elem && elem.textContent != shorthash){
elem.textContent = shorthash
elem.title = sd_checkpoint_hash
elem.href = "https://google.com/search?q=" + sd_checkpoint_hash
}
})
let txt2img_textarea, img2img_textarea = undefined; let txt2img_textarea, img2img_textarea = undefined;
let wait_time = 800
let token_timeout;
function update_txt2img_tokens(...args) { function restart_reload() {
update_token_counter("txt2img_token_button") document.body.innerHTML = '<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>';
if (args.length == 2)
return args[0]
return args;
}
function update_img2img_tokens(...args) { var requestPing = function() {
update_token_counter("img2img_token_button") requestGet("./internal/ping", {}, function(data) {
if (args.length == 2) location.reload();
return args[0] }, function() {
return args; setTimeout(requestPing, 500);
} });
};
function update_token_counter(button_id) { setTimeout(requestPing, 2000);
if (token_timeout)
clearTimeout(token_timeout);
token_timeout = setTimeout(() => gradioApp().getElementById(button_id)?.click(), wait_time);
}
function restart_reload(){ return [];
document.body.innerHTML='<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>';
setTimeout(function(){location.reload()},2000)
return []
} }
// Simulate an `input` DOM event for Gradio Textbox component. Needed after you edit its contents in javascript, otherwise your edits // Simulate an `input` DOM event for Gradio Textbox component. Needed after you edit its contents in javascript, otherwise your edits
// will only visible on web page and not sent to python. // will only visible on web page and not sent to python.
function updateInput(target){ function updateInput(target) {
let e = new Event("input", { bubbles: true }) let e = new Event("input", {bubbles: true});
Object.defineProperty(e, "target", {value: target}) Object.defineProperty(e, "target", {value: target});
target.dispatchEvent(e); target.dispatchEvent(e);
}
var desiredCheckpointName = null;
function selectCheckpoint(name) {
desiredCheckpointName = name;
gradioApp().getElementById('change_checkpoint').click();
}
function currentImg2imgSourceResolution(w, h, scaleBy) {
var img = gradioApp().querySelector('#mode_img2img > div[style="display: block;"] img');
return img ? [img.naturalWidth, img.naturalHeight, scaleBy] : [0, 0, scaleBy];
}
function updateImg2imgResizeToTextAfterChangingImage() {
// At the time this is called from gradio, the image has no yet been replaced.
// There may be a better solution, but this is simple and straightforward so I'm going with it.
setTimeout(function() {
gradioApp().getElementById('img2img_update_resize_to').click();
}, 500);
return [];
}
function setRandomSeed(elem_id) {
var input = gradioApp().querySelector("#" + elem_id + " input");
if (!input) return [];
input.value = "-1";
updateInput(input);
return [];
}
function switchWidthHeight(tabname) {
var width = gradioApp().querySelector("#" + tabname + "_width input[type=number]");
var height = gradioApp().querySelector("#" + tabname + "_height input[type=number]");
if (!width || !height) return [];
var tmp = width.value;
width.value = height.value;
height.value = tmp;
updateInput(width);
updateInput(height);
return [];
}
var onEditTimers = {};
// calls func after afterMs milliseconds has passed since the input elem has beed enited 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;
} }
+62
View File
@@ -0,0 +1,62 @@
// various hints and extra info for the settings tab
var settingsHintsSetup = false;
onOptionsChanged(function() {
if (settingsHintsSetup) return;
settingsHintsSetup = true;
gradioApp().querySelectorAll('#settings [id^=setting_]').forEach(function(div) {
var name = div.id.substr(8);
var commentBefore = opts._comments_before[name];
var commentAfter = opts._comments_after[name];
if (!commentBefore && !commentAfter) return;
var span = null;
if (div.classList.contains('gradio-checkbox')) span = div.querySelector('label span');
else if (div.classList.contains('gradio-checkboxgroup')) span = div.querySelector('span').firstChild;
else if (div.classList.contains('gradio-radio')) span = div.querySelector('span').firstChild;
else span = div.querySelector('label span').firstChild;
if (!span) return;
if (commentBefore) {
var comment = document.createElement('DIV');
comment.className = 'settings-comment';
comment.innerHTML = commentBefore;
span.parentElement.insertBefore(document.createTextNode('\xa0'), span);
span.parentElement.insertBefore(comment, span);
span.parentElement.insertBefore(document.createTextNode('\xa0'), span);
}
if (commentAfter) {
comment = document.createElement('DIV');
comment.className = 'settings-comment';
comment.innerHTML = commentAfter;
span.parentElement.insertBefore(comment, span.nextSibling);
span.parentElement.insertBefore(document.createTextNode('\xa0'), span.nextSibling);
}
});
});
function settingsHintsShowQuicksettings() {
requestGet("./internal/quicksettings-hint", {}, function(data) {
var table = document.createElement('table');
table.className = 'popup-table';
data.forEach(function(obj) {
var tr = document.createElement('tr');
var td = document.createElement('td');
td.textContent = obj.name;
tr.appendChild(td);
td = document.createElement('td');
td.textContent = obj.label;
tr.appendChild(td);
table.appendChild(tr);
});
popup(table);
});
}
+32 -314
View File
@@ -1,330 +1,48 @@
# this scripts installs necessary requirements and launches main program in webui.py from modules import launch_utils
import subprocess
import os
import sys
import importlib.util
import shlex
import platform
import argparse
import json
dir_repos = "repositories" args = launch_utils.args
dir_extensions = "extensions" python = launch_utils.python
python = sys.executable git = launch_utils.git
git = os.environ.get('GIT', "git") index_url = launch_utils.index_url
index_url = os.environ.get('INDEX_URL', "") dir_repos = launch_utils.dir_repos
stored_commit_hash = None
skip_install = False
commit_hash = launch_utils.commit_hash
git_tag = launch_utils.git_tag
def commit_hash(): run = launch_utils.run
global stored_commit_hash is_installed = launch_utils.is_installed
repo_dir = launch_utils.repo_dir
if stored_commit_hash is not None: run_pip = launch_utils.run_pip
return stored_commit_hash check_run_python = launch_utils.check_run_python
git_clone = launch_utils.git_clone
git_pull_recursive = launch_utils.git_pull_recursive
list_extensions = launch_utils.list_extensions
run_extension_installer = launch_utils.run_extension_installer
prepare_environment = launch_utils.prepare_environment
configure_for_tests = launch_utils.configure_for_tests
start = launch_utils.start
try:
stored_commit_hash = run(f"{git} rev-parse HEAD").strip()
except Exception:
stored_commit_hash = "<none>"
return stored_commit_hash def main():
if args.dump_sysinfo:
filename = launch_utils.dump_sysinfo()
print(f"Sysinfo saved as {filename}. Exiting...")
def extract_arg(args, name):
return [x for x in args if x != name], name in args
def extract_opt(args, name):
opt = None
is_present = False
if name in args:
is_present = True
idx = args.index(name)
del args[idx]
if idx < len(args) and args[idx][0] != "-":
opt = args[idx]
del args[idx]
return args, is_present, opt
def run(command, desc=None, errdesc=None, custom_env=None, live=False):
if desc is not None:
print(desc)
if live:
result = subprocess.run(command, shell=True, env=os.environ if custom_env is None else custom_env)
if result.returncode != 0:
raise RuntimeError(f"""{errdesc or 'Error running command'}.
Command: {command}
Error code: {result.returncode}""")
return ""
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, env=os.environ if custom_env is None else custom_env)
if result.returncode != 0:
message = f"""{errdesc or 'Error running command'}.
Command: {command}
Error code: {result.returncode}
stdout: {result.stdout.decode(encoding="utf8", errors="ignore") if len(result.stdout)>0 else '<empty>'}
stderr: {result.stderr.decode(encoding="utf8", errors="ignore") if len(result.stderr)>0 else '<empty>'}
"""
raise RuntimeError(message)
return result.stdout.decode(encoding="utf8", errors="ignore")
def check_run(command):
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
return result.returncode == 0
def is_installed(package):
try:
spec = importlib.util.find_spec(package)
except ModuleNotFoundError:
return False
return spec is not None
def repo_dir(name):
return os.path.join(dir_repos, name)
def run_python(code, desc=None, errdesc=None):
return run(f'"{python}" -c "{code}"', desc, errdesc)
def run_pip(args, desc=None):
if skip_install:
return
index_url_line = f' --index-url {index_url}' if index_url != '' else ''
return run(f'"{python}" -m pip {args} --prefer-binary{index_url_line}', desc=f"Installing {desc}", errdesc=f"Couldn't install {desc}")
def check_run_python(code):
return check_run(f'"{python}" -c "{code}"')
def git_clone(url, dir, name, commithash=None):
# TODO clone into temporary dir and move if successful
if os.path.exists(dir):
if commithash is None:
return
current_hash = run(f'"{git}" -C "{dir}" rev-parse HEAD', None, f"Couldn't determine {name}'s hash: {commithash}").strip()
if current_hash == commithash:
return
run(f'"{git}" -C "{dir}" fetch', f"Fetching updates for {name}...", f"Couldn't fetch {name}")
run(f'"{git}" -C "{dir}" checkout {commithash}', f"Checking out commit for {name} with hash: {commithash}...", f"Couldn't checkout commit {commithash} for {name}")
return
run(f'"{git}" clone "{url}" "{dir}"', f"Cloning {name} into {dir}...", f"Couldn't clone {name}")
if commithash is not None:
run(f'"{git}" -C "{dir}" checkout {commithash}', None, "Couldn't checkout {name}'s hash: {commithash}")
def version_check(commit):
try:
import requests
commits = requests.get('https://api.github.com/repos/AUTOMATIC1111/stable-diffusion-webui/branches/master').json()
if commit != "<none>" and commits['commit']['sha'] != commit:
print("--------------------------------------------------------")
print("| You are not up to date with the most recent release. |")
print("| Consider running `git pull` to update. |")
print("--------------------------------------------------------")
elif commits['commit']['sha'] == commit:
print("You are up to date with the most recent release.")
else:
print("Not a git clone, can't perform version check.")
except Exception as e:
print("version check failed", e)
def run_extension_installer(extension_dir):
path_installer = os.path.join(extension_dir, "install.py")
if not os.path.isfile(path_installer):
return
try:
env = os.environ.copy()
env['PYTHONPATH'] = os.path.abspath(".")
print(run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {extension_dir}", custom_env=env))
except Exception as e:
print(e, file=sys.stderr)
def list_extensions(settings_file):
settings = {}
try:
if os.path.isfile(settings_file):
with open(settings_file, "r", encoding="utf8") as file:
settings = json.load(file)
except Exception as e:
print(e, file=sys.stderr)
disabled_extensions = set(settings.get('disabled_extensions', []))
return [x for x in os.listdir(dir_extensions) if x not in disabled_extensions]
def run_extensions_installers(settings_file):
if not os.path.isdir(dir_extensions):
return
for dirname_extension in list_extensions(settings_file):
run_extension_installer(os.path.join(dir_extensions, dirname_extension))
def prepare_environment():
global skip_install
pip_installer_location = os.environ.get('PIP_INSTALLER_LOCATION', None)
torch_command = os.environ.get('TORCH_COMMAND', "pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 --extra-index-url https://download.pytorch.org/whl/cu117")
requirements_file = os.environ.get('REQS_FILE', "requirements_versions.txt")
commandline_args = os.environ.get('COMMANDLINE_ARGS', "")
gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379")
clip_package = os.environ.get('CLIP_PACKAGE', "git+https://github.com/openai/CLIP.git@d50d76daa670286dd6cacf3bcd80b5e4823fc8e1")
openclip_package = os.environ.get('OPENCLIP_PACKAGE', "git+https://github.com/mlfoundations/open_clip.git@bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b")
stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/Stability-AI/stablediffusion.git")
taming_transformers_repo = os.environ.get('TAMING_TRANSFORMERS_REPO', "https://github.com/CompVis/taming-transformers.git")
k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git')
codeformer_repo = os.environ.get('CODEFORMER_REPO', 'https://github.com/sczhou/CodeFormer.git')
blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git')
stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "47b6b607fdd31875c9279cd2f4f16b92e4ea958e")
taming_transformers_commit_hash = os.environ.get('TAMING_TRANSFORMERS_COMMIT_HASH', "24268930bf1dce879235a7fddd0b2355b84d7ea6")
k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH', "5b3af030dd83e0297272d861c19477735d0317ec")
codeformer_commit_hash = os.environ.get('CODEFORMER_COMMIT_HASH', "c5b4593074ba6214284d6acd5f1719b6c5d739af")
blip_commit_hash = os.environ.get('BLIP_COMMIT_HASH', "48211a1594f1321b00f14c9f7a5b4813144b2fb9")
sys.argv += shlex.split(commandline_args)
parser = argparse.ArgumentParser()
parser.add_argument("--ui-settings-file", type=str, help="filename to use for ui settings", default='config.json')
args, _ = parser.parse_known_args(sys.argv)
sys.argv, _ = extract_arg(sys.argv, '-f')
sys.argv, skip_torch_cuda_test = extract_arg(sys.argv, '--skip-torch-cuda-test')
sys.argv, reinstall_xformers = extract_arg(sys.argv, '--reinstall-xformers')
sys.argv, reinstall_torch = extract_arg(sys.argv, '--reinstall-torch')
sys.argv, update_check = extract_arg(sys.argv, '--update-check')
sys.argv, run_tests, test_dir = extract_opt(sys.argv, '--tests')
sys.argv, skip_install = extract_arg(sys.argv, '--skip-install')
xformers = '--xformers' in sys.argv
ngrok = '--ngrok' in sys.argv
commit = commit_hash()
print(f"Python {sys.version}")
print(f"Commit hash: {commit}")
if pip_installer_location is not None and not is_installed("pip"):
run(f'"{python}" "{pip_installer_location}"', "Installing pip", "Couldn't install pip")
if reinstall_torch or not is_installed("torch") or not is_installed("torchvision"):
run(f'"{python}" -m {torch_command}', "Installing torch and torchvision", "Couldn't install torch", live=True)
if not skip_torch_cuda_test:
run_python("import torch; assert torch.cuda.is_available(), 'Torch is not able to use GPU; add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check'")
if not is_installed("gfpgan"):
run_pip(f"install {gfpgan_package}", "gfpgan")
if not is_installed("clip"):
run_pip(f"install {clip_package}", "clip")
if not is_installed("open_clip"):
run_pip(f"install {openclip_package}", "open_clip")
if (not is_installed("xformers") or reinstall_xformers) and xformers:
if platform.system() == "Windows":
if platform.python_version().startswith("3.10"):
run_pip(f"install -U -I --no-deps xformers==0.0.16rc425", "xformers")
else:
print("Installation of xformers is not supported in this version of Python.")
print("You can also check this and build manually: https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers#building-xformers-on-windows-by-duckness")
if not is_installed("xformers"):
exit(0)
elif platform.system() == "Linux":
run_pip("install xformers==0.0.16rc425", "xformers")
if not is_installed("pyngrok") and ngrok:
run_pip("install pyngrok", "ngrok")
os.makedirs(dir_repos, exist_ok=True)
git_clone(stable_diffusion_repo, repo_dir('stable-diffusion-stability-ai'), "Stable Diffusion", stable_diffusion_commit_hash)
git_clone(taming_transformers_repo, repo_dir('taming-transformers'), "Taming Transformers", taming_transformers_commit_hash)
git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)
git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)
git_clone(blip_repo, repo_dir('BLIP'), "BLIP", blip_commit_hash)
if not is_installed("lpips"):
run_pip(f"install -r {os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}", "requirements for CodeFormer")
run_pip(f"install -r {requirements_file}", "requirements for Web UI")
run_extensions_installers(settings_file=args.ui_settings_file)
if update_check:
version_check(commit)
if "--exit" in sys.argv:
print("Exiting because of --exit argument")
exit(0) exit(0)
if run_tests: launch_utils.startup_timer.record("initial startup")
exitcode = tests(test_dir)
exit(exitcode)
with launch_utils.startup_timer.subcategory("prepare environment"):
if not args.skip_prepare_environment:
prepare_environment()
def tests(test_dir): if args.test_server:
if "--api" not in sys.argv: configure_for_tests()
sys.argv.append("--api")
if "--ckpt" not in sys.argv:
sys.argv.append("--ckpt")
sys.argv.append("./test/test_files/empty.pt")
if "--skip-torch-cuda-test" not in sys.argv:
sys.argv.append("--skip-torch-cuda-test")
if "--disable-nan-check" not in sys.argv:
sys.argv.append("--disable-nan-check")
print(f"Launching Web UI in another process for testing with arguments: {' '.join(sys.argv[1:])}") start()
os.environ['COMMANDLINE_ARGS'] = ""
with open('test/stdout.txt', "w", encoding="utf8") as stdout, open('test/stderr.txt', "w", encoding="utf8") as stderr:
proc = subprocess.Popen([sys.executable, *sys.argv], stdout=stdout, stderr=stderr)
import test.server_poll
exitcode = test.server_poll.run_tests(proc, test_dir)
print(f"Stopping Web UI process with id {proc.pid}")
proc.kill()
return exitcode
def start():
print(f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}")
import webui
if '--nowebui' in sys.argv:
webui.api_only()
else:
webui.webui()
if __name__ == "__main__": if __name__ == "__main__":
prepare_environment() main()
start()
Binary file not shown.
Binary file not shown.
+408 -152
View File
@@ -1,41 +1,46 @@
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
from threading import Lock from threading import Lock
from io import BytesIO from io import BytesIO
from gradio.processing_utils import decode_base64_to_file from fastapi import APIRouter, Depends, FastAPI, Request, Response
from fastapi import APIRouter, Depends, FastAPI, HTTPException, Request, Response
from fastapi.security import HTTPBasic, HTTPBasicCredentials from fastapi.security import HTTPBasic, HTTPBasicCredentials
from fastapi.exceptions import HTTPException
from fastapi.responses import JSONResponse
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 from modules import sd_samplers, deepbooru, sd_hijack, images, scripts, ui, postprocessing, errors, restart, shared_items, script_callbacks, generation_parameters_copypaste
from modules.api.models import * from modules.api import models
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.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,Image
from modules.sd_models import checkpoints_list, find_checkpoint_config from modules.sd_models import unload_model_weights, reload_model_weights, checkpoint_aliases
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 List from typing import Any
import piexif import piexif
import piexif.helper import piexif.helper
from contextlib import closing
def upscaler_to_index(name: str):
try:
return [x.name.lower() for x in shared.sd_upscalers].index(name.lower())
except:
raise HTTPException(status_code=400, detail=f"Invalid upscaler, needs to be one of these: {' , '.join([x.name for x in sd_upscalers])}")
def script_name_to_index(name, scripts): def script_name_to_index(name, scripts):
try: try:
return [script.title().lower() for script in scripts].index(name.lower()) return [script.title().lower() for script in scripts].index(name.lower())
except: except Exception as e:
raise HTTPException(status_code=422, detail=f"Script '{name}' not found") raise HTTPException(status_code=422, detail=f"Script '{name}' not found") from e
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)
@@ -44,20 +49,57 @@ def validate_sampler_name(name):
return name return name
def setUpscalers(req: dict): def setUpscalers(req: dict):
reqDict = vars(req) reqDict = vars(req)
reqDict['extras_upscaler_1'] = reqDict.pop('upscaler_1', None) reqDict['extras_upscaler_1'] = reqDict.pop('upscaler_1', None)
reqDict['extras_upscaler_2'] = reqDict.pop('upscaler_2', None) reqDict['extras_upscaler_2'] = reqDict.pop('upscaler_2', None)
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 = Image.open(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 = Image.open(BytesIO(base64.b64decode(encoding)))
return image return image
except Exception as err: except Exception as e:
raise HTTPException(status_code=500, detail="Invalid encoded image") raise HTTPException(status_code=500, detail="Invalid encoded image") from e
def encode_pil_to_base64(image): def encode_pil_to_base64(image):
with io.BytesIO() as output_bytes: with io.BytesIO() as output_bytes:
@@ -72,6 +114,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 == "RGBA":
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") }
@@ -88,7 +132,19 @@ def encode_pil_to_base64(image):
return base64.b64encode(bytes_data) return base64.b64encode(bytes_data)
def api_middleware(app: FastAPI): def api_middleware(app: FastAPI):
rich_available = False
try:
if os.environ.get('WEBUI_RICH_EXCEPTIONS', None) is not None:
import anyio # importing just so it can be placed on silent list
import starlette # importing just so it can be placed on silent list
from rich.console import Console
console = Console()
rich_available = True
except Exception:
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):
ts = time.time() ts = time.time()
@@ -98,22 +154,53 @@ 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
def handle_exception(request: Request, e: Exception):
err = {
"error": type(e).__name__,
"detail": vars(e).get('detail', ''),
"body": vars(e).get('body', ''),
"errors": str(e),
}
if not isinstance(e, HTTPException): # do not print backtrace on known httpexceptions
message = f"API error: {request.method}: {request.url} {err}"
if rich_available:
print(message)
console.print_exception(show_locals=True, max_frames=2, extra_lines=1, suppress=[anyio, starlette], word_wrap=False, width=min([console.width, 200]))
else:
errors.report(message, exc_info=True)
return JSONResponse(status_code=vars(e).get('status_code', 500), content=jsonable_encoder(err))
@app.middleware("http")
async def exception_handling(request: Request, call_next):
try:
return await call_next(request)
except Exception as e:
return handle_exception(request, e)
@app.exception_handler(Exception)
async def fastapi_exception_handler(request: Request, e: Exception):
return handle_exception(request, e)
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, e: HTTPException):
return handle_exception(request, e)
class Api: class Api:
def __init__(self, app: FastAPI, queue_lock: Lock): def __init__(self, app: FastAPI, queue_lock: Lock):
if shared.cmd_opts.api_auth: if shared.cmd_opts.api_auth:
self.credentials = dict() self.credentials = {}
for auth in shared.cmd_opts.api_auth.split(","): for auth in shared.cmd_opts.api_auth.split(","):
user, password = auth.split(":") user, password = auth.split(":")
self.credentials[user] = password self.credentials[user] = password
@@ -122,33 +209,49 @@ class Api:
self.app = app self.app = app
self.queue_lock = queue_lock self.queue_lock = queue_lock
api_middleware(self.app) api_middleware(self.app)
self.add_api_route("/sdapi/v1/txt2img", self.text2imgapi, methods=["POST"], response_model=TextToImageResponse) self.add_api_route("/sdapi/v1/txt2img", self.text2imgapi, methods=["POST"], response_model=models.TextToImageResponse)
self.add_api_route("/sdapi/v1/img2img", self.img2imgapi, methods=["POST"], response_model=ImageToImageResponse) self.add_api_route("/sdapi/v1/img2img", self.img2imgapi, methods=["POST"], response_model=models.ImageToImageResponse)
self.add_api_route("/sdapi/v1/extra-single-image", self.extras_single_image_api, methods=["POST"], response_model=ExtrasSingleImageResponse) self.add_api_route("/sdapi/v1/extra-single-image", self.extras_single_image_api, methods=["POST"], response_model=models.ExtrasSingleImageResponse)
self.add_api_route("/sdapi/v1/extra-batch-images", self.extras_batch_images_api, methods=["POST"], response_model=ExtrasBatchImagesResponse) self.add_api_route("/sdapi/v1/extra-batch-images", self.extras_batch_images_api, methods=["POST"], response_model=models.ExtrasBatchImagesResponse)
self.add_api_route("/sdapi/v1/png-info", self.pnginfoapi, methods=["POST"], response_model=PNGInfoResponse) self.add_api_route("/sdapi/v1/png-info", self.pnginfoapi, methods=["POST"], response_model=models.PNGInfoResponse)
self.add_api_route("/sdapi/v1/progress", self.progressapi, methods=["GET"], response_model=ProgressResponse) self.add_api_route("/sdapi/v1/progress", self.progressapi, methods=["GET"], response_model=models.ProgressResponse)
self.add_api_route("/sdapi/v1/interrogate", self.interrogateapi, methods=["POST"]) self.add_api_route("/sdapi/v1/interrogate", self.interrogateapi, methods=["POST"])
self.add_api_route("/sdapi/v1/interrupt", self.interruptapi, methods=["POST"]) self.add_api_route("/sdapi/v1/interrupt", self.interruptapi, methods=["POST"])
self.add_api_route("/sdapi/v1/skip", self.skip, methods=["POST"]) self.add_api_route("/sdapi/v1/skip", self.skip, methods=["POST"])
self.add_api_route("/sdapi/v1/options", self.get_config, methods=["GET"], response_model=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=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[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[UpscalerItem]) 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[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/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=List[HypernetworkItem]) 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/face-restorers", self.get_face_restorers, methods=["GET"], response_model=List[FaceRestorerItem]) 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/realesrgan-models", self.get_realesrgan_models, methods=["GET"], response_model=List[RealesrganItem]) self.add_api_route("/sdapi/v1/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=list[models.HypernetworkItem])
self.add_api_route("/sdapi/v1/prompt-styles", self.get_prompt_styles, methods=["GET"], response_model=List[PromptStyleItem]) 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/embeddings", self.get_embeddings, methods=["GET"], response_model=EmbeddingsResponse) self.add_api_route("/sdapi/v1/realesrgan-models", self.get_realesrgan_models, methods=["GET"], response_model=list[models.RealesrganItem])
self.add_api_route("/sdapi/v1/prompt-styles", self.get_prompt_styles, methods=["GET"], response_model=list[models.PromptStyleItem])
self.add_api_route("/sdapi/v1/embeddings", self.get_embeddings, methods=["GET"], response_model=models.EmbeddingsResponse)
self.add_api_route("/sdapi/v1/refresh-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/create/embedding", self.create_embedding, methods=["POST"], response_model=CreateResponse) self.add_api_route("/sdapi/v1/refresh-vae", self.refresh_vae, methods=["POST"])
self.add_api_route("/sdapi/v1/create/hypernetwork", self.create_hypernetwork, methods=["POST"], response_model=CreateResponse) self.add_api_route("/sdapi/v1/create/embedding", self.create_embedding, methods=["POST"], response_model=models.CreateResponse)
self.add_api_route("/sdapi/v1/preprocess", self.preprocess, methods=["POST"], response_model=PreprocessResponse) self.add_api_route("/sdapi/v1/create/hypernetwork", self.create_hypernetwork, methods=["POST"], response_model=models.CreateResponse)
self.add_api_route("/sdapi/v1/train/embedding", self.train_embedding, methods=["POST"], response_model=TrainResponse) self.add_api_route("/sdapi/v1/preprocess", self.preprocess, methods=["POST"], response_model=models.PreprocessResponse)
self.add_api_route("/sdapi/v1/train/hypernetwork", self.train_hypernetwork, methods=["POST"], response_model=TrainResponse) self.add_api_route("/sdapi/v1/train/embedding", self.train_embedding, methods=["POST"], response_model=models.TrainResponse)
self.add_api_route("/sdapi/v1/memory", self.get_memory, methods=["GET"], response_model=MemoryResponse) self.add_api_route("/sdapi/v1/train/hypernetwork", self.train_hypernetwork, methods=["POST"], response_model=models.TrainResponse)
self.add_api_route("/sdapi/v1/memory", self.get_memory, methods=["GET"], response_model=models.MemoryResponse)
self.add_api_route("/sdapi/v1/unload-checkpoint", self.unloadapi, methods=["POST"])
self.add_api_route("/sdapi/v1/reload-checkpoint", self.reloadapi, methods=["POST"])
self.add_api_route("/sdapi/v1/scripts", self.get_scripts_list, methods=["GET"], response_model=models.ScriptsList)
self.add_api_route("/sdapi/v1/script-info", self.get_script_info, methods=["GET"], response_model=list[models.ScriptInfo])
self.add_api_route("/sdapi/v1/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_img2img = []
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:
@@ -162,98 +265,194 @@ class Api:
raise HTTPException(status_code=401, detail="Incorrect username or password", headers={"WWW-Authenticate": "Basic"}) raise HTTPException(status_code=401, detail="Incorrect username or password", headers={"WWW-Authenticate": "Basic"})
def get_script(self, script_name, script_runner): def get_selectable_script(self, script_name, script_runner):
if script_name is None: if script_name is None or script_name == "":
return None, None return None, None
if not script_runner.scripts:
script_runner.initialize_scripts(False)
ui.create_ui()
script_idx = script_name_to_index(script_name, script_runner.selectable_scripts) script_idx = script_name_to_index(script_name, script_runner.selectable_scripts)
script = script_runner.selectable_scripts[script_idx] script = script_runner.selectable_scripts[script_idx]
return script, script_idx return script, script_idx
def text2imgapi(self, txt2imgreq: StableDiffusionTxt2ImgProcessingAPI): def get_scripts_list(self):
script, script_idx = self.get_script(txt2imgreq.script_name, scripts.scripts_txt2img) t2ilist = [script.name for script in scripts.scripts_txt2img.scripts if script.name is not None]
i2ilist = [script.name for script in scripts.scripts_img2img.scripts if script.name is not None]
populate = txt2imgreq.copy(update={ # Override __init__ params return models.ScriptsList(txt2img=t2ilist, img2img=i2ilist)
def get_script_info(self):
res = []
for script_list in [scripts.scripts_txt2img.scripts, scripts.scripts_img2img.scripts]:
res += [script.api_info for script in script_list if script.api_info is not None]
return res
def get_script(self, script_name, script_runner):
if script_name is None or script_name == "":
return None, None
script_idx = script_name_to_index(script_name, script_runner.scripts)
return script_runner.scripts[script_idx]
def init_default_script_args(self, script_runner):
#find max idx from the scripts in runner and generate a none array to init script_args
last_arg_index = 1
for script in script_runner.scripts:
if last_arg_index < script.args_to:
last_arg_index = script.args_to
# None everywhere except position 0 to initialize script args
script_args = [None]*last_arg_index
script_args[0] = 0
# get default values
with gr.Blocks(): # will throw errors calling ui function without this
for script in script_runner.scripts:
if script.ui(script.is_img2img):
ui_default_values = []
for elem in script.ui(script.is_img2img):
ui_default_values.append(elem.value)
script_args[script.args_from:script.args_to] = ui_default_values
return script_args
def init_script_args(self, request, default_script_args, selectable_scripts, selectable_idx, script_runner):
script_args = default_script_args.copy()
# position 0 in script_arg is the idx+1 of the selectable script that is going to be run when using scripts.scripts_*2img.run()
if selectable_scripts:
script_args[selectable_scripts.args_from:selectable_scripts.args_to] = request.script_args
script_args[0] = selectable_idx + 1
# Now check for always on scripts
if request.alwayson_scripts:
for alwayson_script_name in request.alwayson_scripts.keys():
alwayson_script = self.get_script(alwayson_script_name, script_runner)
if alwayson_script is None:
raise HTTPException(status_code=422, detail=f"always on script {alwayson_script_name} not found")
# Selectable script in always on script param check
if alwayson_script.alwayson is False:
raise HTTPException(status_code=422, detail="Cannot have a selectable script in the always on scripts params")
# always on script with no arg should always run so you don't really need to add them to the requests
if "args" in request.alwayson_scripts[alwayson_script_name]:
# min between arg length in scriptrunner and arg length in the request
for idx in range(0, min((alwayson_script.args_to - alwayson_script.args_from), len(request.alwayson_scripts[alwayson_script_name]["args"]))):
script_args[alwayson_script.args_from + idx] = request.alwayson_scripts[alwayson_script_name]["args"][idx]
return script_args
def text2imgapi(self, txt2imgreq: models.StableDiffusionTxt2ImgProcessingAPI):
script_runner = scripts.scripts_txt2img
if not script_runner.scripts:
script_runner.initialize_scripts(False)
ui.create_ui()
if not self.default_script_arg_txt2img:
self.default_script_arg_txt2img = self.init_default_script_args(script_runner)
selectable_scripts, selectable_script_idx = self.get_selectable_script(txt2imgreq.script_name, script_runner)
populate = txt2imgreq.copy(update={ # Override __init__ params
"sampler_name": validate_sampler_name(txt2imgreq.sampler_name or txt2imgreq.sampler_index), "sampler_name": validate_sampler_name(txt2imgreq.sampler_name or txt2imgreq.sampler_index),
"do_not_save_samples": True, "do_not_save_samples": not txt2imgreq.save_images,
"do_not_save_grid": True "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
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('alwayson_scripts', None)
script_args = self.init_script_args(txt2imgreq, self.default_script_arg_txt2img, selectable_scripts, selectable_script_idx, script_runner)
send_images = args.pop('send_images', True)
args.pop('save_images', None)
with self.queue_lock: with self.queue_lock:
p = StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **args) with closing(StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **args)) as p:
p.is_api = True
shared.state.begin() p.scripts = script_runner
if script is not None:
p.outpath_grids = opts.outdir_txt2img_grids p.outpath_grids = opts.outdir_txt2img_grids
p.outpath_samples = opts.outdir_txt2img_samples p.outpath_samples = opts.outdir_txt2img_samples
p.script_args = [script_idx + 1] + [None] * (script.args_from - 1) + p.script_args
processed = scripts.scripts_txt2img.run(p, *p.script_args)
else:
processed = process_images(p)
shared.state.end()
b64images = list(map(encode_pil_to_base64, processed.images)) try:
shared.state.begin(job="scripts_txt2img")
if selectable_scripts is not None:
p.script_args = script_args
processed = scripts.scripts_txt2img.run(p, *p.script_args) # Need to pass args as list here
else:
p.script_args = tuple(script_args) # Need to pass args as tuple here
processed = process_images(p)
finally:
shared.state.end()
shared.total_tqdm.clear()
return TextToImageResponse(images=b64images, parameters=vars(txt2imgreq), info=processed.js()) b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
def img2imgapi(self, img2imgreq: StableDiffusionImg2ImgProcessingAPI): return models.TextToImageResponse(images=b64images, parameters=vars(txt2imgreq), info=processed.js())
def img2imgapi(self, img2imgreq: models.StableDiffusionImg2ImgProcessingAPI):
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")
script, script_idx = self.get_script(img2imgreq.script_name, scripts.scripts_img2img)
mask = img2imgreq.mask mask = img2imgreq.mask
if mask: if mask:
mask = decode_base64_to_image(mask) mask = decode_base64_to_image(mask)
populate = img2imgreq.copy(update={ # Override __init__ params script_runner = scripts.scripts_img2img
if not script_runner.scripts:
script_runner.initialize_scripts(True)
ui.create_ui()
if not self.default_script_arg_img2img:
self.default_script_arg_img2img = self.init_default_script_args(script_runner)
selectable_scripts, selectable_script_idx = self.get_selectable_script(img2imgreq.script_name, script_runner)
populate = img2imgreq.copy(update={ # Override __init__ params
"sampler_name": validate_sampler_name(img2imgreq.sampler_name or img2imgreq.sampler_index), "sampler_name": validate_sampler_name(img2imgreq.sampler_name or img2imgreq.sampler_index),
"do_not_save_samples": True, "do_not_save_samples": not img2imgreq.save_images,
"do_not_save_grid": True, "do_not_save_grid": not img2imgreq.save_images,
"mask": mask "mask": mask,
} })
)
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
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('alwayson_scripts', None)
script_args = self.init_script_args(img2imgreq, self.default_script_arg_img2img, selectable_scripts, selectable_script_idx, script_runner)
send_images = args.pop('send_images', True)
args.pop('save_images', None)
with self.queue_lock: with self.queue_lock:
p = StableDiffusionProcessingImg2Img(sd_model=shared.sd_model, **args) with closing(StableDiffusionProcessingImg2Img(sd_model=shared.sd_model, **args)) as p:
p.init_images = [decode_base64_to_image(x) for x in init_images] p.init_images = [decode_base64_to_image(x) for x in init_images]
p.is_api = True
shared.state.begin() p.scripts = script_runner
if script is not None:
p.outpath_grids = opts.outdir_img2img_grids p.outpath_grids = opts.outdir_img2img_grids
p.outpath_samples = opts.outdir_img2img_samples p.outpath_samples = opts.outdir_img2img_samples
p.script_args = [script_idx + 1] + [None] * (script.args_from - 1) + p.script_args
processed = scripts.scripts_img2img.run(p, *p.script_args)
else:
processed = process_images(p)
shared.state.end()
b64images = list(map(encode_pil_to_base64, processed.images)) try:
shared.state.begin(job="scripts_img2img")
if selectable_scripts is not None:
p.script_args = script_args
processed = scripts.scripts_img2img.run(p, *p.script_args) # Need to pass args as list here
else:
p.script_args = tuple(script_args) # Need to pass args as tuple here
processed = process_images(p)
finally:
shared.state.end()
shared.total_tqdm.clear()
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
if not img2imgreq.include_init_images: if not img2imgreq.include_init_images:
img2imgreq.init_images = None img2imgreq.init_images = None
img2imgreq.mask = None img2imgreq.mask = None
return ImageToImageResponse(images=b64images, parameters=vars(img2imgreq), info=processed.js()) return models.ImageToImageResponse(images=b64images, parameters=vars(img2imgreq), info=processed.js())
def extras_single_image_api(self, req: ExtrasSingleImageRequest): def extras_single_image_api(self, req: models.ExtrasSingleImageRequest):
reqDict = setUpscalers(req) reqDict = setUpscalers(req)
reqDict['image'] = decode_base64_to_image(reqDict['image']) reqDict['image'] = decode_base64_to_image(reqDict['image'])
@@ -261,45 +460,38 @@ class Api:
with self.queue_lock: with self.queue_lock:
result = postprocessing.run_extras(extras_mode=0, image_folder="", input_dir="", output_dir="", save_output=False, **reqDict) result = postprocessing.run_extras(extras_mode=0, image_folder="", input_dir="", output_dir="", save_output=False, **reqDict)
return ExtrasSingleImageResponse(image=encode_pil_to_base64(result[0][0]), html_info=result[1]) return models.ExtrasSingleImageResponse(image=encode_pil_to_base64(result[0][0]), html_info=result[1])
def extras_batch_images_api(self, req: ExtrasBatchImagesRequest): def extras_batch_images_api(self, req: models.ExtrasBatchImagesRequest):
reqDict = setUpscalers(req) reqDict = setUpscalers(req)
def prepareFiles(file): image_list = reqDict.pop('imageList', [])
file = decode_base64_to_file(file.data, file_path=file.name) image_folder = [decode_base64_to_image(x.data) for x in image_list]
file.orig_name = file.name
return file
reqDict['image_folder'] = list(map(prepareFiles, reqDict['imageList']))
reqDict.pop('imageList')
with self.queue_lock: with self.queue_lock:
result = postprocessing.run_extras(extras_mode=1, image="", input_dir="", output_dir="", save_output=False, **reqDict) result = postprocessing.run_extras(extras_mode=1, image_folder=image_folder, image="", input_dir="", output_dir="", save_output=False, **reqDict)
return 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: PNGInfoRequest):
if(not req.image.strip()):
return PNGInfoResponse(info="")
def pnginfoapi(self, req: models.PNGInfoRequest):
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 PNGInfoResponse(info="") return models.PNGInfoResponse(info="")
geninfo, items = images.read_info_from_image(image) geninfo, items = images.read_info_from_image(image)
if geninfo is None: if geninfo is None:
geninfo = "" geninfo = ""
items = {**{'parameters': geninfo}, **items} params = generation_parameters_copypaste.parse_generation_parameters(geninfo)
script_callbacks.infotext_pasted_callback(geninfo, params)
return PNGInfoResponse(info=geninfo, items=items) return models.PNGInfoResponse(info=geninfo, items=items, parameters=params)
def progressapi(self, req: 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
if shared.state.job_count == 0: if shared.state.job_count == 0:
return ProgressResponse(progress=0, eta_relative=0, state=shared.state.dict(), textinfo=shared.state.textinfo) return models.ProgressResponse(progress=0, eta_relative=0, state=shared.state.dict(), textinfo=shared.state.textinfo)
# avoid dividing zero # avoid dividing zero
progress = 0.01 progress = 0.01
@@ -321,9 +513,9 @@ 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 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)
def interrogateapi(self, interrogatereq: InterrogateRequest): def interrogateapi(self, interrogatereq: models.InterrogateRequest):
image_b64 = interrogatereq.image image_b64 = interrogatereq.image
if image_b64 is None: if image_b64 is None:
raise HTTPException(status_code=404, detail="Image not found") raise HTTPException(status_code=404, detail="Image not found")
@@ -340,13 +532,23 @@ class Api:
else: else:
raise HTTPException(status_code=404, detail="Model not found") raise HTTPException(status_code=404, detail="Model not found")
return InterrogateResponse(caption=processed) return models.InterrogateResponse(caption=processed)
def interruptapi(self): def interruptapi(self):
shared.state.interrupt() shared.state.interrupt()
return {} return {}
def unloadapi(self):
unload_model_weights()
return {}
def reloadapi(self):
reload_model_weights()
return {}
def skip(self): def skip(self):
shared.state.skip() shared.state.skip()
@@ -361,9 +563,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 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
@@ -386,8 +592,21 @@ class Api:
for upscaler in shared.sd_upscalers for upscaler in shared.sd_upscalers
] ]
def get_latent_upscale_modes(self):
return [
{
"name": upscale_mode,
}
for upscale_mode in [*(shared.latent_upscale_modes or {})]
]
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(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):
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]
@@ -427,48 +646,51 @@ class Api:
} }
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 CreateResponse(info = "create embedding filename: {filename}".format(filename = filename))
except AssertionError as e: except AssertionError as e:
return models.TrainResponse(info=f"create embedding error: {e}")
finally:
shared.state.end() shared.state.end()
return TrainResponse(info = "create embedding error: {error}".format(error = e))
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 CreateResponse(info = "create hypernetwork filename: {filename}".format(filename = filename))
except AssertionError as e: except AssertionError as e:
return models.TrainResponse(info=f"create hypernetwork error: {e}")
finally:
shared.state.end() shared.state.end()
return TrainResponse(info = "create hypernetwork error: {error}".format(error = e))
def preprocess(self, args: dict): def preprocess(self, args: dict):
try: try:
shared.state.begin() shared.state.begin(job="preprocess")
preprocess(**args) # quick operation unless blip/booru interrogation is enabled preprocess(**args) # quick operation unless blip/booru interrogation is enabled
shared.state.end() shared.state.end()
return PreprocessResponse(info = 'preprocess complete') return models.PreprocessResponse(info='preprocess complete')
except KeyError as e: except KeyError as e:
return models.PreprocessResponse(info=f"preprocess error: invalid token: {e}")
except Exception as e:
return models.PreprocessResponse(info=f"preprocess error: {e}")
finally:
shared.state.end() shared.state.end()
return PreprocessResponse(info = "preprocess error: invalid token: {error}".format(error = e))
except AssertionError as e:
shared.state.end()
return PreprocessResponse(info = "preprocess error: {error}".format(error = e))
except FileNotFoundError as e:
shared.state.end()
return PreprocessResponse(info = 'preprocess error: {error}'.format(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 = ''
@@ -481,15 +703,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 TrainResponse(info = "train embedding complete: filename: {filename} error: {error}".format(filename = filename, error = error)) except Exception as msg:
except AssertionError as msg: return models.TrainResponse(info=f"train embedding error: {msg}")
finally:
shared.state.end() shared.state.end()
return TrainResponse(info = "train embedding error: {msg}".format(msg = msg))
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
@@ -497,7 +719,7 @@ class Api:
if not apply_optimizations: if not apply_optimizations:
sd_hijack.undo_optimizations() sd_hijack.undo_optimizations()
try: try:
hypernetwork, filename = train_hypernetwork(*args) hypernetwork, filename = train_hypernetwork(**args)
except Exception as e: except Exception as e:
error = e error = e
finally: finally:
@@ -506,14 +728,16 @@ class Api:
if not apply_optimizations: if not apply_optimizations:
sd_hijack.apply_optimizations() sd_hijack.apply_optimizations()
shared.state.end() shared.state.end()
return TrainResponse(info="train embedding complete: filename: {filename} error: {error}".format(filename=filename, error=error)) return models.TrainResponse(info=f"train embedding complete: filename: {filename} error: {error}")
except AssertionError as msg: except Exception as exc:
return models.TrainResponse(info=f"train embedding error: {exc}")
finally:
shared.state.end() shared.state.end()
return TrainResponse(info="train embedding error: {error}".format(error=error))
def get_memory(self): def get_memory(self):
try: try:
import os, psutil import os
import psutil
process = psutil.Process(os.getpid()) process = psutil.Process(os.getpid())
res = process.memory_info() # only rss is cross-platform guaranteed so we dont rely on other values res = process.memory_info() # only rss is cross-platform guaranteed so we dont rely on other values
ram_total = 100 * res.rss / process.memory_percent() # and total memory is calculated as actual value is not cross-platform safe ram_total = 100 * res.rss / process.memory_percent() # and total memory is calculated as actual value is not cross-platform safe
@@ -540,11 +764,43 @@ class Api:
'events': warnings, 'events': warnings,
} }
else: else:
cuda = { 'error': 'unavailable' } cuda = {'error': 'unavailable'}
except Exception as err: except Exception as err:
cuda = { 'error': f'{err}' } cuda = {'error': f'{err}'}
return 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) uvicorn.run(self.app, host=server_name, port=port, timeout_keep_alive=shared.cmd_opts.timeout_keep_alive, root_path=root_path)
def kill_webui(self):
restart.stop_program()
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.")
+83 -31
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",
@@ -14,8 +13,8 @@ API_NOT_ALLOWED = [
"outpath_samples", "outpath_samples",
"outpath_grids", "outpath_grids",
"sampler_index", "sampler_index",
"do_not_save_samples", # "do_not_save_samples",
"do_not_save_grid", # "do_not_save_grid",
"extra_generation_params", "extra_generation_params",
"overlay_images", "overlay_images",
"do_not_reload_embeddings", "do_not_reload_embeddings",
@@ -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
] ]
@@ -100,22 +100,40 @@ class PydanticModelGenerator:
StableDiffusionTxt2ImgProcessingAPI = PydanticModelGenerator( StableDiffusionTxt2ImgProcessingAPI = PydanticModelGenerator(
"StableDiffusionProcessingTxt2Img", "StableDiffusionProcessingTxt2Img",
StableDiffusionProcessingTxt2Img, StableDiffusionProcessingTxt2Img,
[{"key": "sampler_index", "type": str, "default": "Euler"}, {"key": "script_name", "type": str, "default": None}, {"key": "script_args", "type": list, "default": []}] [
{"key": "sampler_index", "type": str, "default": "Euler"},
{"key": "script_name", "type": str, "default": None},
{"key": "script_args", "type": list, "default": []},
{"key": "send_images", "type": bool, "default": True},
{"key": "save_images", "type": bool, "default": False},
{"key": "alwayson_scripts", "type": dict, "default": {}},
]
).generate_model() ).generate_model()
StableDiffusionImg2ImgProcessingAPI = PydanticModelGenerator( StableDiffusionImg2ImgProcessingAPI = PydanticModelGenerator(
"StableDiffusionProcessingImg2Img", "StableDiffusionProcessingImg2Img",
StableDiffusionProcessingImg2Img, StableDiffusionProcessingImg2Img,
[{"key": "sampler_index", "type": str, "default": "Euler"}, {"key": "init_images", "type": list, "default": None}, {"key": "denoising_strength", "type": float, "default": 0.75}, {"key": "mask", "type": str, "default": None}, {"key": "include_init_images", "type": bool, "default": False, "exclude" : True}, {"key": "script_name", "type": str, "default": None}, {"key": "script_args", "type": list, "default": []}] [
{"key": "sampler_index", "type": str, "default": "Euler"},
{"key": "init_images", "type": list, "default": None},
{"key": "denoising_strength", "type": float, "default": 0.75},
{"key": "mask", "type": str, "default": None},
{"key": "include_init_images", "type": bool, "default": False, "exclude" : True},
{"key": "script_name", "type": str, "default": None},
{"key": "script_args", "type": list, "default": []},
{"key": "send_images", "type": bool, "default": True},
{"key": "save_images", "type": bool, "default": False},
{"key": "alwayson_scripts", "type": dict, "default": {}},
]
).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
@@ -148,17 +166,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")
@@ -189,11 +208,10 @@ class PreprocessResponse(BaseModel):
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())})
@@ -205,15 +223,16 @@ for key in _options:
if(_options[key].dest != 'help'): if(_options[key].dest != 'help'):
flag = _options[key] flag = _options[key]
_type = str _type = str
if _options[key].default is not None: _type = type(_options[key].default) if _options[key].default is not None:
flags.update({flag.dest: (_type,Field(default=flag.default, description=flag.help))}) _type = type(_options[key].default)
flags.update({flag.dest: (_type, Field(default=flag.default, description=flag.help))})
FlagsModel = create_model("Flags", **flags) 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 UpscalerItem(BaseModel): class UpscalerItem(BaseModel):
name: str = Field(title="Name") name: str = Field(title="Name")
@@ -222,13 +241,20 @@ class UpscalerItem(BaseModel):
model_url: Optional[str] = Field(title="URL") model_url: Optional[str] = Field(title="URL")
scale: Optional[float] = Field(title="Scale") scale: Optional[float] = Field(title="Scale")
class LatentUpscalerModeItem(BaseModel):
name: str = Field(title="Name")
class SDModelItem(BaseModel): class SDModelItem(BaseModel):
title: str = Field(title="Title") title: str = Field(title="Title")
model_name: str = Field(title="Model Name") model_name: str = Field(title="Model Name")
hash: Optional[str] = Field(title="Short hash") hash: Optional[str] = Field(title="Short hash")
sha256: Optional[str] = Field(title="sha256 hash") sha256: Optional[str] = Field(title="sha256 hash")
filename: str = Field(title="Filename") filename: str = Field(title="Filename")
config: str = Field(title="Config file") config: Optional[str] = Field(title="Config file")
class SDVaeItem(BaseModel):
model_name: str = Field(title="Model Name")
filename: str = Field(title="Filename")
class HypernetworkItem(BaseModel): class HypernetworkItem(BaseModel):
name: str = Field(title="Name") name: str = Field(title="Name")
@@ -248,10 +274,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")
@@ -261,9 +283,39 @@ 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")
cuda: dict = Field(title="CUDA", description="nVidia CUDA memory stats") cuda: dict = Field(title="CUDA", description="nVidia CUDA memory stats")
class ScriptsList(BaseModel):
txt2img: list = Field(default=None, title="Txt2img", description="Titles of scripts (txt2img)")
img2img: list = Field(default=None, title="Img2img", description="Titles of scripts (img2img)")
class ScriptArg(BaseModel):
label: str = Field(default=None, title="Label", description="Name of the argument in UI")
value: Optional[Any] = Field(default=None, title="Value", description="Default value of the argument")
minimum: Optional[Any] = Field(default=None, title="Minimum", description="Minimum allowed value for the argumentin UI")
maximum: Optional[Any] = Field(default=None, title="Minimum", description="Maximum allowed value for the argumentin UI")
step: Optional[Any] = Field(default=None, title="Minimum", description="Step for changing value of the argumentin UI")
choices: Optional[list[str]] = Field(default=None, title="Choices", description="Possible values for the argument")
class ScriptInfo(BaseModel):
name: str = Field(default=None, title="Name", description="Script name")
is_alwayson: bool = Field(default=None, title="IsAlwayson", description="Flag specifying whether this script is an alwayson script")
is_img2img: bool = Field(default=None, title="IsImg2img", description="Flag specifying whether this script is an img2img script")
args: list[ScriptArg] = Field(title="Arguments", description="List of script's arguments")
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")
+124
View File
@@ -0,0 +1,124 @@
import json
import os
import os.path
import threading
import time
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_data = None
cache_lock = threading.Lock()
dump_cache_after = None
dump_cache_thread = None
def dump_cache():
"""
Marks cache for writing to disk. 5 seconds after no one else flags the cache for writing, it is written.
"""
global dump_cache_after
global dump_cache_thread
def thread_func():
global dump_cache_after
global dump_cache_thread
while dump_cache_after is not None and time.time() < dump_cache_after:
time.sleep(1)
with cache_lock:
cache_filename_tmp = cache_filename + "-"
with open(cache_filename_tmp, "w", encoding="utf8") as file:
json.dump(cache_data, file, indent=4)
os.replace(cache_filename_tmp, cache_filename)
dump_cache_after = None
dump_cache_thread = None
with cache_lock:
dump_cache_after = time.time() + 5
if dump_cache_thread is None:
dump_cache_thread = threading.Thread(name='cache-writer', target=thread_func)
dump_cache_thread.start()
def cache(subsection):
"""
Retrieves or initializes a cache for a specific subsection.
Parameters:
subsection (str): The subsection identifier for the cache.
Returns:
dict: The cache data for the specified subsection.
"""
global cache_data
if cache_data is None:
with cache_lock:
if cache_data is None:
if not os.path.isfile(cache_filename):
cache_data = {}
else:
try:
with open(cache_filename, "r", encoding="utf8") as file:
cache_data = json.load(file)
except Exception:
os.replace(cache_filename, os.path.join(script_path, "tmp", "cache.json"))
print('[ERROR] issue occurred while trying to read cache.json, move current cache to tmp/cache.json and create new cache')
cache_data = {}
s = cache_data.get(subsection, {})
cache_data[subsection] = s
return s
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']
+33 -24
View File
@@ -1,12 +1,10 @@
from functools import wraps
import html import html
import sys
import threading
import traceback
import time import time
from modules import shared, progress from modules import shared, progress, errors, devices, fifo_lock
queue_lock = threading.Lock() queue_lock = fifo_lock.FIFOLock()
def wrap_queued_call(func): def wrap_queued_call(func):
@@ -20,21 +18,23 @@ 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
if len(args) > 0 and type(args[0]) == str and args[0][0:5] == "task(" and args[0][-1] == ")": if args and type(args[0]) == str and args[0].startswith("task(") and args[0].endswith(")"):
id_task = args[0] id_task = args[0]
progress.add_task_to_queue(id_task) progress.add_task_to_queue(id_task)
else: else:
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:
res = func(*args, **kwargs) res = func(*args, **kwargs)
progress.record_results(id_task, res)
finally: finally:
progress.finish_task(id_task) progress.finish_task(id_task)
@@ -46,6 +46,7 @@ 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, 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:
@@ -55,16 +56,14 @@ def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
try: try:
res = list(func(*args, **kwargs)) res = list(func(*args, **kwargs))
except Exception as e: except Exception as e:
# When printing out our debug argument list, do not print out more than a MB of text # When printing out our debug argument list,
max_debug_str_len = 131072 # (1024*1024)/8 # do not print out more than a 100 KB of text
max_debug_str_len = 131072
print("Error completing request", file=sys.stderr) message = "Error completing request"
argStr = f"Arguments: {str(args)} {str(kwargs)}" arg_str = f"Arguments: {args} {kwargs}"[:max_debug_str_len]
print(argStr[:max_debug_str_len], file=sys.stderr) if len(arg_str) > max_debug_str_len:
if len(argStr) > max_debug_str_len: arg_str += f" (Argument list truncated at {max_debug_str_len}/{len(arg_str)} characters)"
print(f"(Argument list truncated at {max_debug_str_len}/{len(argStr)} characters)", file=sys.stderr) errors.report(f"{message}\n{arg_str}", exc_info=True)
print(traceback.format_exc(), file=sys.stderr)
shared.state.job = "" shared.state.job = ""
shared.state.job_count = 0 shared.state.job_count = 0
@@ -72,7 +71,10 @@ def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
if extra_outputs_array is None: if extra_outputs_array is None:
extra_outputs_array = [None, ''] extra_outputs_array = [None, '']
res = extra_outputs_array + [f"<div class='error'>{html.escape(type(e).__name__+': '+str(e))}</div>"] error_message = f'{type(e).__name__}: {e}'
res = extra_outputs_array + [f"<div class='error'>{html.escape(error_message)}</div>"]
devices.torch_gc()
shared.state.skipped = False shared.state.skipped = False
shared.state.interrupted = False shared.state.interrupted = False
@@ -84,9 +86,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()}
@@ -94,16 +96,23 @@ 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 amout of video memory allocated by the Torch library "
toltip_sys = "System: peak amout of video memory allocated by all running programs, out of total capacity"
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 = ''
# 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}</div>"
return tuple(res) return tuple(res)
return f return f
+120
View File
@@ -0,0 +1,120 @@
import argparse
import json
import os
from modules.paths_internal import models_path, script_path, data_path, extensions_dir, extensions_builtin_dir, sd_default_config, sd_model_file # noqa: F401
parser = argparse.ArgumentParser()
parser.add_argument("-f", action='store_true', help=argparse.SUPPRESS) # allows running as root; implemented outside of webui
parser.add_argument("--update-all-extensions", action='store_true', help="launch.py argument: download updates for all extensions when starting the program")
parser.add_argument("--skip-python-version-check", action='store_true', help="launch.py argument: do not check python version")
parser.add_argument("--skip-torch-cuda-test", action='store_true', help="launch.py argument: do not check if CUDA is able to work properly")
parser.add_argument("--reinstall-xformers", action='store_true', help="launch.py argument: install the appropriate version of xformers 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("--test-server", action='store_true', help="launch.py argument: configure server for testing")
parser.add_argument("--log-startup", action='store_true', help="launch.py argument: print a detailed log of what's happening at startup")
parser.add_argument("--skip-prepare-environment", action='store_true', help="launch.py argument: skip all environment preparation")
parser.add_argument("--skip-install", action='store_true', help="launch.py argument: skip installation of packages")
parser.add_argument("--dump-sysinfo", action='store_true', help="launch.py argument: dump limited sysinfo file (without information about extensions, options) to disk and quit")
parser.add_argument("--loglevel", type=str, help="log level; one of: CRITICAL, ERROR, WARNING, INFO, DEBUG", default=None)
parser.add_argument("--do-not-download-clip", action='store_true', help="do not download CLIP model even if it's not included in the checkpoint")
parser.add_argument("--data-dir", type=str, default=os.path.dirname(os.path.dirname(os.path.realpath(__file__))), help="base path where all user data is stored")
parser.add_argument("--config", type=str, default=sd_default_config, help="path to config which constructs model",)
parser.add_argument("--ckpt", type=str, default=sd_model_file, help="path to checkpoint of stable diffusion model; if specified, this checkpoint will be added to the list of checkpoints and loaded",)
parser.add_argument("--ckpt-dir", type=str, default=None, help="Path to directory with stable diffusion checkpoints")
parser.add_argument("--vae-dir", type=str, default=None, help="Path to directory with VAE files")
parser.add_argument("--gfpgan-dir", type=str, help="GFPGAN directory", default=('./src/gfpgan' if os.path.exists('./src/gfpgan') else './GFPGAN'))
parser.add_argument("--gfpgan-model", type=str, help="GFPGAN model file name", default=None)
parser.add_argument("--no-half", action='store_true', help="do not switch the model to 16-bit floats")
parser.add_argument("--no-half-vae", action='store_true', help="do not switch the VAE model to 16-bit floats")
parser.add_argument("--no-progressbar-hiding", action='store_true', help="do not hide progressbar in gradio UI (we hide it because it slows down ML if you have hardware acceleration in browser)")
parser.add_argument("--max-batch-count", type=int, default=16, help="maximum batch count value for the UI")
parser.add_argument("--embeddings-dir", type=str, default=os.path.join(data_path, 'embeddings'), help="embeddings directory for textual inversion (default: embeddings)")
parser.add_argument("--textual-inversion-templates-dir", type=str, default=os.path.join(script_path, 'textual_inversion_templates'), help="directory with textual inversion templates")
parser.add_argument("--hypernetwork-dir", type=str, default=os.path.join(models_path, 'hypernetworks'), help="hypernetwork directory")
parser.add_argument("--localizations-dir", type=str, default=os.path.join(script_path, 'localizations'), help="localizations directory")
parser.add_argument("--allow-code", action='store_true', help="allow custom script execution from webui")
parser.add_argument("--medvram", action='store_true', help="enable stable diffusion model optimizations for sacrificing a little speed for low VRM usage")
parser.add_argument("--medvram-sdxl", action='store_true', help="enable --medvram optimization just for SDXL models")
parser.add_argument("--lowvram", action='store_true', help="enable stable diffusion model optimizations for sacrificing a lot of speed for very low VRM usage")
parser.add_argument("--lowram", action='store_true', help="load stable diffusion checkpoint weights to VRAM instead of RAM")
parser.add_argument("--always-batch-cond-uncond", action='store_true', help="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("--upcast-sampling", action='store_true', help="upcast sampling. No effect with --no-half. Usually produces similar results to --no-half with better performance while using less memory.")
parser.add_argument("--share", action='store_true', help="use share=True for gradio and make the UI accessible through their site")
parser.add_argument("--ngrok", type=str, help="ngrok authtoken, alternative to gradio --share", default=None)
parser.add_argument("--ngrok-region", type=str, help="does not do anything.", default="")
parser.add_argument("--ngrok-options", type=json.loads, help='The options to pass to ngrok in JSON format, e.g.: \'{"authtoken_from_env":true, "basic_auth":"user:password", "oauth_provider":"google", "oauth_allow_emails":"user@asdf.com"}\'', default=dict())
parser.add_argument("--enable-insecure-extension-access", action='store_true', help="enable extensions tab regardless of other options")
parser.add_argument("--codeformer-models-path", type=str, help="Path to directory with codeformer model file(s).", default=os.path.join(models_path, 'Codeformer'))
parser.add_argument("--gfpgan-models-path", type=str, help="Path to directory with GFPGAN model file(s).", default=os.path.join(models_path, 'GFPGAN'))
parser.add_argument("--esrgan-models-path", type=str, help="Path to directory with ESRGAN model file(s).", default=os.path.join(models_path, 'ESRGAN'))
parser.add_argument("--bsrgan-models-path", type=str, help="Path to directory with BSRGAN model file(s).", default=os.path.join(models_path, 'BSRGAN'))
parser.add_argument("--realesrgan-models-path", type=str, help="Path to directory with RealESRGAN model file(s).", default=os.path.join(models_path, 'RealESRGAN'))
parser.add_argument("--clip-models-path", type=str, help="Path to directory with CLIP model file(s).", default=None)
parser.add_argument("--xformers", action='store_true', help="enable xformers for cross attention layers")
parser.add_argument("--force-enable-xformers", action='store_true', help="enable xformers for cross attention layers regardless of whether the checking code thinks you can run it; do not make bug reports if this fails to work")
parser.add_argument("--xformers-flash-attention", action='store_true', help="enable xformers with Flash Attention to improve reproducibility (supported for SD2.x or variant only)")
parser.add_argument("--deepdanbooru", action='store_true', help="does not do anything")
parser.add_argument("--opt-split-attention", action='store_true', help="prefer Doggettx's cross-attention layer optimization for automatic choice of optimization")
parser.add_argument("--opt-sub-quad-attention", action='store_true', help="prefer memory efficient sub-quadratic cross-attention layer optimization for automatic choice of optimization")
parser.add_argument("--sub-quad-q-chunk-size", type=int, help="query chunk size for the sub-quadratic cross-attention layer optimization to use", default=1024)
parser.add_argument("--sub-quad-kv-chunk-size", type=int, help="kv chunk size for the sub-quadratic cross-attention layer optimization to use", default=None)
parser.add_argument("--sub-quad-chunk-threshold", type=int, help="the percentage of VRAM threshold for the sub-quadratic cross-attention layer optimization to use chunking", default=None)
parser.add_argument("--opt-split-attention-invokeai", action='store_true', help="prefer InvokeAI's cross-attention layer optimization for automatic choice of optimization")
parser.add_argument("--opt-split-attention-v1", action='store_true', help="prefer older version of split attention optimization for automatic choice of optimization")
parser.add_argument("--opt-sdp-attention", action='store_true', help="prefer scaled dot product cross-attention layer optimization for automatic choice of optimization; requires PyTorch 2.*")
parser.add_argument("--opt-sdp-no-mem-attention", action='store_true', help="prefer scaled dot product cross-attention layer optimization without memory efficient attention for automatic choice of optimization, makes image generation deterministic; requires PyTorch 2.*")
parser.add_argument("--disable-opt-split-attention", action='store_true', help="prefer no cross-attention layer optimization for automatic choice of optimization")
parser.add_argument("--disable-nan-check", action='store_true', help="do not check if produced images/latent spaces have nans; useful for running without a checkpoint in CI")
parser.add_argument("--use-cpu", nargs='+', help="use CPU as torch device for specified modules", default=[], type=str.lower)
parser.add_argument("--disable-model-loading-ram-optimization", action='store_true', help="disable an optimization that reduces RAM use when loading a model")
parser.add_argument("--listen", action='store_true', help="launch gradio with 0.0.0.0 as server name, allowing to respond to network requests")
parser.add_argument("--port", type=int, help="launch gradio with given server port, you need root/admin rights for ports < 1024, defaults to 7860 if available", default=None)
parser.add_argument("--show-negative-prompt", action='store_true', help="does not do anything", default=False)
parser.add_argument("--ui-config-file", type=str, help="filename to use for ui configuration", default=os.path.join(data_path, 'ui-config.json'))
parser.add_argument("--hide-ui-dir-config", action='store_true', help="hide directory configuration from webui", default=False)
parser.add_argument("--freeze-settings", action='store_true', help="disable editing settings", default=False)
parser.add_argument("--ui-settings-file", type=str, help="filename to use for ui settings", default=os.path.join(data_path, 'config.json'))
parser.add_argument("--gradio-debug", action='store_true', help="launch gradio with --debug option")
parser.add_argument("--gradio-auth", type=str, help='set gradio authentication like "username:password"; or comma-delimit multiple like "u1:p1,u2:p2,u3:p3"', default=None)
parser.add_argument("--gradio-auth-path", type=str, help='set gradio authentication file path ex. "/path/to/auth/file" same auth format as --gradio-auth', default=None)
parser.add_argument("--gradio-img2img-tool", type=str, help='does not do anything')
parser.add_argument("--gradio-inpaint-tool", type=str, help="does not do anything")
parser.add_argument("--gradio-allowed-path", action='append', help="add path to gradio's allowed_paths, make it possible to serve files from it", default=[data_path])
parser.add_argument("--opt-channelslast", action='store_true', help="change memory type for stable diffusion to channels last")
parser.add_argument("--styles-file", type=str, help="filename to use for styles", default=os.path.join(data_path, 'styles.csv'))
parser.add_argument("--autolaunch", action='store_true', help="open the webui URL in the system's default browser upon launch", default=False)
parser.add_argument("--theme", type=str, help="launches the UI with light or dark theme", default=None)
parser.add_argument("--use-textbox-seed", action='store_true', help="use textbox for seeds in UI (no up/down, but possible to input long seeds)", default=False)
parser.add_argument("--disable-console-progressbars", action='store_true', help="do not output progressbars to console", default=False)
parser.add_argument("--enable-console-prompts", action='store_true', help="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("--disable-safe-unpickle", action='store_true', help="disable checking pytorch models for malicious code", default=False)
parser.add_argument("--api", action='store_true', help="use api=True to launch the API together with the webui (use --nowebui instead for only the API)")
parser.add_argument("--api-auth", type=str, help='Set authentication for API like "username:password"; or comma-delimit multiple like "u1:p1,u2:p2,u3:p3"', default=None)
parser.add_argument("--api-log", action='store_true', help="use api-log=True to enable logging of all API requests")
parser.add_argument("--nowebui", action='store_true', help="use api=True to launch the API instead of the webui")
parser.add_argument("--ui-debug-mode", action='store_true', help="Don't load model to quickly launch UI")
parser.add_argument("--device-id", type=str, help="Select the default CUDA device to use (export CUDA_VISIBLE_DEVICES=0,1,etc might be needed before)", default=None)
parser.add_argument("--administrator", action='store_true', help="Administrator rights", default=False)
parser.add_argument("--cors-allow-origins", type=str, help="Allowed CORS origin(s) in the form of a comma-separated list (no spaces)", default=None)
parser.add_argument("--cors-allow-origins-regex", type=str, help="Allowed CORS origin(s) in the form of a single regular expression", default=None)
parser.add_argument("--tls-keyfile", type=str, help="Partially enables TLS, requires --tls-certfile to fully function", default=None)
parser.add_argument("--tls-certfile", type=str, help="Partially enables TLS, requires --tls-keyfile to fully function", 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("--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("--skip-version-check", action='store_true', help="Do not check versions of torch and xformers")
parser.add_argument("--no-hashing", action='store_true', help="disable sha256 hashing of checkpoints to help loading performance", default=False)
parser.add_argument("--no-download-sd-model", action='store_true', help="don't download SD1.5 model even if no model is found in --ckpt-dir", default=False)
parser.add_argument('--subpath', type=str, help='customize the subpath for gradio, use with reverse proxy')
parser.add_argument('--add-stop-route', action='store_true', help='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", )
+11 -13
View File
@@ -1,14 +1,12 @@
# this file is copied from CodeFormer repository. Please see comment in modules/codeformer_model.py # this file is copied from CodeFormer repository. Please see comment in modules/codeformer_model.py
import math import math
import numpy as np
import torch import torch
from torch import nn, Tensor from torch import nn, Tensor
import torch.nn.functional as F import torch.nn.functional as F
from typing import Optional, List from typing import Optional
from modules.codeformer.vqgan_arch import * from modules.codeformer.vqgan_arch import VQAutoEncoder, ResBlock
from basicsr.utils import get_root_logger
from basicsr.utils.registry import ARCH_REGISTRY from basicsr.utils.registry import ARCH_REGISTRY
def calc_mean_std(feat, eps=1e-5): def calc_mean_std(feat, eps=1e-5):
@@ -121,7 +119,7 @@ class TransformerSALayer(nn.Module):
tgt_mask: Optional[Tensor] = None, tgt_mask: Optional[Tensor] = None,
tgt_key_padding_mask: Optional[Tensor] = None, tgt_key_padding_mask: Optional[Tensor] = None,
query_pos: Optional[Tensor] = None): query_pos: Optional[Tensor] = None):
# self attention # self attention
tgt2 = self.norm1(tgt) tgt2 = self.norm1(tgt)
q = k = self.with_pos_embed(tgt2, query_pos) q = k = self.with_pos_embed(tgt2, query_pos)
@@ -161,10 +159,10 @@ class Fuse_sft_block(nn.Module):
@ARCH_REGISTRY.register() @ARCH_REGISTRY.register()
class CodeFormer(VQAutoEncoder): class CodeFormer(VQAutoEncoder):
def __init__(self, dim_embd=512, n_head=8, n_layers=9, def __init__(self, dim_embd=512, n_head=8, n_layers=9,
codebook_size=1024, latent_size=256, codebook_size=1024, latent_size=256,
connect_list=['32', '64', '128', '256'], connect_list=('32', '64', '128', '256'),
fix_modules=['quantize','generator']): fix_modules=('quantize', 'generator')):
super(CodeFormer, self).__init__(512, 64, [1, 2, 2, 4, 4, 8], 'nearest',2, [16], codebook_size) super(CodeFormer, self).__init__(512, 64, [1, 2, 2, 4, 4, 8], 'nearest',2, [16], codebook_size)
if fix_modules is not None: if fix_modules is not None:
@@ -181,14 +179,14 @@ class CodeFormer(VQAutoEncoder):
self.feat_emb = nn.Linear(256, self.dim_embd) self.feat_emb = nn.Linear(256, self.dim_embd)
# transformer # transformer
self.ft_layers = nn.Sequential(*[TransformerSALayer(embed_dim=dim_embd, nhead=n_head, dim_mlp=self.dim_mlp, dropout=0.0) 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)]) for _ in range(self.n_layers)])
# logits_predict head # logits_predict head
self.idx_pred_layer = nn.Sequential( self.idx_pred_layer = nn.Sequential(
nn.LayerNorm(dim_embd), nn.LayerNorm(dim_embd),
nn.Linear(dim_embd, codebook_size, bias=False)) nn.Linear(dim_embd, codebook_size, bias=False))
self.channels = { self.channels = {
'16': 512, '16': 512,
'32': 256, '32': 256,
@@ -223,7 +221,7 @@ class CodeFormer(VQAutoEncoder):
enc_feat_dict = {} enc_feat_dict = {}
out_list = [self.fuse_encoder_block[f_size] for f_size in self.connect_list] out_list = [self.fuse_encoder_block[f_size] for f_size in self.connect_list]
for i, block in enumerate(self.encoder.blocks): for i, block in enumerate(self.encoder.blocks):
x = block(x) x = block(x)
if i in out_list: if i in out_list:
enc_feat_dict[str(x.shape[-1])] = x.clone() enc_feat_dict[str(x.shape[-1])] = x.clone()
@@ -268,11 +266,11 @@ class CodeFormer(VQAutoEncoder):
fuse_list = [self.fuse_generator_block[f_size] for f_size in self.connect_list] fuse_list = [self.fuse_generator_block[f_size] for f_size in self.connect_list]
for i, block in enumerate(self.generator.blocks): for i, block in enumerate(self.generator.blocks):
x = block(x) x = block(x)
if i in fuse_list: # fuse after i-th block if i in fuse_list: # fuse after i-th block
f_size = str(x.shape[-1]) f_size = str(x.shape[-1])
if w>0: if w>0:
x = self.fuse_convs_dict[f_size](enc_feat_dict[f_size].detach(), x, w) x = self.fuse_convs_dict[f_size](enc_feat_dict[f_size].detach(), x, w)
out = x out = x
# logits doesn't need softmax before cross_entropy loss # logits doesn't need softmax before cross_entropy loss
return out, logits, lq_feat return out, logits, lq_feat
+21 -23
View File
@@ -5,17 +5,15 @@ VQGAN code, adapted from the original created by the Unleashing Transformers aut
https://github.com/samb-t/unleashing-transformers/blob/master/models/vqgan.py https://github.com/samb-t/unleashing-transformers/blob/master/models/vqgan.py
''' '''
import numpy as np
import torch import torch
import torch.nn as nn import torch.nn as nn
import torch.nn.functional as F import torch.nn.functional as F
import copy
from basicsr.utils import get_root_logger from basicsr.utils import get_root_logger
from basicsr.utils.registry import ARCH_REGISTRY from basicsr.utils.registry import ARCH_REGISTRY
def normalize(in_channels): def normalize(in_channels):
return torch.nn.GroupNorm(num_groups=32, num_channels=in_channels, eps=1e-6, affine=True) return torch.nn.GroupNorm(num_groups=32, num_channels=in_channels, eps=1e-6, affine=True)
@torch.jit.script @torch.jit.script
def swish(x): def swish(x):
@@ -212,15 +210,15 @@ class AttnBlock(nn.Module):
# compute attention # compute attention
b, c, h, w = q.shape b, c, h, w = q.shape
q = q.reshape(b, c, h*w) q = q.reshape(b, c, h*w)
q = q.permute(0, 2, 1) q = q.permute(0, 2, 1)
k = k.reshape(b, c, h*w) k = k.reshape(b, c, h*w)
w_ = torch.bmm(q, k) w_ = torch.bmm(q, k)
w_ = w_ * (int(c)**(-0.5)) w_ = w_ * (int(c)**(-0.5))
w_ = F.softmax(w_, dim=2) w_ = F.softmax(w_, dim=2)
# attend to values # attend to values
v = v.reshape(b, c, h*w) v = v.reshape(b, c, h*w)
w_ = w_.permute(0, 2, 1) w_ = w_.permute(0, 2, 1)
h_ = torch.bmm(v, w_) h_ = torch.bmm(v, w_)
h_ = h_.reshape(b, c, h, w) h_ = h_.reshape(b, c, h, w)
@@ -272,18 +270,18 @@ class Encoder(nn.Module):
def forward(self, x): def forward(self, x):
for block in self.blocks: for block in self.blocks:
x = block(x) x = block(x)
return x return x
class Generator(nn.Module): class Generator(nn.Module):
def __init__(self, nf, emb_dim, ch_mult, res_blocks, img_size, attn_resolutions): def __init__(self, nf, emb_dim, ch_mult, res_blocks, img_size, attn_resolutions):
super().__init__() super().__init__()
self.nf = nf self.nf = nf
self.ch_mult = ch_mult self.ch_mult = ch_mult
self.num_resolutions = len(self.ch_mult) self.num_resolutions = len(self.ch_mult)
self.num_res_blocks = res_blocks self.num_res_blocks = res_blocks
self.resolution = img_size self.resolution = img_size
self.attn_resolutions = attn_resolutions self.attn_resolutions = attn_resolutions
self.in_channels = emb_dim self.in_channels = emb_dim
self.out_channels = 3 self.out_channels = 3
@@ -317,29 +315,29 @@ class Generator(nn.Module):
blocks.append(nn.Conv2d(block_in_ch, self.out_channels, kernel_size=3, stride=1, padding=1)) blocks.append(nn.Conv2d(block_in_ch, self.out_channels, kernel_size=3, stride=1, padding=1))
self.blocks = nn.ModuleList(blocks) self.blocks = nn.ModuleList(blocks)
def forward(self, x): def forward(self, x):
for block in self.blocks: for block in self.blocks:
x = block(x) x = block(x)
return x return x
@ARCH_REGISTRY.register() @ARCH_REGISTRY.register()
class VQAutoEncoder(nn.Module): class VQAutoEncoder(nn.Module):
def __init__(self, img_size, nf, ch_mult, quantizer="nearest", res_blocks=2, attn_resolutions=[16], codebook_size=1024, emb_dim=256, 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): beta=0.25, gumbel_straight_through=False, gumbel_kl_weight=1e-8, model_path=None):
super().__init__() super().__init__()
logger = get_root_logger() logger = get_root_logger()
self.in_channels = 3 self.in_channels = 3
self.nf = nf self.nf = nf
self.n_blocks = res_blocks self.n_blocks = res_blocks
self.codebook_size = codebook_size self.codebook_size = codebook_size
self.embed_dim = emb_dim self.embed_dim = emb_dim
self.ch_mult = ch_mult self.ch_mult = ch_mult
self.resolution = img_size self.resolution = img_size
self.attn_resolutions = attn_resolutions self.attn_resolutions = attn_resolutions or [16]
self.quantizer_type = quantizer self.quantizer_type = quantizer
self.encoder = Encoder( self.encoder = Encoder(
self.in_channels, self.in_channels,
@@ -365,11 +363,11 @@ class VQAutoEncoder(nn.Module):
self.kl_weight self.kl_weight
) )
self.generator = Generator( self.generator = Generator(
self.nf, self.nf,
self.embed_dim, self.embed_dim,
self.ch_mult, self.ch_mult,
self.n_blocks, self.n_blocks,
self.resolution, self.resolution,
self.attn_resolutions self.attn_resolutions
) )
@@ -434,4 +432,4 @@ class VQGANDiscriminator(nn.Module):
raise ValueError('Wrong params!') raise ValueError('Wrong params!')
def forward(self, x): def forward(self, x):
return self.main(x) return self.main(x)
+10 -21
View File
@@ -1,14 +1,12 @@
import os import os
import sys
import traceback
import cv2 import cv2
import torch import torch
import modules.face_restoration import modules.face_restoration
import modules.shared import modules.shared
from modules import shared, devices, modelloader from modules import shared, devices, modelloader, errors
from modules.paths import script_path, models_path from modules.paths import models_path
# codeformer people made a choice to include modified basicsr library to their project which makes # 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. # it utterly impossible to use it alongside with other libraries that also use basicsr, like GFPGAN.
@@ -17,14 +15,11 @@ model_dir = "Codeformer"
model_path = os.path.join(models_path, model_dir) 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'
have_codeformer = False
codeformer = None codeformer = None
def setup_model(dirname): def setup_model(dirname):
global model_path os.makedirs(model_path, exist_ok=True)
if not os.path.exists(model_path):
os.makedirs(model_path)
path = modules.paths.paths.get("CodeFormer", None) path = modules.paths.paths.get("CodeFormer", None)
if path is None: if path is None:
@@ -33,11 +28,9 @@ def setup_model(dirname):
try: try:
from torchvision.transforms.functional import normalize from torchvision.transforms.functional import normalize
from modules.codeformer.codeformer_arch import CodeFormer from modules.codeformer.codeformer_arch import CodeFormer
from basicsr.utils.download_util import load_file_from_url from basicsr.utils import img2tensor, tensor2img
from basicsr.utils import imwrite, img2tensor, tensor2img
from facelib.utils.face_restoration_helper import FaceRestoreHelper from facelib.utils.face_restoration_helper import FaceRestoreHelper
from facelib.detection.retinaface import retinaface from facelib.detection.retinaface import retinaface
from modules.shared import cmd_opts
net_class = CodeFormer net_class = CodeFormer
@@ -55,7 +48,7 @@ def setup_model(dirname):
if self.net is not None and self.face_helper is not None: if self.net is not None and self.face_helper is not None:
self.net.to(devices.device_codeformer) self.net.to(devices.device_codeformer)
return self.net, self.face_helper 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') 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: if len(model_paths) != 0:
ckpt_path = model_paths[0] ckpt_path = model_paths[0]
else: else:
@@ -96,7 +89,7 @@ def setup_model(dirname):
self.face_helper.get_face_landmarks_5(only_center_face=False, resize=640, eye_dist_threshold=5) self.face_helper.get_face_landmarks_5(only_center_face=False, resize=640, eye_dist_threshold=5)
self.face_helper.align_warp_face() self.face_helper.align_warp_face()
for idx, cropped_face in enumerate(self.face_helper.cropped_faces): for cropped_face in self.face_helper.cropped_faces:
cropped_face_t = img2tensor(cropped_face / 255., bgr2rgb=True, float32=True) 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) 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) cropped_face_t = cropped_face_t.unsqueeze(0).to(devices.device_codeformer)
@@ -106,9 +99,9 @@ def setup_model(dirname):
output = self.net(cropped_face_t, w=w if w is not None else shared.opts.code_former_weight, adain=True)[0] 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)) restored_face = tensor2img(output, rgb2bgr=True, min_max=(-1, 1))
del output del output
torch.cuda.empty_cache() devices.torch_gc()
except Exception as error: except Exception:
print(f'\tFailed inference for CodeFormer: {error}', file=sys.stderr) errors.report('Failed inference for CodeFormer', exc_info=True)
restored_face = tensor2img(cropped_face_t, rgb2bgr=True, min_max=(-1, 1)) restored_face = tensor2img(cropped_face_t, rgb2bgr=True, min_max=(-1, 1))
restored_face = restored_face.astype('uint8') restored_face = restored_face.astype('uint8')
@@ -129,15 +122,11 @@ def setup_model(dirname):
return restored_img return restored_img
global have_codeformer
have_codeformer = True
global codeformer global codeformer
codeformer = FaceRestorerCodeFormer(dirname) codeformer = FaceRestorerCodeFormer(dirname)
shared.face_restorers.append(codeformer) shared.face_restorers.append(codeformer)
except Exception: except Exception:
print("Error setting up CodeFormer:", file=sys.stderr) errors.report("Error setting up CodeFormer", exc_info=True)
print(traceback.format_exc(), file=sys.stderr)
# sys.path = stored_sys_path # sys.path = stored_sys_path
+198
View File
@@ -0,0 +1,198 @@
"""
Supports saving and restoring webui and extensions from a known working set of commits
"""
import os
import json
import tqdm
from datetime import datetime
import git
from modules import shared, extensions, errors
from modules.paths_internal import script_path, config_states_dir
all_config_states = {}
def list_config_states():
global all_config_states
all_config_states.clear()
os.makedirs(config_states_dir, exist_ok=True)
config_states = []
for filename in os.listdir(config_states_dir):
if filename.endswith(".json"):
path = os.path.join(config_states_dir, filename)
try:
with open(path, "r", encoding="utf-8") as f:
j = json.load(f)
assert "created_at" in j, '"created_at" does not exist'
j["filepath"] = path
config_states.append(j)
except Exception as e:
print(f'[ERROR]: Config states {path}, {e}')
config_states = sorted(config_states, key=lambda cs: cs["created_at"], reverse=True)
for cs in config_states:
timestamp = datetime.fromtimestamp(cs["created_at"]).strftime('%Y-%m-%d %H:%M:%S')
name = cs.get("name", "Config")
full_name = f"{name}: {timestamp}"
all_config_states[full_name] = cs
return all_config_states
def get_webui_config():
webui_repo = None
try:
if os.path.exists(os.path.join(script_path, ".git")):
webui_repo = git.Repo(script_path)
except Exception:
errors.report(f"Error reading webui git info from {script_path}", exc_info=True)
webui_remote = None
webui_commit_hash = None
webui_commit_date = None
webui_branch = None
if webui_repo and not webui_repo.bare:
try:
webui_remote = next(webui_repo.remote().urls, None)
head = webui_repo.head.commit
webui_commit_date = webui_repo.head.commit.committed_date
webui_commit_hash = head.hexsha
webui_branch = webui_repo.active_branch.name
except Exception:
webui_remote = None
return {
"remote": webui_remote,
"commit_hash": webui_commit_hash,
"commit_date": webui_commit_date,
"branch": webui_branch,
}
def get_extension_config():
ext_config = {}
for ext in extensions.extensions:
ext.read_info_from_repo()
entry = {
"name": ext.name,
"path": ext.path,
"enabled": ext.enabled,
"is_builtin": ext.is_builtin,
"remote": ext.remote,
"commit_hash": ext.commit_hash,
"commit_date": ext.commit_date,
"branch": ext.branch,
"have_info_from_repo": ext.have_info_from_repo
}
ext_config[ext.name] = entry
return ext_config
def get_config():
creation_time = datetime.now().timestamp()
webui_config = get_webui_config()
ext_config = get_extension_config()
return {
"created_at": creation_time,
"webui": webui_config,
"extensions": ext_config
}
def restore_webui_config(config):
print("* Restoring webui state...")
if "webui" not in config:
print("Error: No webui data saved to config")
return
webui_config = config["webui"]
if "commit_hash" not in webui_config:
print("Error: No commit saved to webui config")
return
webui_commit_hash = webui_config.get("commit_hash", None)
webui_repo = None
try:
if os.path.exists(os.path.join(script_path, ".git")):
webui_repo = git.Repo(script_path)
except Exception:
errors.report(f"Error reading webui git info from {script_path}", exc_info=True)
return
try:
webui_repo.git.fetch(all=True)
webui_repo.git.reset(webui_commit_hash, hard=True)
print(f"* Restored webui to commit {webui_commit_hash}.")
except Exception:
errors.report(f"Error restoring webui to commit{webui_commit_hash}")
def restore_extension_config(config):
print("* Restoring extension state...")
if "extensions" not in config:
print("Error: No extension data saved to config")
return
ext_config = config["extensions"]
results = []
disabled = []
for ext in tqdm.tqdm(extensions.extensions):
if ext.is_builtin:
continue
ext.read_info_from_repo()
current_commit = ext.commit_hash
if ext.name not in ext_config:
ext.disabled = True
disabled.append(ext.name)
results.append((ext, current_commit[:8], False, "Saved extension state not found in config, marking as disabled"))
continue
entry = ext_config[ext.name]
if "commit_hash" in entry and entry["commit_hash"]:
try:
ext.fetch_and_reset_hard(entry["commit_hash"])
ext.read_info_from_repo()
if current_commit != entry["commit_hash"]:
results.append((ext, current_commit[:8], True, entry["commit_hash"][:8]))
except Exception as ex:
results.append((ext, current_commit[:8], False, ex))
else:
results.append((ext, current_commit[:8], False, "No commit hash found in config"))
if not entry.get("enabled", False):
ext.disabled = True
disabled.append(ext.name)
else:
ext.disabled = False
shared.opts.disabled_extensions = disabled
shared.opts.save(shared.config_filename)
print("* Finished restoring extensions. Results:")
for ext, prev_commit, success, result in results:
if success:
print(f" + {ext.name}: {prev_commit} -> {result}")
else:
print(f" ! {ext.name}: FAILURE ({result})")
+1 -2
View File
@@ -2,7 +2,6 @@ import os
import re import re
import torch import torch
from PIL import Image
import numpy as np import numpy as np
from modules import modelloader, paths, deepbooru_model, devices, images, shared from modules import modelloader, paths, deepbooru_model, devices, images, shared
@@ -79,7 +78,7 @@ class DeepDanbooru:
res = [] res = []
filtertags = set([x.strip().replace(' ', '_') for x in shared.opts.deepbooru_filter_tags.split(",")]) filtertags = {x.strip().replace(' ', '_') for x in shared.opts.deepbooru_filter_tags.split(",")}
for tag in [x for x in tags if x not in filtertags]: for tag in [x for x in tags if x not in filtertags]:
probability = probability_dict[tag] probability = probability_dict[tag]
+3 -1
View File
@@ -2,6 +2,8 @@ import torch
import torch.nn as nn import torch.nn as nn
import torch.nn.functional as F import torch.nn.functional as F
from modules import devices
# see https://github.com/AUTOMATIC1111/TorchDeepDanbooru for more # see https://github.com/AUTOMATIC1111/TorchDeepDanbooru for more
@@ -196,7 +198,7 @@ class DeepDanbooruModel(nn.Module):
t_358, = inputs t_358, = inputs
t_359 = t_358.permute(*[0, 3, 1, 2]) t_359 = t_358.permute(*[0, 3, 1, 2])
t_359_padded = F.pad(t_359, [2, 3, 2, 3], value=0) t_359_padded = F.pad(t_359, [2, 3, 2, 3], value=0)
t_360 = self.n_Conv_0(t_359_padded) t_360 = self.n_Conv_0(t_359_padded.to(self.n_Conv_0.bias.dtype) if devices.unet_needs_upcast else t_359_padded)
t_361 = F.relu(t_360) t_361 = F.relu(t_360)
t_361 = F.pad(t_361, [0, 1, 0, 1], value=float('-inf')) t_361 = F.pad(t_361, [0, 1, 0, 1], value=float('-inf'))
t_362 = self.n_MaxPool_0(t_361) t_362 = self.n_MaxPool_0(t_361)
+60 -98
View File
@@ -1,52 +1,43 @@
import sys, os, shlex import sys
import contextlib import contextlib
from functools import lru_cache
import torch import torch
from modules import errors from modules import errors, shared
from packaging import version
if sys.platform == "darwin":
from modules import mac_specific
# has_mps is only available in nightly pytorch (for now) and macOS 12.3+.
# check `getattr` and try it for compatibility
def has_mps() -> bool: def has_mps() -> bool:
if not getattr(torch, 'has_mps', False): if sys.platform != "darwin":
return False return False
try: else:
torch.zeros(1).to(torch.device("mps")) return mac_specific.has_mps
return True
except Exception:
return False
def extract_device_id(args, name):
for x in range(len(args)):
if name in args[x]:
return args[x + 1]
return None
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}"
return "cuda" return "cuda"
def get_optimal_device(): def get_optimal_device_name():
if torch.cuda.is_available(): if torch.cuda.is_available():
return torch.device(get_cuda_device_string()) return get_cuda_device_string()
if has_mps(): if has_mps():
return torch.device("mps") return "mps"
return cpu return "cpu"
def get_optimal_device():
return torch.device(get_optimal_device_name())
def get_device_for(task): def get_device_for(task):
from modules import shared
if task in shared.cmd_opts.use_cpu: if task in shared.cmd_opts.use_cpu:
return cpu return cpu
@@ -54,49 +45,55 @@ def get_device_for(task):
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()
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())]): device_id = (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()
if torch.cuda.get_device_capability(device_id) == (7, 5) and torch.cuda.get_device_name(device_id).startswith("NVIDIA GeForce GTX 16"):
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 device: torch.device = None
dtype = torch.float16 device_interrogate: torch.device = None
dtype_vae = torch.float16 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
unet_needs_upcast = False
def randn(seed, shape): def cond_cast_unet(input):
torch.manual_seed(seed) return input.to(dtype_unet) if unet_needs_upcast else input
if device.type == 'mps':
return torch.randn(shape, device=cpu).to(device)
return torch.randn(shape, device=device)
def randn_without_seed(shape): def cond_cast_float(input):
if device.type == 'mps': return input.float() if unet_needs_upcast else input
return torch.randn(shape, device=cpu).to(device)
return torch.randn(shape, device=device)
nv_rng = None
def autocast(disable=False): def autocast(disable=False):
from modules import shared
if disable: if disable:
return contextlib.nullcontext() return contextlib.nullcontext()
@@ -106,13 +103,15 @@ def autocast(disable=False):
return torch.autocast("cuda") return torch.autocast("cuda")
def without_autocast(disable=False):
return torch.autocast("cuda", enabled=False) if torch.is_autocast_enabled() and not disable else contextlib.nullcontext()
class NansException(Exception): class NansException(Exception):
pass pass
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
@@ -123,7 +122,7 @@ def test_for_nans(x, where):
message = "A tensor with all NaNs was produced in Unet." message = "A tensor with all 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 using --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 all NaNs was produced in VAE."
@@ -133,60 +132,23 @@ def test_for_nans(x, where):
else: else:
message = "A tensor with all NaNs was produced." message = "A tensor with all NaNs was produced."
message += " Use --disable-nan-check commandline argument to disable this check."
raise NansException(message) raise NansException(message)
# MPS workaround for https://github.com/pytorch/pytorch/issues/79383 @lru_cache
orig_tensor_to = torch.Tensor.to def first_time_calculation():
def tensor_to_fix(self, *args, **kwargs): """
if self.device.type != 'mps' and \ just do any calculation with pytorch layers - the first time this is done it allocaltes about 700MB of memory and
((len(args) > 0 and isinstance(args[0], torch.device) and args[0].type == 'mps') or \ spends about 2.7 seconds doing that, at least wih NVidia.
(isinstance(kwargs.get('device'), torch.device) and kwargs['device'].type == 'mps')): """
self = self.contiguous()
return orig_tensor_to(self, *args, **kwargs)
x = torch.zeros((1, 1)).to(device, dtype)
linear = torch.nn.Linear(1, 1).to(device, dtype)
linear(x)
# MPS workaround for https://github.com/pytorch/pytorch/issues/80800 x = torch.zeros((1, 1, 3, 3)).to(device, dtype)
orig_layer_norm = torch.nn.functional.layer_norm conv2d = torch.nn.Conv2d(1, 1, (3, 3)).to(device, dtype)
def layer_norm_fix(*args, **kwargs): conv2d(x)
if len(args) > 0 and isinstance(args[0], torch.Tensor) and args[0].device.type == 'mps':
args = list(args)
args[0] = args[0].contiguous()
return orig_layer_norm(*args, **kwargs)
# MPS workaround for https://github.com/pytorch/pytorch/issues/90532
orig_tensor_numpy = torch.Tensor.numpy
def numpy_fix(self, *args, **kwargs):
if self.requires_grad:
self = self.detach()
return orig_tensor_numpy(self, *args, **kwargs)
# MPS workaround for https://github.com/pytorch/pytorch/issues/89784
orig_cumsum = torch.cumsum
orig_Tensor_cumsum = torch.Tensor.cumsum
def cumsum_fix(input, cumsum_func, *args, **kwargs):
if input.device.type == 'mps':
output_dtype = kwargs.get('dtype', input.dtype)
if output_dtype == torch.int64:
return cumsum_func(input.cpu(), *args, **kwargs).to(input.device)
elif cumsum_needs_bool_fix and output_dtype == torch.bool or cumsum_needs_int_fix and (output_dtype == torch.int8 or output_dtype == torch.int16):
return cumsum_func(input.to(torch.int32), *args, **kwargs).to(torch.int64)
return cumsum_func(input, *args, **kwargs)
if has_mps():
if version.parse(torch.__version__) < version.parse("1.13"):
# PyTorch 1.13 doesn't need these fixes but unfortunately is slower and has regressions that prevent training from working
torch.Tensor.to = tensor_to_fix
torch.nn.functional.layer_norm = layer_norm_fix
torch.Tensor.numpy = numpy_fix
elif version.parse(torch.__version__) > version.parse("1.13.1"):
cumsum_needs_int_fix = not torch.Tensor([1,2]).to(torch.device("mps")).equal(torch.ShortTensor([1,1]).to(torch.device("mps")).cumsum(0))
cumsum_needs_bool_fix = not torch.BoolTensor([True,True]).to(device=torch.device("mps"), dtype=torch.int64).equal(torch.BoolTensor([True,False]).to(torch.device("mps")).cumsum(0))
torch.cumsum = lambda input, *args, **kwargs: ( cumsum_fix(input, orig_cumsum, *args, **kwargs) )
torch.Tensor.cumsum = lambda self, *args, **kwargs: ( cumsum_fix(self, orig_Tensor_cumsum, *args, **kwargs) )
orig_narrow = torch.narrow
torch.narrow = lambda *args, **kwargs: ( orig_narrow(*args, **kwargs).clone() )
+95 -2
View File
@@ -1,8 +1,43 @@
import sys import sys
import textwrap
import traceback import traceback
exception_records = []
def record_exception():
_, e, tb = sys.exc_info()
if e is None:
return
if exception_records and exception_records[-1] == e:
return
from modules import sysinfo
exception_records.append(sysinfo.format_exception(e, tb))
if len(exception_records) > 5:
exception_records.pop(0)
def report(message: str, *, exc_info: bool = False) -> None:
"""
Print an error message to stderr, with optional traceback.
"""
record_exception()
for line in message.splitlines():
print("***", line, file=sys.stderr)
if exc_info:
print(textwrap.indent(traceback.format_exc(), " "), file=sys.stderr)
print("---", file=sys.stderr)
def print_error_explanation(message): def print_error_explanation(message):
record_exception()
lines = message.strip().split("\n") lines = message.strip().split("\n")
max_len = max([len(x) for x in lines]) max_len = max([len(x) for x in lines])
@@ -12,9 +47,15 @@ def print_error_explanation(message):
print('=' * max_len, file=sys.stderr) print('=' * max_len, file=sys.stderr)
def display(e: Exception, task): def display(e: Exception, task, *, full_traceback=False):
record_exception()
print(f"{task or 'error'}: {type(e).__name__}", file=sys.stderr) print(f"{task or 'error'}: {type(e).__name__}", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr) te = traceback.TracebackException.from_exception(e)
if full_traceback:
# include frames leading up to the try-catch block
te.stack = traceback.StackSummary(traceback.extract_stack()[:-2] + te.stack)
print(*te.format(), sep="", file=sys.stderr)
message = str(e) message = str(e)
if "copying a param with shape torch.Size([640, 1024]) from checkpoint, the shape in current model is torch.Size([640, 768])" in message: if "copying a param with shape torch.Size([640, 1024]) from checkpoint, the shape in current model is torch.Size([640, 768])" in message:
@@ -28,6 +69,8 @@ already_displayed = {}
def display_once(e: Exception, task): def display_once(e: Exception, task):
record_exception()
if task in already_displayed: if task in already_displayed:
return return
@@ -41,3 +84,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.0.0"
expected_xformers_version = "0.0.20"
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())
+17 -21
View File
@@ -1,24 +1,20 @@
import os import sys
import numpy as np 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
import modules.esrgan_model_arch as arch import modules.esrgan_model_arch as arch
from modules import shared, modelloader, images, devices from modules import modelloader, images, devices
from modules.upscaler import Upscaler, UpscalerData
from modules.shared import opts from modules.shared import opts
from modules.upscaler import Upscaler, UpscalerData
def mod2normal(state_dict): def mod2normal(state_dict):
# this code is copied from https://github.com/victorca25/iNNfer # this code is copied from https://github.com/victorca25/iNNfer
if 'conv_first.weight' in state_dict: if 'conv_first.weight' in state_dict:
crt_net = {} crt_net = {}
items = [] items = list(state_dict)
for k, v in state_dict.items():
items.append(k)
crt_net['model.0.weight'] = state_dict['conv_first.weight'] crt_net['model.0.weight'] = state_dict['conv_first.weight']
crt_net['model.0.bias'] = state_dict['conv_first.bias'] crt_net['model.0.bias'] = state_dict['conv_first.bias']
@@ -52,9 +48,7 @@ def resrgan2normal(state_dict, nb=23):
if "conv_first.weight" in state_dict and "body.0.rdb1.conv1.weight" in state_dict: if "conv_first.weight" in state_dict and "body.0.rdb1.conv1.weight" in state_dict:
re8x = 0 re8x = 0
crt_net = {} crt_net = {}
items = [] items = list(state_dict)
for k, v in state_dict.items():
items.append(k)
crt_net['model.0.weight'] = state_dict['conv_first.weight'] crt_net['model.0.weight'] = state_dict['conv_first.weight']
crt_net['model.0.bias'] = state_dict['conv_first.bias'] crt_net['model.0.bias'] = state_dict['conv_first.bias']
@@ -138,7 +132,7 @@ class UpscalerESRGAN(Upscaler):
scaler_data = UpscalerData(self.model_name, self.model_url, self, 4) scaler_data = UpscalerData(self.model_name, self.model_url, self, 4)
scalers.append(scaler_data) scalers.append(scaler_data)
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)
@@ -147,23 +141,25 @@ class UpscalerESRGAN(Upscaler):
self.scalers.append(scaler_data) self.scalers.append(scaler_data)
def do_upscale(self, img, selected_model): def do_upscale(self, img, selected_model):
model = self.load_model(selected_model) try:
if model is None: model = self.load_model(selected_model)
except Exception as e:
print(f"Unable to load ESRGAN model {selected_model}: {e}", file=sys.stderr)
return img return img
model.to(devices.device_esrgan) model.to(devices.device_esrgan)
img = esrgan_upscale(model, img) img = esrgan_upscale(model, img)
return img return img
def load_model(self, path: str): def load_model(self, path: str):
if "http" in path: if path.startswith("http"):
filename = load_file_from_url(url=self.model_url, model_dir=self.model_path, # TODO: this doesn't use `path` at all?
file_name="%s.pth" % self.model_name, filename = modelloader.load_file_from_url(
progress=True) url=self.model_url,
model_dir=self.model_download_path,
file_name=f"{self.model_name}.pth",
)
else: else:
filename = path filename = path
if not os.path.exists(filename) or filename is None:
print("Unable to load %s from %s" % (self.model_path, filename))
return None
state_dict = torch.load(filename, map_location='cpu' if devices.device_esrgan.type == 'mps' else None) state_dict = torch.load(filename, map_location='cpu' if devices.device_esrgan.type == 'mps' else None)
+13 -11
View File
@@ -1,7 +1,7 @@
# this file is adapted from https://github.com/victorca25/iNNfer # this file is adapted from https://github.com/victorca25/iNNfer
from collections import OrderedDict
import math import math
import functools
import torch import torch
import torch.nn as nn import torch.nn as nn
import torch.nn.functional as F import torch.nn.functional as F
@@ -37,7 +37,7 @@ class RRDBNet(nn.Module):
elif upsample_mode == 'pixelshuffle': elif upsample_mode == 'pixelshuffle':
upsample_block = pixelshuffle_block upsample_block = pixelshuffle_block
else: else:
raise NotImplementedError('upsample mode [{:s}] is not found'.format(upsample_mode)) raise NotImplementedError(f'upsample mode [{upsample_mode}] is not found')
if upscale == 3: if upscale == 3:
upsampler = upsample_block(nf, nf, 3, act_type=act_type, convtype=convtype) upsampler = upsample_block(nf, nf, 3, act_type=act_type, convtype=convtype)
else: else:
@@ -105,7 +105,7 @@ class ResidualDenseBlock_5C(nn.Module):
Modified options that can be used: Modified options that can be used:
- "Partial Convolution based Padding" arXiv:1811.11718 - "Partial Convolution based Padding" arXiv:1811.11718
- "Spectral normalization" arXiv:1802.05957 - "Spectral normalization" arXiv:1802.05957
- "ICASSP 2020 - ESRGAN+ : Further Improving ESRGAN" N. C. - "ICASSP 2020 - ESRGAN+ : Further Improving ESRGAN" N. C.
{Rakotonirina} and A. {Rasoanaivo} {Rakotonirina} and A. {Rasoanaivo}
""" """
@@ -170,7 +170,7 @@ class GaussianNoise(nn.Module):
scale = self.sigma * x.detach() if self.is_relative_detach else self.sigma * x scale = self.sigma * x.detach() if self.is_relative_detach else self.sigma * x
sampled_noise = self.noise.repeat(*x.size()).normal_() * scale sampled_noise = self.noise.repeat(*x.size()).normal_() * scale
x = x + sampled_noise x = x + sampled_noise
return x return x
def conv1x1(in_planes, out_planes, stride=1): def conv1x1(in_planes, out_planes, stride=1):
return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False) return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)
@@ -260,10 +260,10 @@ class Upsample(nn.Module):
def extra_repr(self): def extra_repr(self):
if self.scale_factor is not None: if self.scale_factor is not None:
info = 'scale_factor=' + str(self.scale_factor) info = f'scale_factor={self.scale_factor}'
else: else:
info = 'size=' + str(self.size) info = f'size={self.size}'
info += ', mode=' + self.mode info += f', mode={self.mode}'
return info return info
@@ -349,7 +349,7 @@ def act(act_type, inplace=True, neg_slope=0.2, n_prelu=1, beta=1.0):
elif act_type == 'sigmoid': # [0, 1] range output elif act_type == 'sigmoid': # [0, 1] range output
layer = nn.Sigmoid() layer = nn.Sigmoid()
else: else:
raise NotImplementedError('activation layer [{:s}] is not found'.format(act_type)) raise NotImplementedError(f'activation layer [{act_type}] is not found')
return layer return layer
@@ -371,7 +371,7 @@ def norm(norm_type, nc):
elif norm_type == 'none': elif norm_type == 'none':
def norm_layer(x): return Identity() def norm_layer(x): return Identity()
else: else:
raise NotImplementedError('normalization layer [{:s}] is not found'.format(norm_type)) raise NotImplementedError(f'normalization layer [{norm_type}] is not found')
return layer return layer
@@ -387,7 +387,7 @@ def pad(pad_type, padding):
elif pad_type == 'zero': elif pad_type == 'zero':
layer = nn.ZeroPad2d(padding) layer = nn.ZeroPad2d(padding)
else: else:
raise NotImplementedError('padding layer [{:s}] is not implemented'.format(pad_type)) raise NotImplementedError(f'padding layer [{pad_type}] is not implemented')
return layer return layer
@@ -431,15 +431,17 @@ def conv_block(in_nc, out_nc, kernel_size, stride=1, dilation=1, groups=1, bias=
pad_type='zero', norm_type=None, act_type='relu', mode='CNA', convtype='Conv2D', pad_type='zero', norm_type=None, act_type='relu', mode='CNA', convtype='Conv2D',
spectral_norm=False): spectral_norm=False):
""" Conv layer with padding, normalization, activation """ """ Conv layer with padding, normalization, activation """
assert mode in ['CNA', 'NAC', 'CNAC'], 'Wrong conv mode [{:s}]'.format(mode) assert mode in ['CNA', 'NAC', 'CNAC'], f'Wrong conv mode [{mode}]'
padding = get_valid_padding(kernel_size, dilation) padding = get_valid_padding(kernel_size, dilation)
p = pad(pad_type, padding) if pad_type and pad_type != 'zero' else None p = pad(pad_type, padding) if pad_type and pad_type != 'zero' else None
padding = padding if pad_type == 'zero' else 0 padding = padding if pad_type == 'zero' else 0
if convtype=='PartialConv2D': if convtype=='PartialConv2D':
from torchvision.ops import PartialConv2d # this is definitely not going to work, but PartialConv2d doesn't work anyway and this shuts up static analyzer
c = PartialConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding, c = PartialConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
dilation=dilation, bias=bias, groups=groups) dilation=dilation, bias=bias, groups=groups)
elif convtype=='DeformConv2D': elif convtype=='DeformConv2D':
from torchvision.ops import DeformConv2d # not tested
c = DeformConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding, c = DeformConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
dilation=dilation, bias=bias, groups=groups) dilation=dilation, bias=bias, groups=groups)
elif convtype=='Conv3D': elif convtype=='Conv3D':
+92 -26
View File
@@ -1,21 +1,28 @@
import os import os
import sys import threading
import traceback
import git from modules import shared, errors, cache, scripts
from modules.gitpython_hack import Repo
from modules import paths, shared from modules.paths_internal import extensions_dir, extensions_builtin_dir, script_path # noqa: F401
extensions = [] extensions = []
extensions_dir = os.path.join(paths.script_path, "extensions")
extensions_builtin_dir = os.path.join(paths.script_path, "extensions-builtin") os.makedirs(extensions_dir, exist_ok=True)
def active(): def active():
return [x for x in extensions if x.enabled] if shared.cmd_opts.disable_all_extensions or shared.opts.disable_all_extensions == "all":
return []
elif shared.cmd_opts.disable_extra_extensions or shared.opts.disable_all_extensions == "extra":
return [x for x in extensions if x.enabled and x.is_builtin]
else:
return [x for x in extensions if x.enabled]
class Extension: class Extension:
lock = threading.Lock()
cached_fields = ['remote', 'commit_date', 'branch', 'commit_hash', 'version']
def __init__(self, name, path, enabled=True, is_builtin=False): def __init__(self, name, path, enabled=True, is_builtin=False):
self.name = name self.name = name
self.path = path self.path = path
@@ -23,27 +30,66 @@ class Extension:
self.status = '' self.status = ''
self.can_update = False self.can_update = False
self.is_builtin = is_builtin self.is_builtin = is_builtin
self.commit_hash = ''
self.commit_date = None
self.version = ''
self.branch = None
self.remote = None
self.have_info_from_repo = False
def to_dict(self):
return {x: getattr(self, x) for x in self.cached_fields}
def from_dict(self, d):
for field in self.cached_fields:
setattr(self, field, d[field])
def read_info_from_repo(self):
if self.is_builtin or self.have_info_from_repo:
return
def read_from_repo():
with self.lock:
if self.have_info_from_repo:
return
self.do_read_info_from_repo()
return self.to_dict()
try:
d = cache.cached_data_for_file('extensions-git', self.name, os.path.join(self.path, ".git"), read_from_repo)
self.from_dict(d)
except FileNotFoundError:
pass
self.status = 'unknown' if self.status == '' else self.status
def do_read_info_from_repo(self):
repo = None repo = None
try: try:
if os.path.exists(os.path.join(path, ".git")): if os.path.exists(os.path.join(self.path, ".git")):
repo = git.Repo(path) repo = Repo(self.path)
except Exception: except Exception:
print(f"Error reading github repository info from {path}:", file=sys.stderr) errors.report(f"Error reading github repository info from {self.path}", exc_info=True)
print(traceback.format_exc(), file=sys.stderr)
if repo is None or repo.bare: if repo is None or repo.bare:
self.remote = None self.remote = None
else: else:
try: try:
self.remote = next(repo.remote().urls, None) self.remote = next(repo.remote().urls, None)
self.status = 'unknown' commit = repo.head.commit
self.commit_date = commit.committed_date
if repo.active_branch:
self.branch = repo.active_branch.name
self.commit_hash = commit.hexsha
self.version = self.commit_hash[:8]
except Exception: except Exception:
errors.report(f"Failed reading extension data from Git repository ({self.name})", exc_info=True)
self.remote = None self.remote = None
def list_files(self, subdir, extension): self.have_info_from_repo = True
from modules import scripts
def list_files(self, subdir, extension):
dirpath = os.path.join(self.path, subdir) dirpath = os.path.join(self.path, subdir)
if not os.path.isdir(dirpath): if not os.path.isdir(dirpath):
return [] return []
@@ -57,22 +103,34 @@ class Extension:
return res return res
def check_updates(self): def check_updates(self):
repo = git.Repo(self.path) repo = Repo(self.path)
for fetch in repo.remote().fetch("--dry-run"): for fetch in repo.remote().fetch(dry_run=True):
if fetch.flags != fetch.HEAD_UPTODATE: if fetch.flags != fetch.HEAD_UPTODATE:
self.can_update = True self.can_update = True
self.status = "behind" self.status = "new commits"
return return
try:
origin = repo.rev_parse('origin')
if repo.head.commit != origin:
self.can_update = True
self.status = "behind HEAD"
return
except Exception:
self.can_update = False
self.status = "unknown (remote error)"
return
self.can_update = False self.can_update = False
self.status = "latest" self.status = "latest"
def fetch_and_reset_hard(self): def fetch_and_reset_hard(self, commit='origin'):
repo = git.Repo(self.path) repo = Repo(self.path)
# Fix: `error: Your local changes to the following files would be overwritten by merge`, # Fix: `error: Your local changes to the following files would be overwritten by merge`,
# because WSL2 Docker set 755 file permissions instead of 644, this results to the error. # because WSL2 Docker set 755 file permissions instead of 644, this results to the error.
repo.git.fetch('--all') repo.git.fetch(all=True)
repo.git.reset('--hard', 'origin') repo.git.reset(commit, hard=True)
self.have_info_from_repo = False
def list_extensions(): def list_extensions():
@@ -81,7 +139,16 @@ def list_extensions():
if not os.path.isdir(extensions_dir): if not os.path.isdir(extensions_dir):
return return
paths = [] if shared.cmd_opts.disable_all_extensions:
print("*** \"--disable-all-extensions\" arg was used, will not load any extensions ***")
elif shared.opts.disable_all_extensions == "all":
print("*** \"Disable all extensions\" option was set, will not load any extensions ***")
elif shared.cmd_opts.disable_extra_extensions:
print("*** \"--disable-extra-extensions\" arg was used, will only load built-in extensions ***")
elif shared.opts.disable_all_extensions == "extra":
print("*** \"Disable all extensions\" option was set, will only load built-in extensions ***")
extension_paths = []
for dirname in [extensions_dir, extensions_builtin_dir]: for dirname in [extensions_dir, extensions_builtin_dir]:
if not os.path.isdir(dirname): if not os.path.isdir(dirname):
return return
@@ -91,9 +158,8 @@ def list_extensions():
if not os.path.isdir(path): if not os.path.isdir(path):
continue continue
paths.append((extension_dirname, path, dirname == extensions_builtin_dir)) extension_paths.append((extension_dirname, path, dirname == extensions_builtin_dir))
for dirname, path, is_builtin in paths: for dirname, path, is_builtin in extension_paths:
extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin) extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin)
extensions.append(extension) extensions.append(extension)
+92 -15
View File
@@ -1,22 +1,48 @@
import json
import os
import re import re
import logging
from collections import defaultdict from collections import defaultdict
from modules import errors from modules import errors
extra_network_registry = {} extra_network_registry = {}
extra_network_aliases = {}
def initialize(): def initialize():
extra_network_registry.clear() extra_network_registry.clear()
extra_network_aliases.clear()
def register_extra_network(extra_network): def register_extra_network(extra_network):
extra_network_registry[extra_network.name] = extra_network extra_network_registry[extra_network.name] = extra_network
def register_extra_network_alias(extra_network, alias):
extra_network_aliases[alias] = extra_network
def register_default_extra_networks():
from modules.extra_networks_hypernet import ExtraNetworkHypernet
register_extra_network(ExtraNetworkHypernet())
class ExtraNetworkParams: class ExtraNetworkParams:
def __init__(self, items=None): def __init__(self, items=None):
self.items = items or [] self.items = items or []
self.positional = []
self.named = {}
for item in self.items:
parts = item.split('=', 2) if isinstance(item, str) else [item]
if len(parts) == 2:
self.named[parts[0]] = parts[1]
else:
self.positional.append(item)
def __eq__(self, other):
return self.items == other.items
class ExtraNetwork: class ExtraNetwork:
@@ -61,24 +87,58 @@ class ExtraNetwork:
raise NotImplementedError raise NotImplementedError
def lookup_extra_networks(extra_network_data):
"""returns a dict mapping ExtraNetwork objects to lists of arguments for those extra networks.
Example input:
{
'lora': [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D58310>],
'lyco': [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D58F70>],
'hypernet': [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D5A800>]
}
Example output:
{
<extra_networks_lora.ExtraNetworkLora object at 0x0000020581BEECE0>: [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D58310>, <modules.extra_networks.ExtraNetworkParams object at 0x0000020690D58F70>],
<modules.extra_networks_hypernet.ExtraNetworkHypernet object at 0x0000020581BEEE60>: [<modules.extra_networks.ExtraNetworkParams object at 0x0000020690D5A800>]
}
"""
res = {}
for extra_network_name, extra_network_args in list(extra_network_data.items()):
extra_network = extra_network_registry.get(extra_network_name, None)
alias = extra_network_aliases.get(extra_network_name, None)
if alias is not None and extra_network is None:
extra_network = alias
if extra_network is None:
logging.info(f"Skipping unknown extra network: {extra_network_name}")
continue
res.setdefault(extra_network, []).extend(extra_network_args)
return res
def activate(p, extra_network_data): def activate(p, extra_network_data):
"""call activate for extra networks in extra_network_data in specified order, then call """call activate for extra networks in extra_network_data in specified order, then call
activate for all remaining registered networks with an empty argument list""" activate for all remaining registered networks with an empty argument list"""
for extra_network_name, extra_network_args in extra_network_data.items(): activated = []
extra_network = extra_network_registry.get(extra_network_name, None)
if extra_network is None: for extra_network, extra_network_args in lookup_extra_networks(extra_network_data).items():
print(f"Skipping unknown extra network: {extra_network_name}")
continue
try: try:
extra_network.activate(p, extra_network_args) extra_network.activate(p, extra_network_args)
activated.append(extra_network)
except Exception as e: except Exception as e:
errors.display(e, f"activating extra network {extra_network_name} with arguments {extra_network_args}") errors.display(e, f"activating extra network {extra_network.name} with arguments {extra_network_args}")
for extra_network_name, extra_network in extra_network_registry.items(): for extra_network_name, extra_network in extra_network_registry.items():
args = extra_network_data.get(extra_network_name, None) if extra_network in activated:
if args is not None:
continue continue
try: try:
@@ -86,24 +146,24 @@ def activate(p, extra_network_data):
except Exception as e: except Exception as e:
errors.display(e, f"activating extra network {extra_network_name}") errors.display(e, f"activating extra network {extra_network_name}")
if p.scripts is not None:
p.scripts.after_extra_networks_activate(p, batch_number=p.iteration, prompts=p.prompts, seeds=p.seeds, subseeds=p.subseeds, extra_network_data=extra_network_data)
def deactivate(p, extra_network_data): def deactivate(p, extra_network_data):
"""call deactivate for extra networks in extra_network_data in specified order, then call """call deactivate for extra networks in extra_network_data in specified order, then call
deactivate for all remaining registered networks""" deactivate for all remaining registered networks"""
for extra_network_name, extra_network_args in extra_network_data.items(): data = lookup_extra_networks(extra_network_data)
extra_network = extra_network_registry.get(extra_network_name, None)
if extra_network is None:
continue
for extra_network in data:
try: try:
extra_network.deactivate(p) extra_network.deactivate(p)
except Exception as e: except Exception as e:
errors.display(e, f"deactivating extra network {extra_network_name}") errors.display(e, f"deactivating extra network {extra_network.name}")
for extra_network_name, extra_network in extra_network_registry.items(): for extra_network_name, extra_network in extra_network_registry.items():
args = extra_network_data.get(extra_network_name, None) if extra_network in data:
if args is not None:
continue continue
try: try:
@@ -145,3 +205,20 @@ def parse_prompts(prompts):
return res, extra_data return res, extra_data
def get_user_metadata(filename):
if filename is None:
return {}
basename, ext = os.path.splitext(filename)
metadata_filename = basename + '.json'
metadata = {}
try:
if os.path.isfile(metadata_filename):
with open(metadata_filename, "r", encoding="utf8") as file:
metadata = json.load(file)
except Exception as e:
errors.display(e, f"reading extra network user metadata from {metadata_filename}")
return metadata
+9 -2
View File
@@ -1,4 +1,4 @@
from modules import extra_networks from modules import extra_networks, shared
from modules.hypernetworks import hypernetwork from modules.hypernetworks import hypernetwork
@@ -7,10 +7,17 @@ class ExtraNetworkHypernet(extra_networks.ExtraNetwork):
super().__init__('hypernet') super().__init__('hypernet')
def activate(self, p, params_list): def activate(self, p, params_list):
additional = shared.opts.sd_hypernetwork
if additional != "None" and additional in shared.hypernetworks and not any(x for x in params_list if x.items[0] == additional):
hypernet_prompt_text = f"<hypernet:{additional}:{shared.opts.extra_networks_default_multiplier}>"
p.all_prompts = [f"{prompt}{hypernet_prompt_text}" for prompt in p.all_prompts]
params_list.append(extra_networks.ExtraNetworkParams(items=[additional, shared.opts.extra_networks_default_multiplier]))
names = [] names = []
multipliers = [] multipliers = []
for params in params_list: for params in params_list:
assert len(params.items) > 0 assert params.items
names.append(params.items[0]) names.append(params.items[0])
multipliers.append(float(params.items[1]) if len(params.items) > 1 else 1.0) multipliers.append(float(params.items[1]) if len(params.items) > 1 else 1.0)
+91 -12
View File
@@ -1,12 +1,13 @@
import os import os
import re import re
import shutil import shutil
import json
import torch import torch
import tqdm import tqdm
from modules import shared, images, sd_models, sd_vae from modules import shared, images, sd_models, sd_vae, sd_models_config, errors
from modules.ui_common import plaintext_to_html from modules.ui_common import plaintext_to_html
import gradio as gr import gradio as gr
import safetensors.torch import safetensors.torch
@@ -37,7 +38,7 @@ def run_pnginfo(image):
def create_config(ckpt_result, config_source, a, b, c): def create_config(ckpt_result, config_source, a, b, c):
def config(x): def config(x):
res = sd_models.find_checkpoint_config(x) if x else None res = sd_models_config.find_checkpoint_config_near_filename(x) if x else None
return res if res != shared.sd_default_config else None return res if res != shared.sd_default_config else None
if config_source == 0: if config_source == 0:
@@ -71,9 +72,21 @@ def to_half(tensor, enable):
return tensor return tensor
def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_model_name, interp_method, multiplier, save_as_half, custom_name, checkpoint_format, config_source, bake_in_vae, discard_weights): def read_metadata(primary_model_name, secondary_model_name, tertiary_model_name):
shared.state.begin() metadata = {}
shared.state.job = 'model-merge'
for checkpoint_name in [primary_model_name, secondary_model_name, tertiary_model_name]:
checkpoint_info = sd_models.checkpoints_list.get(checkpoint_name, None)
if checkpoint_info is None:
continue
metadata.update(checkpoint_info.metadata)
return json.dumps(metadata, indent=4, ensure_ascii=False)
def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_model_name, interp_method, multiplier, save_as_half, custom_name, checkpoint_format, config_source, bake_in_vae, discard_weights, save_metadata, add_merge_recipe, copy_metadata_fields, metadata_json):
shared.state.begin(job="model-merge")
def fail(message): def fail(message):
shared.state.textinfo = message shared.state.textinfo = message
@@ -132,16 +145,17 @@ def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_
tertiary_model_info = sd_models.checkpoints_list[tertiary_model_name] if theta_func1 else None tertiary_model_info = sd_models.checkpoints_list[tertiary_model_name] if theta_func1 else None
result_is_inpainting_model = False result_is_inpainting_model = False
result_is_instruct_pix2pix_model = False
if theta_func2: if theta_func2:
shared.state.textinfo = f"Loading B" shared.state.textinfo = "Loading B"
print(f"Loading {secondary_model_info.filename}...") print(f"Loading {secondary_model_info.filename}...")
theta_1 = sd_models.read_state_dict(secondary_model_info.filename, map_location='cpu') theta_1 = sd_models.read_state_dict(secondary_model_info.filename, map_location='cpu')
else: else:
theta_1 = None theta_1 = None
if theta_func1: if theta_func1:
shared.state.textinfo = f"Loading C" shared.state.textinfo = "Loading C"
print(f"Loading {tertiary_model_info.filename}...") print(f"Loading {tertiary_model_info.filename}...")
theta_2 = sd_models.read_state_dict(tertiary_model_info.filename, map_location='cpu') theta_2 = sd_models.read_state_dict(tertiary_model_info.filename, map_location='cpu')
@@ -185,11 +199,16 @@ def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_
if a.shape != b.shape and a.shape[0:1] + a.shape[2:] == b.shape[0:1] + b.shape[2:]: if a.shape != b.shape and a.shape[0:1] + a.shape[2:] == b.shape[0:1] + b.shape[2:]:
if a.shape[1] == 4 and b.shape[1] == 9: if a.shape[1] == 4 and b.shape[1] == 9:
raise RuntimeError("When merging inpainting model with a normal one, A must be the inpainting model.") raise RuntimeError("When merging inpainting model with a normal one, A must be the inpainting model.")
if a.shape[1] == 4 and b.shape[1] == 8:
raise RuntimeError("When merging instruct-pix2pix model with a normal one, A must be the instruct-pix2pix model.")
assert a.shape[1] == 9 and b.shape[1] == 4, f"Bad dimensions for merged layer {key}: A={a.shape}, B={b.shape}" if a.shape[1] == 8 and b.shape[1] == 4:#If we have an Instruct-Pix2Pix model...
theta_0[key][:, 0:4, :, :] = theta_func2(a[:, 0:4, :, :], b, multiplier)#Merge only the vectors the models have in common. Otherwise we get an error due to dimension mismatch.
theta_0[key][:, 0:4, :, :] = theta_func2(a[:, 0:4, :, :], b, multiplier) result_is_instruct_pix2pix_model = True
result_is_inpainting_model = True else:
assert a.shape[1] == 9 and b.shape[1] == 4, f"Bad dimensions for merged layer {key}: A={a.shape}, B={b.shape}"
theta_0[key][:, 0:4, :, :] = theta_func2(a[:, 0:4, :, :], b, multiplier)
result_is_inpainting_model = True
else: else:
theta_0[key] = theta_func2(a, b, multiplier) theta_0[key] = theta_func2(a, b, multiplier)
@@ -226,6 +245,7 @@ def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_
filename = filename_generator() if custom_name == '' else custom_name filename = filename_generator() if custom_name == '' else custom_name
filename += ".inpainting" if result_is_inpainting_model else "" filename += ".inpainting" if result_is_inpainting_model else ""
filename += ".instruct-pix2pix" if result_is_instruct_pix2pix_model else ""
filename += "." + checkpoint_format filename += "." + checkpoint_format
output_modelname = os.path.join(ckpt_dir, filename) output_modelname = os.path.join(ckpt_dir, filename)
@@ -234,13 +254,72 @@ def run_modelmerger(id_task, primary_model_name, secondary_model_name, tertiary_
shared.state.textinfo = "Saving" shared.state.textinfo = "Saving"
print(f"Saving to {output_modelname}...") print(f"Saving to {output_modelname}...")
metadata = {}
if save_metadata and copy_metadata_fields:
if primary_model_info:
metadata.update(primary_model_info.metadata)
if secondary_model_info:
metadata.update(secondary_model_info.metadata)
if tertiary_model_info:
metadata.update(tertiary_model_info.metadata)
if save_metadata:
try:
metadata.update(json.loads(metadata_json))
except Exception as e:
errors.display(e, "readin metadata from json")
metadata["format"] = "pt"
if save_metadata and add_merge_recipe:
merge_recipe = {
"type": "webui", # indicate this model was merged with webui's built-in merger
"primary_model_hash": primary_model_info.sha256,
"secondary_model_hash": secondary_model_info.sha256 if secondary_model_info else None,
"tertiary_model_hash": tertiary_model_info.sha256 if tertiary_model_info else None,
"interp_method": interp_method,
"multiplier": multiplier,
"save_as_half": save_as_half,
"custom_name": custom_name,
"config_source": config_source,
"bake_in_vae": bake_in_vae,
"discard_weights": discard_weights,
"is_inpainting": result_is_inpainting_model,
"is_instruct_pix2pix": result_is_instruct_pix2pix_model
}
sd_merge_models = {}
def add_model_metadata(checkpoint_info):
checkpoint_info.calculate_shorthash()
sd_merge_models[checkpoint_info.sha256] = {
"name": checkpoint_info.name,
"legacy_hash": checkpoint_info.hash,
"sd_merge_recipe": checkpoint_info.metadata.get("sd_merge_recipe", None)
}
sd_merge_models.update(checkpoint_info.metadata.get("sd_merge_models", {}))
add_model_metadata(primary_model_info)
if secondary_model_info:
add_model_metadata(secondary_model_info)
if tertiary_model_info:
add_model_metadata(tertiary_model_info)
metadata["sd_merge_recipe"] = json.dumps(merge_recipe)
metadata["sd_merge_models"] = json.dumps(sd_merge_models)
_, extension = os.path.splitext(output_modelname) _, extension = os.path.splitext(output_modelname)
if extension.lower() == ".safetensors": if extension.lower() == ".safetensors":
safetensors.torch.save_file(theta_0, output_modelname, metadata={"format": "pt"}) safetensors.torch.save_file(theta_0, output_modelname, metadata=metadata if len(metadata)>0 else None)
else: else:
torch.save(theta_0, output_modelname) torch.save(theta_0, output_modelname)
sd_models.list_models() sd_models.list_models()
created_model = next((ckpt for ckpt in sd_models.checkpoints_list.values() if ckpt.name == filename), None)
if created_model:
created_model.calculate_shorthash()
create_config(output_modelname, config_source, primary_model_info, secondary_model_info, tertiary_model_info) create_config(output_modelname, config_source, primary_model_info, secondary_model_info, tertiary_model_info)

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