import os import inspect from typing import cast import gradio as gr from modules import errors, sd_models, sd_vae, extras, sd_samplers, ui_symbols, modelstats from modules.ui_components import ToolButton from modules.ui_common import create_refresh_button from modules.call_queue import wrap_gradio_gpu_call from modules.shared import opts, log extra_ui = [] def create_ui(): log.debug('UI initialize: tab=models') dummy_component = gr.Label(visible=False) with gr.Row(elem_id="models_tab"): with gr.Column(elem_id='models_output_container', scale=1): models_outcome = gr.HTML(elem_id="models_outcome", value="") models_file = gr.File(label='', visible=False) with gr.Column(elem_id='models_input_container', scale=3): with gr.Tab(label="Current", elem_id="models_current_tab"): def create_modules_table(rows: list): html = """ {tbody}
ModuleClassDeviceDtypeQuantParamsModulesConfig
""" tbody = '' for row in rows: try: config = str(row.config) except Exception: config = '{}' try: tbody += f""" {row.name} {row.cls} {row.device} {row.dtype} {row.quant} {row.params} {row.modules}
{config}
""" except Exception as e: log.error(f'Model list: row={vars(row)} {e}') return html.format(tbody=tbody) def analyze(): model = modelstats.analyze() if model is None: return ["Model not loaded", {}] meta = model.meta html = create_modules_table(model.modules) return [html, meta] with gr.Row(): model_analyze = gr.Button(value="Analyze model", variant='primary') with gr.Row(): model_desc = gr.HTML(value="", elem_id="model_desc") with gr.Accordion(label="Save model", open=False): with gr.Row(): save_name = gr.Textbox(label="Model name", placeholder="Model name to save as") with gr.Row(): save_path = gr.Textbox(label="Model base path", placeholder="Path to save model to", value=opts.diffusers_dir) with gr.Row(): save_shard = gr.Textbox(label="Max shard size", placeholder="Maximum shard size", value="10GB") save_overwrite = gr.Checkbox(label="Overwrite existing", value=False) with gr.Row(): save_result = gr.HTML(value="", elem_id="model_save_outcome") with gr.Row(): model_save = gr.Button(value="Save model", variant='primary') model_save.click(fn=sd_models.save_model, inputs=[save_name, save_path, save_shard, save_overwrite], outputs=[save_result]) with gr.Accordion(label="Metadata", open=False): model_meta = gr.JSON(label="Metadata", value={}, elem_id="model_meta") model_analyze.click(fn=analyze, inputs=[], outputs=[model_desc, model_meta]) with gr.Tab(label="List", elem_id="models_list_tab"): def create_models_table(rows: list): from modules import sd_detect html = """ {tbody}
NameTypeDetectPipelineHashSizeMTime
""" tbody = '' for row in rows: try: f = row.filename stat_size, stat_mtime = modelstats.stat(f) if os.path.isfile(f): typ = os.path.splitext(f)[1][1:] size = f"{round(stat_size / 1024 / 1024 / 1024, 3)} gb" elif os.path.isdir(f): typ = 'diffusers' size = 'folder' else: typ = 'unknown' size = 'unknown' guess = 'Diffusion' # set default guess guess = sd_detect.guess_by_size(f, guess) guess = sd_detect.guess_by_name(f, guess) guess, pipeline = sd_detect.guess_by_diffusers(f, guess) guess = sd_detect.guess_variant(f, guess) pipeline = sd_detect.shared_items.get_pipelines().get(guess, None) if pipeline is None else pipeline tbody += f""" {row.model_name} {typ} {guess} {pipeline.__name__ if pipeline else '(unknown)'} {row.shorthash} {size} {stat_mtime} """ except Exception as e: log.error(f'Model list: row={vars(row)} {e}') return html.format(tbody=tbody) with gr.Row(): gr.HTML('

List all locally available models


') with gr.Row(): model_list_btn = gr.Button(value="List models", variant='primary') model_checkhash_btn = gr.Button(value="Calculate missing hashes", variant='secondary') with gr.Row(): model_table = gr.HTML(value='', elem_id="model_list_table") model_checkhash_btn.click(fn=sd_models.update_model_hashes, inputs=[], outputs=[model_table]) model_list_btn.click(fn=lambda: create_models_table(list(sd_models.checkpoints_list.values())), inputs=[], outputs=[model_table]) with gr.Tab(label="Metadata", elem_id="models_metadata_tab"): from modules.civitai.metadata_civitai import civit_search_metadata, civit_update_metadata with gr.Row(): gr.HTML('

Fetch model preview metadata


') with gr.Row(): civit_previews_btn = gr.Button(value="Scan missing", variant='primary') civit_update_btn = gr.Button(value="Update all", variant='primary') with gr.Row(): civit_metadata = gr.HTML(value='', elem_id="civit_metadata") civit_previews_btn.click(fn=civit_search_metadata, inputs=[], outputs=[civit_metadata]) civit_update_btn.click(fn=civit_update_metadata, inputs=[], outputs=[civit_metadata]) with gr.Tab(label="Loader", elem_id="models_loader_tab"): from modules import ui_models_load ui_models_load.create_ui(models_outcome, models_file) with gr.Tab(label="Merge", elem_id="models_merge_tab"): from modules.merging import merge_methods from modules.merging.merge_utils import BETA_METHODS, TRIPLE_METHODS, interpolate from modules.merging.merge_presets import BLOCK_WEIGHTS_PRESETS, SDXL_BLOCK_WEIGHTS_PRESETS def sd_model_choices(): return ['None'] + sd_models.checkpoint_titles() with gr.Row(): gr.HTML('

 Merge multiple models

') with gr.Row(equal_height=False): with gr.Column(variant='compact'): with gr.Row(): custom_name = gr.Textbox(label="New model name") with gr.Row(): merge_mode = gr.Dropdown(choices=merge_methods.__all__, value="weighted_sum", label="Interpolation Method") merge_mode_docs = gr.HTML(value=merge_methods.weighted_sum.__doc__.strip().replace("\n", "
")) # pylint: disable=no-member # pyright: ignore[reportOptionalMemberAccess] with gr.Row(): primary_model_name = gr.Dropdown(sd_model_choices(), label="Primary model", value="None") create_refresh_button(primary_model_name, sd_models.list_models, lambda: {"choices": sd_model_choices()}, "checkpoint_A_refresh") secondary_model_name = gr.Dropdown(sd_model_choices(), label="Secondary model", value="None") create_refresh_button(secondary_model_name, sd_models.list_models, lambda: {"choices": sd_model_choices()}, "checkpoint_B_refresh") tertiary_model_name = gr.Dropdown(sd_model_choices(), label="Tertiary model", value="None", visible=False) tertiary_refresh = create_refresh_button(tertiary_model_name, sd_models.list_models, lambda: {"choices": sd_model_choices()}, "checkpoint_C_refresh", visible=False) with gr.Row(): with gr.Tabs() as tabs: with gr.TabItem(label="Simple Merge", id=0): with gr.Row(): alpha = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Alpha Ratio', value=0.5) beta = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Beta Ratio', value=None, visible=False) with gr.TabItem(label="Preset Block Merge", id=1): with gr.Row(): sdxl = gr.Checkbox(label="SDXL") with gr.Row(): alpha_preset = gr.Dropdown( choices=["None"] + list(BLOCK_WEIGHTS_PRESETS.keys()), value=None, label="ALPHA Block Weight Preset", multiselect=True, max_choices=2) alpha_preset_lambda = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Preset Interpolation Ratio', value=None, visible=False) apply_preset = ToolButton('⇨', visible=True) with gr.Row(): beta_preset = gr.Dropdown(choices=["None"] + list(BLOCK_WEIGHTS_PRESETS.keys()), value=None, label="BETA Block Weight Preset", multiselect=True, max_choices=2, interactive=True, visible=False) beta_preset_lambda = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Preset Interpolation Ratio', value=None, interactive=True, visible=False) beta_apply_preset = ToolButton('⇨', interactive=True, visible=False) with gr.TabItem(label="Manual Block Merge", id=2): with gr.Row(): alpha_label = gr.Markdown("# Alpha") with gr.Row(): alpha_base = gr.Textbox(value=None, label="Base", min_width=70, scale=1) alpha_in_blocks = gr.Textbox(value=None, label="In Blocks", scale=15) alpha_mid_block = gr.Textbox(value=None, label="Mid Block", min_width=80, scale=1) alpha_out_blocks = gr.Textbox(value=None, label="Out Block", scale=15) with gr.Row(): beta_label = gr.Markdown("# Beta", visible=False) with gr.Row(): beta_base = gr.Textbox(value=None, label="Base", min_width=70, scale=1, interactive=True, visible=False) beta_in_blocks = gr.Textbox(value=None, label="In Blocks", interactive=True, scale=15, visible=False) beta_mid_block = gr.Textbox(value=None, label="Mid Block", min_width=80, interactive=True, scale=1, visible=False) beta_out_blocks = gr.Textbox(value=None, label="Out Block", interactive=True, scale=15, visible=False) with gr.Row(): overwrite = gr.Checkbox(label="Overwrite model") with gr.Row(): save_metadata = gr.Checkbox(value=True, label="Save metadata") with gr.Row(): weights_clip = gr.Checkbox(label="Weights clip") prune = gr.Checkbox(label="Prune", value=True, visible=False) with gr.Row(): re_basin = gr.Checkbox(label="ReBasin") re_basin_iterations = gr.Slider(minimum=0, maximum=25, step=1, label='Number of ReBasin Iterations', value=None, visible=False) with gr.Row(): checkpoint_format = gr.Radio(choices=["ckpt", "safetensors"], value="safetensors", visible=False, label="Model format") with gr.Row(): precision = gr.Radio(choices=["fp16", "fp32"], value="fp16", label="Model precision") with gr.Row(): device = gr.Radio(choices=["cpu", "shuffle", "gpu"], value="cpu", label="Merge Device") unload = gr.Checkbox(label="Unload Current Model from VRAM", value=False, visible=False) with gr.Row(): bake_in_vae = gr.Dropdown(choices=["None"] + list(sd_vae.vae_dict), value="None", interactive=True, label="Replace VAE") create_refresh_button(bake_in_vae, sd_vae.refresh_vae_list, lambda: {"choices": ["None"] + list(sd_vae.vae_dict)}, "modelmerger_bake_in_vae_refresh") with gr.Row(): modelmerger_merge = gr.Button(value="Merge", variant='primary') def modelmerger(dummy_component, # dummy function just to get argspec later overwrite, # pylint: disable=unused-argument primary_model_name, # pylint: disable=unused-argument secondary_model_name, # pylint: disable=unused-argument tertiary_model_name, # pylint: disable=unused-argument merge_mode, # pylint: disable=unused-argument alpha, # pylint: disable=unused-argument beta, # pylint: disable=unused-argument alpha_preset, # pylint: disable=unused-argument alpha_preset_lambda, # pylint: disable=unused-argument alpha_base, # pylint: disable=unused-argument alpha_in_blocks, # pylint: disable=unused-argument alpha_mid_block, # pylint: disable=unused-argument alpha_out_blocks, # pylint: disable=unused-argument beta_preset, # pylint: disable=unused-argument beta_preset_lambda, # pylint: disable=unused-argument beta_base, # pylint: disable=unused-argument beta_in_blocks, # pylint: disable=unused-argument beta_mid_block, # pylint: disable=unused-argument beta_out_blocks, # pylint: disable=unused-argument precision, # pylint: disable=unused-argument custom_name, # pylint: disable=unused-argument checkpoint_format, # pylint: disable=unused-argument save_metadata, # pylint: disable=unused-argument weights_clip, # pylint: disable=unused-argument prune, # pylint: disable=unused-argument re_basin, # pylint: disable=unused-argument re_basin_iterations, # pylint: disable=unused-argument device, # pylint: disable=unused-argument unload, # pylint: disable=unused-argument bake_in_vae): # pylint: disable=unused-argument kwargs = {} for x in inspect.getfullargspec(modelmerger)[0]: kwargs[x] = locals()[x] for key in list(kwargs.keys()): if kwargs[key] in [None, "None", "", 0, []]: del kwargs[key] del kwargs['dummy_component'] if kwargs.get("custom_name", None) is None: log.error('Merge: no output model specified') return [*[gr.Dropdown.update(choices=sd_models.checkpoint_titles()) for _ in range(4)], "No output model specified"] elif kwargs.get("primary_model_name", None) is None or kwargs.get("secondary_model_name", None) is None: log.error('Merge: no models selected') return [*[gr.Dropdown.update(choices=sd_models.checkpoint_titles()) for _ in range(4)], "No models selected"] else: log.debug(f'Merge start: {kwargs}') try: results = extras.run_modelmerger(dummy_component, **kwargs) except Exception as e: errors.display(e, 'Merge') sd_models.list_models() # to remove the potentially missing models from the list return [*[gr.Dropdown.update(choices=sd_models.checkpoint_titles()) for _ in range(4)], f"Error merging checkpoints: {e}"] return results def tertiary(mode): if mode in TRIPLE_METHODS: return [gr.update(visible=True) for _ in range(2)] else: return [gr.update(visible=False) for _ in range(2)] def beta_visibility(mode): if mode in BETA_METHODS: return [gr.update(visible=True) for _ in range(9)] else: return [gr.update(visible=False) for _ in range(9)] def show_iters(show): if show: return gr.Slider.update(value=5, visible=True) else: return gr.Slider.update(value=None, visible=False) def show_help(mode): try: doc = getattr(merge_methods, mode).__doc__.strip().replace("\n", "
") except AttributeError: log.warning(f'Merge mode "{mode}" is missing documentation') doc = "Error: Documentation missing" return gr.update(value=doc, visible=True) def show_unload(device): if device == "gpu": return gr.update(visible=True) else: return gr.update(visible=False) def preset_visiblility(x): if len(x) == 2: return gr.Slider.update(value=0.5, visible=True) else: return gr.Slider.update(value=None, visible=False) def load_presets(presets, ratio): for i, p in enumerate(presets): presets[i] = BLOCK_WEIGHTS_PRESETS[p] if len(presets) == 2: preset = interpolate(presets, ratio) else: preset = presets[0] preset = ['%.3f' % x if int(x) != x else str(x) for x in preset] # pylint: disable=consider-using-f-string preset = [preset[0], ",".join(preset[1:13]), preset[13], ",".join(preset[14:])] return [gr.update(value=x) for x in preset] + [gr.update(selected=2)] def preset_choices(sdxl): if sdxl: return [gr.update(choices=["None"] + list(SDXL_BLOCK_WEIGHTS_PRESETS.keys())) for _ in range(2)] else: return [gr.update(choices=["None"] + list(BLOCK_WEIGHTS_PRESETS.keys())) for _ in range(2)] device.change(fn=show_unload, inputs=device, outputs=unload) merge_mode.change(fn=show_help, inputs=merge_mode, outputs=merge_mode_docs) sdxl.change(fn=preset_choices, inputs=sdxl, outputs=[alpha_preset, beta_preset]) alpha_preset.change(fn=preset_visiblility, inputs=alpha_preset, outputs=alpha_preset_lambda) beta_preset.change(fn=preset_visiblility, inputs=alpha_preset, outputs=beta_preset_lambda) merge_mode.input(fn=tertiary, inputs=merge_mode, outputs=[tertiary_model_name, tertiary_refresh]) merge_mode.input(fn=beta_visibility, inputs=merge_mode, outputs=[beta, alpha_label, beta_label, beta_apply_preset, beta_preset, beta_base, beta_in_blocks, beta_mid_block, beta_out_blocks]) re_basin.change(fn=show_iters, inputs=re_basin, outputs=re_basin_iterations) apply_preset.click(fn=load_presets, inputs=[alpha_preset, alpha_preset_lambda], outputs=[alpha_base, alpha_in_blocks, alpha_mid_block, alpha_out_blocks, cast("gr.components.Component", tabs)]) # Casting because Tabs has an update method. beta_apply_preset.click(fn=load_presets, inputs=[beta_preset, beta_preset_lambda], outputs=[beta_base, beta_in_blocks, beta_mid_block, beta_out_blocks, cast("gr.components.Component", tabs)]) # Casting because Tabs has an update method. modelmerger_merge.click( fn=wrap_gradio_gpu_call(modelmerger, extra_outputs=lambda: [gr.update() for _ in range(4)], name='Models'), _js='modelmerger', inputs=[ dummy_component, overwrite, primary_model_name, secondary_model_name, tertiary_model_name, merge_mode, alpha, beta, alpha_preset, alpha_preset_lambda, alpha_base, alpha_in_blocks, alpha_mid_block, alpha_out_blocks, beta_preset, beta_preset_lambda, beta_base, beta_in_blocks, beta_mid_block, beta_out_blocks, precision, custom_name, checkpoint_format, save_metadata, weights_clip, prune, re_basin, re_basin_iterations, device, unload, bake_in_vae, ], outputs=[ primary_model_name, secondary_model_name, tertiary_model_name, dummy_component, models_outcome, ] ) with gr.Tab(label="Replace", elem_id="models_replace_tab"): with gr.Row(): gr.HTML('

 Replace model components

') with gr.Row(): with gr.Column(scale=3): model_type = gr.Dropdown(label="Base model type", choices=['sd15', 'sdxl', 'sd21', 'sd35', 'flux.1'], value='sdxl', interactive=False) with gr.Column(scale=5): with gr.Row(): model_name = gr.Dropdown(sd_models.checkpoint_titles(), label="Input model") create_refresh_button(model_name, sd_models.list_models, lambda: {"choices": sd_models.checkpoint_titles()}, "checkpoint_Z_refresh") with gr.Column(scale=5): custom_name = gr.Textbox(label="Output model", placeholder="Output model path") with gr.Row(): with gr.Column(scale=3): gr.HTML('Model components
Specify the components to include
Paths can be relative or absolute

') with gr.Column(scale=5): comp_unet = gr.Textbox(placeholder="UNet model", show_label=False) comp_vae = gr.Textbox(placeholder="VAE model", show_label=False) with gr.Column(scale=5): comp_te1 = gr.Textbox(placeholder="Text encoder 1", show_label=False) comp_te2 = gr.Textbox(placeholder="Text encoder 2", show_label=False) with gr.Row(): with gr.Column(scale=3): gr.HTML('Model settings
') with gr.Column(scale=10): with gr.Row(): precision = gr.Dropdown(label="Model precision", choices=["fp32", "fp16", "bf16"], value="fp16") comp_scheduler = gr.Dropdown(label="Sampler", choices=[s.name for s in sd_samplers.samplers if s.constructor is not None]) comp_prediction = gr.Dropdown(label="Prediction type", choices=["epsilon", "v"], value="epsilon") with gr.Row(): with gr.Column(scale=3): gr.HTML('Merge LoRA
') with gr.Column(scale=9): comp_lora = gr.Textbox(label="Comma separated list with optional strength per LoRA", placeholder="LoRA models") with gr.Column(scale=1): comp_fuse = gr.Number(label="Fuse strength", value=1.0) with gr.Row(): gr.HTML('
') with gr.Row(): with gr.Column(scale=2): gr.HTML('Model metadata
') with gr.Column(scale=5): meta_author = gr.Textbox(placeholder="Author name", show_label=False) meta_version = gr.Textbox(placeholder="Model version", show_label=False) meta_license = gr.Textbox(placeholder="Model license", show_label=False) with gr.Column(scale=5): meta_desc = gr.Textbox(placeholder="Model description", lines=3, show_label=False) meta_hint = gr.Textbox(placeholder="Model hint", lines=3, show_label=False) with gr.Column(scale=3): meta_thumbnail = gr.Image(label="Thumbnail", type='pil') with gr.Row(): gr.HTML('Note: Save is optional as you can merge in-memory and use newly created model immediately') with gr.Row(): create_diffusers = gr.Checkbox(label="Save diffusers", value=True) create_safetensors = gr.Checkbox(label="Save safetensors", value=True) debug = gr.Checkbox(label="Debug info", value=False) model_modules_btn = gr.Button(value="Merge Modules", variant='primary') model_modules_btn.click( fn=extras.run_model_modules, inputs=[ model_type, model_name, custom_name, comp_unet, comp_vae, comp_te1, comp_te2, precision, comp_scheduler, comp_prediction, comp_lora, comp_fuse, meta_author, meta_version, meta_license, meta_desc, meta_hint, meta_thumbnail, create_diffusers, create_safetensors, debug, ], outputs=[models_outcome] ) with gr.Tab(label="CivitAI", elem_id="models_civitai_tab"): from modules.civitai.search_civitai import search_civitai, create_model_cards, base_models def civitai_search(civit_search_text, civit_search_tag, civit_nsfw, civit_type, civit_base, civit_token): results = search_civitai(query=civit_search_text, tag=civit_search_tag, nsfw=civit_nsfw, types=civit_type, base=civit_base, token=civit_token) html = create_model_cards(results) return html def civitai_update_token(token): log.debug('CivitAI update token') opts.civitai_token = token opts.save() def civitai_download(model_urls, model_names, model_types, model_path, civit_token, model_output): from modules.civitai.download_civitai import download_civit_model for model_url, model_name, model_type in zip(model_urls, model_names, model_types): msg = f"

Initiating download

{model_name} | {model_type} | {model_url}

" yield msg + model_output download_civit_model(model_url, model_name, model_path, model_type, civit_token) yield model_output with gr.Row(): gr.HTML('

Search & Download

') with gr.Row(elem_id='civitai_search_row'): civit_search_text = gr.Textbox(label='', placeholder='keyword', elem_id="civit_search_text") civit_search_tag = gr.Textbox(label='', placeholder='tag', elem_id="civit_search_text") civit_search_text_btn = ToolButton(value=ui_symbols.search, interactive=True, elem_id="civit_text_search") with gr.Accordion(label='Advanced', open=False, elem_id="civitai_search_options"): civit_download_btn = gr.Button(value="Download model", variant='primary', elem_id="civitai_download_btn", visible=False) with gr.Row(): civit_token = gr.Textbox(opts.civitai_token, label='CivitAI token', placeholder='optional access token for private or gated models', elem_id="civitai_token") with gr.Row(): civit_nsfw = gr.Checkbox(label='NSFW allowed', value=True) with gr.Row(): civit_type = gr.Textbox(label='Target model type', placeholder='Checkpoint, LORA, ...', value='') with gr.Row(): # civit_base = gr.Textbox(label='Base model', placeholder='SDXL, ...') civit_base = gr.Dropdown(choices=base_models, label='Base model', value='') with gr.Row(): civit_folder = gr.Textbox(label='Download folder', placeholder='optional folder for downloads') with gr.Row(): civitai_models_output = gr.HTML('', elem_id="civitai_models_output") # sort, period, limit _dummy = gr.Label(visible=False) # dummy component to get argspec later civit_inputs = [civit_search_text, civit_search_tag, civit_nsfw, civit_type, civit_base, civit_token] civit_search_text_btn.click(fn=civitai_search, inputs=civit_inputs, outputs=[civitai_models_output]) civit_search_text.submit(fn=civitai_search, inputs=civit_inputs, outputs=[civitai_models_output]) civit_search_tag.submit(fn=civitai_search, inputs=civit_inputs, outputs=[civitai_models_output]) civit_token.change(fn=civitai_update_token, inputs=[civit_token], outputs=[]) civit_download_btn.click( fn=civitai_download, _js="downloadCivitModel", inputs=[_dummy, _dummy, _dummy, civit_folder, civit_token, civitai_models_output], outputs=[civitai_models_output], show_progress='full', ) with gr.Tab(label="Huggingface", elem_id="models_huggingface_tab"): from modules.models_hf import hf_search, hf_select, hf_download_model, hf_update_token with gr.Column(scale=6): with gr.Row(): gr.HTML('

 Download model from huggingface

') with gr.Row(): hf_search_text = gr.Textbox('', label='Search models', placeholder='search huggingface models') hf_search_btn = ToolButton(value=ui_symbols.search, interactive=True, elem_id="hf_text_search") with gr.Row(): hf_selected = gr.Textbox('', label='Select model', placeholder='select model from search results or enter model name manually') with gr.Accordion(label='Advanced', open=False, elem_id="hf_search_options"): with gr.Row(): hf_token = gr.Textbox(opts.huggingface_token, label='Huggingface token', placeholder='optional access token for private or gated models', elem_id="hf_token") with gr.Row(): hf_variant = gr.Textbox('', label='Specify model variant', placeholder='') hf_revision = gr.Textbox('', label='Specify model revision', placeholder='') with gr.Row(): hf_mirror = gr.Textbox('', label='Huggingface mirror', placeholder='optional mirror site for downloads') hf_custom_pipeline = gr.Textbox('', label='Custom pipeline', placeholder='optional pipeline for downloads') with gr.Column(scale=1): gr.HTML('
') hf_download_model_btn = gr.Button(value="Download model", variant='primary') with gr.Row(): hf_headers = ['Name', 'Pipeline', 'Tags', 'Downloads', 'Updated', 'URL'] hf_types = ['str', 'str', 'str', 'number', 'date', 'markdown'] hf_results = gr.DataFrame(None, label='Search results', show_label=True, interactive=False, wrap=True, headers=hf_headers, datatype=hf_types) hf_search_text.submit(fn=hf_search, inputs=[hf_search_text], outputs=[hf_results]) hf_search_btn.click(fn=hf_search, inputs=[hf_search_text], outputs=[hf_results]) hf_results.select(fn=hf_select, inputs=[hf_results], outputs=[hf_selected]) hf_download_model_btn.click(fn=hf_download_model, inputs=[hf_selected, hf_token, hf_variant, hf_revision, hf_mirror, hf_custom_pipeline], outputs=[models_outcome]) hf_token.change(fn=hf_update_token, inputs=[hf_token], outputs=[]) from modules.lora.lora_extract import create_ui as lora_extract_ui lora_extract_ui() for ui in extra_ui: if callable(ui): ui()