diff --git a/CHANGELOG.md b/CHANGELOG.md index bd558174d..b333b2e24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Change Log for SD.Next +## Update for 2025-01-16 + +- **Gallery**: + - add http fallback for slow/unreliable links +- **Fixes**: + - non-full vae decode + - send-to image transfer + - sana vae tiling + - increase gallery timeouts + - update ui element ids + ## Update for 2025-01-15 ### Highlights for 2025-01-15 diff --git a/extensions-builtin/sdnext-modernui b/extensions-builtin/sdnext-modernui index 2960e3679..c17c53928 160000 --- a/extensions-builtin/sdnext-modernui +++ b/extensions-builtin/sdnext-modernui @@ -1 +1 @@ -Subproject commit 2960e36797dafb46545f5ad03364cb7003b84c7e +Subproject commit c17c5392816e3e6e212c7d10166260728e10d249 diff --git a/installer.py b/installer.py index e925f2c30..1e62ddd2a 100644 --- a/installer.py +++ b/installer.py @@ -492,7 +492,7 @@ def check_diffusers(): t_start = time.time() if args.skip_all or args.skip_git: return - sha = 'c944f0651f679728d4ec7b6488120ac49c2f1315' # diffusers commit hash + sha = 'b785ddb654e4be3ae0066e231734754bdb2a191c' # 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 '' @@ -876,7 +876,7 @@ def install_packages(): if args.profile: pr = cProfile.Profile() pr.enable() - log.info('Verifying packages') + # log.info('Install: verifying packages') clip_package = os.environ.get('CLIP_PACKAGE', "git+https://github.com/openai/CLIP.git") install(clip_package, 'clip', quiet=True) install('open-clip-torch', no_deps=True, quiet=True) diff --git a/javascript/aspectRatioOverlay.js b/javascript/aspectRatioOverlay.js index ff0b621ed..380ebef80 100644 --- a/javascript/aspectRatioOverlay.js +++ b/javascript/aspectRatioOverlay.js @@ -12,7 +12,7 @@ function dimensionChange(e, is_width, is_height) { if (tabIndex === 0) targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img'); // img2img else if (tabIndex === 1) targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img'); // Sketch else if (tabIndex === 2) targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img'); // Inpaint - else if (tabIndex === 3) targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img'); // Inpaint sketch + else if (tabIndex === 3) targetElement = gradioApp().querySelector('#composite div[data-testid=image] img'); // Inpaint sketch if (targetElement) { let arPreviewRect = gradioApp().querySelector('#imageARPreview'); diff --git a/javascript/gallery.js b/javascript/gallery.js index 32f261e12..a2c225441 100644 --- a/javascript/gallery.js +++ b/javascript/gallery.js @@ -46,7 +46,7 @@ class GalleryFolder extends HTMLElement { else folder.shadow.children[1].classList.remove('gallery-folder-selected'); } }); - div.addEventListener('click', fetchFiles); // eslint-disable-line no-use-before-define + div.addEventListener('click', fetchFilesWS); // eslint-disable-line no-use-before-define this.shadow.appendChild(div); } } @@ -224,7 +224,7 @@ async function getHash(str, algo = 'SHA-256') { } } -async function wsConnect(socket, timeout = 2000) { +async function wsConnect(socket, timeout = 5000) { const intrasleep = 100; const ttl = timeout / intrasleep; const isOpened = () => (socket.readyState === WebSocket.OPEN); @@ -327,17 +327,57 @@ async function gallerySort(btn) { el.status.innerText = `Sort | ${arr.length.toLocaleString()} images | ${Math.floor(t1 - t0).toLocaleString()}ms`; } -async function fetchFiles(evt) { // fetch file-by-file list over websockets +async function fetchFilesHT(evt) { + el.status.innerText = `Folder | ${evt.target.name}`; + const t0 = performance.now(); + const fragment = document.createDocumentFragment(); + el.status.innerText = `Folder | ${evt.target.name} | in-progress`; + let numFiles = 0; + + const res = await fetch(`/sdapi/v1/browser/files?folder=${encodeURI(evt.target.name)}`); + if (!res || res.status !== 200) { + el.status.innerText = `Folder | ${evt.target.name} | failed: ${res?.statusText}`; + return; + } + const jsonData = await res.json(); + for (const line of jsonData) { + const data = decodeURI(line).split('##F##'); + numFiles++; + const f = new GalleryFile(data[0], data[1]); + fragment.appendChild(f); + } + + el.files.appendChild(fragment); + + const t1 = performance.now(); + log(`gallery: folder=${evt.target.name} num=${numFiles} time=${Math.floor(t1 - t0)}ms`); + el.status.innerText = `Folder | ${evt.target.name} | ${numFiles.toLocaleString()} images | ${Math.floor(t1 - t0).toLocaleString()}ms`; + addSeparators(); +} + +async function fetchFilesWS(evt) { // fetch file-by-file list over websockets el.files.innerHTML = ''; if (!url) return; if (ws && ws.readyState === WebSocket.OPEN) ws.close(); // abort previous request - ws = new WebSocket(`${url}/sdapi/v1/browser/files`); - await wsConnect(ws); + let wsConnected = false; + try { + ws = new WebSocket(`${url}/sdapi/v1/browser/files`); + wsConnected = await wsConnect(ws); + } catch (err) { + log('gallery: ws connect error', err); + return; + } + log(`gallery: connected=${wsConnected} state=${ws?.readyState} url=${ws?.url}`); + if (!wsConnected) { + await fetchFilesHT(evt); // fallback to http + return; + } el.status.innerText = `Folder | ${evt.target.name}`; const t0 = performance.now(); let numFiles = 0; let t1 = performance.now(); let fragment = document.createDocumentFragment(); + ws.onmessage = (event) => { numFiles++; t1 = performance.now(); diff --git a/javascript/sdnext.css b/javascript/sdnext.css index 91ab6318d..139b7d1bb 100644 --- a/javascript/sdnext.css +++ b/javascript/sdnext.css @@ -36,12 +36,6 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { margin-left .gradio-image { min-height: fit-content; } .gradio-image img { object-fit: contain; } */ -/* -.gradio-image { min-height: 200px !important; } -.image-container { height: unset !important; } -.control-image { height: unset !important; } -#img2img_sketch, #img2maskimg, #inpaint_sketch { overflow: overlay !important; resize: auto; background: var(--panel-background-fill); z-index: 5; } -*/ /* color elements */ .gradio-dropdown, .block.gradio-slider, .block.gradio-checkbox, .block.gradio-textbox, .block.gradio-radio, .block.gradio-checkboxgroup, .block.gradio-number, .block.gradio-colorpicker { border-width: 0 !important; box-shadow: none !important;} diff --git a/modules/api/gallery.py b/modules/api/gallery.py index 52455ffa1..ea33a9b27 100644 --- a/modules/api/gallery.py +++ b/modules/api/gallery.py @@ -154,6 +154,24 @@ async def get_thumb(file: str): content = { 'error': str(e) } return JSONResponse(content=content) + @app.get("/sdapi/v1/browser/files", response_model=list) + async def ht_files(folder: str): + try: + t0 = time.time() + files = files_cache.directory_files(folder, recursive=True) + lines = [] + for f in files: + file = os.path.relpath(f, folder) + msg = quote(folder) + '##F##' + quote(file) + msg = msg[:1] + ":" + msg[4:] if msg[1:4] == "%3A" else msg + lines.append(msg) + t1 = time.time() + shared.log.debug(f'Gallery: type=ht folder="{folder}" files={len(lines)} time={t1-t0:.3f}') + return lines + except Exception as e: + shared.log.error(f'Gallery: {folder} {e}') + return [] + @app.websocket("/sdapi/v1/browser/files") async def ws_files(ws: WebSocket): try: @@ -173,7 +191,7 @@ async def ws_files(ws: WebSocket): await manager.send(ws, msg) await manager.send(ws, '#END#') t1 = time.time() - shared.log.debug(f'Gallery: folder="{folder}" files={numFiles} time={t1-t0:.3f}') + shared.log.debug(f'Gallery: type=ws folder="{folder}" files={numFiles} time={t1-t0:.3f}') except WebSocketDisconnect: debug('Browser WS unexpected disconnect') manager.disconnect(ws) diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index ce1896169..fe65efe19 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -105,12 +105,12 @@ def create_buttons(tabs_list): return buttons -def bind_buttons(buttons, send_image, send_generate_info): +def bind_buttons(buttons, image_component, send_generate_info): """old function for backwards compatibility; do not use this, use register_paste_params_button""" for tabname, button in buttons.items(): source_text_component = send_generate_info if isinstance(send_generate_info, gr.components.Component) else None source_tabname = send_generate_info if isinstance(send_generate_info, str) else None - bindings = ParamBinding(paste_button=button, tabname=tabname, source_text_component=source_text_component, source_image_component=send_image, source_tabname=source_tabname) + bindings = ParamBinding(paste_button=button, tabname=tabname, source_text_component=source_text_component, source_image_component=image_component, source_tabname=source_tabname) register_paste_params_button(bindings) @@ -124,27 +124,18 @@ def connect_paste_params_buttons(): if binding.tabname not in paste_fields: debug(f"Not not registered: tab={binding.tabname}") continue - """ - # legacy code that sets width/height based on image itself instead of metadata + fields = paste_fields[binding.tabname]["fields"] + destination_image_component = paste_fields[binding.tabname]["init_img"] - destination_width_component = next(iter([field for field, name in fields if name == "Size-1"] if fields else []), None) - destination_height_component = next(iter([field for field, name in fields if name == "Size-2"] if fields else []), None) if binding.source_image_component and destination_image_component: - if isinstance(binding.source_image_component, gr.Gallery): - func = send_image_and_dimensions if destination_width_component else image_from_url_text - jsfunc = "extract_image_from_gallery" - else: - func = send_image_and_dimensions if destination_width_component else lambda x: x - jsfunc = None binding.paste_button.click( - fn=func, - _js=jsfunc, + _js="extract_image_from_gallery" if isinstance(binding.source_image_component, gr.Gallery) else None, + fn=send_image, inputs=[binding.source_image_component], - outputs=[destination_image_component, destination_width_component, destination_height_component] if destination_width_component else [destination_image_component], + outputs=[destination_image_component], show_progress=False, ) - """ - fields = paste_fields[binding.tabname]["fields"] + override_settings_component = binding.override_settings_component or paste_fields[binding.tabname]["override_settings_component"] if binding.source_text_component is not None and fields is not None: connect_paste(binding.paste_button, fields, binding.source_text_component, override_settings_component, binding.tabname) @@ -165,15 +156,20 @@ def connect_paste_params_buttons(): ) +def send_image(x): + image = x if isinstance(x, Image.Image) else image_from_url_text(x) + return image + + def send_image_and_dimensions(x): - img = x if isinstance(x, Image.Image) else image_from_url_text(x) - if shared.opts.send_size and isinstance(img, Image.Image): - w = img.width - h = img.height + image = x if isinstance(x, Image.Image) else image_from_url_text(x) + if shared.opts.send_size and isinstance(image, Image.Image): + w = image.width + h = image.height else: w = gr.update() h = gr.update() - return img, w, h + return image, w, h def create_override_settings_dict(text_pairs): diff --git a/modules/processing_args.py b/modules/processing_args.py index 81f4ae5d3..509ba77e2 100644 --- a/modules/processing_args.py +++ b/modules/processing_args.py @@ -180,8 +180,8 @@ def set_pipeline_args(p, model, prompts:list, negative_prompts:list, prompts_2:t if not chi: args['complex_human_instruction'] = None if 'use_resolution_binning' in possible: - args['use_resolution_binning'] = True - p.extra_generation_params["Binning"] = True + args['use_resolution_binning'] = False + # p.extra_generation_params["Binning"] = True if prompt_parser_diffusers.embedder is not None and not prompt_parser_diffusers.embedder.scheduled_prompt: # not scheduled so we dont need it anymore prompt_parser_diffusers.embedder = None diff --git a/modules/processing_vae.py b/modules/processing_vae.py index faaacb21e..4d988e73b 100644 --- a/modules/processing_vae.py +++ b/modules/processing_vae.py @@ -58,16 +58,11 @@ def full_vqgan_decode(latents, model): if scaling_factor: latents = latents * scaling_factor - vae_name = os.path.splitext(os.path.basename(sd_vae.loaded_vae_file))[0] if sd_vae.loaded_vae_file is not None else "default" - vae_stats = f'name="{vae_name}" dtype={model.vqgan.dtype} device={model.vqgan.device}' - latents_stats = f'shape={latents.shape} dtype={latents.dtype} device={latents.device}' - stats = f'vae {vae_stats} latents {latents_stats}' - log_debug(f'VAE config: {model.vqgan.config}') try: decoded = model.vqgan.decode(latents).sample.clamp(0, 1) except Exception as e: - shared.log.error(f'VAE decode: {stats} {e}') + shared.log.error(f'VAE decode: {e}') errors.display(e, 'VAE decode') decoded = [] @@ -85,7 +80,8 @@ def full_vqgan_decode(latents, model): t1 = time.time() if debug: log_debug(f'VAE memory: {shared.mem_mon.read()}') - shared.log.debug(f'VAE decode: {stats} time={round(t1-t0, 3)}') + vae_name = os.path.splitext(os.path.basename(sd_vae.loaded_vae_file))[0] if sd_vae.loaded_vae_file is not None else "default" + shared.log.debug(f'VAE decode: vae="{vae_name}" type="vqgan" dtype={model.vqgan.dtype} device={model.vqgan.device} time={round(t1-t0, 3)}') return decoded @@ -103,7 +99,6 @@ def full_vae_decode(latents, model): base_device = None if shared.opts.diffusers_move_unet and not getattr(model, 'has_accelerate', False): base_device = sd_models.move_base(model, devices.cpu) - elif shared.opts.diffusers_offload_mode != "sequential": sd_models.move_model(model.vae, devices.device) @@ -134,17 +129,12 @@ def full_vae_decode(latents, model): if shift_factor: latents = latents + shift_factor - vae_name = os.path.splitext(os.path.basename(sd_vae.loaded_vae_file))[0] if sd_vae.loaded_vae_file is not None else "default" - vae_stats = f'vae="{vae_name}" dtype={model.vae.dtype} device={model.vae.device} upcast={upcast} slicing={getattr(model.vae, "use_slicing", None)} tiling={getattr(model.vae, "use_tiling", None)}' - latents_stats = f'latents={latents.shape}:{latents.device}:{latents.dtype}' - stats = f'{vae_stats} {latents_stats}' - log_debug(f'VAE config: {model.vae.config}') try: with devices.inference_context(): decoded = model.vae.decode(latents, return_dict=False)[0] except Exception as e: - shared.log.error(f'VAE decode: {stats} {e}') + shared.log.error(f'VAE decode: {e}') if 'out of memory' not in str(e): errors.display(e, 'VAE decode') decoded = [] @@ -162,21 +152,24 @@ def full_vae_decode(latents, model): elif shared.opts.diffusers_move_unet and not getattr(model, 'has_accelerate', False) and base_device is not None: sd_models.move_base(model, base_device) + t1 = time.time() if debug: log_debug(f'VAE memory: {shared.mem_mon.read()}') - shared.log.debug(f'Decode: {stats} time={round(t1-t0, 3)}') + vae_name = os.path.splitext(os.path.basename(sd_vae.loaded_vae_file))[0] if sd_vae.loaded_vae_file is not None else "default" + shared.log.debug(f'Decode: vae="{vae_name}" upcast={upcast} slicing={getattr(model.vae, "use_slicing", None)} tiling={getattr(model.vae, "use_tiling", None)} latents={latents.shape}:{latents.device}:{latents.dtype} time={t1-t0:.3f}') return decoded def full_vae_encode(image, model): - log_debug(f'VAE encode: name={sd_vae.loaded_vae_file if sd_vae.loaded_vae_file is not None else "baked"} dtype={model.vae.dtype} upcast={model.vae.config.get("force_upcast", None)}') if shared.opts.diffusers_move_unet and not getattr(model, 'has_accelerate', False) and hasattr(model, 'unet'): log_debug('Moving to CPU: model=UNet') unet_device = model.unet.device sd_models.move_model(model.unet, devices.cpu) if not shared.opts.diffusers_offload_mode == "sequential" and hasattr(model, 'vae'): sd_models.move_model(model.vae, devices.device) + vae_name = sd_vae.loaded_vae_file if sd_vae.loaded_vae_file is not None else "default" + log_debug(f'Encode vae="{vae_name}" dtype={model.vae.dtype} upcast={model.vae.config.get("force_upcast", None)}') encoded = model.vae.encode(image.to(model.vae.device, model.vae.dtype)).latent_dist.sample() if shared.opts.diffusers_move_unet and not getattr(model, 'has_accelerate', False) and hasattr(model, 'unet'): sd_models.move_model(model.unet, unet_device) @@ -184,7 +177,7 @@ def full_vae_encode(image, model): def taesd_vae_decode(latents): - log_debug(f'VAE decode: name=TAESD images={len(latents)} latents={latents.shape} slicing={shared.opts.diffusers_vae_slicing}') + t0 = time.time() if len(latents) == 0: return [] if shared.opts.diffusers_vae_slicing and len(latents) > 1: @@ -193,11 +186,13 @@ def taesd_vae_decode(latents): decoded[i] = sd_vae_taesd.decode(latents[i]) else: decoded = sd_vae_taesd.decode(latents) + t1 = time.time() + shared.log.debug(f'Decode: vae="taesd" latents={latents.shape}:{latents.dtype}:{latents.device} time={t1-t0:.3f}') return decoded def taesd_vae_encode(image): - log_debug(f'VAE encode: name=TAESD image={image.shape}') + shared.log.debug(f'Encode: vae="taesd" image={image.shape}') encoded = sd_vae_taesd.encode(image) return encoded @@ -243,6 +238,8 @@ def vae_decode(latents, model, output_type='np', full_quality=True, width=None, decoded = 2.0 * decoded - 1.0 # typical normalized range if torch.is_tensor(decoded): + if len(decoded.shape) == 3 and decoded.shape[0] == 3: + decoded = decoded.unsqueeze(0) if hasattr(model, 'video_processor'): imgs = model.video_processor.postprocess_video(decoded, output_type='pil') elif hasattr(model, 'image_processor'): diff --git a/modules/ui_control.py b/modules/ui_control.py index f577ad4c2..53a44f0e0 100644 --- a/modules/ui_control.py +++ b/modules/ui_control.py @@ -169,7 +169,7 @@ def create_ui(_blocks: gr.Blocks=None): video_skip_frames = gr.Slider(minimum=0, maximum=100, step=1, label='Skip input frames', value=0, elem_id="control_video_skip_frames") with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, video_duration, video_loop, video_pad, video_interpolate = create_video_inputs() + video_type, video_duration, video_loop, video_pad, video_interpolate = create_video_inputs(tab='control') enable_hr, hr_sampler_index, hr_denoising_strength, hr_resize_mode, hr_resize_context, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative = ui_sections.create_hires_inputs('control') detailer_enabled, detailer_prompt, detailer_negative, detailer_steps, detailer_strength = shared.yolo.ui('control') diff --git a/modules/ui_sections.py b/modules/ui_sections.py index a9bbe4ef2..def7e39b5 100644 --- a/modules/ui_sections.py +++ b/modules/ui_sections.py @@ -131,7 +131,7 @@ def create_seed_inputs(tab, reuse_visible=True): return seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w -def create_video_inputs(): +def create_video_inputs(tab:str): def video_type_change(video_type): return [ gr.update(visible=video_type != 'None'), @@ -141,12 +141,12 @@ def video_type_change(video_type): ] with gr.Column(): video_codecs = ['None', 'GIF', 'PNG', 'MP4/MP4V', 'MP4/AVC1', 'MP4/JVT3', 'MKV/H264', 'AVI/DIVX', 'AVI/RGBA', 'MJPEG/MJPG', 'MPG/MPG1', 'AVR/AVR1'] - video_type = gr.Dropdown(label='Video type', choices=video_codecs, value='None') + video_type = gr.Dropdown(label='Video type', choices=video_codecs, value='None', elem_id=f"{tab}_video_type") with gr.Column(): - video_duration = gr.Slider(label='Duration', minimum=0.25, maximum=300, step=0.25, value=2, visible=False) - video_loop = gr.Checkbox(label='Loop', value=True, visible=False, elem_id="control_video_loop") - video_pad = gr.Slider(label='Pad frames', minimum=0, maximum=24, step=1, value=1, visible=False) - video_interpolate = gr.Slider(label='Interpolate frames', minimum=0, maximum=24, step=1, value=0, visible=False) + video_duration = gr.Slider(label='Duration', minimum=0.25, maximum=300, step=0.25, value=2, visible=False, elem_id=f"{tab}_video_duration") + video_loop = gr.Checkbox(label='Loop', value=True, visible=False, elem_id=f"{tab}_video_loop") + video_pad = gr.Slider(label='Pad frames', minimum=0, maximum=24, step=1, value=1, visible=False, elem_id=f"{tab}_video_pad") + video_interpolate = gr.Slider(label='Interpolate frames', minimum=0, maximum=24, step=1, value=0, visible=False, elem_id=f"{tab}_video_interpolate") video_type.change(fn=video_type_change, inputs=[video_type], outputs=[video_duration, video_loop, video_pad, video_interpolate]) return video_type, video_duration, video_loop, video_pad, video_interpolate diff --git a/package.json b/package.json index 95f8899bf..6d3c8de4b 100644 --- a/package.json +++ b/package.json @@ -16,12 +16,12 @@ "url": "git+https://github.com/vladmandic/automatic.git" }, "scripts": { - "venv": "source venv/bin/activate", - "start": "python launch.py --debug", - "ruff": "ruff check", + "venv": ". venv/bin/activate", + "start": "npm run venv; python launch.py --debug", + "ruff": ". venv/bin/activate && ruff check", "eslint": "eslint javascript/ extensions-builtin/sdnext-modernui/javascript/", - "pylint": "pylint *.py modules/ extensions-builtin/", - "lint": "npm run eslint; npm run ruff; npm run pylint", + "pylint": ". venv/bin/activate && pylint *.py modules/ extensions-builtin/ | grep -v '^*'", + "lint": "npm run eslint && npm run ruff && npm run pylint", "test": "cli/test.sh" }, "devDependencies": { diff --git a/scripts/allegrovideo.py b/scripts/allegrovideo.py index b340e4962..003211a60 100644 --- a/scripts/allegrovideo.py +++ b/scripts/allegrovideo.py @@ -37,7 +37,7 @@ def show(self, is_img2img): return not is_img2img if shared.native else False # return signature is array of gradio components - def ui(self, _is_img2img): + def ui(self, is_img2img): with gr.Row(): gr.HTML('  Allegro Video
') with gr.Row(): @@ -46,7 +46,7 @@ def ui(self, _is_img2img): override_scheduler = gr.Checkbox(label='Override scheduler', value=True) with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs() + video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') return [num_frames, override_scheduler, video_type, duration, gif_loop, mp4_pad, mp4_interpolate] def run(self, p: processing.StableDiffusionProcessing, num_frames, override_scheduler, video_type, duration, gif_loop, mp4_pad, mp4_interpolate): # pylint: disable=arguments-differ, unused-argument diff --git a/scripts/animatediff.py b/scripts/animatediff.py index a704baae7..34b7829c1 100644 --- a/scripts/animatediff.py +++ b/scripts/animatediff.py @@ -196,7 +196,7 @@ def show(self, is_img2img): return not is_img2img - def ui(self, _is_img2img): + def ui(self, is_img2img): with gr.Row(): gr.HTML("  AnimateDiff
") with gr.Row(): @@ -221,7 +221,7 @@ def ui(self, _is_img2img): fi_temporal = gr.Slider(label='Temporal frequency', minimum=0.0, maximum=1.0, step=0.05, value=0.25) with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs() + video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') return [adapter_index, frames, lora_index, strength, latent_mode, video_type, duration, gif_loop, mp4_pad, mp4_interpolate, override_scheduler, fi_method, fi_iters, fi_order, fi_spatial, fi_temporal] def run(self, p: processing.StableDiffusionProcessing, adapter_index, frames, lora_index, strength, latent_mode, video_type, duration, gif_loop, mp4_pad, mp4_interpolate, override_scheduler, fi_method, fi_iters, fi_order, fi_spatial, fi_temporal): # pylint: disable=arguments-differ, unused-argument diff --git a/scripts/cogvideo.py b/scripts/cogvideo.py index 7b7a557f8..7184dd946 100644 --- a/scripts/cogvideo.py +++ b/scripts/cogvideo.py @@ -28,7 +28,7 @@ def show(self, is_img2img): return shared.native - def ui(self, _is_img2img): + def ui(self, is_img2img): with gr.Row(): gr.HTML("  CogVideoX
") with gr.Row(): @@ -46,7 +46,7 @@ def ui(self, _is_img2img): video = gr.Video(value=None, label='Video', source='upload', width=256, height=256) with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, duration, loop, pad, interpolate = create_video_inputs() + video_type, duration, loop, pad, interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') return [model, sampler, frames, guidance, offload, override, video_type, duration, loop, pad, interpolate, image, video] def load(self, model): diff --git a/scripts/hunyuanvideo.py b/scripts/hunyuanvideo.py index 874e20fc0..aac3eb8f0 100644 --- a/scripts/hunyuanvideo.py +++ b/scripts/hunyuanvideo.py @@ -60,7 +60,7 @@ def show(self, is_img2img): return not is_img2img if shared.native else False # return signature is array of gradio components - def ui(self, _is_img2img): + def ui(self, is_img2img): with gr.Row(): gr.HTML('  Hunyuan Video
') with gr.Row(): @@ -72,7 +72,7 @@ def ui(self, _is_img2img): template = gr.TextArea(label='Prompt processor', lines=3, value=default_template) with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs() + video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') return [num_frames, tile_frames, override_scheduler, template, video_type, duration, gif_loop, mp4_pad, mp4_interpolate] def run(self, p: processing.StableDiffusionProcessing, num_frames, tile_frames, override_scheduler, template, video_type, duration, gif_loop, mp4_pad, mp4_interpolate): # pylint: disable=arguments-differ, unused-argument diff --git a/scripts/image2video.py b/scripts/image2video.py index 6ef27412c..b39b793b5 100644 --- a/scripts/image2video.py +++ b/scripts/image2video.py @@ -20,7 +20,7 @@ def show(self, is_img2img): # return False # return signature is array of gradio components - def ui(self, _is_img2img): + def ui(self, is_img2img): def model_change(model_name): model = next(m for m in MODELS if m['name'] == model_name) return gr.update(value=model['info']), gr.update(visible=model_name == 'PIA'), gr.update(visible=model_name == 'VGen') @@ -47,7 +47,7 @@ def model_change(model_name): vg_fps = gr.Slider(label='Change rate', minimum=0.1, maximum=1.0, step=0.1, value=0.5) with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs() + video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') model_name.change(fn=model_change, inputs=[model_name], outputs=[model_info, fi_accordion, vgen_accordion]) return [model_name, num_frames, video_type, duration, gif_loop, mp4_pad, mp4_interpolate, fi_method, fi_iters, fi_order, fi_spatial, fi_temporal, vg_chunks, vg_fps] diff --git a/scripts/ltxvideo.py b/scripts/ltxvideo.py index 3f6cad08e..5599ceed4 100644 --- a/scripts/ltxvideo.py +++ b/scripts/ltxvideo.py @@ -65,7 +65,7 @@ def show(self, is_img2img): return shared.native # return signature is array of gradio components - def ui(self, _is_img2img): + def ui(self, is_img2img): def model_change(model): return gr.update(visible=model == 'custom') @@ -84,7 +84,7 @@ def model_change(model): model_custom = gr.Textbox(value='', label='Path to model file', visible=False) with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs() + video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') model.change(fn=model_change, inputs=[model], outputs=[model_custom]) return [model, model_custom, decode, sampler, num_frames, video_type, duration, gif_loop, mp4_pad, mp4_interpolate, teacache_enable, teacache_threshold] diff --git a/scripts/mochivideo.py b/scripts/mochivideo.py index cb2950eda..a3ed431bb 100644 --- a/scripts/mochivideo.py +++ b/scripts/mochivideo.py @@ -16,14 +16,14 @@ def show(self, is_img2img): return not is_img2img if shared.native else False # return signature is array of gradio components - def ui(self, _is_img2img): + def ui(self, is_img2img): with gr.Row(): gr.HTML('  Mochi.1 Video
') with gr.Row(): num_frames = gr.Slider(label='Frames', minimum=9, maximum=257, step=1, value=45) with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs() + video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') return [num_frames, video_type, duration, gif_loop, mp4_pad, mp4_interpolate] def run(self, p: processing.StableDiffusionProcessing, num_frames, video_type, duration, gif_loop, mp4_pad, mp4_interpolate): # pylint: disable=arguments-differ, unused-argument diff --git a/scripts/stablevideodiffusion.py b/scripts/stablevideodiffusion.py index 59cba1e96..20b302ff6 100644 --- a/scripts/stablevideodiffusion.py +++ b/scripts/stablevideodiffusion.py @@ -22,7 +22,7 @@ def show(self, is_img2img): return is_img2img if shared.native else False # return signature is array of gradio components - def ui(self, _is_img2img): + def ui(self, is_img2img): with gr.Row(): gr.HTML('  Stable Video Diffusion
') with gr.Row(): @@ -39,7 +39,7 @@ def ui(self, _is_img2img): override_resolution = gr.Checkbox(label='Override resolution', value=True) with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs() + video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') return [model, num_frames, override_resolution, min_guidance_scale, max_guidance_scale, decode_chunk_size, motion_bucket_id, noise_aug_strength, video_type, duration, gif_loop, mp4_pad, mp4_interpolate] def run(self, p: processing.StableDiffusionProcessing, model, num_frames, override_resolution, min_guidance_scale, max_guidance_scale, decode_chunk_size, motion_bucket_id, noise_aug_strength, video_type, duration, gif_loop, mp4_pad, mp4_interpolate): # pylint: disable=arguments-differ, unused-argument diff --git a/scripts/text2video.py b/scripts/text2video.py index a58340f60..4a5f71f2e 100644 --- a/scripts/text2video.py +++ b/scripts/text2video.py @@ -29,7 +29,7 @@ def show(self, is_img2img): return not is_img2img if shared.native else False # return signature is array of gradio components - def ui(self, _is_img2img): + def ui(self, is_img2img): def model_info_change(model_name): if model_name == 'None': @@ -50,7 +50,7 @@ def model_info_change(model_name): num_frames = gr.Slider(label='Frames', minimum=1, maximum=50, step=1, value=0) with gr.Row(): from modules.ui_sections import create_video_inputs - video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs() + video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') return [model_name, use_default, num_frames, video_type, duration, gif_loop, mp4_pad, mp4_interpolate] def run(self, p: processing.StableDiffusionProcessing, model_name, use_default, num_frames, video_type, duration, gif_loop, mp4_pad, mp4_interpolate): # pylint: disable=arguments-differ, unused-argument diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py index 38ee177e1..109d808b8 100644 --- a/scripts/xyz_grid.py +++ b/scripts/xyz_grid.py @@ -65,7 +65,7 @@ def ui(self, is_img2img): create_video = gr.Checkbox(label='Create video', value=False, elem_id=self.elem_id("xyz_create_video"), container=False) with gr.Row(visible=False) as ui_video: - video_type, video_duration, video_loop, video_pad, video_interpolate = create_video_inputs() + video_type, video_duration, video_loop, video_pad, video_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') create_video.change(fn=lambda x: gr.update(visible=x), inputs=[create_video], outputs=[ui_video]) with gr.Row(): diff --git a/scripts/xyz_grid_on.py b/scripts/xyz_grid_on.py index 2a8f22aba..1b0f79f43 100644 --- a/scripts/xyz_grid_on.py +++ b/scripts/xyz_grid_on.py @@ -71,7 +71,7 @@ def ui(self, is_img2img): create_video = gr.Checkbox(label='Create video', value=False, elem_id=self.elem_id("xyz_create_video"), container=False) with gr.Row(visible=False) as ui_video: - video_type, video_duration, video_loop, video_pad, video_interpolate = create_video_inputs() + video_type, video_duration, video_loop, video_pad, video_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') create_video.change(fn=lambda x: gr.update(visible=x), inputs=[create_video], outputs=[ui_video]) with gr.Row():