EmbeddingGemma 2 Encode Images
Give every frame in the batch a fingerprint
- model
- images
- embeddings
- report
Look at any "best of N" workflow and you'll see the same sad shape: generate a batch, save a batch, open the folder, click through sixteen thumbnails, pick one. This node is the first half of automating that decision. It reads an IMAGE batch and hands back one vector per image, all in the same space as the text you'd describe them with.
So instead of "which of these looks best", you can ask "which of these matches the prompt I actually wrote", and get an index.
What it does to your pixels
The conversion is deliberately dumb and that's the point: the float tensor is multiplied by 255, rounded, clamped to uint8, and handed to PIL as RGB. If the image came from ComfyUI's Load Image, those are exactly the file's pixels - no resampling, no colour-space surprise. Single-channel images get repeated to three channels.
Then it's the official image processing: 280 tokens per image into the model's context, no task prefix. No prefix on the image side is not laziness - that's how the model was trained. Text gets the instruction, media doesn't.
Labels are positional: image 0, image 1, and so on. That matters downstream, because Similarity's best_label output will hand you a string like image 3 rather than a nice path or prompt. Fine if you're reading the ranking JSON; mildly annoying if you wanted to display it.
The inputs
Two you'll touch, one you won't.
images - a normal ComfyUI IMAGE, which means a whole batch, not one image. A batch of 8 gives you 8 embeddings. It has to be an [B, H, W, C] tensor with 1, 3 or 4 channels; anything else errors with the shape in the message.
dimensions - 768 / 512 / 256 / 128, Matryoshka truncation with renormalisation. Default 768. Here the model card's warning bites hardest: 512 and 256 are near-lossless, but 128 loses noticeably on images, video and audio. Use 256 as your cheap default and don't go to 128 unless you've measured it on your own data. And whatever you pick, the text embeddings you compare against must use the same number, or Similarity and Rank Images will refuse to run - they check and raise a message with both lengths.
model - the EG2_MODEL output from EmbeddingGemma 2 Loader, which must have been set with at least text + image/video modalities. On plain text this node fails saying the loaded set doesn't include image - not a bug, you told it not to build the vision tower.
Outputs are embeddings (the EG2_EMBEDDINGS bundle) and report, a JSON string with the count, vector length, dtype, device and elapsed seconds.
Where it actually earns its keep
Pair it with Rank Images when you want the order back as pixels: batch in, sorted batch out, top k kept. That's your "generate 12, keep the 3 that match the prompt" pipeline, and the prompt goes in as SearchQuery text.
Pair it with Similarity when you're labelling rather than sorting - five captions encoded as SearchQuery, one image encoded here, and the node tells you which caption wins and by how much. The author shipped a workflow for exactly this: workflows/gui/image_captions in the repo, pointing at input/example.png.
The honest caveat: this is semantic matching. It'll prefer the image with a boat in it over the one without. It will not tell you which of two boats is composed better, more prompt-faithful in the details, or less likely to have six fingers. Aesthetic scoring is a different tool. What this gives you is a fairly literal reading of content, and it's much better at "the sky is in the shot" than at "the lighting is nicer".
Install
cd ComfyUI/custom_nodes
git clone https://github.com/hiroki-abe-58/ComfyUI-EmbeddingGemma2
python -m pip install -r ComfyUI-EmbeddingGemma2/requirements.txt
python ComfyUI-EmbeddingGemma2/tools/download_model.py --models-dir ../models/embeddinggemma
Or install EmbeddingGemma 2 for ComfyUI from ComfyUI Manager and restart. The download is about 1.5 GB, SHA-256 verified against a pinned revision, and lands in models/embeddinggemma/embeddinggemma-2/.
Gotchas worth knowing before you file a bug
The pack requires a current ComfyUI - it's written against the V3 backend node API, so on an older build the nodes don't register and it looks like a broken install.
Your ComfyUI model dropdown may be empty after downloading by hand. The loader only offers folders that contain all five expected files, modules.json included. Run the download script instead of copying a HuggingFace snapshot and this just works.
And the dependency swap: sentence-transformers 6.1.0 pins huggingface-hub<2.0, so a fresh ComfyUI 0.38 environment drops from 2.2.0 to 1.33.0. Fine in testing; blame it if something unrelated stops importing.
On the author's RTX 5090 one image encodes in 0.06 s. The full model peaks around 2.5 GiB - not enough to push your sampler out of VRAM, but it is another tenant.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| model | EG2_MODEL | — | |
| images | IMAGE | — | |
| dimensions | COMBO | 768 | Matryoshka length: the leading dimensions, re-normalised. 768 = full; 512 / 256 are close to lossless; 128 loses noticeably on images, video and audio (model card). Only vectors of the same length can be compared. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| embeddings | EG2_EMBEDDINGS | — |
| report | STRING | — |