Views
No views yet
Lychee-rerank-mm is the latest generalist multimodal reranking model developed based on the Qwen2.5-VL-Instruct foundation model. It is designed for reranking tasks in image-text multimodal retrieval scenarios.
Lychee-rerank-mm is jointly developed by the NLP Team of Harbin Institute of Technology, Shenzhen, and the 7B parameter versions are released as open source.
| Model Type | Models | Size | Instruction Aware |
|---|---|---|---|
| Multimodal Reranking | lychee-rerank-mm | 8.29B | Yes |
Note:
Instruction Awarenotes whether the reranking model supports customizing the input instruction according to different tasks.- Like most models, for most downstream tasks, using instructions (instruct) typically yields an improvement to not using them. Therefore, we recommend that developers create tailored instructions specific to their tasks and scenarios.
instruction according to their specific scenarios.1import torch
2from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
3from qwen_vl_utils import process_vision_info
4
5
6def format_content(text, image, prefix='Query:'):
7 content = []
8 if not text and not image:
9 content = [{'type': 'text', 'text': prefix}]
10 return content
11 content.append({'type': 'text', 'text': prefix})
12 if image:
13 content.append({'type': 'image', 'image': 'file://' + image})
14 if text:
15 content.append({'type': 'text', 'text': text})
16 return content
17
18def format_instruction(instruction, query_text, query_image_path, doc_text, doc_image_path):
19 inputs = []
20 inputs.append({
21 "role": "system",
22 "content": [{
23 "type": "text",
24 "text": "Judge whether the Document meets the requirements based on the Query and the Instruct provided. Note that the answer can only be \"yes\" or \"no\"."
25 }
26 ]
27 })
28 contents = []
29 contents.append({
30 "type": "text",
31 "text": '<Instruct>: ' + instruction
32 })
33 query_content = format_content(query_text, query_image_path, prefix='<Query>:')
34 contents.extend(query_content)
35 doc_content = format_content(doc_text, doc_image_path, prefix='\n<Document>:')
36 contents.extend(doc_content)
37 inputs.append({
38 "role": "user",
39 "content": contents
40 })
41 return inputs
42
43
44def process_inputs(pairs):
45 texts = [tokenizer.apply_chat_template(
46 messages,
47 tokenize=False,
48 add_generation_prompt=True
49 ) for messages in pairs]
50 try:
51 image_inputs, video_inputs = process_vision_info(pairs)
52 except Exception as e:
53 print(f'Failed to load image, consider to remove it from the dataset')
54 inputs = tokenizer(
55 text=texts,
56 images=image_inputs,
57 videos=video_inputs,
58 padding=True,
59 return_tensors="pt",
60 truncation=False,
61 max_length=3200
62 )
63 for key in inputs:
64 inputs[key] = inputs[key].to(model.device)
65 return inputs
66
67
68@torch.no_grad()
69def compute_logits(inputs, **kwargs):
70 batch_scores = model(**inputs).logits[:, -1, :]
71 true_vector = batch_scores[:, token_true_id]
72 false_vector = batch_scores[:, token_false_id]
73 batch_scores = torch.stack([false_vector, true_vector], dim=1)
74 batch_scores = torch.nn.functional.log_softmax(batch_scores, dim=1)
75 scores = batch_scores[:, 1].exp().tolist()
76 return scores
77
78
79model_name_or_path = "vec-ai/lychee-rerank-mm"
80min_pixels = 4*28*28
81max_pixels = 1280*28*28
82tokenizer = AutoProcessor.from_pretrained(model_name_or_path, padding_side='left', min_pixels=min_pixels, max_pixels=max_pixels, trust_remote_code=True)
83# We recommend enabling flash_attention_2 for better acceleration and memory saving.
84model = Qwen2_5_VLForConditionalGeneration.from_pretrained(model_name_or_path, torch_dtype=torch.bfloat16, attn_implementation="flash_attention_2").cuda().eval()
85
86token_false_id = tokenizer.tokenizer.get_vocab()["no"]
87token_true_id = tokenizer.tokenizer.get_vocab()["yes"]
88
89task = 'Given a web search query, retrieve relevant passages that answer the query'
90
91query_texts = [
92 "What is the capital of China?",
93 "Explain gravity",
94]
95
96query_images = [
97 None,
98 None,
99]
100
101doc_texts = [
102 "The capital of China is Beijing.",
103 "Gravity is a force that attracts two bodies towards each other. It gives weight to physical objects and is responsible for the movement of planets around the sun.",
104]
105
106doc_images = [
107 None,
108 None,
109]
110
111pairs = [format_instruction(task, query_text, query_image, doc_text, doc_image) for query_text, query_image, doc_text, doc_image in zip(query_texts, query_images, doc_texts, doc_images)]
112
113# Tokenize the input texts
114inputs = process_inputs(pairs)
115scores = compute_logits(inputs)
116
117print("scores: ", scores)
118
119query_text = "What breed is the cat in the image?"
120query_image = "./images/Siamese_cat1.jpg"
121doc_texts = [
122 "The Siamese cat is one of the first distinctly recognised breeds of Asian cat. It derives from the Wichianmat landrace. The Siamese cat is one of several varieties of cats native to Thailand (known as Siam before 1939). The original Siamese became one of the most popular breeds in Europe and North America in the 19th century. Siamese cats have a distinctive colourpoint coat, resulting from a temperature-sensitive type of albinism.",
123 "The Asian or Asian group, is a cat breed similar to the European Burmese, but comes in a range of different coat colours and patterns. Long-haired Asians of all varieties are called Tiffanies. Asians are grouped in section 5 (Burmese) by the Governing Council of the Cat Fancy (GCCF)."
124]
125doc_images = [
126 "./images/Siamese_cat2.jpg",
127 "./images/Asian_cat.jpg",
128]
129pairs = [format_instruction(task, query_text, query_image, doc_text, doc_image) for doc_text, doc_image in zip(doc_texts, doc_images)]
130inputs = process_inputs(pairs)
131scores = compute_logits(inputs)
132print("scores: ", scores)| Model | Param | ALL (40) | T→T (14) | I→I (1) | T→I (4) | T→VD (5) | I→T (5) | T→IT (2) | IT→T (4) | IT→I (2) | IT→IT (3) |
|---|---|---|---|---|---|---|---|---|---|---|---|
| GME-2B | 2.21B | 52.54 | 49.59 | 30.75 | 48.46 | 66.39 | 52.62 | 77.02 | 39.88 | 36.70 | 66.89 |
| Qwen3-Reranker | 4.02B | -- | 60.49 | -- | -- | -- | -- | -- | -- | -- | -- |
| Jina-rerank-m0 | 2.21B | 54.36 | 55.36 | 27.50 | 59.46 | 73.13 | 55.43 | 74.95 | 27.82 | 37.65 | 51.54 |
| MonoQwen2-VL-v0.1 | 2.21B | 44.20 | 48.89 | 12.59 | 58.73 | 71.29 | 19.62 | 76.46 | 14.35 | 31.75 | 35.83 |
| lychee-rerank-mm-3B | 3.75B | 61.40 | 59.22 | 29.76 | 58.85 | 72.38 | 63.06 | 81.96 | 48.81 | 43.97 | 79.08 |
| lychee-rerank-mm-7B | 8.29B | 63.85 | 61.08 | 32.83 | 61.18 | 72.94 | 66.61 | 84.55 | 53.29 | 47.39 | 82.19 |
@misc{dai2025supervisedfinetuningcontrastivelearning,
title={Supervised Fine-Tuning or Contrastive Learning? Towards Better Multimodal LLM Reranking},
author={Ziqi Dai and Xin Zhang and Mingxin Li and Yanzhao Zhang and Dingkun Long and Pengjun Xie and Meishan Zhang and Wenjie Li and Min Zhang},
year={2025},
eprint={2510.14824},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2510.14824},
}