Nodes/ComfyUI-IP-Composer/IP-Comp Concept Subspace
ComfyUI Node

IP-Comp Concept Subspace

Teach a CLIP model a concept in seconds — no training, just SVD

By godmt·Created about a year ago·Updated about a year ago· 5
IP-Comp Concept Subspace
  • open_clip_model
  • concept_subspace
descriptions
rank30
batch_size100

This is the node that makes IP-Composer feel like magic, because it turns a list of sentences into a reusable visual concept. Type a bunch of descriptions of "fur" into it, hit run, and out comes a concept subspace - a small matrix that captures what "fur" means in CLIP embedding space. The word "training" never enters the picture. It's linear algebra, it takes seconds, and you don't touch a gradient.

The original IP-Composer pipeline uses an LLM to generate those descriptions for you. This ComfyUI port hands that job to you: you paste the descriptions yourself (or chain in an LLM node - the repo's example workflow literally wires up Griptape for it). If you'd rather not write descriptions at all, skip this node entirely and load a prebuilt subspace with IP-Comp Load Concept Subspace instead.

How it works

The source is refreshingly honest about what's happening:

embs = np.vstack(embs)                    # all description embeddings, one row each
_, _, v = np.linalg.svd(embs, full_matrices=False)
concept_subspace = torch.from_numpy(v)    # top `rank` rows become the subspace

Every line of your descriptions gets tokenized and encoded by the OpenCLIP model into a vector. Stack those vectors, run SVD, and the top singular vectors are the directions in embedding space along which your descriptions vary the most. Those directions are the concept. Feed enough varied descriptions - "a picture of black fur with glossy highlights", "short fur with blended stripes" - and the shared structure rises to the top while the noise stays below the rank cutoff. That's the whole "training-free" claim, and it holds up: the paper this pack ports does exactly this.

The inputs that matter

  • open_clip_model - comes from IP-Comp Load CLIP Vision. No other source; this node needs OpenCLIP's text encoder, which ComfyUI's normal CLIP loader can't give you.
  • descriptions - one concept description per line. This is the input that actually determines the result. More variety = a more robust concept; a list of twenty near-identical sentences gives you a subspace that overfits one narrow thing.
  • rank - how many SVD directions to keep. Default 30, and the sane starting point. Too low and the concept gets vague; too high and it starts collecting noise.
  • batch_size - descriptions are encoded in batches (default 100). You can mostly ignore it; if you're encoding hundreds of lines and running out of VRAM, drop it.

The output, concept_subspace, feeds IP-Comp Save Concept Subspace (to cache it on disk) or directly into IP-Comp Concept Merge (to use it once).

Installing it

Same as the rest of the pack:

cd ComfyUI/custom_nodes
git clone https://github.com/godmt/ComfyUI-IP-Composer

Restart, let ComfyUI Manager pull in the open-clip-torch dependency, and you're set. Note that the first run of IP-Comp Load CLIP Vision downloads the CLIP weights from HuggingFace - a few hundred MB, and it needs internet.

Where people get burned

  • Stale descriptions. The subspace only knows what you wrote. If you want a concept that generalizes (say, "outfit" rather than "one red dress"), describe it across many colors, materials, and contexts.
  • Model drift. The subspace lives in the embedding space of whichever CLIP model built it. Build with ViT-H-14, then merge with embeddings from a different vision model, and the concept directions point at nothing. The metadata records the model; check it.
  • VRAM on big lists. batch_size exists because a thousand descriptions won't fit in one forward pass. If you see OOM with long lists, this is the knob.

It's a young, barely-documented pack, so lean on the example workflows when in doubt - then replace their descriptions with your own and watch the same concept appear in your merges.

Categoryip_composer

Inputs (4)

NameTypeDefaultDescription
open_clip_modelOPEN_CLIP
descriptionsSTRING
rankINT301–1024
batch_sizeINT1001–512

Outputs (1)

NameTypeDescription
concept_subspaceCONCEPT_SUBSPACE