Aesthetics V2
The batch ranker that actually works, with a score to prove it
- image
- best
- best_score
Same job as the pack's v1 Aesthetics node - look at a batch of image variations, keep the best one - but this version swaps the fragile CLIP hack for HPSv2, the human-preference scorer, and it actually works out of the box. It also hands you the score, which is the part you'll end up caring about.
What it is. Aesthetics V2 takes an image batch and a text prompt, scores each frame with Human Preference Score v2.1 (hpsv2.score(..., hps_version="v2.1")), and returns the winning image plus a FLOAT of its score. HPSv2 is the model trained on a big pile of "which of these two images did humans prefer" data - the closest thing the community has to a proxy for "does this look good to a person," as opposed to CLIP's fuzzier semantic match. That's a meaningful upgrade over v1: v1 ranks by textual similarity to your prompt, v2 ranks by human preference conditioned on the prompt text.
Where you'd use it. Any workflow that churns out variations and wants to keep the winner automatically. The classic pattern is a random-prompt or multi-seed generator feeding a batch into this node, then straight to a VAE decode and a Save Image. It also slots in as an automated curator during dataset building: run a big batch, let it pick the top frame per prompt, and only the pick goes into your folder. The best_score float is the real prize there - wire it to a Show Text node or a text file logger and you can track "how good was the pick" across runs, or threshold it in a switch so only images scoring above, say, 0.65 survive.
Inputs and outputs. Tiny surface again:
image(IMAGE) - the batch of variations. Batch of one works too; you just get a score for it.text(STRING, multiline) - the prompt you're judging against. It feeds the scoring, not the generation.best(IMAGE) - the winning frame.best_score(FLOAT) - the HPSv2 score of that frame, roughly in the 0β1 range.
Installing it and the first-run dance. The pack is sneccc/comfyui-snek-nodes; search that in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/sneccc/comfyui-snek-nodes
Then restart. Here's where it gets interesting: the module tries import hpsv2 on load, and if that fails it runs the pack's install.py, which git clones tgxs002/HPSv2 into your custom_nodes folder and patches the repo's broken imports (it strips a clint progress-bar dependency and a stray from turtle import forward) before pip-installing it editable. That's the author's way of working around HPSv2's famously messy setup, and it mostly works - but it needs git and network on first startup, and it writes a HPSv2 directory next to the pack. First run also downloads the HPSv2.1 weights from Hugging Face, so budget a few hundred MB and a short wait before you judge it.
Troubleshooting. If the node reports missing dependencies, watch the ComfyUI console during startup - the do_install() call prints loudly. If the HPSv2 clone fails (firewall, no git), nothing else will fix it automatically; run git clone https://github.com/tgxs002/HPSv2.git and pip install -e HPSv2 by hand. Score output comes back as a tensor; if a downstream node complains about types, it's a cast issue on the score, not the image.
Bottom line. This is the one of the pack's two aesthetics nodes worth actually using. The mechanism is sound, the extra score output opens up real automation, and the install, while hacky, does resolve itself. Treat v1 as an artifact and skip it.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | β | |
| text | STRING | β |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| best | IMAGE | β |
| best_score | FLOAT | β |