Downloads · 30 days
31
4% of all-time downloads
yinuoy/MR2-Molmo2-4B-RM
MR2-Molmo2-4B-RM is a image-text-to-text model from yinuoy. Use it for the image-text-to-text task on the model card, and read the license before you ship it in a product. It is set up for transformers. The card lists the license as apache-2.0.
MR²-Molmo2-4B-RM is a multi-response multimodal reward model built on top of Molmo2-4B. Unlike conventional reward models that score each response independently, our model scores all N candidate responses in a single…
Downloads · 30 days
31
4% of all-time downloads
All-time downloads
848
Public
Parameters
4.9B
9.7 GB on disk
Likes
1
Public
Click a slice to open those files.
.safetensors9.7 GB · 100%
From the Hugging Face model README
MR²-Molmo2-4B-RM is a multi-response multimodal reward model built on top of Molmo2-4B. Unlike conventional reward models that score each response independently, our model scores all N candidate responses in a single forward pass by concatenating them into one sequence, enabling direct comparative reasoning across candidates while achieving up to N× inference speedup.
This model is described in our paper: You Only Judge Once: Multi-response Reward Modeling in a Single Forward Pass (arXiv).
Quick links:
Proprietary models (as judge)
| Model | Size | VL-RB | MM-RB | MMRLHF | MR²B-I | VRB | MR²B-V | Avg |
|---|---|---|---|---|---|---|---|---|
| GPT-5 | -- | 75.0 | 64.6 | 71.8 | 87.1 | 68.2 | 50.1 | 69.5 |
| Claude-Sonnet-4.5 | -- | 68.6 | 78.2 | 70.0 | 72.9 | 67.5 | 49.1 | 67.7 |
| Gemini-2.5-Pro | -- | 70.5 | 82.4 | 70.6 | 71.2 | 63.2 | 49.7 | 67.9 |
Open-source VLMs (as judge)
| Model | Size | VL-RB | MM-RB | MMRLHF | MR²B-I | VRB | MR²B-V | Avg |
|---|---|---|---|---|---|---|---|---|
| Qwen3-VL-32B | 32B | 67.1 | 79.0 | 78.8 | 60.8 | 65.8 | 49.9 | 66.9 |
Generative reward models
| Model | Size | VL-RB | MM-RB | MMRLHF | MR²B-I | VRB | MR²B-V | Avg |
|---|---|---|---|---|---|---|---|---|
| R1-Reward | 7B | 71.4 | 82.2 | 80.6 | 58.8 | 61.2 | 44.9 | 66.5 |
Discriminative reward models (including ours)
| Model | Size | VL-RB | MM-RB | MMRLHF | MR²B-I | VRB | MR²B-V | Avg |
|---|---|---|---|---|---|---|---|---|
| Skywork-VL-Reward | 7B | 69.0 | 74.2 | 72.4 | 52.9 | 62.9 | 46.7 | 63.0 |
| IXC-2.5-Reward | 7B | 70.0 | 66.6 | 71.2 | 55.0 | 57.1 | 48.7 | 61.4 |
| MR²-Molmo2-4B-RM (Ours) | 4B | 82.2 | 73.2 | 92.4 | 62.5 | 66.3 | 50.7 | 71.2 |
VL-RB: VL-RewardBench (macro pairwise acc.); MM-RB: Multimodal RewardBench (pairwise acc.); MMRLHF: MM-RLHF RewardBench (pairwise acc.); MR²B-I: MR²Bench-Image (best-of-4 acc.); VRB: VideoRewardBench (macro pairwise acc.); MR²B-V: MR²Bench-Video (best-of-4 acc.).
git clone https://github.com/yinuoyang01/multi-response-rm.git
cd multi-response-rm
pip install -r requirements.txt
import json
import torch
from transformers import AutoProcessor, AutoModelForImageTextToText
from huggingface_hub import hf_hub_download
from PIL import Image
from mr2rm.models.reward_model import MultiResponseRewardModel
from mr2rm.data.dataset import add_resp_sep_token, RESP_SEP_TOKEN
model_id = "yinuoy/MR2-Molmo2-4B-RM"
# 1. Processor (register the <|resp_sep|> special token)
processor = AutoProcessor.from_pretrained(
model_id, trust_remote_code=True, dtype="auto", device_map="auto",
)
add_resp_sep_token(processor.tokenizer)
# 2. Base model + reward model (value-head config from reward_model_config.json)
base_model = AutoModelForImageTextToText.from_pretrained(
model_id, trust_remote_code=True, dtype="auto", device_map="auto",
)
config_path = hf_hub_download(repo_id=model_id, filename="reward_model_config.json")
with open(config_path) as f:
rm_config = json.load(f)
reward_model = MultiResponseRewardModel(
base_model=base_model,
value_head_type=rm_config["value_head_type"],
value_head_hidden_dim=rm_config["value_head_hidden_dim"],
value_head_activation=rm_config["value_head_activation"],
resp_repr_mode=rm_config["resp_repr_mode"],
)
# 3. Load value-head weights
vh_path = hf_hub_download(repo_id=model_id, filename="value_head.pt")
reward_model.value_head.load_state_dict(torch.load(vh_path, map_location="cpu"))
device = next(reward_model.base_model.parameters()).device
dtype = next(reward_model.base_model.parameters()).dtype
reward_model.value_head = reward_model.value_head.to(device=device, dtype=dtype)
reward_model.eval()
# 4. Build input: user=(prompt+image), assistant=(responses joined by <|resp_sep|>)
image = Image.open("example.jpg").convert("RGB")
prompt = "Describe this image."
responses = [
"A golden retriever sitting on grass.",
"A dog in a park on a sunny day.",
"There is an animal outside.",
"I don't know.",
]
sep = f"\n\n{RESP_SEP_TOKEN}\n\n"
assistant_text = sep.join(responses)
messages = [
{"role": "user", "content": [dict(type="image", image=image), dict(type="text", text=prompt)]},
{"role": "assistant", "content": [dict(type="text", text=assistant_text)]},
]
inputs = processor.apply_chat_template(
messages, tokenize=True, return_tensors="pt", return_dict=True,
)
inputs = {k: v.to(device) for k, v in inputs.items()}
# 5. Locate the last-token position of each response (just before each <|resp_sep|>, plus end-of-sequence for the final one)
sep_token_id = processor.tokenizer.convert_tokens_to_ids(RESP_SEP_TOKEN)
input_ids = inputs["input_ids"][0]
sep_positions = (input_ids == sep_token_id).nonzero(as_tuple=True)[0].tolist()
end_positions = [p - 1 for p in sep_positions] + [input_ids.size(0) - 1]
resp_indices = torch.tensor([end_positions], device=device)
# 6. One forward pass — scores for all N responses
with torch.inference_mode():
(scores,) = reward_model(
input_ids=inputs["input_ids"],
attention_mask=inputs.get("attention_mask"),
resp_indices=resp_indices,
**{k: v for k, v in inputs.items() if k not in ["input_ids", "attention_mask"]},
)
rewards = scores[0].tolist()
print("Scores:", rewards)
print("Best response:", responses[rewards.index(max(rewards))])
# Score N candidates and pick the best
best_idx = scores.argmax().item()
best_response = responses[best_idx]
# For each rollout group of N responses, compute scores in one forward pass
# Use scores as rewards for GRPO advantage computation
<|resp_sep|> as the per-response representationThis model is licensed under Apache 2.0, consistent with the Molmo2 base model license. It is intended for research and educational use. This model is trained on third-party datasets that are subject to their respective licenses; please review the sources listed above to determine if this model is appropriate for your use case.
@misc{yang2026judgeoncemultiresponsereward,
title={You Only Judge Once: Multi-response Reward Modeling in a Single Forward Pass},
author={Yinuo Yang and Zixian Ma and Manasi Ganti and Jieyu Zhang and Ranjay Krishna},
year={2026},
eprint={2604.10966},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2604.10966},
}