From 7b5639cff5f607a77f536b6ed46979a0d1220531 Mon Sep 17 00:00:00 2001 From: JSTayco Date: Thu, 30 Mar 2023 01:40:00 -0700 Subject: [PATCH] Huge WIP This is a massive WIP and should not be trusted or used right now. However, major milestones have been crossed. Both message boxes and file dialogs are now properly subprocessed and work on macOS. I think by extension, it may work on runpod environments as well, but that remains to be tested. --- .gitignore | 241 +++++++++++- dreambooth_gui.py | 437 +++++++++++----------- library/basic_caption_gui.py | 15 +- library/blip_caption_gui.py | 13 +- library/common_gui.py | 244 ++++++------ library/convert_model_gui.py | 13 +- library/dataset_balancing_gui.py | 11 +- library/dreambooth_folder_creation_gui.py | 13 +- library/extract_lora_gui.py | 21 +- library/extract_lycoris_locon_gui.py | 21 +- library/git_caption_gui.py | 11 +- library/gui_subprocesses.py | 84 +++++ library/merge_lora_gui.py | 21 +- library/resize_lora_gui.py | 19 +- library/sampler_gui.py | 1 - library/svd_merge_lora_gui.py | 21 +- library/tensorboard_gui.py | 6 +- library/verify_lora_gui.py | 13 +- library/wd14_caption_gui.py | 15 +- lora_gui.py | 40 +- textual_inversion_gui.py | 31 +- 21 files changed, 799 insertions(+), 492 deletions(-) create mode 100644 library/gui_subprocesses.py diff --git a/.gitignore b/.gitignore index 71fe116..4fc61ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,242 @@ -venv -__pycache__ +# Kohya_SS Specifics cudnn_windows .vscode -*.egg-info -build wd14_tagger_model .DS_Store locon gui-user.bat -gui-user.ps1 \ No newline at end of file +gui-user.ps1 +*.whl* +.idea + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser \ No newline at end of file diff --git a/dreambooth_gui.py b/dreambooth_gui.py index a72acff..6fbdbf0 100644 --- a/dreambooth_gui.py +++ b/dreambooth_gui.py @@ -3,13 +3,15 @@ # v3: Add new Utilities tab for Dreambooth folder preparation # v3.1: Adding captionning of images to utilities -import gradio as gr +import argparse import json import math import os -import subprocess import pathlib -import argparse +import subprocess + +import gradio as gr + from library.common_gui import ( get_folder_path, remove_doublequote, @@ -26,88 +28,87 @@ from library.common_gui import ( gradio_source_model, # set_legacy_8bitadam, update_my_data, - check_if_model_exist, + check_if_model_exist, is_valid_config, show_message_box, ) +from library.dreambooth_folder_creation_gui import ( + gradio_dreambooth_folder_creation_tab, +) +from library.sampler_gui import sample_gradio_config, run_cmd_sample from library.tensorboard_gui import ( gradio_tensorboard, start_tensorboard, stop_tensorboard, ) -from library.dreambooth_folder_creation_gui import ( - gradio_dreambooth_folder_creation_tab, -) from library.utilities import utilities_tab -from library.sampler_gui import sample_gradio_config, run_cmd_sample -from easygui import msgbox folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 save_style_symbol = '\U0001f4be' # 💾 -document_symbol = '\U0001F4C4' # 📄 +document_symbol = '\U0001F4C4' # 📄 def save_configuration( - save_as, - file_path, - pretrained_model_name_or_path, - v2, - v_parameterization, - logging_dir, - train_data_dir, - reg_data_dir, - output_dir, - max_resolution, - learning_rate, - lr_scheduler, - lr_warmup, - train_batch_size, - epoch, - save_every_n_epochs, - mixed_precision, - save_precision, - seed, - num_cpu_threads_per_process, - cache_latents, - caption_extension, - enable_bucket, - gradient_checkpointing, - full_fp16, - no_token_padding, - stop_text_encoder_training, - # use_8bit_adam, - xformers, - save_model_as, - shuffle_caption, - save_state, - resume, - prior_loss_weight, - color_aug, - flip_aug, - clip_skip, - vae, - output_name, - max_token_length, - max_train_epochs, - max_data_loader_n_workers, - mem_eff_attn, - gradient_accumulation_steps, - model_list, - keep_tokens, - persistent_data_loader_workers, - bucket_no_upscale, - random_crop, - bucket_reso_steps, - caption_dropout_every_n_epochs, - caption_dropout_rate, - optimizer, - optimizer_args, - noise_offset, - sample_every_n_steps, - sample_every_n_epochs, - sample_sampler, - sample_prompts, - additional_parameters, - vae_batch_size, + save_as, + file_path, + pretrained_model_name_or_path, + v2, + v_parameterization, + logging_dir, + train_data_dir, + reg_data_dir, + output_dir, + max_resolution, + learning_rate, + lr_scheduler, + lr_warmup, + train_batch_size, + epoch, + save_every_n_epochs, + mixed_precision, + save_precision, + seed, + num_cpu_threads_per_process, + cache_latents, + caption_extension, + enable_bucket, + gradient_checkpointing, + full_fp16, + no_token_padding, + stop_text_encoder_training, + # use_8bit_adam, + xformers, + save_model_as, + shuffle_caption, + save_state, + resume, + prior_loss_weight, + color_aug, + flip_aug, + clip_skip, + vae, + output_name, + max_token_length, + max_train_epochs, + max_data_loader_n_workers, + mem_eff_attn, + gradient_accumulation_steps, + model_list, + keep_tokens, + persistent_data_loader_workers, + bucket_no_upscale, + random_crop, + bucket_reso_steps, + caption_dropout_every_n_epochs, + caption_dropout_rate, + optimizer, + optimizer_args, + noise_offset, + sample_every_n_steps, + sample_every_n_epochs, + sample_sampler, + sample_prompts, + additional_parameters, + vae_batch_size, ): # Get list of function parameters and values parameters = list(locals().items()) @@ -134,10 +135,10 @@ def save_configuration( name: value for name, value in parameters # locals().items() if name - not in [ - 'file_path', - 'save_as', - ] + not in [ + 'file_path', + 'save_as', + ] } # Extract the destination directory from the file path @@ -155,67 +156,67 @@ def save_configuration( def open_configuration( - ask_for_file, - file_path, - pretrained_model_name_or_path, - v2, - v_parameterization, - logging_dir, - train_data_dir, - reg_data_dir, - output_dir, - max_resolution, - learning_rate, - lr_scheduler, - lr_warmup, - train_batch_size, - epoch, - save_every_n_epochs, - mixed_precision, - save_precision, - seed, - num_cpu_threads_per_process, - cache_latents, - caption_extension, - enable_bucket, - gradient_checkpointing, - full_fp16, - no_token_padding, - stop_text_encoder_training, - # use_8bit_adam, - xformers, - save_model_as, - shuffle_caption, - save_state, - resume, - prior_loss_weight, - color_aug, - flip_aug, - clip_skip, - vae, - output_name, - max_token_length, - max_train_epochs, - max_data_loader_n_workers, - mem_eff_attn, - gradient_accumulation_steps, - model_list, - keep_tokens, - persistent_data_loader_workers, - bucket_no_upscale, - random_crop, - bucket_reso_steps, - caption_dropout_every_n_epochs, - caption_dropout_rate, - optimizer, - optimizer_args, - noise_offset, - sample_every_n_steps, - sample_every_n_epochs, - sample_sampler, - sample_prompts, - additional_parameters, - vae_batch_size, + ask_for_file, + file_path, + pretrained_model_name_or_path, + v2, + v_parameterization, + logging_dir, + train_data_dir, + reg_data_dir, + output_dir, + max_resolution, + learning_rate, + lr_scheduler, + lr_warmup, + train_batch_size, + epoch, + save_every_n_epochs, + mixed_precision, + save_precision, + seed, + num_cpu_threads_per_process, + cache_latents, + caption_extension, + enable_bucket, + gradient_checkpointing, + full_fp16, + no_token_padding, + stop_text_encoder_training, + # use_8bit_adam, + xformers, + save_model_as, + shuffle_caption, + save_state, + resume, + prior_loss_weight, + color_aug, + flip_aug, + clip_skip, + vae, + output_name, + max_token_length, + max_train_epochs, + max_data_loader_n_workers, + mem_eff_attn, + gradient_accumulation_steps, + model_list, + keep_tokens, + persistent_data_loader_workers, + bucket_no_upscale, + random_crop, + bucket_reso_steps, + caption_dropout_every_n_epochs, + caption_dropout_rate, + optimizer, + optimizer_args, + noise_offset, + sample_every_n_steps, + sample_every_n_epochs, + sample_sampler, + sample_prompts, + additional_parameters, + vae_batch_size, ): # Get list of function parameters and values parameters = list(locals().items()) @@ -225,17 +226,20 @@ def open_configuration( original_file_path = file_path if ask_for_file: - file_path = get_file_path(file_path) + file_path = get_file_path(file_path, filedialog_type="json") - if not file_path == '' and not file_path == None: - # load variables from JSON file + if not file_path == '' and file_path is not None: with open(file_path, 'r') as f: my_data = json.load(f) - print('Loading config...') - # Update values to fix deprecated use_8bit_adam checkbox and set appropriate optimizer if it is set to True - my_data = update_my_data(my_data) + if is_valid_config(my_data): + print('Loading config...') + my_data = update_my_data(my_data) + else: + print("Invalid configuration file.") + my_data = {} + show_message_box("Invalid configuration file.") else: - file_path = original_file_path # In case a file_path was provided and the user decide to cancel the open action + file_path = original_file_path my_data = {} values = [file_path] @@ -247,85 +251,85 @@ def open_configuration( def train_model( - pretrained_model_name_or_path, - v2, - v_parameterization, - logging_dir, - train_data_dir, - reg_data_dir, - output_dir, - max_resolution, - learning_rate, - lr_scheduler, - lr_warmup, - train_batch_size, - epoch, - save_every_n_epochs, - mixed_precision, - save_precision, - seed, - num_cpu_threads_per_process, - cache_latents, - caption_extension, - enable_bucket, - gradient_checkpointing, - full_fp16, - no_token_padding, - stop_text_encoder_training_pct, - # use_8bit_adam, - xformers, - save_model_as, - shuffle_caption, - save_state, - resume, - prior_loss_weight, - color_aug, - flip_aug, - clip_skip, - vae, - output_name, - max_token_length, - max_train_epochs, - max_data_loader_n_workers, - mem_eff_attn, - gradient_accumulation_steps, - model_list, # Keep this. Yes, it is unused here but required given the common list used - keep_tokens, - persistent_data_loader_workers, - bucket_no_upscale, - random_crop, - bucket_reso_steps, - caption_dropout_every_n_epochs, - caption_dropout_rate, - optimizer, - optimizer_args, - noise_offset, - sample_every_n_steps, - sample_every_n_epochs, - sample_sampler, - sample_prompts, - additional_parameters, - vae_batch_size, + pretrained_model_name_or_path, + v2, + v_parameterization, + logging_dir, + train_data_dir, + reg_data_dir, + output_dir, + max_resolution, + learning_rate, + lr_scheduler, + lr_warmup, + train_batch_size, + epoch, + save_every_n_epochs, + mixed_precision, + save_precision, + seed, + num_cpu_threads_per_process, + cache_latents, + caption_extension, + enable_bucket, + gradient_checkpointing, + full_fp16, + no_token_padding, + stop_text_encoder_training_pct, + # use_8bit_adam, + xformers, + save_model_as, + shuffle_caption, + save_state, + resume, + prior_loss_weight, + color_aug, + flip_aug, + clip_skip, + vae, + output_name, + max_token_length, + max_train_epochs, + max_data_loader_n_workers, + mem_eff_attn, + gradient_accumulation_steps, + model_list, # Keep this. Yes, it is unused here but required given the common list used + keep_tokens, + persistent_data_loader_workers, + bucket_no_upscale, + random_crop, + bucket_reso_steps, + caption_dropout_every_n_epochs, + caption_dropout_rate, + optimizer, + optimizer_args, + noise_offset, + sample_every_n_steps, + sample_every_n_epochs, + sample_sampler, + sample_prompts, + additional_parameters, + vae_batch_size, ): if pretrained_model_name_or_path == '': - msgbox('Source model information is missing') + show_message_box('Source model information is missing') return if train_data_dir == '': - msgbox('Image folder path is missing') + show_message_box('Image folder path is missing') return if not os.path.exists(train_data_dir): - msgbox('Image folder does not exist') + show_message_box('Image folder does not exist') return if reg_data_dir != '': if not os.path.exists(reg_data_dir): - msgbox('Regularisation folder does not exist') + show_message_box('Regularisation folder does not exist') return if output_dir == '': - msgbox('Output folder path is missing') + show_message_box('Output folder path is missing') return if check_if_model_exist(output_name, output_dir, save_model_as): @@ -351,7 +355,8 @@ def train_model( try: repeats = int(folder.split('_')[0]) except ValueError: - print('\033[33mSubfolder', folder, 'does not have a proper repeat value, please correct the name or remove it... can\'t train...\033[0m') + print('\033[33mSubfolder', folder, + 'does not have a proper repeat value, please correct the name or remove it... can\'t train...\033[0m') continue # Count the number of images in the folder @@ -360,12 +365,12 @@ def train_model( f for f in os.listdir(os.path.join(train_data_dir, folder)) if f.endswith('.jpg') - or f.endswith('.jpeg') - or f.endswith('.png') - or f.endswith('.webp') + or f.endswith('.jpeg') + or f.endswith('.png') + or f.endswith('.webp') ] ) - + if num_images == 0: print(f'{folder} folder contain no images, skipping...') else: @@ -525,10 +530,10 @@ def train_model( def dreambooth_tab( - train_data_dir=gr.Textbox(), - reg_data_dir=gr.Textbox(), - output_dir=gr.Textbox(), - logging_dir=gr.Textbox(), + train_data_dir=gr.Textbox(), + reg_data_dir=gr.Textbox(), + output_dir=gr.Textbox(), + logging_dir=gr.Textbox(), ): dummy_db_true = gr.Label(value=True, visible=False) dummy_db_false = gr.Label(value=False, visible=False) diff --git a/library/basic_caption_gui.py b/library/basic_caption_gui.py index b2d208d..d36dae1 100644 --- a/library/basic_caption_gui.py +++ b/library/basic_caption_gui.py @@ -1,8 +1,9 @@ -import gradio as gr -from easygui import msgbox -import subprocess -from .common_gui import get_folder_path, add_pre_postfix, find_replace import os +import subprocess + +import gradio as gr + +from .common_gui import get_folder_path, add_pre_postfix, find_replace def caption_images( @@ -17,11 +18,11 @@ def caption_images( ): # Check for images_dir if not images_dir: - msgbox('Image folder is missing...') + show_message_box('Image folder is missing...') return if not caption_ext: - msgbox('Please provide an extension for the caption files.') + show_message_box('Please provide an extension for the caption files.') return if caption_text: @@ -60,7 +61,7 @@ def caption_images( ) else: if prefix or postfix: - msgbox( + show_message_box( 'Could not modify caption files with requested change because the "Overwrite existing captions in folder" option is not selected...' ) diff --git a/library/blip_caption_gui.py b/library/blip_caption_gui.py index 2e0081d..35fd513 100644 --- a/library/blip_caption_gui.py +++ b/library/blip_caption_gui.py @@ -1,7 +1,8 @@ -import gradio as gr -from easygui import msgbox -import subprocess import os +import subprocess + +import gradio as gr + from .common_gui import get_folder_path, add_pre_postfix PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' @@ -21,16 +22,16 @@ def caption_images( ): # Check for caption_text_input # if caption_text_input == "": - # msgbox("Caption text is missing...") + # show_message_box("Caption text is missing...") # return # Check for images_dir_input if train_data_dir == '': - msgbox('Image folder is missing...') + show_message_box('Image folder is missing...') return if caption_file_ext == '': - msgbox('Please provide an extension for the caption files.') + show_message_box('Please provide an extension for the caption files.') return print(f'Captioning files in {train_data_dir}...') diff --git a/library/common_gui.py b/library/common_gui.py index 25e7379..f47dfcc 100644 --- a/library/common_gui.py +++ b/library/common_gui.py @@ -1,14 +1,17 @@ -from tkinter import filedialog, Tk -from easygui import msgbox import os -import gradio as gr -import easygui import shutil +import subprocess +from tkinter import filedialog, Tk + +import easygui +import gradio as gr + +from library.gui_subprocesses import save_file_dialog folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 save_style_symbol = '\U0001f4be' # 💾 -document_symbol = '\U0001F4C4' # 📄 +document_symbol = '\U0001F4C4' # 📄 # define a list of substrings to search for v2 base models V2_BASE_MODELS = [ @@ -34,6 +37,31 @@ ALL_PRESET_MODELS = V2_BASE_MODELS + V_PARAMETERIZATION_MODELS + V1_MODELS FILE_ENV_EXCLUSION = ['COLAB_GPU', 'RUNPOD_ENVIRONMENT'] +def open_file_dialog(initial_dir, initial_file, file_types="all"): + current_directory = os.path.dirname(os.path.abspath(__file__)) + + args = ["python", f"{current_directory}/gui_subprocesses.py", "file_dialog"] + if initial_dir: + args.append(initial_dir) + if initial_file: + args.append(initial_file) + if file_types: + args.append(file_types) + + file_path = subprocess.check_output(args).decode("utf-8").strip() + return file_path + + +def show_message_box(message, title=""): + current_directory = os.path.dirname(os.path.abspath(__file__)) + + args = ["python", f"{current_directory}/gui_subprocesses.py", "msgbox", message] + if title: + args.append(title) + + subprocess.run(args) + + def check_if_model_exist(output_name, output_dir, save_model_as): if save_model_as in ['diffusers', 'diffusers_safetendors']: ckpt_folder = os.path.join(output_dir, output_name) @@ -62,6 +90,22 @@ def check_if_model_exist(output_name, output_dir, save_model_as): return False +def is_valid_config(data): + # Check if the data is a dictionary + if not isinstance(data, dict): + return False + + # Add checks for expected keys and valid values + # For example, check if 'use_8bit_adam' is a boolean + if "use_8bit_adam" in data and not isinstance(data["use_8bit_adam"], bool): + return False + + # Add more checks for other keys as needed + + # If all checks pass, return True + return True + + def update_my_data(my_data): # Update the optimizer based on the use_8bit_adam flag use_8bit_adam = my_data.get('use_8bit_adam', False) @@ -87,8 +131,8 @@ def update_my_data(my_data): # Update model save choices due to changes for LoRA and TI training if ( - (my_data.get('LoRA_type') or my_data.get('num_vectors_per_token')) - and my_data.get('save_model_as') not in ['safetensors', 'ckpt'] + (my_data.get('LoRA_type') or my_data.get('num_vectors_per_token')) + and my_data.get('save_model_as') not in ['safetensors', 'ckpt'] ): message = ( 'Updating save_model_as to safetensors because the current value in the config file is no longer applicable to {}' @@ -102,11 +146,6 @@ def update_my_data(my_data): return my_data -def get_dir_and_file(file_path): - dir_path, file_name = os.path.split(file_path) - return (dir_path, file_name) - - # def has_ext_files(directory, extension): # # Iterate through all the files in the directory # for file in os.listdir(directory): @@ -117,67 +156,36 @@ def get_dir_and_file(file_path): # return False -def get_file_path( - file_path='', default_extension='.json', extension_name='Config files' -): - if not any(var in os.environ for var in FILE_ENV_EXCLUSION): - current_file_path = file_path - # print(f'current file path: {current_file_path}') +def get_file_path(file_path='', filedialog_type="lora"): + current_file_path = file_path - initial_dir, initial_file = get_dir_and_file(file_path) + initial_dir, initial_file = os.path.split(file_path) + file_path = open_file_dialog(initial_dir, initial_file, file_types=filedialog_type) - # Create a hidden Tkinter root window - root = Tk() - root.wm_attributes('-topmost', 1) - root.withdraw() - - # Show the open file dialog and get the selected file path - file_path = filedialog.askopenfilename( - filetypes=( - (extension_name, f'*{default_extension}'), - ('All files', '*.*'), - ), - defaultextension=default_extension, - initialfile=initial_file, - initialdir=initial_dir, - ) - - # Destroy the hidden root window - root.destroy() - - # If no file is selected, use the current file path - if not file_path: - file_path = current_file_path - current_file_path = file_path - # print(f'current file path: {current_file_path}') + # If no file is selected, use the current file path + if not file_path: + file_path = current_file_path + current_file_path = file_path return file_path + def get_any_file_path(file_path=''): - if not any(var in os.environ for var in FILE_ENV_EXCLUSION): - current_file_path = file_path - # print(f'current file path: {current_file_path}') + current_file_path = file_path + # print(f'current file path: {current_file_path}') - initial_dir, initial_file = get_dir_and_file(file_path) + initial_dir, initial_file = os.path.split(file_path) + file_path = open_file_dialog(initial_dir, initial_file, "all") - root = Tk() - root.wm_attributes('-topmost', 1) - root.withdraw() - file_path = filedialog.askopenfilename( - initialdir=initial_dir, - initialfile=initial_file, - ) - root.destroy() - - if file_path == '': - file_path = current_file_path + if file_path == '': + file_path = current_file_path return file_path def remove_doublequote(file_path): - if file_path != None: + if file_path is not None: file_path = file_path.replace('"', '') return file_path @@ -196,62 +204,37 @@ def remove_doublequote(file_path): # ) -def get_folder_path(folder_path=''): - if not any(var in os.environ for var in FILE_ENV_EXCLUSION): - current_folder_path = folder_path +def get_folder_path(folder_path='', filedialog_type="directory"): + current_folder_path = folder_path - initial_dir, initial_file = get_dir_and_file(folder_path) + initial_dir, initial_file = os.path.split(folder_path) + file_path = open_file_dialog(initial_dir, initial_file, filedialog_type) - root = Tk() - root.wm_attributes('-topmost', 1) - root.withdraw() - folder_path = filedialog.askdirectory(initialdir=initial_dir) - root.destroy() - - if folder_path == '': - folder_path = current_folder_path + if folder_path == '': + folder_path = current_folder_path return folder_path def get_saveasfile_path( - file_path='', defaultextension='.json', extension_name='Config files' + file_path='', filedialog_type="json" ): - if not any(var in os.environ for var in FILE_ENV_EXCLUSION): - current_file_path = file_path - # print(f'current file path: {current_file_path}') + current_file_path = file_path - initial_dir, initial_file = get_dir_and_file(file_path) + initial_dir, initial_file = os.path.split(file_path) + save_file_path = save_file_dialog(initial_dir, initial_file, filedialog_type) - root = Tk() - root.wm_attributes('-topmost', 1) - root.withdraw() - save_file_path = filedialog.asksaveasfile( - filetypes=( - (f'{extension_name}', f'{defaultextension}'), - ('All files', '*'), - ), - defaultextension=defaultextension, - initialdir=initial_dir, - initialfile=initial_file, - ) - root.destroy() - - # print(save_file_path) - - if save_file_path == None: - file_path = current_file_path - else: - print(save_file_path.name) - file_path = save_file_path.name - - # print(file_path) + if save_file_path is None: + file_path = current_file_path + else: + print(save_file_path.name) + file_path = save_file_path.name return file_path def get_saveasfilename_path( - file_path='', extensions='*', extension_name='Config files' + file_path='', extensions='*', extension_name='Config files' ): if not any(var in os.environ for var in FILE_ENV_EXCLUSION): current_file_path = file_path @@ -280,10 +263,10 @@ def get_saveasfilename_path( def add_pre_postfix( - folder: str = '', - prefix: str = '', - postfix: str = '', - caption_file_ext: str = '.caption', + folder: str = '', + prefix: str = '', + postfix: str = '', + caption_file_ext: str = '.caption', ) -> None: """ Add prefix and/or postfix to the content of caption files within a folder. @@ -343,10 +326,10 @@ def has_ext_files(folder_path: str, file_extension: str) -> bool: def find_replace( - folder_path: str = '', - caption_file_ext: str = '.caption', - search_text: str = '', - replace_text: str = '', + folder_path: str = '', + caption_file_ext: str = '.caption', + search_text: str = '', + replace_text: str = '', ) -> None: """ Find and replace text in caption files within a folder. @@ -360,7 +343,7 @@ def find_replace( print('Running caption find/replace') if not has_ext_files(folder_path, caption_file_ext): - msgbox( + show_message_box( f'No files with extension {caption_file_ext} were found in {folder_path}...' ) return @@ -374,7 +357,7 @@ def find_replace( for caption_file in caption_files: with open( - os.path.join(folder_path, caption_file), 'r', errors='ignore' + os.path.join(folder_path, caption_file), 'r', errors='ignore' ) as f: content = f.read() @@ -386,7 +369,7 @@ def find_replace( def color_aug_changed(color_aug): if color_aug: - msgbox( + show_message_box( 'Disabling "Cache latent" because "Color augmentation" has been selected...' ) return gr.Checkbox.update(value=False, interactive=False) @@ -427,7 +410,7 @@ def save_inference_file(output_dir, v2, v_parameterization, output_name): def set_pretrained_model_name_or_path_input( - model_list, pretrained_model_name_or_path, v2, v_parameterization + model_list, pretrained_model_name_or_path, v2, v_parameterization ): # check if $v2 and $v_parameterization are empty and if $pretrained_model_name_or_path contains any of the substrings in the v2 list if str(model_list) in V2_BASE_MODELS: @@ -452,9 +435,9 @@ def set_pretrained_model_name_or_path_input( if model_list == 'custom': if ( - str(pretrained_model_name_or_path) in V1_MODELS - or str(pretrained_model_name_or_path) in V2_BASE_MODELS - or str(pretrained_model_name_or_path) in V_PARAMETERIZATION_MODELS + str(pretrained_model_name_or_path) in V1_MODELS + or str(pretrained_model_name_or_path) in V2_BASE_MODELS + or str(pretrained_model_name_or_path) in V_PARAMETERIZATION_MODELS ): pretrained_model_name_or_path = '' v2 = False @@ -481,12 +464,11 @@ def set_v2_checkbox(model_list, v2, v_parameterization): def set_model_list( - model_list, - pretrained_model_name_or_path, - v2, - v_parameterization, + model_list, + pretrained_model_name_or_path, + v2, + v_parameterization, ): - if not pretrained_model_name_or_path in ALL_PRESET_MODELS: model_list = 'custom' else: @@ -529,7 +511,7 @@ def gradio_config(): def get_pretrained_model_name_or_path_file( - model_list, pretrained_model_name_or_path + model_list, pretrained_model_name_or_path ): pretrained_model_name_or_path = get_any_file_path( pretrained_model_name_or_path @@ -537,13 +519,13 @@ def get_pretrained_model_name_or_path_file( set_model_list(model_list, pretrained_model_name_or_path) -def gradio_source_model(save_model_as_choices = [ - 'same as source model', - 'ckpt', - 'diffusers', - 'diffusers_safetensors', - 'safetensors', - ]): +def gradio_source_model(save_model_as_choices=[ + 'same as source model', + 'ckpt', + 'diffusers', + 'diffusers_safetensors', + 'safetensors', +]): with gr.Tab('Source model'): # Define the input elements with gr.Row(): @@ -648,9 +630,9 @@ def gradio_source_model(save_model_as_choices = [ def gradio_training( - learning_rate_value='1e-6', - lr_scheduler_value='constant', - lr_warmup_value='0', + learning_rate_value='1e-6', + lr_scheduler_value='constant', + lr_warmup_value='0', ): with gr.Row(): train_batch_size = gr.Slider( diff --git a/library/convert_model_gui.py b/library/convert_model_gui.py index aaa39b8..dd43b0e 100644 --- a/library/convert_model_gui.py +++ b/library/convert_model_gui.py @@ -1,8 +1,9 @@ -import gradio as gr -from easygui import msgbox -import subprocess import os import shutil +import subprocess + +import gradio as gr + from .common_gui import get_folder_path, get_file_path folder_symbol = '\U0001f4c2' # 📂 @@ -22,7 +23,7 @@ def convert_model( ): # Check for caption_text_input if source_model_type == '': - msgbox('Invalid source model type') + show_message_box('Invalid source model type') return # Check if source model exist @@ -31,14 +32,14 @@ def convert_model( elif os.path.isdir(source_model_input): print('The provided model is a folder') else: - msgbox('The provided source model is neither a file nor a folder') + show_message_box('The provided source model is neither a file nor a folder') return # Check if source model exist if os.path.isdir(target_model_folder_input): print('The provided model folder exist') else: - msgbox('The provided target folder does not exist') + show_message_box('The provided target folder does not exist') return run_cmd = f'{PYTHON} "tools/convert_diffusers20_original_sd.py"' diff --git a/library/dataset_balancing_gui.py b/library/dataset_balancing_gui.py index 2e6bc98..34292f6 100644 --- a/library/dataset_balancing_gui.py +++ b/library/dataset_balancing_gui.py @@ -1,9 +1,12 @@ import os import re + import gradio as gr -from easygui import msgbox, boolbox +from easygui import boolbox + from .common_gui import get_folder_path + # def select_folder(): # # Open a file dialog to select a directory # folder = filedialog.askdirectory() @@ -16,14 +19,14 @@ def dataset_balancing(concept_repeats, folder, insecure): if not concept_repeats > 0: # Display an error message if the total number of repeats is not a valid integer - msgbox('Please enter a valid integer for the total number of repeats.') + show_message_box('Please enter a valid integer for the total number of repeats.') return concept_repeats = int(concept_repeats) # Check if folder exist if folder == '' or not os.path.isdir(folder): - msgbox('Please enter a valid folder for balancing.') + show_message_box('Please enter a valid folder for balancing.') return pattern = re.compile(r'^\d+_.+$') @@ -85,7 +88,7 @@ def dataset_balancing(concept_repeats, folder, insecure): f'Skipping folder {subdir} because it does not match kohya_ss expected syntax...' ) - msgbox('Dataset balancing completed...') + show_message_box('Dataset balancing completed...') def warning(insecure): diff --git a/library/dreambooth_folder_creation_gui.py b/library/dreambooth_folder_creation_gui.py index b5d5ff4..53ec71a 100644 --- a/library/dreambooth_folder_creation_gui.py +++ b/library/dreambooth_folder_creation_gui.py @@ -1,8 +1,9 @@ -import gradio as gr -from easygui import diropenbox, msgbox -from .common_gui import get_folder_path -import shutil import os +import shutil + +import gradio as gr + +from .common_gui import get_folder_path def copy_info_to_Folders_tab(training_folder): @@ -39,12 +40,12 @@ def dreambooth_folder_preparation( # Check for instance prompt if util_instance_prompt_input == '': - msgbox('Instance prompt missing...') + show_message_box('Instance prompt missing...') return # Check for class prompt if util_class_prompt_input == '': - msgbox('Class prompt missing...') + show_message_box('Class prompt missing...') return # Create the training_dir path diff --git a/library/extract_lora_gui.py b/library/extract_lora_gui.py index 5f48686..6a5df1b 100644 --- a/library/extract_lora_gui.py +++ b/library/extract_lora_gui.py @@ -1,11 +1,10 @@ -import gradio as gr -from easygui import msgbox -import subprocess import os +import subprocess + +import gradio as gr + from .common_gui import ( - get_saveasfilename_path, - get_any_file_path, - get_file_path, + get_file_path, get_saveasfile_path, ) folder_symbol = '\U0001f4c2' # 📂 @@ -27,20 +26,20 @@ def extract_lora( ): # Check for caption_text_input if model_tuned == '': - msgbox('Invalid finetuned model file') + show_message_box('Invalid finetuned model file') return if model_org == '': - msgbox('Invalid base model file') + show_message_box('Invalid base model file') return # Check if source model exist if not os.path.isfile(model_tuned): - msgbox('The provided finetuned model is not a file') + show_message_box('The provided finetuned model is not a file') return if not os.path.isfile(model_org): - msgbox('The provided base model is not a file') + show_message_box('The provided base model is not a file') return run_cmd = ( @@ -121,7 +120,7 @@ def gradio_extract_lora_tab(): folder_symbol, elem_id='open_folder_small' ) button_save_to.click( - get_saveasfilename_path, + get_saveasfile_path, inputs=[save_to, lora_ext, lora_ext_name], outputs=save_to, show_progress=False, diff --git a/library/extract_lycoris_locon_gui.py b/library/extract_lycoris_locon_gui.py index 13575bb..f95bf96 100644 --- a/library/extract_lycoris_locon_gui.py +++ b/library/extract_lycoris_locon_gui.py @@ -1,11 +1,10 @@ -import gradio as gr -from easygui import msgbox -import subprocess import os +import subprocess + +import gradio as gr + from .common_gui import ( - get_saveasfilename_path, - get_any_file_path, - get_file_path, + get_file_path, get_saveasfile_path, ) folder_symbol = '\U0001f4c2' # 📂 @@ -36,20 +35,20 @@ def extract_lycoris_locon( ): # Check for caption_text_input if db_model == '': - msgbox('Invalid finetuned model file') + show_message_box('Invalid finetuned model file') return if base_model == '': - msgbox('Invalid base model file') + show_message_box('Invalid base model file') return # Check if source model exist if not os.path.isfile(db_model): - msgbox('The provided finetuned model is not a file') + show_message_box('The provided finetuned model is not a file') return if not os.path.isfile(base_model): - msgbox('The provided base model is not a file') + show_message_box('The provided base model is not a file') return run_cmd = f'{PYTHON} "{os.path.join("tools","lycoris_locon_extract.py")}"' @@ -167,7 +166,7 @@ def gradio_extract_lycoris_locon_tab(): folder_symbol, elem_id='open_folder_small' ) button_output_name.click( - get_saveasfilename_path, + get_saveasfile_path, inputs=[output_name, lora_ext, lora_ext_name], outputs=output_name, show_progress=False, diff --git a/library/git_caption_gui.py b/library/git_caption_gui.py index 9aaf3d9..4ef87b4 100644 --- a/library/git_caption_gui.py +++ b/library/git_caption_gui.py @@ -1,7 +1,8 @@ -import gradio as gr -from easygui import msgbox -import subprocess import os +import subprocess + +import gradio as gr + from .common_gui import get_folder_path, add_pre_postfix PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' @@ -19,11 +20,11 @@ def caption_images( ): # Check for images_dir_input if train_data_dir == '': - msgbox('Image folder is missing...') + show_message_box('Image folder is missing...') return if caption_ext == '': - msgbox('Please provide an extension for the caption files.') + show_message_box('Please provide an extension for the caption files.') return print(f'GIT captioning files in {train_data_dir}...') diff --git a/library/gui_subprocesses.py b/library/gui_subprocesses.py new file mode 100644 index 0000000..87e65fc --- /dev/null +++ b/library/gui_subprocesses.py @@ -0,0 +1,84 @@ +import sys +import tkinter as tk +from tkinter import filedialog, messagebox + + +def open_file_dialog(initial_dir=None, initial_file=None, file_types="all"): + file_type_filters = { + "all": [("All files", "*.*")], + "video": [("Video files", "*.mp4;*.avi;*.mkv;*.mov;*.flv;*.wmv")], + "images": [("Image files", "*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff")], + "json": [("JSON files", "*.json")], + "lora": [("LoRa files", "*.ckpt;*.pt;*.safetensors")], + "directory": [], + } + + if file_types in file_type_filters: + filters = file_type_filters[file_types] + else: + filters = file_type_filters["all"] + + if file_types == "directory": + return filedialog.askdirectory(initialdir=initial_dir) + else: + return filedialog.askopenfilename(initialdir=initial_dir, initialfile=initial_file, filetypes=filters) + + +def save_file_dialog(initial_dir, initial_file, files_type="all"): + root = tk.Tk() + root.withdraw() + + filetypes_switch = { + "all": [("All files", "*.*")], + "video": [("Video files", "*.mp4;*.avi;*.mkv;*.webm;*.flv;*.mov;*.wmv")], + "images": [("Image files", "*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff;*.ico")], + "json": [("JSON files", "*.json")], + "lora": [("LoRa files", "*.ckpt;*.pt;*.safetensors")], + } + + filetypes = filetypes_switch.get(files_type, filetypes_switch["all"]) + save_file_path = filedialog.asksaveasfilename(initialdir=initial_dir, initialfile=initial_file, filetypes=filetypes, + defaultextension=filetypes) + + root.destroy() + + return save_file_path + + +def show_message_box(_message, _title="Message", _level="info"): + root = tk.Tk() + root.withdraw() + + message_type = { + "warning": messagebox.showwarning, + "error": messagebox.showerror, + "info": messagebox.showinfo, + "question": messagebox.askquestion, + "okcancel": messagebox.askokcancel, + "retrycancel": messagebox.askretrycancel, + "yesno": messagebox.askyesno, + "yesnocancel": messagebox.askyesnocancel + } + + if _level in message_type: + message_type[_level](_title, _message) + else: + messagebox.showinfo(_title, _message) + + root.destroy() + + +if __name__ == '__main__': + mode = sys.argv[1] + + if mode == 'file_dialog': + starting_dir = sys.argv[2] if len(sys.argv) > 2 else None + starting_file = sys.argv[3] if len(sys.argv) > 3 else None + file_class = sys.argv[2] if len(sys.argv) > 2 else None + file_path = open_file_dialog(starting_dir, starting_file, file_class) + print(file_path) + + elif mode == 'msgbox': + message = sys.argv[2] + title = sys.argv[3] if len(sys.argv) > 3 else "" + show_message_box(message, title) diff --git a/library/merge_lora_gui.py b/library/merge_lora_gui.py index 21cd16a..e5f6b9b 100644 --- a/library/merge_lora_gui.py +++ b/library/merge_lora_gui.py @@ -1,11 +1,10 @@ -import gradio as gr -from easygui import msgbox -import subprocess import os +import subprocess + +import gradio as gr + from .common_gui import ( - get_saveasfilename_path, - get_any_file_path, - get_file_path, + get_file_path, get_saveasfile_path, ) folder_symbol = '\U0001f4c2' # 📂 @@ -25,20 +24,20 @@ def merge_lora( ): # Check for caption_text_input if lora_a_model == '': - msgbox('Invalid model A file') + show_message_box('Invalid model A file') return if lora_b_model == '': - msgbox('Invalid model B file') + show_message_box('Invalid model B file') return # Check if source model exist if not os.path.isfile(lora_a_model): - msgbox('The provided model A is not a file') + show_message_box('The provided model A is not a file') return if not os.path.isfile(lora_b_model): - msgbox('The provided model B is not a file') + show_message_box('The provided model B is not a file') return ratio_a = ratio @@ -122,7 +121,7 @@ def gradio_merge_lora_tab(): folder_symbol, elem_id='open_folder_small' ) button_save_to.click( - get_saveasfilename_path, + get_saveasfile_path, inputs=[save_to, lora_ext, lora_ext_name], outputs=save_to, show_progress=False, diff --git a/library/resize_lora_gui.py b/library/resize_lora_gui.py index 05a7734..a47e407 100644 --- a/library/resize_lora_gui.py +++ b/library/resize_lora_gui.py @@ -1,8 +1,9 @@ -import gradio as gr -from easygui import msgbox -import subprocess import os -from .common_gui import get_saveasfilename_path, get_file_path +import subprocess + +import gradio as gr + +from .common_gui import get_file_path, get_saveasfile_path PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' folder_symbol = '\U0001f4c2' # 📂 @@ -23,24 +24,24 @@ def resize_lora( ): # Check for caption_text_input if model == '': - msgbox('Invalid model file') + show_message_box('Invalid model file') return # Check if source model exist if not os.path.isfile(model): - msgbox('The provided model is not a file') + show_message_box('The provided model is not a file') return if dynamic_method == 'sv_ratio': if float(dynamic_param) < 2: - msgbox( + show_message_box( f'Dynamic parameter for {dynamic_method} need to be 2 or greater...' ) return if dynamic_method == 'sv_fro' or dynamic_method == 'sv_cumulative': if float(dynamic_param) < 0 or float(dynamic_param) > 1: - msgbox( + show_message_box( f'Dynamic parameter for {dynamic_method} need to be between 0 and 1...' ) return @@ -134,7 +135,7 @@ def gradio_resize_lora_tab(): folder_symbol, elem_id='open_folder_small' ) button_save_to.click( - get_saveasfilename_path, + get_saveasfile_path, inputs=[save_to, lora_ext, lora_ext_name], outputs=save_to, show_progress=False, diff --git a/library/sampler_gui.py b/library/sampler_gui.py index ce95313..c1ba146 100644 --- a/library/sampler_gui.py +++ b/library/sampler_gui.py @@ -1,7 +1,6 @@ import tempfile import os import gradio as gr -from easygui import msgbox folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 diff --git a/library/svd_merge_lora_gui.py b/library/svd_merge_lora_gui.py index 042be2e..a2b040c 100644 --- a/library/svd_merge_lora_gui.py +++ b/library/svd_merge_lora_gui.py @@ -1,11 +1,10 @@ -import gradio as gr -from easygui import msgbox -import subprocess import os +import subprocess + +import gradio as gr + from .common_gui import ( - get_saveasfilename_path, - get_any_file_path, - get_file_path, + get_file_path, get_saveasfile_path, ) folder_symbol = '\U0001f4c2' # 📂 @@ -28,20 +27,20 @@ def svd_merge_lora( ): # Check for caption_text_input if lora_a_model == '': - msgbox('Invalid model A file') + show_message_box('Invalid model A file') return if lora_b_model == '': - msgbox('Invalid model B file') + show_message_box('Invalid model B file') return # Check if source model exist if not os.path.isfile(lora_a_model): - msgbox('The provided model A is not a file') + show_message_box('The provided model A is not a file') return if not os.path.isfile(lora_b_model): - msgbox('The provided model B is not a file') + show_message_box('The provided model B is not a file') return ratio_a = ratio @@ -144,7 +143,7 @@ def gradio_svd_merge_lora_tab(): folder_symbol, elem_id='open_folder_small' ) button_save_to.click( - get_saveasfilename_path, + get_saveasfile_path, inputs=[save_to, lora_ext, lora_ext_name], outputs=save_to, show_progress=False, diff --git a/library/tensorboard_gui.py b/library/tensorboard_gui.py index d08a02d..f2dd74f 100644 --- a/library/tensorboard_gui.py +++ b/library/tensorboard_gui.py @@ -1,9 +1,9 @@ import os -import gradio as gr -from easygui import msgbox import subprocess import time +import gradio as gr + tensorboard_proc = None # I know... bad but heh TENSORBOARD = 'tensorboard' if os.name == 'posix' else 'tensorboard.exe' @@ -13,7 +13,7 @@ def start_tensorboard(logging_dir): if not os.listdir(logging_dir): print('Error: log folder is empty') - msgbox(msg='Error: log folder is empty') + show_message_box(msg='Error: log folder is empty') return run_cmd = [f'{TENSORBOARD}', '--logdir', f'{logging_dir}'] diff --git a/library/verify_lora_gui.py b/library/verify_lora_gui.py index a7a0bf9..a72160e 100644 --- a/library/verify_lora_gui.py +++ b/library/verify_lora_gui.py @@ -1,10 +1,9 @@ -import gradio as gr -from easygui import msgbox -import subprocess import os +import subprocess + +import gradio as gr + from .common_gui import ( - get_saveasfilename_path, - get_any_file_path, get_file_path, ) @@ -20,12 +19,12 @@ def verify_lora( ): # verify for caption_text_input if lora_model == '': - msgbox('Invalid model A file') + show_message_box('Invalid model A file') return # verify if source model exist if not os.path.isfile(lora_model): - msgbox('The provided model A is not a file') + show_message_box('The provided model A is not a file') return run_cmd = [ diff --git a/library/wd14_caption_gui.py b/library/wd14_caption_gui.py index 1970849..a9f7742 100644 --- a/library/wd14_caption_gui.py +++ b/library/wd14_caption_gui.py @@ -1,8 +1,9 @@ -import gradio as gr -from easygui import msgbox -import subprocess -from .common_gui import get_folder_path import os +import subprocess + +import gradio as gr + +from .common_gui import get_folder_path def replace_underscore_with_space(folder_path, file_extension): @@ -20,16 +21,16 @@ def caption_images( ): # Check for caption_text_input # if caption_text_input == "": - # msgbox("Caption text is missing...") + # show_message_box("Caption text is missing...") # return # Check for images_dir_input if train_data_dir == '': - msgbox('Image folder is missing...') + show_message_box('Image folder is missing...') return if caption_extension == '': - msgbox('Please provide an extension for the caption files.') + show_message_box('Please provide an extension for the caption files.') return print(f'Captioning files in {train_data_dir}...') diff --git a/lora_gui.py b/lora_gui.py index e7ada89..819927c 100644 --- a/lora_gui.py +++ b/lora_gui.py @@ -3,14 +3,15 @@ # v3: Add new Utilities tab for Dreambooth folder preparation # v3.1: Adding captionning of images to utilities -import gradio as gr -import easygui +import argparse import json import math import os -import subprocess import pathlib -import argparse +import subprocess + +import gradio as gr + from library.common_gui import ( get_folder_path, remove_doublequote, @@ -27,24 +28,23 @@ from library.common_gui import ( run_cmd_training, # set_legacy_8bitadam, update_my_data, - check_if_model_exist, + check_if_model_exist, show_message_box, ) +from library.dataset_balancing_gui import gradio_dataset_balancing_tab from library.dreambooth_folder_creation_gui import ( gradio_dreambooth_folder_creation_tab, ) +from library.merge_lora_gui import gradio_merge_lora_tab +from library.resize_lora_gui import gradio_resize_lora_tab +from library.sampler_gui import sample_gradio_config, run_cmd_sample +from library.svd_merge_lora_gui import gradio_svd_merge_lora_tab from library.tensorboard_gui import ( gradio_tensorboard, start_tensorboard, stop_tensorboard, ) -from library.dataset_balancing_gui import gradio_dataset_balancing_tab from library.utilities import utilities_tab -from library.merge_lora_gui import gradio_merge_lora_tab -from library.svd_merge_lora_gui import gradio_svd_merge_lora_tab from library.verify_lora_gui import gradio_verify_lora_tab -from library.resize_lora_gui import gradio_resize_lora_tab -from library.sampler_gui import sample_gradio_config, run_cmd_sample -from easygui import msgbox folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 @@ -353,35 +353,35 @@ def train_model( print_only_bool = True if print_only.get('label') == 'True' else False if pretrained_model_name_or_path == '': - msgbox('Source model information is missing') + show_message_box('Source model information is missing') return if train_data_dir == '': - msgbox('Image folder path is missing') + show_message_box('Image folder path is missing') return if not os.path.exists(train_data_dir): - msgbox('Image folder does not exist') + show_message_box('Image folder does not exist') return if reg_data_dir != '': if not os.path.exists(reg_data_dir): - msgbox('Regularisation folder does not exist') + show_message_box('Regularisation folder does not exist') return if output_dir == '': - msgbox('Output folder path is missing') + show_message_box('Output folder path is missing') return if int(bucket_reso_steps) < 1: - msgbox('Bucket resolution steps need to be greater than 0') + show_message_box('Bucket resolution steps need to be greater than 0') return if not os.path.exists(output_dir): os.makedirs(output_dir) if stop_text_encoder_training_pct > 0: - msgbox( + show_message_box( 'Output "stop text encoder training" is not yet supported. Ignoring' ) stop_text_encoder_training_pct = 0 @@ -396,7 +396,7 @@ def train_model( unet_lr = 0 # if (float(text_encoder_lr) == 0) and (float(unet_lr) == 0): - # msgbox( + # show_message_box( # 'At least one Learning Rate value for "Text encoder" or "Unet" need to be provided' # ) # return @@ -532,7 +532,7 @@ def train_model( run_cmd += f' --network_train_unet_only' else: if float(text_encoder_lr) == 0: - msgbox('Please input learning rate values.') + show_message_box('Please input learning rate values.') return run_cmd += f' --network_dim={network_dim}' diff --git a/textual_inversion_gui.py b/textual_inversion_gui.py index 7b8c19c..f48904a 100644 --- a/textual_inversion_gui.py +++ b/textual_inversion_gui.py @@ -3,13 +3,15 @@ # v3: Add new Utilities tab for Dreambooth folder preparation # v3.1: Adding captionning of images to utilities -import gradio as gr +import argparse import json import math import os -import subprocess import pathlib -import argparse +import subprocess + +import gradio as gr + from library.common_gui import ( get_folder_path, remove_doublequote, @@ -28,17 +30,16 @@ from library.common_gui import ( update_my_data, check_if_model_exist, ) +from library.dreambooth_folder_creation_gui import ( + gradio_dreambooth_folder_creation_tab, +) +from library.sampler_gui import sample_gradio_config, run_cmd_sample from library.tensorboard_gui import ( gradio_tensorboard, start_tensorboard, stop_tensorboard, ) -from library.dreambooth_folder_creation_gui import ( - gradio_dreambooth_folder_creation_tab, -) from library.utilities import utilities_tab -from library.sampler_gui import sample_gradio_config, run_cmd_sample -from easygui import msgbox folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 @@ -323,32 +324,32 @@ def train_model( additional_parameters,vae_batch_size, ): if pretrained_model_name_or_path == '': - msgbox('Source model information is missing') + show_message_box('Source model information is missing') return if train_data_dir == '': - msgbox('Image folder path is missing') + show_message_box('Image folder path is missing') return if not os.path.exists(train_data_dir): - msgbox('Image folder does not exist') + show_message_box('Image folder does not exist') return if reg_data_dir != '': if not os.path.exists(reg_data_dir): - msgbox('Regularisation folder does not exist') + show_message_box('Regularisation folder does not exist') return if output_dir == '': - msgbox('Output folder path is missing') + show_message_box('Output folder path is missing') return if token_string == '': - msgbox('Token string is missing') + show_message_box('Token string is missing') return if init_word == '': - msgbox('Init word is missing') + show_message_box('Init word is missing') return if not os.path.exists(output_dir):