diff --git a/modules/config.py b/modules/config.py index ef86f7c8..3e3cd6d9 100644 --- a/modules/config.py +++ b/modules/config.py @@ -79,21 +79,55 @@ def try_load_deprecated_user_path_config(): try_load_deprecated_user_path_config() +def list_presets(): + preset_folder = 'presets' + presets = ['initial'] + if not os.path.exists(preset_folder): + print('No presets found.') + return presets; + + return presets + [f[:f.index(".json")] for f in os.listdir(preset_folder) if f.endswith('.json')] + +available_presets = list_presets() + +def update_presets(): + global available_presets + available_presets = list_presets() + +def try_get_preset_content(preset): + if isinstance(preset, str): + preset_path = os.path.abspath(f'./presets/{preset}.json') + try: + if os.path.exists(preset_path): + with open(preset_path, "r", encoding="utf-8") as json_file: + json_content = json.load(json_file) + print(f'Loaded preset: {preset_path}') + return json_content + else: + raise FileNotFoundError + except Exception as e: + print(f'Load preset [{preset_path}] failed') + print(e) + return {} + +def try_load_preset_global(preset): + global config_dict + + if isinstance(preset, str): + preset_path = os.path.abspath(f'./presets/{preset}.json') + try: + if os.path.exists(preset_path): + with open(preset_path, "r", encoding="utf-8") as json_file: + config_dict.update(json.load(json_file)) + print(f'Loaded preset: {preset_path}') + else: + raise FileNotFoundError + except Exception as e: + print(f'Load preset [{preset_path}] failed') + print(e) + preset = args_manager.args.preset - -if isinstance(preset, str): - preset_path = os.path.abspath(f'./presets/{preset}.json') - try: - if os.path.exists(preset_path): - with open(preset_path, "r", encoding="utf-8") as json_file: - config_dict.update(json.load(json_file)) - print(f'Loaded preset: {preset_path}') - else: - raise FileNotFoundError - except Exception as e: - print(f'Load preset [{preset_path}] failed') - print(e) - +try_load_preset_global(preset) def get_dir_or_set_default(key, default_value): global config_dict, visited_keys, always_save_keys @@ -152,12 +186,12 @@ def get_config_item_or_set_default(key, default_value, validator, disable_empty_ return default_value -default_base_model_name = get_config_item_or_set_default( +default_base_model_name = default_model = get_config_item_or_set_default( key='default_model', default_value='juggernautXL_version6Rundiffusion.safetensors', validator=lambda x: isinstance(x, str) ) -default_refiner_model_name = get_config_item_or_set_default( +default_refiner_model_name = default_refiner = get_config_item_or_set_default( key='default_refiner', default_value='None', validator=lambda x: isinstance(x, str) @@ -327,24 +361,25 @@ default_black_out_nsfw = get_config_item_or_set_default( config_dict["default_loras"] = default_loras = default_loras[:5] + [['None', 1.0] for _ in range(5 - len(default_loras))] -possible_preset_keys = [ - "default_model", - "default_refiner", - "default_refiner_switch", - "default_loras", - "default_cfg_scale", - "default_sample_sharpness", - "default_sampler", - "default_scheduler", - "default_performance", - "default_prompt", - "default_prompt_negative", - "default_styles", - "default_aspect_ratio", - "checkpoint_downloads", - "embeddings_downloads", - "lora_downloads", -] +# mapping config to meta parameter +possible_preset_keys = { + "default_model": "Base Model", + "default_refiner": "Refiner Model", + "default_refiner_switch": "Refiner Switch", + "default_loras": "", + "default_cfg_scale": "Guidance Scale", + "default_sample_sharpness": "Sharpness", + "default_sampler": "Sampler", + "default_scheduler": "Scheduler", + "default_performance": "Performance", + "default_prompt": "Prompt", + "default_prompt_negative": "Negative Prompt", + "default_styles": "Styles", + "default_aspect_ratio": "Resolution", + "checkpoint_downloads": None, + "embeddings_downloads": None, + "lora_downloads": None, +} REWRITE_PRESET = False diff --git a/modules/meta_parser.py b/modules/meta_parser.py index 78d73978..b9465c48 100644 --- a/modules/meta_parser.py +++ b/modules/meta_parser.py @@ -142,3 +142,20 @@ def load_parameter_button_click(raw_prompt_txt): results.append(gr.update()) return results + +def parse_meta_from_preset(preset_content): + assert isinstance(preset_content, dict) + preset_prepared = {} + items = preset_content + + for settings_key, meta_key in modules.config.possible_preset_keys.items(): + if settings_key != "default_loras": + preset_prepared[meta_key] = items[settings_key] if settings_key in items and items[settings_key] is not None else getattr(modules.config, settings_key) + else: + loras = getattr(modules.config, settings_key) + if settings_key in items: + loras = items[settings_key] + for index, lora in enumerate(loras[:5]): + preset_prepared[f'LoRA {index + 1}'] = ' : '.join(map(str, lora)) + + return load_parameter_button_click(json.dumps(preset_prepared)) \ No newline at end of file diff --git a/webui.py b/webui.py index aef02313..63aec585 100644 --- a/webui.py +++ b/webui.py @@ -226,6 +226,10 @@ with shared.gradio_root: with gr.Column(scale=1, visible=modules.config.default_advanced_checkbox) as advanced_column: with gr.Tab(label='Setting'): + preset_selection = gr.Radio(label='Preset', + choices=modules.config.available_presets, + value=args_manager.args.preset if args_manager.args.preset else "initial", + interactive=True) performance_selection = gr.Radio(label='Performance', choices=modules.flags.performance_selections, value=modules.config.default_performance, @@ -470,13 +474,16 @@ with shared.gradio_root: def model_refresh_clicked(): modules.config.update_all_model_names() + modules.config.update_presets() results = [] - results += [gr.update(choices=modules.config.model_filenames), gr.update(choices=['None'] + modules.config.model_filenames)] + results += [gr.update(choices=modules.config.model_filenames), + gr.update(choices=['None'] + modules.config.model_filenames), + gr.update(choices=modules.config.available_presets)] for i in range(5): results += [gr.update(choices=['None'] + modules.config.lora_filenames), gr.update()] return results - model_refresh.click(model_refresh_clicked, [], [base_model, refiner_model] + lora_ctrls, + model_refresh.click(model_refresh_clicked, [], [base_model, refiner_model, preset_selection] + lora_ctrls, queue=False, show_progress=False) with gr.Tab(label='Audio'): @@ -497,6 +504,36 @@ with shared.gradio_root: play_notification.change(fn=play_notification_checked, inputs=[play_notification, notification], outputs=[notification_input], queue=False) notification_input.change(fn=notification_input_changed, inputs=[notification_input, notification], outputs=[notification], queue=False) + def preset_selection_change(preset): + preset_content = modules.config.try_get_preset_content(preset) if preset != 'initial' else {} + return modules.meta_parser.parse_meta_from_preset(preset_content) + + preset_selection.change(preset_selection_change, inputs=preset_selection, outputs=[ + advanced_checkbox, + image_number, + prompt, + negative_prompt, + style_selections, + performance_selection, + aspect_ratios_selection, + overwrite_width, + overwrite_height, + sharpness, + guidance_scale, + adm_scaler_positive, + adm_scaler_negative, + adm_scaler_end, + base_model, + refiner_model, + refiner_switch, + sampler_name, + scheduler_name, + seed_random, + image_seed, + generate_button, + load_parameter_button + ] + lora_ctrls, queue=False, show_progress=False) + performance_selection.change(lambda x: [gr.update(interactive=x != 'Extreme Speed')] * 11 + [gr.update(visible=x != 'Extreme Speed')] * 1 + [gr.update(interactive=x != 'Extreme Speed', value=x == 'Extreme Speed', )] * 1,