From 90a28732af07f64166139535744c9e7a87bc0e5a Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 9 Sep 2022 21:01:15 +0530 Subject: [PATCH 01/11] Revert "Revert "Revert "Revert "Merge branch 'develop' of github.com:cmdr2/stable-diffusion-ui into develop"""" This reverts commit eb6d19a4dc1fb51d977a62b12a42da324b392c56. --- ui/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/index.html b/ui/index.html index 5204a698..2b03ee88 100644 --- a/ui/index.html +++ b/ui/index.html @@ -790,7 +790,7 @@ async function makeImage() { let successCount = 0 for (let i = 0; i < batchCount; i++) { - reqBody['seed'] = seed + i + reqBody['seed'] = seed + (i * batchSize) let success = await doMakeImage(reqBody) From 53533e71e9ed67d51ff95498ed3329b717011e8b Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 9 Sep 2022 21:02:33 +0530 Subject: [PATCH 02/11] Revert "Revert "Revert "Revert "Merge main"""" This reverts commit 9d92174b1d7957d994648f0ba26672fa23701597. --- CONTRIBUTING.md | 40 ++++++++++++++++++++++++++++++++++++++++ Troubleshooting.md | 14 ++++++++++++++ scripts/on_env_start.sh | 2 ++ scripts/on_sd_start.sh | 2 ++ scripts/post_activate.sh | 2 ++ scripts/start.sh | 2 ++ 6 files changed, 62 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..7449d8a6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,40 @@ +Hi there, these instructions are meant for the developers of this project. + +If you only want to use the Stable Diffusion UI, you've downloaded the wrong file. In that case, please download and follow the instructions at https://github.com/cmdr2/stable-diffusion-ui#installation + +Thanks + +# For developers: + +If you would like to contribute to this project, there is a discord for dicussion: +[![Discord Server](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.com/invite/u9yhsFmEkB) + +## Development environment for UI (frontend and server) changes +This is in-flux, but one way to get a development environment running for editing the UI of this project is: +(swap `.sh` or `.bat` in instructions depending on your environment, and be sure to adjust any paths to match where you're working) + +1) `git clone` the repository, e.g. to `/projects/stable-diffusion-ui-repo` +2) Download the pre-built end user archive from the link on github, and extract it, e.g. to `/projects/stable-diffusion-ui-archive` +3) `cd /projects/stable-diffusion-ui-archive` and run the script to set up and start the project, e.g. `start.sh` +4) Check you can view and generate images on `localhost:9000` +5) Close the server, and edit `/projects/stable-diffusion-ui-archive/scripts/on_env_start.sh` +6) Comment out the line near the bottom that copies the `files/ui` folder, e.g. `cp -Rf sd-ui-files/ui ui` for `.sh` or `@xcopy sd-ui-files\ui ui /s /i /Y` for `.bat` +7) Delete the current `ui` folder at `/projects/stable-diffusion-ui-archive/ui` +8) Now make a symlink between the repository clone (where you will be making changes) and this archive (where you will be running stable diffusion): +`ln -s /projects/stable-diffusion-ui-repo/ui /projects/stable-diffusion-ui-archive/ui` +or for Windows +`mklink /D \projects\stable-diffusion-ui-archive\ui \projects\stable-diffusion-ui-repo\ui` (link name first, source repo dir second) +9) Run the archive again `start.sh` and ensure you can still use the UI. +10) Congrats, now any changes you make in your repo `ui` folder are linked to this running archive of the app and can be previewed in the browser. + +Check the `ui/frontend/build/README.md` for instructions on running and building the React code. + +## Development environment for Installer changes +Build the Windows installer using Windows, and the Linux installer using Linux. Don't mix the two, and don't use WSL. An Ubuntu VM is fine for building the Linux installer on a Windows host. + +1. Install Miniconda 3 or Anaconda. +2. Install `conda install -c conda-forge -y conda-pack` +3. Open the Anaconda Prompt. Do not use WSL if you're building for Windows. +4. Run `build.bat` or `./build.sh` depending on whether you're in Windows or Linux. +5. Compress the `stable-diffusion-ui` folder created inside the `dist` folder. Make a `zip` for Windows, and `tar.xz` for Linux (smaller files, and Linux users already have tar). +6. Make a new GitHub release and upload the Windows and Linux installer builds. diff --git a/Troubleshooting.md b/Troubleshooting.md index e5be9d60..7e807b78 100644 --- a/Troubleshooting.md +++ b/Troubleshooting.md @@ -1,5 +1,19 @@ Common issues and their solutions. If these solutions don't work, please feel free to ask at the [discord server](https://discord.com/invite/u9yhsFmEkB) or [file an issue](https://github.com/cmdr2/stable-diffusion-ui/issues). +## RuntimeError: CUDA out of memory +This can happen if your PC has less than 6GB of VRAM. + +Try disabling the "Turbo mode" setting under "Advanced Settings", since that takes an additional 1 GB of VRAM (to increase the speed). + +Additionally, a common reason for this error is that you're using an initial image larger than 768x768 pixels. Try using a smaller initial image. + +Also try generating smaller sized images. + +## ClobberError: This transaction has incompatible packages due to a shared path +On Windows, please ensure that you had placed the `stable-diffusion-ui` folder after unzipping to the root of C: or D: (or any drive). For e.g. `C:\stable-diffusion-ui`. **Note:** This has to be done **before** you start the installation process. If you have already installed (and are facing this error), please delete the installed folder, and start fresh by unzipping and placing the folder at the top of your drive. + +This error can also be caused if you already have conda/miniconda/anaconda installed, due to package conflicts. Please open your Anaconda Prompt, and run `conda clean --all` to clean up unused packages. + ## Green image generated This usually happens if you're running NVIDIA 1650 or 1660 Super. To solve this, please close and run the Stable Diffusion command on your computer. If you're using the older Docker-based solution (v1), please upgrade to v2: https://github.com/cmdr2/stable-diffusion-ui/tree/v2#installation diff --git a/scripts/on_env_start.sh b/scripts/on_env_start.sh index d314427b..79ab23a7 100755 --- a/scripts/on_env_start.sh +++ b/scripts/on_env_start.sh @@ -1,3 +1,5 @@ +#!/bin/bash + printf "\n\nStable Diffusion UI\n\n" if [ -f "scripts/config.sh" ]; then diff --git a/scripts/on_sd_start.sh b/scripts/on_sd_start.sh index fba9ca63..d78e0597 100755 --- a/scripts/on_sd_start.sh +++ b/scripts/on_sd_start.sh @@ -1,3 +1,5 @@ +#!/bin/bash + cp sd-ui-files/scripts/on_env_start.sh scripts/ source installer/etc/profile.d/conda.sh diff --git a/scripts/post_activate.sh b/scripts/post_activate.sh index 4f0921d2..ec715af0 100755 --- a/scripts/post_activate.sh +++ b/scripts/post_activate.sh @@ -1,3 +1,5 @@ +#!/bin/bash + conda-unpack source $CONDA_PREFIX/etc/profile.d/conda.sh diff --git a/scripts/start.sh b/scripts/start.sh index 407796a6..d6c75ad8 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -1,3 +1,5 @@ +#!/bin/bash + source installer/bin/activate conda-unpack From 65b2c056c6c8dab4ba86d632c85d12f156d966f4 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 9 Sep 2022 21:05:24 +0530 Subject: [PATCH 03/11] Revert "Revert "Revert "Revert "Merge pull request #112 from cmdr2/develop"""" This reverts commit 0dd38870e0f5380c33a26fff31cfa7aef5902aba. --- scripts/on_sd_start.bat | 139 +++++++++++++++++++++++++ scripts/on_sd_start.sh | 150 +++++++++++++++++++++++++++ ui/index.html | 68 ++++++++++++- ui/modifiers.json | 34 ++++++- ui/sd_internal/__init__.py | 8 +- ui/sd_internal/runtime.py | 202 ++++++++++++++++++++++++++++++------- ui/server.py | 16 ++- 7 files changed, 567 insertions(+), 50 deletions(-) diff --git a/scripts/on_sd_start.bat b/scripts/on_sd_start.bat index f5315eda..9c0f6880 100644 --- a/scripts/on_sd_start.bat +++ b/scripts/on_sd_start.bat @@ -2,6 +2,9 @@ @copy sd-ui-files\scripts\on_env_start.bat scripts\ /Y +@REM Caution, this file will make your eyes and brain bleed. It's such an unholy mess. +@REM Note to self: Please rewrite this in Python. For the sake of your own sanity. + @>nul grep -c "sd_git_cloned" scripts\install_status.txt @if "%ERRORLEVEL%" EQU "0" ( @echo "Stable Diffusion's git repository was already installed. Updating.." @@ -58,6 +61,48 @@ @echo conda_sd_env_created >> ..\scripts\install_status.txt ) +@>nul grep -c "conda_sd_gfpgan_deps_installed" ..\scripts\install_status.txt +@if "%ERRORLEVEL%" EQU "0" ( + @echo "Packages necessary for GFPGAN (Face Correction) were already installed" +) else ( + @echo. & echo "Downloading packages necessary for GFPGAN (Face Correction).." & echo. + + @call pip install -e git+https://github.com/TencentARC/GFPGAN#egg=GFPGAN || ( + @echo. & echo "Error installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) + + for /f "tokens=*" %%a in ('python -c "from gfpgan import GFPGANer; print(42)"') do if "%%a" NEQ "42" ( + @echo. & echo "Dependency test failed! Error installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) + + @echo conda_sd_gfpgan_deps_installed >> ..\scripts\install_status.txt +) + +@>nul grep -c "conda_sd_esrgan_deps_installed" ..\scripts\install_status.txt +@if "%ERRORLEVEL%" EQU "0" ( + @echo "Packages necessary for ESRGAN (Resolution Upscaling) were already installed" +) else ( + @echo. & echo "Downloading packages necessary for ESRGAN (Resolution Upscaling).." & echo. + + @call pip install -e git+https://github.com/xinntao/Real-ESRGAN#egg=realesrgan || ( + @echo. & echo "Error installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) + + for /f "tokens=*" %%a in ('python -c "from basicsr.archs.rrdbnet_arch import RRDBNet; from realesrgan import RealESRGANer; print(42)"') do if "%%a" NEQ "42" ( + @echo. & echo "Dependency test failed! Error installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) + + @echo conda_sd_esrgan_deps_installed >> ..\scripts\install_status.txt +) + @>nul grep -c "conda_sd_ui_deps_installed" ..\scripts\install_status.txt @if "%ERRORLEVEL%" EQU "0" ( echo "Packages necessary for Stable Diffusion UI were already installed" @@ -84,6 +129,8 @@ call WHERE uvicorn > .tmp @echo conda_sd_ui_deps_installed >> ..\scripts\install_status.txt ) + + @if exist "sd-v1-4.ckpt" ( for %%I in ("sd-v1-4.ckpt") do if "%%~zI" EQU "4265380512" ( echo "Data files (weights) necessary for Stable Diffusion were already downloaded" @@ -112,6 +159,98 @@ call WHERE uvicorn > .tmp ) ) + + +@if exist "GFPGANv1.3.pth" ( + for %%I in ("GFPGANv1.3.pth") do if "%%~zI" EQU "348632874" ( + echo "Data files (weights) necessary for GFPGAN (Face Correction) were already downloaded" + ) else ( + echo. & echo "The GFPGAN model file present at %cd%\GFPGANv1.3.pth is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo. + del "GFPGANv1.3.pth" + ) +) + +@if not exist "GFPGANv1.3.pth" ( + @echo. & echo "Downloading data files (weights) for GFPGAN (Face Correction).." & echo. + + @call curl -L -k https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth > GFPGANv1.3.pth + + @if exist "GFPGANv1.3.pth" ( + for %%I in ("GFPGANv1.3.pth") do if "%%~zI" NEQ "348632874" ( + echo. & echo "Error: The downloaded GFPGAN model file was invalid! Bytes downloaded: %%~zI" & echo. + echo. & echo "Error downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) + ) else ( + @echo. & echo "Error downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) +) + + + +@if exist "RealESRGAN_x4plus.pth" ( + for %%I in ("RealESRGAN_x4plus.pth") do if "%%~zI" EQU "67040989" ( + echo "Data files (weights) necessary for ESRGAN (Resolution Upscaling) x4plus were already downloaded" + ) else ( + echo. & echo "The GFPGAN model file present at %cd%\RealESRGAN_x4plus.pth is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo. + del "RealESRGAN_x4plus.pth" + ) +) + +@if not exist "RealESRGAN_x4plus.pth" ( + @echo. & echo "Downloading data files (weights) for ESRGAN (Resolution Upscaling) x4plus.." & echo. + + @call curl -L -k https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth > RealESRGAN_x4plus.pth + + @if exist "RealESRGAN_x4plus.pth" ( + for %%I in ("RealESRGAN_x4plus.pth") do if "%%~zI" NEQ "67040989" ( + echo. & echo "Error: The downloaded ESRGAN x4plus model file was invalid! Bytes downloaded: %%~zI" & echo. + echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) + ) else ( + @echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) +) + + + +@if exist "RealESRGAN_x4plus_anime_6B.pth" ( + for %%I in ("RealESRGAN_x4plus_anime_6B.pth") do if "%%~zI" EQU "17938799" ( + echo "Data files (weights) necessary for ESRGAN (Resolution Upscaling) x4plus_anime were already downloaded" + ) else ( + echo. & echo "The GFPGAN model file present at %cd%\RealESRGAN_x4plus_anime_6B.pth is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo. + del "RealESRGAN_x4plus_anime_6B.pth" + ) +) + +@if not exist "RealESRGAN_x4plus_anime_6B.pth" ( + @echo. & echo "Downloading data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime.." & echo. + + @call curl -L -k https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth > RealESRGAN_x4plus_anime_6B.pth + + @if exist "RealESRGAN_x4plus_anime_6B.pth" ( + for %%I in ("RealESRGAN_x4plus_anime_6B.pth") do if "%%~zI" NEQ "17938799" ( + echo. & echo "Error: The downloaded ESRGAN x4plus_anime model file was invalid! Bytes downloaded: %%~zI" & echo. + echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) + ) else ( + @echo. & echo "Error downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" & echo. + pause + exit /b + ) +) + + + @>nul grep -c "sd_install_complete" ..\scripts\install_status.txt @if "%ERRORLEVEL%" NEQ "0" ( @echo sd_weights_downloaded >> ..\scripts\install_status.txt diff --git a/scripts/on_sd_start.sh b/scripts/on_sd_start.sh index d78e0597..36d2c9e3 100755 --- a/scripts/on_sd_start.sh +++ b/scripts/on_sd_start.sh @@ -4,6 +4,9 @@ cp sd-ui-files/scripts/on_env_start.sh scripts/ source installer/etc/profile.d/conda.sh +# Caution, this file will make your eyes and brain bleed. It's such an unholy mess. +# Note to self: Please rewrite this in Python. For the sake of your own sanity. + if [ -e "scripts/install_status.txt" ] && [ `grep -c sd_git_cloned scripts/install_status.txt` -gt "0" ]; then echo "Stable Diffusion's git repository was already installed. Updating.." @@ -60,6 +63,52 @@ else echo conda_sd_env_created >> ../scripts/install_status.txt fi +if [ `grep -c conda_sd_gfpgan_deps_installed ../scripts/install_status.txt` -gt "0" ]; then + echo "Packages necessary for GFPGAN (Face Correction) were already installed" +else + printf "\n\nDownloading packages necessary for GFPGAN (Face Correction)..\n" + + if pip install -e git+https://github.com/TencentARC/GFPGAN#egg=GFPGAN ; then + echo "Installed. Testing.." + else + printf "\n\nError installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi + + out_test=`python -c "from gfpgan import GFPGANer; print(42)"` + if [ "$out_test" != "42" ]; then + printf "\n\nDependency test failed! Error installing the packages necessary for GFPGAN (Face Correction). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi + + echo conda_sd_gfpgan_deps_installed >> ../scripts/install_status.txt +fi + +if [ `grep -c conda_sd_esrgan_deps_installed ../scripts/install_status.txt` -gt "0" ]; then + echo "Packages necessary for ESRGAN (Resolution Upscaling) were already installed" +else + printf "\n\nDownloading packages necessary for ESRGAN (Resolution Upscaling)..\n" + + if pip install -e git+https://github.com/xinntao/Real-ESRGAN#egg=realesrgan ; then + echo "Installed. Testing.." + else + printf "\n\nError installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi + + out_test=`python -c "from basicsr.archs.rrdbnet_arch import RRDBNet; from realesrgan import RealESRGANer; print(42)"` + if [ "$out_test" != "42" ]; then + printf "\n\nDependency test failed! Error installing the packages necessary for ESRGAN (Resolution Upscaling). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi + + echo conda_sd_esrgan_deps_installed >> ../scripts/install_status.txt +fi + if [ `grep -c conda_sd_ui_deps_installed ../scripts/install_status.txt` -gt "0" ]; then echo "Packages necessary for Stable Diffusion UI were already installed" else @@ -82,6 +131,8 @@ else echo conda_sd_ui_deps_installed >> ../scripts/install_status.txt fi + + if [ -f "sd-v1-4.ckpt" ]; then model_size=`ls -l sd-v1-4.ckpt | awk '{print $5}'` @@ -111,7 +162,106 @@ if [ ! -f "sd-v1-4.ckpt" ]; then read -p "Press any key to continue" exit fi +fi + +if [ -f "GFPGANv1.3.pth" ]; then + model_size=`ls -l GFPGANv1.3.pth | awk '{print $5}'` + + if [ "$model_size" -eq "348632874" ]; then + echo "Data files (weights) necessary for GFPGAN (Face Correction) were already downloaded" + else + printf "\n\nThe model file present at $PWD/GFPGANv1.3.pth is invalid. It is only $model_size bytes in size. Re-downloading.." + rm GFPGANv1.3.pth + fi +fi + +if [ ! -f "GFPGANv1.3.pth" ]; then + echo "Downloading data files (weights) for GFPGAN (Face Correction).." + + curl -L -k https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth > GFPGANv1.3.pth + + if [ -f "GFPGANv1.3.pth" ]; then + model_size=`ls -l GFPGANv1.3.pth | awk '{print $5}'` + if [ ! "$model_size" -eq "348632874" ]; then + printf "\n\nError: The downloaded GFPGAN model file was invalid! Bytes downloaded: $model_size\n\n" + printf "\n\nError downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi + else + printf "\n\nError downloading the data files (weights) for GFPGAN (Face Correction). Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi +fi + + +if [ -f "RealESRGAN_x4plus.pth" ]; then + model_size=`ls -l RealESRGAN_x4plus.pth | awk '{print $5}'` + + if [ "$model_size" -eq "67040989" ]; then + echo "Data files (weights) necessary for ESRGAN (Resolution Upscaling) x4plus were already downloaded" + else + printf "\n\nThe model file present at $PWD/RealESRGAN_x4plus.pth is invalid. It is only $model_size bytes in size. Re-downloading.." + rm RealESRGAN_x4plus.pth + fi +fi + +if [ ! -f "RealESRGAN_x4plus.pth" ]; then + echo "Downloading data files (weights) for ESRGAN (Resolution Upscaling) x4plus.." + + curl -L -k https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth > RealESRGAN_x4plus.pth + + if [ -f "RealESRGAN_x4plus.pth" ]; then + model_size=`ls -l RealESRGAN_x4plus.pth | awk '{print $5}'` + if [ ! "$model_size" -eq "67040989" ]; then + printf "\n\nError: The downloaded ESRGAN x4plus model file was invalid! Bytes downloaded: $model_size\n\n" + printf "\n\nError downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi + else + printf "\n\nError downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi +fi + + +if [ -f "RealESRGAN_x4plus_anime_6B.pth" ]; then + model_size=`ls -l RealESRGAN_x4plus_anime_6B.pth | awk '{print $5}'` + + if [ "$model_size" -eq "17938799" ]; then + echo "Data files (weights) necessary for ESRGAN (Resolution Upscaling) x4plus_anime were already downloaded" + else + printf "\n\nThe model file present at $PWD/RealESRGAN_x4plus_anime_6B.pth is invalid. It is only $model_size bytes in size. Re-downloading.." + rm RealESRGAN_x4plus_anime_6B.pth + fi +fi + +if [ ! -f "RealESRGAN_x4plus_anime_6B.pth" ]; then + echo "Downloading data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime.." + + curl -L -k https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth > RealESRGAN_x4plus_anime_6B.pth + + if [ -f "RealESRGAN_x4plus_anime_6B.pth" ]; then + model_size=`ls -l RealESRGAN_x4plus_anime_6B.pth | awk '{print $5}'` + if [ ! "$model_size" -eq "17938799" ]; then + printf "\n\nError: The downloaded ESRGAN x4plus_anime model file was invalid! Bytes downloaded: $model_size\n\n" + printf "\n\nError downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi + else + printf "\n\nError downloading the data files (weights) for ESRGAN (Resolution Upscaling) x4plus_anime. Sorry about that, please try to:\n 1. Run this installer again.\n 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md\n 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB\n 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues\nThanks!\n\n" + read -p "Press any key to continue" + exit + fi +fi + + +if [ `grep -c sd_install_complete ../scripts/install_status.txt` -gt "0" ]; then echo sd_weights_downloaded >> ../scripts/install_status.txt echo sd_install_complete >> ../scripts/install_status.txt fi diff --git a/ui/index.html b/ui/index.html index 2b03ee88..0bda4254 100644 --- a/ui/index.html +++ b/ui/index.html @@ -269,7 +269,7 @@
 
Stable Diffusion is starting.. -

Stable Diffusion UI v2.09

+

Stable Diffusion UI v2.1 (beta)

@@ -299,6 +299,16 @@

Advanced Settings

    +
  • +
  • + + +
  • +
  • +
  • (images at once)
  • @@ -393,6 +403,9 @@ const USE_TURBO_MODE_KEY = "useTurboMode" const DISK_PATH_KEY = "diskPath" const ADVANCED_PANEL_OPEN_KEY = "advancedPanelOpen" const MODIFIERS_PANEL_OPEN_KEY = "modifiersPanelOpen" +const USE_FACE_CORRECTION_KEY = "useFaceCorrection" +const USE_UPSCALING_KEY = "useUpscaling" +const SHOW_ONLY_FILTERED_IMAGE_KEY = "showOnlyFilteredImage" const HEALTH_PING_INTERVAL = 5 // seconds const MAX_INIT_IMAGE_DIMENSION = 768 @@ -421,6 +434,10 @@ let diskPathField = document.querySelector('#diskPath') let useBetaChannelField = document.querySelector("#use_beta_channel") let promptStrengthField = document.querySelector('#prompt_strength') let promptStrengthValueLabel = document.querySelector('#prompt_strength_value') +let useFaceCorrectionField = document.querySelector("#use_face_correction") +let useUpscalingField = document.querySelector("#use_upscale") +let upscaleModelField = document.querySelector("#upscale_model") +let showOnlyFilteredImageField = document.querySelector("#show_only_filtered_image") let makeImageBtn = document.querySelector('#makeImage') @@ -489,6 +506,18 @@ function isSoundEnabled() { return getLocalStorageBoolItem(SOUND_ENABLED_KEY, true) } +function isFaceCorrectionEnabled() { + return getLocalStorageBoolItem(USE_FACE_CORRECTION_KEY, false) +} + +function isUpscalingEnabled() { + return getLocalStorageBoolItem(USE_UPSCALING_KEY, false) +} + +function isShowOnlyFilteredImageEnabled() { + return getLocalStorageBoolItem(SHOW_ONLY_FILTERED_IMAGE_KEY, false) +} + function isSaveToDiskEnabled() { return getLocalStorageBoolItem(SAVE_TO_DISK_KEY, false) } @@ -784,6 +813,18 @@ async function makeImage() { reqBody['save_to_disk_path'] = diskPathField.value.trim() } + if (useFaceCorrectionField.checked) { + reqBody['use_face_correction'] = 'GFPGANv1.3' + } + + if (useUpscalingField.checked) { + reqBody['use_upscale'] = upscaleModelField.value + } + + if (showOnlyFilteredImageField.checked && (useUpscalingField.checked || useFaceCorrectionField.checked)) { + reqBody['show_only_filtered_image'] = showOnlyFilteredImageField.checked + } + let time = new Date().getTime() imagesContainer.innerHTML = '' @@ -826,13 +867,14 @@ async function makeImage() { function createFileName() { // Most important information is the prompt - const underscoreName = lastPromptUsed.replace(/[^a-zA-Z0-9]/g, '_'); + let underscoreName = lastPromptUsed.replace(/[^a-zA-Z0-9]/g, '_') + underscoreName = underscoreName.substring(0, 100) const seed = seedField.value; const steps = numInferenceStepsField.value; const guidance = guidanceScaleField.value; // name and the top level metadata - let fileName = `sd_${underscoreName}_Seed-${seed}_Steps-${steps}_Guidance-${guidance}`; + let fileName = `${underscoreName}_Seed-${seed}_Steps-${steps}_Guidance-${guidance}` // add the tags // let tags = []; @@ -851,9 +893,9 @@ function createFileName() { // fileName += `${tagString}`; // add the file extension - fileName += `.png`; + fileName += `.png` - return fileName; + return fileName } @@ -863,6 +905,15 @@ soundToggle.checked = isSoundEnabled() saveToDiskField.checked = isSaveToDiskEnabled() diskPathField.disabled = !saveToDiskField.checked +useFaceCorrectionField.addEventListener('click', handleBoolSettingChange(USE_FACE_CORRECTION_KEY)) +useFaceCorrectionField.checked = isFaceCorrectionEnabled() + +useUpscalingField.checked = isUpscalingEnabled() +upscaleModelField.disabled = !useUpscalingField.checked + +showOnlyFilteredImageField.addEventListener('click', handleBoolSettingChange(SHOW_ONLY_FILTERED_IMAGE_KEY)) +showOnlyFilteredImageField.checked = isShowOnlyFilteredImageEnabled() + useCPUField.addEventListener('click', handleBoolSettingChange(USE_CPU_KEY)) useCPUField.checked = isUseCPUEnabled() @@ -879,6 +930,11 @@ saveToDiskField.addEventListener('click', function(e) { handleBoolSettingChange(SAVE_TO_DISK_KEY)(e) }) +useUpscalingField.addEventListener('click', function(e) { + upscaleModelField.disabled = !this.checked + handleBoolSettingChange(USE_UPSCALING_KEY)(e) +}) + function setPanelOpen(panelHandle) { let panelContents = panelHandle.nextElementSibling panelHandle.classList.add('active') @@ -1177,6 +1233,8 @@ async function init() { setInterval(healthCheck, HEALTH_PING_INTERVAL * 1000) healthCheck() + + playSound() } init() diff --git a/ui/modifiers.json b/ui/modifiers.json index ab7131e8..9eb2e7f5 100644 --- a/ui/modifiers.json +++ b/ui/modifiers.json @@ -152,50 +152,74 @@ "trending on Artstation", "by Agnes Lawrence Pelton", "by Akihito Yoshida", + "by Alex Grey", + "by Alexander Jansson", + "by Alphonse Mucha", "by Andy Warhol", "by Artgerm", "by Asaf Hanuka", "by Aubrey Beardsley", "by Banksy", + "by Beeple", "by Ben Enwonwu", + "by Bob Eggleton", "by Caravaggio Michelangelo Merisi", + "by Caspar David Friedrich", + "by Chris Foss", "by Claude Monet", + "by Dan Mumford", "by David Mann", "by Diego Velázquez", "by Disney Animation Studios", "by Édouard Manet", + "by Esao Andrews", "by Frida Kahlo", + "by Gediminas Pranckevicius", "by Georgia O'Keeffe", + "by Greg Rutkowski", + "by Gustave Doré", + "by Gustave Klimt", "by H.R. Giger", "by Hayao Miyazaki", "by Henri Matisse", + "by HP Lovecraft", "by Ivan Shishkin", + "by Jack Kirby", "by Jackson Pollock", + "by James Jean", + "by Jim Burns", "by Johannes Vermeer", "by John William Waterhouse", "by Katsushika Hokusai", "by Ko Young Hoon", "by Leonardo da Vinci", "by Lisa Frank", + "by M.C. Escher", "by Mahmoud Saïd", "by Makoto Shinkai", + "by Marc Simonetti", "by Mark Brooks", "by Michelangelo", - "by Paul Klee", "by Pablo Picasso", + "by Paul Klee", + "by Peter Mohrbacher", "by Pierre-Auguste Renoir", "by Pixar Animation Studios", "by Rembrandt", "by Richard Dadd", "by Rossdraws", + "by Salvador Dalí", "by Sam Does Arts", "by Sandro Botticelli", - "by Salvador Dalí", - "by Tivadar Csontváry Kosztka", + "by Ted Nasmith", "by Thomas Kinkade", - "by Yoshitaka Amano", + "by Tivadar Csontváry Kosztka", + "by Victo Ngai", + "by Vincent Di Fate", "by Vincent van Gogh", - "by wlop" + "by Wes Anderson", + "by wlop", + "by Yoshitaka Amano" ] ], [ diff --git a/ui/sd_internal/__init__.py b/ui/sd_internal/__init__.py index ec4c54b7..a85aca9e 100644 --- a/ui/sd_internal/__init__.py +++ b/ui/sd_internal/__init__.py @@ -17,6 +17,9 @@ class Request: turbo: bool = True use_cpu: bool = False use_full_precision: bool = False + use_face_correction: str = None # or "GFPGANv1.3" + use_upscale: str = None # or "RealESRGAN_x4plus" or "RealESRGAN_x4plus_anime_6B" + show_only_filtered_image: bool = False def to_string(self): return f''' @@ -30,7 +33,10 @@ class Request: save_to_disk_path: {self.save_to_disk_path} turbo: {self.turbo} use_cpu: {self.use_cpu} - use_full_precision: {self.use_full_precision}''' + use_full_precision: {self.use_full_precision} + use_face_correction: {self.use_face_correction} + use_upscale: {self.use_upscale} + show_only_filtered_image: {self.show_only_filtered_image}''' class Image: data: str # base64 diff --git a/ui/sd_internal/runtime.py b/ui/sd_internal/runtime.py index 0999b86d..f0ca6412 100644 --- a/ui/sd_internal/runtime.py +++ b/ui/sd_internal/runtime.py @@ -16,12 +16,17 @@ from ldm.util import instantiate_from_config from optimizedSD.optimUtils import split_weighted_subprompts from transformers import logging +from gfpgan import GFPGANer +from basicsr.archs.rrdbnet_arch import RRDBNet +from realesrgan import RealESRGANer + import uuid logging.set_verbosity_error() # consts config_yaml = "optimizedSD/v1-inference.yaml" +filename_regex = re.compile('[^a-zA-Z0-9]') # api stuff from . import Request, Response, Image as ResponseImage @@ -31,10 +36,16 @@ from io import BytesIO # local session_id = str(uuid.uuid4())[-8:] -ckpt = None +ckpt_file = None +gfpgan_file = None +real_esrgan_file = None + model = None modelCS = None modelFS = None +model_gfpgan = None +model_real_esrgan = None + model_is_half = False model_fs_is_half = False device = None @@ -43,25 +54,30 @@ precision = 'autocast' sampler_plms = None sampler_ddim = None +has_valid_gpu = False force_full_precision = False try: gpu_name = torch.cuda.get_device_name(torch.cuda.current_device()) - force_full_precision = ('nvidia' in gpu_name.lower()) and (' 1660' in gpu_name or ' 1650' in gpu_name) # otherwise these NVIDIA cards create green images + has_valid_gpu = True + force_full_precision = ('nvidia' in gpu_name.lower()) and ('1660' in gpu_name or ' 1650' in gpu_name) # otherwise these NVIDIA cards create green images if force_full_precision: - print('forcing full precision on NVIDIA 16xx cards, to avoid green images') + print('forcing full precision on NVIDIA 16xx cards, to avoid green images. GPU detected: ', gpu_name) except: + print('WARNING: No compatible GPU found. Using the CPU, but this will be very slow!') pass -# api -def load_model(ckpt_to_use, device_to_use='cuda', turbo=False, unet_bs_to_use=1, precision_to_use='autocast', half_model_fs=False): - global ckpt, model, modelCS, modelFS, model_is_half, device, unet_bs, precision, model_fs_is_half +def load_model_ckpt(ckpt_to_use, device_to_use='cuda', turbo=False, unet_bs_to_use=1, precision_to_use='autocast', half_model_fs=False): + global ckpt_file, model, modelCS, modelFS, model_is_half, device, unet_bs, precision, model_fs_is_half - ckpt = ckpt_to_use - device = device_to_use + ckpt_file = ckpt_to_use + device = device_to_use if has_valid_gpu else 'cpu' precision = precision_to_use if not force_full_precision else 'full' unet_bs = unet_bs_to_use - sd = load_model_from_config(f"{ckpt}") + if device == 'cpu': + precision = 'full' + + sd = load_model_from_config(f"{ckpt_file}.ckpt") li, lo = [], [] for key, value in sd.items(): sp = key.split(".") @@ -111,29 +127,89 @@ def load_model(ckpt_to_use, device_to_use='cuda', turbo=False, unet_bs_to_use=1, else: model_fs_is_half = False + print('loaded ', ckpt_file, 'to', device, 'precision', precision) + +def load_model_gfpgan(gfpgan_to_use): + global gfpgan_file, model_gfpgan + + if gfpgan_to_use is None: + return + + gfpgan_file = gfpgan_to_use + model_path = gfpgan_to_use + ".pth" + + if device == 'cpu': + model_gfpgan = GFPGANer(model_path=model_path, upscale=1, arch='clean', channel_multiplier=2, bg_upsampler=None, device=torch.device('cpu')) + else: + model_gfpgan = GFPGANer(model_path=model_path, upscale=1, arch='clean', channel_multiplier=2, bg_upsampler=None, device=torch.device('cuda')) + + print('loaded ', gfpgan_to_use, 'to', device, 'precision', precision) + +def load_model_real_esrgan(real_esrgan_to_use): + global real_esrgan_file, model_real_esrgan + + if real_esrgan_to_use is None: + return + + real_esrgan_file = real_esrgan_to_use + model_path = real_esrgan_to_use + ".pth" + + RealESRGAN_models = { + 'RealESRGAN_x4plus': RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4), + 'RealESRGAN_x4plus_anime_6B': RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=6, num_grow_ch=32, scale=4) + } + + model_to_use = RealESRGAN_models[real_esrgan_to_use] + + if device == 'cpu': + model_real_esrgan = RealESRGANer(scale=2, model_path=model_path, model=model_to_use, pre_pad=0, half=False) # cpu does not support half + model_real_esrgan.device = torch.device('cpu') + model_real_esrgan.model.to('cpu') + else: + model_real_esrgan = RealESRGANer(scale=2, model_path=model_path, model=model_to_use, pre_pad=0, half=model_is_half) + + model_real_esrgan.model.name = real_esrgan_to_use + + print('loaded ', real_esrgan_to_use, 'to', device, 'precision', precision) + def mk_img(req: Request): global modelFS, device + global model_gfpgan, model_real_esrgan res = Response() res.images = [] model.turbo = req.turbo if req.use_cpu: - device = 'cpu' + if device != 'cpu': + device = 'cpu' - if model_is_half: - print('reloading model for cpu') - load_model(ckpt, device) + if model_is_half: + load_model_ckpt(ckpt_file, device) + + load_model_gfpgan(gfpgan_file) + load_model_real_esrgan(real_esrgan_file) else: - device = 'cuda' + if has_valid_gpu: + prev_device = device + device = 'cuda' - if (precision == 'autocast' and (req.use_full_precision or not model_is_half)) or \ - (precision == 'full' and not req.use_full_precision and not force_full_precision) or \ - (req.init_image is None and model_fs_is_half) or \ - (req.init_image is not None and not model_fs_is_half and not force_full_precision): + if (precision == 'autocast' and (req.use_full_precision or not model_is_half)) or \ + (precision == 'full' and not req.use_full_precision and not force_full_precision) or \ + (req.init_image is None and model_fs_is_half) or \ + (req.init_image is not None and not model_fs_is_half and not force_full_precision): - print('reloading model for cuda') - load_model(ckpt, device, model.turbo, unet_bs, ('full' if req.use_full_precision else 'autocast'), half_model_fs=(req.init_image is not None and not req.use_full_precision)) + load_model_ckpt(ckpt_file, device, model.turbo, unet_bs, ('full' if req.use_full_precision else 'autocast'), half_model_fs=(req.init_image is not None and not req.use_full_precision)) + + if prev_device != device: + load_model_gfpgan(gfpgan_file) + load_model_real_esrgan(real_esrgan_file) + + if req.use_face_correction != gfpgan_file: + load_model_gfpgan(req.use_face_correction) + + if req.use_upscale != real_esrgan_file: + load_model_real_esrgan(req.use_upscale) model.cdevice = device modelCS.cond_stage_model.device = device @@ -152,6 +228,9 @@ def mk_img(req: Request): opt_strength = req.prompt_strength opt_save_to_disk_path = req.save_to_disk_path opt_init_img = req.init_image + opt_use_face_correction = req.use_face_correction + opt_use_upscale = req.use_upscale + opt_show_only_filtered = req.show_only_filtered_image opt_format = 'png' print(req.to_string(), '\n device', device) @@ -245,29 +324,54 @@ def mk_img(req: Request): x_samples_ddim = modelFS.decode_first_stage(x_samples[i].unsqueeze(0)) x_sample = torch.clamp((x_samples_ddim + 1.0) / 2.0, min=0.0, max=1.0) x_sample = 255.0 * rearrange(x_sample[0].cpu().numpy(), "c h w -> h w c") - img = Image.fromarray(x_sample.astype(np.uint8)) - - img_data = img_to_base64_str(img) - res.images.append(ResponseImage(data=img_data, seed=opt_seed)) + x_sample = x_sample.astype(np.uint8) + img = Image.fromarray(x_sample) if opt_save_to_disk_path is not None: - try: - prompt_flattened = "_".join(re.split(":| ", prompts[0])) - prompt_flattened = prompt_flattened.replace(',', '') - prompt_flattened = prompt_flattened[:50] + prompt_flattened = filename_regex.sub('_', prompts[0]) + prompt_flattened = prompt_flattened[:50] - img_id = str(uuid.uuid4())[-8:] + img_id = str(uuid.uuid4())[-8:] - file_path = f"{prompt_flattened}_{img_id}" - img_out_path = os.path.join(session_out_path, f"{file_path}.{opt_format}") - meta_out_path = os.path.join(session_out_path, f"{file_path}.txt") + file_path = f"{prompt_flattened}_{img_id}" + img_out_path = os.path.join(session_out_path, f"{file_path}.{opt_format}") + meta_out_path = os.path.join(session_out_path, f"{file_path}.txt") - metadata = f"{prompts[0]}\nWidth: {opt_W}\nHeight: {opt_H}\nSeed: {opt_seed}\nSteps: {opt_ddim_steps}\nGuidance Scale: {opt_scale}" - img.save(img_out_path) - with open(meta_out_path, 'w') as f: - f.write(metadata) - except: - print('could not save the file', traceback.format_exc()) + if not opt_show_only_filtered: + save_image(img, img_out_path) + + save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_strength, opt_use_face_correction, opt_use_upscale) + + if not opt_show_only_filtered: + img_data = img_to_base64_str(img) + res.images.append(ResponseImage(data=img_data, seed=opt_seed)) + + if (opt_use_face_correction is not None and opt_use_face_correction.startswith('GFPGAN')) or \ + (opt_use_upscale is not None and opt_use_upscale.startswith('RealESRGAN')): + + gc() + filters_applied = [] + + if opt_use_face_correction: + _, _, output = model_gfpgan.enhance(x_sample[:,:,::-1], has_aligned=False, only_center_face=False, paste_back=True) + x_sample = output[:,:,::-1] + filters_applied.append(opt_use_face_correction) + + if opt_use_upscale: + output, _ = model_real_esrgan.enhance(x_sample[:,:,::-1]) + x_sample = output[:,:,::-1] + filters_applied.append(opt_use_upscale) + + filtered_image = Image.fromarray(x_sample) + + filtered_img_data = img_to_base64_str(filtered_image) + res.images.append(ResponseImage(data=filtered_img_data, seed=opt_seed)) + + filters_applied = "_".join(filters_applied) + + if opt_save_to_disk_path is not None: + filtered_img_out_path = os.path.join(session_out_path, f"{file_path}_{filters_applied}.{opt_format}") + save_image(filtered_image, filtered_img_out_path) seeds += str(opt_seed) + "," opt_seed += 1 @@ -282,6 +386,21 @@ def mk_img(req: Request): return res +def save_image(img, img_out_path): + try: + img.save(img_out_path) + except: + print('could not save the file', traceback.format_exc()) + +def save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_prompt_strength, opt_correct_face, opt_upscale): + metadata = f"{prompts[0]}\nWidth: {opt_W}\nHeight: {opt_H}\nSeed: {opt_seed}\nSteps: {opt_ddim_steps}\nGuidance Scale: {opt_scale}\nPrompt Strength: {opt_prompt_strength}\nUse Face Correction: {opt_correct_face}\nUse Upscaling: {opt_upscale}" + + try: + with open(meta_out_path, 'w') as f: + f.write(metadata) + except: + print('could not save the file', traceback.format_exc()) + def _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, start_code, opt_C, opt_f, opt_ddim_eta, c, uc, opt_seed): shape = [opt_n_samples, opt_C, opt_H // opt_f, opt_W // opt_f] @@ -327,6 +446,13 @@ def _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, o return samples_ddim +def gc(): + if device == 'cpu': + return + + torch.cuda.empty_cache() + torch.cuda.ipc_collect() + # internal def chunk(it, size): diff --git a/ui/server.py b/ui/server.py index e287f5f1..b2dc13b4 100644 --- a/ui/server.py +++ b/ui/server.py @@ -17,6 +17,7 @@ OUTPUT_DIRNAME = "Stable Diffusion UI" # in the user's home folder from fastapi import FastAPI, HTTPException from starlette.responses import FileResponse from pydantic import BaseModel +import logging from sd_internal import Request, Response @@ -45,6 +46,9 @@ class ImageRequest(BaseModel): turbo: bool = True use_cpu: bool = False use_full_precision: bool = False + use_face_correction: str = None # or "GFPGANv1.3" + use_upscale: str = None # or "RealESRGAN_x4plus" or "RealESRGAN_x4plus_anime_6B" + show_only_filtered_image: bool = False class SetAppConfigRequest(BaseModel): update_branch: str = "main" @@ -67,7 +71,7 @@ async def ping(): model_is_loading = True from sd_internal import runtime - runtime.load_model(ckpt_to_use="sd-v1-4.ckpt") + runtime.load_model_ckpt(ckpt_to_use="sd-v1-4") model_loaded = True model_is_loading = False @@ -97,6 +101,9 @@ async def image(req : ImageRequest): r.use_cpu = req.use_cpu r.use_full_precision = req.use_full_precision r.save_to_disk_path = req.save_to_disk_path + r.use_upscale: str = req.use_upscale + r.use_face_correction = req.use_face_correction + r.show_only_filtered_image = req.show_only_filtered_image try: res: Response = runtime.mk_img(r) @@ -164,5 +171,12 @@ def read_modifiers(): def read_home_dir(): return {outpath} +# don't log /ping requests +class HealthCheckLogFilter(logging.Filter): + def filter(self, record: logging.LogRecord) -> bool: + return record.getMessage().find('/ping') == -1 + +logging.getLogger('uvicorn.access').addFilter(HealthCheckLogFilter()) + # start the browser ui import webbrowser; webbrowser.open('http://localhost:9000') From d21c0bfc18e96e64231daaf14029a72019fde721 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 9 Sep 2022 21:06:51 +0530 Subject: [PATCH 04/11] Invert the logic - show only the filtered image by default --- ui/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/index.html b/ui/index.html index 0bda4254..a6001dbe 100644 --- a/ui/index.html +++ b/ui/index.html @@ -307,7 +307,7 @@
  • -
  • +

  • (images at once)
  • @@ -515,7 +515,7 @@ function isUpscalingEnabled() { } function isShowOnlyFilteredImageEnabled() { - return getLocalStorageBoolItem(SHOW_ONLY_FILTERED_IMAGE_KEY, false) + return getLocalStorageBoolItem(SHOW_ONLY_FILTERED_IMAGE_KEY, true) } function isSaveToDiskEnabled() { From f727dd26ed21c39da62471188dcf8cc23ca0708f Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Fri, 9 Sep 2022 21:11:05 +0530 Subject: [PATCH 05/11] Set the set to 0 if deselecting from random; Allow 10 million random images by increasing the seed size --- ui/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/index.html b/ui/index.html index a6001dbe..444534d9 100644 --- a/ui/index.html +++ b/ui/index.html @@ -773,7 +773,7 @@ async function makeImage() { makeImageBtn.innerHTML = 'Processing..' makeImageBtn.disabled = true - let seed = (randomSeedField.checked ? Math.floor(Math.random() * 10000) : parseInt(seedField.value)) + let seed = (randomSeedField.checked ? Math.floor(Math.random() * 10000000) : parseInt(seedField.value)) let numOutputsTotal = parseInt(numOutputsTotalField.value) let numOutputsParallel = parseInt(numOutputsParallelField.value) let batchCount = Math.ceil(numOutputsTotal / numOutputsParallel) @@ -1005,7 +1005,7 @@ async function getAppConfig() { function checkRandomSeed() { if (randomSeedField.checked) { seedField.disabled = true - seedField.value = "random" + seedField.value = "0" } else { seedField.disabled = false } From 622322c8787df8329fb8246158d0c0e6a8057e8a Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Sat, 10 Sep 2022 00:23:19 +0530 Subject: [PATCH 06/11] Fix --- scripts/on_sd_start.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/on_sd_start.bat b/scripts/on_sd_start.bat index 986d0c91..9eb7600b 100644 --- a/scripts/on_sd_start.bat +++ b/scripts/on_sd_start.bat @@ -5,7 +5,7 @@ @REM Caution, this file will make your eyes and brain bleed. It's such an unholy mess. @REM Note to self: Please rewrite this in Python. For the sake of your own sanity. -@call python -c "import os; import shutil; frm = 'sd-ui-files\ui\hotfix\9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'; dst = os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'transformers', '9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'); shutil.copyfile(frm, dst); print('Hotfixed broken JSON file from OpenAI');" +@call python -c "import os; import shutil; frm = 'sd-ui-files\\ui\hotfix\\9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'; dst = os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'transformers', '9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'); shutil.copyfile(frm, dst); print('Hotfixed broken JSON file from OpenAI');" @>nul grep -c "sd_git_cloned" scripts\install_status.txt @if "%ERRORLEVEL%" EQU "0" ( From a6b4d59d94eac344d6dbfb64823715decb3fba12 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Sat, 10 Sep 2022 00:29:46 +0530 Subject: [PATCH 07/11] Fix unnecessary warning for config.json --- ui/server.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/server.py b/ui/server.py index 5e92a201..3fff7a9c 100644 --- a/ui/server.py +++ b/ui/server.py @@ -148,6 +148,9 @@ def getAppConfig(): try: config_json_path = os.path.join(CONFIG_DIR, 'config.json') + if not os.path.exists(config_json_path): + return HTTPException(status_code=500, detail="No config file") + with open(config_json_path, 'r') as f: config_json_str = f.read() config = json.loads(config_json_str) From cd1db214b069667f4f0505ba70e77cb0112636a4 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Sat, 10 Sep 2022 00:34:51 +0530 Subject: [PATCH 08/11] Fix --- scripts/on_sd_start.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/on_sd_start.bat b/scripts/on_sd_start.bat index 9eb7600b..9f993ec2 100644 --- a/scripts/on_sd_start.bat +++ b/scripts/on_sd_start.bat @@ -5,7 +5,7 @@ @REM Caution, this file will make your eyes and brain bleed. It's such an unholy mess. @REM Note to self: Please rewrite this in Python. For the sake of your own sanity. -@call python -c "import os; import shutil; frm = 'sd-ui-files\\ui\hotfix\\9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'; dst = os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'transformers', '9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'); shutil.copyfile(frm, dst); print('Hotfixed broken JSON file from OpenAI');" +@call python -c "import os; import shutil; frm = 'sd-ui-files\\ui\\hotfix\\9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'; dst = os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'transformers', '9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'); shutil.copyfile(frm, dst); print('Hotfixed broken JSON file from OpenAI');" @>nul grep -c "sd_git_cloned" scripts\install_status.txt @if "%ERRORLEVEL%" EQU "0" ( From 905bcd8d1b5a67b7999d154ae03a449c6e3edf9d Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Sat, 10 Sep 2022 00:37:04 +0530 Subject: [PATCH 09/11] Fix on linux --- scripts/on_sd_start.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/on_sd_start.sh b/scripts/on_sd_start.sh index 36d2c9e3..b50a5546 100755 --- a/scripts/on_sd_start.sh +++ b/scripts/on_sd_start.sh @@ -4,6 +4,8 @@ cp sd-ui-files/scripts/on_env_start.sh scripts/ source installer/etc/profile.d/conda.sh +python -c "import os; import shutil; frm = 'sd-ui-files/ui/hotfix/9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'; dst = os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'transformers', '9c24e6cd9f499d02c4f21a033736dabd365962dc80fe3aeb57a8f85ea45a20a3.26fead7ea4f0f843f6eb4055dfd25693f1a71f3c6871b184042d4b126244e142'); shutil.copyfile(frm, dst); print('Hotfixed broken JSON file from OpenAI');" + # Caution, this file will make your eyes and brain bleed. It's such an unholy mess. # Note to self: Please rewrite this in Python. For the sake of your own sanity. From 9c09a4d393e2cb70baed06d6cdd92cf0d5f3c4c7 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Sat, 10 Sep 2022 01:24:45 +0530 Subject: [PATCH 10/11] Update Troubleshooting.md --- Troubleshooting.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Troubleshooting.md b/Troubleshooting.md index 7e807b78..45eafd95 100644 --- a/Troubleshooting.md +++ b/Troubleshooting.md @@ -9,7 +9,7 @@ Additionally, a common reason for this error is that you're using an initial ima Also try generating smaller sized images. -## ClobberError: This transaction has incompatible packages due to a shared path +## No ldm found, or antlr4 or any other missing module, or ClobberError: This transaction has incompatible packages due to a shared path On Windows, please ensure that you had placed the `stable-diffusion-ui` folder after unzipping to the root of C: or D: (or any drive). For e.g. `C:\stable-diffusion-ui`. **Note:** This has to be done **before** you start the installation process. If you have already installed (and are facing this error), please delete the installed folder, and start fresh by unzipping and placing the folder at the top of your drive. This error can also be caused if you already have conda/miniconda/anaconda installed, due to package conflicts. Please open your Anaconda Prompt, and run `conda clean --all` to clean up unused packages. @@ -19,9 +19,6 @@ This usually happens if you're running NVIDIA 1650 or 1660 Super. To solve this, If you're still seeing this error, please try enabling "Full Precision" under "Advanced Settings" in the Stable Diffusion UI. -## No module found -This can happen if you're hitting the Windows file path length limitation. To solve this, please upgrade to v2 by following the installation steps here: https://github.com/cmdr2/stable-diffusion-ui/tree/v2#installation , and ensure that you've placed the `stable-diffusion-ui` folder in `C:` or `D:` (or any top-level location). - ## './docker-compose.yml' is invalid: > ERROR: The Compose file './docker-compose.yml' is invalid because: > services.stability-ai.deploy.resources.reservations value Additional properties are not allowed ('devices' was unexpected) From 387605f4430c270dc2cf8664f37a05d33001d3e1 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Sat, 10 Sep 2022 15:08:07 +0530 Subject: [PATCH 11/11] Show a label for the update channel, next to the version number --- ui/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/index.html b/ui/index.html index a6b48816..7ed226ec 100644 --- a/ui/index.html +++ b/ui/index.html @@ -269,7 +269,7 @@
     
    Stable Diffusion is starting..
-

Stable Diffusion UI v2.1 (beta)

+

Stable Diffusion UI v2.1

@@ -438,6 +438,7 @@ let useFaceCorrectionField = document.querySelector("#use_face_correction") let useUpscalingField = document.querySelector("#use_upscale") let upscaleModelField = document.querySelector("#upscale_model") let showOnlyFilteredImageField = document.querySelector("#show_only_filtered_image") +let updateBranchLabel = document.querySelector("#updateBranchLabel") let makeImageBtn = document.querySelector('#makeImage') @@ -1001,6 +1002,7 @@ async function getAppConfig() { if (config.update_branch === 'beta') { useBetaChannelField.checked = true + updateBranchLabel.innerHTML = "(beta)" } console.log('get config status response', config)