diff --git a/CHANGELOG.md b/CHANGELOG.md
index c7d062f7a..6d14b8d4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,13 @@
## Update for 2025-07-30
+- **Feature**
+ - Wan select which stage to run: *first/second/both* with configurable *boundary ration* when running both stages
+ in settings -> model options
+- **UI**
+ - modernui checkbox/radio styling
- **Fixes**
+ - fix Wan2.2 5B I2V workflow
- fix inpaint image metadata
- fix processing image save loop
- fix api progress reporting endpoint
diff --git a/extensions-builtin/sdnext-modernui b/extensions-builtin/sdnext-modernui
index 06c9747d2..9741e151b 160000
--- a/extensions-builtin/sdnext-modernui
+++ b/extensions-builtin/sdnext-modernui
@@ -1 +1 @@
-Subproject commit 06c9747d29a2d7271f9265199f1557a1722cb108
+Subproject commit 9741e151b01dda2d2697c8ca8a369e50482e976e
diff --git a/installer.py b/installer.py
index d3a2eacf0..5bf112e5c 100644
--- a/installer.py
+++ b/installer.py
@@ -593,7 +593,7 @@ def check_diffusers():
t_start = time.time()
if args.skip_all or args.skip_git:
return
- sha = '56d438727036b0918b30bbe3110c5fe1634ed19d' # diffusers commit hash
+ sha = 'c052791b5fe29ce8a308bf63dda97aa205b729be' # 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 -1)
cur = opts.get('diffusers_version', '') if minor > -1 else ''
diff --git a/modules/interrogate/interrogate.py b/modules/interrogate/interrogate.py
index ce3f75193..7f7befcf2 100644
--- a/modules/interrogate/interrogate.py
+++ b/modules/interrogate/interrogate.py
@@ -9,6 +9,7 @@ def interrogate(image):
if isinstance(image, dict) and 'name' in image:
image = Image.open(image['name'])
if image is None:
+ shared.log.error('Interrogate: no image provided')
return ''
t0 = time.time()
if shared.opts.interrogate_default_type == 'OpenCLiP':
diff --git a/modules/shared.py b/modules/shared.py
index 60bc59da1..2769ff361 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -200,7 +200,8 @@ options_templates.update(options_section(('model_options', "Models Options"), {
"model_h1_sep": OptionInfo("
HiDream
", "", gr.HTML),
"model_h1_llama_repo": OptionInfo("Default", "LLama repo", gr.Textbox),
"model_wan_sep": OptionInfo("WanAI
", "", gr.HTML),
- "model_wan_disable_t2": OptionInfo(True, "Disable second stage"),
+ "model_wan_stage": OptionInfo("first", "Processing stage", gr.Radio, {"choices": ['first', 'second', 'both'] }),
+ "model_wan_boundary": OptionInfo(0.85, "Stage boundary ratio", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05 }),
}))
options_templates.update(options_section(('vae_encoder', "Variational Auto Encoder"), {
diff --git a/pipelines/model_wanai.py b/pipelines/model_wanai.py
index ba815c2f0..7400bdd10 100644
--- a/pipelines/model_wanai.py
+++ b/pipelines/model_wanai.py
@@ -8,11 +8,6 @@ def load_transformer(repo_id, diffusers_load_config={}, subfolder='transformer')
load_args, quant_args = model_quant.get_dit_args(diffusers_load_config, module='Model', device_map=True)
fn = None
- if subfolder == 'transformer_2' and 'a14b' not in repo_id.lower():
- return None
- if subfolder == 'transformer_2' and shared.opts.model_wan_disable_t2:
- return None
-
if shared.opts.sd_unet is not None and shared.opts.sd_unet != 'Default':
from modules import sd_unet
if shared.opts.sd_unet not in list(sd_unet.unet_dict):
@@ -63,13 +58,28 @@ def load_wan(checkpoint_info, diffusers_load_config={}):
repo_id = sd_models.path_to_repo(checkpoint_info)
sd_models.hf_auth_check(checkpoint_info)
- transformer = load_transformer(repo_id, diffusers_load_config, 'transformer')
- transformer_2 = load_transformer(repo_id, diffusers_load_config, 'transformer_2')
+ if 'a14b' in repo_id.lower():
+ if shared.opts.model_wan_stage == 'first':
+ transformer = load_transformer(repo_id, diffusers_load_config, 'transformer')
+ transformer_2 = None
+ elif shared.opts.model_wan_stage == 'second':
+ transformer = load_transformer(repo_id, diffusers_load_config, 'transformer_2')
+ transformer_2 = None
+ elif shared.opts.model_wan_stage == 'both':
+ transformer = load_transformer(repo_id, diffusers_load_config, 'transformer')
+ transformer_2 = load_transformer(repo_id, diffusers_load_config, 'transformer_2')
+ else:
+ shared.log.error(f'Load model: type=WanAI stage="{shared.opts.model_wan_stage}" unsupported')
+ return None
+ else:
+ transformer = load_transformer(repo_id, diffusers_load_config, 'transformer')
+ transformer_2 = None
+
text_encoder = load_text_encoder(repo_id, diffusers_load_config)
load_args, _quant_args = model_quant.get_dit_args(diffusers_load_config, module='Model')
- boundary_ratio = 0.8 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} boundary={boundary_ratio}')
+ 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}')
cls = diffusers.WanPipeline
pipe = cls.from_pretrained(
@@ -88,6 +98,7 @@ def load_wan(checkpoint_info, diffusers_load_config={}):
del text_encoder
del transformer
+ del transformer_2
sd_hijack_te.init_hijack(pipe)
from modules.video_models import video_vae