arXiv | Model Weights | Validation History | Training | Evaluation | Citation
We derive that regression and ranking are approximately equivalent under a unified margin view. Based on this observation, we propose MR-IQA for margin learning in blind image quality assessment.
Create an isolated Python environment before installing project dependencies. The training environment targets a Linux CUDA machine; macOS or CPU-only machines can still inspect scripts and manifests, but cannot install the CUDA wheels or run the 8-GPU training launchers directly.
conda create -n mr-iqa python=3.12.13 -y
conda activate mr-iqa
pip install -r requirements.txtIf your cluster manages environments with venv instead of conda:
python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtrequirements.txt includes the PyTorch wheel index and a normalized version of the W&B environment used by the released run. If your default package index cannot resolve a training-time package, use the same package mirror/index as the training server. The launch scripts add src/ to PYTHONPATH and use CUDA_HOME when CUDA extensions need to be compiled.
Optional runtime overrides:
export CUDA_HOME=<cuda-toolkit-root>
export PYTHON_BIN=python3
export REPORT_TO=noneThe training and test manifests in this repository are derived from the normalized version of DeQA-Score data.
Prepare a training manifest in JSON or JSONL format. Each row should contain an image path and a human quality score:
{"image": "000001.png", "score": 3.72, "std": 0.41}Supported score keys include score, mos, rating, human_score, normalized_score, and gt_score_norm. Supported uncertainty keys include std, score_std, mos_std, source_std, and std_norm.
The committed manifests use relative image paths only. Point IMAGE_ROOT or VAL_IMAGE_ROOT to the corresponding image directory on your machine or cluster.
Expected layout:
data/
manifest_checksums.json
train_manifest/
train.jsonl
val_manifests/
koniq_val_200_seed42.json
test_manifests/
agiqa3k.json
csiq.json
kadid_full.json
koniq.json
livew.json
pipal.json
spaq_full.json
tid2013.json
The launch scripts do not contain local absolute paths. Set the model, manifest, and image-root paths explicitly for each machine.
Run 8-GPU full fine-tuning without validation:
MODEL_PATH=<hf-model-id-or-local-model-dir> \
DATA_FILES=data/train_manifest/train.jsonl \
IMAGE_ROOT=<train-image-root> \
OUTPUT_DIR=outputs/mr-iqa-2b \
VARIANCE_MODE=unit \
PROMPT_MODE=non_thinking \
bash scripts/train_mr_iqa_2b_8gpu.shRun 8-GPU full fine-tuning followed by 8-GPU validation:
MODEL_PATH=<hf-model-id-or-local-model-dir> \
DATA_FILES=data/train_manifest/train.jsonl \
IMAGE_ROOT=<train-image-root> \
VAL_DATA_FILE=data/val_manifests/koniq_val_200_seed42.json \
VAL_IMAGE_ROOT=<val-image-root> \
OUTPUT_DIR=outputs/mr-iqa-2b \
VAL_OUTPUT_JSON=outputs/mr-iqa-2b/validation/final.json \
VARIANCE_MODE=unit \
PROMPT_MODE=non_thinking \
bash scripts/train_mr_iqa_2b_8gpu_with_val.shVARIANCE_MODE controls the margin scale:
unit uses variance scale 1
sigma uses the paired ground-truth score sigma
PROMPT_MODE defaults to non_thinking. Set PROMPT_MODE=thinking to use the two-part thinking prompt and require outputs in the form <thinking>...</thinking><answer>{"rating": 3.50}</answer>.
For thinking-mode training, keep the same launch flow and set:
PROMPT_MODE=thinkingFor a 4B backbone, use:
bash scripts/train_mr_iqa_4b_8gpu.shor the validation-enabled wrapper:
bash scripts/train_mr_iqa_4b_8gpu_with_val.shSingle-dataset evaluation:
python src/mr_iqa/evaluate_mr_iqa.py \
--model_name_or_path <model-or-checkpoint> \
--data_file data/test_manifests/koniq.json \
--image_root <image-root> \
--output_json outputs/eval/koniq.json \
--prompt_mode non_thinking8-GPU validation-only evaluation:
MODEL_DIR=<model-or-checkpoint> \
VAL_DATA_FILE=data/val_manifests/koniq_val_200_seed42.json \
IMAGE_ROOT=<image-root> \
OUT_JSON=outputs/validation/koniq_val.json \
PROMPT_MODE=non_thinking \
bash scripts/validation_eval_8gpu.sh8-GPU generalization evaluation:
MODEL_DIR=<model-or-checkpoint> \
DATA_DIR=data/test_manifests \
IMAGE_ROOT=<image-root> \
OUT_DIR=outputs/generalization \
PROMPT_MODE=non_thinking \
bash scripts/generalization_eval_8gpu.shOverride the default generalization set with DATASETS="koniq spaq_full" if you only want a subset.
Single-image inference:
python src/mr_iqa/infer_single_image.py \
--model_name_or_path <model-or-checkpoint> \
--image_path <image-path> \
--prompt_mode non_thinkingFor a thinking-mode model, use --prompt_mode thinking. If --max_new_tokens is not set, single-image inference uses 64 tokens for non-thinking and 256 tokens for thinking.
configs/ DeepSpeed configuration
data/ Relative-path training, validation, and test manifests
scripts/ 2B/4B training and 8-GPU evaluation launchers
src/mr_iqa/ Training, scoring, parsing, and evaluation code
assets/ Project overview PDF and PNG preview
We sincerely thank the open-source community for making this work possible. In particular, MR-IQA builds on the broader ecosystem around Qwen3-VL and is inspired by community progress in visual quality reasoning such as VisualQuality-R1.
This project is released under the MIT License. See LICENSE for details.
@misc{li2026mriqaunifiedmarginview,
title={MR-IQA: A Unified Margin View of Regression and Ranking for Blind Image Quality Assessment},
author={Yuan Li and Youyuan Lin and Zitang Sun and Yung-Hao Yang and Kiyofumi Miyoshi and Chenhui Chu and Shin'ya Nishida},
year={2026},
eprint={2606.29760},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2606.29760}
}