This repository contains three specialized Large Reward Models (LRMs) fine-tuned from
Qwen3-VL-8B-Instruct for generating reward signals in robot reinforcement learning. Each model serves a distinct role in the reward pipeline:
Given an initial observation and two later observations, predicts which is closer to task completion.
1from transformers import Qwen3VLForConditionalGeneration, AutoProcessor
2import torch
3from PIL import Image
4
5model_path = "USC-PSI-Lab/LRM-models"
6subfolder = "contrastive"
7
8model = Qwen3VLForConditionalGeneration.from_pretrained(
9 model_path, subfolder=subfolder,
10 torch_dtype=torch.bfloat16, device_map="auto",
11)
12processor = AutoProcessor.from_pretrained(
13 model_path, subfolder=subfolder,
14)
15
16# Load images
17initial_img = Image.open("initial.jpg").convert("RGB")
18image_a = Image.open("image_a.jpg").convert("RGB")
19image_b = Image.open("image_b.jpg").convert("RGB")
20
21messages = [{"role": "user", "content": [
22 {"type": "text", "text": "Task: Compare the completion progress.\n\nThe task is: Pick up the cup.\n\nYou are given:\n- Initial observation: "},
23 {"type": "image", "image": initial_img},
24 {"type": "text", "text": "\n- Later observation (Image A): "},
25 {"type": "image", "image": image_a},
26 {"type": "text", "text": "\n- Later observation (Image B): "},
27 {"type": "image", "image": image_b},
28 {"type": "text", "text": '\n\nQuestion: Which of Image A or Image B is closer to completing the task?\nSelect one value from the following list:\n["ImageA", "ImageB"]\n\nPlease provide a step-by-step visual analysis first, and then output your answer in the following JSON format:\n{ "more_complete_image": "selected_value" }'},
29]}]
30
31text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
32inputs = processor(text=[text], images=[initial_img, image_a, image_b], padding=True, return_tensors="pt").to(model.device)
33
34with torch.no_grad():
35 outputs = model.generate(**inputs, max_new_tokens=2048, do_sample=False)
36
37response = processor.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
38print(response)
39# Output: { "more_complete_image": "ImageA" }
Estimates completion progress as a value between 0.0 and 1.0.
1subfolder = "progress"
2
3model = Qwen3VLForConditionalGeneration.from_pretrained(
4 model_path, subfolder=subfolder,
5 torch_dtype=torch.bfloat16, device_map="auto",
6)
7processor = AutoProcessor.from_pretrained(
8 model_path, subfolder=subfolder,
9)
10
11observation = Image.open("observation.jpg").convert("RGB")
12
13messages = [{"role": "user", "content": [
14 {"type": "text", "text": "Task: Estimate the completion progress.\n\nThe task is: Pick up the cup.\n\nYou are given:\n- Current observation: "},
15 {"type": "image", "image": observation},
16 {"type": "text", "text": '\n\nEstimate the task completion progress from 0.0 (not started) to 1.0 (fully completed).\nOutput your answer in the following JSON format:\n{ "completion_progress": value }'},
17]}]
18
19text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
20inputs = processor(text=[text], images=[observation], padding=True, return_tensors="pt").to(model.device)
21
22with torch.no_grad():
23 outputs = model.generate(**inputs, max_new_tokens=2048, do_sample=False)
24
25response = processor.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
26print(response)
27# Output: { "completion_progress": 0.7 }
Binary prediction of whether a task has been completed.
1subfolder = "completion"
2
3model = Qwen3VLForConditionalGeneration.from_pretrained(
4 model_path, subfolder=subfolder,
5 torch_dtype=torch.bfloat16, device_map="auto",
6)
7processor = AutoProcessor.from_pretrained(
8 model_path, subfolder=subfolder,
9)
10
11observation = Image.open("observation.jpg").convert("RGB")
12
13messages = [{"role": "user", "content": [
14 {"type": "text", "text": "Task: Determine task completion.\n\nThe task is: Pick up the cup.\n\nYou are given:\n- Current observation: "},
15 {"type": "image", "image": observation},
16 {"type": "text", "text": '\n\nHas the task been completed?\nOutput your answer in the following JSON format:\n{ "task_completed": "yes" or "no" }'},
17]}]
18
19text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
20inputs = processor(text=[text], images=[observation], padding=True, return_tensors="pt").to(model.device)
21
22with torch.no_grad():
23 outputs = model.generate(**inputs, max_new_tokens=512, do_sample=False)
24
25response = processor.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
26print(response)
27# Output: { "task_completed": "no" }
This project is licensed under the Apache 2.0 License.