Merge pull request #3708 from vladmandic/dev

merge dev to master
This commit is contained in:
Vladimir Mandic
2025-01-16 11:54:17 -05:00
committed by GitHub
24 changed files with 146 additions and 90 deletions
+11
View File
@@ -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
+2 -2
View File
@@ -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)
+1 -1
View File
@@ -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');
+45 -5
View File
@@ -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();
-6
View File
@@ -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;}
+19 -1
View File
@@ -154,6 +154,24 @@ def register_api(app: FastAPI): # register api
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 @@ def register_api(app: FastAPI): # register api
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)
+18 -22
View File
@@ -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):
+2 -2
View File
@@ -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
+15 -18
View File
@@ -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'):
+1 -1
View File
@@ -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')
+6 -6
View File
@@ -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 create_video_inputs():
]
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
+5 -5
View File
@@ -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": {
+2 -2
View File
@@ -37,7 +37,7 @@ class Script(scripts.Script):
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('<a href="https://huggingface.co/rhymes-ai/Allegro">&nbsp Allegro Video</a><br>')
with gr.Row():
@@ -46,7 +46,7 @@ class Script(scripts.Script):
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
+2 -2
View File
@@ -196,7 +196,7 @@ class Script(scripts.Script):
return not is_img2img
def ui(self, _is_img2img):
def ui(self, is_img2img):
with gr.Row():
gr.HTML("<span>&nbsp AnimateDiff</span><br>")
with gr.Row():
@@ -221,7 +221,7 @@ class Script(scripts.Script):
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
+2 -2
View File
@@ -28,7 +28,7 @@ class Script(scripts.Script):
return shared.native
def ui(self, _is_img2img):
def ui(self, is_img2img):
with gr.Row():
gr.HTML("<span>&nbsp CogVideoX</span><br>")
with gr.Row():
@@ -46,7 +46,7 @@ class Script(scripts.Script):
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):
+2 -2
View File
@@ -60,7 +60,7 @@ class Script(scripts.Script):
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('<a href="https://huggingface.co/tencent/HunyuanVideo">&nbsp Hunyuan Video</a><br>')
with gr.Row():
@@ -72,7 +72,7 @@ class Script(scripts.Script):
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
+2 -2
View File
@@ -20,7 +20,7 @@ class Script(scripts.Script):
# 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 @@ class Script(scripts.Script):
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]
+2 -2
View File
@@ -65,7 +65,7 @@ class Script(scripts.Script):
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 @@ class Script(scripts.Script):
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]
+2 -2
View File
@@ -16,14 +16,14 @@ class Script(scripts.Script):
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('<a href="https://huggingface.co/genmo/mochi-1-preview">&nbsp Mochi.1 Video</a><br>')
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
+2 -2
View File
@@ -22,7 +22,7 @@ class Script(scripts.Script):
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('<a href="https://huggingface.co/stabilityai/stable-video-diffusion-img2vid">&nbsp Stable Video Diffusion</a><br>')
with gr.Row():
@@ -39,7 +39,7 @@ class Script(scripts.Script):
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
+2 -2
View File
@@ -29,7 +29,7 @@ class Script(scripts.Script):
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 @@ class Script(scripts.Script):
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
+1 -1
View File
@@ -65,7 +65,7 @@ class Script(scripts.Script):
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():
+1 -1
View File
@@ -71,7 +71,7 @@ class Script(scripts.Script):
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():