Face Correction (GFPGAN) and Upscaling (RealESRGAN)

GFPGAN and RealESRGAN
This commit is contained in:
cmdr2 2022-09-10 15:12:23 +05:30 committed by GitHub
commit 813e65e586
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 620 additions and 53 deletions

40
CONTRIBUTING.md Normal file
View File

@ -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.

View File

@ -1,3 +1,5 @@
#!/bin/bash
printf "\n\nStable Diffusion UI\n\n" printf "\n\nStable Diffusion UI\n\n"
if [ -f "scripts/config.sh" ]; then if [ -f "scripts/config.sh" ]; then

View File

@ -2,6 +2,9 @@
@copy sd-ui-files\scripts\on_env_start.bat scripts\ /Y @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.
@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 @>nul grep -c "sd_git_cloned" scripts\install_status.txt
@ -60,6 +63,48 @@
@echo conda_sd_env_created >> ..\scripts\install_status.txt @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 @>nul grep -c "conda_sd_ui_deps_installed" ..\scripts\install_status.txt
@if "%ERRORLEVEL%" EQU "0" ( @if "%ERRORLEVEL%" EQU "0" (
echo "Packages necessary for Stable Diffusion UI were already installed" echo "Packages necessary for Stable Diffusion UI were already installed"
@ -86,6 +131,8 @@ call WHERE uvicorn > .tmp
@echo conda_sd_ui_deps_installed >> ..\scripts\install_status.txt @echo conda_sd_ui_deps_installed >> ..\scripts\install_status.txt
) )
@if exist "sd-v1-4.ckpt" ( @if exist "sd-v1-4.ckpt" (
for %%I in ("sd-v1-4.ckpt") do if "%%~zI" EQU "4265380512" ( for %%I in ("sd-v1-4.ckpt") do if "%%~zI" EQU "4265380512" (
echo "Data files (weights) necessary for Stable Diffusion were already downloaded" echo "Data files (weights) necessary for Stable Diffusion were already downloaded"
@ -114,6 +161,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 @>nul grep -c "sd_install_complete" ..\scripts\install_status.txt
@if "%ERRORLEVEL%" NEQ "0" ( @if "%ERRORLEVEL%" NEQ "0" (
@echo sd_weights_downloaded >> ..\scripts\install_status.txt @echo sd_weights_downloaded >> ..\scripts\install_status.txt

View File

@ -1,9 +1,14 @@
#!/bin/bash
cp sd-ui-files/scripts/on_env_start.sh scripts/ cp sd-ui-files/scripts/on_env_start.sh scripts/
source installer/etc/profile.d/conda.sh 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');" 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.
if [ -e "scripts/install_status.txt" ] && [ `grep -c sd_git_cloned scripts/install_status.txt` -gt "0" ]; then 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.." echo "Stable Diffusion's git repository was already installed. Updating.."
@ -60,6 +65,52 @@ else
echo conda_sd_env_created >> ../scripts/install_status.txt echo conda_sd_env_created >> ../scripts/install_status.txt
fi 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 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" echo "Packages necessary for Stable Diffusion UI were already installed"
else else
@ -82,6 +133,8 @@ else
echo conda_sd_ui_deps_installed >> ../scripts/install_status.txt echo conda_sd_ui_deps_installed >> ../scripts/install_status.txt
fi fi
if [ -f "sd-v1-4.ckpt" ]; then if [ -f "sd-v1-4.ckpt" ]; then
model_size=`ls -l sd-v1-4.ckpt | awk '{print $5}'` model_size=`ls -l sd-v1-4.ckpt | awk '{print $5}'`
@ -111,7 +164,106 @@ if [ ! -f "sd-v1-4.ckpt" ]; then
read -p "Press any key to continue" read -p "Press any key to continue"
exit exit
fi 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_weights_downloaded >> ../scripts/install_status.txt
echo sd_install_complete >> ../scripts/install_status.txt echo sd_install_complete >> ../scripts/install_status.txt
fi fi

View File

@ -1,3 +1,5 @@
#!/bin/bash
conda-unpack conda-unpack
source $CONDA_PREFIX/etc/profile.d/conda.sh source $CONDA_PREFIX/etc/profile.d/conda.sh

View File

@ -1,3 +1,5 @@
#!/bin/bash
source installer/bin/activate source installer/bin/activate
conda-unpack conda-unpack

View File

@ -269,7 +269,7 @@
<div id="server-status-color">&nbsp;</div> <div id="server-status-color">&nbsp;</div>
<span id="server-status-msg">Stable Diffusion is starting..</span> <span id="server-status-msg">Stable Diffusion is starting..</span>
</div> </div>
<h1>Stable Diffusion UI <small>v2.09</small></h1> <h1>Stable Diffusion UI <small>v2.1 <span id="updateBranchLabel"></span></small></h1>
</div> </div>
<div id="editor-inputs"> <div id="editor-inputs">
<div id="editor-inputs-prompt" class="row"> <div id="editor-inputs-prompt" class="row">
@ -299,6 +299,16 @@
<div id="editor-settings" class="panel-box"> <div id="editor-settings" class="panel-box">
<h4 class="collapsible">Advanced Settings</h4> <h4 class="collapsible">Advanced Settings</h4>
<ul id="editor-settings-entries" class="collapsible-content"> <ul id="editor-settings-entries" class="collapsible-content">
<li><input id="use_face_correction" name="use_face_correction" type="checkbox" checked> <label for="use_face_correction">Fix incorrect faces and eyes (uses GFPGAN)</label></li>
<li>
<input id="use_upscale" name="use_upscale" type="checkbox"> <label for="use_upscale">Upscale the image to 4x resolution using </label>
<select id="upscale_model" name="upscale_model">
<option value="RealESRGAN_x4plus" selected>RealESRGAN_x4plus</option>
<option value="RealESRGAN_x4plus_anime_6B">RealESRGAN_x4plus_anime_6B</option>
</select>
</li>
<li><input id="show_only_filtered_image" name="show_only_filtered_image" type="checkbox" checked> <label for="show_only_filtered_image">Show only the corrected/upscaled image</label></li>
<br/>
<li><label for="seed">Seed:</label> <input id="seed" name="seed" size="10" value="30000"> <input id="random_seed" name="random_seed" type="checkbox" checked> <label for="random_seed">Random Image</label></li> <li><label for="seed">Seed:</label> <input id="seed" name="seed" size="10" value="30000"> <input id="random_seed" name="random_seed" type="checkbox" checked> <label for="random_seed">Random Image</label></li>
<li><label for="num_outputs_total">Number of images to make:</label> <input id="num_outputs_total" name="num_outputs_total" value="1" size="4"> <label for="num_outputs_parallel">Generate in parallel:</label> <input id="num_outputs_parallel" name="num_outputs_parallel" value="1" size="4"> (images at once)</li> <li><label for="num_outputs_total">Number of images to make:</label> <input id="num_outputs_total" name="num_outputs_total" value="1" size="4"> <label for="num_outputs_parallel">Generate in parallel:</label> <input id="num_outputs_parallel" name="num_outputs_parallel" value="1" size="4"> (images at once)</li>
<li><label for="width">Width:</label> <li><label for="width">Width:</label>
@ -393,6 +403,9 @@ const USE_TURBO_MODE_KEY = "useTurboMode"
const DISK_PATH_KEY = "diskPath" const DISK_PATH_KEY = "diskPath"
const ADVANCED_PANEL_OPEN_KEY = "advancedPanelOpen" const ADVANCED_PANEL_OPEN_KEY = "advancedPanelOpen"
const MODIFIERS_PANEL_OPEN_KEY = "modifiersPanelOpen" 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 HEALTH_PING_INTERVAL = 5 // seconds
const MAX_INIT_IMAGE_DIMENSION = 768 const MAX_INIT_IMAGE_DIMENSION = 768
@ -421,6 +434,11 @@ let diskPathField = document.querySelector('#diskPath')
let useBetaChannelField = document.querySelector("#use_beta_channel") let useBetaChannelField = document.querySelector("#use_beta_channel")
let promptStrengthField = document.querySelector('#prompt_strength') let promptStrengthField = document.querySelector('#prompt_strength')
let promptStrengthValueLabel = document.querySelector('#prompt_strength_value') 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 updateBranchLabel = document.querySelector("#updateBranchLabel")
let makeImageBtn = document.querySelector('#makeImage') let makeImageBtn = document.querySelector('#makeImage')
@ -489,6 +507,18 @@ function isSoundEnabled() {
return getLocalStorageBoolItem(SOUND_ENABLED_KEY, true) 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, true)
}
function isSaveToDiskEnabled() { function isSaveToDiskEnabled() {
return getLocalStorageBoolItem(SAVE_TO_DISK_KEY, false) return getLocalStorageBoolItem(SAVE_TO_DISK_KEY, false)
} }
@ -744,7 +774,7 @@ async function makeImage() {
makeImageBtn.innerHTML = 'Processing..' makeImageBtn.innerHTML = 'Processing..'
makeImageBtn.disabled = true 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 numOutputsTotal = parseInt(numOutputsTotalField.value)
let numOutputsParallel = parseInt(numOutputsParallelField.value) let numOutputsParallel = parseInt(numOutputsParallelField.value)
let batchCount = Math.ceil(numOutputsTotal / numOutputsParallel) let batchCount = Math.ceil(numOutputsTotal / numOutputsParallel)
@ -784,13 +814,25 @@ async function makeImage() {
reqBody['save_to_disk_path'] = diskPathField.value.trim() 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() let time = new Date().getTime()
imagesContainer.innerHTML = '' imagesContainer.innerHTML = ''
let successCount = 0 let successCount = 0
for (let i = 0; i < batchCount; i++) { for (let i = 0; i < batchCount; i++) {
reqBody['seed'] = seed + i reqBody['seed'] = seed + (i * batchSize)
let success = await doMakeImage(reqBody) let success = await doMakeImage(reqBody)
@ -826,13 +868,14 @@ async function makeImage() {
function createFileName() { function createFileName() {
// Most important information is the prompt // 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 seed = seedField.value;
const steps = numInferenceStepsField.value; const steps = numInferenceStepsField.value;
const guidance = guidanceScaleField.value; const guidance = guidanceScaleField.value;
// name and the top level metadata // 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 // add the tags
// let tags = []; // let tags = [];
@ -851,9 +894,9 @@ function createFileName() {
// fileName += `${tagString}`; // fileName += `${tagString}`;
// add the file extension // add the file extension
fileName += `.png`; fileName += `.png`
return fileName; return fileName
} }
@ -863,6 +906,15 @@ soundToggle.checked = isSoundEnabled()
saveToDiskField.checked = isSaveToDiskEnabled() saveToDiskField.checked = isSaveToDiskEnabled()
diskPathField.disabled = !saveToDiskField.checked 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.addEventListener('click', handleBoolSettingChange(USE_CPU_KEY))
useCPUField.checked = isUseCPUEnabled() useCPUField.checked = isUseCPUEnabled()
@ -879,6 +931,11 @@ saveToDiskField.addEventListener('click', function(e) {
handleBoolSettingChange(SAVE_TO_DISK_KEY)(e) handleBoolSettingChange(SAVE_TO_DISK_KEY)(e)
}) })
useUpscalingField.addEventListener('click', function(e) {
upscaleModelField.disabled = !this.checked
handleBoolSettingChange(USE_UPSCALING_KEY)(e)
})
function setPanelOpen(panelHandle) { function setPanelOpen(panelHandle) {
let panelContents = panelHandle.nextElementSibling let panelContents = panelHandle.nextElementSibling
panelHandle.classList.add('active') panelHandle.classList.add('active')
@ -945,6 +1002,7 @@ async function getAppConfig() {
if (config.update_branch === 'beta') { if (config.update_branch === 'beta') {
useBetaChannelField.checked = true useBetaChannelField.checked = true
updateBranchLabel.innerHTML = "(beta)"
} }
console.log('get config status response', config) console.log('get config status response', config)
@ -956,7 +1014,7 @@ async function getAppConfig() {
function checkRandomSeed() { function checkRandomSeed() {
if (randomSeedField.checked) { if (randomSeedField.checked) {
seedField.disabled = true seedField.disabled = true
seedField.value = "random" seedField.value = "0"
} else { } else {
seedField.disabled = false seedField.disabled = false
} }
@ -1184,6 +1242,8 @@ async function init() {
setInterval(healthCheck, HEALTH_PING_INTERVAL * 1000) setInterval(healthCheck, HEALTH_PING_INTERVAL * 1000)
healthCheck() healthCheck()
playSound()
} }
init() init()

View File

@ -152,50 +152,74 @@
"trending on Artstation", "trending on Artstation",
"by Agnes Lawrence Pelton", "by Agnes Lawrence Pelton",
"by Akihito Yoshida", "by Akihito Yoshida",
"by Alex Grey",
"by Alexander Jansson",
"by Alphonse Mucha",
"by Andy Warhol", "by Andy Warhol",
"by Artgerm", "by Artgerm",
"by Asaf Hanuka", "by Asaf Hanuka",
"by Aubrey Beardsley", "by Aubrey Beardsley",
"by Banksy", "by Banksy",
"by Beeple",
"by Ben Enwonwu", "by Ben Enwonwu",
"by Bob Eggleton",
"by Caravaggio Michelangelo Merisi", "by Caravaggio Michelangelo Merisi",
"by Caspar David Friedrich",
"by Chris Foss",
"by Claude Monet", "by Claude Monet",
"by Dan Mumford",
"by David Mann", "by David Mann",
"by Diego Velázquez", "by Diego Velázquez",
"by Disney Animation Studios", "by Disney Animation Studios",
"by Édouard Manet", "by Édouard Manet",
"by Esao Andrews",
"by Frida Kahlo", "by Frida Kahlo",
"by Gediminas Pranckevicius",
"by Georgia O'Keeffe", "by Georgia O'Keeffe",
"by Greg Rutkowski",
"by Gustave Doré",
"by Gustave Klimt",
"by H.R. Giger", "by H.R. Giger",
"by Hayao Miyazaki", "by Hayao Miyazaki",
"by Henri Matisse", "by Henri Matisse",
"by HP Lovecraft",
"by Ivan Shishkin", "by Ivan Shishkin",
"by Jack Kirby",
"by Jackson Pollock", "by Jackson Pollock",
"by James Jean",
"by Jim Burns",
"by Johannes Vermeer", "by Johannes Vermeer",
"by John William Waterhouse", "by John William Waterhouse",
"by Katsushika Hokusai", "by Katsushika Hokusai",
"by Ko Young Hoon", "by Ko Young Hoon",
"by Leonardo da Vinci", "by Leonardo da Vinci",
"by Lisa Frank", "by Lisa Frank",
"by M.C. Escher",
"by Mahmoud Saïd", "by Mahmoud Saïd",
"by Makoto Shinkai", "by Makoto Shinkai",
"by Marc Simonetti",
"by Mark Brooks", "by Mark Brooks",
"by Michelangelo", "by Michelangelo",
"by Paul Klee",
"by Pablo Picasso", "by Pablo Picasso",
"by Paul Klee",
"by Peter Mohrbacher",
"by Pierre-Auguste Renoir", "by Pierre-Auguste Renoir",
"by Pixar Animation Studios", "by Pixar Animation Studios",
"by Rembrandt", "by Rembrandt",
"by Richard Dadd", "by Richard Dadd",
"by Rossdraws", "by Rossdraws",
"by Salvador Dalí",
"by Sam Does Arts", "by Sam Does Arts",
"by Sandro Botticelli", "by Sandro Botticelli",
"by Salvador Dalí", "by Ted Nasmith",
"by Tivadar Csontváry Kosztka",
"by Thomas Kinkade", "by Thomas Kinkade",
"by Yoshitaka Amano", "by Tivadar Csontváry Kosztka",
"by Victo Ngai",
"by Vincent Di Fate",
"by Vincent van Gogh", "by Vincent van Gogh",
"by wlop" "by Wes Anderson",
"by wlop",
"by Yoshitaka Amano"
] ]
], ],
[ [

View File

@ -17,6 +17,9 @@ class Request:
turbo: bool = True turbo: bool = True
use_cpu: bool = False use_cpu: bool = False
use_full_precision: 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): def to_string(self):
return f''' return f'''
@ -30,7 +33,10 @@ class Request:
save_to_disk_path: {self.save_to_disk_path} save_to_disk_path: {self.save_to_disk_path}
turbo: {self.turbo} turbo: {self.turbo}
use_cpu: {self.use_cpu} 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: class Image:
data: str # base64 data: str # base64

View File

@ -16,12 +16,17 @@ from ldm.util import instantiate_from_config
from optimizedSD.optimUtils import split_weighted_subprompts from optimizedSD.optimUtils import split_weighted_subprompts
from transformers import logging from transformers import logging
from gfpgan import GFPGANer
from basicsr.archs.rrdbnet_arch import RRDBNet
from realesrgan import RealESRGANer
import uuid import uuid
logging.set_verbosity_error() logging.set_verbosity_error()
# consts # consts
config_yaml = "optimizedSD/v1-inference.yaml" config_yaml = "optimizedSD/v1-inference.yaml"
filename_regex = re.compile('[^a-zA-Z0-9]')
# api stuff # api stuff
from . import Request, Response, Image as ResponseImage from . import Request, Response, Image as ResponseImage
@ -31,10 +36,16 @@ from io import BytesIO
# local # local
session_id = str(uuid.uuid4())[-8:] session_id = str(uuid.uuid4())[-8:]
ckpt = None ckpt_file = None
gfpgan_file = None
real_esrgan_file = None
model = None model = None
modelCS = None modelCS = None
modelFS = None modelFS = None
model_gfpgan = None
model_real_esrgan = None
model_is_half = False model_is_half = False
model_fs_is_half = False model_fs_is_half = False
device = None device = None
@ -43,25 +54,30 @@ precision = 'autocast'
sampler_plms = None sampler_plms = None
sampler_ddim = None sampler_ddim = None
has_valid_gpu = False
force_full_precision = False force_full_precision = False
try: try:
gpu_name = torch.cuda.get_device_name(torch.cuda.current_device()) gpu_name = torch.cuda.get_device_name(torch.cuda.current_device())
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 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: 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: except:
print('WARNING: No compatible GPU found. Using the CPU, but this will be very slow!')
pass pass
# api 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):
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_file, model, modelCS, modelFS, model_is_half, device, unet_bs, precision, model_fs_is_half
global ckpt, model, modelCS, modelFS, model_is_half, device, unet_bs, precision, model_fs_is_half
ckpt = ckpt_to_use ckpt_file = ckpt_to_use
device = device_to_use device = device_to_use if has_valid_gpu else 'cpu'
precision = precision_to_use if not force_full_precision else 'full' precision = precision_to_use if not force_full_precision else 'full'
unet_bs = unet_bs_to_use 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 = [], [] li, lo = [], []
for key, value in sd.items(): for key, value in sd.items():
sp = key.split(".") sp = key.split(".")
@ -111,20 +127,71 @@ def load_model(ckpt_to_use, device_to_use='cuda', turbo=False, unet_bs_to_use=1,
else: else:
model_fs_is_half = False 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): def mk_img(req: Request):
global modelFS, device global modelFS, device
global model_gfpgan, model_real_esrgan
res = Response() res = Response()
res.images = [] res.images = []
model.turbo = req.turbo model.turbo = req.turbo
if req.use_cpu: if req.use_cpu:
if device != 'cpu':
device = 'cpu' device = 'cpu'
if model_is_half: if model_is_half:
print('reloading model for cpu') load_model_ckpt(ckpt_file, device)
load_model(ckpt, device)
load_model_gfpgan(gfpgan_file)
load_model_real_esrgan(real_esrgan_file)
else: else:
if has_valid_gpu:
prev_device = device
device = 'cuda' device = 'cuda'
if (precision == 'autocast' and (req.use_full_precision or not model_is_half)) or \ if (precision == 'autocast' and (req.use_full_precision or not model_is_half)) or \
@ -132,8 +199,17 @@ def mk_img(req: Request):
(req.init_image is None and model_fs_is_half) 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): (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(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))
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))
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 model.cdevice = device
modelCS.cond_stage_model.device = device modelCS.cond_stage_model.device = device
@ -152,6 +228,9 @@ def mk_img(req: Request):
opt_strength = req.prompt_strength opt_strength = req.prompt_strength
opt_save_to_disk_path = req.save_to_disk_path opt_save_to_disk_path = req.save_to_disk_path
opt_init_img = req.init_image 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' opt_format = 'png'
print(req.to_string(), '\n device', device) print(req.to_string(), '\n device', device)
@ -245,15 +324,11 @@ def mk_img(req: Request):
x_samples_ddim = modelFS.decode_first_stage(x_samples[i].unsqueeze(0)) 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 = 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") x_sample = 255.0 * rearrange(x_sample[0].cpu().numpy(), "c h w -> h w c")
img = Image.fromarray(x_sample.astype(np.uint8)) x_sample = x_sample.astype(np.uint8)
img = Image.fromarray(x_sample)
img_data = img_to_base64_str(img)
res.images.append(ResponseImage(data=img_data, seed=opt_seed))
if opt_save_to_disk_path is not None: if opt_save_to_disk_path is not None:
try: prompt_flattened = filename_regex.sub('_', prompts[0])
prompt_flattened = "_".join(re.split(":| ", prompts[0]))
prompt_flattened = prompt_flattened.replace(',', '')
prompt_flattened = prompt_flattened[:50] prompt_flattened = prompt_flattened[:50]
img_id = str(uuid.uuid4())[-8:] img_id = str(uuid.uuid4())[-8:]
@ -262,12 +337,41 @@ def mk_img(req: Request):
img_out_path = os.path.join(session_out_path, f"{file_path}.{opt_format}") 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") 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}" if not opt_show_only_filtered:
img.save(img_out_path) save_image(img, img_out_path)
with open(meta_out_path, 'w') as f:
f.write(metadata) 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)
except:
print('could not save the file', traceback.format_exc()) 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) + "," seeds += str(opt_seed) + ","
opt_seed += 1 opt_seed += 1
@ -282,6 +386,21 @@ def mk_img(req: Request):
return res 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): 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] 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 return samples_ddim
def gc():
if device == 'cpu':
return
torch.cuda.empty_cache()
torch.cuda.ipc_collect()
# internal # internal
def chunk(it, size): def chunk(it, size):

View File

@ -17,6 +17,7 @@ OUTPUT_DIRNAME = "Stable Diffusion UI" # in the user's home folder
from fastapi import FastAPI, HTTPException from fastapi import FastAPI, HTTPException
from starlette.responses import FileResponse from starlette.responses import FileResponse
from pydantic import BaseModel from pydantic import BaseModel
import logging
from sd_internal import Request, Response from sd_internal import Request, Response
@ -45,6 +46,9 @@ class ImageRequest(BaseModel):
turbo: bool = True turbo: bool = True
use_cpu: bool = False use_cpu: bool = False
use_full_precision: 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): class SetAppConfigRequest(BaseModel):
update_branch: str = "main" update_branch: str = "main"
@ -68,7 +72,7 @@ async def ping():
model_is_loading = True model_is_loading = True
from sd_internal import runtime 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_loaded = True
model_is_loading = False model_is_loading = False
@ -98,6 +102,9 @@ async def image(req : ImageRequest):
r.use_cpu = req.use_cpu r.use_cpu = req.use_cpu
r.use_full_precision = req.use_full_precision r.use_full_precision = req.use_full_precision
r.save_to_disk_path = req.save_to_disk_path 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: try:
res: Response = runtime.mk_img(r) res: Response = runtime.mk_img(r)
@ -168,5 +175,12 @@ def read_modifiers():
def read_home_dir(): def read_home_dir():
return {outpath} 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 # start the browser ui
import webbrowser; webbrowser.open('http://localhost:9000') import webbrowser; webbrowser.open('http://localhost:9000')