Save CLIP Embedding (.npy)
Save CLIP Embeddings to Disk
- clip_vision_output
- path
- dimensions
ComfyUI can compute a CLIP vision embedding for an image, and then it throws it away. There's no built-in node that writes one to a file, which means an embedding can never leave a workflow. SaveClipEmbedding is that missing node: it takes a CLIP_VISION_OUTPUT and dumps the image embedding to a .npy file on disk.
Why would you want that? Because some jobs are inherently batch-wide. Inside one workflow you compare one image to one other image - that's the sibling InsightFace face-similarity node's whole trick. But near-duplicate detection across a whole folder of frames, or building a vector index of an image collection to search later, can't be done one image at a time inside the graph. You run the graph once per image, save each embedding, and do the pairwise comparison in plain Python afterwards. This node is the extraction half of exactly that pipeline.
How it works
CLIP vision outputs carry two useful tensors: penultimate_hidden_states (patch tokens, what IPAdapter feeds on) and image_embeds, the single projected vector per image. This node takes image_embeds - for a ViT-L/14 CLIP that's 768 floats per image. It converts to a numpy float32 array, optionally normalizes each vector to unit length, and saves it.
Normalization matters more than it looks. If your downstream use is cosine similarity (it almost always is - dedupe, retrieval, nearest-neighbor), unit-length vectors turn cosine into a plain dot product and save you the normalization step in whatever script reads the file. It's a flag rather than a given so you can keep raw magnitudes if they mean something to you. Leave it on.
The file layout is [batch, 768] float32, so a multi-frame batch becomes one .npy with one row per image. Anything that reads numpy can consume it - no torch needed on the reading side.
Inputs and outputs
clip_vision_output- wire up your CLIP Vision Encode here.path(default"embedding") - the output path without an extension;.npyis appended for you.normalize(defaulttrue) - unit-length vectors for cosine work.create_dirs(defaulttrue) - make parent directories if missing.
The two outputs, path and dimensions, tell you where it went (full path) and the vector size (768 for the usual ViT-L/14). Both are mostly for passing along to a downstream logger.
One gotcha worth knowing before you automate this: a relative path resolves against ComfyUI's own working directory, not your terminal's. If you're driving this over the ComfyUI API from another process, send an absolute path or the file lands somewhere you aren't looking. And if you turn create_dirs off with a missing directory, it politely returns an empty path and dimensions of 0 rather than crashing - that's the node telling you the folder doesn't exist.
Installing
It ships in the same pack as the face-similarity node, which is how you find it:
cd ComfyUI/custom_nodes
git clone https://github.com/phobod/ComfyUI_Face_similarity.git
cd ComfyUI_Face_similarity
pip install -r requirements.txt
or search ComfyUI_Face_similarity in ComfyUI Manager. Note the README only documents the InsightFace node - this one (like its neighbor AestheticScore, which consumes the same clip_vision_output) is code-complete but undocumented in the repo. The source is clean and MIT, so it's not a trust problem, just a "the README is behind" problem.
Troubleshooting
- Wrong dimension in the file? Check which CLIP you loaded. ViT-H and SigLIP models give different-sized vectors; if you're building a collection to compare, use the same CLIP for every image or your vectors won't line up.
- File not where you expected? Absolute path from API callers, remember.
- Silent empty outputs? Check whether
create_dirsis false and the target directory doesn't exist yet.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| clip_vision_output | CLIP_VISION_OUTPUT | — | |
| path | STRING | embedding | — |
| normalize | BOOLEAN | true | — |
| create_dirs | BOOLEAN | true | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| path | STRING | — |
| dimensions | INT | — |