Nodes/ComfyUI_UniBlockSwap/UniBlockSwap TE
ComfyUI Node

UniBlockSwap TE

When the text encoder is the real VRAM hog

By smthemex·Created 2 months ago·Updated 15 days ago· 130
UniBlockSwap TE
  • clip
  • clip
num_blocks-1

Everyone blames the big diffusion model, but on the new crop of models the text encoder quietly eats a shocking slice of your card. Krea 2 ships a Qwen3VL 4B encoder, and a 4B LLM is not small. You squeeze the DiT down with a GGUF quant, hit Generate, and the OOM comes from the CLIP side instead. That's the gap UniBlockSwap TE fills: same author, same pack, same block-swap trick as its big sibling UniBlockSwap, applied to the text encoder instead of the diffusion model.

What it is

A model/loaders node that takes a clip (CLIP) in and gives a clip (CLIP) out, meant to sit between your CLIP loader and CLIPTextEncode. It clones your CLIP, wraps the encoder's block containers (the layer stacks inside the cond_stage_model) in a swap-aware list, and shuffles blocks between GPU and CPU so the encoder isn't all resident at once. Same mechanics as the parent node: a resident prefix stays pinned in VRAM, the tail lazy-loads, and everything is released when inference ends.

When to actually use it

Here's the thing the README is careful to tell you: don't reach for this first. The author's own guidance is to rely on ComfyUI's built-in vbar handling of the text encoder, and only add TE swap if you genuinely OOM on it - adding swap costs system RAM, and the text encoder is only in play during conditioning anyway. So the sane order is: quantize the model, add UniBlockSwap to the DiT, try a run, and only then consider UniBlockSwap TE for whatever's still OOMing. On a 4-6GB card this node is often the difference between "runs with the encoder offloaded" and "runs at all" - it's just the last lever, not the first.

The one knob

Same num_blocks semantics as UniBlockSwap (INT, default -1):

  • -1 - most aggressive: 1-block resident prefix. Least VRAM, slowest encoding.
  • 0 - disabled, pure passthrough.
  • N - keep N leading blocks resident.
  • ≥ total blocks - no swap (same as 0).

Everything is named and shaped exactly like the model node, so if you already understand UniBlockSwap you already understand this one. The output clip feeds CLIPTextEncode, and the conditioning it produces is byte-identical to the unswapped version - swapping changes memory, not math.

Installing it

You almost certainly already have it: UniBlockSwap TE ships in the same pack as UniBlockSwap, so if that node is installed this one is too. If not:

cd ComfyUI/custom_nodes
git clone https://github.com/smthemex/ComfyUI_UniBlockSwap

Then restart ComfyUI. No requirements.txt, no extra pip packages - it's pure Python on ComfyUI's own APIs. ComfyUI Manager will also find it as "ComfyUI_UniBlockSwap".

Common issues

  • System RAM again. TE swap stores encoder blocks in RAM, and stacked on top of model swap it can push a 16GB machine into swap-of-the-swap territory. Watch your memory counter.
  • The silent disable. num_blocks ≥ total turns the node off without telling you. If nothing changed after you added it, check that value.
  • Old clones. Earlier versions had a bug where changing num_blocks broke LoRA mounting on the swapped blocks; the current resident-prefix design fixed it. If you cloned this months ago, update the pack.
  • No text encoder found. Some models don't expose a block container the node recognizes; the node logs a warning and passes your clip through unchanged, so it degrades gracefully rather than crashing.

Swap is about making the workflow fit, not about speed - you're trading a bit of encode time for a card that can hold the whole pipeline.

Categorymodel/loaders

Inputs (2)

NameTypeDefaultDescription
clipCLIP
num_blocksoptINT-1-1–10000前缀常驻块数: 一次性把 block 0..N-1 推送进 CUDA, 常驻到本次推理结束才释放; 其余块按需逐块懒加载。-1 = 单块前缀常驻(最省显存); N = N 块前缀常驻; >= 总块数 = 不 swap 全部驻留

Outputs (1)

NameTypeDescription
clipCLIP