From 3bd97352ba38745b127de3da1f77559ce34d7e8b Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sat, 29 Oct 2022 14:47:58 -0400 Subject: [PATCH 01/53] Don't reset reqBody, only replace using req as we use a new task object created from UI inputs. Fix plugins needing to specify many params or they would be missing in the render request. --- ui/media/js/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/media/js/main.js b/ui/media/js/main.js index 681c073d..964bc420 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -343,7 +343,7 @@ function onDownloadImageClick(req, img) { function modifyCurrentRequest(req, ...reqDiff) { const newTaskRequest = getCurrentUserRequest() - newTaskRequest.reqBody = Object.assign({}, req, ...reqDiff, { + newTaskRequest.reqBody = Object.assign(newTaskRequest.reqBody, req, ...reqDiff, { use_cpu: useCPUField.checked }) newTaskRequest.seed = newTaskRequest.reqBody.seed From b7a663ed201af4497fad6c15f257c702c246014d Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sat, 29 Oct 2022 17:33:44 -0400 Subject: [PATCH 02/53] Implement complete device selection in the backend. --- ui/sd_internal/__init__.py | 4 +-- ui/sd_internal/runtime.py | 41 +++++++++++++++++++++++-------- ui/sd_internal/task_manager.py | 45 ++++++++++++++++++++++------------ ui/server.py | 8 +++++- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/ui/sd_internal/__init__.py b/ui/sd_internal/__init__.py index 0b159ae7..da5f6b59 100644 --- a/ui/sd_internal/__init__.py +++ b/ui/sd_internal/__init__.py @@ -18,7 +18,6 @@ class Request: precision: str = "autocast" # or "full" save_to_disk_path: str = None 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" @@ -50,7 +49,7 @@ class Request: "output_format": self.output_format, } - def to_string(self): + def __str__(self): return f''' session_id: {self.session_id} prompt: {self.prompt} @@ -64,7 +63,6 @@ class Request: precision: {self.precision} 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_face_correction: {self.use_face_correction} use_upscale: {self.use_upscale} diff --git a/ui/sd_internal/runtime.py b/ui/sd_internal/runtime.py index 9e8d2818..1060889a 100644 --- a/ui/sd_internal/runtime.py +++ b/ui/sd_internal/runtime.py @@ -45,6 +45,25 @@ from io import BytesIO from threading import local as LocalThreadVars thread_data = LocalThreadVars() +def get_processor_name(): + try: + import platform, subprocess + if platform.system() == "Windows": + return platform.processor() + elif platform.system() == "Darwin": + os.environ['PATH'] = os.environ['PATH'] + os.pathsep + '/usr/sbin' + command ="sysctl -n machdep.cpu.brand_string" + return subprocess.check_output(command).strip() + elif platform.system() == "Linux": + command = "cat /proc/cpuinfo" + all_info = subprocess.check_output(command, shell=True).decode().strip() + for line in all_info.split("\n"): + if "model name" in line: + return re.sub( ".*model name.*:", "", line,1).strip() + except: + print(traceback.format_exc()) + return "cpu" + def device_would_fail(device): if device == 'cpu': return None # Returns None when no issues found, otherwise returns the detected error str. @@ -68,17 +87,17 @@ def device_select(device): print(failure_msg) return False - device_name = torch.cuda.get_device_name(device) + thread_data.device_name = torch.cuda.get_device_name(device) + thread_data.device = device - # otherwise these NVIDIA cards create green images - thread_data.force_full_precision = ('nvidia' in device_name.lower() or 'geforce' in device_name.lower()) and (' 1660' in device_name or ' 1650' in device_name) + # Force full precision on 1660 and 1650 NVIDIA cards to avoid creating green images + device_name = thread_data.device_name.lower() + thread_data.force_full_precision = ('nvidia' in device_name or 'geforce' in device_name) and (' 1660' in device_name or ' 1650' in device_name) if thread_data.force_full_precision: - print('forcing full precision on NVIDIA 16xx cards, to avoid green images. GPU detected: ', device_name) + print('forcing full precision on NVIDIA 16xx cards, to avoid green images. GPU detected: ', thread_data.device_name) # Apply force_full_precision now before models are loaded. thread_data.precision = 'full' - thread_data.device = device - thread_data.has_valid_gpu = True return True def device_init(device_selection=None): @@ -100,24 +119,26 @@ def device_init(device_selection=None): thread_data.model_is_half = False thread_data.model_fs_is_half = False thread_data.device = None + thread_data.device_name = None thread_data.unet_bs = 1 thread_data.precision = 'autocast' thread_data.sampler_plms = None thread_data.sampler_ddim = None thread_data.turbo = False - thread_data.has_valid_gpu = False thread_data.force_full_precision = False thread_data.reduced_memory = True if device_selection.lower() == 'cpu': - print('CPU requested, skipping gpu init.') thread_data.device = 'cpu' + thread_data.device_name = get_processor_name() + print('Render device CPU available as', thread_data.device_name) return if not torch.cuda.is_available(): if device_selection == 'auto' or device_selection == 'current': print('WARNING: torch.cuda is not available. Using the CPU, but this will be very slow!') thread_data.device = 'cpu' + thread_data.device_name = get_processor_name() return else: raise EnvironmentError('torch.cuda is not available.') @@ -475,7 +496,7 @@ def do_mk_img(req: Request): thread_data.vae_file = req.use_vae_model needs_model_reload = True - if thread_data.has_valid_gpu: + if thread_data.device != 'cpu': if (thread_data.precision == 'autocast' and (req.use_full_precision or not thread_data.model_is_half)) or \ (thread_data.precision == 'full' and not req.use_full_precision and not thread_data.force_full_precision): thread_data.precision = 'full' if req.use_full_precision else 'autocast' @@ -500,7 +521,7 @@ def do_mk_img(req: Request): opt_f = 8 opt_ddim_eta = 0.0 - print(req.to_string(), '\n device', thread_data.device) + print(req, '\n device', torch.device(thread_data.device), "as", thread_data.device_name) print('\n\n Using precision:', thread_data.precision) seed_everything(opt_seed) diff --git a/ui/sd_internal/task_manager.py b/ui/sd_internal/task_manager.py index eae17891..10461873 100644 --- a/ui/sd_internal/task_manager.py +++ b/ui/sd_internal/task_manager.py @@ -38,6 +38,7 @@ class RenderTask(): # Task with output queue and completion lock. def __init__(self, req: Request): self.request: Request = req # Initial Request self.response: Any = None # Copy of the last reponse + self.render_device = None self.temp_images:list = [None] * req.num_outputs * (1 if req.show_only_filtered_image else 2) self.error: Exception = None self.lock: threading.Lock = threading.Lock() # Locks at task start and unlocks when task is completed @@ -68,7 +69,8 @@ class ImageRequest(BaseModel): # allow_nsfw: bool = False save_to_disk_path: str = None turbo: bool = True - use_cpu: bool = False + use_cpu: bool = False ##TODO Remove after UI and plugins transition. + render_device: str = None 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" @@ -89,7 +91,7 @@ class FilterRequest(BaseModel): height: int = 512 save_to_disk_path: str = None turbo: bool = True - use_cpu: bool = False + render_device: str = None use_full_precision: bool = False output_format: str = "jpeg" # or "png" @@ -219,26 +221,24 @@ def thread_get_next_task(): queued_task.error = Exception('cuda:0 is not available with the current config. Remove GFPGANer filter to run task.') task = queued_task break - if queued_task.request.use_cpu: + if queued_task.render_device == 'cpu': queued_task.error = Exception('Cpu cannot be used to run this task. Remove GFPGANer filter to run task.') task = queued_task break if not runtime.is_first_cuda_device(runtime.thread_data.device): continue # Wait for cuda:0 - if queued_task.request.use_cpu and runtime.thread_data.device != 'cpu': - if is_alive('cpu') > 0: - continue # CPU Tasks, Skip GPU device + if queued_task.render_device and runtime.thread_data.device != queued_task.render_device: + # Is asking for a specific render device. + if is_alive(queued_task.render_device) > 0: + continue # requested device alive, skip current one. else: - queued_task.error = Exception('Cpu is not enabled in render_devices.') - task = queued_task - break - if not queued_task.request.use_cpu and runtime.thread_data.device == 'cpu': - if is_alive() > 1: # cpu is alive, so need more than one. - continue # GPU Tasks, don't run on CPU unless there is nothing else. - else: - queued_task.error = Exception('No active gpu found. Please check the error message in the command-line window at startup.') + # Requested device is not active, return error to UI. + queued_task.error = Exception(str(queued_task.render_device) + ' is not currently active.') task = queued_task break + if not queued_task.render_device and runtime.thread_data.device == 'cpu' and is_alive() > 1: + # not asking for any specific devices, cpu want to grab task but other render devices are alive. + continue # Skip Tasks, don't run on CPU unless there is nothing else or user asked for it. task = queued_task break if task is not None: @@ -256,7 +256,8 @@ def thread_render(device): print(traceback.format_exc()) return weak_thread_data[threading.current_thread()] = { - 'device': runtime.thread_data.device + 'device': runtime.thread_data.device, + 'device_name': runtime.thread_data.device_name } if runtime.thread_data.device != 'cpu' or is_alive() == 1: preload_model() @@ -341,6 +342,17 @@ def get_cached_task(session_id:str, update_ttl:bool=False): return None return task_cache.tryGet(session_id) +def get_devices(): + if not manager_lock.acquire(blocking=True, timeout=LOCK_TIMEOUT): raise Exception('get_devices' + ERR_LOCK_FAILED) + try: + device_dict = {} + for rthread in render_threads: + weak_data = weak_thread_data.get(rthread) + device_dict.update({weak_data['device']:weak_data['device_name']}) + return device_dict + finally: + manager_lock.release() + def is_first_cuda_device(device): from . import runtime # When calling runtime from outside thread_render DO NOT USE thread specific attributes or functions. return runtime.is_first_cuda_device(device) @@ -416,7 +428,6 @@ def render(req : ImageRequest): r.sampler = req.sampler # r.allow_nsfw = req.allow_nsfw r.turbo = req.turbo - 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 @@ -433,6 +444,8 @@ def render(req : ImageRequest): r.stream_image_progress = False new_task = RenderTask(r) + new_task.render_device = req.render_device + if task_cache.put(r.session_id, new_task, TASK_TTL): # Use twice the normal timeout for adding user requests. # Tries to force task_cache.put to fail before tasks_queue.put would. diff --git a/ui/server.py b/ui/server.py index c722894f..7fcd96bd 100644 --- a/ui/server.py +++ b/ui/server.py @@ -261,6 +261,8 @@ def read_web_data(key:str=None): if config is None: raise HTTPException(status_code=500, detail="Config file is missing or unreadable") return JSONResponse(config, headers=NOCACHE_HEADERS) + elif key == 'devices': + return JSONResponse(task_manager.get_devices(), headers=NOCACHE_HEADERS) elif key == 'models': return JSONResponse(getModels(), headers=NOCACHE_HEADERS) elif key == 'modifiers': return FileResponse(os.path.join(SD_UI_DIR, 'modifiers.json'), headers=NOCACHE_HEADERS) @@ -305,7 +307,11 @@ def save_model_to_config(model_name): @app.post('/render') def render(req : task_manager.ImageRequest): - if req.use_cpu and task_manager.is_alive('cpu') <= 0: raise HTTPException(status_code=403, detail=f'CPU rendering is not enabled in config.json or the thread has died...') # HTTP403 Forbidden + if req.use_cpu: # TODO Remove after transition. + print('WARNING Replace {use_cpu: true} by {render_device: "cpu"}') + req.render_device = 'cpu' + del req.use_cpu + if req.render_device and task_manager.is_alive(req.render_device) <= 0: raise HTTPException(status_code=403, detail=f'{req.render_device} rendering is not enabled in config.json or the thread has died...') # HTTP403 Forbidden if req.use_face_correction and task_manager.is_alive(0) <= 0: #TODO Remove when GFPGANer is fixed upstream. raise HTTPException(status_code=412, detail=f'GFPGANer only works GPU:0, use CUDA_VISIBLE_DEVICES if GFPGANer is needed on a specific GPU.') # HTTP412 Precondition Failed try: From 6229cdb1baa04cb6ea49023d79b1ab69af37cd37 Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sat, 29 Oct 2022 17:47:45 -0400 Subject: [PATCH 03/53] Added a missing device_name --- ui/sd_internal/runtime.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/sd_internal/runtime.py b/ui/sd_internal/runtime.py index 1060889a..41673f12 100644 --- a/ui/sd_internal/runtime.py +++ b/ui/sd_internal/runtime.py @@ -183,6 +183,7 @@ def device_init(device_selection=None): return print('WARNING: No compatible GPU found. Using the CPU, but this will be very slow!') thread_data.device = 'cpu' + thread_data.device_name = get_processor_name() def is_first_cuda_device(device): if device is None: return False From 099727d671585e8cab9a9a3e78e8daa270549e94 Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sat, 29 Oct 2022 18:57:10 -0400 Subject: [PATCH 04/53] Added auto unload to CPU if GPUs are active. --- ui/sd_internal/task_manager.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ui/sd_internal/task_manager.py b/ui/sd_internal/task_manager.py index 10461873..44472e11 100644 --- a/ui/sd_internal/task_manager.py +++ b/ui/sd_internal/task_manager.py @@ -21,6 +21,7 @@ LOCK_TIMEOUT = 15 # Maximum locking time in seconds before failing a task. # It's better to get an exception than a deadlock... ALWAYS use timeout in critical paths. DEVICE_START_TIMEOUT = 60 # seconds - Maximum time to wait for a render device to init. +CPU_UNLOAD_TIMEOUT = 4 * 60 # seconds - Idle time before CPU unload resource when GPUs are present. class SymbolClass(type): # Print nicely formatted Symbol names. def __repr__(self): return self.__qualname__ @@ -269,6 +270,11 @@ def thread_render(device): return task = thread_get_next_task() if task is None: + if runtime.thread_data.device == 'cpu' and is_alive() > 1 and hasattr(runtime.thread_data, 'lastActive') and time.time() - runtime.thread_data.lastActive > CPU_UNLOAD_TIMEOUT: + # GPUs present and CPU is idle. Unload resources. + runtime.unload_models() + runtime.unload_filters() + del runtime.thread_data.lastActive time.sleep(1) continue if task.error is not None: @@ -284,6 +290,9 @@ def thread_render(device): print(f'Session {task.request.session_id} starting task {id(task)}') if not task.lock.acquire(blocking=False): raise Exception('Got locked task from queue.') try: + if runtime.thread_data.device == 'cpu' and is_alive() > 1: + # CPU is not the only device. Keep track of active time to unload resources later. + runtime.thread_data.lastActive = time.time() # Open data generator. res = runtime.mk_img(task.request) if current_model_path == task.request.use_stable_diffusion_model: From bf9778123252f35b48b299defbee4445c4bf5eca Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sat, 29 Oct 2022 18:57:31 -0400 Subject: [PATCH 05/53] Don't let users register the same device twice. --- ui/server.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/server.py b/ui/server.py index 7fcd96bd..ecc96f57 100644 --- a/ui/server.py +++ b/ui/server.py @@ -403,6 +403,9 @@ if 'render_devices' in config: # Start a new thread for each device. if not isinstance(config['render_devices'], list): raise Exception('Invalid render_devices value in config.') for device in config['render_devices']: + if task_manager.is_alive(device): + print(device, 'already registered.') + continue if not task_manager.start_render_thread(device): print(device, 'failed to start.') if task_manager.is_alive() <= 0: # No running devices, probably invalid user config. From 70acc8a7c09049e1946571519bb75c16e9fc020d Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sat, 29 Oct 2022 19:02:07 -0400 Subject: [PATCH 06/53] Syntax... --- ui/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/server.py b/ui/server.py index ecc96f57..6c110866 100644 --- a/ui/server.py +++ b/ui/server.py @@ -403,7 +403,7 @@ if 'render_devices' in config: # Start a new thread for each device. if not isinstance(config['render_devices'], list): raise Exception('Invalid render_devices value in config.') for device in config['render_devices']: - if task_manager.is_alive(device): + if task_manager.is_alive(device) >= 1: print(device, 'already registered.') continue if not task_manager.start_render_thread(device): From eb994716e6651f9cf1a82bad1fd759ba7958b852 Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sun, 30 Oct 2022 01:33:17 -0400 Subject: [PATCH 07/53] Indentation... --- ui/sd_internal/task_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/sd_internal/task_manager.py b/ui/sd_internal/task_manager.py index 44472e11..fcd8c994 100644 --- a/ui/sd_internal/task_manager.py +++ b/ui/sd_internal/task_manager.py @@ -238,8 +238,8 @@ def thread_get_next_task(): task = queued_task break if not queued_task.render_device and runtime.thread_data.device == 'cpu' and is_alive() > 1: - # not asking for any specific devices, cpu want to grab task but other render devices are alive. - continue # Skip Tasks, don't run on CPU unless there is nothing else or user asked for it. + # not asking for any specific devices, cpu want to grab task but other render devices are alive. + continue # Skip Tasks, don't run on CPU unless there is nothing else or user asked for it. task = queued_task break if task is not None: From c687091ce905d0a88447fabdb0a8c26e11cb3aad Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sun, 30 Oct 2022 01:38:32 -0400 Subject: [PATCH 08/53] Only return valid data for alive threads. --- ui/sd_internal/task_manager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/sd_internal/task_manager.py b/ui/sd_internal/task_manager.py index fcd8c994..0aa8e62f 100644 --- a/ui/sd_internal/task_manager.py +++ b/ui/sd_internal/task_manager.py @@ -356,7 +356,11 @@ def get_devices(): try: device_dict = {} for rthread in render_threads: + if not rthread.is_alive(): + continue weak_data = weak_thread_data.get(rthread) + if not weak_data or not 'device' in weak_data or not 'device_name' in weak_data: + continue device_dict.update({weak_data['device']:weak_data['device_name']}) return device_dict finally: From 22085456123b6adaf85602b2c1f4dd0705287ae0 Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sun, 30 Oct 2022 05:39:45 -0400 Subject: [PATCH 09/53] Don't display this warning if on CPU. --- ui/server.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/server.py b/ui/server.py index 6c110866..4681599a 100644 --- a/ui/server.py +++ b/ui/server.py @@ -397,6 +397,7 @@ config = getConfig() # Start the task_manager task_manager.default_model_to_load = resolve_ckpt_to_use() task_manager.default_vae_to_load = resolve_vae_to_use(ckpt_model_path=task_manager.default_model_to_load) +display_warning = False if 'render_devices' in config: # Start a new thread for each device. if isinstance(config['render_devices'], str): config['render_devices'] = config['render_devices'].split(',') @@ -411,8 +412,9 @@ if 'render_devices' in config: # Start a new thread for each device. if task_manager.is_alive() <= 0: # No running devices, probably invalid user config. print('WARNING: No active render devices after loading config. Validate "render_devices" in config.json') print('Loading default render devices to replace invalid render_devices field from config', config['render_devices']) + elif task_manager.is_alive(0) <= 0: # Missing GPU:0 + display_warning = True # Warn user to update settings... -display_warning = False if task_manager.is_alive() <= 0: # Either no defauls or no devices after loading config. # Select best GPU device using free memory, if more than one device. if task_manager.start_render_thread('auto'): # Detect best device for renders @@ -430,12 +432,11 @@ if task_manager.is_alive() <= 0: # Either no defauls or no devices after loading if not task_manager.start_render_thread('cpu'): print('Failed to start CPU render device...') -if display_warning or task_manager.is_alive(0) <= 0: +if display_warning: print('WARNING: GFPGANer only works on GPU:0, use CUDA_VISIBLE_DEVICES if GFPGANer is needed on a specific GPU.') print('Using CUDA_VISIBLE_DEVICES will remap the selected devices starting at GPU:0 fixing GFPGANer') print('Add the line "@set CUDA_VISIBLE_DEVICES=N" where N is the GPUs to use to config.bat') print('Add the line "CUDA_VISIBLE_DEVICES=N" where N is the GPUs to use to config.sh') - del display_warning # start the browser ui From eb596ba8660b372b6d7f0906a7d3681e764e9512 Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sun, 30 Oct 2022 06:04:06 -0400 Subject: [PATCH 10/53] Allow start_render_thread to proceed faster in case of failure. --- ui/sd_internal/task_manager.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ui/sd_internal/task_manager.py b/ui/sd_internal/task_manager.py index 0aa8e62f..14a2050e 100644 --- a/ui/sd_internal/task_manager.py +++ b/ui/sd_internal/task_manager.py @@ -253,8 +253,11 @@ def thread_render(device): from . import runtime try: runtime.device_init(device) - except: + except Exception as e: print(traceback.format_exc()) + weak_thread_data[threading.current_thread()] = { + 'error': e + } return weak_thread_data[threading.current_thread()] = { 'device': runtime.thread_data.device, @@ -377,8 +380,7 @@ def is_alive(name=None): for rthread in render_threads: if name is not None: weak_data = weak_thread_data.get(rthread) - if weak_data is None or weak_data['device'] is None: - print('The thread', rthread.name, 'is registered but has no data store in the task manager.') + if weak_data is None or not 'device' in weak_data or weak_data['device'] is None: continue thread_name = str(weak_data['device']).lower() if is_first_cuda_device(name): @@ -405,6 +407,8 @@ def start_render_thread(device='auto'): manager_lock.release() timeout = DEVICE_START_TIMEOUT while not rthread.is_alive() or not rthread in weak_thread_data or not 'device' in weak_thread_data[rthread]: + if rthread in weak_thread_data and 'error' in weak_thread_data[rthread]: + return False if timeout <= 0: return False timeout -= 1 From a922a93016b4b5f84970209514c07cedff1f64f1 Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sun, 30 Oct 2022 14:09:12 -0400 Subject: [PATCH 11/53] Can work with one or more params, don't need a minimum of two. Still works just the same. --- ui/media/js/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/media/js/main.js b/ui/media/js/main.js index 964bc420..418f8758 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -340,10 +340,10 @@ function onDownloadImageClick(req, img) { imgDownload.click() } -function modifyCurrentRequest(req, ...reqDiff) { +function modifyCurrentRequest(...reqDiff) { const newTaskRequest = getCurrentUserRequest() - newTaskRequest.reqBody = Object.assign(newTaskRequest.reqBody, req, ...reqDiff, { + newTaskRequest.reqBody = Object.assign(newTaskRequest.reqBody, ...reqDiff, { use_cpu: useCPUField.checked }) newTaskRequest.seed = newTaskRequest.reqBody.seed From bc2f9204e97b9f90ae890e77a790e048f2fc3731 Mon Sep 17 00:00:00 2001 From: ayunami2000 Date: Sun, 30 Oct 2022 18:16:31 -0400 Subject: [PATCH 12/53] Improve UI on mobile devices --- ui/media/css/main.css | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ui/media/css/main.css b/ui/media/css/main.css index 9f8bca08..8f0a8412 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -559,6 +559,26 @@ input::file-selector-button { left: 0px; right: 0px; } + .popup > div { + padding-left: 5px !important; + padding-right: 5px !important; + } + .popup > div input, .popup > div select { + max-width: 40vw; + } + .popup .close-button { + padding: 0px !important; + margin: 24px !important; + } + #reset-image-settings .simple-tooltip.right { + right: initial; + left: 0px; + top: 50%; + transform: translate(calc(-100% + 15%), -50%); + } + :hover > #reset-image-settings .simple-tooltip.right { + transform: translate(100%, -50%); + } } #promptsFromFileBtn { @@ -708,4 +728,4 @@ input::file-selector-button { #settings-button { cursor: pointer; -} \ No newline at end of file +} From 7f151cbebad81b6e28bcbf21af6008ad21997980 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Mon, 31 Oct 2022 00:48:18 +0100 Subject: [PATCH 13/53] Copy CUDA_VISIBLE_DEVICES to config.*, it it has been set Don't delete CUDA_VISIBLE_DEVICES settings when generating a new config file --- ui/server.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/server.py b/ui/server.py index c722894f..0df08785 100644 --- a/ui/server.py +++ b/ui/server.py @@ -111,6 +111,8 @@ def setConfig(config): config_bat.append('::Set the devices visible inside SD-UI here') config_bat.append(f"::@set CUDA_VISIBLE_DEVICES={','.join(gpu_devices)}") # Needs better detection for edge cases, add as a comment for now. print('Add the line "@set CUDA_VISIBLE_DEVICES=N" where N is the GPUs to use to config.bat') + if os.getenv('CUDA_VISIBLE_DEVICES') is not None: + config_bat.append(f"@set CUDA_VISIBLE_DEVICES={os.getenv('CUDA_VISIBLE_DEVICES')}") config_bat_path = os.path.join(CONFIG_DIR, 'config.bat') with open(config_bat_path, 'w', encoding='utf-8') as f: f.write('\r\n'.join(config_bat)) @@ -126,6 +128,8 @@ def setConfig(config): config_sh.append('#Set the devices visible inside SD-UI here') config_sh.append(f"#CUDA_VISIBLE_DEVICES={','.join(gpu_devices)}") # Needs better detection for edge cases, add as a comment for now. print('Add the line "CUDA_VISIBLE_DEVICES=N" where N is the GPUs to use to config.sh') + if os.getenv('CUDA_VISIBLE_DEVICES') is not None: + config_sh.append(f"export CUDA_VISIBLE_DEVICES=\"{os.getenv('CUDA_VISIBLE_DEVICES')}\"") config_sh_path = os.path.join(CONFIG_DIR, 'config.sh') with open(config_sh_path, 'w', encoding='utf-8') as f: f.write('\n'.join(config_sh)) @@ -430,4 +434,4 @@ if display_warning or task_manager.is_alive(0) <= 0: del display_warning # start the browser ui -import webbrowser; webbrowser.open('http://localhost:9000') \ No newline at end of file +import webbrowser; webbrowser.open('http://localhost:9000') From d656c34bd4d00cc768ab2c22d3449e25ce00b686 Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sun, 30 Oct 2022 23:21:39 -0400 Subject: [PATCH 14/53] Add support for drag&drop for the text files made by the backend and also supports JSON. --- ui/index.html | 1 + ui/media/js/dnd.js | 311 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 312 insertions(+) create mode 100644 ui/media/js/dnd.js diff --git a/ui/index.html b/ui/index.html index 5e6a2685..fcb45f75 100644 --- a/ui/index.html +++ b/ui/index.html @@ -263,6 +263,7 @@ + - + diff --git a/ui/media/js/utils.js b/ui/media/js/utils.js index f3ad2d78..cb7dfdab 100644 --- a/ui/media/js/utils.js +++ b/ui/media/js/utils.js @@ -342,3 +342,15 @@ function asyncDelay(timeout) { setTimeout(resolve, timeout, true) }) } + +function preventNonNumericalInput(e) { + e = e || window.event; + let charCode = (typeof e.which == "undefined") ? e.keyCode : e.which; + let charStr = String.fromCharCode(charCode); + let re = e.target.getAttribute('pattern') || '^[0-9]+$' + re = new RegExp(re) + + if (!charStr.match(re)) { + e.preventDefault(); + } +} From f964fe37505884ebdbefca1cf94e43467ce32e2e Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sat, 5 Nov 2022 13:33:38 -0400 Subject: [PATCH 34/53] Add on/off support for parsing boolean. --- ui/media/js/dnd.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index d282935b..9154b2a0 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -13,11 +13,13 @@ function parseBoolean(stringValue) { switch(stringValue?.toLowerCase()?.trim()) { case "true": case "yes": + case "on": case "1": return true; case "false": case "no": + case "off": case "0": case null: case undefined: From 35762149201622069c8626daa3b902bfac126912 Mon Sep 17 00:00:00 2001 From: Marc-Andre Ferland Date: Sat, 5 Nov 2022 13:35:09 -0400 Subject: [PATCH 35/53] Remove prompt_strength and init_image when not using in-painting --- ui/media/js/dnd.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/media/js/dnd.js b/ui/media/js/dnd.js index 9154b2a0..9e53451f 100644 --- a/ui/media/js/dnd.js +++ b/ui/media/js/dnd.js @@ -408,6 +408,10 @@ function checkWriteToClipboardPermission (result) { event.stopPropagation() const uiState = readUI() TASK_REQ_NO_EXPORT.forEach((key) => delete uiState.reqBody[key]) + if (uiState.reqBody.init_image && !IMAGE_REGEX.test(uiState.reqBody.init_image)) { + delete uiState.reqBody.init_image + delete uiState.reqBody.prompt_strength + } navigator.clipboard.writeText(JSON.stringify(uiState, undefined, 4)) }) resetSettings.parentNode.insertBefore(copyIcon, resetSettings) From 74ca756a538bad52baeba2fa8feca25f1c42ef12 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Sun, 6 Nov 2022 00:27:11 +0100 Subject: [PATCH 36/53] Protect SD_UI_BIND_PORT and SD_UI_BIND_IP in config files --- ui/server.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ui/server.py b/ui/server.py index 00e5d0f1..dc487c68 100644 --- a/ui/server.py +++ b/ui/server.py @@ -107,6 +107,7 @@ def setConfig(config): config_bat = [ f"@set update_branch={config['update_branch']}" ] + if os.getenv('CUDA_VISIBLE_DEVICES') is None: if len(gpu_devices) > 0 and not has_first_cuda_device: config_bat.append('::Set the devices visible inside SD-UI here') @@ -117,6 +118,13 @@ def setConfig(config): if len(gpu_devices) > 0 and not has_first_cuda_device: print('GPU:0 seems to be missing! Validate that CUDA_VISIBLE_DEVICES is set properly.') config_bat_path = os.path.join(CONFIG_DIR, 'config.bat') + + if os.getenv('SD_UI_BIND_PORT') is not None: + config_bat.append(f"@set SD_UI_BIND_PORT={os.getenv('SD_UI_BIND_PORT')}") + if os.getenv('SD_UI_BIND_IP') is not None: + config_bat.append(f"@set SD_UI_BIND_IP={os.getenv('SD_UI_BIND_IP')}") + + with open(config_bat_path, 'w', encoding='utf-8') as f: f.write('\r\n'.join(config_bat)) except Exception as e: @@ -136,6 +144,12 @@ def setConfig(config): config_sh.append(f"export CUDA_VISIBLE_DEVICES=\"{os.getenv('CUDA_VISIBLE_DEVICES')}\"") if len(gpu_devices) > 0 and not has_first_cuda_device: print('GPU:0 seems to be missing! Validate that CUDA_VISIBLE_DEVICES is set properly.') + + if os.getenv('SD_UI_BIND_PORT') is not None: + config_sh.append(f"export SD_UI_BIND_PORT={os.getenv('SD_UI_BIND_PORT')}") + if os.getenv('SD_UI_BIND_IP') is not None: + config_sh.append(f"export SD_UI_BIND_IP={os.getenv('SD_UI_BIND_IP')}") + config_sh_path = os.path.join(CONFIG_DIR, 'config.sh') with open(config_sh_path, 'w', encoding='utf-8') as f: f.write('\n'.join(config_sh)) From 58b759f652e4b34477787c91a6934d7a62b3ce8a Mon Sep 17 00:00:00 2001 From: JeLuF Date: Sun, 6 Nov 2022 16:50:23 +0100 Subject: [PATCH 37/53] Fix tabs to spaces --- ui/server.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/server.py b/ui/server.py index dc487c68..1779c116 100644 --- a/ui/server.py +++ b/ui/server.py @@ -120,9 +120,9 @@ def setConfig(config): config_bat_path = os.path.join(CONFIG_DIR, 'config.bat') if os.getenv('SD_UI_BIND_PORT') is not None: - config_bat.append(f"@set SD_UI_BIND_PORT={os.getenv('SD_UI_BIND_PORT')}") + config_bat.append(f"@set SD_UI_BIND_PORT={os.getenv('SD_UI_BIND_PORT')}") if os.getenv('SD_UI_BIND_IP') is not None: - config_bat.append(f"@set SD_UI_BIND_IP={os.getenv('SD_UI_BIND_IP')}") + config_bat.append(f"@set SD_UI_BIND_IP={os.getenv('SD_UI_BIND_IP')}") with open(config_bat_path, 'w', encoding='utf-8') as f: @@ -146,9 +146,9 @@ def setConfig(config): print('GPU:0 seems to be missing! Validate that CUDA_VISIBLE_DEVICES is set properly.') if os.getenv('SD_UI_BIND_PORT') is not None: - config_sh.append(f"export SD_UI_BIND_PORT={os.getenv('SD_UI_BIND_PORT')}") + config_sh.append(f"export SD_UI_BIND_PORT={os.getenv('SD_UI_BIND_PORT')}") if os.getenv('SD_UI_BIND_IP') is not None: - config_sh.append(f"export SD_UI_BIND_IP={os.getenv('SD_UI_BIND_IP')}") + config_sh.append(f"export SD_UI_BIND_IP={os.getenv('SD_UI_BIND_IP')}") config_sh_path = os.path.join(CONFIG_DIR, 'config.sh') with open(config_sh_path, 'w', encoding='utf-8') as f: From abbfae2fc0578008c25806ab88030e1687300070 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Mon, 7 Nov 2022 17:55:27 +0530 Subject: [PATCH 38/53] Simplify the logic used for displaying the GFPGAN warning --- ui/sd_internal/runtime.py | 4 ++-- ui/server.py | 23 +++++++---------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/ui/sd_internal/runtime.py b/ui/sd_internal/runtime.py index 69127d1f..00a4f691 100644 --- a/ui/sd_internal/runtime.py +++ b/ui/sd_internal/runtime.py @@ -136,12 +136,12 @@ def device_init(device_selection=None): return if not torch.cuda.is_available(): if device_selection == 'auto' or device_selection == 'current': - print('WARNING: torch.cuda is not available. Using the CPU, but this will be very slow!') + print('WARNING: Could not find a compatible GPU. Using the CPU, but this will be very slow!') thread_data.device = 'cpu' thread_data.device_name = get_processor_name() return else: - raise EnvironmentError('torch.cuda is not available.') + raise EnvironmentError(f'Could not find a compatible GPU for the requested device_selection: {device_selection}!') device_count = torch.cuda.device_count() if device_count <= 1 and device_selection == 'auto': device_selection = 'current' # Use 'auto' only when there is more than one compatible device found. diff --git a/ui/server.py b/ui/server.py index 00e5d0f1..50098cc1 100644 --- a/ui/server.py +++ b/ui/server.py @@ -407,7 +407,6 @@ config = getConfig() # Start the task_manager task_manager.default_model_to_load = resolve_ckpt_to_use() task_manager.default_vae_to_load = resolve_vae_to_use(ckpt_model_path=task_manager.default_model_to_load) -display_warning = False if 'render_devices' in config: # Start a new thread for each device. if isinstance(config['render_devices'], str): config['render_devices'] = config['render_devices'].split(',') @@ -422,32 +421,24 @@ if 'render_devices' in config: # Start a new thread for each device. if task_manager.is_alive() <= 0: # No running devices, probably invalid user config. print('WARNING: No active render devices after loading config. Validate "render_devices" in config.json') print('Loading default render devices to replace invalid render_devices field from config', config['render_devices']) - elif task_manager.is_alive(0) <= 0: # Missing GPU:0 - display_warning = True # Warn user to update settings... if task_manager.is_alive() <= 0: # Either no defauls or no devices after loading config. # Select best GPU device using free memory, if more than one device. if task_manager.start_render_thread('auto'): # Detect best device for renders - if task_manager.is_alive(0) <= 0: # has no cuda:0 - if task_manager.is_alive('cpu') >= 1: # auto used CPU. - pass # Maybe add warning here about CPU mode... - elif task_manager.start_render_thread('cuda'): # An other cuda device is better and cuda:0 is missing, try to start it... - display_warning = True # And warn user to update settings... - else: - print('Failed to start GPU:0...') + # if cuda:0 is missing, another cuda device is better. try to start it... + if task_manager.is_alive(0) <= 0 and task_manager.is_alive('cpu') <= 0 and not task_manager.start_render_thread('cuda'): + print('Failed to start GPU:0...') else: print('Failed to start gpu device.') - if task_manager.is_alive('cpu') <= 0: - # Allow CPU to be used for renders - if not task_manager.start_render_thread('cpu'): - print('Failed to start CPU render device...') + if task_manager.is_alive('cpu') <= 0 and not task_manager.start_render_thread('cpu'): # Allow CPU to be used for renders + print('Failed to start CPU render device...') -if display_warning: +is_using_a_gpu = (task_manager.is_alive() > task_manager.is_alive('cpu')) +if is_using_a_gpu and task_manager.is_alive(0) <= 0: print('WARNING: GFPGANer only works on GPU:0, use CUDA_VISIBLE_DEVICES if GFPGANer is needed on a specific GPU.') print('Using CUDA_VISIBLE_DEVICES will remap the selected devices starting at GPU:0 fixing GFPGANer') print('Add the line "@set CUDA_VISIBLE_DEVICES=N" where N is the GPUs to use to config.bat') print('Add the line "CUDA_VISIBLE_DEVICES=N" where N is the GPUs to use to config.sh') -del display_warning # start the browser ui import webbrowser; webbrowser.open('http://localhost:9000') From 90b1609d4e157f167c043a7146a37a5507d6040d Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Mon, 7 Nov 2022 18:08:43 +0530 Subject: [PATCH 39/53] device_selection is already a string, since we've used string functions before this line --- ui/sd_internal/runtime.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ui/sd_internal/runtime.py b/ui/sd_internal/runtime.py index 00a4f691..6fba4ddd 100644 --- a/ui/sd_internal/runtime.py +++ b/ui/sd_internal/runtime.py @@ -129,7 +129,9 @@ def device_init(device_selection=None): thread_data.force_full_precision = False thread_data.reduced_memory = True - if device_selection.lower() == 'cpu': + device_selection = device_selection.lower() + + if device_selection == 'cpu': thread_data.device = 'cpu' thread_data.device_name = get_processor_name() print('Render device CPU available as', thread_data.device_name) @@ -162,10 +164,10 @@ def device_init(device_selection=None): print(f'Setting GPU:{device} as active') torch.cuda.device(device) return - if isinstance(device_selection, str): - device_selection = device_selection.lower() - if device_selection.startswith('gpu:'): - device_selection = int(device_selection[4:]) + + if device_selection.startswith('gpu:'): + device_selection = int(device_selection[4:]) + if device_selection != 'cuda' and device_selection != 'current' and device_selection != 'gpu': if device_select(device_selection): if isinstance(device_selection, int): From 67cca3bc007a2a2fa8171e42711be278a4cfe7c4 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Mon, 7 Nov 2022 18:26:10 +0530 Subject: [PATCH 40/53] Print the devices for which rendering threads have started; Prettier print of the model data --- ui/sd_internal/runtime.py | 7 ++++++- ui/server.py | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ui/sd_internal/runtime.py b/ui/sd_internal/runtime.py index 6fba4ddd..c003d356 100644 --- a/ui/sd_internal/runtime.py +++ b/ui/sd_internal/runtime.py @@ -285,7 +285,12 @@ def load_model_ckpt(): thread_data.model_is_half = False thread_data.model_fs_is_half = False - print('loaded', thread_data.ckpt_file, 'as', model.device, '->', modelCS.cond_stage_model.device, '->', thread_data.modelFS.device, 'using precision', thread_data.precision) + print(f'''loaded model + model file: {thread_data.ckpt_file}.ckpt + model.device: {model.device} + modelCS.device: {modelCS.cond_stage_model.device} + modelFS.device: {thread_data.modelFS.device} + using precision: {thread_data.precision}''') def unload_filters(): if thread_data.model_gfpgan is not None: diff --git a/ui/server.py b/ui/server.py index 50098cc1..bf5871a4 100644 --- a/ui/server.py +++ b/ui/server.py @@ -440,5 +440,7 @@ if is_using_a_gpu and task_manager.is_alive(0) <= 0: print('Add the line "@set CUDA_VISIBLE_DEVICES=N" where N is the GPUs to use to config.bat') print('Add the line "CUDA_VISIBLE_DEVICES=N" where N is the GPUs to use to config.sh') +print('active devices', task_manager.get_devices()) + # start the browser ui import webbrowser; webbrowser.open('http://localhost:9000') From 47f7c938ae611662e0cc65210010117502589496 Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Mon, 7 Nov 2022 23:15:59 -0800 Subject: [PATCH 41/53] Update main.css --- ui/media/css/main.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/media/css/main.css b/ui/media/css/main.css index 2df03a64..e7083380 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -706,7 +706,7 @@ input::file-selector-button { } .popup { - position: absolute; + position: fixed; background: rgba(32, 33, 36, 50%); top: 0px; left: 0px; From a68ebd2b760f31c6091f920d9f8012adac6dc9f2 Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Tue, 8 Nov 2022 02:17:26 -0800 Subject: [PATCH 42/53] Fixing the popup position on larger screens Fixing the popup position on larger screens; Smaller screens still get the current rendering experience. --- ui/media/css/main.css | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/media/css/main.css b/ui/media/css/main.css index e7083380..b0543497 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -706,7 +706,7 @@ input::file-selector-button { } .popup { - position: fixed; + position: absolute; background: rgba(32, 33, 36, 50%); top: 0px; left: 0px; @@ -717,6 +717,12 @@ input::file-selector-button { transition: 0s visibility, 0.3s opacity; } +@media only screen and (min-height: 1050px) { + .popup { + position: fixed; + } +} + .popup > div { position: relative; background: var(--background-color2); From 9bc7521de0efaaba3aaa73becf4a5a9806536204 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Tue, 8 Nov 2022 16:54:15 +0530 Subject: [PATCH 43/53] Make custom VAE an Image Setting, rather than a System Setting; Don't load a VAE into memory by default --- scripts/on_sd_start.bat | 18 ++++---- scripts/on_sd_start.sh | 18 ++++---- ui/index.html | 13 ++++-- ui/media/js/auto-save.js | 1 + ui/media/js/main.js | 39 ++++++++--------- ui/media/js/parameters.js | 5 --- ui/sd_internal/runtime.py | 16 ++++--- ui/server.py | 91 +++++++++++++++++++-------------------- 8 files changed, 102 insertions(+), 99 deletions(-) diff --git a/scripts/on_sd_start.bat b/scripts/on_sd_start.bat index f8f2d3bf..4c188183 100644 --- a/scripts/on_sd_start.bat +++ b/scripts/on_sd_start.bat @@ -191,7 +191,9 @@ call WHERE uvicorn > .tmp if not exist "..\models\stable-diffusion" mkdir "..\models\stable-diffusion" +if not exist "..\models\vae" mkdir "..\models\vae" echo. > "..\models\stable-diffusion\Put your custom ckpt files here.txt" +echo. > "..\models\vae\Put your VAE files here.txt" @if exist "sd-v1-4.ckpt" ( for %%I in ("sd-v1-4.ckpt") do if "%%~zI" EQU "4265380512" ( @@ -321,22 +323,22 @@ echo. > "..\models\stable-diffusion\Put your custom ckpt files here.txt" -@if exist "..\models\stable-diffusion\vae-ft-mse-840000-ema-pruned.vae.pt" ( - for %%I in ("..\models\stable-diffusion\vae-ft-mse-840000-ema-pruned.vae.pt") do if "%%~zI" EQU "334695179" ( +@if exist "..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt" ( + for %%I in ("..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt") do if "%%~zI" EQU "334695179" ( echo "Data files (weights) necessary for the default VAE (sd-vae-ft-mse-original) were already downloaded" ) else ( - echo. & echo "The default VAE (sd-vae-ft-mse-original) file present at models\stable-diffusion\vae-ft-mse-840000-ema-pruned.vae.pt is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo. - del "..\models\stable-diffusion\vae-ft-mse-840000-ema-pruned.vae.pt" + echo. & echo "The default VAE (sd-vae-ft-mse-original) file present at models\vae\vae-ft-mse-840000-ema-pruned.ckpt is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo. + del "..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt" ) ) -@if not exist "..\models\stable-diffusion\vae-ft-mse-840000-ema-pruned.vae.pt" ( +@if not exist "..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt" ( @echo. & echo "Downloading data files (weights) for the default VAE (sd-vae-ft-mse-original).." & echo. - @call curl -L -k https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.ckpt > ..\models\stable-diffusion\vae-ft-mse-840000-ema-pruned.vae.pt + @call curl -L -k https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.ckpt > ..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt - @if exist "..\models\stable-diffusion\vae-ft-mse-840000-ema-pruned.vae.pt" ( - for %%I in ("..\models\stable-diffusion\vae-ft-mse-840000-ema-pruned.vae.pt") do if "%%~zI" NEQ "334695179" ( + @if exist "..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt" ( + for %%I in ("..\models\vae\vae-ft-mse-840000-ema-pruned.ckpt") do if "%%~zI" NEQ "334695179" ( echo. & echo "Error: The downloaded default VAE (sd-vae-ft-mse-original) file was invalid! Bytes downloaded: %%~zI" & echo. echo. & echo "Error downloading the data files (weights) for the default VAE (sd-vae-ft-mse-original). 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/wiki/Troubleshooting" & 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 diff --git a/scripts/on_sd_start.sh b/scripts/on_sd_start.sh index eedc798b..6facac16 100755 --- a/scripts/on_sd_start.sh +++ b/scripts/on_sd_start.sh @@ -170,7 +170,9 @@ fi mkdir -p "../models/stable-diffusion" +mkdir -p "../models/vae" echo "" > "../models/stable-diffusion/Put your custom ckpt files here.txt" +echo "" > "../models/vae/Put your VAE files here.txt" if [ -f "sd-v1-4.ckpt" ]; then model_size=`find "sd-v1-4.ckpt" -printf "%s"` @@ -300,24 +302,24 @@ if [ ! -f "RealESRGAN_x4plus_anime_6B.pth" ]; then fi -if [ -f "../models/stable-diffusion/vae-ft-mse-840000-ema-pruned.vae.pt" ]; then - model_size=`find ../models/stable-diffusion/vae-ft-mse-840000-ema-pruned.vae.pt -printf "%s"` +if [ -f "../models/vae/vae-ft-mse-840000-ema-pruned.ckpt" ]; then + model_size=`find ../models/vae/vae-ft-mse-840000-ema-pruned.ckpt -printf "%s"` if [ "$model_size" -eq "334695179" ]; then echo "Data files (weights) necessary for the default VAE (sd-vae-ft-mse-original) were already downloaded" else - printf "\n\nThe model file present at models/stable-diffusion/vae-ft-mse-840000-ema-pruned.vae.pt is invalid. It is only $model_size bytes in size. Re-downloading.." - rm ../models/stable-diffusion/vae-ft-mse-840000-ema-pruned.vae.pt + printf "\n\nThe model file present at models/vae/vae-ft-mse-840000-ema-pruned.ckpt is invalid. It is only $model_size bytes in size. Re-downloading.." + rm ../models/vae/vae-ft-mse-840000-ema-pruned.ckpt fi fi -if [ ! -f "../models/stable-diffusion/vae-ft-mse-840000-ema-pruned.vae.pt" ]; then +if [ ! -f "../models/vae/vae-ft-mse-840000-ema-pruned.ckpt" ]; then echo "Downloading data files (weights) for the default VAE (sd-vae-ft-mse-original).." - curl -L -k https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.ckpt > ../models/stable-diffusion/vae-ft-mse-840000-ema-pruned.vae.pt + curl -L -k https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.ckpt > ../models/vae/vae-ft-mse-840000-ema-pruned.ckpt - if [ -f "../models/stable-diffusion/vae-ft-mse-840000-ema-pruned.vae.pt" ]; then - model_size=`find ../models/stable-diffusion/vae-ft-mse-840000-ema-pruned.vae.pt -printf "%s"` + if [ -f "../models/vae/vae-ft-mse-840000-ema-pruned.ckpt" ]; then + model_size=`find ../models/vae/vae-ft-mse-840000-ema-pruned.ckpt -printf "%s"` if [ ! "$model_size" -eq "334695179" ]; then printf "\n\nError: The downloaded default VAE (sd-vae-ft-mse-original) file was invalid! Bytes downloaded: $model_size\n\n" printf "\n\nError downloading the data files (weights) for the default VAE (sd-vae-ft-mse-original). 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/wiki/Troubleshooting\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" diff --git a/ui/index.html b/ui/index.html index ad788f31..a09b8ebf 100644 --- a/ui/index.html +++ b/ui/index.html @@ -18,7 +18,7 @@