hako-mikan / sd-webui-supermerger

model merge extention for stable diffusion web ui
GNU Affero General Public License v3.0
753 stars 112 forks source link

#290 #313

Closed groinge closed 10 months ago

groinge commented 11 months ago

Added config selection. Can now use config from any input model when loading a model.

Also fixed inpaint merging.

There's one issue I ran in to though and I'm not sure if my fix is proper. Trying to save current merge occasionally gets me one of these errors when it tries to load the model at the end of save_model:

Traceback (most recent call last):
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\gradio\routes.py", line 488, in run_predict
    output = await app.get_blocks().process_api(
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\gradio\blocks.py", line 1431, in process_api
    result = await self.call_function(
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\gradio\blocks.py", line 1103, in call_function
    prediction = await anyio.to_thread.run_sync(
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\anyio\to_thread.py", line 33, in run_sync
    return await get_asynclib().run_sync_in_worker_thread(
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\anyio\_backends\_asyncio.py", line 877, in run_sync_in_worker_thread
    return await future
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\anyio\_backends\_asyncio.py", line 807, in run
    result = context.run(func, *args)
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\gradio\utils.py", line 707, in wrapper
    response = f(*args, **kwargs)
  File "C:\Users\user\Desktop\stable-diffusion-webui\extensions\sd-webui-supermerger\scripts\supermerger.py", line 564, in save_current_merge
    msg = savemodel(None,None,custom_name,save_settings)
  File "C:\Users\user\Desktop\stable-diffusion-webui\extensions\sd-webui-supermerger\scripts\mergers\model_util.py", line 150, in savemodel
    load_model(checkpoint_info, already_loaded_state_dict=state_dict)
  File "C:\Users\user\Desktop\stable-diffusion-webui\modules\sd_models.py", line 649, in load_model
    sd_model.cond_stage_model_empty_prompt = get_empty_cond(sd_model)
  File "C:\Users\user\Desktop\stable-diffusion-webui\modules\sd_models.py", line 537, in get_empty_cond
    return sd_model.cond_stage_model([""])
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\torch\nn\modules\module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "C:\Users\user\Desktop\stable-diffusion-webui\modules\sd_hijack_clip.py", line 234, in forward
    z = self.process_tokens(tokens, multipliers)
  File "C:\Users\user\Desktop\stable-diffusion-webui\modules\sd_hijack_clip.py", line 273, in process_tokens
    z = self.encode_with_transformers(tokens)
  File "C:\Users\user\Desktop\stable-diffusion-webui\modules\sd_hijack_clip.py", line 326, in encode_with_transformers
    outputs = self.wrapped.transformer(input_ids=tokens, output_hidden_states=-opts.CLIP_stop_at_last_layers)
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\torch\nn\modules\module.py", line 1527, in _call_impl
    result = hook(self, args)
  File "C:\Users\user\Desktop\stable-diffusion-webui\modules\lowvram.py", line 52, in send_me_to_gpu
    module_in_gpu.to(cpu)
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\torch\nn\modules\module.py", line 1145, in to
    return self._apply(convert)
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\torch\nn\modules\module.py", line 797, in _apply
    module._apply(fn)
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\torch\nn\modules\module.py", line 797, in _apply
    module._apply(fn)
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\torch\nn\modules\module.py", line 797, in _apply
    module._apply(fn)
  [Previous line repeated 2 more times]
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\torch\nn\modules\module.py", line 820, in _apply
    param_applied = fn(param)
  File "C:\Users\user\Desktop\stable-diffusion-webui\venv\lib\site-packages\torch\nn\modules\module.py", line 1143, in convert
    return t.to(device, dtype if t.is_floating_point() or t.is_complex() else None, non_blocking)
NotImplementedError: Cannot copy out of meta tensor; no data!

This error also happens on main, I don't think its introduced by my code.

My solution was to add this before load_model in savemodel:

name = os.path.basename(fname)
checkpoint_info = sd_models.get_closet_checkpoint_match(name)
sd_models.model_data.__init__()
load_model(checkpoint_info, already_loaded_state_dict=state_dict)

It works but it was just luck since I don't understand the inner working of webui. I saw that sd_models.model_data.init() was used before loading everywhere else in the code. And I figured that changing the model info to that of the saved model might help prevent issues since its a real checkpoint now.

Is this a stupid solution? It seems to work all the time but I might be completely missing something. And I honestly don't understand why the model is loaded there.