mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
+5
-3
@@ -1,8 +1,8 @@
|
||||
# Change Log for SD.Next
|
||||
|
||||
## Update for 2025-09-11
|
||||
## Update for 2025-09-12
|
||||
|
||||
### Highlights for 2025-09-11
|
||||
### Highlights for 2025-09-12
|
||||
|
||||
*What's new*? Big one is that we're (finally) switching the default UI to **ModernUI**!
|
||||
StandardUI is still available and can be selected in settings, but ModernUI is now the default for new installs
|
||||
@@ -12,7 +12,7 @@ Also, there are quite a few offloading improvements and many quality-of-life cha
|
||||
|
||||
[ReadMe](https://github.com/vladmandic/automatic/blob/master/README.md) | [ChangeLog](https://github.com/vladmandic/automatic/blob/master/CHANGELOG.md) | [Docs](https://vladmandic.github.io/sdnext-docs/) | [WiKi](https://github.com/vladmandic/automatic/wiki) | [Discord](https://discord.com/invite/sd-next-federal-batch-inspectors-1101998836328697867) | [Sponsor](https://github.com/sponsors/vladmandic)
|
||||
|
||||
### Details for 2025-09-11
|
||||
### Details for 2025-09-12
|
||||
|
||||
- **Models**
|
||||
- **Chroma** final versions: [Chroma1-HD](https://huggingface.co/lodestones/Chroma1-HD), [Chroma1-Base](https://huggingface.co/lodestones/Chroma1-Base) and [Chroma1-Flash](https://huggingface.co/lodestones/Chroma1-Flash)
|
||||
@@ -88,6 +88,8 @@ Also, there are quite a few offloading improvements and many quality-of-life cha
|
||||
- disallow `zluda` and `directml` on non-windows platforms
|
||||
- update openvino to `openvino==2025.3.0`
|
||||
- add deprecation warning for `python==3.9`
|
||||
- allow setting denoise strength to 0 in control/img2img
|
||||
this allows to run workflows which only refine or detail existing image without changing it
|
||||
- **Detailer** allow manually setting processing resolution
|
||||
*note*: this does not impact the actual image resolution, only the resolution at which detailer internally operates
|
||||
- **Fixes**
|
||||
|
||||
+3
-1
@@ -23,5 +23,7 @@
|
||||
"chroma-unlocked-v50": "models/Reference/lodestones Chroma Unlocked HD",
|
||||
"chroma-unlocked-v50-annealed": "models/Reference/lodestones Chroma Unlocked HD",
|
||||
"vladmandic--Qwen-Lightning": "models/Reference/Qwen-Lightning.jpg",
|
||||
"vladmandic--Qwen-Lightning-Edit": "models/Reference/Qwen-Lightning.jpg"
|
||||
"vladmandic--Qwen-Lightning-Edit": "models/Reference/Qwen-Lightning.jpg",
|
||||
"Wan-AI--Wan2.2-T2V-A14B-Diffusers": "models/Reference/Wan2.2-T2V-A14B.jpg",
|
||||
"Wan-AI--Wan2.1-T2V-14B-Diffusers": "models/Reference/Wan-AI--Wan2.1.jpg"
|
||||
}
|
||||
|
||||
@@ -383,6 +383,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
if p.scripts is not None and isinstance(p.scripts, scripts_manager.ScriptRunner):
|
||||
p.scripts.process(p)
|
||||
|
||||
shared.state.begin('Process')
|
||||
shared.state.batch_count = p.n_iter
|
||||
with devices.inference_context():
|
||||
t0 = time.time()
|
||||
@@ -494,4 +495,5 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
|
||||
if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
|
||||
devices.torch_gc(force=True, reason='final')
|
||||
shared.state.end()
|
||||
return results
|
||||
|
||||
@@ -23,19 +23,20 @@ def task_specific_kwargs(p, model):
|
||||
vae_scale_factor = sd_vae.get_vae_scale_factor(model)
|
||||
task_args = {}
|
||||
is_img2img_model = bool('Zero123' in model_cls)
|
||||
task_type = sd_models.get_diffusers_task(model)
|
||||
if len(getattr(p, 'init_images', [])) > 0:
|
||||
if isinstance(p.init_images[0], str):
|
||||
p.init_images = [helpers.decode_base64_to_image(i, quiet=True) for i in p.init_images]
|
||||
if isinstance(p.init_images[0], Image.Image):
|
||||
p.init_images = [i.convert('RGB') if i.mode != 'RGB' else i for i in p.init_images if i is not None]
|
||||
if (sd_models.get_diffusers_task(model) == sd_models.DiffusersTaskType.TEXT_2_IMAGE or len(getattr(p, 'init_images', [])) == 0) and not is_img2img_model and 'video' not in p.ops:
|
||||
if (task_type == sd_models.DiffusersTaskType.TEXT_2_IMAGE or len(getattr(p, 'init_images', [])) == 0) and not is_img2img_model and 'video' not in p.ops:
|
||||
p.ops.append('txt2img')
|
||||
if hasattr(p, 'width') and hasattr(p, 'height'):
|
||||
task_args = {
|
||||
'width': vae_scale_factor * math.ceil(p.width / vae_scale_factor),
|
||||
'height': vae_scale_factor * math.ceil(p.height / vae_scale_factor),
|
||||
}
|
||||
elif (sd_models.get_diffusers_task(model) == sd_models.DiffusersTaskType.IMAGE_2_IMAGE or is_img2img_model) and len(getattr(p, 'init_images', [])) > 0:
|
||||
elif (task_type == sd_models.DiffusersTaskType.IMAGE_2_IMAGE or is_img2img_model) and len(getattr(p, 'init_images', [])) > 0:
|
||||
if shared.sd_model_type == 'sdxl' and hasattr(model, 'register_to_config'):
|
||||
if model_cls in sd_models.i2i_pipes:
|
||||
pass
|
||||
@@ -69,7 +70,7 @@ def task_specific_kwargs(p, model):
|
||||
'height': p.height,
|
||||
'input_images': [p.init_images], # omnigen expects list-of-lists
|
||||
}
|
||||
elif sd_models.get_diffusers_task(model) == sd_models.DiffusersTaskType.INSTRUCT and len(getattr(p, 'init_images', [])) > 0:
|
||||
elif task_type == sd_models.DiffusersTaskType.INSTRUCT and len(getattr(p, 'init_images', [])) > 0:
|
||||
p.ops.append('instruct')
|
||||
task_args = {
|
||||
'width': vae_scale_factor * math.ceil(p.width / vae_scale_factor) if hasattr(p, 'width') else None,
|
||||
@@ -77,7 +78,7 @@ def task_specific_kwargs(p, model):
|
||||
'image': p.init_images,
|
||||
'strength': p.denoising_strength,
|
||||
}
|
||||
elif (sd_models.get_diffusers_task(model) == sd_models.DiffusersTaskType.INPAINTING or is_img2img_model) and len(getattr(p, 'init_images', [])) > 0:
|
||||
elif (task_type == sd_models.DiffusersTaskType.INPAINTING or is_img2img_model) and len(getattr(p, 'init_images', [])) > 0:
|
||||
if shared.sd_model_type == 'sdxl' and hasattr(model, 'register_to_config'):
|
||||
if model_cls in [sd_models.i2i_pipes]:
|
||||
pass
|
||||
|
||||
@@ -118,6 +118,7 @@ def process_post(p: processing.StableDiffusionProcessing):
|
||||
|
||||
|
||||
def process_base(p: processing.StableDiffusionProcessing):
|
||||
shared.state.begin('Base')
|
||||
txt2img = is_txt2img()
|
||||
use_refiner_start = is_refiner_enabled(p) and (not p.is_hr_pass)
|
||||
use_denoise_start = not txt2img and p.refiner_start > 0 and p.refiner_start < 1
|
||||
@@ -207,6 +208,7 @@ def process_base(p: processing.StableDiffusionProcessing):
|
||||
process_post(p)
|
||||
|
||||
shared.state.nextjob()
|
||||
shared.state.end()
|
||||
return output
|
||||
|
||||
|
||||
@@ -518,8 +520,8 @@ def process_diffusers(p: processing.StableDiffusionProcessing):
|
||||
p.init_images.append(p.init_images[-1])
|
||||
# pipeline type is set earlier in processing, but check for sanity
|
||||
is_control = getattr(p, 'is_control', False) is True
|
||||
has_images = len(getattr(p, 'init_images' ,[])) > 0
|
||||
if sd_models.get_diffusers_task(shared.sd_model) != sd_models.DiffusersTaskType.TEXT_2_IMAGE and not has_images and not is_control:
|
||||
has_images = len(getattr(p, 'init_images', [])) > 0
|
||||
if (sd_models.get_diffusers_task(shared.sd_model) != sd_models.DiffusersTaskType.TEXT_2_IMAGE) and (not has_images) and (not is_control):
|
||||
shared.sd_model = sd_models.set_diffuser_pipe(shared.sd_model, sd_models.DiffusersTaskType.TEXT_2_IMAGE) # reset pipeline
|
||||
if hasattr(shared.sd_model, 'unet') and hasattr(shared.sd_model.unet, 'config') and hasattr(shared.sd_model.unet.config, 'in_channels') and shared.sd_model.unet.config.in_channels == 9 and not is_control:
|
||||
shared.sd_model = sd_models.set_diffuser_pipe(shared.sd_model, sd_models.DiffusersTaskType.INPAINTING) # force pipeline
|
||||
@@ -541,6 +543,10 @@ def process_diffusers(p: processing.StableDiffusionProcessing):
|
||||
images, _index=shared.history.selected
|
||||
output = SimpleNamespace(images=images)
|
||||
|
||||
if len(output.images) == 0 and has_images:
|
||||
shared.log.debug('Processing: using input as base output')
|
||||
output.images = p.init_images
|
||||
|
||||
if shared.state.interrupted or shared.state.skipped:
|
||||
shared.sd_model = orig_pipeline
|
||||
return results
|
||||
|
||||
@@ -97,7 +97,6 @@ def generate_click(job_id: str, state: str, active_tab: str, *args):
|
||||
time.sleep(0.01)
|
||||
from modules.control.run import control_run
|
||||
debug(f'Control: tab="{active_tab}" job={job_id} args={args}')
|
||||
shared.state.begin('Generate')
|
||||
progress.add_task_to_queue(job_id)
|
||||
with call_queue.queue_lock:
|
||||
yield [None, None, None, None, 'Control: starting', '']
|
||||
@@ -140,7 +139,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
with gr.Row():
|
||||
input_type = gr.Radio(label="Control input type", choices=['Control only', 'Init image same as control', 'Separate init image'], value='Control only', type='index', elem_id='control_input_type')
|
||||
with gr.Row():
|
||||
denoising_strength = gr.Slider(minimum=0.01, maximum=1.0, step=0.01, label='Denoising strength', value=0.30, elem_id="control_input_denoising_strength")
|
||||
denoising_strength = gr.Slider(minimum=0.00, maximum=0.99, step=0.01, label='Denoising strength', value=0.30, elem_id="control_input_denoising_strength")
|
||||
|
||||
with gr.Accordion(open=False, label="Size", elem_id="control_size", elem_classes=["small-accordion"]):
|
||||
with gr.Tabs():
|
||||
|
||||
@@ -129,7 +129,7 @@ def create_ui():
|
||||
|
||||
with gr.Accordion(open=False, label="Denoise", elem_classes=["small-accordion"], elem_id="img2img_denoise_group"):
|
||||
with gr.Row():
|
||||
denoising_strength = gr.Slider(minimum=0.0, maximum=0.99, step=0.01, label='Denoising strength', value=0.30, elem_id="img2img_denoising_strength")
|
||||
denoising_strength = gr.Slider(minimum=0.00, maximum=0.99, step=0.01, label='Denoising strength', value=0.30, elem_id="img2img_denoising_strength")
|
||||
refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise start', value=0.0, elem_id="img2img_refiner_start")
|
||||
|
||||
vae_type, tiling, hidiffusion, cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, pag_scale, pag_adaptive, cfg_end = ui_sections.create_advanced_inputs('img2img')
|
||||
|
||||
@@ -81,7 +81,7 @@ def load_wan(checkpoint_info, diffusers_load_config={}):
|
||||
|
||||
load_args, _quant_args = model_quant.get_dit_args(diffusers_load_config, module='Model')
|
||||
boundary_ratio = shared.opts.model_wan_boundary if transformer_2 is not None else None
|
||||
shared.log.debug(f'Load model: type=WanAI model="{checkpoint_info.name}" repo="{repo_id}" offload={shared.opts.diffusers_offload_mode} dtype={devices.dtype} args={load_args} stage={shared.opts.model_wan_stage} boundary={boundary_ratio}')
|
||||
shared.log.debug(f'Load model: type=WanAI model="{checkpoint_info.name}" repo="{repo_id}" offload={shared.opts.diffusers_offload_mode} dtype={devices.dtype} args={load_args} stage="{shared.opts.model_wan_stage}" boundary={boundary_ratio}')
|
||||
|
||||
cls = diffusers.WanPipeline
|
||||
pipe = cls.from_pretrained(
|
||||
@@ -103,7 +103,7 @@ def load_wan(checkpoint_info, diffusers_load_config={}):
|
||||
del transformer_2
|
||||
|
||||
diffusers.pipelines.auto_pipeline.AUTO_TEXT2IMAGE_PIPELINES_MAPPING["wanai"] = diffusers.WanPipeline
|
||||
diffusers.pipelines.auto_pipeline.AUTO_IMAGE2IMAGE_PIPELINES_MAPPING["wanai"] = diffusers.WanImageToVideoPipeline
|
||||
# diffusers.pipelines.auto_pipeline.AUTO_IMAGE2IMAGE_PIPELINES_MAPPING["wanai"] = diffusers.WanImageToVideoPipeline
|
||||
|
||||
sd_hijack_te.init_hijack(pipe)
|
||||
sd_hijack_vae.init_hijack(pipe)
|
||||
|
||||
Reference in New Issue
Block a user