Apply Null-LaLoRA (Universal + Null)
Frozen Null Space Meets Trainable Subspace
- model
- clip
- subspace
- null_lalora_weights
- MODEL
- CLIP
ApplyNullLaLoRA (displayed as "Apply Null-LaLoRA (Universal + Null)") is the most research-forward node in ComfyUI_UniversalSubspace, and the one you'll use last - if you use it at all. The others handle "plain" universal weights; this one applies a specific training scheme the author calls Null-LaLoRA, built to combine a frozen null-space component with a trainable subspace component.
The idea
The display name says it: "universal + null." A Null-LaLoRA splits each layer's adapter in two:
- a frozen null part - weights pinned so they don't disturb what the base model already knows, which is the trick for avoiding forgetting or collisions when you stack adapters;
- a trainable universal part - coordinates along the shared subspace basis (the same
μ + V·αscheme as the rest of the pack), which carries the new behavior the training was actually about.
Optionally it adds DoRA-style magnitude scaling on top. The docstring names the companion training script, network_null_lalora_bata.py - note that this script is not in the pack. The repo only ships inference; the training half lives in the author's research pipeline.
What the node does
It reconstructs each layer's down/up matrices, concatenates the frozen and trainable pieces along the rank dimension, applies either standard (s) or DoRA (m) scaling, and hands the assembled LoRA to ComfyUI's load_lora_for_models like any other apply node. Two details worth knowing:
- It deliberately processes the reconstruction on CPU to save VRAM. Your GPU stays free during the math, at the cost of speed - for big LoRAs the apply can take a beat.
- The weights file has to carry the null parts, either saved inside it (keys like
.null_up/.null_down) or pulled from the subspace file itself. If neither exists for a layer, the layer is silently skipped.
The inputs
model,clip- as always.subspace-UNIVERSAL_SUBSPACEfrom UniversalLoRALoader.null_lalora_weights- aUNIVERSAL_WEIGHTSfile from LoadUniversalWeights, but in the Null-LaLoRA format:alpha_down/alpha_upfor the trainable part,sormfor scaling.strength_model/strength_clip- default 1.0, range -10 to 10.
Outputs are MODEL and CLIP, wired into sampler and conditioning as usual.
The honest take
This node only does something if you have a Null-LaLoRA trained with the author's pipeline. That's a tiny audience: people following this specific research line. If you're not one of them, this node will load fine, accept a weights file, and quietly do nothing - the console prints Null-LaLoRA Applied Layers: 0 and the model passes through untouched. Don't mistake that for a bug. It's the pack working as intended on data it can't handle. Check the console, verify your weights file actually contains alpha_down / alpha_up and null parts, and confirm the layer naming matches the basis before assuming something's broken.
Install
Identical to the rest of the pack - no extra dependencies, nothing heavy to pull:
# ComfyUI Manager: Manager → Install Custom Nodes → search "UniversalSubspace" → Install → Restart
cd ComfyUI/custom_nodes
git clone https://github.com/a-ru2016/ComfyUI_UniversalSubspace
Then restart ComfyUI. It'll appear under the UniversalSubspace category alongside the four siblings. And yes - this whole pack is research-grade with effectively no community usage, so if this node looks over your head, that's not a value judgment on you. It's a value judgment on the node.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| clip | CLIP | — | |
| subspace | UNIVERSAL_SUBSPACE | — | |
| null_lalora_weights | UNIVERSAL_WEIGHTS | — | |
| strength_model | FLOAT | 1.00-10–10 | — |
| strength_clip | FLOAT | 1.00-10–10 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |
| CLIP | CLIP | — |