QReAlign NR Score
Quality and aesthetics from a vision-language judge
- model
- image
- score
Most no-reference metrics are small CNNs trained on distortion datasets: blur, noise, JPEG artifacts. They know what a broken image looks like and not much else. Q-ReAlign is a different species - a Qwen3.5-VL vision-language model that gets asked how good the picture is and answers with a level word, which the pack converts into a 0–1 score. It's slower, bigger, and it's the closest thing in this pack to a human opinion on aesthetics.
The two tasks
task is the widget that matters, because it changes the question being asked:
quality IQA- trained on quality assessment data. Does this image look technically well-made? Focus on artifacts, distortions, technical soundness.aesthetic IAA- aesthetic assessment. Does this image look good? Composition, appeal, taste.
Those two answers genuinely diverge, and running both on the same batch is the interesting use. A crisp, boring render can score high on quality and mediocre on aesthetics; a soft, atmospheric one can invert that. Point two nodes at one loader and you get both columns for the price of one model load.
It's the aesthetic head that makes this node hard to replace. The LAION Aesthetic variant on the generic loader is the other taste-scorer in this pack - a small predictor trained to guess how much humans would like a picture, the same lineage that selected LAION-Aesthetics out of LAION-5B. Useful, but a 2022-era taste model with a known bias toward certain looks. Q-ReAlign is a much newer generation of the same idea, and it costs accordingly.
How the score is made
The output is 0–1, higher better, computed from the model's level-word probabilities: it's asked to grade and returns something in the excellent-to-bad range, and the pack weights those probabilities from 1.0 down to 0.0. That's Q-Align's trick, and it's why the score is smooth rather than a hard grade out of 5.
Output is a score socket, emitted per image, so eight images in means eight floats out and any scalar consumer downstream runs eight times.
Inputs besides the task
image takes the batch, scored one at a time - expect real time per image, not the milliseconds an NR CNN takes. model comes from (Down)load Q-ReAlign and only that loader's output type is accepted here.
memory_management matters more on this node than anywhere else in the pack. Default unload model (VRAM + RAM) throws the model away after scoring: fast to free the card, and about thirty seconds to reload if you're on Pro. keep loaded keeps it resident.
The gotcha, straight from the tooltips: when several score nodes share one loader - exactly the quality-plus-aesthetic setup above - unload on each makes the shared model reload between them. Set keep loaded on all but the last node, or put a single Unload Pyiqa Models at the end of the graph.
Choosing a size
(Down)load Q-ReAlign gives you mini 0.8B, lite 4B and pro 9B, each also in an int8_convrot build that cuts size by about a third (Pro: 17.5 → 11.55 GiB) with score drift measured in thousandths. If your card can hold it at all, take the int8 Pro. If it can't, mini int8 at 1.56 GiB is genuinely usable and fast enough to score a few hundred images.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/AnsteinHuynh/ComfyUI-pyiqa-toolbox
python -m pip install -r ComfyUI-pyiqa-toolbox/requirements.txt
Or ComfyUI Manager → search pyiqa-toolbox. Restart. The node is under pyiqa/QReAlign.
Q-ReAlign needs transformers>=5, which the pack does not force on install - the loader checks at load time and prints the fix:
python -m pip install -U "transformers>=5"
Weights auto-download on first score into ComfyUI/models/pyiqa (or wherever your pyiqa path in extra_model_paths.yaml points). There's a shipped NR example workflow - Workflow → Browse Templates → ComfyUI-pyiqa-toolbox - that scores a batch with A-FINE, FGResQ NR and Q-ReAlign aesthetic, which is a decent template to steal.
Common issues
Slow first score. It's downloading several gigabytes and then loading a VLM. Watch the console; the size is logged before the load starts.
Both scores nearly identical between the two tasks. They're correlated - both are the same model's opinion - so expect movement, not a complete reordering. If you want a sharper distinction, run the aesthetic head alone on a batch that's technically clean.
Model reloading between your two score nodes. That's memory_management doing what it says. keep loaded on the earlier node.
VRAM gone after a run but the graph feels fine. The metric is invisible to ComfyUI's model manager, so nothing evicts it for you. Unload it deliberately.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| memory_management | COMBO | unload model (VRAM + RAM) | What happens to this metric after it scores. 'unload model (VRAM + RAM)': the metric is fully unloaded - gone from VRAM and RAM, only the file on disk remains; the next score reloads it (seconds for small models, ~30s for Q-ReAlign Pro). Re-queueing just works: a previously-unloaded model handed back by ComfyUI's output cache is rebuilt transparently. 'keep loaded': stays on the GPU, fastest to re-score, holds its VRAM between runs. With several score nodes sharing one loader, unload only on the LAST one - earlier nodes should 'keep loaded' or you pay a reload between them. |
| model | PYIQA_QREALIGN,PYIQA_ANY | From the matching Loader node. This input (and the loader feeding it) is evaluated LAZILY - only once this node's image inputs exist - so a generation-only run never loads the metric model. | |
| image | IMAGE | Image(s) to score; batch is scored per-image. Lazy: evaluated before the model loads. | |
| task | COMBO | quality IQA | Scoring task: quality IQA or aesthetic IAA. Passed as the arch's per-call task_ override. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| score | FLOAT | Per-image Q-ReAlign score in 0-1 for the chosen task (quality IQA or aesthetic IAA); higher is better. Computed from the model's level-word probabilities (excellent..bad weighted 1.0..0.0). |