mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
update models current and list tabs
Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
+2
-1
@@ -17,7 +17,8 @@
|
||||
- quicksettings reset button to restore all quicksettings to default values
|
||||
because things do sometimes get wrong...
|
||||
- updated real-time hints, thanks @CalamitousFelicitousness
|
||||
- new *models -> list models* tab
|
||||
- updated *models -> current* tab
|
||||
- updated *models -> list models* tab
|
||||
- more css optimizations and styling
|
||||
- **Offloading**
|
||||
- changed **default** values for offloading based on detected gpu memory
|
||||
|
||||
@@ -33,8 +33,7 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma
|
||||
- Extensions tab:
|
||||
- full CSS redesign
|
||||
- Models tab:
|
||||
- Validate subtab: replace table with custom html
|
||||
- Update subtab: replace table with custom html
|
||||
- Metadata subtab: replace table with custom html
|
||||
- CivitAI subtab: redesign downloader
|
||||
|
||||
### Under Consideration
|
||||
|
||||
@@ -1965,6 +1965,30 @@ div:has(>#tab-gallery-folders) {
|
||||
margin-top: 0.2em;
|
||||
}
|
||||
|
||||
#model_desc {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#model_list_table {
|
||||
overflow: auto;
|
||||
max-height: 50vh;
|
||||
}
|
||||
|
||||
.simple-table tr {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.simple-table td {
|
||||
padding: 0.2em !important;
|
||||
}
|
||||
|
||||
.model-config {
|
||||
font-size: 0.8em !important;
|
||||
opacity: 0.8;
|
||||
max-height: 6em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@keyframes move {
|
||||
from {
|
||||
background-position-x: 0, -40px;
|
||||
|
||||
@@ -11,6 +11,7 @@ class Module():
|
||||
dtype: str = None
|
||||
params: int = 0
|
||||
modules: int = 0
|
||||
quant: str = None
|
||||
config: dict = None
|
||||
|
||||
def __init__(self, name, module):
|
||||
@@ -25,6 +26,7 @@ class Module():
|
||||
self.dtype = getattr(module, 'dtype', None)
|
||||
self.params = sum(p.numel() for p in module.parameters(recurse=True))
|
||||
self.modules = len(list(module.modules()))
|
||||
self.quant = getattr(module, 'quantization_method', None)
|
||||
|
||||
def __repr__(self):
|
||||
s = f'name="{self.name}" cls={self.cls} config={self.config is not None}'
|
||||
@@ -69,6 +71,8 @@ class Model():
|
||||
|
||||
|
||||
def analyze():
|
||||
if not shared.sd_loaded:
|
||||
return None
|
||||
model = Model(shared.opts.sd_model_checkpoint)
|
||||
if model.cls == '':
|
||||
return model
|
||||
|
||||
@@ -351,6 +351,16 @@ def apply_balanced_offload_to_module(module, op="apply"):
|
||||
devices.torch_gc(fast=True, force=True, reason='offload')
|
||||
|
||||
|
||||
def report_model_stats(module_name, module):
|
||||
try:
|
||||
size = offload_hook_instance.offload_map.get(module_name, 0)
|
||||
quant = getattr(module, "quantization_method", None)
|
||||
params = sum(p.numel() for p in module.parameters(recurse=True))
|
||||
shared.log.debug(f'Module: name={module_name} cls={module.__class__.__name__} size={size:.3f} params={params} quant={quant}')
|
||||
except Exception as e:
|
||||
shared.log.error(f'Module stats: name={module_name} {e}')
|
||||
|
||||
|
||||
def apply_balanced_offload(sd_model=None, exclude=[]):
|
||||
global offload_hook_instance # pylint: disable=global-statement
|
||||
if shared.opts.diffusers_offload_mode != "balanced":
|
||||
@@ -382,6 +392,7 @@ def apply_balanced_offload(sd_model=None, exclude=[]):
|
||||
module.module_name = module_name
|
||||
module.offload_dir = os.path.join(shared.opts.accelerate_offload_path, checkpoint_name, module_name)
|
||||
apply_balanced_offload_to_module(module, op='apply')
|
||||
report_model_stats(module_name, module)
|
||||
set_accelerate(sd_model)
|
||||
t = time.time() - t0
|
||||
process_timer.add('offload', t)
|
||||
|
||||
+130
-116
@@ -16,7 +16,6 @@ def create_ui():
|
||||
dummy_component = gr.Label(visible=False)
|
||||
with gr.Row(elem_id="models_tab"):
|
||||
with gr.Column(elem_id='models_output_container', scale=1):
|
||||
# models_output = gr.Textbox(elem_id="models_output", value="", show_label=False)
|
||||
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="")
|
||||
@@ -25,20 +24,48 @@ def create_ui():
|
||||
with gr.Column(elem_id='models_input_container', scale=3):
|
||||
|
||||
with gr.Tab(label="Current"):
|
||||
def create_modules_table(rows: list):
|
||||
html = """
|
||||
<table class="simple-table">
|
||||
<thead">
|
||||
<tr><th>Module</th><th>Class</th><th>Device</th><th>Dtype</th><th>Quant</th><th>Params</th><th>Modules</th><th>Config</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tbody}
|
||||
</tbody>
|
||||
</table>
|
||||
"""
|
||||
tbody = ''
|
||||
for row in rows:
|
||||
try:
|
||||
config = str(row.config)
|
||||
except Exception:
|
||||
config = '{}'
|
||||
try:
|
||||
tbody += f"""
|
||||
<tr>
|
||||
<td>{row.name}</td>
|
||||
<td>{row.cls}</td>
|
||||
<td>{row.device}</td>
|
||||
<td>{row.dtype}</td>
|
||||
<td>{row.quant}</td>
|
||||
<td>{row.params}</td>
|
||||
<td>{row.modules}</td>
|
||||
<td><div class='model-config'>{config}</div></td>
|
||||
</tr>
|
||||
"""
|
||||
except Exception as e:
|
||||
log.error(f'Model list: row={vars(row)} {e}')
|
||||
return html.format(tbody=tbody)
|
||||
|
||||
def analyze():
|
||||
from modules import modelstats
|
||||
model = modelstats.analyze()
|
||||
desc = f"Model: {model.name}<br>Type: {model.type}<br>Class: {model.cls}<br>Size: {model.size} bytes<br>Modified: {model.mtime}<br>"
|
||||
if model is None:
|
||||
return ["Model not loaded", {}]
|
||||
meta = model.meta
|
||||
components = []
|
||||
for m in model.modules:
|
||||
try:
|
||||
component = (m.name, m.cls, str(m.device), str(m.dtype), m.params, m.modules, str(m.config))
|
||||
components.append(component)
|
||||
except Exception:
|
||||
component = (m.name, m.cls, str(m.device), str(m.dtype), m.params, m.modules, '')
|
||||
components.append(component)
|
||||
return [desc, components, meta]
|
||||
html = create_modules_table(model.modules)
|
||||
return [html, meta]
|
||||
|
||||
with gr.Row():
|
||||
gr.HTML('<h2> Analyze currently loaded model<br></h2>')
|
||||
@@ -46,14 +73,100 @@ def create_ui():
|
||||
model_analyze = gr.Button(value="Analyze", variant='primary')
|
||||
with gr.Row():
|
||||
model_desc = gr.HTML(value="", elem_id="model_desc")
|
||||
with gr.Row():
|
||||
module_headers = ['Module', 'Class', 'Device', 'DType', 'Params', 'Modules', 'Config']
|
||||
module_types = ['str', 'str', 'str', 'str', 'number', 'number', 'str']
|
||||
model_modules = gr.DataFrame(value=None, label=None, show_label=False, interactive=False, wrap=True, headers=module_headers, datatype=module_types, type='array')
|
||||
with gr.Row():
|
||||
model_meta = gr.JSON(label="Metadata", value={}, elem_id="model_meta")
|
||||
|
||||
model_analyze.click(fn=analyze, inputs=[], outputs=[model_desc, model_modules, model_meta])
|
||||
model_analyze.click(fn=analyze, inputs=[], outputs=[model_desc, model_meta])
|
||||
|
||||
with gr.Tab(label="List"):
|
||||
def create_models_table(rows: list):
|
||||
from modules import sd_detect
|
||||
html = """
|
||||
<table class="simple-table">
|
||||
<thead">
|
||||
<tr><th>Name</th><th>Type</th><th>Detect</th><th>Pipeline</th><th>Hash</th><th>Size</th><th>MTime</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tbody}
|
||||
</tbody>
|
||||
</table>
|
||||
"""
|
||||
tbody = ''
|
||||
for row in rows:
|
||||
try:
|
||||
f = row.filename
|
||||
stat = os.stat(row.filename)
|
||||
if os.path.isfile(f):
|
||||
typ = os.path.splitext(f)[1][1:]
|
||||
size = f'{str(round(stat.st_size / 1024 / 1024 / 1024, 3)) + ' mb'}'
|
||||
elif os.path.isdir(f):
|
||||
typ = 'diffusers'
|
||||
size = 'folder'
|
||||
else:
|
||||
typ = 'unknown'
|
||||
size = 'unknown'
|
||||
guess = 'Stable Diffusion XL' if 'XL' in f.upper() else 'Stable 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"""
|
||||
<tr>
|
||||
<td>{row.model_name}</td>
|
||||
<td>{typ}</td>
|
||||
<td>{guess}</td>
|
||||
<td>{pipeline.__name__ if pipeline else '(unknown)'}</td>
|
||||
<td>{row.shorthash}</td>
|
||||
<td>{size}</td>
|
||||
<td>{datetime.fromtimestamp(stat.st_mtime).replace(microsecond=0)}</td>
|
||||
</tr>
|
||||
"""
|
||||
except Exception as e:
|
||||
log.error(f'Model list: row={vars(row)} {e}')
|
||||
return html.format(tbody=tbody)
|
||||
|
||||
with gr.Row():
|
||||
gr.HTML('<h2> List models <br></h2>')
|
||||
with gr.Row():
|
||||
model_list_btn = gr.Button(value="List models", variant='primary')
|
||||
model_checkhash_btn = gr.Button(value="Calculate missing hashes", variant='secondary')
|
||||
model_checkhash_btn.click(fn=sd_models.update_model_hashes, inputs=[], outputs=[models_outcome])
|
||||
with gr.Row():
|
||||
model_table = gr.HTML(value='', elem_id="model_list_table")
|
||||
|
||||
model_list_btn.click(fn=lambda: create_models_table(sd_models.checkpoints_list.values()), inputs=[], outputs=[model_table])
|
||||
|
||||
with gr.Tab(label="Metadata"):
|
||||
from modules.models_civitai import civit_search_metadata, civit_update_metadata, civit_update_select, civit_update_download
|
||||
with gr.Row():
|
||||
gr.HTML('<h2> CivitAI fetch metadata<br></h2>')
|
||||
gr.HTML('Fetches preview and metadata information for models with missing information<br>Models with existing previews and information are not updated<br>')
|
||||
with gr.Row():
|
||||
civit_previews_btn = gr.Button(value="Start", variant='primary')
|
||||
with gr.Row():
|
||||
civit_previews_rehash = gr.Checkbox(value=True, label="Check alternative hash")
|
||||
civit_previews_btn.click(fn=civit_search_metadata, inputs=[civit_previews_rehash, civit_previews_rehash], outputs=[models_outcome])
|
||||
|
||||
with gr.Row():
|
||||
gr.HTML('<h2> Scan CivitAI for information on latest available model versions<br></h2>')
|
||||
with gr.Row():
|
||||
civit_update_btn = gr.Button(value="Update", variant='primary')
|
||||
with gr.Row():
|
||||
gr.HTML('<h2>Update scan results</h2>')
|
||||
with gr.Row():
|
||||
civit_headers4 = ['ID', 'File', 'Name', 'Versions', 'Current', 'Latest', 'Update']
|
||||
civit_types4 = ['number', 'str', 'str', 'number', 'str', 'str', 'str']
|
||||
civit_widths4 = ['10%', '25%', '25%', '5%', '10%', '10%', '15%']
|
||||
civit_results4 = gr.DataFrame(value=None, label=None, show_label=False, interactive=False, wrap=True, row_count=20, headers=civit_headers4, datatype=civit_types4, type='array', column_widths=civit_widths4)
|
||||
with gr.Row():
|
||||
gr.HTML('<h3>Select model from the list and download update if available</h3>')
|
||||
with gr.Row():
|
||||
civit_update_download_btn = gr.Button(value="Download", variant='primary', visible=False)
|
||||
|
||||
civit_update_btn.click(fn=civit_update_metadata, inputs=[], outputs=[civit_results4, models_outcome])
|
||||
civit_results4.select(fn=civit_update_select, inputs=[civit_results4], outputs=[models_outcome, civit_update_download_btn])
|
||||
civit_update_download_btn.click(fn=civit_update_download, inputs=[], outputs=[models_outcome])
|
||||
|
||||
with gr.Tab(label="Loader"):
|
||||
from modules import ui_models_load
|
||||
@@ -303,7 +416,7 @@ def create_ui():
|
||||
]
|
||||
)
|
||||
|
||||
with gr.Tab(label="Modules"):
|
||||
with gr.Tab(label="Replace"):
|
||||
with gr.Row():
|
||||
gr.HTML('<h2> Replace model components<br></h2>')
|
||||
with gr.Row():
|
||||
@@ -375,105 +488,6 @@ def create_ui():
|
||||
outputs=[models_outcome]
|
||||
)
|
||||
|
||||
with gr.Tab(label="List"):
|
||||
from modules import sd_checkpoint
|
||||
def create_models_table(rows: list[sd_checkpoint.CheckpointInfo]):
|
||||
from modules import sd_detect
|
||||
html = """
|
||||
<table id="ui-defauls">
|
||||
<thead">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Detect</th>
|
||||
<th>Pipeline</th>
|
||||
<th>Hash</th>
|
||||
<th>Size</th>
|
||||
<th>MTime</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tbody}
|
||||
</tbody>
|
||||
</table>
|
||||
"""
|
||||
tbody = ''
|
||||
for row in rows:
|
||||
try:
|
||||
f = row.filename
|
||||
stat = os.stat(row.filename)
|
||||
if os.path.isfile(f):
|
||||
typ = os.path.splitext(f)[1][1:]
|
||||
size = f'{str(round(stat.st_size / 1024 / 1024 / 1024, 3)) + ' mb'}'
|
||||
elif os.path.isdir(f):
|
||||
typ = 'diffusers'
|
||||
size = 'folder'
|
||||
else:
|
||||
typ = 'unknown'
|
||||
size = 'unknown'
|
||||
guess = 'Stable Diffusion XL' if 'XL' in f.upper() else 'Stable 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"""
|
||||
<tr>
|
||||
<td>{row.model_name}</td>
|
||||
<td>{typ}</td>
|
||||
<td>{guess}</td>
|
||||
<td>{pipeline.__name__ if pipeline else '(unknown)'}</td>
|
||||
<td>{row.shorthash}</td>
|
||||
<td>{size}</td>
|
||||
<td>{datetime.fromtimestamp(stat.st_mtime).replace(microsecond=0)}</td>
|
||||
</tr>
|
||||
"""
|
||||
except Exception as e:
|
||||
log.error(f'Model list: row={vars(row)} {e}')
|
||||
return html.format(tbody=tbody)
|
||||
|
||||
with gr.Row():
|
||||
gr.HTML('<h2> List models <br></h2>')
|
||||
with gr.Row():
|
||||
model_list_btn = gr.Button(value="List models", variant='primary')
|
||||
model_checkhash_btn = gr.Button(value="Calculate missing hashes", variant='secondary')
|
||||
model_checkhash_btn.click(fn=sd_models.update_model_hashes, inputs=[], outputs=[models_outcome])
|
||||
with gr.Row():
|
||||
model_table = gr.HTML(value='', elem_id="model_list_table")
|
||||
|
||||
model_list_btn.click(fn=lambda: create_models_table(sd_models.checkpoints_list.values()), inputs=[], outputs=[model_table])
|
||||
|
||||
with gr.Tab(label="Metadata"):
|
||||
from modules.models_civitai import civit_search_metadata, civit_update_metadata, civit_update_select, civit_update_download
|
||||
with gr.Row():
|
||||
gr.HTML('<h2> CivitAI fetch metadata<br></h2>')
|
||||
gr.HTML('Fetches preview and metadata information for models with missing information<br>Models with existing previews and information are not updated<br>')
|
||||
with gr.Row():
|
||||
civit_previews_btn = gr.Button(value="Start", variant='primary')
|
||||
with gr.Row():
|
||||
civit_previews_rehash = gr.Checkbox(value=True, label="Check alternative hash")
|
||||
civit_previews_btn.click(fn=civit_search_metadata, inputs=[civit_previews_rehash, civit_previews_rehash], outputs=[models_outcome])
|
||||
|
||||
with gr.Row():
|
||||
gr.HTML('<h2> Scan CivitAI for information on latest available model versions<br></h2>')
|
||||
with gr.Row():
|
||||
civit_update_btn = gr.Button(value="Update", variant='primary')
|
||||
with gr.Row():
|
||||
gr.HTML('<h2>Update scan results</h2>')
|
||||
with gr.Row():
|
||||
civit_headers4 = ['ID', 'File', 'Name', 'Versions', 'Current', 'Latest', 'Update']
|
||||
civit_types4 = ['number', 'str', 'str', 'number', 'str', 'str', 'str']
|
||||
civit_widths4 = ['10%', '25%', '25%', '5%', '10%', '10%', '15%']
|
||||
civit_results4 = gr.DataFrame(value=None, label=None, show_label=False, interactive=False, wrap=True, row_count=20, headers=civit_headers4, datatype=civit_types4, type='array', column_widths=civit_widths4)
|
||||
with gr.Row():
|
||||
gr.HTML('<h3>Select model from the list and download update if available</h3>')
|
||||
with gr.Row():
|
||||
civit_update_download_btn = gr.Button(value="Download", variant='primary', visible=False)
|
||||
|
||||
civit_update_btn.click(fn=civit_update_metadata, inputs=[], outputs=[civit_results4, models_outcome])
|
||||
civit_results4.select(fn=civit_update_select, inputs=[civit_results4], outputs=[models_outcome, civit_update_download_btn])
|
||||
civit_update_download_btn.click(fn=civit_update_download, inputs=[], outputs=[models_outcome])
|
||||
|
||||
with gr.Tab(label="CivitAI"):
|
||||
from modules.models_civitai import civitai_update_token, civit_search_model, civit_search_metadata, civit_select1, civit_select2, civit_select3, civit_download_model
|
||||
|
||||
|
||||
Reference in New Issue
Block a user