diff --git a/README-ja.md b/README-ja.md index 064464c..319efe9 100644 --- a/README-ja.md +++ b/README-ja.md @@ -38,6 +38,18 @@ PowerShellを使う場合、venvを使えるようにするためには以下の - 「Set-ExecutionPolicy Unrestricted」と入力し、Yと答えます。 - 管理者のPowerShellを閉じます。 +## Ubuntu環境でのインストール + +``` +git clone https://github.com/kohya-ss/sd-scripts.git +cd sd-scripts +bash ubuntu_setup.sh +``` + +をコマンドプロンプトで実行し、tkをインストールし、accelerateの質問をWindowsと同じように答えます。 + +`./gui.sh`でGUIを実行します。 + ## Windows環境でのインストール 以下の例ではPyTorchは1.12.1/CUDA 11.6版をインストールします。CUDA 11.3版やPyTorch 1.13を使う場合は適宜書き換えください。 diff --git a/README.md b/README.md index 7c5dc8f..8bec9b9 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,19 @@ If you run on Linux and would like to use the GUI, there is now a port of it as ## Installation +### Ubuntu +In the terminal, run + +``` +git clone https://github.com/bmaltais/kohya_ss.git +cd kohya_ss +bash ubuntu_setup.sh +``` + +then configure accelerate with the same answers as in the Windows instructions when prompted. + +### Windows + Give unrestricted script access to powershell so venv can work: - Run PowerShell as an administrator @@ -163,6 +176,9 @@ This will store your a backup file with your current locally installed pip packa ## Change History +* 2023/03/04 (v21.1.3): + - Fix progress bar being displayed when not required. + - Add support for linux, thank you @devNegative-asm * 2023/03/03 (v21.1.2): - Fix issue https://github.com/bmaltais/kohya_ss/issues/277 - Fix issue https://github.com/bmaltais/kohya_ss/issues/278 introduce by LoCon project switching to pip module. Make sure to run upgrade.ps1 to install the latest pip requirements for LoCon support. diff --git a/dreambooth_gui.py b/dreambooth_gui.py index 84517e0..48bc2cf 100644 --- a/dreambooth_gui.py +++ b/dreambooth_gui.py @@ -25,7 +25,7 @@ from library.common_gui import ( gradio_config, gradio_source_model, set_legacy_8bitadam, - my_data, + update_my_data, ) from library.tensorboard_gui import ( gradio_tensorboard, @@ -214,7 +214,7 @@ def open_configuration( 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 = my_data(my_data) + my_data = update_my_data(my_data) else: file_path = original_file_path # In case a file_path was provided and the user decide to cancel the open action my_data = {} @@ -456,7 +456,7 @@ def train_model( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) # check if output_dir/last is a folder... therefore it is a diffuser model last_dir = pathlib.Path(f'{output_dir}/{output_name}') @@ -500,7 +500,9 @@ def dreambooth_tab( '📂', elem_id='open_folder_small' ) train_data_dir_input_folder.click( - get_folder_path, outputs=train_data_dir + get_folder_path, + outputs=train_data_dir, + show_progress=False, ) reg_data_dir = gr.Textbox( label='Regularisation folder', @@ -510,7 +512,9 @@ def dreambooth_tab( '📂', elem_id='open_folder_small' ) reg_data_dir_input_folder.click( - get_folder_path, outputs=reg_data_dir + get_folder_path, + outputs=reg_data_dir, + show_progress=False, ) with gr.Row(): output_dir = gr.Textbox( @@ -529,7 +533,9 @@ def dreambooth_tab( '📂', elem_id='open_folder_small' ) logging_dir_input_folder.click( - get_folder_path, outputs=logging_dir + get_folder_path, + outputs=logging_dir, + show_progress=False, ) with gr.Row(): output_name = gr.Textbox( @@ -610,7 +616,11 @@ def dreambooth_tab( placeholder='(Optiona) path to checkpoint of vae to replace for training', ) vae_button = gr.Button('📂', elem_id='open_folder_small') - vae_button.click(get_any_file_path, outputs=vae) + vae_button.click( + get_any_file_path, + outputs=vae, + show_progress=False, + ) ( use_8bit_adam, xformers, @@ -664,10 +674,12 @@ def dreambooth_tab( button_start_tensorboard.click( start_tensorboard, inputs=logging_dir, + show_progress=False, ) button_stop_tensorboard.click( stop_tensorboard, + show_progress=False, ) settings_list = [ @@ -730,23 +742,27 @@ def dreambooth_tab( open_configuration, inputs=[config_file_name] + settings_list, outputs=[config_file_name] + settings_list, + show_progress=False, ) button_save_config.click( save_configuration, inputs=[dummy_db_false, config_file_name] + settings_list, outputs=[config_file_name], + show_progress=False, ) button_save_as_config.click( save_configuration, inputs=[dummy_db_true, config_file_name] + settings_list, outputs=[config_file_name], + show_progress=False, ) button_run.click( train_model, inputs=settings_list, + show_progress=False, ) return ( diff --git a/finetune_gui.py b/finetune_gui.py index 251dee8..f9a831b 100644 --- a/finetune_gui.py +++ b/finetune_gui.py @@ -19,7 +19,7 @@ from library.common_gui import ( color_aug_changed, run_cmd_training, set_legacy_8bitadam, - my_data, + update_my_data, ) from library.tensorboard_gui import ( gradio_tensorboard, @@ -33,6 +33,8 @@ refresh_symbol = '\U0001f504' # 🔄 save_style_symbol = '\U0001f4be' # 💾 document_symbol = '\U0001F4C4' # 📄 +PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' + def save_configuration( save_as, @@ -216,7 +218,7 @@ def open_config_file( my_data_db = 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 = my_data(my_data) + my_data = update_my_data(my_data) else: file_path = original_file_path # In case a file_path was provided and the user decide to cancel the open action my_data_db = {} @@ -295,9 +297,7 @@ def train_model( if not os.path.exists(train_dir): os.mkdir(train_dir) - run_cmd = ( - f'./venv/Scripts/python.exe finetune/merge_captions_to_metadata.py' - ) + run_cmd = f'{PYTHON} finetune/merge_captions_to_metadata.py' if caption_extension == '': run_cmd += f' --caption_extension=".caption"' else: @@ -310,13 +310,11 @@ def train_model( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) # create images buckets if generate_image_buckets: - run_cmd = ( - f'./venv/Scripts/python.exe finetune/prepare_buckets_latents.py' - ) + run_cmd = f'{PYTHON} finetune/prepare_buckets_latents.py' run_cmd += f' "{image_folder}"' run_cmd += f' "{train_dir}/{caption_metadata_filename}"' run_cmd += f' "{train_dir}/{latent_metadata_filename}"' @@ -334,7 +332,7 @@ def train_model( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) image_num = len( [ @@ -444,7 +442,7 @@ def train_model( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) # check if output_dir/last is a folder... therefore it is a diffuser model last_dir = pathlib.Path(f'{output_dir}/{output_name}') @@ -490,7 +488,11 @@ def finetune_tab(): train_dir_folder = gr.Button( folder_symbol, elem_id='open_folder_small' ) - train_dir_folder.click(get_folder_path, outputs=train_dir) + train_dir_folder.click( + get_folder_path, + outputs=train_dir, + show_progress=False, + ) image_folder = gr.Textbox( label='Training Image folder', @@ -500,7 +502,9 @@ def finetune_tab(): folder_symbol, elem_id='open_folder_small' ) image_folder_input_folder.click( - get_folder_path, outputs=image_folder + get_folder_path, + outputs=image_folder, + show_progress=False, ) with gr.Row(): output_dir = gr.Textbox( @@ -510,7 +514,11 @@ def finetune_tab(): output_dir_input_folder = gr.Button( folder_symbol, elem_id='open_folder_small' ) - output_dir_input_folder.click(get_folder_path, outputs=output_dir) + output_dir_input_folder.click( + get_folder_path, + outputs=output_dir, + show_progress=False, + ) logging_dir = gr.Textbox( label='Logging folder', @@ -520,7 +528,9 @@ def finetune_tab(): folder_symbol, elem_id='open_folder_small' ) logging_dir_input_folder.click( - get_folder_path, outputs=logging_dir + get_folder_path, + outputs=logging_dir, + show_progress=False, ) with gr.Row(): output_name = gr.Textbox( @@ -654,6 +664,7 @@ def finetune_tab(): button_stop_tensorboard.click( stop_tensorboard, + show_progress=False, ) settings_list = [ @@ -724,18 +735,21 @@ def finetune_tab(): open_config_file, inputs=[config_file_name] + settings_list, outputs=[config_file_name] + settings_list, + show_progress=False, ) button_save_config.click( save_configuration, inputs=[dummy_ft_false, config_file_name] + settings_list, outputs=[config_file_name], + show_progress=False, ) button_save_as_config.click( save_configuration, inputs=[dummy_ft_true, config_file_name] + settings_list, outputs=[config_file_name], + show_progress=False, ) diff --git a/gui.sh b/gui.sh new file mode 100755 index 0000000..90b26db --- /dev/null +++ b/gui.sh @@ -0,0 +1,3 @@ +#!/bin/bash +source venv/bin/activate +python kohya_gui.py diff --git a/library/basic_caption_gui.py b/library/basic_caption_gui.py index 2412dfb..a26f571 100644 --- a/library/basic_caption_gui.py +++ b/library/basic_caption_gui.py @@ -2,6 +2,7 @@ import gradio as gr from easygui import msgbox import subprocess from .common_gui import get_folder_path, add_pre_postfix, find_replace +import os def caption_images( @@ -38,7 +39,7 @@ def caption_images( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) if overwrite_input: if not prefix == '' or not postfix == '': @@ -85,7 +86,9 @@ def gradio_basic_caption_gui_tab(): '📂', elem_id='open_folder_small' ) button_images_dir_input.click( - get_folder_path, outputs=images_dir_input + get_folder_path, + outputs=images_dir_input, + show_progress=False, ) caption_file_ext = gr.Textbox( label='Caption file extension', @@ -139,4 +142,5 @@ def gradio_basic_caption_gui_tab(): find, replace, ], + show_progress=False, ) diff --git a/library/blip_caption_gui.py b/library/blip_caption_gui.py index 61acd75..30d6955 100644 --- a/library/blip_caption_gui.py +++ b/library/blip_caption_gui.py @@ -4,6 +4,8 @@ import subprocess import os from .common_gui import get_folder_path, add_pre_postfix +PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' + def caption_images( train_data_dir, @@ -32,7 +34,7 @@ def caption_images( return print(f'Captioning files in {train_data_dir}...') - run_cmd = f'.\\venv\\Scripts\\python.exe "finetune/make_captions.py"' + run_cmd = f'{PYTHON} "finetune/make_captions.py"' run_cmd += f' --batch_size="{int(batch_size)}"' run_cmd += f' --num_beams="{int(num_beams)}"' run_cmd += f' --top_p="{top_p}"' @@ -48,7 +50,7 @@ def caption_images( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) # Add prefix and postfix add_pre_postfix( @@ -81,7 +83,9 @@ def gradio_blip_caption_gui_tab(): '📂', elem_id='open_folder_small' ) button_train_data_dir_input.click( - get_folder_path, outputs=train_data_dir + get_folder_path, + outputs=train_data_dir, + show_progress=False, ) with gr.Row(): caption_file_ext = gr.Textbox( @@ -138,4 +142,5 @@ def gradio_blip_caption_gui_tab(): prefix, postfix, ], + show_progress=False, ) diff --git a/library/common_gui.py b/library/common_gui.py index 9251a27..90fac72 100644 --- a/library/common_gui.py +++ b/library/common_gui.py @@ -10,11 +10,11 @@ save_style_symbol = '\U0001f4be' # 💾 document_symbol = '\U0001F4C4' # 📄 -def my_data(my_data): +def update_my_data(my_data): if my_data.get('use_8bit_adam', False): my_data['optimizer'] = 'AdamW8bit' my_data['use_8bit_adam'] = False - + if my_data.get('model_list', 'custom') == []: print('Old config with empty model list. Setting to custom...') my_data['model_list'] = 'custom' @@ -276,7 +276,9 @@ 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): +def set_pretrained_model_name_or_path_input( + model_list, pretrained_model_name_or_path, v2, v_parameterization +): # define a list of substrings to search for substrings_v2 = [ 'stabilityai/stable-diffusion-2-1-base', @@ -320,7 +322,12 @@ def set_pretrained_model_name_or_path_input(model_list, pretrained_model_name_or return model_list, v2, v_parameterization if model_list == 'custom': - if str(pretrained_model_name_or_path) in substrings_v1_model or str(pretrained_model_name_or_path) in substrings_v2 or str(pretrained_model_name_or_path) in substrings_v_parameterization: + if ( + str(pretrained_model_name_or_path) in substrings_v1_model + or str(pretrained_model_name_or_path) in substrings_v2 + or str(pretrained_model_name_or_path) + in substrings_v_parameterization + ): pretrained_model_name_or_path = '' v2 = False v_parameterization = False @@ -359,7 +366,7 @@ def gradio_source_model(): pretrained_model_name_or_path = gr.Textbox( label='Pretrained model name or path', placeholder='enter the path to custom model or name of pretrained model', - value='runwayml/stable-diffusion-v1-5' + value='runwayml/stable-diffusion-v1-5', ) pretrained_model_name_or_path_file = gr.Button( document_symbol, elem_id='open_folder_small' @@ -368,6 +375,7 @@ def gradio_source_model(): get_any_file_path, inputs=pretrained_model_name_or_path, outputs=pretrained_model_name_or_path, + show_progress=False, ) pretrained_model_name_or_path_folder = gr.Button( folder_symbol, elem_id='open_folder_small' @@ -376,6 +384,7 @@ def gradio_source_model(): get_folder_path, inputs=pretrained_model_name_or_path, outputs=pretrained_model_name_or_path, + show_progress=False, ) model_list = gr.Dropdown( label='Model Quick Pick', @@ -388,7 +397,7 @@ def gradio_source_model(): 'runwayml/stable-diffusion-v1-5', 'CompVis/stable-diffusion-v1-4', ], - value='runwayml/stable-diffusion-v1-5' + value='runwayml/stable-diffusion-v1-5', ) save_model_as = gr.Dropdown( label='Save trained model as', @@ -409,7 +418,12 @@ def gradio_source_model(): ) model_list.change( set_pretrained_model_name_or_path_input, - inputs=[model_list, pretrained_model_name_or_path, v2, v_parameterization], + inputs=[ + model_list, + pretrained_model_name_or_path, + v2, + v_parameterization, + ], outputs=[ pretrained_model_name_or_path, v2, @@ -661,7 +675,11 @@ def gradio_advanced_training(): placeholder='path to "last-state" state folder to resume from', ) resume_button = gr.Button('📂', elem_id='open_folder_small') - resume_button.click(get_folder_path, outputs=resume) + resume_button.click( + get_folder_path, + outputs=resume, + show_progress=False, + ) max_train_epochs = gr.Textbox( label='Max train epoch', placeholder='(Optional) Override number of epoch', diff --git a/library/convert_model_gui.py b/library/convert_model_gui.py index fca75fc..f6352e0 100644 --- a/library/convert_model_gui.py +++ b/library/convert_model_gui.py @@ -9,6 +9,7 @@ folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 save_style_symbol = '\U0001f4be' # 💾 document_symbol = '\U0001F4C4' # 📄 +PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' def convert_model( @@ -40,7 +41,7 @@ def convert_model( msgbox('The provided target folder does not exist') return - run_cmd = f'.\\venv\Scripts\python.exe "tools/convert_diffusers20_original_sd.py"' + run_cmd = f'{PYTHON} "tools/convert_diffusers20_original_sd.py"' v1_models = [ 'runwayml/stable-diffusion-v1-5', @@ -87,7 +88,7 @@ def convert_model( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) if ( not target_model_type == 'diffuser' @@ -166,7 +167,9 @@ def gradio_convert_model_tab(): folder_symbol, elem_id='open_folder_small' ) button_source_model_dir.click( - get_folder_path, outputs=source_model_input + get_folder_path, + outputs=source_model_input, + show_progress=False, ) button_source_model_file = gr.Button( @@ -176,6 +179,7 @@ def gradio_convert_model_tab(): get_file_path, inputs=[source_model_input], outputs=source_model_input, + show_progress=False, ) source_model_type = gr.Dropdown( @@ -199,7 +203,9 @@ def gradio_convert_model_tab(): folder_symbol, elem_id='open_folder_small' ) button_target_model_folder.click( - get_folder_path, outputs=target_model_folder_input + get_folder_path, + outputs=target_model_folder_input, + show_progress=False, ) target_model_name_input = gr.Textbox( @@ -234,4 +240,5 @@ def gradio_convert_model_tab(): target_model_type, target_save_precision_type, ], + show_progress=False, ) diff --git a/library/dataset_balancing_gui.py b/library/dataset_balancing_gui.py index ce6d094..2e6bc98 100644 --- a/library/dataset_balancing_gui.py +++ b/library/dataset_balancing_gui.py @@ -118,7 +118,9 @@ def gradio_dataset_balancing_tab(): '📂', elem_id='open_folder_small' ) select_dataset_folder_button.click( - get_folder_path, outputs=select_dataset_folder_input + get_folder_path, + outputs=select_dataset_folder_input, + show_progress=False, ) total_repeats_number = gr.Number( @@ -140,4 +142,5 @@ def gradio_dataset_balancing_tab(): select_dataset_folder_input, insecure, ], + show_progress=False, ) diff --git a/library/dreambooth_folder_creation_gui.py b/library/dreambooth_folder_creation_gui.py index f8e23b2..b5d5ff4 100644 --- a/library/dreambooth_folder_creation_gui.py +++ b/library/dreambooth_folder_creation_gui.py @@ -140,7 +140,9 @@ def gradio_dreambooth_folder_creation_tab( '📂', elem_id='open_folder_small' ) button_util_training_images_dir_input.click( - get_folder_path, outputs=util_training_images_dir_input + get_folder_path, + outputs=util_training_images_dir_input, + show_progress=False, ) util_training_images_repeat_input = gr.Number( label='Repeats', @@ -158,7 +160,9 @@ def gradio_dreambooth_folder_creation_tab( '📂', elem_id='open_folder_small' ) button_util_regularization_images_dir_input.click( - get_folder_path, outputs=util_regularization_images_dir_input + get_folder_path, + outputs=util_regularization_images_dir_input, + show_progress=False, ) util_regularization_images_repeat_input = gr.Number( label='Repeats', @@ -190,6 +194,7 @@ def gradio_dreambooth_folder_creation_tab( util_class_prompt_input, util_training_dir_output, ], + show_progress=False, ) button_copy_info_to_Folders_tab = gr.Button('Copy info to Folders Tab') button_copy_info_to_Folders_tab.click( @@ -201,4 +206,5 @@ def gradio_dreambooth_folder_creation_tab( output_dir_input, logging_dir_input, ], + show_progress=False, ) diff --git a/library/extract_lora_gui.py b/library/extract_lora_gui.py index 074e3ed..6020c8d 100644 --- a/library/extract_lora_gui.py +++ b/library/extract_lora_gui.py @@ -12,6 +12,7 @@ folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 save_style_symbol = '\U0001f4be' # 💾 document_symbol = '\U0001F4C4' # 📄 +PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' def extract_lora( @@ -41,7 +42,7 @@ def extract_lora( return run_cmd = ( - f'.\\venv\Scripts\python.exe "networks\extract_lora_from_models.py"' + f'{PYTHON} "{os.path.join("networks","extract_lora_from_models.py")}"' ) run_cmd += f' --save_precision {save_precision}' run_cmd += f' --save_to "{save_to}"' @@ -54,7 +55,7 @@ def extract_lora( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) ### @@ -85,6 +86,7 @@ def gradio_extract_lora_tab(): get_file_path, inputs=[model_tuned, model_ext, model_ext_name], outputs=model_tuned, + show_progress=False, ) model_org = gr.Textbox( @@ -99,6 +101,7 @@ def gradio_extract_lora_tab(): get_file_path, inputs=[model_org, model_ext, model_ext_name], outputs=model_org, + show_progress=False, ) with gr.Row(): save_to = gr.Textbox( @@ -113,6 +116,7 @@ def gradio_extract_lora_tab(): get_saveasfilename_path, inputs=[save_to, lora_ext, lora_ext_name], outputs=save_to, + show_progress=False, ) save_precision = gr.Dropdown( label='Save precision', @@ -136,4 +140,5 @@ def gradio_extract_lora_tab(): extract_button.click( extract_lora, inputs=[model_tuned, model_org, save_to, save_precision, dim, v2], + show_progress=False, ) diff --git a/library/git_caption_gui.py b/library/git_caption_gui.py index 3cc69d4..0ce1dda 100644 --- a/library/git_caption_gui.py +++ b/library/git_caption_gui.py @@ -4,6 +4,8 @@ import subprocess import os from .common_gui import get_folder_path, add_pre_postfix +PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' + def caption_images( train_data_dir, @@ -73,7 +75,9 @@ def gradio_git_caption_gui_tab(): '📂', elem_id='open_folder_small' ) button_train_data_dir_input.click( - get_folder_path, outputs=train_data_dir + get_folder_path, + outputs=train_data_dir, + show_progress=False, ) with gr.Row(): caption_ext = gr.Textbox( @@ -126,4 +130,5 @@ def gradio_git_caption_gui_tab(): prefix, postfix, ], + show_progress=False, ) diff --git a/library/merge_lora_gui.py b/library/merge_lora_gui.py index 03a1257..a3ecd48 100644 --- a/library/merge_lora_gui.py +++ b/library/merge_lora_gui.py @@ -12,6 +12,7 @@ folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 save_style_symbol = '\U0001f4be' # 💾 document_symbol = '\U0001F4C4' # 📄 +PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' def merge_lora( @@ -43,7 +44,7 @@ def merge_lora( ratio_a = ratio ratio_b = 1 - ratio - run_cmd = f'.\\venv\Scripts\python.exe "networks\merge_lora.py"' + run_cmd = f'{PYTHON} "{os.path.join("networks","merge_lora.py")}"' run_cmd += f' --save_precision {save_precision}' run_cmd += f' --precision {precision}' run_cmd += f' --save_to "{save_to}"' @@ -53,7 +54,7 @@ def merge_lora( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) ### @@ -81,6 +82,7 @@ def gradio_merge_lora_tab(): get_file_path, inputs=[lora_a_model, lora_ext, lora_ext_name], outputs=lora_a_model, + show_progress=False, ) lora_b_model = gr.Textbox( @@ -95,6 +97,7 @@ def gradio_merge_lora_tab(): get_file_path, inputs=[lora_b_model, lora_ext, lora_ext_name], outputs=lora_b_model, + show_progress=False, ) with gr.Row(): ratio = gr.Slider( @@ -119,6 +122,7 @@ def gradio_merge_lora_tab(): get_saveasfilename_path, inputs=[save_to, lora_ext, lora_ext_name], outputs=save_to, + show_progress=False, ) precision = gr.Dropdown( label='Merge precision', @@ -145,4 +149,5 @@ def gradio_merge_lora_tab(): precision, save_precision, ], + show_progress=False, ) diff --git a/library/resize_lora_gui.py b/library/resize_lora_gui.py index b9dec29..8d41ee8 100644 --- a/library/resize_lora_gui.py +++ b/library/resize_lora_gui.py @@ -4,6 +4,7 @@ import subprocess import os from .common_gui import get_saveasfilename_path, get_file_path +PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 save_style_symbol = '\U0001f4be' # 💾 @@ -30,7 +31,7 @@ def resize_lora( if device == '': device = 'cuda' - run_cmd = f'.\\venv\Scripts\python.exe "networks\\resize_lora.py"' + run_cmd = f'{PYTHON} "{os.path.join("networks","resize_lora.py")}"' run_cmd += f' --save_precision {save_precision}' run_cmd += f' --save_to {save_to}' run_cmd += f' --model {model}' @@ -40,7 +41,7 @@ def resize_lora( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) ### @@ -68,6 +69,7 @@ def gradio_resize_lora_tab(): get_file_path, inputs=[model, lora_ext, lora_ext_name], outputs=model, + show_progress=False, ) with gr.Row(): new_rank = gr.Slider( @@ -92,6 +94,7 @@ def gradio_resize_lora_tab(): get_saveasfilename_path, inputs=[save_to, lora_ext, lora_ext_name], outputs=save_to, + show_progress=False, ) save_precision = gr.Dropdown( label='Save precision', @@ -116,4 +119,5 @@ def gradio_resize_lora_tab(): save_precision, device, ], + show_progress=False, ) diff --git a/library/tensorboard_gui.py b/library/tensorboard_gui.py index 1182773..d08a02d 100644 --- a/library/tensorboard_gui.py +++ b/library/tensorboard_gui.py @@ -5,6 +5,7 @@ import subprocess import time tensorboard_proc = None # I know... bad but heh +TENSORBOARD = 'tensorboard' if os.name == 'posix' else 'tensorboard.exe' def start_tensorboard(logging_dir): @@ -15,7 +16,7 @@ def start_tensorboard(logging_dir): msgbox(msg='Error: log folder is empty') return - run_cmd = f'tensorboard.exe --logdir "{logging_dir}"' + run_cmd = [f'{TENSORBOARD}', '--logdir', f'{logging_dir}'] print(run_cmd) if tensorboard_proc is not None: diff --git a/library/verify_lora_gui.py b/library/verify_lora_gui.py index 51fa510..a7a0bf9 100644 --- a/library/verify_lora_gui.py +++ b/library/verify_lora_gui.py @@ -8,6 +8,7 @@ from .common_gui import ( get_file_path, ) +PYTHON = 'python3' if os.name == 'posix' else './venv/Scripts/python.exe' folder_symbol = '\U0001f4c2' # 📂 refresh_symbol = '\U0001f504' # 🔄 save_style_symbol = '\U0001f4be' # 💾 @@ -27,13 +28,15 @@ def verify_lora( msgbox('The provided model A is not a file') return - run_cmd = f'.\\venv\Scripts\python.exe "networks\check_lora_weights.py"' - run_cmd += f' {lora_model}' + run_cmd = [ + PYTHON, + os.path.join('networks', 'check_lora_weights.py'), + f'{lora_model}', + ] - print(run_cmd) + print(' '.join(run_cmd)) # Run the command - subprocess.run(run_cmd) process = subprocess.Popen( run_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) @@ -69,6 +72,7 @@ def gradio_verify_lora_tab(): get_file_path, inputs=[lora_model, lora_ext, lora_ext_name], outputs=lora_model, + show_progress=False, ) verify_button = gr.Button('Verify', variant='primary') @@ -94,4 +98,5 @@ def gradio_verify_lora_tab(): lora_model, ], outputs=[lora_model_verif_output, lora_model_verif_error], + show_progress=False, ) diff --git a/library/wd14_caption_gui.py b/library/wd14_caption_gui.py index 3d97ebf..0c1cf79 100644 --- a/library/wd14_caption_gui.py +++ b/library/wd14_caption_gui.py @@ -2,6 +2,7 @@ import gradio as gr from easygui import msgbox import subprocess from .common_gui import get_folder_path +import os def caption_images(train_data_dir, caption_extension, batch_size, thresh): @@ -30,7 +31,7 @@ def caption_images(train_data_dir, caption_extension, batch_size, thresh): print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) print('...captioning done') @@ -55,7 +56,9 @@ def gradio_wd14_caption_gui_tab(): '📂', elem_id='open_folder_small' ) button_train_data_dir_input.click( - get_folder_path, outputs=train_data_dir + get_folder_path, + outputs=train_data_dir, + show_progress=False, ) caption_extension = gr.Textbox( @@ -75,4 +78,5 @@ def gradio_wd14_caption_gui_tab(): caption_button.click( caption_images, inputs=[train_data_dir, caption_extension, batch_size, thresh], + show_progress=False, ) diff --git a/lora_gui.py b/lora_gui.py index 5026618..c6c31ef 100644 --- a/lora_gui.py +++ b/lora_gui.py @@ -25,7 +25,7 @@ from library.common_gui import ( gradio_source_model, run_cmd_training, set_legacy_8bitadam, - my_data, + update_my_data, ) from library.dreambooth_folder_creation_gui import ( gradio_dreambooth_folder_creation_tab, @@ -239,7 +239,7 @@ def open_configuration( 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 = my_data(my_data) + my_data = update_my_data(my_data) else: file_path = original_file_path # In case a file_path was provided and the user decide to cancel the open action my_data = {} @@ -462,7 +462,9 @@ def train_model( try: import locon.locon_kohya except ModuleNotFoundError: - print("\033[1;31mError:\033[0m The required module 'locon' is not installed. Please install by running \033[33mupgrade.ps1\033[0m before running this program.") + print( + "\033[1;31mError:\033[0m The required module 'locon' is not installed. Please install by running \033[33mupgrade.ps1\033[0m before running this program." + ) return run_cmd += f' --network_module=locon.locon_kohya' run_cmd += ( @@ -544,7 +546,7 @@ def train_model( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) # check if output_dir/last is a folder... therefore it is a diffuser model last_dir = pathlib.Path(f'{output_dir}/{output_name}') @@ -588,27 +590,41 @@ def lora_tab( ) train_data_dir_folder = gr.Button('📂', elem_id='open_folder_small') train_data_dir_folder.click( - get_folder_path, outputs=train_data_dir + get_folder_path, + outputs=train_data_dir, + show_progress=False, ) reg_data_dir = gr.Textbox( label='Regularisation folder', placeholder='(Optional) Folder where where the regularization folders containing the images are located', ) reg_data_dir_folder = gr.Button('📂', elem_id='open_folder_small') - reg_data_dir_folder.click(get_folder_path, outputs=reg_data_dir) + reg_data_dir_folder.click( + get_folder_path, + outputs=reg_data_dir, + show_progress=False, + ) with gr.Row(): output_dir = gr.Textbox( label='Output folder', placeholder='Folder to output trained model', ) output_dir_folder = gr.Button('📂', elem_id='open_folder_small') - output_dir_folder.click(get_folder_path, outputs=output_dir) + output_dir_folder.click( + get_folder_path, + outputs=output_dir, + show_progress=False, + ) logging_dir = gr.Textbox( label='Logging folder', placeholder='Optional: enable logging and output TensorBoard log to this folder', ) logging_dir_folder = gr.Button('📂', elem_id='open_folder_small') - logging_dir_folder.click(get_folder_path, outputs=logging_dir) + logging_dir_folder.click( + get_folder_path, + outputs=logging_dir, + show_progress=False, + ) with gr.Row(): output_name = gr.Textbox( label='Model output name', @@ -662,6 +678,7 @@ def lora_tab( get_any_file_path, inputs=[lora_network_weights], outputs=lora_network_weights, + show_progress=False, ) ( learning_rate, @@ -736,7 +753,7 @@ def lora_tab( return gr.Group.update(visible=True) else: return gr.Group.update(visible=False) - + LoRA_type.change( LoRA_type_change, inputs=[LoRA_type], outputs=[LoCon_row] ) @@ -834,10 +851,12 @@ def lora_tab( button_start_tensorboard.click( start_tensorboard, inputs=logging_dir, + show_progress=False, ) button_stop_tensorboard.click( stop_tensorboard, + show_progress=False, ) settings_list = [ @@ -910,23 +929,27 @@ def lora_tab( open_configuration, inputs=[config_file_name] + settings_list, outputs=[config_file_name] + settings_list + [LoCon_row], + show_progress=False, ) button_save_config.click( save_configuration, inputs=[dummy_db_false, config_file_name] + settings_list, outputs=[config_file_name], + show_progress=False, ) button_save_as_config.click( save_configuration, inputs=[dummy_db_true, config_file_name] + settings_list, outputs=[config_file_name], + show_progress=False, ) button_run.click( train_model, inputs=settings_list, + show_progress=False, ) return ( diff --git a/textual_inversion_gui.py b/textual_inversion_gui.py index 48d2793..b8715a4 100644 --- a/textual_inversion_gui.py +++ b/textual_inversion_gui.py @@ -25,7 +25,7 @@ from library.common_gui import ( gradio_config, gradio_source_model, set_legacy_8bitadam, - my_data, + update_my_data, ) from library.tensorboard_gui import ( gradio_tensorboard, @@ -226,7 +226,7 @@ def open_configuration( my_data_db = 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 = my_data(my_data) + my_data = update_my_data(my_data) else: file_path = original_file_path # In case a file_path was provided and the user decide to cancel the open action my_data_db = {} @@ -498,7 +498,7 @@ def train_model( print(run_cmd) # Run the command - subprocess.run(run_cmd) + os.system(run_cmd) # check if output_dir/last is a folder... therefore it is a diffuser model last_dir = pathlib.Path(f'{output_dir}/{output_name}') @@ -542,7 +542,9 @@ def ti_tab( '📂', elem_id='open_folder_small' ) train_data_dir_input_folder.click( - get_folder_path, outputs=train_data_dir + get_folder_path, + outputs=train_data_dir, + show_progress=False, ) reg_data_dir = gr.Textbox( label='Regularisation folder', @@ -552,7 +554,9 @@ def ti_tab( '📂', elem_id='open_folder_small' ) reg_data_dir_input_folder.click( - get_folder_path, outputs=reg_data_dir + get_folder_path, + outputs=reg_data_dir, + show_progress=False, ) with gr.Row(): output_dir = gr.Textbox( @@ -562,7 +566,11 @@ def ti_tab( output_dir_input_folder = gr.Button( '📂', elem_id='open_folder_small' ) - output_dir_input_folder.click(get_folder_path, outputs=output_dir) + output_dir_input_folder.click( + get_folder_path, + outputs=output_dir, + show_progress=False, + ) logging_dir = gr.Textbox( label='Logging folder', placeholder='Optional: enable logging and output TensorBoard log to this folder', @@ -571,7 +579,9 @@ def ti_tab( '📂', elem_id='open_folder_small' ) logging_dir_input_folder.click( - get_folder_path, outputs=logging_dir + get_folder_path, + outputs=logging_dir, + show_progress=False, ) with gr.Row(): output_name = gr.Textbox( @@ -607,7 +617,11 @@ def ti_tab( placeholder='(Optional) Path to existing TI embeding file to keep training', ) weights_file_input = gr.Button('📂', elem_id='open_folder_small') - weights_file_input.click(get_file_path, outputs=weights) + weights_file_input.click( + get_file_path, + outputs=weights, + show_progress=False, + ) with gr.Row(): token_string = gr.Textbox( label='Token string', @@ -688,7 +702,11 @@ def ti_tab( placeholder='(Optiona) path to checkpoint of vae to replace for training', ) vae_button = gr.Button('📂', elem_id='open_folder_small') - vae_button.click(get_any_file_path, outputs=vae) + vae_button.click( + get_any_file_path, + outputs=vae, + show_progress=False, + ) ( use_8bit_adam, xformers, @@ -742,10 +760,12 @@ def ti_tab( button_start_tensorboard.click( start_tensorboard, inputs=logging_dir, + show_progress=False, ) button_stop_tensorboard.click( stop_tensorboard, + show_progress=False, ) settings_list = [ @@ -814,23 +834,27 @@ def ti_tab( open_configuration, inputs=[config_file_name] + settings_list, outputs=[config_file_name] + settings_list, + show_progress=False, ) button_save_config.click( save_configuration, inputs=[dummy_db_false, config_file_name] + settings_list, outputs=[config_file_name], + show_progress=False, ) button_save_as_config.click( save_configuration, inputs=[dummy_db_true, config_file_name] + settings_list, outputs=[config_file_name], + show_progress=False, ) button_run.click( train_model, inputs=settings_list, + show_progress=False, ) return ( diff --git a/ubuntu_setup.sh b/ubuntu_setup.sh new file mode 100755 index 0000000..1431155 --- /dev/null +++ b/ubuntu_setup.sh @@ -0,0 +1,12 @@ +#!/bin/bash +echo installing tk +sudo apt install python3-tk +python3 -m venv venv +source venv/bin/activate +pip install torch==1.12.1+cu116 torchvision==0.13.1+cu116 --extra-index-url https://download.pytorch.org/whl/cu116 +pip install --use-pep517 --upgrade -r requirements.txt +pip install -U -I --no-deps https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/linux/xformers-0.0.14.dev0-cp310-cp310-linux_x86_64.whl + +accelerate config + +echo -e "setup finished! run \e[0;92m./gui.sh\e[0m to start"