ImageRewardScore
Get a human-preference grade for every render, no humans required
- model
- images
- SCORE_FLOAT
- SCORE_STRING
ImageRewardScore is the node people actually mean when they say they're using ImageReward in ComfyUI. You hand it an image, a prompt, and a loaded ImageReward model, and it hands back a single number: how well that image matches that prompt, according to a model trained on 137k+ human preference comparisons. It's a taste test you can run a thousand times without asking anyone to rate anything.
That makes it a favorite for the "quality step" problem. ComfyUI will happily save whatever comes out of the sampler, including the cursed stuff - broken hands, melted faces, anatomy from a fever dream. ImageRewardScore gives you a signal to act on: gate the save on a threshold, or feed a batch of candidates and keep the highest score. The typical shape is ImageRewardLoader → ImageRewardScore → some comparator, with your generated image and its prompt both going in. It's not magic - it's a preference model, not an oracle - but for "which of these is least broken" it's surprisingly reliable.
How it works
ImageReward encodes the image with a BLIP ViT-Large visual encoder, lets the text encoder attend over it with your prompt, and pushes the resulting features through a small MLP that outputs a scalar. That score is then normalized around zero - the code subtracts the training mean and divides by the standard deviation - so scores land roughly in a band of about -2 to +2. Higher is better. The important part: the score is prompt-relative. It measures alignment with the specific prompt you feed it, so scores from different prompts aren't comparable. Compare images scored against the same prompt, or the number means little.
The inputs and outputs that matter
model(IMAGEREWARD_MODEL) - plug in the output ofImageRewardLoader. Non-negotiable.prompt(STRING, multiline) - the prompt you generated the image with. This is where the score comes from; a vague or wrong prompt produces a meaningless score. You can type it in or right-click and convert it to a graph input so it shares the prompt you actually used.images(IMAGE) - your render, typically from a VAE decode.
One trap worth knowing: the node loops over every image in the batch and averages the scores. If you feed it a batch of 16 candidates to rank, you get one mean number, not sixteen. To rank candidates individually, score them one at a time.
Outputs are the same number twice: SCORE_FLOAT and SCORE_STRING. Wire the float into a comparer or an if-style gate; the string is handy for shoving into a text/display node so you can actually see the grade.
Install and setup
Same as the loader - this is one pack. ComfyUI Manager, search "ImageReward", or:
cd ComfyUI/custom_nodes
git clone https://github.com/ZaneA/ComfyUI-ImageReward
pip install -r ComfyUI-ImageReward/requirements.txt
The first run downloads the ~1.8 GB model into ~/.cache/ImageReward. Dependencies are image-reward==1.4 plus OpenAI's clip built from source, and image-reward pins some older libraries (timm, fairscale) that can collide with other custom nodes sharing your environment.
Common issues
The genuinely weird one: people report ImageReward and its dependencies misbehaving on very new CUDA toolkits (12.8/13.0-era). If scoring errors out on a fresh install and you're on a cutting-edge driver stack, that's a known source of friction. Otherwise the usual suspects apply: if every score clusters suspiciously close to zero, that's normal - the scores are standardized - and if the numbers feel off, double-check the prompt matches what generated the image. Garbage prompt, garbage grade.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| model | IMAGEREWARD_MODEL | — | |
| prompt | STRING | — | |
| images | IMAGE | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| SCORE_FLOAT | FLOAT | — |
| SCORE_STRING | STRING | — |