From 2b8c199e561089b8f37fc7348cf2987bfae2c25a Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 2 May 2023 10:52:58 +0530 Subject: [PATCH 01/61] Create PRIVACY.md --- PRIVACY.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 PRIVACY.md diff --git a/PRIVACY.md b/PRIVACY.md new file mode 100644 index 00000000..e33e2180 --- /dev/null +++ b/PRIVACY.md @@ -0,0 +1,8 @@ +// placeholder until a more formal and legal-sounding privacy policy document is written. but the information below is true. + +This is a summary of how Easy Diffusion uses your data or tracks you: +* The short answer is - Easy Diffusion does *not* use your data, and does not track you. +* Easy Diffusion does not send your prompts or usage or analytics to anyone. There is no tracking. We don't even know how many people use Easy Diffusion, let alone their prompts. +* Easy Diffusion fetches updates to the code whenever it starts up. It does this by contacting GitHub directly, via SSL (secure connection). Only your computer and GitHub and [this repository](https://github.com/cmdr2/stable-diffusion-ui) are involved, and no third party is involved. Some countries intercepts SSL connections, that's not something we can do much about. +* Easy Diffusion fetches the models from huggingface.co and github.com, if they don't exist on your PC. For e.g. if the safety checker (NSFW) model doesn't exist, it'll try to download it. +* Occasionally, antivirus software are known to *incorrectly* flag and delete some model files, which will result in Easy Diffusion re-downloading `pytorch_model.bin`. This *incorrect deletion* affects other Stable Diffusion UIs as well, like Invoke AI - https://itch.io/post/7509488 From 35d36f9eb300b0da640311805141b186e19b8ee7 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 2 May 2023 10:53:17 +0530 Subject: [PATCH 02/61] Update PRIVACY.md --- PRIVACY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVACY.md b/PRIVACY.md index e33e2180..9d813724 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -1,7 +1,7 @@ // placeholder until a more formal and legal-sounding privacy policy document is written. but the information below is true. This is a summary of how Easy Diffusion uses your data or tracks you: -* The short answer is - Easy Diffusion does *not* use your data, and does not track you. +* The short answer is - Easy Diffusion does *not* use your data, and does *not* track you. * Easy Diffusion does not send your prompts or usage or analytics to anyone. There is no tracking. We don't even know how many people use Easy Diffusion, let alone their prompts. * Easy Diffusion fetches updates to the code whenever it starts up. It does this by contacting GitHub directly, via SSL (secure connection). Only your computer and GitHub and [this repository](https://github.com/cmdr2/stable-diffusion-ui) are involved, and no third party is involved. Some countries intercepts SSL connections, that's not something we can do much about. * Easy Diffusion fetches the models from huggingface.co and github.com, if they don't exist on your PC. For e.g. if the safety checker (NSFW) model doesn't exist, it'll try to download it. From c1e5c8dc86c7d3c921d4b6d87a3e18c34488db63 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 2 May 2023 11:00:57 +0530 Subject: [PATCH 03/61] Update PRIVACY.md --- PRIVACY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVACY.md b/PRIVACY.md index 9d813724..bda8a2a8 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -3,6 +3,6 @@ This is a summary of how Easy Diffusion uses your data or tracks you: * The short answer is - Easy Diffusion does *not* use your data, and does *not* track you. * Easy Diffusion does not send your prompts or usage or analytics to anyone. There is no tracking. We don't even know how many people use Easy Diffusion, let alone their prompts. -* Easy Diffusion fetches updates to the code whenever it starts up. It does this by contacting GitHub directly, via SSL (secure connection). Only your computer and GitHub and [this repository](https://github.com/cmdr2/stable-diffusion-ui) are involved, and no third party is involved. Some countries intercepts SSL connections, that's not something we can do much about. +* Easy Diffusion fetches updates to the code whenever it starts up. It does this by contacting GitHub directly, via SSL (secure connection). Only your computer and GitHub and [this repository](https://github.com/cmdr2/stable-diffusion-ui) are involved, and no third party is involved. Some countries intercepts SSL connections, that's not something we can do much about. GitHub does *not* share statistics (even with me) about how many people fetched code updates. * Easy Diffusion fetches the models from huggingface.co and github.com, if they don't exist on your PC. For e.g. if the safety checker (NSFW) model doesn't exist, it'll try to download it. * Occasionally, antivirus software are known to *incorrectly* flag and delete some model files, which will result in Easy Diffusion re-downloading `pytorch_model.bin`. This *incorrect deletion* affects other Stable Diffusion UIs as well, like Invoke AI - https://itch.io/post/7509488 From 49599dc3baef01f32d89dae809abaac2f17cb15e Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 2 May 2023 11:03:09 +0530 Subject: [PATCH 04/61] Update PRIVACY.md --- PRIVACY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVACY.md b/PRIVACY.md index bda8a2a8..ce1b4e1f 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -1,6 +1,6 @@ // placeholder until a more formal and legal-sounding privacy policy document is written. but the information below is true. -This is a summary of how Easy Diffusion uses your data or tracks you: +This is a summary of whether Easy Diffusion uses your data or tracks you: * The short answer is - Easy Diffusion does *not* use your data, and does *not* track you. * Easy Diffusion does not send your prompts or usage or analytics to anyone. There is no tracking. We don't even know how many people use Easy Diffusion, let alone their prompts. * Easy Diffusion fetches updates to the code whenever it starts up. It does this by contacting GitHub directly, via SSL (secure connection). Only your computer and GitHub and [this repository](https://github.com/cmdr2/stable-diffusion-ui) are involved, and no third party is involved. Some countries intercepts SSL connections, that's not something we can do much about. GitHub does *not* share statistics (even with me) about how many people fetched code updates. From 5a9e74cef765afe80e68ffc3800d91dac8c385c5 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 2 May 2023 11:05:58 +0530 Subject: [PATCH 05/61] Update PRIVACY.md --- PRIVACY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/PRIVACY.md b/PRIVACY.md index ce1b4e1f..6c997997 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -5,4 +5,5 @@ This is a summary of whether Easy Diffusion uses your data or tracks you: * Easy Diffusion does not send your prompts or usage or analytics to anyone. There is no tracking. We don't even know how many people use Easy Diffusion, let alone their prompts. * Easy Diffusion fetches updates to the code whenever it starts up. It does this by contacting GitHub directly, via SSL (secure connection). Only your computer and GitHub and [this repository](https://github.com/cmdr2/stable-diffusion-ui) are involved, and no third party is involved. Some countries intercepts SSL connections, that's not something we can do much about. GitHub does *not* share statistics (even with me) about how many people fetched code updates. * Easy Diffusion fetches the models from huggingface.co and github.com, if they don't exist on your PC. For e.g. if the safety checker (NSFW) model doesn't exist, it'll try to download it. +* Easy Diffusion fetches code packages from pypi.org, which is the standard hosting service for all Python projects. That's where packages installed via `pip install` are stored. * Occasionally, antivirus software are known to *incorrectly* flag and delete some model files, which will result in Easy Diffusion re-downloading `pytorch_model.bin`. This *incorrect deletion* affects other Stable Diffusion UIs as well, like Invoke AI - https://itch.io/post/7509488 From 843d22d0d42b5f5c64789b5016bad7b41310e37d Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 3 May 2023 14:53:18 +0530 Subject: [PATCH 06/61] Update README.md --- README.md | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 3cb0bf8e..54d66221 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,11 @@ Click the download button for your operating system:

**Hardware requirements:** -- **Windows:** NVIDIA graphics card, or run on your CPU -- **Linux:** NVIDIA or AMD graphics card, or run on your CPU -- **Mac:** M1 or M2, or run on your CPU +- **Windows:** NVIDIA graphics card, or run on your CPU. +- **Linux:** NVIDIA or AMD graphics card, or run on your CPU. +- **Mac:** M1 or M2, or run on your CPU. +- Minimum 8 GB of system RAM. +- Atleast 25 GB of space on the hard disk. The installer will take care of whatever is needed. If you face any problems, you can join the friendly [Discord community](https://discord.com/invite/u9yhsFmEkB) and ask for assistance. @@ -113,14 +115,6 @@ Useful for judging (and stopping) an image quickly, without waiting for it to fi ![Screenshot of task queue](https://user-images.githubusercontent.com/844287/217043984-0b35f73b-1318-47cb-9eed-a2a91b430490.png) - -# System Requirements -1. Windows 10/11, or Linux. Experimental support for Mac is coming soon. -2. An NVIDIA graphics card, preferably with 4GB or more of VRAM. If you don't have a compatible graphics card, it'll automatically run in the slower "CPU Mode". -3. Minimum 8 GB of RAM and 25GB of disk space. - -You don't need to install or struggle with Python, Anaconda, Docker etc. The installer will take care of whatever is needed. - ---- # How to use? From 3f9ec378a0094d7f3d25114a7d5c73a36206fdb1 Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Thu, 4 May 2023 09:16:19 -0700 Subject: [PATCH 07/61] Fix restoration of inactive image modifiers --- ui/media/js/image-modifiers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/media/js/image-modifiers.js b/ui/media/js/image-modifiers.js index fd4ecaf1..69f31ab1 100644 --- a/ui/media/js/image-modifiers.js +++ b/ui/media/js/image-modifiers.js @@ -246,7 +246,7 @@ function refreshInactiveTags(inactiveTags) { overlays.forEach((i) => { let modifierName = i.parentElement.getElementsByClassName("modifier-card-label")[0].getElementsByTagName("p")[0] .dataset.fullName - if (inactiveTags?.find((element) => element === modifierName) !== undefined) { + if (inactiveTags?.find((element) => trimModifiers(element) === modifierName) !== undefined) { i.parentElement.classList.add("modifier-toggle-inactive") } }) From fec21408962b451c693cae271c57289ca350538f Mon Sep 17 00:00:00 2001 From: Olivia Godone-Maresca Date: Thu, 4 May 2023 19:36:10 -0400 Subject: [PATCH 08/61] Allow grabbing the image to scroll zoomed in images --- ui/media/css/image-modal.css | 8 +++++ ui/media/js/image-modal.js | 63 ++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/ui/media/css/image-modal.css b/ui/media/css/image-modal.css index 1001807c..64096003 100644 --- a/ui/media/css/image-modal.css +++ b/ui/media/css/image-modal.css @@ -70,6 +70,14 @@ max-height: calc(100vh - (var(--popup-padding) * 2) - 4px); } +#viewFullSizeImgModal img:not(.natural-zoom) { + cursor: grab; +} + +#viewFullSizeImgModal .grabbing img:not(.natural-zoom) { + cursor: grabbing; +} + #viewFullSizeImgModal .content > div::-webkit-scrollbar-track, #viewFullSizeImgModal .content > div::-webkit-scrollbar-corner { background: rgba(0, 0, 0, .5) } diff --git a/ui/media/js/image-modal.js b/ui/media/js/image-modal.js index 3a97c4d8..28c1eaf2 100644 --- a/ui/media/js/image-modal.js +++ b/ui/media/js/image-modal.js @@ -63,15 +63,73 @@ const imageModal = (function() { setZoomLevel(imageContainer.querySelector("img")?.classList?.contains("natural-zoom")) ) - const state = { + const initialState = () => ({ previous: undefined, next: undefined, + + start: { + x: 0, + y: 0, + }, + + scroll: { + x: 0, + y: 0, + }, + }) + + const state = initialState() + + // Allow grabbing the image to scroll + const stopGrabbing = (e) => { + if(imageContainer.classList.contains("grabbing")) { + imageContainer.classList.remove("grabbing") + e?.preventDefault() + console.log(`stopGrabbing()`, e) + } + } + + const addImageGrabbing = (image) => { + image?.addEventListener('mousedown', (e) => { + if (!image.classList.contains("natural-zoom")) { + e.stopPropagation() + e.stopImmediatePropagation() + e.preventDefault() + + imageContainer.classList.add("grabbing") + state.start.x = e.pageX - imageContainer.offsetLeft + state.scroll.x = imageContainer.scrollLeft + state.start.y = e.pageY - imageContainer.offsetTop + state.scroll.y = imageContainer.scrollTop + } + }) + + image?.addEventListener('mouseup', stopGrabbing) + image?.addEventListener('mouseleave', stopGrabbing) + image?.addEventListener('mousemove', (e) => { + if(imageContainer.classList.contains("grabbing")) { + e.stopPropagation() + e.stopImmediatePropagation() + e.preventDefault() + + // Might need to increase this multiplier based on the image size to window size ratio + // The default 1:1 is pretty slow + const multiplier = 1.0 + + const deltaX = e.pageX - imageContainer.offsetLeft - state.start.x + imageContainer.scrollLeft = state.scroll.x - (deltaX * multiplier) + const deltaY = e.pageY - imageContainer.offsetTop - state.start.y + imageContainer.scrollTop = state.scroll.y - (deltaY * multiplier) + } + }) } const clear = () => { imageContainer.innerHTML = "" - Object.keys(state).forEach((key) => delete state[key]) + Object.entries(initialState()).forEach(([key, value]) => state[key] = value) + + stopGrabbing() } const close = () => { @@ -95,6 +153,7 @@ const imageModal = (function() { const src = typeof options === "string" ? options : options.src const imgElem = createElement("img", { src }, "natural-zoom") + addImageGrabbing(imgElem) imageContainer.appendChild(imgElem) modalElem.classList.add("active") document.body.style.overflow = "hidden" From 2d1be6186e7037b146fe8062145e8593990db719 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 10 May 2023 20:19:17 +0530 Subject: [PATCH 09/61] sdkit 1.0.88 - Fix LoRA in low VRAM mode --- scripts/check_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 031f7d66..3fcfce14 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -18,7 +18,7 @@ os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0"), "torchvision": ("0.12.0", "0.14.1", "0.15.1"), - "sdkit": "1.0.87", + "sdkit": "1.0.88", "stable-diffusion-sdkit": "2.1.4", "rich": "12.6.0", "uvicorn": "0.19.0", From 08f44472f8bd0052fcb04cb443180b13cc961a6e Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 10 May 2023 20:20:59 +0530 Subject: [PATCH 10/61] changelog --- CHANGES.md | 1 + ui/index.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 9fe2cff0..570d0c72 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed. ### Detailed changelog +* 2.5.36 - 10 May 2023 - (beta-only) Bug fix for "meta" error when using a LoRA in 'low' VRAM usage mode. * 2.5.35 - 3 May 2023 - (beta-only) First round of VRAM Optimizations for the "Test Diffusers" version. This change significantly reduces the amount of VRAM used by the diffusers version during image generation. The VRAM usage is still not equal to the "non-diffusers" version, but more optimizations are coming soon. * 2.5.34 - 22 Apr 2023 - Don't start the browser in an incognito new profile (on Windows). Thanks @JeLuf. * 2.5.33 - 21 Apr 2023 - Install PyTorch 2.0 on new installations (on Windows and Linux). diff --git a/ui/index.html b/ui/index.html index be522689..d196b99d 100644 --- a/ui/index.html +++ b/ui/index.html @@ -30,7 +30,7 @@

Easy Diffusion - v2.5.35 + v2.5.36

From 566a83ce3f14af592903ef0417575229e3b5277a Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Thu, 11 May 2023 14:49:15 +0530 Subject: [PATCH 11/61] sdkit 1.0.89 - use half precision in test diffusers for low vram usage mode' --- scripts/check_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 3fcfce14..b9797515 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -18,7 +18,7 @@ os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0"), "torchvision": ("0.12.0", "0.14.1", "0.15.1"), - "sdkit": "1.0.88", + "sdkit": "1.0.89", "stable-diffusion-sdkit": "2.1.4", "rich": "12.6.0", "uvicorn": "0.19.0", From 4bca739b3d64f3a5827475bd50c52a9025d6e31d Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Thu, 11 May 2023 14:52:30 +0530 Subject: [PATCH 12/61] changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 570d0c72..d6d93bd7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed. ### Detailed changelog +* 2.5.36 - 11 May 2023 - (beta-only) Another VRAM optimization for "low" VRAM usage mode. * 2.5.36 - 10 May 2023 - (beta-only) Bug fix for "meta" error when using a LoRA in 'low' VRAM usage mode. * 2.5.35 - 3 May 2023 - (beta-only) First round of VRAM Optimizations for the "Test Diffusers" version. This change significantly reduces the amount of VRAM used by the diffusers version during image generation. The VRAM usage is still not equal to the "non-diffusers" version, but more optimizations are coming soon. * 2.5.34 - 22 Apr 2023 - Don't start the browser in an incognito new profile (on Windows). Thanks @JeLuf. From add05228bdb34278e0393cfb47ccbcd79392b9fc Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Thu, 11 May 2023 16:30:06 +0530 Subject: [PATCH 13/61] sdkit 1.0.91 - use slice size 1 for low vram usage mode, to reduce VRAM usage --- scripts/check_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index b9797515..8da111e0 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -18,7 +18,7 @@ os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0"), "torchvision": ("0.12.0", "0.14.1", "0.15.1"), - "sdkit": "1.0.89", + "sdkit": "1.0.91", "stable-diffusion-sdkit": "2.1.4", "rich": "12.6.0", "uvicorn": "0.19.0", From 1cba62af242c9ebfd1109b18bc0d8fafeda463a2 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Thu, 11 May 2023 16:30:32 +0530 Subject: [PATCH 14/61] changelog --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index d6d93bd7..6168fcc3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,7 +21,7 @@ Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed. ### Detailed changelog -* 2.5.36 - 11 May 2023 - (beta-only) Another VRAM optimization for "low" VRAM usage mode. +* 2.5.36 - 11 May 2023 - (beta-only) More VRAM optimizations for "low" VRAM usage mode. * 2.5.36 - 10 May 2023 - (beta-only) Bug fix for "meta" error when using a LoRA in 'low' VRAM usage mode. * 2.5.35 - 3 May 2023 - (beta-only) First round of VRAM Optimizations for the "Test Diffusers" version. This change significantly reduces the amount of VRAM used by the diffusers version during image generation. The VRAM usage is still not equal to the "non-diffusers" version, but more optimizations are coming soon. * 2.5.34 - 22 Apr 2023 - Don't start the browser in an incognito new profile (on Windows). Thanks @JeLuf. From 7240c91db722b0c92803f62131f20a887276c5c7 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 12 May 2023 14:48:48 +0530 Subject: [PATCH 15/61] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 6168fcc3..f2432505 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,7 @@ Our focus continues to remain on an easy installation experience, and an easy us ### Detailed changelog * 2.5.36 - 11 May 2023 - (beta-only) More VRAM optimizations for "low" VRAM usage mode. * 2.5.36 - 10 May 2023 - (beta-only) Bug fix for "meta" error when using a LoRA in 'low' VRAM usage mode. +* 2.5.35 - 8 May 2023 - Allow dragging a zoomed-in image (after opening an image with the "expand" button). Thanks @ogmaresca. * 2.5.35 - 3 May 2023 - (beta-only) First round of VRAM Optimizations for the "Test Diffusers" version. This change significantly reduces the amount of VRAM used by the diffusers version during image generation. The VRAM usage is still not equal to the "non-diffusers" version, but more optimizations are coming soon. * 2.5.34 - 22 Apr 2023 - Don't start the browser in an incognito new profile (on Windows). Thanks @JeLuf. * 2.5.33 - 21 Apr 2023 - Install PyTorch 2.0 on new installations (on Windows and Linux). From 8142fd0701d63a35dd8782ebd0b340d4b2d93aeb Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 12 May 2023 14:50:04 +0530 Subject: [PATCH 16/61] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index f2432505..d6ac5cda 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ ### Major Changes - **Nearly twice as fast** - significantly faster speed of image generation. Code contributions are welcome to make our project even faster: https://github.com/easydiffusion/sdkit/#is-it-fast - **Mac M1/M2 support** - Experimental support for Mac M1/M2. Thanks @michaelgallacher, @JeLuf and vishae. +- **AMD support for Linux** - Experimental support for AMD GPUs on Linux. Thanks @DianaNites and @JeLuf. - **Full support for Stable Diffusion 2.1 (including CPU)** - supports loading v1.4 or v2.0 or v2.1 models seamlessly. No need to enable "Test SD2", and no need to add `sd2_` to your SD 2.0 model file names. Works on CPU as well. - **Memory optimized Stable Diffusion 2.1** - you can now use Stable Diffusion 2.1 models, with the same low VRAM optimizations that we've always had for SD 1.4. Please note, the SD 2.0 and 2.1 models require more GPU and System RAM, as compared to the SD 1.4 and 1.5 models. - **11 new samplers!** - explore the new samplers, some of which can generate great images in less than 10 inference steps! We've added the Karras and UniPC samplers. Thanks @Schorny for the UniPC samplers. From 45db4bb0367e237244ccf675c1f2b9c3522e5255 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 12 May 2023 16:49:13 +0530 Subject: [PATCH 17/61] sdkit 1.0.92 - more vram optimizations for low,balanced,high - reduces VRAM usage by 20% (especially with larger images) --- scripts/check_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 8da111e0..21392011 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -18,7 +18,7 @@ os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0"), "torchvision": ("0.12.0", "0.14.1", "0.15.1"), - "sdkit": "1.0.91", + "sdkit": "1.0.92", "stable-diffusion-sdkit": "2.1.4", "rich": "12.6.0", "uvicorn": "0.19.0", From 366bc7275981f1b4d3eb76a40d0d1faa11764419 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Mon, 15 May 2023 17:01:21 +0200 Subject: [PATCH 18/61] Add GTX1630 to list of FP32 GPUs https://discord.com/channels/1014774730907209781/1014774732018683926/1107677076233912340 --- ui/easydiffusion/device_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/easydiffusion/device_manager.py b/ui/easydiffusion/device_manager.py index 59c07ea3..5dd244b7 100644 --- a/ui/easydiffusion/device_manager.py +++ b/ui/easydiffusion/device_manager.py @@ -165,6 +165,7 @@ def needs_to_force_full_precision(context): and ( " 1660" in device_name or " 1650" in device_name + or " 1630" in device_name or " t400" in device_name or " t550" in device_name or " t600" in device_name From 7562a882f4699084c3e07a6ad69b04b513ca2ab9 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 16 May 2023 16:02:20 +0530 Subject: [PATCH 19/61] sdkit 1.0.93 - lower vram usage for balanced mode, by using attention slice of 1 --- scripts/check_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 21392011..18549217 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -18,7 +18,7 @@ os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0"), "torchvision": ("0.12.0", "0.14.1", "0.15.1"), - "sdkit": "1.0.92", + "sdkit": "1.0.93", "stable-diffusion-sdkit": "2.1.4", "rich": "12.6.0", "uvicorn": "0.19.0", From 1605c5fbccb46f66dae672bd8fb2f41e3e7989c6 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 16 May 2023 16:03:12 +0530 Subject: [PATCH 20/61] changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index d6ac5cda..3b910ae6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed. ### Detailed changelog +* 2.5.36 - 16 May 2023 - (beta-only) More VRAM optimizations for "balanced" VRAM usage mode. * 2.5.36 - 11 May 2023 - (beta-only) More VRAM optimizations for "low" VRAM usage mode. * 2.5.36 - 10 May 2023 - (beta-only) Bug fix for "meta" error when using a LoRA in 'low' VRAM usage mode. * 2.5.35 - 8 May 2023 - Allow dragging a zoomed-in image (after opening an image with the "expand" button). Thanks @ogmaresca. From 9410879b73cbac56ed23624c71fe74e9e642b985 Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Tue, 16 May 2023 17:43:14 -0700 Subject: [PATCH 21/61] Fix error when removing image Error report: https://discord.com/channels/1014774730907209781/1085803885500825600/1108150298289115187 --- ui/plugins/ui/Autoscroll.plugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/plugins/ui/Autoscroll.plugin.js b/ui/plugins/ui/Autoscroll.plugin.js index 26969365..336e8b50 100644 --- a/ui/plugins/ui/Autoscroll.plugin.js +++ b/ui/plugins/ui/Autoscroll.plugin.js @@ -23,7 +23,7 @@ img.addEventListener( "load", function() { - img.closest(".imageTaskContainer").scrollIntoView() + img?.closest(".imageTaskContainer").scrollIntoView() }, { once: true } ) From 9d408a62bfd4c895807ef1b5e154550cf93ca661 Mon Sep 17 00:00:00 2001 From: Olivia Godone-Maresca Date: Wed, 17 May 2023 21:13:06 -0400 Subject: [PATCH 22/61] Add DDPM and DEIS samplers for diffusers These new samplers will be hidden when diffusers is disabled. Also, samplers that aren't implemented in diffusers yet will be disabled when using diffusers --- README.md | 2 +- ui/index.html | 18 ++++++++++-------- ui/media/js/parameters.js | 21 +++++++++++++++------ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 3cb0bf8e..2d7fcf5a 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Just delete the `EasyDiffusion` folder to uninstall all the downloaded packages. ### Image generation - **Supports**: "*Text to Image*" and "*Image to Image*". -- **19 Samplers**: `ddim`, `plms`, `heun`, `euler`, `euler_a`, `dpm2`, `dpm2_a`, `lms`, `dpm_solver_stability`, `dpmpp_2s_a`, `dpmpp_2m`, `dpmpp_sde`, `dpm_fast`, `dpm_adaptive`, `unipc_snr`, `unipc_tu`, `unipc_tq`, `unipc_snr_2`, `unipc_tu_2`. +- **21 Samplers**: `ddim`, `plms`, `heun`, `euler`, `euler_a`, `dpm2`, `dpm2_a`, `lms`, `dpm_solver_stability`, `dpmpp_2s_a`, `dpmpp_2m`, `dpmpp_sde`, `dpm_fast`, `dpm_adaptive`, `ddpm`, `deis`, `unipc_snr`, `unipc_tu`, `unipc_tq`, `unipc_snr_2`, `unipc_tu_2`. - **In-Painting**: Specify areas of your image to paint into. - **Simple Drawing Tool**: Draw basic images to guide the AI, without needing an external drawing program. - **Face Correction (GFPGAN)** diff --git a/ui/index.html b/ui/index.html index d196b99d..53632610 100644 --- a/ui/index.html +++ b/ui/index.html @@ -154,16 +154,18 @@ - + - - - - - - + + + + + + + + - + Click to learn more about samplers diff --git a/ui/media/js/parameters.js b/ui/media/js/parameters.js index 75abecd7..8c38f2f5 100644 --- a/ui/media/js/parameters.js +++ b/ui/media/js/parameters.js @@ -388,15 +388,24 @@ async function getAppConfig() { if (config.net && config.net.listen_port !== undefined) { listenPortField.value = config.net.listen_port } - if (config.test_diffusers === undefined || config.update_branch === "main") { - testDiffusers.checked = false + + const testDiffusersEnabled = config.test_diffusers && config.update_branch !== "main" + testDiffusers.checked = testDiffusersEnabled + + if (!testDiffusersEnabled) { document.querySelector("#lora_model_container").style.display = "none" document.querySelector("#lora_alpha_container").style.display = "none" + + document.querySelectorAll("#sampler_name option.diffusers-only").forEach(option => { + option.style.display = "none" + }) } else { - testDiffusers.checked = config.test_diffusers && config.update_branch !== "main" - document.querySelector("#lora_model_container").style.display = testDiffusers.checked ? "" : "none" - document.querySelector("#lora_alpha_container").style.display = - testDiffusers.checked && loraModelField.value !== "" ? "" : "none" + document.querySelector("#lora_model_container").style.display = "" + document.querySelector("#lora_alpha_container").style.display = loraModelField.value ? "" : "none" + + document.querySelectorAll("#sampler_name option.k_diffusion-only").forEach(option => { + option.disabled = true + }) } console.log("get config status response", config) From d3dd15eb63f0f1de3c5654ca224508d4e3350830 Mon Sep 17 00:00:00 2001 From: Olivia Godone-Maresca Date: Wed, 17 May 2023 21:44:28 -0400 Subject: [PATCH 23/61] Fix unipc_tu --- ui/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/index.html b/ui/index.html index 53632610..32d31b34 100644 --- a/ui/index.html +++ b/ui/index.html @@ -162,7 +162,7 @@ - + From 00603ce124d6a137e7e6001cd01fb2007737cd82 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Thu, 18 May 2023 13:55:45 +0200 Subject: [PATCH 24/61] Add Clip Skip support --- ui/easydiffusion/model_manager.py | 12 +++++++++++- ui/easydiffusion/types.py | 1 + ui/index.html | 11 +++++++---- ui/media/js/auto-save.js | 1 + ui/media/js/dnd.js | 8 ++++++++ ui/media/js/engine.js | 2 ++ ui/media/js/main.js | 7 +++++++ ui/media/js/parameters.js | 1 + 8 files changed, 38 insertions(+), 5 deletions(-) diff --git a/ui/easydiffusion/model_manager.py b/ui/easydiffusion/model_manager.py index 7bf56575..324dcec9 100644 --- a/ui/easydiffusion/model_manager.py +++ b/ui/easydiffusion/model_manager.py @@ -122,7 +122,7 @@ def reload_models_if_necessary(context: Context, task_data: TaskData): if context.model_paths.get(model_type) != path } - if set_vram_optimizations(context): # reload SD + if set_vram_optimizations(context) or set_clip_skip(context, task_data): # reload SD models_to_reload["stable-diffusion"] = model_paths_in_req["stable-diffusion"] for model_type, model_path_in_req in models_to_reload.items(): @@ -157,6 +157,16 @@ def set_vram_optimizations(context: Context): return False +def set_clip_skip(context: Context, task_data: TaskData): + clip_skip = task_data.clip_skip + + if clip_skip != context.clip_skip: + context.clip_skip = clip_skip + return True + + return False + + def make_model_folders(): for model_type in KNOWN_MODEL_TYPES: model_dir_path = os.path.join(app.MODELS_DIR, model_type) diff --git a/ui/easydiffusion/types.py b/ui/easydiffusion/types.py index 7462355f..7a5201ab 100644 --- a/ui/easydiffusion/types.py +++ b/ui/easydiffusion/types.py @@ -48,6 +48,7 @@ class TaskData(BaseModel): metadata_output_format: str = "txt" # or "json" stream_image_progress: bool = False stream_image_progress_interval: int = 5 + clip_skip: bool = False class MergeRequest(BaseModel): diff --git a/ui/index.html b/ui/index.html index d196b99d..45263e4b 100644 --- a/ui/index.html +++ b/ui/index.html @@ -135,10 +135,13 @@ Click to learn more about custom models - + + + + + Click to learn more about Clip Skip + + Click to learn more about VAEs diff --git a/ui/media/js/auto-save.js b/ui/media/js/auto-save.js index 1e536247..ee01ba98 100644 --- a/ui/media/js/auto-save.js +++ b/ui/media/js/auto-save.js @@ -13,6 +13,7 @@ const SETTINGS_IDS_LIST = [ "num_outputs_total", "num_outputs_parallel", "stable_diffusion_model", + "clip_skip", "vae_model", "hypernetwork_model", "lora_model", diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index 548b06ad..02848266 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -240,6 +240,14 @@ const TASK_MAPPING = { readUI: () => stableDiffusionModelField.value, parse: (val) => val, }, + clip_skip: { + name: "Clip Skip", + setUI: (value) => { + clip_skip.checked = value + }, + readUI: () => clip_skip.checked, + parse: (val) => Boolean(val), + }, use_vae_model: { name: "VAE model", setUI: (use_vae_model) => { diff --git a/ui/media/js/engine.js b/ui/media/js/engine.js index f396d951..eccae6ac 100644 --- a/ui/media/js/engine.js +++ b/ui/media/js/engine.js @@ -750,6 +750,7 @@ sampler_name: "string", use_stable_diffusion_model: "string", + clip_skip: "boolean", num_inference_steps: "number", guidance_scale: "number", @@ -763,6 +764,7 @@ const TASK_DEFAULTS = { sampler_name: "plms", use_stable_diffusion_model: "sd-v1-4", + clip_skip: false, num_inference_steps: 50, guidance_scale: 7.5, negative_prompt: "", diff --git a/ui/media/js/main.js b/ui/media/js/main.js index a54f6ecb..c69535df 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -13,6 +13,11 @@ const taskConfigSetup = { num_inference_steps: "Inference Steps", guidance_scale: "Guidance Scale", use_stable_diffusion_model: "Model", + clip_skip: { + label: "Clip Skip", + visible: ({ reqBody }) => reqBody?.clip_skip, + value: ({ reqBody }) => "yes", + }, use_vae_model: { label: "VAE", visible: ({ reqBody }) => reqBody?.use_vae_model !== undefined && reqBody?.use_vae_model.trim() !== "", @@ -82,6 +87,7 @@ let useUpscalingField = document.querySelector("#use_upscale") let upscaleModelField = document.querySelector("#upscale_model") let upscaleAmountField = document.querySelector("#upscale_amount") let stableDiffusionModelField = new ModelDropdown(document.querySelector("#stable_diffusion_model"), "stable-diffusion") +let clipSkipField = document.querySelector("#clip_skip") let vaeModelField = new ModelDropdown(document.querySelector("#vae_model"), "vae", "None") let hypernetworkModelField = new ModelDropdown(document.querySelector("#hypernetwork_model"), "hypernetwork", "None") let hypernetworkStrengthSlider = document.querySelector("#hypernetwork_strength_slider") @@ -1224,6 +1230,7 @@ function getCurrentUserRequest() { sampler_name: samplerField.value, //render_device: undefined, // Set device affinity. Prefer this device, but wont activate. use_stable_diffusion_model: stableDiffusionModelField.value, + clip_skip: clipSkipField.checked, use_vae_model: vaeModelField.value, stream_progress_updates: true, stream_image_progress: numOutputsTotal > 50 ? false : streamImageProgressField.checked, diff --git a/ui/media/js/parameters.js b/ui/media/js/parameters.js index 75abecd7..746dc00e 100644 --- a/ui/media/js/parameters.js +++ b/ui/media/js/parameters.js @@ -397,6 +397,7 @@ async function getAppConfig() { document.querySelector("#lora_model_container").style.display = testDiffusers.checked ? "" : "none" document.querySelector("#lora_alpha_container").style.display = testDiffusers.checked && loraModelField.value !== "" ? "" : "none" + document.querySelector("#clip_skip_config").classList.remove("displayNone") } console.log("get config status response", config) From b77036443ffc8175b21675ad49874c996ca40071 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Thu, 18 May 2023 16:04:28 +0200 Subject: [PATCH 25/61] Fail gracefully if proc access isn't possible --- scripts/check_modules.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 18549217..df89f2b2 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -130,10 +130,13 @@ def include_cuda_versions(module_versions: tuple) -> tuple: def is_amd_on_linux(): if os_name == "Linux": - with open("/proc/bus/pci/devices", "r") as f: - device_info = f.read() - if "amdgpu" in device_info and "nvidia" not in device_info: - return True + try: + with open("/proc/bus/pci/devices", "r") as f: + device_info = f.read() + if "amdgpu" in device_info and "nvidia" not in device_info: + return True + except: + return False return False From 063d14d2ac00128ec3096faf09155ae4ce558404 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 19 May 2023 17:25:53 +0530 Subject: [PATCH 26/61] Allow GPUs with less than 2 GB, instead of restricting to 3 GB --- ui/easydiffusion/device_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/easydiffusion/device_manager.py b/ui/easydiffusion/device_manager.py index 59c07ea3..47297900 100644 --- a/ui/easydiffusion/device_manager.py +++ b/ui/easydiffusion/device_manager.py @@ -224,9 +224,9 @@ def is_device_compatible(device): try: _, mem_total = torch.cuda.mem_get_info(device) mem_total /= float(10 ** 9) - if mem_total < 3.0: + if mem_total < 2.0: if is_device_compatible.history.get(device) == None: - log.warn(f"GPU {device} with less than 3 GB of VRAM is not compatible with Stable Diffusion") + log.warn(f"GPU {device} with less than 2 GB of VRAM is not compatible with Stable Diffusion") is_device_compatible.history[device] = 1 return False except RuntimeError as e: From 53b23756a4d97502e03d0ef261c4054ac8726f41 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 19 May 2023 17:26:04 +0530 Subject: [PATCH 27/61] formatting --- ui/easydiffusion/device_manager.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/easydiffusion/device_manager.py b/ui/easydiffusion/device_manager.py index 47297900..4b92ac6e 100644 --- a/ui/easydiffusion/device_manager.py +++ b/ui/easydiffusion/device_manager.py @@ -98,8 +98,8 @@ def auto_pick_devices(currently_active_devices): continue mem_free, mem_total = torch.cuda.mem_get_info(device) - mem_free /= float(10 ** 9) - mem_total /= float(10 ** 9) + mem_free /= float(10**9) + mem_total /= float(10**9) device_name = torch.cuda.get_device_name(device) log.debug( f"{device} detected: {device_name} - Memory (free/total): {round(mem_free, 2)}Gb / {round(mem_total, 2)}Gb" @@ -181,7 +181,7 @@ def get_max_vram_usage_level(device): else: return "high" - mem_total /= float(10 ** 9) + mem_total /= float(10**9) if mem_total < 4.5: return "low" elif mem_total < 6.5: @@ -223,7 +223,7 @@ def is_device_compatible(device): # Memory check try: _, mem_total = torch.cuda.mem_get_info(device) - mem_total /= float(10 ** 9) + mem_total /= float(10**9) if mem_total < 2.0: if is_device_compatible.history.get(device) == None: log.warn(f"GPU {device} with less than 2 GB of VRAM is not compatible with Stable Diffusion") From 415213878dfb985c45fce946bd111f4951716e72 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 19 May 2023 17:28:54 +0530 Subject: [PATCH 28/61] sdkit 1.0.94 - vram optimizations - perform softmax in half precision --- scripts/check_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 18549217..d6e0b251 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -18,7 +18,7 @@ os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0"), "torchvision": ("0.12.0", "0.14.1", "0.15.1"), - "sdkit": "1.0.93", + "sdkit": "1.0.94", "stable-diffusion-sdkit": "2.1.4", "rich": "12.6.0", "uvicorn": "0.19.0", From b08e9b79827e6034dba0361e746cad9b36d3e966 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 19 May 2023 17:29:10 +0530 Subject: [PATCH 29/61] changelog --- CHANGES.md | 1 + ui/index.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 3b910ae6..e29f75a0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed. ### Detailed changelog +* 2.5.37 - 19 May 2023 - (beta-only) More VRAM optimizations for all modes in diffusers. The VRAM usage for diffusers in "low" and "balanced" should now be equal or less than the non-diffusers version. Performs softmax in half precision, like sdkit does. * 2.5.36 - 16 May 2023 - (beta-only) More VRAM optimizations for "balanced" VRAM usage mode. * 2.5.36 - 11 May 2023 - (beta-only) More VRAM optimizations for "low" VRAM usage mode. * 2.5.36 - 10 May 2023 - (beta-only) Bug fix for "meta" error when using a LoRA in 'low' VRAM usage mode. diff --git a/ui/index.html b/ui/index.html index d196b99d..d4b8c7bd 100644 --- a/ui/index.html +++ b/ui/index.html @@ -30,7 +30,7 @@

Easy Diffusion - v2.5.36 + v2.5.37

From 107323d8e7dfe26383c59af7759aacc1f73b81e6 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 19 May 2023 17:42:47 +0530 Subject: [PATCH 30/61] sdkit 1.0.95 - lower vram usage for high mode --- scripts/check_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 4b88cd1c..98748967 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -18,7 +18,7 @@ os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0"), "torchvision": ("0.12.0", "0.14.1", "0.15.1"), - "sdkit": "1.0.94", + "sdkit": "1.0.95", "stable-diffusion-sdkit": "2.1.4", "rich": "12.6.0", "uvicorn": "0.19.0", From 11e1436e2efb92b41aae84289addc4ab3b1b9171 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 19 May 2023 17:56:20 +0530 Subject: [PATCH 31/61] 2 GB cards aren't exactly 2 GB --- ui/easydiffusion/device_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/easydiffusion/device_manager.py b/ui/easydiffusion/device_manager.py index 3a820116..dc705927 100644 --- a/ui/easydiffusion/device_manager.py +++ b/ui/easydiffusion/device_manager.py @@ -225,7 +225,7 @@ def is_device_compatible(device): try: _, mem_total = torch.cuda.mem_get_info(device) mem_total /= float(10**9) - if mem_total < 2.0: + if mem_total < 1.9: if is_device_compatible.history.get(device) == None: log.warn(f"GPU {device} with less than 2 GB of VRAM is not compatible with Stable Diffusion") is_device_compatible.history[device] = 1 From 760909f4958765f2496079b52ac7baef8db2eb92 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 19 May 2023 18:23:10 +0530 Subject: [PATCH 32/61] Update CHANGES.md --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index e29f75a0..9b2b72c1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,8 @@ Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed. ### Detailed changelog +* 2.5.37 - 19 May 2023 - (beta-only) Two more samplers: DDPM and DEIS. Also disables the samplers that aren't working yet in the Diffusers version. Thanks @ogmaresca. +* 2.5.37 - 19 May 2023 - (beta-only) Support CLIP-Skip. You can set this option under the models dropdown. Thanks @JeLuf. * 2.5.37 - 19 May 2023 - (beta-only) More VRAM optimizations for all modes in diffusers. The VRAM usage for diffusers in "low" and "balanced" should now be equal or less than the non-diffusers version. Performs softmax in half precision, like sdkit does. * 2.5.36 - 16 May 2023 - (beta-only) More VRAM optimizations for "balanced" VRAM usage mode. * 2.5.36 - 11 May 2023 - (beta-only) More VRAM optimizations for "low" VRAM usage mode. From bdf36a8dabff7f2dbd2dfe92c8c82d2dbc96e10f Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 19 May 2023 18:36:37 +0530 Subject: [PATCH 33/61] sdkit 1.0.96 - missing xformers import --- scripts/check_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 98748967..1590f569 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -18,7 +18,7 @@ os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0"), "torchvision": ("0.12.0", "0.14.1", "0.15.1"), - "sdkit": "1.0.95", + "sdkit": "1.0.96", "stable-diffusion-sdkit": "2.1.4", "rich": "12.6.0", "uvicorn": "0.19.0", From a6dbdf664b2efa965926aa38c81a278817fb48c5 Mon Sep 17 00:00:00 2001 From: Olivia Godone-Maresca Date: Fri, 19 May 2023 19:05:32 -0400 Subject: [PATCH 34/61] Add Clip Skip to metadata files Also, force the properties to be in a consistent order so that, for example, LoRA strength will always be the line below LoRA model. I've rearranged the properties so that they are saved in the same order that the properties are laid out in the UI --- ui/easydiffusion/renderer.py | 2 +- ui/easydiffusion/utils/save_utils.py | 72 ++++++++++++++-------------- ui/media/js/dnd.js | 1 + 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/ui/easydiffusion/renderer.py b/ui/easydiffusion/renderer.py index f685d038..e26b4389 100644 --- a/ui/easydiffusion/renderer.py +++ b/ui/easydiffusion/renderer.py @@ -72,7 +72,7 @@ def make_images( def print_task_info(req: GenerateImageRequest, task_data: TaskData): - req_str = pprint.pformat(get_printable_request(req)).replace("[", "\[") + req_str = pprint.pformat(get_printable_request(req, task_data)).replace("[", "\[") task_str = pprint.pformat(task_data.dict()).replace("[", "\[") log.info(f"request: {req_str}") log.info(f"task data: {task_str}") diff --git a/ui/easydiffusion/utils/save_utils.py b/ui/easydiffusion/utils/save_utils.py index a7043f27..24b2198c 100644 --- a/ui/easydiffusion/utils/save_utils.py +++ b/ui/easydiffusion/utils/save_utils.py @@ -15,23 +15,24 @@ img_number_regex = re.compile("([0-9]{5,})") # keep in sync with `ui/media/js/dnd.js` TASK_TEXT_MAPPING = { "prompt": "Prompt", + "negative_prompt": "Negative Prompt", + "seed": "Seed", + "use_stable_diffusion_model": "Stable Diffusion model", + "clip_skip": "Clip Skip", + "use_vae_model": "VAE model", + "sampler_name": "Sampler", "width": "Width", "height": "Height", - "seed": "Seed", "num_inference_steps": "Steps", "guidance_scale": "Guidance Scale", "prompt_strength": "Prompt Strength", + "use_lora_model": "LoRA model", + "lora_alpha": "LoRA Strength", + "use_hypernetwork_model": "Hypernetwork model", + "hypernetwork_strength": "Hypernetwork Strength", "use_face_correction": "Use Face Correction", "use_upscale": "Use Upscaling", "upscale_amount": "Upscale By", - "sampler_name": "Sampler", - "negative_prompt": "Negative Prompt", - "use_stable_diffusion_model": "Stable Diffusion model", - "use_vae_model": "VAE model", - "use_hypernetwork_model": "Hypernetwork model", - "hypernetwork_strength": "Hypernetwork Strength", - "use_lora_model": "LoRA model", - "lora_alpha": "LoRA Strength", } time_placeholders = { @@ -179,27 +180,7 @@ def save_images_to_disk(images: list, filtered_images: list, req: GenerateImageR def get_metadata_entries_for_request(req: GenerateImageRequest, task_data: TaskData): - metadata = get_printable_request(req) - metadata.update( - { - "use_stable_diffusion_model": task_data.use_stable_diffusion_model, - "use_vae_model": task_data.use_vae_model, - "use_hypernetwork_model": task_data.use_hypernetwork_model, - "use_lora_model": task_data.use_lora_model, - "use_face_correction": task_data.use_face_correction, - "use_upscale": task_data.use_upscale, - } - ) - if metadata["use_upscale"] is not None: - metadata["upscale_amount"] = task_data.upscale_amount - if task_data.use_hypernetwork_model is None: - del metadata["hypernetwork_strength"] - if task_data.use_lora_model is None: - if "lora_alpha" in metadata: - del metadata["lora_alpha"] - app_config = app.getConfig() - if not app_config.get("test_diffusers", False) and "use_lora_model" in metadata: - del metadata["use_lora_model"] + metadata = get_printable_request(req, task_data) # if text, format it in the text format expected by the UI is_txt_format = task_data.metadata_output_format.lower() == "txt" @@ -213,12 +194,33 @@ def get_metadata_entries_for_request(req: GenerateImageRequest, task_data: TaskD return entries -def get_printable_request(req: GenerateImageRequest): - metadata = req.dict() - del metadata["init_image"] - del metadata["init_image_mask"] - if req.init_image is None: +def get_printable_request(req: GenerateImageRequest, task_data: TaskData): + req_metadata = req.dict() + task_data_metadata = task_data.dict() + + # Save the metadata in the order defined in TASK_TEXT_MAPPING + metadata = {} + for key in TASK_TEXT_MAPPING.keys(): + if key in req_metadata: + metadata[key] = req_metadata[key] + elif key in task_data_metadata: + metadata[key] = task_data_metadata[key] + + # Clean up the metadata + if req.init_image is None and "prompt_strength" in metadata: del metadata["prompt_strength"] + if task_data.use_upscale is None and "upscale_amount" in metadata: + del metadata["upscale_amount"] + if task_data.use_hypernetwork_model is None and "hypernetwork_strength" in metadata: + del metadata["hypernetwork_strength"] + if task_data.use_lora_model is None and "lora_alpha" in metadata: + del metadata["lora_alpha"] + + app_config = app.getConfig() + if not app_config.get("test_diffusers", False): + for key in (x for x in ["use_lora_model", "lora_alpha", "clip_skip"] if x in metadata): + del metadata[key] + return metadata diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index 02848266..8b66a3a4 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -37,6 +37,7 @@ function parseBoolean(stringValue) { } } +// keep in sync with `ui/easydiffusion/utils/save_utils.py` const TASK_MAPPING = { prompt: { name: "Prompt", From 70a3beeaa2c44c21b7f43c58ba98548a5e485535 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Sun, 21 May 2023 17:42:47 +0200 Subject: [PATCH 35/61] Automatically use 'Low' when VRAM<4.5GB --- ui/media/js/auto-save.js | 16 ++++++++++++++++ ui/media/js/main.js | 2 +- ui/media/js/parameters.js | 4 +++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ui/media/js/auto-save.js b/ui/media/js/auto-save.js index ee01ba98..49d3c751 100644 --- a/ui/media/js/auto-save.js +++ b/ui/media/js/auto-save.js @@ -169,6 +169,22 @@ function loadSettings() { } }) CURRENTLY_LOADING_SETTINGS = false + } else if (localStorage.length < 2) { + // localStorage is too short for OldSettings + // So this is likely the first time Easy Diffusion is running. + // Initialize vram_usage_level based on the available VRAM + function initGPUProfile(event) { + if ( "detail" in event + && "active" in event.detail + && "cuda:0" in event.detail.active + && event.detail.active["cuda:0"].mem_total <4.5 ) + { + vramUsageLevelField.value = "low" + vramUsageLevelField.dispatchEvent(new Event("change")) + } + document.removeEventListener("system_info_update", initGPUProfile) + } + document.addEventListener("system_info_update", initGPUProfile) } else { CURRENTLY_LOADING_SETTINGS = true tryLoadOldSettings() diff --git a/ui/media/js/main.js b/ui/media/js/main.js index c69535df..0ce32f2b 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -239,7 +239,7 @@ function setServerStatus(event) { break } if (SD.serverState.devices) { - setDeviceInfo(SD.serverState.devices) + document.dispatchEvent(new CustomEvent("system_info_update", { detail: SD.serverState.devices})) } } diff --git a/ui/media/js/parameters.js b/ui/media/js/parameters.js index e48e2e04..30cdda78 100644 --- a/ui/media/js/parameters.js +++ b/ui/media/js/parameters.js @@ -586,7 +586,7 @@ async function getSystemInfo() { $("#use_gpus").val(activeDeviceIds) } - setDeviceInfo(devices) + document.dispatchEvent(new CustomEvent("system_info_update", { detail: devices})) setHostInfo(res["hosts"]) let force = false if (res["enforce_output_dir"] !== undefined) { @@ -657,3 +657,5 @@ saveSettingsBtn.addEventListener("click", function() { saveSettingsBtn.classList.add("active") Promise.all([savePromise, asyncDelay(300)]).then(() => saveSettingsBtn.classList.remove("active")) }) + +document.addEventListener("system_info_update", (e) => setDeviceInfo(e.detail)) From cac4bd11d2337b2bcb5108cec87ad51078eaf6ef Mon Sep 17 00:00:00 2001 From: JeLuF Date: Sun, 21 May 2023 17:59:06 +0200 Subject: [PATCH 36/61] Network settings - Fix typo. The 'Please restart' text should be part of the note, not the label --- ui/media/js/parameters.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/media/js/parameters.js b/ui/media/js/parameters.js index e48e2e04..ac011263 100644 --- a/ui/media/js/parameters.js +++ b/ui/media/js/parameters.js @@ -181,8 +181,8 @@ var PARAMETERS = [ { id: "listen_to_network", type: ParameterType.checkbox, - label: "Make Stable Diffusion available on your network. Please restart the program after changing this.", - note: "Other devices on your network can access this web page", + label: "Make Stable Diffusion available on your network", + note: "Other devices on your network can access this web page. Please restart the program after changing this.", icon: "fa-network-wired", default: true, saveInAppConfig: true, From 0f6caaec3319c82427e1bf2274a58091974b8c9c Mon Sep 17 00:00:00 2001 From: JeLuF Date: Mon, 22 May 2023 10:21:19 +0200 Subject: [PATCH 37/61] get_config: return default value if conf file is corrupted --- scripts/get_config.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/get_config.py b/scripts/get_config.py index 02523364..9cdfb2fe 100644 --- a/scripts/get_config.py +++ b/scripts/get_config.py @@ -1,5 +1,6 @@ import os import argparse +import sys # The config file is in the same directory as this script config_directory = os.path.dirname(__file__) @@ -21,16 +22,16 @@ if os.path.isfile(config_yaml): try: config = yaml.safe_load(configfile) except Exception as e: - print(e) - exit() + print(e, file=sys.stderr) + config = {} elif os.path.isfile(config_json): import json with open(config_json, 'r') as configfile: try: config = json.load(configfile) except Exception as e: - print(e) - exit() + print(e, file=sys.stderr) + config = {} else: config = {} From ea9861d180ed4c91749324b8685fd8335570de5b Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Mon, 22 May 2023 16:07:50 +0530 Subject: [PATCH 38/61] Less min VRAM requirement --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c6b047e4..6a629e57 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ Click the download button for your operating system:

**Hardware requirements:** -- **Windows:** NVIDIA graphics card, or run on your CPU. -- **Linux:** NVIDIA or AMD graphics card, or run on your CPU. +- **Windows:** NVIDIA graphics card (minimum 2 GB RAM), or run on your CPU. +- **Linux:** NVIDIA or AMD graphics card (minimum 2 GB RAM), or run on your CPU. - **Mac:** M1 or M2, or run on your CPU. - Minimum 8 GB of system RAM. - Atleast 25 GB of space on the hard disk. @@ -86,7 +86,7 @@ Just delete the `EasyDiffusion` folder to uninstall all the downloaded packages. ### Performance and security - **Fast**: Creates a 512x512 image with euler_a in 5 seconds, on an NVIDIA 3060 12GB. -- **Low Memory Usage**: Create 512x512 images with less than 3 GB of GPU RAM, and 768x768 images with less than 4 GB of GPU RAM! +- **Low Memory Usage**: Create 512x512 images with less than 2 GB of GPU RAM, and 768x768 images with less than 3 GB of GPU RAM! - **Use CPU setting**: If you don't have a compatible graphics card, but still want to run it on your CPU. - **Multi-GPU support**: Automatically spreads your tasks across multiple GPUs (if available), for faster performance! - **Auto scan for malicious models**: Uses picklescan to prevent malicious models. From d60cb61e585ea89928c47403a0a5af7cc1c0a7f6 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Mon, 22 May 2023 18:06:38 +0530 Subject: [PATCH 39/61] sdkit 1.0.97 - flatten arguments sent to latent upscaler --- scripts/check_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check_modules.py b/scripts/check_modules.py index 1590f569..8747d173 100644 --- a/scripts/check_modules.py +++ b/scripts/check_modules.py @@ -18,7 +18,7 @@ os_name = platform.system() modules_to_check = { "torch": ("1.11.0", "1.13.1", "2.0.0"), "torchvision": ("0.12.0", "0.14.1", "0.15.1"), - "sdkit": "1.0.96", + "sdkit": "1.0.97", "stable-diffusion-sdkit": "2.1.4", "rich": "12.6.0", "uvicorn": "0.19.0", From 0127714929c9eb5567a4dd4a0360df2d771db48f Mon Sep 17 00:00:00 2001 From: JeLuF Date: Mon, 22 May 2023 21:19:31 +0200 Subject: [PATCH 40/61] Add 'ED is ready, go to localhost:9000' msg to log Sometimes the browser window does not open (esp. on Linux and Mac). Show a prominent message to the log so that users don't wait for hours. --- ui/easydiffusion/app.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ui/easydiffusion/app.py b/ui/easydiffusion/app.py index b6318f01..3064e151 100644 --- a/ui/easydiffusion/app.py +++ b/ui/easydiffusion/app.py @@ -10,6 +10,8 @@ import warnings from easydiffusion import task_manager from easydiffusion.utils import log from rich.logging import RichHandler +from rich.console import Console +from rich.panel import Panel from sdkit.utils import log as sdkit_log # hack, so we can overwrite the log config # Remove all handlers associated with the root logger object. @@ -213,11 +215,19 @@ def open_browser(): ui = config.get("ui", {}) net = config.get("net", {}) port = net.get("listen_port", 9000) + if ui.get("open_browser_on_start", True): import webbrowser webbrowser.open(f"http://localhost:{port}") + Console().print(Panel( + "\n" + + "[white]Easy Diffusion is ready to serve requests.\n\n" + + "A new browser tab should have been opened by now.\n" + + f"If not, please open your web browser and navigate to [bold yellow underline]http://localhost:{port}/\n", + title="Easy Diffusion is ready", style="bold yellow on blue")) + def get_image_modifiers(): modifiers_json_path = os.path.join(SD_UI_DIR, "modifiers.json") From 2bab4341a3d658e1d4516b68f66449467265329e Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 23 May 2023 16:53:53 +0530 Subject: [PATCH 41/61] Add 'Latent Upscaler' as an option in the upscaling dropdown --- ui/easydiffusion/model_manager.py | 7 +++-- ui/easydiffusion/renderer.py | 24 +++++++++++++---- ui/easydiffusion/types.py | 3 ++- ui/index.html | 8 ++++-- ui/media/css/main.css | 6 +++++ ui/media/js/main.js | 44 ++++++++++++++++++++++++++++++- 6 files changed, 81 insertions(+), 11 deletions(-) diff --git a/ui/easydiffusion/model_manager.py b/ui/easydiffusion/model_manager.py index 324dcec9..d6a227be 100644 --- a/ui/easydiffusion/model_manager.py +++ b/ui/easydiffusion/model_manager.py @@ -107,12 +107,15 @@ def resolve_model_to_use(model_name: str = None, model_type: str = None): def reload_models_if_necessary(context: Context, task_data: TaskData): + use_upscale_lower = task_data.use_upscale.lower() if task_data.use_upscale else "" + model_paths_in_req = { "stable-diffusion": task_data.use_stable_diffusion_model, "vae": task_data.use_vae_model, "hypernetwork": task_data.use_hypernetwork_model, "gfpgan": task_data.use_face_correction, - "realesrgan": task_data.use_upscale, + "realesrgan": task_data.use_upscale if "realesrgan" in use_upscale_lower else None, + "latent_upscaler": True if task_data.use_upscale == "latent_upscaler" else None, "nsfw_checker": True if task_data.block_nsfw else None, "lora": task_data.use_lora_model, } @@ -142,7 +145,7 @@ def resolve_model_paths(task_data: TaskData): if task_data.use_face_correction: task_data.use_face_correction = resolve_model_to_use(task_data.use_face_correction, "gfpgan") - if task_data.use_upscale: + if task_data.use_upscale and "realesrgan" in task_data.use_upscale.lower(): task_data.use_upscale = resolve_model_to_use(task_data.use_upscale, "realesrgan") diff --git a/ui/easydiffusion/renderer.py b/ui/easydiffusion/renderer.py index e26b4389..c60c42df 100644 --- a/ui/easydiffusion/renderer.py +++ b/ui/easydiffusion/renderer.py @@ -95,7 +95,7 @@ def make_images_internal( task_data.stream_image_progress_interval, ) gc(context) - filtered_images = filter_images(task_data, images, user_stopped) + filtered_images = filter_images(req, task_data, images, user_stopped) if task_data.save_to_disk_path is not None: save_images_to_disk(images, filtered_images, req, task_data) @@ -151,22 +151,36 @@ def generate_images_internal( return images, user_stopped -def filter_images(task_data: TaskData, images: list, user_stopped): +def filter_images(req: GenerateImageRequest, task_data: TaskData, images: list, user_stopped): if user_stopped: return images filters_to_apply = [] + filter_params = {} if task_data.block_nsfw: filters_to_apply.append("nsfw_checker") if task_data.use_face_correction and "gfpgan" in task_data.use_face_correction.lower(): filters_to_apply.append("gfpgan") - if task_data.use_upscale and "realesrgan" in task_data.use_upscale.lower(): - filters_to_apply.append("realesrgan") + if task_data.use_upscale: + if "realesrgan" in task_data.use_upscale.lower(): + filters_to_apply.append("realesrgan") + elif task_data.use_upscale == "latent_upscaler": + filters_to_apply.append("latent_upscaler") + + filter_params["latent_upscaler_options"] = { + "prompt": req.prompt, + "negative_prompt": req.negative_prompt, + "seed": req.seed, + "num_inference_steps": task_data.latent_upscaler_steps, + "guidance_scale": 0, + } + + filter_params["scale"] = task_data.upscale_amount if len(filters_to_apply) == 0: return images - return apply_filters(context, filters_to_apply, images, scale=task_data.upscale_amount) + return apply_filters(context, filters_to_apply, images, **filter_params) def construct_response(images: list, seeds: list, task_data: TaskData, base_seed: int): diff --git a/ui/easydiffusion/types.py b/ui/easydiffusion/types.py index 7a5201ab..a76f489a 100644 --- a/ui/easydiffusion/types.py +++ b/ui/easydiffusion/types.py @@ -32,8 +32,9 @@ class TaskData(BaseModel): vram_usage_level: str = "balanced" # or "low" or "medium" use_face_correction: str = None # or "GFPGANv1.3" - use_upscale: str = None # or "RealESRGAN_x4plus" or "RealESRGAN_x4plus_anime_6B" + use_upscale: str = None # or "RealESRGAN_x4plus" or "RealESRGAN_x4plus_anime_6B" or "latent_upscaler" upscale_amount: int = 4 # or 2 + latent_upscaler_steps: int = 10 use_stable_diffusion_model: str = "sd-v1-4" # use_stable_diffusion_config: str = "v1-inference" use_vae_model: str = None diff --git a/ui/index.html b/ui/index.html index 99087eec..5097d84a 100644 --- a/ui/index.html +++ b/ui/index.html @@ -258,14 +258,18 @@
  • with +
    + +
  • diff --git a/ui/media/css/main.css b/ui/media/css/main.css index ba513237..8f4f49fa 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -1303,6 +1303,12 @@ body.wait-pause { display:none !important; } +#latent_upscaler_settings { + padding-top: 3pt; + padding-bottom: 3pt; + padding-left: 5pt; +} + /* TOAST NOTIFICATIONS */ .toast-notification { position: fixed; diff --git a/ui/media/js/main.js b/ui/media/js/main.js index 0ce32f2b..23ed5f46 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -86,6 +86,9 @@ let gfpganModelField = new ModelDropdown(document.querySelector("#gfpgan_model") let useUpscalingField = document.querySelector("#use_upscale") let upscaleModelField = document.querySelector("#upscale_model") let upscaleAmountField = document.querySelector("#upscale_amount") +let latentUpscalerSettings = document.querySelector("#latent_upscaler_settings") +let latentUpscalerStepsSlider = document.querySelector("#latent_upscaler_steps_slider") +let latentUpscalerStepsField = document.querySelector("#latent_upscaler_steps") let stableDiffusionModelField = new ModelDropdown(document.querySelector("#stable_diffusion_model"), "stable-diffusion") let clipSkipField = document.querySelector("#clip_skip") let vaeModelField = new ModelDropdown(document.querySelector("#vae_model"), "vae", "None") @@ -239,7 +242,7 @@ function setServerStatus(event) { break } if (SD.serverState.devices) { - document.dispatchEvent(new CustomEvent("system_info_update", { detail: SD.serverState.devices})) + document.dispatchEvent(new CustomEvent("system_info_update", { detail: SD.serverState.devices })) } } @@ -1268,6 +1271,10 @@ function getCurrentUserRequest() { if (useUpscalingField.checked) { newTask.reqBody.use_upscale = upscaleModelField.value newTask.reqBody.upscale_amount = upscaleAmountField.value + if (upscaleModelField.value === "latent_upscaler") { + newTask.reqBody.upscale_amount = "2" + newTask.reqBody.latent_upscaler_steps = latentUpscalerStepsField.value + } } if (hypernetworkModelField.value) { newTask.reqBody.use_hypernetwork_model = hypernetworkModelField.value @@ -1582,6 +1589,20 @@ useUpscalingField.addEventListener("change", function(e) { upscaleAmountField.disabled = !this.checked }) +function onUpscaleModelChange() { + let upscale4x = document.querySelector("#upscale_amount_4x") + if (upscaleModelField.value === "latent_upscaler") { + upscale4x.disabled = true + upscaleAmountField.value = "2" + latentUpscalerSettings.classList.remove("displayNone") + } else { + upscale4x.disabled = false + latentUpscalerSettings.classList.add("displayNone") + } +} +upscaleModelField.addEventListener("change", onUpscaleModelChange) +onUpscaleModelChange() + makeImageBtn.addEventListener("click", makeImage) document.onkeydown = function(e) { @@ -1591,6 +1612,27 @@ document.onkeydown = function(e) { } } +/********************* Latent Upscaler Steps **************************/ +function updateLatentUpscalerSteps() { + latentUpscalerStepsField.value = latentUpscalerStepsSlider.value + latentUpscalerStepsField.dispatchEvent(new Event("change")) +} + +function updateLatentUpscalerStepsSlider() { + if (latentUpscalerStepsField.value < 1) { + latentUpscalerStepsField.value = 1 + } else if (latentUpscalerStepsField.value > 50) { + latentUpscalerStepsField.value = 50 + } + + latentUpscalerStepsSlider.value = latentUpscalerStepsField.value + latentUpscalerStepsSlider.dispatchEvent(new Event("change")) +} + +latentUpscalerStepsSlider.addEventListener("input", updateLatentUpscalerSteps) +latentUpscalerStepsField.addEventListener("input", updateLatentUpscalerStepsSlider) +updateLatentUpscalerSteps() + /********************* Guidance **************************/ function updateGuidanceScale() { guidanceScaleField.value = guidanceScaleSlider.value / 10 From a87dca1ef4b0c2bd6a0380866b1ca76acbc26c89 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 23 May 2023 16:55:42 +0530 Subject: [PATCH 42/61] changelog --- CHANGES.md | 1 + ui/index.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 9b2b72c1..d8e5c3f0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed. ### Detailed changelog +* 2.5.38 - 23 May 2023 - Add Latent Upscaler as another option for upscaling images. Thanks @JeLuf for the implementation of the Latent Upscaler model. * 2.5.37 - 19 May 2023 - (beta-only) Two more samplers: DDPM and DEIS. Also disables the samplers that aren't working yet in the Diffusers version. Thanks @ogmaresca. * 2.5.37 - 19 May 2023 - (beta-only) Support CLIP-Skip. You can set this option under the models dropdown. Thanks @JeLuf. * 2.5.37 - 19 May 2023 - (beta-only) More VRAM optimizations for all modes in diffusers. The VRAM usage for diffusers in "low" and "balanced" should now be equal or less than the non-diffusers version. Performs softmax in half precision, like sdkit does. diff --git a/ui/index.html b/ui/index.html index 5097d84a..dc4eb7f0 100644 --- a/ui/index.html +++ b/ui/index.html @@ -30,7 +30,7 @@

    Easy Diffusion - v2.5.37 + v2.5.38

    From eba83386c1e69ac2d02c8e11c7b59251a518664b Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 24 May 2023 10:08:00 +0530 Subject: [PATCH 43/61] make a note about a flood fill library --- ui/media/js/image-editor.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/media/js/image-editor.js b/ui/media/js/image-editor.js index af19daeb..e7de9f2b 100644 --- a/ui/media/js/image-editor.js +++ b/ui/media/js/image-editor.js @@ -834,6 +834,7 @@ function pixelCompare(int1, int2) { } // adapted from https://ben.akrin.com/canvas_fill/fill_04.html +// May 2023 - look at using a library instead of custom code: https://github.com/shaneosullivan/example-canvas-fill function flood_fill(editor, the_canvas_context, x, y, color) { pixel_stack = [{ x: x, y: y }] pixels = the_canvas_context.getImageData(0, 0, editor.width, editor.height) From 30c07eab6b5fd131fa0858d7582d690fbdb7b76a Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 24 May 2023 15:30:55 +0530 Subject: [PATCH 44/61] Cleaner reporting of errors in the UI; Suggest increasing the page size if that's the error --- ui/media/js/main.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ui/media/js/main.js b/ui/media/js/main.js index 23ed5f46..473ed780 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -296,6 +296,7 @@ function logError(msg, res, outputMsg) { logMsg(msg, "error", outputMsg) console.log("request error", res) + console.trace() setStatus("request", "error", "error") } @@ -787,11 +788,6 @@ function getTaskUpdater(task, reqBody, outputContainer) { } msg += "" logError(msg, event, outputMsg) - } else { - let msg = `Unexpected Read Error:
    Error:${
    -                            this.exception
    -                        }
    EventInfo: ${JSON.stringify(event, undefined, 4)}
    ` - logError(msg, event, outputMsg) } break } @@ -888,15 +884,15 @@ function onTaskCompleted(task, reqBody, instance, outputContainer, stepUpdate) { 1. If you have set an initial image, please try reducing its dimension to ${MAX_INIT_IMAGE_DIMENSION}x${MAX_INIT_IMAGE_DIMENSION} or smaller.
    2. Try picking a lower level in the 'GPU Memory Usage' setting (in the 'Settings' tab).
    3. Try generating a smaller image.
    ` - } else if (msg.toLowerCase().includes("DefaultCPUAllocator: not enough memory")) { + } else if (msg.includes("DefaultCPUAllocator: not enough memory")) { msg += `

    Reason: Your computer is running out of system RAM! -
    +

    Suggestions:
    1. Try closing unnecessary programs and browser tabs.
    2. If that doesn't help, please increase your computer's virtual memory by following these steps for - Windows, or + Windows or Linux.
    3. Try restarting your computer.
    ` } From 8554b0eab2a355c5472c42ccad039b01c7f18d67 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 24 May 2023 16:02:53 +0530 Subject: [PATCH 45/61] Better reporting of model load errors - sends the report to the browser UI during the next image rendering task --- ui/easydiffusion/model_manager.py | 23 ++++++++++++++++++++++- ui/easydiffusion/renderer.py | 1 + ui/easydiffusion/task_manager.py | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ui/easydiffusion/model_manager.py b/ui/easydiffusion/model_manager.py index d6a227be..0a1f1b5c 100644 --- a/ui/easydiffusion/model_manager.py +++ b/ui/easydiffusion/model_manager.py @@ -53,15 +53,21 @@ def load_default_models(context: Context): scan_model=context.model_paths[model_type] != None and not context.model_paths[model_type].endswith(".safetensors"), ) + if model_type in context.model_load_errors: + del context.model_load_errors[model_type] except Exception as e: log.error(f"[red]Error while loading {model_type} model: {context.model_paths[model_type]}[/red]") log.exception(e) del context.model_paths[model_type] + context.model_load_errors[model_type] = str(e) # storing the entire Exception can lead to memory leaks + def unload_all(context: Context): for model_type in KNOWN_MODEL_TYPES: unload_model(context, model_type) + if model_type in context.model_load_errors: + del context.model_load_errors[model_type] def resolve_model_to_use(model_name: str = None, model_type: str = None): @@ -132,7 +138,14 @@ def reload_models_if_necessary(context: Context, task_data: TaskData): context.model_paths[model_type] = model_path_in_req action_fn = unload_model if context.model_paths[model_type] is None else load_model - action_fn(context, model_type, scan_model=False) # we've scanned them already + try: + action_fn(context, model_type, scan_model=False) # we've scanned them already + if model_type in context.model_load_errors: + del context.model_load_errors[model_type] + except Exception as e: + log.exception(e) + if action_fn == load_model: + context.model_load_errors[model_type] = str(e) # storing the entire Exception can lead to memory leaks def resolve_model_paths(task_data: TaskData): @@ -149,6 +162,14 @@ def resolve_model_paths(task_data: TaskData): task_data.use_upscale = resolve_model_to_use(task_data.use_upscale, "realesrgan") +def fail_if_models_did_not_load(context: Context): + for model_type in KNOWN_MODEL_TYPES: + if model_type in context.model_load_errors: + e = context.model_load_errors[model_type] + raise Exception(f"Could not load the {model_type} model! Reason: " + e) + # concat 'e', don't use in format string (injection attack) + + def set_vram_optimizations(context: Context): config = app.getConfig() vram_usage_level = config.get("vram_usage_level", "balanced") diff --git a/ui/easydiffusion/renderer.py b/ui/easydiffusion/renderer.py index c60c42df..e2dae34f 100644 --- a/ui/easydiffusion/renderer.py +++ b/ui/easydiffusion/renderer.py @@ -33,6 +33,7 @@ def init(device): context.stop_processing = False context.temp_images = {} context.partial_x_samples = None + context.model_load_errors = {} from easydiffusion import app diff --git a/ui/easydiffusion/task_manager.py b/ui/easydiffusion/task_manager.py index c11acbec..a91cd9c6 100644 --- a/ui/easydiffusion/task_manager.py +++ b/ui/easydiffusion/task_manager.py @@ -336,6 +336,7 @@ def thread_render(device): current_state = ServerStates.LoadingModel model_manager.resolve_model_paths(task.task_data) model_manager.reload_models_if_necessary(renderer.context, task.task_data) + model_manager.fail_if_models_did_not_load(renderer.context) current_state = ServerStates.Rendering task.response = renderer.make_images( From db265309a57d576f2ec08433c56c33b8f8bb27a4 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 24 May 2023 16:24:29 +0530 Subject: [PATCH 46/61] Show an explanation for why the CPU toggle is disabled; utility class for alert() and confirm() that matches the ED theme; code formatting --- ui/media/js/main.js | 19 +++------ ui/media/js/parameters.js | 19 +++++++-- ui/media/js/utils.js | 90 +++++++++++++++++++++++++-------------- 3 files changed, 79 insertions(+), 49 deletions(-) diff --git a/ui/media/js/main.js b/ui/media/js/main.js index 473ed780..ecd8ad73 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -261,20 +261,11 @@ function shiftOrConfirm(e, prompt, fn) { if (e.shiftKey || !confirmDangerousActionsField.checked) { fn(e) } else { - $.confirm({ - theme: "modern", - title: prompt, - useBootstrap: false, - animateFromElement: false, - content: - 'Tip: To skip this dialog, use shift-click or disable the "Confirm dangerous actions" setting in the Settings tab.', - buttons: { - yes: () => { - fn(e) - }, - cancel: () => {}, - }, - }) + confirm( + 'Tip: To skip this dialog, use shift-click or disable the "Confirm dangerous actions" setting in the Settings tab.', + prompt, + fn + ) } } diff --git a/ui/media/js/parameters.js b/ui/media/js/parameters.js index f51b5290..4c7240eb 100644 --- a/ui/media/js/parameters.js +++ b/ui/media/js/parameters.js @@ -191,7 +191,8 @@ var PARAMETERS = [ id: "listen_port", type: ParameterType.custom, label: "Network port", - note: "Port that this server listens to. The '9000' part in 'http://localhost:9000'. Please restart the program after changing this.", + note: + "Port that this server listens to. The '9000' part in 'http://localhost:9000'. Please restart the program after changing this.", icon: "fa-anchor", render: (parameter) => { return `` @@ -396,14 +397,14 @@ async function getAppConfig() { document.querySelector("#lora_model_container").style.display = "none" document.querySelector("#lora_alpha_container").style.display = "none" - document.querySelectorAll("#sampler_name option.diffusers-only").forEach(option => { + document.querySelectorAll("#sampler_name option.diffusers-only").forEach((option) => { option.style.display = "none" }) } else { document.querySelector("#lora_model_container").style.display = "" document.querySelector("#lora_alpha_container").style.display = loraModelField.value ? "" : "none" - document.querySelectorAll("#sampler_name option.k_diffusion-only").forEach(option => { + document.querySelectorAll("#sampler_name option.k_diffusion-only").forEach((option) => { option.disabled = true }) document.querySelector("#clip_skip_config").classList.remove("displayNone") @@ -568,6 +569,16 @@ async function getSystemInfo() { if (allDeviceIds.length === 0) { useCPUField.checked = true useCPUField.disabled = true // no compatible GPUs, so make the CPU mandatory + + getParameterSettingsEntry("use_cpu").addEventListener("click", function() { + alert( + "Sorry, we could not find a compatible graphics card! Easy Diffusion supports graphics cards with minimum 2 GB of RAM. " + + "Only NVIDIA cards are supported on Windows. NVIDIA and AMD cards are supported on Linux.

    " + + "If you have a compatible graphics card, please try updating to the latest drivers.

    " + + "Only the CPU can be used for generating images, without a compatible graphics card.", + "No compatible graphics card found!" + ) + }) } autoPickGPUsField.checked = devices["config"] === "auto" @@ -586,7 +597,7 @@ async function getSystemInfo() { $("#use_gpus").val(activeDeviceIds) } - document.dispatchEvent(new CustomEvent("system_info_update", { detail: devices})) + document.dispatchEvent(new CustomEvent("system_info_update", { detail: devices })) setHostInfo(res["hosts"]) let force = false if (res["enforce_output_dir"] !== undefined) { diff --git a/ui/media/js/utils.js b/ui/media/js/utils.js index d1578d8e..16778b2d 100644 --- a/ui/media/js/utils.js +++ b/ui/media/js/utils.js @@ -843,57 +843,85 @@ function createTab(request) { /* TOAST NOTIFICATIONS */ function showToast(message, duration = 5000, error = false) { - const toast = document.createElement("div"); - toast.classList.add("toast-notification"); + const toast = document.createElement("div") + toast.classList.add("toast-notification") if (error === true) { - toast.classList.add("toast-notification-error"); + toast.classList.add("toast-notification-error") } - toast.innerHTML = message; - document.body.appendChild(toast); + toast.innerHTML = message + document.body.appendChild(toast) // Set the position of the toast on the screen - const toastCount = document.querySelectorAll(".toast-notification").length; - const toastHeight = toast.offsetHeight; + const toastCount = document.querySelectorAll(".toast-notification").length + const toastHeight = toast.offsetHeight const previousToastsHeight = Array.from(document.querySelectorAll(".toast-notification")) .slice(0, -1) // exclude current toast - .reduce((totalHeight, toast) => totalHeight + toast.offsetHeight + 10, 0); // add 10 pixels for spacing - toast.style.bottom = `${10 + previousToastsHeight}px`; - toast.style.right = "10px"; + .reduce((totalHeight, toast) => totalHeight + toast.offsetHeight + 10, 0) // add 10 pixels for spacing + toast.style.bottom = `${10 + previousToastsHeight}px` + toast.style.right = "10px" // Delay the removal of the toast until animation has completed const removeToast = () => { - toast.classList.add("hide"); + toast.classList.add("hide") const removeTimeoutId = setTimeout(() => { - toast.remove(); + toast.remove() // Adjust the position of remaining toasts - const remainingToasts = document.querySelectorAll(".toast-notification"); - const removedToastBottom = toast.getBoundingClientRect().bottom; - + const remainingToasts = document.querySelectorAll(".toast-notification") + const removedToastBottom = toast.getBoundingClientRect().bottom + remainingToasts.forEach((toast) => { if (toast.getBoundingClientRect().bottom < removedToastBottom) { - toast.classList.add("slide-down"); + toast.classList.add("slide-down") } - }); - + }) + // Wait for the slide-down animation to complete setTimeout(() => { // Remove the slide-down class after the animation has completed - const slidingToasts = document.querySelectorAll(".slide-down"); + const slidingToasts = document.querySelectorAll(".slide-down") slidingToasts.forEach((toast) => { - toast.classList.remove("slide-down"); - }); - + toast.classList.remove("slide-down") + }) + // Adjust the position of remaining toasts again, in case there are multiple toasts being removed at once - const remainingToastsDown = document.querySelectorAll(".toast-notification"); - let heightSoFar = 0; + const remainingToastsDown = document.querySelectorAll(".toast-notification") + let heightSoFar = 0 remainingToastsDown.forEach((toast) => { - toast.style.bottom = `${10 + heightSoFar}px`; - heightSoFar += toast.offsetHeight + 10; // add 10 pixels for spacing - }); - }, 0); // The duration of the slide-down animation (in milliseconds) - }, 500); - }; + toast.style.bottom = `${10 + heightSoFar}px` + heightSoFar += toast.offsetHeight + 10 // add 10 pixels for spacing + }) + }, 0) // The duration of the slide-down animation (in milliseconds) + }, 500) + } // Remove the toast after specified duration - setTimeout(removeToast, duration); + setTimeout(removeToast, duration) +} + +function alert(msg, title) { + title = title || "" + $.alert({ + theme: "modern", + title: title, + useBootstrap: false, + animateFromElement: false, + content: msg, + }) +} + +function confirm(msg, title, fn) { + title = title || "" + $.confirm({ + theme: "modern", + title: title, + useBootstrap: false, + animateFromElement: false, + content: msg, + buttons: { + yes: () => { + fn(e) + }, + cancel: () => {}, + }, + }) } From 3d7e16cfd944540a0e5b9a0f0c8c10b760f6cf7d Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 24 May 2023 16:29:58 +0530 Subject: [PATCH 47/61] changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index d8e5c3f0..a1e49336 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ Our focus continues to remain on an easy installation experience, and an easy user-interface. While still remaining pretty powerful, in terms of features and speed. ### Detailed changelog +* 2.5.38 - 24 May 2023 - Better reporting of errors, and show an explanation if the user cannot disable the "Use CPU" setting. * 2.5.38 - 23 May 2023 - Add Latent Upscaler as another option for upscaling images. Thanks @JeLuf for the implementation of the Latent Upscaler model. * 2.5.37 - 19 May 2023 - (beta-only) Two more samplers: DDPM and DEIS. Also disables the samplers that aren't working yet in the Diffusers version. Thanks @ogmaresca. * 2.5.37 - 19 May 2023 - (beta-only) Support CLIP-Skip. You can set this option under the models dropdown. Thanks @JeLuf. From 3ea74af76d32f005eaed7df6bc9245e99f99ffd6 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Wed, 24 May 2023 19:29:54 +0200 Subject: [PATCH 48/61] Fix confirmation dialog By splitting the confirmation function into two halves, the closure was lost --- ui/media/js/main.js | 2 +- ui/media/js/utils.js | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ui/media/js/main.js b/ui/media/js/main.js index ecd8ad73..fa37600a 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -264,7 +264,7 @@ function shiftOrConfirm(e, prompt, fn) { confirm( 'Tip: To skip this dialog, use shift-click or disable the "Confirm dangerous actions" setting in the Settings tab.', prompt, - fn + () => { fn(e) } ) } } diff --git a/ui/media/js/utils.js b/ui/media/js/utils.js index 16778b2d..6ddb0ae6 100644 --- a/ui/media/js/utils.js +++ b/ui/media/js/utils.js @@ -918,9 +918,7 @@ function confirm(msg, title, fn) { animateFromElement: false, content: msg, buttons: { - yes: () => { - fn(e) - }, + yes: fn, cancel: () => {}, }, }) From 9dfa300083eba3b5f059c889f7c55e6468a27271 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Thu, 25 May 2023 00:16:14 +0200 Subject: [PATCH 49/61] Add seamless tiling support --- ui/easydiffusion/types.py | 1 + ui/index.html | 9 +++++++++ ui/media/js/auto-save.js | 1 + ui/media/js/dnd.js | 8 ++++++++ ui/media/js/engine.js | 3 ++- ui/media/js/main.js | 7 +++++++ 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ui/easydiffusion/types.py b/ui/easydiffusion/types.py index a76f489a..e4426714 100644 --- a/ui/easydiffusion/types.py +++ b/ui/easydiffusion/types.py @@ -23,6 +23,7 @@ class GenerateImageRequest(BaseModel): sampler_name: str = None # "ddim", "plms", "heun", "euler", "euler_a", "dpm2", "dpm2_a", "lms" hypernetwork_strength: float = 0 lora_alpha: float = 0 + tiling: str = "none" # "none", "x", "y", "xy" class TaskData(BaseModel): diff --git a/ui/index.html b/ui/index.html index dc4eb7f0..4814446b 100644 --- a/ui/index.html +++ b/ui/index.html @@ -236,6 +236,15 @@
    + + + Click to learn more about Seamless Tiling +
    - +
    - + Click to learn more about samplers From 69d937e0b1e1eb94855fa2b3b155e8b3b5df3ac4 Mon Sep 17 00:00:00 2001 From: Olivia Godone-Maresca Date: Fri, 26 May 2023 19:51:30 -0400 Subject: [PATCH 57/61] Add tiling and latent upscaler steps to metadata Also fix txt metadata labels when also embedding metadata --- ui/easydiffusion/utils/save_utils.py | 26 ++++++++++++++++---------- ui/media/js/auto-save.js | 1 + ui/media/js/dnd.js | 8 ++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/ui/easydiffusion/utils/save_utils.py b/ui/easydiffusion/utils/save_utils.py index 24b2198c..6a6f7239 100644 --- a/ui/easydiffusion/utils/save_utils.py +++ b/ui/easydiffusion/utils/save_utils.py @@ -30,9 +30,11 @@ TASK_TEXT_MAPPING = { "lora_alpha": "LoRA Strength", "use_hypernetwork_model": "Hypernetwork model", "hypernetwork_strength": "Hypernetwork Strength", + "tiling": "Seamless Tiling", "use_face_correction": "Use Face Correction", "use_upscale": "Use Upscaling", "upscale_amount": "Upscale By", + "latent_upscaler_steps": "Latent Upscaler Steps" } time_placeholders = { @@ -169,21 +171,23 @@ def save_images_to_disk(images: list, filtered_images: list, req: GenerateImageR output_quality=task_data.output_quality, output_lossless=task_data.output_lossless, ) - if task_data.metadata_output_format.lower() in ["json", "txt", "embed"]: - save_dicts( - metadata_entries, - save_dir_path, - file_name=make_filter_filename, - output_format=task_data.metadata_output_format, - file_format=task_data.output_format, - ) + if task_data.metadata_output_format: + for metadata_output_format in task_data.metadata_output_format.split(","): + if metadata_output_format.lower() in ["json", "txt", "embed"]: + save_dicts( + metadata_entries, + save_dir_path, + file_name=make_filter_filename, + output_format=task_data.metadata_output_format, + file_format=task_data.output_format, + ) def get_metadata_entries_for_request(req: GenerateImageRequest, task_data: TaskData): metadata = get_printable_request(req, task_data) # if text, format it in the text format expected by the UI - is_txt_format = task_data.metadata_output_format.lower() == "txt" + is_txt_format = task_data.metadata_output_format and "txt" in task_data.metadata_output_format.lower().split(",") if is_txt_format: metadata = {TASK_TEXT_MAPPING[key]: val for key, val in metadata.items() if key in TASK_TEXT_MAPPING} @@ -215,10 +219,12 @@ def get_printable_request(req: GenerateImageRequest, task_data: TaskData): del metadata["hypernetwork_strength"] if task_data.use_lora_model is None and "lora_alpha" in metadata: del metadata["lora_alpha"] + if task_data.use_upscale is not "latent_upscaler" and "latent_upscaler_steps" in metadata: + del metadata["latent_upscaler_steps"] app_config = app.getConfig() if not app_config.get("test_diffusers", False): - for key in (x for x in ["use_lora_model", "lora_alpha", "clip_skip"] if x in metadata): + for key in (x for x in ["use_lora_model", "lora_alpha", "clip_skip", "tiling", "latent_upscaler_steps"] if x in metadata): del metadata[key] return metadata diff --git a/ui/media/js/auto-save.js b/ui/media/js/auto-save.js index 1424a301..bbcbf9a5 100644 --- a/ui/media/js/auto-save.js +++ b/ui/media/js/auto-save.js @@ -35,6 +35,7 @@ const SETTINGS_IDS_LIST = [ "gfpgan_model", "use_upscale", "upscale_amount", + "latent_upscaler_steps", "block_nsfw", "show_only_filtered_image", "upscale_model", diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index a303301e..09def0b8 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -221,6 +221,14 @@ const TASK_MAPPING = { readUI: () => upscaleAmountField.value, parse: (val) => val, }, + latent_upscaler_steps: { + name: "Latent Upscaler Steps", + setUI: (latent_upscaler_steps) => { + latentUpscalerStepsField.value = latent_upscaler_steps + }, + readUI: () => latentUpscalerStepsField.value, + parse: (val) => val, + }, sampler_name: { name: "Sampler", setUI: (sampler_name) => { From 6826435046421e350c2b92608e61f0e3694a702c Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Sat, 27 May 2023 00:26:25 -0700 Subject: [PATCH 58/61] Fix restore task to UI flow Fixes a regression introduced by https://github.com/cmdr2/stable-diffusion-ui/pull/1304 --- ui/media/js/dnd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index a303301e..bac15bba 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -43,7 +43,6 @@ const TASK_MAPPING = { name: "Prompt", setUI: (prompt) => { promptField.value = prompt - promptField.dispatchEvent(new Event("input")) }, readUI: () => promptField.value, parse: (val) => val, @@ -422,6 +421,7 @@ function restoreTaskToUI(task, fieldsToSkip) { if (!("original_prompt" in task.reqBody)) { promptField.value = task.reqBody.prompt } + promptField.dispatchEvent(new Event("input")) // properly reset checkboxes if (!("use_face_correction" in task.reqBody)) { From 30dcc7477f12d22d2dc8b17b9c61fc80e3e56bc7 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Sun, 28 May 2023 01:43:58 +0200 Subject: [PATCH 59/61] Fix GFPGAN settings import The word None which many txt metadata files contain as value for the GFPGAN field should not be considered to be a model name. If the value is None, disable the checkbox --- ui/media/js/dnd.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index 8b66a3a4..f8fd8ccc 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -172,16 +172,22 @@ const TASK_MAPPING = { name: "Use Face Correction", setUI: (use_face_correction) => { const oldVal = gfpganModelField.value - gfpganModelField.value = getModelPath(use_face_correction, [".pth"]) - if (gfpganModelField.value) { - // Is a valid value for the field. - useFaceCorrectionField.checked = true - gfpganModelField.disabled = false - } else { - // Not a valid value, restore the old value and disable the filter. + console.log("use face correction", use_face_correction) + if (use_face_correction == null || use_face_correction == "None") { gfpganModelField.disabled = true - gfpganModelField.value = oldVal useFaceCorrectionField.checked = false + } else { + gfpganModelField.value = getModelPath(use_face_correction, [".pth"]) + if (gfpganModelField.value) { + // Is a valid value for the field. + useFaceCorrectionField.checked = true + gfpganModelField.disabled = false + } else { + // Not a valid value, restore the old value and disable the filter. + gfpganModelField.disabled = true + gfpganModelField.value = oldVal + useFaceCorrectionField.checked = false + } } //useFaceCorrectionField.checked = parseBoolean(use_face_correction) From 7202ffba6e9645cbbd4e668e475ca3bbfb1a7d41 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Sun, 28 May 2023 02:36:56 +0200 Subject: [PATCH 60/61] Fix #1312 - invert model A and B ratio in merge --- ui/plugins/ui/merge.plugin.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/ui/plugins/ui/merge.plugin.js b/ui/plugins/ui/merge.plugin.js index 5ce97b2d..d3ddedbf 100644 --- a/ui/plugins/ui/merge.plugin.js +++ b/ui/plugins/ui/merge.plugin.js @@ -403,16 +403,19 @@ // Batch main loop for (let i = 0; i < iterations; i++) { let alpha = (start + i * step) / 100 - switch (document.querySelector("#merge-interpolation").value) { - case "SmoothStep": - alpha = smoothstep(alpha) - break - case "SmootherStep": - alpha = smootherstep(alpha) - break - case "SmoothestStep": - alpha = smootheststep(alpha) - break + + if (isTabActive(tabSettingsBatch)) { + switch (document.querySelector("#merge-interpolation").value) { + case "SmoothStep": + alpha = smoothstep(alpha) + break + case "SmootherStep": + alpha = smootherstep(alpha) + break + case "SmoothestStep": + alpha = smootheststep(alpha) + break + } } addLogMessage(`merging batch job ${i + 1}/${iterations}, alpha = ${alpha.toFixed(5)}...`) @@ -420,7 +423,8 @@ request["out_path"] += "-" + alpha.toFixed(5) + "." + document.querySelector("#merge-format").value addLogMessage(`  filename: ${request["out_path"]}`) - request["ratio"] = alpha + // sdkit documentation: "ratio - the ratio of the second model. 1 means only the second model will be used." + request["ratio"] = 1-alpha let res = await fetch("/model/merge", { method: "POST", headers: { "Content-Type": "application/json" }, From 7830ec7ca2b9d4715cd9d2cd9238d2d40f07d619 Mon Sep 17 00:00:00 2001 From: Olivia Godone-Maresca Date: Sun, 28 May 2023 14:39:36 -0400 Subject: [PATCH 61/61] Fix SyntaxWarning on startup Fixes ``` /ssd2/easydiffusion/ui/easydiffusion/utils/save_utils.py:222: SyntaxWarning: "is not" with a literal. Did you mean "!="? if task_data.use_upscale is not "latent_upscaler" and "latent_upscaler_steps" in metadata: ``` --- ui/easydiffusion/utils/save_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/easydiffusion/utils/save_utils.py b/ui/easydiffusion/utils/save_utils.py index 6a6f7239..ff2906a6 100644 --- a/ui/easydiffusion/utils/save_utils.py +++ b/ui/easydiffusion/utils/save_utils.py @@ -219,7 +219,7 @@ def get_printable_request(req: GenerateImageRequest, task_data: TaskData): del metadata["hypernetwork_strength"] if task_data.use_lora_model is None and "lora_alpha" in metadata: del metadata["lora_alpha"] - if task_data.use_upscale is not "latent_upscaler" and "latent_upscaler_steps" in metadata: + if task_data.use_upscale != "latent_upscaler" and "latent_upscaler_steps" in metadata: del metadata["latent_upscaler_steps"] app_config = app.getConfig()