Aesthetic Score (LAION)
How Pretty Is It, Actually? A Local LAION Aesthetic Score
- clip_vision_output
- score
- scores
You've got forty seeds and you need the three that don't suck. AestheticScore gives you a number from 1 to 10 for "how aesthetically pleasing is this image" - computed locally, no API, no second model download beyond one small head. It's the same LAION aesthetic predictor people have used to rank generations for years, wrapped as a ComfyUI output node that reads the CLIP embedding you already have in the graph.
It lives in the ComfyUI_Face_similarity pack from phobod, which is a bit of a grab-bag: the README is all about the InsightFace face-comparison node that gives the repo its name, and then there are these CLIP-vision and VLM tools bolted on with zero documentation. Same install, same folder, five useful nodes you'd never expect from the title.
What it actually does
Wire an image through a CLIPVisionEncode node and feed its CLIP_VISION_OUTPUT in here. The node grabs the projected 768-dimensional image_embeds - not the patch tokens - normalizes them, and pushes them through a tiny MLP: the "sac+logos+ava1-l14-linearMSE" head from christophschuhmann's improved-aesthetic-predictor. That head was trained on human ratings of images in the AVA/LAION logo set, so the output is a rough proxy for "would a person call this nice-looking." It is a filter, not a verdict. Use it to rank a batch and keep the top few; don't build your life around a 0.3 difference.
Weights download once on first run to ComfyUI/models/aesthetic/ and stay there.
The inputs and outputs that matter
There's exactly one input: clip_vision_output. That's the whole surface - no threshold, no sliders, nothing to misconfigure. Two outputs:
score(FLOAT) - the batch mean. Score a single image and this is your 1–10.scores(STRING) - per-image values for the batch, comma-separated. This is the one you want when you feed in several frames at once.
It's an output node, so the result also lands in the /history payload - handy if you're driving ComfyUI over the API and want the score back without scraping the console.
Installing it
Search ComfyUI_Face_similarity in ComfyUI Manager and install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/phobod/ComfyUI_Face_similarity.git
cd ComfyUI_Face_similarity
pip install -r requirements.txt
Heads up: the pack's requirements install the face-similarity stack - insightface, onnxruntime-gpu, opencv - none of which AestheticScore touches. It only needs torch and numpy, which ComfyUI already has. You can't avoid the heavy deps with a per-node install, but you can ignore them once they're in.
Where people get burned
The classic failure is the wrong CLIP model, and the symptom is confusing. If you feed it an embedding from a ViT-H (the SDXL-era CLIP that most IPAdapter workflows use) or a SigLIP model, the head can't take it - the first layer is hard-wired to 768 inputs. The node prints an honest error naming the actual dimension and reminding you the LAION head needs 768 (OpenAI CLIP ViT-L/14), then returns 0.0. A score of exactly zero is never a bad image; it's a wrong CLIP. Load the ViT-L/14 model instead - in ComfyUI that's the clip-vit-large-patch14 file from the CLIP Vision loader.
A blank score can also just mean the head weights are still downloading on first run - watch the console for the [AestheticScore] downloading weights line. And if you're scoring video frames, remember the mean hides the bad ones; read the scores string.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| clip_vision_output | CLIP_VISION_OUTPUT | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| score | FLOAT | — |
| scores | STRING | — |