From f2a4ef1eb0b53214b5f2faf44605990c3e5bd40a Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Wed, 9 Apr 2025 08:59:23 -0400 Subject: [PATCH] loader basic gguf support Signed-off-by: Vladimir Mandic --- installer.py | 2 +- modules/ui_models.py | 5 ++-- modules/ui_models_load.py | 55 ++++++++++++++++++++++++++------------- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/installer.py b/installer.py index 2311e681c..44d81c6e6 100644 --- a/installer.py +++ b/installer.py @@ -538,7 +538,7 @@ def check_diffusers(): t_start = time.time() if args.skip_all or args.skip_git or args.experimental: return - sha = '506f39af3a7b533209cc96f1732fff347070bdbd' # diffusers commit hash + sha = 'd1387ecee5262e75386ce8948ddcf9a4de0ebbfa' # diffusers commit hash pkg = pkg_resources.working_set.by_key.get('diffusers', None) minor = int(pkg.version.split('.')[1] if pkg is not None else 0) cur = opts.get('diffusers_version', '') if minor > 0 else '' diff --git a/modules/ui_models.py b/modules/ui_models.py index e9754ac59..de8d1e729 100644 --- a/modules/ui_models.py +++ b/modules/ui_models.py @@ -26,6 +26,7 @@ def create_ui(): gr.HTML(elem_id="models_progress", value="") models_image = gr.Image(elem_id="models_image", show_label=False, interactive=False, type='pil') models_outcome = gr.HTML(elem_id="models_error", value="") + models_file = gr.File(label='', type='file', help='', visible=False) with gr.Column(elem_id='models_input_container', scale=3): @@ -53,9 +54,9 @@ def create_ui(): model_analyze.click(fn=analyze, inputs=[], outputs=[model_desc, model_modules, model_meta]) - with gr.Tab(label="Custom"): + with gr.Tab(label="Loader"): from modules import ui_models_load - ui_models_load.create_ui(models_outcome) + ui_models_load.create_ui(models_outcome, models_file) with gr.Tab(label="Merge"): def sd_model_choices(): diff --git a/modules/ui_models_load.py b/modules/ui_models_load.py index c4c5c8823..902769365 100644 --- a/modules/ui_models_load.py +++ b/modules/ui_models_load.py @@ -1,5 +1,6 @@ import os import re +import json # pylint: disable=unused-import import inspect import gradio as gr import torch @@ -13,17 +14,7 @@ debug_log = shared.log.trace if debug_enabled else lambda *args, **kwargs: None components = [] -def load_receipe(): - # TODO custom: load receipe - return 'Load receipe not implemented yet' - - -def save_receipe(): - # TODO custom: save receipe - return 'Save receipe not implemented yet' - - -def load_model(model, cls, repo, dataframes): +def load_model(model: str, cls: str, repo: str, dataframes: list): if cls is None: shared.log.error('Model load: class is None') return 'Model load: class is None' @@ -157,6 +148,9 @@ class Component(): def __str__(self): return f'id={self.id} name="{self.name}" cls={self.cls} type={self.type} loadable={self.loadable} val="{self.val}" str="{self.str}" enum="{self.enum}" local="{self.local}" remote="{self.remote}" repo="{self.repo}" subfolder="{self.subfolder}" dtype={self.dtype} quant={self.quant} revision={self.revision}' + def save(self): + return [self.name, self.local, self.remote, self.dtype, self.quant] + def dataframe(self): return [self.id, self.name, self.loadable, self.val, self.str, self.local, self.remote, self.dtype, self.quant] @@ -192,10 +186,14 @@ class Component(): self.download = False if self.local is not None and len(self.local) > 0: if not os.path.exists(self.local): - debug_log(f'Model load component: local="{self.local}" does not exist') - if hasattr(self.cls, 'from_single_file') and os.path.isfile(self.local): + debug_log(f'Model load component: local="{self.local}" file not found') + elif hasattr(self.cls, 'from_single_file') and os.path.isfile(self.local) and self.local.endswith('.safetensors'): debug_log(f'Model load component: local="{self.local}" type=file args={load_args} quant={quant_type}') return self.cls.from_single_file(self.local, **load_args, **quant_args, cache_dir=shared.opts.hfcache_dir) + elif os.path.isfile(self.local) and self.local.endswith('.gguf'): + debug_log(f'Model load component: local="{self.local}" type=gguf args={load_args} quant={quant_type}') + from modules import ggml + return ggml.load_gguf(self.local, cls=self.cls, compute_dtype=self.dtype) else: debug_log(f'Model load component: local="{self.local}" type=folder args={load_args} quant={quant_type}') return self.cls.from_pretrained(self.local, **load_args, **quant_args, cache_dir=shared.opts.hfcache_dir) @@ -214,7 +212,7 @@ class Component(): return None -def create_ui(status): +def create_ui(gr_status, gr_file): def get_components(cls): if cls is None: return [] @@ -256,6 +254,27 @@ def create_ui(status): if c.remote and len(c.remote) > 0: c.repo, c.subfolder, c.local, c.download = process_huggingface_url(c.remote) + # TODO loader: load receipe + def load_receipe(file_select): + if file_select is not None and 'name' in file_select: + fn = file_select['name'] + shared.log.debug(f'Load receipe: fn={fn}') + return ['Load receipe not implemented yet', gr.update(label='Receipe .json file', file_types=['json'], visible=True)] + + # TODO loader: save receipe + def save_receipe(model: str, repo: str): + receipe = { + 'model': model, + 'repo': repo, + 'components': [] + } + for c in components: + if c.loadable: + receipe['components'].append(c.save()) + # with open('/tmp/receipe.json', 'w', encoding='utf8') as f: + # json.dump(receipe, f, indent=2) + return 'Save receipe not implemented yet' + with gr.Row(): gr.HTML('

 Custom model loader

') with gr.Row(): @@ -293,7 +312,7 @@ def create_ui(status): btn_load_model = gr.Button(value="Load model") btn_unload_model = gr.Button(value="Unload model") - btn_load_receipe.click(fn=load_receipe, inputs=[], outputs=[status]) - btn_save_receipe.click(fn=save_receipe, inputs=[], outputs=[status]) - btn_load_model.click(fn=load_model, inputs=[model, cls, repo, dataframes], outputs=[status]) - btn_unload_model.click(fn=unload_model, inputs=[], outputs=[status]) + btn_load_receipe.click(fn=load_receipe, inputs=[gr_file], outputs=[gr_status, gr_file]) + btn_save_receipe.click(fn=save_receipe, inputs=[model, repo], outputs=[gr_status]) + btn_load_model.click(fn=load_model, inputs=[model, cls, repo, dataframes], outputs=[gr_status]) + btn_unload_model.click(fn=unload_model, inputs=[], outputs=[gr_status])