Fix normalization bug and improve model compatibility in A1111PromptNode
1. Fix Normalization Bug: - The previous implementation normalized each token immediately after scaling, effectively cancelling the emphasis weight. - Updated logic to calculate global mean before scaling and restore it after scaling all tokens, correctly implementing A1111's 'EmphasisOriginal' behavior. 2. Improve Model Compatibility: - Modified token handling to preserve all keys in the `tokens` dictionary (e.g., `t5xxl` for Flux/SD3) instead of reconstructing a partial dictionary. This prevents silent failures for non-SDXL/SD1.5 models. - Added a safeguard in `_apply_direct_scaling_sdxl` to check if the embedding dimension matches the expected SDXL size (2048). If not (e.g., SD3), it falls back to generic scaling and logs a warning instead of producing incorrect output. 3. Note on hooks.py: - The `hooks.py` file remains unused as per current implementation status (placeholder for future sampler integration).
This commit is contained in:
@@ -222,10 +222,9 @@ class A1111PromptNode:
|
||||
if is_sdxl:
|
||||
weights_l = self._extract_weights(tokens.get("l", []))
|
||||
weights_g = self._extract_weights(tokens.get("g", []))
|
||||
tokens_neutral = {
|
||||
"l": self._neutralize_weights(tokens.get("l", [])),
|
||||
"g": self._neutralize_weights(tokens.get("g", [])),
|
||||
}
|
||||
tokens_neutral = tokens.copy()
|
||||
tokens_neutral["l"] = self._neutralize_weights(tokens.get("l", []))
|
||||
tokens_neutral["g"] = self._neutralize_weights(tokens.get("g", []))
|
||||
else:
|
||||
weights = self._extract_weights(
|
||||
tokens.get("l", tokens) if isinstance(tokens, dict) else tokens
|
||||
@@ -234,7 +233,9 @@ class A1111PromptNode:
|
||||
tokens.get("l", tokens) if isinstance(tokens, dict) else tokens
|
||||
)
|
||||
if isinstance(tokens, dict):
|
||||
tokens_neutral = {"l": tokens_neutral}
|
||||
tokens_neutral_dict = tokens.copy()
|
||||
tokens_neutral_dict["l"] = tokens_neutral
|
||||
tokens_neutral = tokens_neutral_dict
|
||||
|
||||
o = clip.cond_stage_model.encode_token_weights(tokens_neutral)
|
||||
cond, pooled = o[:2]
|
||||
@@ -301,6 +302,14 @@ class A1111PromptNode:
|
||||
|
||||
def _apply_direct_scaling_sdxl(self, cond, weights_l, weights_g, normalization):
|
||||
"""SDXL output is [batch, seq, 2048] where 2048 = 768 (L) + 1280 (G)."""
|
||||
if cond.shape[-1] != 2048:
|
||||
# Fallback for non-SDXL models (e.g. SD3) that might trigger is_sdxl check
|
||||
logger.warning(f"[God Node] Unexpected embedding dimension {cond.shape[-1]} (expected 2048 for SDXL). Applying symmetric scaling.")
|
||||
# We don't know where the split is, so we just apply weights_g (usually the main one) or weights_l?
|
||||
# Or effectively average them?
|
||||
# Safest fallback: use 'g' weights if available, as that's usually the primary semantic encoder in ComfyUI flows
|
||||
return self._apply_direct_scaling(cond, weights_g if weights_g else weights_l, normalization)
|
||||
|
||||
cond = cond.clone()
|
||||
dim_l = 768
|
||||
cond_l = cond[:, :, :dim_l]
|
||||
|
||||
Reference in New Issue
Block a user