From 392d0305fcc1409fbcf3ea064d81ea516da01526 Mon Sep 17 00:00:00 2001 From: kijai <40791699+kijai@users.noreply.github.com> Date: Sun, 21 Dec 2025 15:06:14 +0200 Subject: [PATCH] Add portrait_cfg --- fantasyportrait/nodes.py | 4 +++- nodes_sampler.py | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/fantasyportrait/nodes.py b/fantasyportrait/nodes.py index 23d0312..befdc53 100644 --- a/fantasyportrait/nodes.py +++ b/fantasyportrait/nodes.py @@ -220,6 +220,7 @@ class WanVideoAddFantasyPortrait: "strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step": 0.01, "tooltip": "Strength of the portrait embedding"}), "start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01, "tooltip": "Start percentage of the embedding application"}), "end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01, "tooltip": "End percentage of the embedding application"}), + "portrait_cfg": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 20.0, "step": 0.01, "tooltip": "CFG scale for the portrait embedding"}), } } @@ -228,12 +229,13 @@ class WanVideoAddFantasyPortrait: FUNCTION = "add" CATEGORY = "WanVideoWrapper" - def add(self, embeds, portrait_embeds, strength, start_percent=0.0, end_percent=1.0): + def add(self, embeds, portrait_embeds, strength, start_percent=0.0, end_percent=1.0, portrait_cfg=1.0): new_entry = { "adapter_proj": portrait_embeds, "strength": strength, "start_percent": start_percent, "end_percent": end_percent, + "cfg_scale": portrait_cfg, } updated = dict(embeds) diff --git a/nodes_sampler.py b/nodes_sampler.py index cdbda4c..2bebb93 100644 --- a/nodes_sampler.py +++ b/nodes_sampler.py @@ -659,12 +659,10 @@ class WanVideoSampler: fantasy_portrait_embeds = image_embeds.get("portrait_embeds", None) if fantasy_portrait_embeds is not None: log.info("Using FantasyPortrait embeddings") - fantasy_portrait_input = { - "adapter_proj": fantasy_portrait_embeds.get("adapter_proj", None), - "strength": fantasy_portrait_embeds.get("strength", 1.0), - "start_percent": fantasy_portrait_embeds.get("start_percent", 0.0), - "end_percent": fantasy_portrait_embeds.get("end_percent", 1.0), - } + fantasy_portrait_input = fantasy_portrait_embeds.copy() + portrait_cfg = fantasy_portrait_input.get("cfg_scale", 1.0) + if not isinstance(portrait_cfg, list): + portrait_cfg = [portrait_cfg] * (steps + 1) # MiniMax Remover minimax_latents = minimax_mask_latents = None @@ -1577,6 +1575,14 @@ class WanVideoSampler: if math.isclose(cfg_scale, 1.0): if use_fresca: noise_pred_cond = fourier_filter(noise_pred_cond, fresca_scale_low, fresca_scale_high, fresca_freq_cutoff) + if fantasy_portrait_input is not None and not math.isclose(portrait_cfg[idx], 1.0): + print("Applying Fantasy Portrait CFG...") + base_params["fantasy_portrait_input"] = None + noise_pred_no_portrait, noise_pred_ovi, cache_state_uncond = transformer(context=positive_embeds, pred_id=cache_state[0] if cache_state else None, + vace_data=vace_data, attn_cond=attn_cond, **base_params) + noise_pred_no_portrait = noise_pred_no_portrait[0] + return noise_pred_no_portrait + portrait_cfg[idx] * (noise_pred_cond - noise_pred_no_portrait), noise_pred_ovi, [cache_state_cond, cache_state_uncond] + else: return noise_pred_cond, noise_pred_ovi, [cache_state_cond] #unconditional (negative) pass