diff --git a/README.md b/README.md
index 3d24100..041286b 100644
--- a/README.md
+++ b/README.md
@@ -44,6 +44,11 @@ By default, detailed debug logs are **muted**. If you want detailed debug output
+- **NunchakuQwenImageLoraStackV1**: Multi LoRA stacker with rgthree-style UI - ComfyUI Nodes 2.0 compatible
+ - Clean, minimalist design inspired by [Power Lora Loader (rgthree-comfy)](https://github.com/rgthree/rgthree-comfy). Toggle, LoRA name, and strength per row.
+
+
+
- **NunchakuQwenImageLoraStackV2**: Multi LoRA stacker with dynamic UI - ComfyUI Nodes 2.0 (Beta) compatible
- **AWQ Modulation Layer Support**: Includes experimental support for applying LoRA to AWQ quantized modulation layers (`img_mod.1` / `txt_mod.1`) via the "Apply AWQ Mod" toggle. This feature uses Runtime Monkey Patch with Manual Planar Injection to fix noise issues. ⚠️ **Warning**: **This is an experimental feature currently implemented only in V2 nodes.** If no issues are found, this feature will be applied to V1 and V3 nodes as well.
diff --git a/__init__.py b/__init__.py
index b264462..604e94a 100644
--- a/__init__.py
+++ b/__init__.py
@@ -14,6 +14,8 @@ logger = logging.getLogger(__name__)
logger.info("=" * 40 + " ComfyUI-QwenImageLoraLoader Initialization " + "=" * 40)
NODE_CLASS_MAPPINGS = {}
+QWEN_V1_NODES = {}
+QWEN_V1_NAMES = {}
QWEN_V2_NODES = {}
QWEN_V2_NAMES = {}
QWEN_V3_NODES = {}
@@ -38,7 +40,7 @@ try:
from .nodes.lora.qwenimage import NunchakuQwenImageLoraLoader, NunchakuQwenImageLoraStack
from .nodes.lora.qwenimage_v2 import GENERATED_NODES as QWEN_V2_NODES, GENERATED_DISPLAY_NAMES as QWEN_V2_NAMES
from .nodes.lora.qwenimage_v3 import GENERATED_NODES as QWEN_V3_NODES, GENERATED_DISPLAY_NAMES as QWEN_V3_NAMES
- from .nodes.lora.qwenimage_v4 import GENERATED_NODES as QWEN_V4_NODES, GENERATED_DISPLAY_NAMES as QWEN_V4_NAMES
+ from .nodes.lora.qwenimage_v1 import GENERATED_NODES as QWEN_V1_NODES, GENERATED_DISPLAY_NAMES as QWEN_V1_NAMES
from .nodes.lora.zimageturbo_v2 import GENERATED_NODES as ZIMAGETURBO_V2_NODES, GENERATED_DISPLAY_NAMES as ZIMAGETURBO_V2_NAMES
# Z-Image-Turbo V3 is deprecated - removed from registration
# from .nodes.lora.zimageturbo_v3 import GENERATED_NODES as ZIMAGETURBO_V3_NODES, GENERATED_DISPLAY_NAMES as ZIMAGETURBO_V3_NAMES
@@ -51,7 +53,7 @@ try:
node_class.__version__ = __version__
for node_class in QWEN_V3_NODES.values():
node_class.__version__ = __version__
- for node_class in QWEN_V4_NODES.values():
+ for node_class in QWEN_V1_NODES.values():
node_class.__version__ = __version__
for node_class in ZIMAGETURBO_V2_NODES.values():
node_class.__version__ = __version__
@@ -65,7 +67,7 @@ try:
NODE_CLASS_MAPPINGS["NunchakuQwenImageLoraStack"] = NunchakuQwenImageLoraStack
NODE_CLASS_MAPPINGS.update(QWEN_V2_NODES)
NODE_CLASS_MAPPINGS.update(QWEN_V3_NODES)
- NODE_CLASS_MAPPINGS.update(QWEN_V4_NODES)
+ NODE_CLASS_MAPPINGS.update(QWEN_V1_NODES)
NODE_CLASS_MAPPINGS.update(ZIMAGETURBO_V2_NODES)
# Z-Image-Turbo V3 registration removed
# NODE_CLASS_MAPPINGS.update(ZIMAGETURBO_V3_NODES)
@@ -78,7 +80,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"NunchakuQwenImageLoraStack": "Nunchaku Qwen Image LoRA Stack (Legacy)",
**QWEN_V2_NAMES,
**QWEN_V3_NAMES,
- **QWEN_V4_NAMES,
+ **QWEN_V1_NAMES,
**ZIMAGETURBO_V2_NAMES,
# Z-Image-Turbo V3 registration removed
# **ZIMAGETURBO_V3_NAMES,
diff --git a/images/qiv1_stack.png b/images/qiv1_stack.png
new file mode 100644
index 0000000..eb69560
Binary files /dev/null and b/images/qiv1_stack.png differ
diff --git a/js/z_qwen_lora_dynamic_v4.js b/js/z_qwen_lora_dynamic_v1.js
similarity index 98%
rename from js/z_qwen_lora_dynamic_v4.js
rename to js/z_qwen_lora_dynamic_v1.js
index 90700c5..f8a7d0e 100644
--- a/js/z_qwen_lora_dynamic_v4.js
+++ b/js/z_qwen_lora_dynamic_v1.js
@@ -1,7 +1,7 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
-console.log("★★★ z_qwen_lora_dynamic_v4.js: Qwen Image LoRA Stack V4 ★★★");
+console.log("★★★ z_qwen_lora_dynamic_v1.js: Qwen Image LoRA Stack V1 ★★★");
// Use LiteGraph built-in colors to ensure Light/Dark Mode compatibility
const getColors = () => ({
@@ -178,10 +178,10 @@ class NunchakuLoraWidget {
}
app.registerExtension({
- name: "nunchaku.qwen_lora_dynamic_v4",
+ name: "nunchaku.qwen_lora_dynamic_v1",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
- if (nodeData.name !== "NunchakuQwenImageLoraStackV4") return;
+ if (nodeData.name !== "NunchakuQwenImageLoraStackV1") return;
// Save original onNodeCreated
const onNodeCreated = nodeType.prototype.onNodeCreated;
@@ -340,5 +340,3 @@ app.registerExtension({
};
}
});
-
-
diff --git a/nodes/lora/qwenimage_v4.py b/nodes/lora/qwenimage_v1.py
similarity index 94%
rename from nodes/lora/qwenimage_v4.py
rename to nodes/lora/qwenimage_v1.py
index 94cf11f..0b3c206 100644
--- a/nodes/lora/qwenimage_v4.py
+++ b/nodes/lora/qwenimage_v1.py
@@ -1,5 +1,5 @@
"""
-This module provides the :class:`NunchakuQwenImageLoraStackV4` node
+This module provides the :class:`NunchakuQwenImageLoraStackV1` node
for applying LoRA weights to Nunchaku Qwen Image models within ComfyUI.
The interface completely mimics the Power Lora Loader from rgthree-comfy(https://github.com/rgthree/rgthree-comfy ),
supporting dynamic additions and custom widgets.
@@ -39,11 +39,11 @@ class FlexibleOptionalInputType(dict):
def __getitem__(self, key):
return (any_type, {})
-class NunchakuQwenImageLoraStackV4:
+class NunchakuQwenImageLoraStackV1:
"""
Node for loading and applying multiple LoRAs to a Nunchaku Qwen Image model with dynamic UI.
- Built upon V3, V4 not only supports the ComfyUI Nodes 2.0 UI but also pays full homage
- to the clean and minimalist design of the Power Lora Loader from the rgthree-comfy project.
+ Built upon V3, pays full homage to the clean and minimalist design of the
+ Power Lora Loader from the rgthree-comfy project.
"""
@classmethod
@@ -76,7 +76,7 @@ class NunchakuQwenImageLoraStackV4:
},
),
},
- "optional": FlexibleOptionalInputType(),
+ "optional": FlexibleOptionalInputType(),
# Use 'hidden' here to let JS pass dynamic LoRA data
"hidden": {
"prompt": "PROMPT",
@@ -89,7 +89,7 @@ class NunchakuQwenImageLoraStackV4:
RETURN_TYPES = ("MODEL",)
OUTPUT_TOOLTIPS = ("The modified diffusion model with all LoRAs applied.",)
FUNCTION = "load_lora_stack"
- TITLE = "Nunchaku Qwen Image LoRA Stack V4"
+ TITLE = "Nunchaku Qwen Image LoRA Stack V1"
CATEGORY = "Nunchaku"
DESCRIPTION = "Apply multiple LoRAs to a diffusion model in a single node with dynamic UI control."
@@ -107,7 +107,7 @@ class NunchakuQwenImageLoraStackV4:
logger.info(f"[LoRA Stack Status] apply_awq_mod: {apply_awq_mod}")
logger.info(f"[LoRA Stack Status] stack_enabled: {stack_enabled}")
logger.info(f"[LoRA Stack Status] Processing {lora_count} LoRA slot(s):")
-
+
for i, key in enumerate(lora_keys):
value = kwargs[key]
if not isinstance(value, dict):
@@ -179,12 +179,12 @@ class NunchakuQwenImageLoraStackV4:
if model_wrapper.cpu_offload_setting != cpu_offload:
logger.info(f"🔄 Updating CPU offload setting from '{model_wrapper.cpu_offload_setting}' to '{cpu_offload}'")
model_wrapper.cpu_offload_setting = cpu_offload
-
+
# Dynamically update the apply_awq_mod setting.
if hasattr(model_wrapper, "apply_awq_mod") and model_wrapper.apply_awq_mod != apply_awq_mod:
logger.info(f"🔄 Updating AWQ mod setting from '{model_wrapper.apply_awq_mod}' to '{apply_awq_mod}'")
model_wrapper.apply_awq_mod = apply_awq_mod
-
+
transformer = model_wrapper.model
elif model_wrapper_type_name == "NunchakuQwenImageTransformer2DModel" or model_wrapper_type_name.endswith(
"NunchakuQwenImageTransformer2DModel"
@@ -239,11 +239,9 @@ class NunchakuQwenImageLoraStackV4:
GENERATED_NODES = {
- "NunchakuQwenImageLoraStackV4": NunchakuQwenImageLoraStackV4,
+ "NunchakuQwenImageLoraStackV1": NunchakuQwenImageLoraStackV1,
}
GENERATED_DISPLAY_NAMES = {
- "NunchakuQwenImageLoraStackV4": "Nunchaku Qwen Image LoRA Stack V4",
+ "NunchakuQwenImageLoraStackV1": "Nunchaku Qwen Image LoRA Stack V1",
}
-
-