ComfyUI Node

Truncate Rank

SVD your deltas

By ljleb·Created 3 years ago·Updated about a month ago· 101
Truncate Rank
  • a (delta)
  • rank (8)
  • use_approximate_basis (True)
  • approximate_basis_iters (2)
  • approximate_basis_seed (None)
  • cache
  • recipe
merge_checkpointingfalse

LoRAs are already small, but not always small enough - and sometimes the problem isn't size, it's noise. Truncate Rank re-factorizes a delta down to its top rank singular directions, which both compresses it and (usually) keeps the signal that matters. If you've ever read the LoRA training advice about rank being expressiveness versus overfitting, this is that same tradeoff applied to an existing model instead of a training run.

What it actually does

Truncate Rank expects a delta - a recipe in the "delta" merge space, meaning a LoRA loaded via Mecha Lora Recipe, or the difference between two models computed with a subtract-style recipe. Under the hood it's sd-mecha's truncate_rank method: each tensor gets flattened to 2D, run through a truncated singular value decomposition, and rebuilt from the top rank singular values. Default rank is 8. Tensors below 2 dimensions pass through untouched, and rank 0 zeroes the delta entirely - useful if you want to know exactly what a rank range is carrying.

Two knobs matter beyond rank. use_approximate_basis (default on) uses torch.svd_lowrank with a couple of iterations and a settable approximate_basis_seed, which is fast and cheap on memory but randomized-ish. Flip it off for an exact full SVD - slower, heavier, deterministic. And if you plan to sweep ranks, plug a Cache Unit into the cache input; the SVD factors are cached, so re-running at a different rank reuses the decomposition instead of recomputing it.

Wiring it up

The delta flows in, the truncated delta flows out (recipe, still in delta space), and then it has to be merged back into a base - usually a weighted sum with your base model at the other end, then into a Mecha Merger for the UNet + text encoder. This is where the low-memory design pays off: you can extract, truncate, and re-add a delta without ever materializing full intermediate checkpoints, which the naive ComfyUI merge path absolutely does.

Installing it

This is one node in the Mecha Merge Node Pack by Louis-Jacob Lebel (ljleb), author of the sd-mecha library that backs the whole pack. Install via ComfyUI Manager (search "mecha" → "Mecha Merge Node Pack") or:

cd ComfyUI/custom_nodes
git clone https://github.com/ljleb/comfy-mecha.git
pip install -r comfy-mecha/requirements.txt

Only dependency is sd-mecha==1.1.7; no model downloads, it works on whatever you already have.

Gotchas

The classic trap: feeding a full checkpoint into a (delta). The socket says delta, and mecha will validate rather than silently do something wrong - but the mental model matters too. Rank too low and the style flattens out; the "right" rank is what the delta can actually express, not a number you should blindly copy. And the merge_checkpointing toggle is worth a mention: it caches the recipe branch in fp16 on CPU for fast re-runs, but treat it as an alternative to a cache unit, not a companion - use both and the memory adds up. This is a genuinely useful node but a niche one; most people never shrink a LoRA by hand, and that's fine.

Categorymecha

Inputs (7)

NameTypeDefaultDescription
a (delta)MECHA_RECIPE
rank (8)optMECHA_RECIPE8
use_approximate_basis (True)optMECHA_RECIPEtrue
approximate_basis_iters (2)optMECHA_RECIPE2
approximate_basis_seed (None)optMECHA_RECIPE
cacheoptMECHA_MERGE_METHOD_CACHE
merge_checkpointingoptBOOLEANfalseSpeeds up an entire branch of a merge graph that does not change often in exchange of memory. - true: store the first output of this recipe node on cpu memory in fp16. On subsequent workflow executions, as long as the inputs do not change, the cached keys are returned after being cast to the original device and dtype. - false: do not store the output. The recipe and its inputs will re-execute on subsequent workflow executions. Note that the memory used to checkpoint the output is distinct from the cache feature. In general, you probably want to either use this *or* a cache unit, but not both at the same time because the memory adds up. The difference between merge checkpointing and cache is that merge checkpointing completely re-merges from scratch if any input changes. Merge checkpointing is also generally much faster than cache in the fast path.

Outputs (1)

NameTypeDescription
recipeMECHA_RECIPE