DZRobo
commited on
Bugfixes (#11)
Browse files* Add MagicLatentAdapter node
Introduces MagicLatentAdapter for generating or adapting latents to match model expectations, including support for 5D (NCDHW) layouts and experimental FLUX/Qwen models. Adds mask alignment utilities to CADE nodes for robust mask blending, improves Gaussian blur to support 5D tensors, and updates preset defaults for improved results. Documentation and workflow updated to reflect new node and features.
* Bugfixes
1. Adjust edge mask gain logic and preset parameters. Fix depth path for CF (hard).
2. Memory leaking fix.
3. Quality improvement at all steps (Easy and SuperSimple)
- mod/easy/mg_cade25_easy.py +45 -18
- mod/hard/mg_cade25.py +52 -21
- mod/hard/mg_controlfusion.py +57 -0
- mod/mg_combinode.py +2 -2
- pressets/mg_cade25.cfg +3 -3
- pressets/mg_controlfusion.cfg +10 -10
mod/easy/mg_cade25_easy.py
CHANGED
|
@@ -1264,6 +1264,21 @@ def _wrap_model_with_guidance(model, guidance_mode: str, rescale_multiplier: flo
|
|
| 1264 |
# Spectral switching/adaptive low state
|
| 1265 |
spec_state = {"ema": None, "mode": "CFGZeroFD"}
|
| 1266 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1267 |
def cfg_func(args):
|
| 1268 |
cond = args["cond"]
|
| 1269 |
uncond = args["uncond"]
|
|
@@ -1748,11 +1763,8 @@ def _build_cf_edge_mask_from_step(image_bhwc: torch.Tensor, preset_step: str) ->
|
|
| 1748 |
ed = (ed * g).clamp(0,1)
|
| 1749 |
except Exception:
|
| 1750 |
pass
|
| 1751 |
-
# Apply opacity + edge strength
|
| 1752 |
-
total_gain = max(0.0, float(edge_alpha)) * max(0.0, float(edge_strength_mul))
|
| 1753 |
-
# Keep at least alpha if blend_factor is set to 0 in presets
|
| 1754 |
-
if total_gain == 0.0:
|
| 1755 |
-
total_gain = max(0.0, float(edge_alpha))
|
| 1756 |
ed = (ed * total_gain).clamp(0,1)
|
| 1757 |
# Return BHWC single-channel
|
| 1758 |
return ed.unsqueeze(0).unsqueeze(-1)
|
|
@@ -2257,6 +2269,19 @@ class ComfyAdaptiveDetailEnhancer25:
|
|
| 2257 |
clipseg_enable = False
|
| 2258 |
# Depth gate cache for micro-detail injection (reuse per resolution)
|
| 2259 |
depth_gate_cache = {"size": None, "mask": None}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2260 |
# check once more right before the loop starts
|
| 2261 |
model_management.throw_exception_if_processing_interrupted()
|
| 2262 |
for i in range(iterations):
|
|
@@ -2265,6 +2290,13 @@ class ComfyAdaptiveDetailEnhancer25:
|
|
| 2265 |
if i % 2 == 0:
|
| 2266 |
clear_gpu_and_ram_cache()
|
| 2267 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2268 |
prev_samples = current_latent["samples"].clone().detach()
|
| 2269 |
|
| 2270 |
iter_seed = seed + i * 7777
|
|
@@ -2376,19 +2408,8 @@ class ComfyAdaptiveDetailEnhancer25:
|
|
| 2376 |
except Exception:
|
| 2377 |
pass
|
| 2378 |
|
| 2379 |
-
#
|
| 2380 |
-
sampler_model =
|
| 2381 |
-
model, guidance_mode, rescale_multiplier, momentum_beta, cfg_curve, perp_damp,
|
| 2382 |
-
use_zero_init=bool(use_zero_init), zero_init_steps=int(zero_init_steps),
|
| 2383 |
-
fdg_low=float(fdg_low), fdg_high=float(fdg_high), fdg_sigma=float(fdg_sigma),
|
| 2384 |
-
midfreq_enable=bool(midfreq_enable), midfreq_gain=float(midfreq_gain), midfreq_sigma_lo=float(midfreq_sigma_lo), midfreq_sigma_hi=float(midfreq_sigma_hi),
|
| 2385 |
-
ze_zero_steps=int(ze_res_zero_steps),
|
| 2386 |
-
ze_adaptive=bool(ze_adaptive), ze_r_switch_hi=float(ze_r_switch_hi), ze_r_switch_lo=float(ze_r_switch_lo),
|
| 2387 |
-
fdg_low_adaptive=bool(fdg_low_adaptive), fdg_low_min=float(fdg_low_min), fdg_low_max=float(fdg_low_max), fdg_ema_beta=float(fdg_ema_beta),
|
| 2388 |
-
use_local_mask=bool(onnx_local_guidance), mask_inside=float(onnx_mask_inside), mask_outside=float(onnx_mask_outside),
|
| 2389 |
-
mahiro_plus_enable=bool(muse_blend), mahiro_plus_strength=float(muse_blend_strength),
|
| 2390 |
-
eps_scale_enable=bool(eps_scale_enable), eps_scale=float(eps_scale)
|
| 2391 |
-
)
|
| 2392 |
|
| 2393 |
# Local best-of-2 in ROI (hands/face), only on early iteration to limit overhead
|
| 2394 |
try:
|
|
@@ -2755,6 +2776,12 @@ class ComfyAdaptiveDetailEnhancer25:
|
|
| 2755 |
sa_patch.enable_crossattention_nag_patch(False)
|
| 2756 |
except Exception:
|
| 2757 |
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2758 |
# Disable KV pruning as well (avoid leaking state)
|
| 2759 |
try:
|
| 2760 |
if hasattr(sa_patch, "set_kv_prune"):
|
|
|
|
| 1264 |
# Spectral switching/adaptive low state
|
| 1265 |
spec_state = {"ema": None, "mode": "CFGZeroFD"}
|
| 1266 |
|
| 1267 |
+
# External reset hook to emulate fresh state per iteration without re-cloning the model
|
| 1268 |
+
def _reset_state():
|
| 1269 |
+
try:
|
| 1270 |
+
prev_delta["t"] = None
|
| 1271 |
+
sigma_seen["max"] = None
|
| 1272 |
+
sigma_seen["min"] = None
|
| 1273 |
+
spec_state["ema"] = None
|
| 1274 |
+
spec_state["mode"] = "CFGZeroFD"
|
| 1275 |
+
except Exception:
|
| 1276 |
+
pass
|
| 1277 |
+
try:
|
| 1278 |
+
setattr(m, "mg_guidance_reset", _reset_state)
|
| 1279 |
+
except Exception:
|
| 1280 |
+
pass
|
| 1281 |
+
|
| 1282 |
def cfg_func(args):
|
| 1283 |
cond = args["cond"]
|
| 1284 |
uncond = args["uncond"]
|
|
|
|
| 1763 |
ed = (ed * g).clamp(0,1)
|
| 1764 |
except Exception:
|
| 1765 |
pass
|
| 1766 |
+
# Apply opacity + edge strength (keep blend_factor only for ControlNet stage, not for mask amplitude)
|
| 1767 |
+
total_gain = max(0.0, float(edge_alpha)) * max(0.0, float(edge_strength_mul))
|
|
|
|
|
|
|
|
|
|
| 1768 |
ed = (ed * total_gain).clamp(0,1)
|
| 1769 |
# Return BHWC single-channel
|
| 1770 |
return ed.unsqueeze(0).unsqueeze(-1)
|
|
|
|
| 2269 |
clipseg_enable = False
|
| 2270 |
# Depth gate cache for micro-detail injection (reuse per resolution)
|
| 2271 |
depth_gate_cache = {"size": None, "mask": None}
|
| 2272 |
+
# Prepare guided sampler once per node run to avoid cloning model each iteration
|
| 2273 |
+
sampler_model = _wrap_model_with_guidance(
|
| 2274 |
+
model, guidance_mode, rescale_multiplier, momentum_beta, cfg_curve, perp_damp,
|
| 2275 |
+
use_zero_init=bool(use_zero_init), zero_init_steps=int(zero_init_steps),
|
| 2276 |
+
fdg_low=float(fdg_low), fdg_high=float(fdg_high), fdg_sigma=float(fdg_sigma),
|
| 2277 |
+
midfreq_enable=bool(midfreq_enable), midfreq_gain=float(midfreq_gain), midfreq_sigma_lo=float(midfreq_sigma_lo), midfreq_sigma_hi=float(midfreq_sigma_hi),
|
| 2278 |
+
ze_zero_steps=int(ze_res_zero_steps),
|
| 2279 |
+
ze_adaptive=bool(ze_adaptive), ze_r_switch_hi=float(ze_r_switch_hi), ze_r_switch_lo=float(ze_r_switch_lo),
|
| 2280 |
+
fdg_low_adaptive=bool(fdg_low_adaptive), fdg_low_min=float(fdg_low_min), fdg_low_max=float(fdg_low_max), fdg_ema_beta=float(fdg_ema_beta),
|
| 2281 |
+
use_local_mask=bool(onnx_local_guidance), mask_inside=float(onnx_mask_inside), mask_outside=float(onnx_mask_outside),
|
| 2282 |
+
mahiro_plus_enable=bool(muse_blend), mahiro_plus_strength=float(muse_blend_strength),
|
| 2283 |
+
eps_scale_enable=bool(eps_scale_enable), eps_scale=float(eps_scale)
|
| 2284 |
+
)
|
| 2285 |
# check once more right before the loop starts
|
| 2286 |
model_management.throw_exception_if_processing_interrupted()
|
| 2287 |
for i in range(iterations):
|
|
|
|
| 2290 |
if i % 2 == 0:
|
| 2291 |
clear_gpu_and_ram_cache()
|
| 2292 |
|
| 2293 |
+
# Reset guidance internal state so each iteration starts clean
|
| 2294 |
+
try:
|
| 2295 |
+
if hasattr(sampler_model, "mg_guidance_reset"):
|
| 2296 |
+
sampler_model.mg_guidance_reset()
|
| 2297 |
+
except Exception:
|
| 2298 |
+
pass
|
| 2299 |
+
|
| 2300 |
prev_samples = current_latent["samples"].clone().detach()
|
| 2301 |
|
| 2302 |
iter_seed = seed + i * 7777
|
|
|
|
| 2408 |
except Exception:
|
| 2409 |
pass
|
| 2410 |
|
| 2411 |
+
# Sampler model prepared once above; reused across iterations (no-op here)
|
| 2412 |
+
sampler_model = sampler_model
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2413 |
|
| 2414 |
# Local best-of-2 in ROI (hands/face), only on early iteration to limit overhead
|
| 2415 |
try:
|
|
|
|
| 2776 |
sa_patch.enable_crossattention_nag_patch(False)
|
| 2777 |
except Exception:
|
| 2778 |
pass
|
| 2779 |
+
# Turn off attention-entropy probe (AQClip Attn-mode) to avoid holding last maps
|
| 2780 |
+
try:
|
| 2781 |
+
if hasattr(sa_patch, "enable_attention_entropy_capture"):
|
| 2782 |
+
sa_patch.enable_attention_entropy_capture(False)
|
| 2783 |
+
except Exception:
|
| 2784 |
+
pass
|
| 2785 |
# Disable KV pruning as well (avoid leaking state)
|
| 2786 |
try:
|
| 2787 |
if hasattr(sa_patch, "set_kv_prune"):
|
mod/hard/mg_cade25.py
CHANGED
|
@@ -150,7 +150,7 @@ def _clipseg_build_mask(image_bhwc: torch.Tensor,
|
|
| 150 |
cur = _encode_clip_image(image_bhwc, clip_vision, target_res=224)
|
| 151 |
dist = _clip_cosine_distance(cur, ref_embed)
|
| 152 |
if dist > float(ref_threshold):
|
| 153 |
-
# up to +50% gain if
|
| 154 |
gate = 1.0 + min(0.5, (dist - float(ref_threshold)) * 4.0)
|
| 155 |
m = m * gate
|
| 156 |
except Exception:
|
|
@@ -919,6 +919,21 @@ def _wrap_model_with_guidance(model, guidance_mode: str, rescale_multiplier: flo
|
|
| 919 |
# Spectral switching/adaptive low state
|
| 920 |
spec_state = {"ema": None, "mode": "CFGZeroFD"}
|
| 921 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 922 |
def cfg_func(args):
|
| 923 |
cond = args["cond"]
|
| 924 |
uncond = args["uncond"]
|
|
@@ -1580,14 +1595,14 @@ class ComfyAdaptiveDetailEnhancer25:
|
|
| 1580 |
mask_last = pre_mask
|
| 1581 |
om = pre_mask.movedim(-1, 1)
|
| 1582 |
pre_area = float(om.mean().item())
|
| 1583 |
-
# One-time gentle damping from area
|
| 1584 |
-
try:
|
| 1585 |
-
|
| 1586 |
-
|
| 1587 |
-
|
| 1588 |
-
|
| 1589 |
-
except Exception:
|
| 1590 |
-
|
| 1591 |
# Compact status
|
| 1592 |
try:
|
| 1593 |
clipseg_status = "on" if bool(clipseg_enable) and isinstance(clipseg_text, str) and clipseg_text.strip() != "" else "off"
|
|
@@ -1600,6 +1615,19 @@ class ComfyAdaptiveDetailEnhancer25:
|
|
| 1600 |
clipseg_enable = False
|
| 1601 |
# Depth gate cache for micro-detail injection (reuse per resolution)
|
| 1602 |
depth_gate_cache = {"size": None, "mask": None}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1603 |
# early interruption check before starting the loop
|
| 1604 |
try:
|
| 1605 |
model_management.throw_exception_if_processing_interrupted()
|
|
@@ -1613,6 +1641,13 @@ class ComfyAdaptiveDetailEnhancer25:
|
|
| 1613 |
if i % 2 == 0:
|
| 1614 |
clear_gpu_and_ram_cache()
|
| 1615 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1616 |
prev_samples = current_latent["samples"].clone().detach()
|
| 1617 |
|
| 1618 |
iter_seed = seed + i * 7777
|
|
@@ -1661,18 +1696,8 @@ class ComfyAdaptiveDetailEnhancer25:
|
|
| 1661 |
except Exception:
|
| 1662 |
pass
|
| 1663 |
|
| 1664 |
-
#
|
| 1665 |
-
sampler_model =
|
| 1666 |
-
model, guidance_mode, rescale_multiplier, momentum_beta, cfg_curve, perp_damp,
|
| 1667 |
-
use_zero_init=bool(use_zero_init), zero_init_steps=int(zero_init_steps),
|
| 1668 |
-
fdg_low=float(fdg_low), fdg_high=float(fdg_high), fdg_sigma=float(fdg_sigma),
|
| 1669 |
-
midfreq_enable=bool(False), midfreq_gain=float(0.0), midfreq_sigma_lo=float(0.8), midfreq_sigma_hi=float(2.0),
|
| 1670 |
-
ze_zero_steps=int(ze_res_zero_steps),
|
| 1671 |
-
ze_adaptive=bool(ze_adaptive), ze_r_switch_hi=float(ze_r_switch_hi), ze_r_switch_lo=float(ze_r_switch_lo),
|
| 1672 |
-
fdg_low_adaptive=bool(fdg_low_adaptive), fdg_low_min=float(fdg_low_min), fdg_low_max=float(fdg_low_max), fdg_ema_beta=float(fdg_ema_beta),
|
| 1673 |
-
mahiro_plus_enable=bool(muse_blend), mahiro_plus_strength=float(muse_blend_strength),
|
| 1674 |
-
eps_scale_enable=bool(eps_scale_enable), eps_scale=float(eps_scale)
|
| 1675 |
-
)
|
| 1676 |
|
| 1677 |
if str(scheduler) == "MGHybrid":
|
| 1678 |
try:
|
|
@@ -1921,6 +1946,12 @@ class ComfyAdaptiveDetailEnhancer25:
|
|
| 1921 |
sa_patch.enable_crossattention_nag_patch(False)
|
| 1922 |
except Exception:
|
| 1923 |
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1924 |
try:
|
| 1925 |
sa_patch.CURRENT_PV_ACCUM = prev_accum
|
| 1926 |
except Exception:
|
|
|
|
| 150 |
cur = _encode_clip_image(image_bhwc, clip_vision, target_res=224)
|
| 151 |
dist = _clip_cosine_distance(cur, ref_embed)
|
| 152 |
if dist > float(ref_threshold):
|
| 153 |
+
# up to +50% gain if distance exceeds the reference threshold
|
| 154 |
gate = 1.0 + min(0.5, (dist - float(ref_threshold)) * 4.0)
|
| 155 |
m = m * gate
|
| 156 |
except Exception:
|
|
|
|
| 919 |
# Spectral switching/adaptive low state
|
| 920 |
spec_state = {"ema": None, "mode": "CFGZeroFD"}
|
| 921 |
|
| 922 |
+
# External reset hook to emulate fresh state per iteration without re-cloning the model
|
| 923 |
+
def _mg_guidance_reset():
|
| 924 |
+
try:
|
| 925 |
+
prev_delta["t"] = None
|
| 926 |
+
sigma_seen["max"] = None
|
| 927 |
+
sigma_seen["min"] = None
|
| 928 |
+
spec_state["ema"] = None
|
| 929 |
+
spec_state["mode"] = "CFGZeroFD"
|
| 930 |
+
except Exception:
|
| 931 |
+
pass
|
| 932 |
+
try:
|
| 933 |
+
setattr(m, "mg_guidance_reset", _mg_guidance_reset)
|
| 934 |
+
except Exception:
|
| 935 |
+
pass
|
| 936 |
+
|
| 937 |
def cfg_func(args):
|
| 938 |
cond = args["cond"]
|
| 939 |
uncond = args["uncond"]
|
|
|
|
| 1595 |
mask_last = pre_mask
|
| 1596 |
om = pre_mask.movedim(-1, 1)
|
| 1597 |
pre_area = float(om.mean().item())
|
| 1598 |
+
# One-time gentle damping from area (disabled to preserve outline precision)
|
| 1599 |
+
# try:
|
| 1600 |
+
# if pre_area > 0.005:
|
| 1601 |
+
# damp = 1.0 - min(0.10, 0.02 + pre_area * 0.08)
|
| 1602 |
+
# current_denoise = max(0.10, current_denoise * damp)
|
| 1603 |
+
# current_cfg = max(1.0, current_cfg * (1.0 - 0.005))
|
| 1604 |
+
# except Exception:
|
| 1605 |
+
# pass
|
| 1606 |
# Compact status
|
| 1607 |
try:
|
| 1608 |
clipseg_status = "on" if bool(clipseg_enable) and isinstance(clipseg_text, str) and clipseg_text.strip() != "" else "off"
|
|
|
|
| 1615 |
clipseg_enable = False
|
| 1616 |
# Depth gate cache for micro-detail injection (reuse per resolution)
|
| 1617 |
depth_gate_cache = {"size": None, "mask": None}
|
| 1618 |
+
# Prepare guided sampler once per node run to avoid cloning model each iteration
|
| 1619 |
+
sampler_model = _wrap_model_with_guidance(
|
| 1620 |
+
model, guidance_mode, rescale_multiplier, momentum_beta, cfg_curve, perp_damp,
|
| 1621 |
+
use_zero_init=bool(use_zero_init), zero_init_steps=int(zero_init_steps),
|
| 1622 |
+
fdg_low=float(fdg_low), fdg_high=float(fdg_high), fdg_sigma=float(fdg_sigma),
|
| 1623 |
+
midfreq_enable=bool(False), midfreq_gain=float(0.0), midfreq_sigma_lo=float(0.8), midfreq_sigma_hi=float(2.0),
|
| 1624 |
+
ze_zero_steps=int(ze_res_zero_steps),
|
| 1625 |
+
ze_adaptive=bool(ze_adaptive), ze_r_switch_hi=float(ze_r_switch_hi), ze_r_switch_lo=float(ze_r_switch_lo),
|
| 1626 |
+
fdg_low_adaptive=bool(fdg_low_adaptive), fdg_low_min=float(fdg_low_min), fdg_low_max=float(fdg_low_max), fdg_ema_beta=float(fdg_ema_beta),
|
| 1627 |
+
use_local_mask=False, mask_inside=1.0, mask_outside=1.0,
|
| 1628 |
+
mahiro_plus_enable=bool(muse_blend), mahiro_plus_strength=float(muse_blend_strength),
|
| 1629 |
+
eps_scale_enable=bool(eps_scale_enable), eps_scale=float(eps_scale)
|
| 1630 |
+
)
|
| 1631 |
# early interruption check before starting the loop
|
| 1632 |
try:
|
| 1633 |
model_management.throw_exception_if_processing_interrupted()
|
|
|
|
| 1641 |
if i % 2 == 0:
|
| 1642 |
clear_gpu_and_ram_cache()
|
| 1643 |
|
| 1644 |
+
# Reset guidance internal state so each iteration starts clean
|
| 1645 |
+
try:
|
| 1646 |
+
if hasattr(sampler_model, "mg_guidance_reset"):
|
| 1647 |
+
sampler_model.mg_guidance_reset()
|
| 1648 |
+
except Exception:
|
| 1649 |
+
pass
|
| 1650 |
+
|
| 1651 |
prev_samples = current_latent["samples"].clone().detach()
|
| 1652 |
|
| 1653 |
iter_seed = seed + i * 7777
|
|
|
|
| 1696 |
except Exception:
|
| 1697 |
pass
|
| 1698 |
|
| 1699 |
+
# Sampler model prepared once above; reuse it here (no-op assignment)
|
| 1700 |
+
sampler_model = sampler_model
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1701 |
|
| 1702 |
if str(scheduler) == "MGHybrid":
|
| 1703 |
try:
|
|
|
|
| 1946 |
sa_patch.enable_crossattention_nag_patch(False)
|
| 1947 |
except Exception:
|
| 1948 |
pass
|
| 1949 |
+
# Turn off attention-entropy probe to avoid holding last maps
|
| 1950 |
+
try:
|
| 1951 |
+
if hasattr(sa_patch, "enable_attention_entropy_capture"):
|
| 1952 |
+
sa_patch.enable_attention_entropy_capture(False)
|
| 1953 |
+
except Exception:
|
| 1954 |
+
pass
|
| 1955 |
try:
|
| 1956 |
sa_patch.CURRENT_PV_ACCUM = prev_accum
|
| 1957 |
except Exception:
|
mod/hard/mg_controlfusion.py
CHANGED
|
@@ -30,6 +30,47 @@ def _try_init_depth_anything(model_path: str):
|
|
| 30 |
if _DEPTH_INIT:
|
| 31 |
return _DEPTH_MODEL is not None
|
| 32 |
_DEPTH_INIT = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
# Prefer our vendored implementation first
|
| 34 |
try:
|
| 35 |
from ...vendor.depth_anything_v2.dpt import DepthAnythingV2 # type: ignore
|
|
@@ -127,6 +168,22 @@ def _build_depth_map(image_bhwc: torch.Tensor, res: int, model_path: str, hires_
|
|
| 127 |
d = torch.from_numpy(d)[None, None] # 1,1,h,w
|
| 128 |
d = F.interpolate(d, size=(H, W), mode='bilinear', align_corners=False)
|
| 129 |
d = d[0, 0].to(device=dev, dtype=dtype)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
d = d.clamp(0, 1)
|
| 131 |
return d
|
| 132 |
except Exception:
|
|
|
|
| 30 |
if _DEPTH_INIT:
|
| 31 |
return _DEPTH_MODEL is not None
|
| 32 |
_DEPTH_INIT = True
|
| 33 |
+
# Resolve model path: allow 'auto' or directory and prefer vitl>vitb>vits>vitg
|
| 34 |
+
try:
|
| 35 |
+
def _prefer_order(paths):
|
| 36 |
+
order = ["vitl", "vitb", "vits", "vitg"]
|
| 37 |
+
scored = []
|
| 38 |
+
for p in paths:
|
| 39 |
+
name = os.path.basename(p).lower()
|
| 40 |
+
score = 100
|
| 41 |
+
for i, tag in enumerate(order):
|
| 42 |
+
if tag in name:
|
| 43 |
+
score = i
|
| 44 |
+
break
|
| 45 |
+
scored.append((score, p))
|
| 46 |
+
scored.sort(key=lambda x: x[0])
|
| 47 |
+
return [p for _, p in scored]
|
| 48 |
+
|
| 49 |
+
def _resolve_path(mp: str) -> str:
|
| 50 |
+
if isinstance(mp, str) and mp.strip().lower() == "auto":
|
| 51 |
+
mp = ""
|
| 52 |
+
if mp and os.path.isfile(mp):
|
| 53 |
+
return mp
|
| 54 |
+
search_dirs = []
|
| 55 |
+
if mp and os.path.isdir(mp):
|
| 56 |
+
search_dirs.append(mp)
|
| 57 |
+
base_dir = os.path.join(os.path.dirname(__file__), '..', 'depth-anything')
|
| 58 |
+
search_dirs.append(base_dir)
|
| 59 |
+
cand = []
|
| 60 |
+
for d in search_dirs:
|
| 61 |
+
try:
|
| 62 |
+
for fn in os.listdir(d):
|
| 63 |
+
if fn.lower().endswith('.pth') and 'depth_anything_v2' in fn.lower():
|
| 64 |
+
cand.append(os.path.join(d, fn))
|
| 65 |
+
except Exception:
|
| 66 |
+
pass
|
| 67 |
+
if cand:
|
| 68 |
+
return _prefer_order(cand)[0]
|
| 69 |
+
return mp
|
| 70 |
+
|
| 71 |
+
model_path = _resolve_path(model_path)
|
| 72 |
+
except Exception:
|
| 73 |
+
pass
|
| 74 |
# Prefer our vendored implementation first
|
| 75 |
try:
|
| 76 |
from ...vendor.depth_anything_v2.dpt import DepthAnythingV2 # type: ignore
|
|
|
|
| 168 |
d = torch.from_numpy(d)[None, None] # 1,1,h,w
|
| 169 |
d = F.interpolate(d, size=(H, W), mode='bilinear', align_corners=False)
|
| 170 |
d = d[0, 0].to(device=dev, dtype=dtype)
|
| 171 |
+
# Heuristic de-banding: sometimes upstream returns column-wise banding
|
| 172 |
+
# Detect when column variance >> row variance, indicating vertical stripes
|
| 173 |
+
try:
|
| 174 |
+
with torch.no_grad():
|
| 175 |
+
dr = d.clamp(0,1)
|
| 176 |
+
# compute per-axis variance summaries in a small, cheap way
|
| 177 |
+
vcol = torch.var(dr, dim=0).mean()
|
| 178 |
+
vrow = torch.var(dr, dim=1).mean()
|
| 179 |
+
if torch.isfinite(vcol) and torch.isfinite(vrow) and (vcol > 8.0 * (vrow + 1e-6)):
|
| 180 |
+
# Apply mild horizontal smoothing only (reduce vertical banding)
|
| 181 |
+
k = max(3, int(round(min(W, 21) // 2 * 2 + 1))) # odd kernel up to ~21
|
| 182 |
+
dr2 = F.avg_pool2d(dr.unsqueeze(0).unsqueeze(0), kernel_size=(1, k), stride=1, padding=(0, k//2))[0,0]
|
| 183 |
+
# preserve global contrast by gentle blend
|
| 184 |
+
d = (0.6 * dr + 0.4 * dr2).clamp(0,1)
|
| 185 |
+
except Exception:
|
| 186 |
+
pass
|
| 187 |
d = d.clamp(0, 1)
|
| 188 |
return d
|
| 189 |
except Exception:
|
mod/mg_combinode.py
CHANGED
|
@@ -294,7 +294,7 @@ class MagicNodesCombiNode:
|
|
| 294 |
|
| 295 |
# single clear at start is enough; avoid double-clearing here
|
| 296 |
|
| 297 |
-
#
|
| 298 |
loras = [
|
| 299 |
(use_lora_1, lora_1, strength_model_1, strength_clip_1),
|
| 300 |
(use_lora_2, lora_2, strength_model_2, strength_clip_2),
|
|
@@ -345,7 +345,7 @@ class MagicNodesCombiNode:
|
|
| 345 |
except Exception:
|
| 346 |
pass
|
| 347 |
|
| 348 |
-
# Embeddings Positive
|
| 349 |
# Standard pipeline: optionally use a shared CLIP after clip_layer + CLIP-LoRA
|
| 350 |
# Select CLIP source for encoding: pristine when standard pipeline is enabled
|
| 351 |
src_clip = clip_clean if bool(standard_pipeline) else clip
|
|
|
|
| 294 |
|
| 295 |
# single clear at start is enough; avoid double-clearing here
|
| 296 |
|
| 297 |
+
# Apply LoRA chain
|
| 298 |
loras = [
|
| 299 |
(use_lora_1, lora_1, strength_model_1, strength_clip_1),
|
| 300 |
(use_lora_2, lora_2, strength_model_2, strength_clip_2),
|
|
|
|
| 345 |
except Exception:
|
| 346 |
pass
|
| 347 |
|
| 348 |
+
# Embeddings: Positive and Negative
|
| 349 |
# Standard pipeline: optionally use a shared CLIP after clip_layer + CLIP-LoRA
|
| 350 |
# Select CLIP source for encoding: pristine when standard pipeline is enabled
|
| 351 |
src_clip = clip_clean if bool(standard_pipeline) else clip
|
pressets/mg_cade25.cfg
CHANGED
|
@@ -118,8 +118,8 @@ aq_attn: true
|
|
| 118 |
seed: 0
|
| 119 |
control_after_generate: randomize
|
| 120 |
steps: 30
|
| 121 |
-
cfg: 7
|
| 122 |
-
denoise: 0.
|
| 123 |
sampler_name: ddim
|
| 124 |
scheduler: MGHybrid
|
| 125 |
iterations: 2
|
|
@@ -355,7 +355,7 @@ control_after_generate: randomize
|
|
| 355 |
steps: 25
|
| 356 |
cfg: 6.0
|
| 357 |
#0.75
|
| 358 |
-
denoise: 0.
|
| 359 |
sampler_name: ddim
|
| 360 |
scheduler: MGHybrid
|
| 361 |
iterations: 2
|
|
|
|
| 118 |
seed: 0
|
| 119 |
control_after_generate: randomize
|
| 120 |
steps: 30
|
| 121 |
+
cfg: 7.5
|
| 122 |
+
denoise: 0.65
|
| 123 |
sampler_name: ddim
|
| 124 |
scheduler: MGHybrid
|
| 125 |
iterations: 2
|
|
|
|
| 355 |
steps: 25
|
| 356 |
cfg: 6.0
|
| 357 |
#0.75
|
| 358 |
+
denoise: 0.45
|
| 359 |
sampler_name: ddim
|
| 360 |
scheduler: MGHybrid
|
| 361 |
iterations: 2
|
pressets/mg_controlfusion.cfg
CHANGED
|
@@ -12,7 +12,7 @@ pyra_low: 109
|
|
| 12 |
pyra_high: 215
|
| 13 |
pyra_resolution: 1024
|
| 14 |
edge_thin_iter: 0
|
| 15 |
-
edge_alpha: 0.
|
| 16 |
edge_boost: 0.10
|
| 17 |
smart_tune: false
|
| 18 |
smart_boost: 0.62
|
|
@@ -20,8 +20,8 @@ smart_boost: 0.62
|
|
| 20 |
# blend & strengths
|
| 21 |
blend_mode: normal
|
| 22 |
blend_factor: 0.35
|
| 23 |
-
strength_pos: 0.
|
| 24 |
-
strength_neg:
|
| 25 |
|
| 26 |
# schedule window
|
| 27 |
start_percent: 0.000
|
|
@@ -38,10 +38,10 @@ stack_prev_control: false
|
|
| 38 |
split_apply: false
|
| 39 |
|
| 40 |
# split timings
|
| 41 |
-
edge_start_percent: 0.
|
| 42 |
-
edge_end_percent: 0.
|
| 43 |
-
depth_start_percent: 0.
|
| 44 |
-
depth_end_percent:
|
| 45 |
|
| 46 |
# multipliers & shape
|
| 47 |
edge_strength_mul: 0.03
|
|
@@ -73,8 +73,8 @@ smart_boost: 0.84
|
|
| 73 |
# blend & strengths
|
| 74 |
blend_mode: normal
|
| 75 |
blend_factor: 0.300
|
| 76 |
-
strength_pos: 0.
|
| 77 |
-
strength_neg:
|
| 78 |
|
| 79 |
# schedule window
|
| 80 |
start_percent: 0.000
|
|
@@ -126,7 +126,7 @@ smart_boost: 0.56
|
|
| 126 |
# blend & strengths
|
| 127 |
blend_mode: normal
|
| 128 |
blend_factor: 0.300
|
| 129 |
-
strength_pos: 0.
|
| 130 |
strength_neg: 1.00
|
| 131 |
|
| 132 |
# schedule window
|
|
|
|
| 12 |
pyra_high: 215
|
| 13 |
pyra_resolution: 1024
|
| 14 |
edge_thin_iter: 0
|
| 15 |
+
edge_alpha: 0.65
|
| 16 |
edge_boost: 0.10
|
| 17 |
smart_tune: false
|
| 18 |
smart_boost: 0.62
|
|
|
|
| 20 |
# blend & strengths
|
| 21 |
blend_mode: normal
|
| 22 |
blend_factor: 0.35
|
| 23 |
+
strength_pos: 0.45
|
| 24 |
+
strength_neg: 1.10
|
| 25 |
|
| 26 |
# schedule window
|
| 27 |
start_percent: 0.000
|
|
|
|
| 38 |
split_apply: false
|
| 39 |
|
| 40 |
# split timings
|
| 41 |
+
edge_start_percent: 0.200
|
| 42 |
+
edge_end_percent: 0.400
|
| 43 |
+
depth_start_percent: 0.200
|
| 44 |
+
depth_end_percent: 0.400
|
| 45 |
|
| 46 |
# multipliers & shape
|
| 47 |
edge_strength_mul: 0.03
|
|
|
|
| 73 |
# blend & strengths
|
| 74 |
blend_mode: normal
|
| 75 |
blend_factor: 0.300
|
| 76 |
+
strength_pos: 0.45
|
| 77 |
+
strength_neg: 1.10
|
| 78 |
|
| 79 |
# schedule window
|
| 80 |
start_percent: 0.000
|
|
|
|
| 126 |
# blend & strengths
|
| 127 |
blend_mode: normal
|
| 128 |
blend_factor: 0.300
|
| 129 |
+
strength_pos: 0.75
|
| 130 |
strength_neg: 1.00
|
| 131 |
|
| 132 |
# schedule window
|