28 Commits
Author SHA1 Message Date
Robert Galasso 02a47d25ff Merge pull request #7 from BobsBlazed/claude/node-update-improve-2fygeb
Update the README and add architecture documentation
2026-08-11 22:21:07 -04:00
Claude 1f1db18e85 Update the README and add architecture documentation
The README still described the project as two nodes for SDXL and FLUX, told
readers to "choose either", and showed an info example predating the
architecture line. It also stated the wrong licence.

README:

- Lead with the three nodes and when to use each, rather than bolting the
  Universal loader onto a two-node description.
- Refresh the info example to a real one, including the architecture/stacks
  line, and explain every column.
- Add a Troubleshooting section covering the cases the node can now report:
  nodes missing from the menu, the mismatch warning, a LoRA that matches
  nothing, a high Other Tensors count, and divergence from the built-in
  LoraLoader.
- Note that the SDXL node also covers SD1.5 and SD2.
- Separate architectures actually verified from those supported by the same
  mechanism but not exercised, rather than implying one list.
- Correct the licence to Apache-2.0; the README claimed GPL-3.0.
- Move the changelog to CHANGELOG.md, which was 90 of the README's 250 lines.

docs/ARCHITECTURE.md is new and covers why classification runs on the canonical
target key rather than the LoRA's own names, why stack matching uses the raw
dotted key instead of the normalised one, how runtime stack discovery and the
depth axis work, and how to add an architecture or a family -- including the
widget-order compatibility contract that is easy to break silently.

Every factual claim in both documents was checked against the code: the FLUX
and SDXL block range tables, the Universal block list, the preset names, the
documented stack names against STACK_ORDER, the test count, and all internal
links and anchors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TUT2wQ8UsjNgosRWu6jvpj
2026-07-30 11:35:59 +00:00
BobsBlazed e7f867a9ed Fix issues found in code review (#6)
Eight findings from a review of 1.2.0. None changes behaviour for a correctly
paired LoRA and model; the first two matter when the pairing is wrong.

The FLUX and SDXL classifiers never received the dot-boundary fix the Universal
loader got, so an SDXL key "input_blocks.4.1.transformer_blocks.0.attn1.to_q.
weight" matched the nested transformer_blocks and was read as double-stream
block 0. The stack patterns are now anchored to the start of the module path,
since the nested stack is dot-preceded too.

Choosing the wrong loader for a model was silent: the keys still match, because
ComfyUI builds the key map from the model, so every tensor lands in whichever
single bucket the classifier reaches. A mismatch check now warns when 90% or
more of the UNet tensors land in one block -- a threshold rather than "all of
them" because cross-family names overlap slightly.

Also: families register through register_family() instead of mutating module
tables at import time; tooltips are stored per family so the shared "Text
Encoder" name no longer collides; the "_head_" output token no longer matches
multi_head_attention; unknown preset names warn; FLUX accepts negative block
indices; and a bucket boundary guarding an impossible fraction was dropped.

Tests grow from 55 to 71, adding tests/test_node_behaviour.py. The real ComfyUI
integration harnesses still classify 8000+ authentic keys across 11
architectures with nothing falling through.

Bumps version to 1.2.1.
2026-07-29 10:49:09 -04:00
BobsBlazed 3c7fd499b6 Add a Universal loader covering every supported architecture (#5)
The FLUX and SDXL loaders know their architecture's block names up front, which
does not scale across ComfyUI's ~99 model configs. The new Universal node
discovers a model's block layout at runtime instead: stack names, stack sizes
and their execution order all come from the loaded model, so pruned, distilled
and brand-new architectures work without a code change.

Concatenating the discovered stacks puts every block on one normalised depth
axis, split into five buckets, alongside embeddings, output head and text
encoder. Covers SD1.5/2/3, SDXL, FLUX, Chroma, AuraFlow, PixArt, HiDream,
Qwen-Image, Wan, LTX-Video, Mochi, HunyuanVideo/DiT, Lumina and Cosmos.

Verified against real ComfyUI: models built from ComfyUI's own configs on the
meta device plus its *_to_diffusers key tables, 8000+ authentic state-dict keys
across 11 architectures, none falling through to "Other Tensors". That pass
found and fixed real gaps: SD3's negative "joint_blocks.-1" index, Lumina's
noise_refiner/context_refiner stacks, AuraFlow's native double_layers naming,
several conditioning embedders, and FLUX's ControlNet pos_embed_input.

No widget was added, removed or reordered on the FLUX or SDXL nodes, so
existing workflows are unaffected.

Bumps version to 1.2.0.
2026-07-28 20:04:26 -04:00
BobsBlazed a297e24319 Fix block classification and overhaul the loader (#4)
The per-block sliders were not targeting the blocks they named. ComfyUI's
key_map maps a LoRA key name to the model state-dict key string the patch
targets (or a (key, offset) tuple for fused FLUX qkv/linear1 weights), but
_invert_key_map treated those values as nn.Module objects and indexed [0] on
them -- on a string that is its first character. Every patch then resolved
through one arbitrary lookup, so all weights were bucketed together.

Classify patches directly on the canonical target key instead, which also makes
the mapping dialect-proof. Fused (key, offset) patches are unpacked correctly.

Also fixes SDXL patches that matched no stage being silently discarded, FLUX
pushing every group into both the model and CLIP patchers, dead double_blocks
19-28 ranges, and bare torch.load on non-safetensors LoRAs.

Adds LoRA file caching, an "info" output with a per-block report, optional clip
input, tooltips, a "Detail & Texture" preset, and unit tests with CI.

Bumps version to 1.1.0.
2026-07-28 12:19:12 -04:00
BobsBlazed 161e9fd9ca Update README.md 2025-08-12 23:41:38 -04:00
BobsBlazed 772d0457b2 Update pyproject.toml 2025-08-12 23:37:02 -04:00
BobsBlazed d896666f93 Update bobs_lora_loader.py 2025-08-12 23:36:45 -04:00
BobsBlazed f36721209d Update pyproject.toml 2025-08-12 23:26:11 -04:00
BobsBlazed c6c89d4de8 Update bobs_lora_loader.py 2025-08-12 23:25:57 -04:00
BobsBlazed 04011d4cb7 Update pyproject.toml 2025-08-12 15:38:39 -04:00
BobsBlazed afb0cb2b13 Update bobs_lora_loader.py 2025-08-12 15:38:27 -04:00
BobsBlazed ec381967e3 Update pyproject.toml 2025-08-12 15:12:11 -04:00
BobsBlazed fc325691a4 Update bobs_lora_loader.py 2025-08-12 15:11:16 -04:00
BobsBlazed d739c3f074 Update bobs_lora_loader.py 2025-08-12 15:10:51 -04:00
BobsBlazed 7e5c6991c8 Update pyproject.toml 2025-08-12 14:24:08 -04:00
BobsBlazed f10769b3b9 Update bobs_lora_loader.py 2025-08-12 14:23:51 -04:00
BobsBlazed 06daf48270 Update issue templates 2025-06-27 08:02:37 -04:00
BobsBlazed a132fda8dc Update pyproject.toml 2025-06-26 22:18:59 -04:00
BobsBlazed b5ff189bb5 Update bobs_lora_loader.py 2025-06-26 22:18:18 -04:00
BobsBlazed 445f5e8d96 Update README.md 2025-06-26 21:43:20 -04:00
BobsBlazed feaea23f9e Update README.md 2025-06-26 21:42:11 -04:00
BobsBlazed 149e52e169 Create publish.yml 2025-06-26 21:36:58 -04:00
BobsBlazed f408cfa104 Create pyproject.toml 2025-06-26 21:31:24 -04:00
BobsBlazed 907113b105 Add files via upload 2025-06-26 21:19:27 -04:00
BobsBlazed 06821d4f5b Update README.md 2025-06-26 21:18:27 -04:00
BobsBlazed a62fbb448e Update README.md 2025-06-26 21:17:57 -04:00
BobsBlazed d7a5f2458f Initial commit 2025-06-26 21:17:13 -04:00