Merge pull request #3856 from vladmandic/dev

refresh master
This commit is contained in:
Vladimir Mandic
2025-04-04 09:17:04 -04:00
committed by GitHub
19 changed files with 169 additions and 50 deletions
+24 -10
View File
@@ -1,5 +1,17 @@
# Change Log for SD.Next
## Update for 2025-04-04
- Video: add FasterCache and PAB support to WanDB and LTX models
- ZLUDA: add more GPUs to recognized list
- LoRA: obey configured device when performing calculations
- Progress: add additional fields to progress API
- Progress: use batch-count for progress
- Grid: add of max-rows and max-columns in settings to control grid format
- Gallery: add max-columns in settings for gradio gallery components
- Styles: resize and bring quick-ui to forward on hover
- Logging: fix debug logging
## Update for 2025-04-03
### Highlights for 2025-04-03
@@ -134,21 +146,23 @@ Models...And support for new models: **CogView-4**, **SANA 1.5**,
- `torch.compile` is now available
- Flash Attention 2 is now available
- **Other**
- new command line option `--monitor PERIOD` to monitor CPU and GPU memory ever n seconds
- **upscale**: new [asymmetric vae v2](https://huggingface.co/Heasterian/AsymmetricAutoencoderKLUpscaler_v2) upscaling method
- **upscale**: new experimental support for `libvips` upscaling
- **quantization**: add support for `optimum-quanto` on-the-fly quantization during load for all models
- **Command line** new option `--monitor PERIOD` to monitor CPU and GPU memory ever n seconds
- **Upscale** new [asymmetric vae v2](https://huggingface.co/Heasterian/AsymmetricAutoencoderKLUpscaler_v2) upscaling method
- **Upscale** new experimental support for `libvips` upscaling
- **Quantization** add support for `optimum-quanto` on-the-fly quantization during load for all models
note: previous method for quanto is still valid and is noted in settings as post-load quantization
- add quantization support to **CogView-3Plus**
- update `diffusers` and other requirements
- rename vae, unet and text-encoder settings *None* to *Default* to avoid confusion
- **Quantization** add support to **CogView-3Plus**
- **Default values** rename vae, unet and text-encoder settings *None* to *Default* to avoid confusion
- **Detailer**: add *renoise* option to increase/decrease noise during detailer pass
which can help with improving level of details
- **CLI**: add `cli/api-grid.py` which can generate grids using params-from-file for x/y axis
- **Samplers** add ability to set sigma adjustment for each sampler
- **ModernUI** updates
- **CSS** updates
- settings vertiocal/dirty indicator restores to default setting instead to previous value
- video interpolate do not skip duplicate frames
- **settings UI** full refactor
- **Video** interpolate do not skip duplicate frames
- **Settings UI** full refactor
- **Settings UI** vertical/dirty indicator restores to default setting instead to previous value
- update `diffusers` and other requirements
- **Wiki/Docs**
- updated [Models](https://github.com/vladmandic/sdnext/wiki/Models) info
- new [Video](https://github.com/vladmandic/sdnext/wiki/Video) guide
+12 -1
View File
@@ -4,6 +4,7 @@ import os
import io
import re
import sys
import json
import importlib.util
from PIL import Image, ExifTags, TiffImagePlugin, PngImagePlugin
from rich import print # pylint: disable=redefined-builtin
@@ -95,6 +96,14 @@ class Exif: # pylint: disable=single-string-used-for-slots
return raw
def print_json(data):
try:
for k, v in data.items():
print(f'json: k={k}', json.loads(v))
except Exception:
pass
def read_exif(filename: str):
if filename.lower().endswith('.heic'):
from pi_heif import register_heif_opener
@@ -103,8 +112,10 @@ def read_exif(filename: str):
image = Image.open(filename)
exif = Exif(image)
print('image:', filename, 'format:', image)
print('exif:', vars(exif.exif)['_data'])
data = vars(exif.exif)['_data']
print('exif:', data)
print('info:', exif.parse())
print_json(data)
except Exception as e:
print('metadata error reading:', filename, e)
+1 -1
View File
@@ -538,7 +538,7 @@ def check_diffusers():
t_start = time.time()
if args.skip_all or args.skip_git or args.experimental:
return
sha = 'e5c6027ef89ec1a2800c0421599da89d4820f2e4' # diffusers commit hash
sha = 'f10775b1b55cbebc58655b966b4ba3a6fc259ca3' # 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 ''
+1
View File
@@ -148,6 +148,7 @@ div#extras_scale_to_tab div.form { flex-direction: row; }
#txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt, #control_prompt, #control_neg_prompt, #video_prompt, #video_neg_prompt { background-color: var(--background-color); box-shadow: none !important; }
#txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea, #control_prompt > label > textarea, #control_neg_prompt > label > textarea, #video_prompt > label > textarea, #video_neg_prompt > label > textarea { font-size: 1.0em; line-height: 1.4em; }
#txt2img_styles, #img2img_styles, #control_styles, #video_styles { padding: 0; margin-top: 2px; }
#txt2img_styles:hover, #img2img_styles:hover, #control_styles:hover, #video_styles:hover { z-index: 1000; }
#txt2img_styles_refresh, #img2img_styles_refresh, #control_styles_refresh, #video_styles_refresh { padding: 0; margin-top: 1em; }
/* settings */
+23 -7
View File
@@ -19,24 +19,40 @@ def check_grid_size(imgs):
return ok
def get_grid_size(imgs, batch_size=1, rows=None):
if rows is None:
def get_grid_size(imgs, batch_size=1, rows=None, cols=None):
if rows and rows > len(imgs):
rows = len(imgs)
if cols and cols > len(imgs):
cols = len(imgs)
if rows is None and cols is None:
if shared.opts.n_rows > 0:
rows = shared.opts.n_rows
cols = math.ceil(len(imgs) / rows)
elif shared.opts.n_rows == 0:
rows = batch_size
cols = math.ceil(len(imgs) / rows)
elif shared.opts.n_cols > 0:
cols = shared.opts.n_cols
rows = math.ceil(len(imgs) / cols)
elif shared.opts.n_cols == 0:
cols = batch_size
rows = math.ceil(len(imgs) / cols)
else:
rows = math.floor(math.sqrt(len(imgs)))
while len(imgs) % rows != 0:
rows -= 1
if rows > len(imgs):
rows = len(imgs)
cols = math.ceil(len(imgs) / rows)
cols = math.ceil(len(imgs) / rows)
elif cols is None:
cols = math.ceil(len(imgs) / rows)
elif rows is None:
rows = math.ceil(len(imgs) / cols)
else:
pass
return rows, cols
def image_grid(imgs, batch_size=1, rows=None):
rows, cols = get_grid_size(imgs, batch_size, rows=rows)
def image_grid(imgs, batch_size:int=1, rows:int=None, cols:int=None):
rows, cols = get_grid_size(imgs, batch_size, rows=rows, cols=cols)
params = script_callbacks.ImageGridLoopParams(imgs, cols, rows)
script_callbacks.image_grid_callback(params)
imgs = [i for i in imgs if i is not None] if imgs is not None else []
+1 -1
View File
@@ -47,7 +47,7 @@ class PipelineBase(TorchCompatibleModule, diffusers.DiffusionPipeline, metaclass
if "optimum.onnxruntime" in sys.modules:
import optimum.onnxruntime
if isinstance(module, optimum.onnxruntime.modeling_diffusion._ORTDiffusionModelPart): # pylint: disable=protected-access
if isinstance(module, optimum.onnxruntime.modeling_diffusion._ORTDiffusionModelPart): # pylint: disable=protected-access, no-member
device = extract_device(args, kwargs)
if device is None:
return self
+24 -10
View File
@@ -293,6 +293,12 @@ class YoloRestorer(Detailer):
p.state = ''
prev_state = shared.state.job
pc = copy(p)
orig_sigma_adjust: float = shared.opts.schedulers_sigma_adjust
orig_sigma_end: float = shared.opts.schedulers_sigma_adjust_max
shared.opts.schedulers_sigma_adjust = shared.opts.detailer_sigma_adjust
shared.opts.schedulers_sigma_adjust_max = shared.opts.detailer_sigma_adjust_max
for item in items:
if item.mask is None:
continue
@@ -308,6 +314,9 @@ class YoloRestorer(Detailer):
if len(pp.images) > 1:
mask_all.append(pp.images[1])
shared.opts.schedulers_sigma_adjust = orig_sigma_adjust
shared.opts.schedulers_sigma_adjust_max = orig_sigma_end
# restore pipeline
if control_pipeline is not None:
shared.sd_model = control_pipeline
@@ -330,7 +339,7 @@ class YoloRestorer(Detailer):
return np_image
def ui(self, tab: str):
def ui_settings_change(detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps):
def ui_settings_change(detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end):
shared.opts.detailer_models = detailers
shared.opts.detailer_classes = classes
shared.opts.detailer_padding = padding
@@ -340,6 +349,8 @@ class YoloRestorer(Detailer):
shared.opts.detailer_min_size = min_size
shared.opts.detailer_max_size = max_size
shared.opts.detailer_iou = iou
shared.opts.detailer_sigma_adjust = renoise_value
shared.opts.detailer_sigma_adjust_max = renoise_end
shared.opts.save(shared.config_filename, silent=True)
shared.log.debug(f'Detailer settings: models={detailers} classes={classes} strength={strength} conf={min_confidence} max={max_detected} iou={iou} size={min_size}-{max_size} padding={padding} steps={steps}')
@@ -371,15 +382,18 @@ class YoloRestorer(Detailer):
min_size = gr.Slider(label="Min size", elem_id=f"{tab}_detailer_min_size", value=min_size, minimum=0.0, maximum=1.0, step=0.05)
max_size = shared.opts.detailer_max_size if shared.opts.detailer_max_size < 1 and shared.opts.detailer_max_size > 0 else 1.0
max_size = gr.Slider(label="Max size", elem_id=f"{tab}_detailer_max_size", value=max_size, minimum=0.0, maximum=1.0, step=0.05)
detailers.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps], outputs=[])
classes.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps], outputs=[])
padding.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps], outputs=[])
blur.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps], outputs=[])
min_confidence.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps], outputs=[])
max_detected.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps], outputs=[])
min_size.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps], outputs=[])
max_size.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps], outputs=[])
iou.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps], outputs=[])
with gr.Row(elem_classes=['flex-break']):
renoise_value = gr.Slider(minimum=0.5, maximum=1.5, step=0.01, label='Renoiose', value=shared.opts.detailer_sigma_adjust, elem_id=f"{tab}_detailer_renoise")
renoise_end = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Renoise end', value=shared.opts.detailer_sigma_adjust_max, elem_id=f"{tab}_detailer_renoise_end")
detailers.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end], outputs=[])
classes.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end], outputs=[])
padding.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end], outputs=[])
blur.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end], outputs=[])
min_confidence.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end], outputs=[])
max_detected.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end], outputs=[])
min_size.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end], outputs=[])
max_size.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end], outputs=[])
iou.change(fn=ui_settings_change, inputs=[detailers, classes, strength, padding, blur, min_confidence, max_detected, min_size, max_size, iou, steps, renoise_value, renoise_end], outputs=[])
return enabled, prompt, negative, steps, strength
+3 -3
View File
@@ -294,14 +294,14 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
ema_scope_context = p.sd_model.ema_scope if not shared.native else nullcontext
if not shared.native:
shared.state.job_count = p.n_iter
shared.state.batch_count = p.n_iter
with devices.inference_context(), ema_scope_context():
t0 = time.time()
if not hasattr(p, 'skip_init'):
p.init(p.all_prompts, p.all_seeds, p.all_subseeds)
debug(f'Processing inner: args={vars(p)}')
for n in range(p.n_iter):
# if hasattr(p, 'skip_processing'):
# continue
shared.state.batch_no = n + 1
pag.apply(p)
debug(f'Processing inner: iteration={n+1}/{p.n_iter}')
p.iteration = n
@@ -455,7 +455,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
p.color_corrections = None
index_of_first_image = 0
if (shared.opts.return_grid or shared.opts.grid_save) and not p.do_not_save_grid and len(output_images) > 1:
if (shared.opts.return_grid or shared.opts.grid_save) and (not p.do_not_save_grid) and (len(output_images) > 1):
if images.check_grid_size(output_images):
r, c = images.get_grid_size(output_images, p.batch_size)
grid = images.image_grid(output_images, p.batch_size)
+1
View File
@@ -125,6 +125,7 @@ def diffusers_callback(pipe, step: int = 0, timestep: int = 0, kwargs: dict = {}
shared.state.current_sigma_next = pipe.scheduler.sigmas[pipe.scheduler.step_index]
if (shared.opts.schedulers_sigma_adjust != 1.0) and (timestep > 1000 * shared.opts.schedulers_sigma_adjust_min) and (timestep < 1000 * shared.opts.schedulers_sigma_adjust_max):
pipe.scheduler.sigmas[pipe.scheduler.step_index+1] = pipe.scheduler.sigmas[pipe.scheduler.step_index+1] * shared.opts.schedulers_sigma_adjust
p.extra_generation_params["Sigma adjust"] = shared.opts.schedulers_sigma_adjust
except Exception:
pass
except Exception as e:
+44 -8
View File
@@ -47,44 +47,80 @@ class ProgressRequest(BaseModel):
class InternalProgressResponse(BaseModel):
job: str = Field(default=None, title="Job name", description="Internal job name")
textinfo: str = Field(default=None, title="Info text", description="Info text used by WebUI.")
# status fields
active: bool = Field(title="Whether the task is being worked on right now")
queued: bool = Field(title="Whether the task is in queue")
paused: bool = Field(title="Whether the task is paused")
completed: bool = Field(title="Whether the task has already finished")
debug: bool = Field(title="Debug logging level")
# raw fields
step: int = Field(default=None, title="Current step", description="Current step of the task")
steps: int = Field(default=None, title="Total steps", description="Total number of steps")
batch_no: int = Field(default=None, title="Current batch", description="Current batch")
batch_count: int = Field(default=None, title="Total batches", description="Total number of batches")
# calculated fields
progress: float = Field(default=None, title="Progress", description="The progress with a range of 0 to 1")
eta: float = Field(default=None, title="ETA in secs")
# image fields
live_preview: str = Field(default=None, title="Live preview image", description="Current live preview; a data: uri")
id_live_preview: int = Field(default=None, title="Live preview image ID", description="Send this together with next request to prevent receiving same image")
textinfo: str = Field(default=None, title="Info text", description="Info text used by WebUI.")
def progressapi(req: ProgressRequest):
def api_progress(req: ProgressRequest):
active = req.id_task == current_task
queued = req.id_task in pending_tasks
completed = req.id_task in finished_tasks
paused = shared.state.paused
step = max(shared.state.sampling_step, 0)
steps = max(shared.state.sampling_steps, 1)
progress = round(min(1, abs(step / steps) if steps > 0 else 0), 2)
batch_no = max(shared.state.batch_no, 0)
batch_count = max(shared.state.batch_count, 0)
current = step / steps if step > 0 and steps > 0 else 0
batch = batch_no / batch_count if batch_no > 0 and batch_count > 0 else 1
progress = round(min(1, current * batch), 2)
elapsed = time.time() - shared.state.time_start if shared.state.time_start is not None else 0
predicted = elapsed / progress if progress > 0 else None
eta = predicted - elapsed if predicted is not None else None
id_live_preview = req.id_live_preview
live_preview = None
textinfo = shared.state.textinfo
updated = shared.state.set_current_image()
debug_log(f'Preview: job={shared.state.job} active={active} progress={step}/{steps}/{progress} image={shared.state.current_image_sampling_step} request={id_live_preview} last={shared.state.id_live_preview} enabled={shared.opts.live_previews_enable} job={shared.state.preview_job} updated={updated} image={shared.state.current_image} elapsed={elapsed:.3f}')
if not active:
return InternalProgressResponse(job=shared.state.job, active=active, queued=queued, paused=paused, completed=completed, id_live_preview=-1, debug=debug, textinfo="Queued..." if queued else "Waiting...")
if shared.opts.live_previews_enable and (shared.state.id_live_preview != id_live_preview) and (shared.state.current_image is not None):
id_live_preview = -1
textinfo = "Queued..." if queued else "Waiting..."
debug_log(f'Preview: job={shared.state.job} active={active} progress={step}/{steps}/{progress} image={shared.state.current_image_sampling_step} request={id_live_preview} last={shared.state.id_live_preview} enabled={shared.opts.live_previews_enable} job={shared.state.preview_job} updated={updated} image={shared.state.current_image} elapsed={elapsed:.3f}')
if shared.opts.live_previews_enable and active and (shared.state.id_live_preview != req.id_live_preview) and (shared.state.current_image is not None):
buffered = io.BytesIO()
shared.state.current_image.save(buffered, format='jpeg')
live_preview = f'data:image/jpeg;base64,{base64.b64encode(buffered.getvalue()).decode("ascii")}'
id_live_preview = shared.state.id_live_preview
res = InternalProgressResponse(job=shared.state.job, active=active, queued=queued, paused=paused, completed=completed, progress=progress, eta=eta, live_preview=live_preview, id_live_preview=id_live_preview, debug=debug, textinfo=shared.state.textinfo)
res = InternalProgressResponse(
job=shared.state.job,
textinfo=textinfo,
active=active,
queued=queued,
paused=paused,
completed=completed,
debug=debug,
progress=progress,
step=step,
steps=steps,
batch_no=batch_no,
batch_count=batch_count,
job_timestamp=shared.state.time_start,
eta=eta,
live_preview=live_preview,
id_live_preview=id_live_preview,
)
return res
def setup_progress_api():
shared.api.add_api_route("/internal/progress", progressapi, methods=["POST"], response_model=InternalProgressResponse)
shared.api.add_api_route("/internal/progress", api_progress, methods=["POST"], response_model=InternalProgressResponse)
+3 -2
View File
@@ -9,6 +9,7 @@ import diffusers
import diffusers.loaders.single_file_utils
import torch
from installer import log
from modules import paths, shared, shared_state, modelloader, devices, script_callbacks, sd_vae, sd_unet, errors, sd_models_config, sd_models_compile, sd_hijack_accelerate, sd_detect, model_quant
from modules.timer import Timer, process as process_timer
from modules.memstats import memory_stats
@@ -25,9 +26,9 @@ sd_metadata_file = os.path.join(paths.data_path, "metadata.json")
sd_metadata = None
sd_metadata_pending = 0
sd_metadata_timer = 0
debug_move = shared.log.trace if os.environ.get('SD_MOVE_DEBUG', None) is not None else lambda *args, **kwargs: None
debug_move = log.trace if os.environ.get('SD_MOVE_DEBUG', None) is not None else lambda *args, **kwargs: None
debug_load = os.environ.get('SD_LOAD_DEBUG', None)
debug_process = shared.log.trace if os.environ.get('SD_PROCESS_DEBUG', None) is not None else lambda *args, **kwargs: None
debug_process = log.trace if os.environ.get('SD_PROCESS_DEBUG', None) is not None else lambda *args, **kwargs: None
diffusers_version = int(diffusers.__version__.split('.')[1])
checkpoint_tiles = checkpoint_titles # legacy compatibility
+3 -1
View File
@@ -19,12 +19,14 @@ class NoWatermark:
def get_signature(cls):
if cls is None or not hasattr(cls, '__init__'):
return {}
signature = inspect.signature(cls.__init__, follow_wrapped=True)
return signature.parameters
def get_call(cls):
if cls is None:
if cls is None or not hasattr(cls, '__call__'): # noqa: B004
return []
signature = inspect.signature(cls.__call__, follow_wrapped=True)
return signature.parameters
+2 -1
View File
@@ -4,11 +4,12 @@ import time
import inspect
import torch
import accelerate.hooks
from installer import log
from modules import shared, devices, errors, model_quant
from modules.timer import process as process_timer
debug_move = shared.log.trace if os.environ.get('SD_MOVE_DEBUG', None) is not None else lambda *args, **kwargs: None
debug_move = log.trace if os.environ.get('SD_MOVE_DEBUG', None) is not None else lambda *args, **kwargs: None
should_offload = ['sc', 'sd3', 'f1', 'hunyuandit', 'auraflow', 'omnigen', 'cogview4']
offload_hook_instance = None
balanced_offload_exclude = ['OmniGenPipeline', 'CogView4Pipeline']
+5 -1
View File
@@ -677,7 +677,8 @@ options_templates.update(options_section(('saving-images', "Image Options"), {
"image_sep_grid": OptionInfo("<h2>Grid Options</h2>", "", gr.HTML),
"grid_save": OptionInfo(True, "Save all generated image grids"),
"grid_format": OptionInfo('jpg', 'File format', gr.Dropdown, {"choices": ["jpg", "png", "webp", "tiff", "jp2", "jxl"]}),
"n_rows": OptionInfo(-1, "Row count", gr.Slider, {"minimum": -1, "maximum": 16, "step": 1}),
"n_rows": OptionInfo(-1, "Grid max rows count", gr.Slider, {"minimum": -1, "maximum": 16, "step": 1}),
"n_cols": OptionInfo(-1, "Grid max columns count", gr.Slider, {"minimum": -1, "maximum": 16, "step": 1}),
"grid_background": OptionInfo("#000000", "Grid background color", gr.ColorPicker, {}),
"font": OptionInfo("", "Font file"),
"font_color": OptionInfo("#FFFFFF", "Font color", gr.ColorPicker, {}),
@@ -745,6 +746,7 @@ options_templates.update(options_section(('ui', "User Interface"), {
"ui_request_timeout": OptionInfo(30000, "UI request timeout", gr.Slider, {"minimum": 1000, "maximum": 120000, "step": 10}),
"motd": OptionInfo(False, "Show MOTD"),
"compact_view": OptionInfo(False, "Compact view"),
"ui_columns": OptionInfo(4, "Gallery view columns", gr.Slider, {"minimum": 1, "maximum": 8, "step": 1}),
"return_grid": OptionInfo(True, "Show grid in results"),
"return_mask": OptionInfo(False, "Inpainting include greyscale mask in results"),
"return_mask_composite": OptionInfo(False, "Inpainting include masked composite in results"),
@@ -829,6 +831,8 @@ options_templates.update(options_section(('postprocessing', "Postprocessing"), {
"detailer_conf": OptionInfo(0.6, "Min confidence", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}),
"detailer_max": OptionInfo(2, "Max detected", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1, "visible": False}),
"detailer_iou": OptionInfo(0.5, "Max overlap", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}),
"detailer_sigma_adjust": OptionInfo(1.0, "Detailer sigma adjust", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}),
"detailer_sigma_adjust_max": OptionInfo(1.0, "Detailer sigma end", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}),
"detailer_min_size": OptionInfo(0.0, "Min object size", gr.Slider, {"minimum": 0.1, "maximum": 1, "step": 0.05, "visible": False}),
"detailer_max_size": OptionInfo(1.0, "Max object size", gr.Slider, {"minimum": 0.1, "maximum": 1, "step": 0.05, "visible": False}),
"detailer_padding": OptionInfo(20, "Item padding", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": False}),
+4
View File
@@ -19,6 +19,8 @@ class State:
job = ""
job_no = 0
job_count = 0
batch_no = 0
batch_count = 0
frame_count = 0
total_jobs = 0
job_timestamp = '0'
@@ -145,6 +147,8 @@ class State:
self.job = title
self.job_count = 0
self.frame_count = 0
self.batch_no = 0
self.batch_count = 0
self.job_no = 0
self.job_timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
self.paused = False
+1 -2
View File
@@ -242,7 +242,6 @@ def create_output_panel(tabname, preview=True, prompt=None, height=None, transfe
with gr.Group(elem_id=f"{tabname}_gallery_container"):
if tabname == "txt2img":
gr.HTML(value="", elem_id="main_info", visible=False, elem_classes=["main-info"])
# columns are for <576px, <768px, <992px, <1200px, <1400px, >1400px
result_gallery = gr.Gallery(value=[],
label='Output',
show_label=False,
@@ -250,7 +249,7 @@ def create_output_panel(tabname, preview=True, prompt=None, height=None, transfe
allow_preview=True,
container=False,
preview=preview,
columns=4,
columns=shared.opts.ui_columns,
object_fit='scale-down',
height=height,
elem_id=f"{tabname}_gallery",
+15
View File
@@ -13,8 +13,23 @@ MEM_BUS_WIDTH = {
"AMD Radeon RX 7900 GRE": 256,
"AMD Radeon RX 7800 XT": 256,
"AMD Radeon RX 7700 XT": 192,
"AMD Radeon RX 7700": 192,
"AMD Radeon RX 7650 GRE": 128,
"AMD Radeon RX 7600 XT": 128,
"AMD Radeon RX 7600": 128,
"AMD Radeon RX 7500 XT": 96,
"AMD Radeon RX 6950 XT": 256,
"AMD Radeon RX 6900 XT": 256,
"AMD Radeon RX 6800 XT": 256,
"AMD Radeon RX 6800": 256,
"AMD Radeon RX 6750 XT": 192,
"AMD Radeon RX 6700 XT": 192,
"AMD Radeon RX 6700": 160,
"AMD Radeon RX 6650 XT": 128,
"AMD Radeon RX 6600 XT": 128,
"AMD Radeon RX 6600": 128,
"AMD Radeon RX 6500 XT": 64,
"AMD Radeon RX 6400": 64,
}
+1 -1
Submodule wiki updated: 9408b299ff...7d2b46a482