# This file is part of sygil-webui (https://github.com/Sygil-Dev/sygil-webui/). # Copyright 2022 Sygil-Dev team. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # base webui import and utils. #from webui_streamlit import st import gfpgan import hydralit as st # streamlit imports from streamlit import StopException, StreamlitAPIException #from streamlit.runtime.scriptrunner import script_run_context #streamlit components section from streamlit_server_state import server_state, server_state_lock import hydralit_components as hc from hydralit import HydraHeadApp import streamlit_nested_layout #other imports import warnings import json import base64, cv2 import os, sys, re, random, datetime, time, math, glob, toml import gc from PIL import Image, ImageFont, ImageDraw, ImageFilter from PIL.PngImagePlugin import PngInfo from scipy import integrate import torch from torchdiffeq import odeint import k_diffusion as K import math, requests import mimetypes import numpy as np from numpy import asarray import pynvml import threading import torch, torchvision from torch import autocast from torchvision import transforms import torch.nn as nn from omegaconf import OmegaConf import yaml from pathlib import Path from contextlib import nullcontext from einops import rearrange, repeat from ldm.util import instantiate_from_config from retry import retry from slugify import slugify import skimage import piexif import piexif.helper from tqdm import trange from ldm.models.diffusion.ddim import DDIMSampler from ldm.util import ismap #from abc import ABC, abstractmethod from typing import Dict, Union from io import BytesIO from packaging import version from uuid import uuid4 from pathlib import Path from huggingface_hub import hf_hub_download #import librosa #from logger import logger, set_logger_verbosity, quiesce_logger #from loguru import logger from nataili.inference.compvis.img2img import img2img from nataili.model_manager import ModelManager from nataili.inference.compvis.txt2img import txt2img from nataili.util.cache import torch_gc from nataili.util.logger import logger, set_logger_verbosity, quiesce_logger try: from realesrgan import RealESRGANer from basicsr.archs.rrdbnet_arch import RRDBNet except ImportError as e: logger.error("You tried to import realesrgan without having it installed properly. To install Real-ESRGAN, run:\n\n" "pip install realesrgan") # Temp imports #from basicsr.utils.registry import ARCH_REGISTRY # end of imports #--------------------------------------------------------------------------------------------------------------- try: # this silences the annoying "Some weights of the model checkpoint were not used when initializing..." message at start. from transformers import logging logging.set_verbosity_error() except: pass # remove some annoying deprecation warnings that show every now and then. warnings.filterwarnings("ignore", category=DeprecationWarning) warnings.filterwarnings("ignore", category=UserWarning) # this is a fix for Windows users. Without it, javascript files will be served with text/html content-type and the bowser will not show any UI mimetypes.init() mimetypes.add_type('application/javascript', '.js') # some of those options should not be changed at all because they would break the model, so I removed them from options. opt_C = 4 opt_f = 8 # The model manager loads and unloads the SD models and has features to download them or find their location #model_manager = ModelManager() def load_configs(): if not "defaults" in st.session_state: st.session_state["defaults"] = {} st.session_state["defaults"] = OmegaConf.load("configs/webui/webui_streamlit.yaml") if (os.path.exists("configs/webui/userconfig_streamlit.yaml")): user_defaults = OmegaConf.load("configs/webui/userconfig_streamlit.yaml") if "version" in user_defaults.general: if version.parse(user_defaults.general.version) < version.parse(st.session_state["defaults"].general.version): logger.error("The version of the user config file is older than the version on the defaults config file. " "This means there were big changes we made on the config." "We are removing this file and recreating it from the defaults in order to make sure things work properly.") os.remove("configs/webui/userconfig_streamlit.yaml") st.experimental_rerun() else: logger.error("The version of the user config file is older than the version on the defaults config file. " "This means there were big changes we made on the config." "We are removing this file and recreating it from the defaults in order to make sure things work properly.") os.remove("configs/webui/userconfig_streamlit.yaml") st.experimental_rerun() try: st.session_state["defaults"] = OmegaConf.merge(st.session_state["defaults"], user_defaults) except KeyError: st.experimental_rerun() else: OmegaConf.save(config=st.session_state.defaults, f="configs/webui/userconfig_streamlit.yaml") loaded = OmegaConf.load("configs/webui/userconfig_streamlit.yaml") assert st.session_state.defaults == loaded if (os.path.exists(".streamlit/config.toml")): st.session_state["streamlit_config"] = toml.load(".streamlit/config.toml") if st.session_state["defaults"].daisi_app.running_on_daisi_io: if os.path.exists("scripts/modeldownload.py"): import modeldownload modeldownload.updateModels() if "keep_all_models_loaded" in st.session_state.defaults.general: with server_state_lock["keep_all_models_loaded"]: server_state["keep_all_models_loaded"] = st.session_state["defaults"].general.keep_all_models_loaded else: st.session_state["defaults"].general.keep_all_models_loaded = False with server_state_lock["keep_all_models_loaded"]: server_state["keep_all_models_loaded"] = st.session_state["defaults"].general.keep_all_models_loaded load_configs() # #if st.session_state["defaults"].debug.enable_hydralit: #navbar_theme = {'txc_inactive': '#FFFFFF','menu_background':'#0e1117','txc_active':'black','option_active':'red'} #app = st.HydraApp(title='Stable Diffusion WebUI', favicon="", use_cookie_cache=False, sidebar_state="expanded", layout="wide", navbar_theme=navbar_theme, #hide_streamlit_markers=False, allow_url_nav=True , clear_cross_app_sessions=False, use_loader=False) #else: #app = None # grid_format = st.session_state["defaults"].general.save_format grid_lossless = False grid_quality = st.session_state["defaults"].general.grid_quality if grid_format == 'png': grid_ext = 'png' grid_format = 'png' elif grid_format in ['jpg', 'jpeg']: grid_quality = int(grid_format) if len(grid_format) > 1 else 100 grid_ext = 'jpg' grid_format = 'jpeg' elif grid_format[0] == 'webp': grid_quality = int(grid_format) if len(grid_format) > 1 else 100 grid_ext = 'webp' grid_format = 'webp' if grid_quality < 0: # e.g. webp:-100 for lossless mode grid_lossless = True grid_quality = abs(grid_quality) # save_format = st.session_state["defaults"].general.save_format save_lossless = False save_quality = 100 if save_format == 'png': save_ext = 'png' save_format = 'png' elif save_format in ['jpg', 'jpeg']: save_quality = int(save_format) if len(save_format) > 1 else 100 save_ext = 'jpg' save_format = 'jpeg' elif save_format == 'webp': save_quality = int(save_format) if len(save_format) > 1 else 100 save_ext = 'webp' save_format = 'webp' if save_quality < 0: # e.g. webp:-100 for lossless mode save_lossless = True save_quality = abs(save_quality) # this should force GFPGAN and RealESRGAN onto the selected gpu as well os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID" # see issue #152 os.environ["CUDA_VISIBLE_DEVICES"] = str(st.session_state["defaults"].general.gpu) # functions to load css locally OR remotely starts here. Options exist for future flexibility. Called as st.markdown with unsafe_allow_html as css injection # TODO, maybe look into async loading the file especially for remote fetching def local_css(file_name): with open(file_name) as f: st.markdown(f'', unsafe_allow_html=True) def remote_css(url): st.markdown(f'', unsafe_allow_html=True) def load_css(isLocal, nameOrURL): if(isLocal): local_css(nameOrURL) else: remote_css(nameOrURL) def set_page_title(title): """ Simple function to allows us to change the title dynamically. Normally you can use `st.set_page_config` to change the title but it can only be used once per app. """ st.sidebar.markdown(unsafe_allow_html=True, body=f"""