add process batch

This commit is contained in:
Vladimir Mandic
2023-10-08 07:25:45 -04:00
parent 95f3a94829
commit 65dfed93a1
3 changed files with 12 additions and 10 deletions
+5 -2
View File
@@ -1,11 +1,10 @@
# Change Log for SD.Next
## Update for 2023-10-07
## Update for 2023-10-08
**TBD**: Candidates before release:
- Note: Free-U requires unreleased diffusers
- Update Lora handler for *backend:diffusers*
- Merge parallel batch processing
This is a big one, with some major changes and new functionality...
And probably the biggest release since introduction of **Diffusers**
@@ -165,6 +164,10 @@ or even free speedups and quality improvements (regardless of which workflows yo
available for *diffusers* and *original* backends
2x speed-up your generations for free :)
thanks @tfernd
- **Batch mode**
new option *settings -> inference -> batch mode*
when using img2img process batch, process multiple images in batch in parallel
thanks @Symbiomatrix
- **General**
- **Startup**
- all main CLI parameters can now be set as environment variable as well
+6 -7
View File
@@ -16,7 +16,7 @@ def process_batch(p, input_files, input_dir, output_dir, inpaint_mask_dir, args)
image_files = [f.name for f in input_files]
else:
if not os.path.isdir(input_dir):
shared.log.error(f"Input directory not found: {input_dir}")
shared.log.error(f"Process batch: directory not found: {input_dir}")
return
image_files = shared.listfiles(input_dir)
is_inpaint_batch = False
@@ -24,22 +24,21 @@ def process_batch(p, input_files, input_dir, output_dir, inpaint_mask_dir, args)
inpaint_masks = shared.listfiles(inpaint_mask_dir)
is_inpaint_batch = len(inpaint_masks) > 0
if is_inpaint_batch:
shared.log.info(f"\nInpaint batch is enabled. {len(inpaint_masks)} masks found.")
# SBM Batch frame should actually print btcrept. Or customise the messages.
shared.log.info(f"Will process {len(image_files)} images, creating {p.n_iter * p.batch_size} new images for each.")
shared.log.info(f"Process batch: inpaint batch masks={len(inpaint_masks)}")
save_normally = output_dir == ''
p.do_not_save_grid = True
p.do_not_save_samples = not save_normally
shared.state.job_count = len(image_files) * p.n_iter
# SBM Batch frame mode, take 2.
if shared.opts.batch_frame_mode:
if shared.opts.batch_frame_mode: # SBM Frame mode is on, process each image in batch with same seed
window_size = p.batch_size
btcrept = 1
p.seed = [p.seed] * window_size # SBM MONKEYPATCH: Need to change processing to support a fixed seed value.
p.subseed = [p.subseed] * window_size # SBM MONKEYPATCH
shared.log.info(f"Process batch: inputs={len(image_files)} parallel={window_size} outputs={p.n_iter} per input ")
else: # SBM Frame mode is off, standard operation of repeating same images with sequential seed.
window_size = 1
btcrept = p.batch_size
shared.log.info(f"Process batch: inputs={len(image_files)} outputs={p.n_iter * p.batch_size} per input")
for i in range(0, len(image_files), window_size):
shared.state.job = f"{i+1} to {min(i+window_size, len(image_files))} out of {len(image_files)}"
if shared.state.skipped:
@@ -99,7 +98,7 @@ def process_batch(p, input_files, input_dir, output_dir, inpaint_mask_dir, args)
for k, v in items.items():
image.info[k] = v
images.save_image(image, path=output_dir, basename=basename, seed=None, prompt=None, extension=ext, info=geninfo, short_filename=True, no_prompt=True, grid=False, pnginfo_section_name="extras", existing_info=image.info, forced_filename=None)
shared.log.debug(f'Processed: {len(batch_image_files)} Memory: {memory_stats()} batch')
shared.log.debug(f'Processed: images={len(batch_image_files)} memory={memory_stats()} batch')
def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, latent_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, full_quality: bool, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, diffusers_guidance_rescale: float, refiner_steps: int, refiner_start: float, clip_skip: int, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_files: list, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, *args): # pylint: disable=unused-argument
+1 -1
View File
@@ -464,7 +464,7 @@ options_templates.update(options_section(('advanced', "Inference Settings"), {
"hypertile_unet_tile": OptionInfo(256, "HyperTile for UNet tile size", gr.Slider, {"minimum": 256, "maximum": 1024, "step": 8}),
"inference_other_sep": OptionInfo("<h2>Other</h2>", "", gr.HTML),
"batch_frame_mode": OptionInfo(False, "Use batchsize to process multiple images in batch mode"),
"batch_frame_mode": OptionInfo(False, "Process multiple images in batch in parallel"),
"inference_mode": OptionInfo("no-grad", "Torch inference mode", gr.Radio, lambda: {"choices": ["no-grad", "inference-mode", "none"]}),
"sd_vae_sliced_encode": OptionInfo(False, "VAE Slicing (original)"),
}))