Views
No views yet
| Model | Params | Dim | V1 | V2 | V3 |
|---|---|---|---|---|---|
| VultronRetrieverPrime-Qwen3.5-8B (ours) | 8.4B | 320 | 92.08 | 68.18 | 64.26 |
| VultronRetrieverCore-Qwen3.5-4.5B (this model) | 4.5B | 320 | 92.21 | 66.12 | 63.57 |
| nvidia/nemotron-colembed-vl-8b-v2 | 8.7B | 4096 | 92.65 | 65.16 | 63.42 |
| webAI-Official/webAI-ColVec1-9b | 9.4B | 2560 | 91.30 | 65.82 | 63.00 |
| webAI-Official/webAI-ColVec1-4b | 4.5B | 640 | 90.49 | 63.60 | 62.22 |
| TomoroAI/tomoro-colqwen3-embed-8b | 8.0B | 320 | 90.76 | 65.40 | 61.59 |
| nvidia/nemotron-colembed-vl-4b-v2 | 4.8B | 2560 | 91.62 | 64.49 | 61.54 |
| athrael-soju/colqwen3.5-4.5B-v3 | 4.6B | 128 | 91.54 | 64.25 | 61.46 |
| OpenSearch-AI/Ops-Colqwen3-4B | 4.8B | 2560 | 91.36 | 68.66 | 61.17 |
| TomoroAI/tomoro-colqwen3-embed-4b | 4.0B | 320 | 90.57 | 64.69 | 60.20 |
| nvidia/llama-nemotron-colembed-vl-3b-v2 | 4.4B | 3072 | 91.74 | 63.38 | 59.79 |
| jinaai/jina-embeddings-v4 | 3.9B | 2048 | 90.35 | 58.23 | 57.52 |
| nomic-ai/colnomic-embed-multimodal-7b | 7.0B | 128 | 89.72 | 60.25 | 57.33 |
| nvidia/llama-nemoretriever-colembed-3b-v1 | 4.4B | 3072 | 91.00 | 63.32 | 57.26 |
| VultronRetrieverFlash-Qwen3.5-0.8B (ours) | 0.85B | 320 | 88.15 | 60.36 | 56.16 |
| Verm1ion/ColTurk-VDR-Qwen3VL-4B-v1.0 | 4.5B | 128 | — | — | 55.81 |
| nomic-ai/colnomic-embed-multimodal-3b | 3.0B | 128 | 89.86 | 55.68 | 55.78 |
| nvidia/llama-nemoretriever-colembed-1b-v1 | 2.4B | 2048 | 90.50 | 62.96 | 55.59 |
| vidore/colqwen2.5-v0.2 | 3.0B | 128 | 89.54 | 60.06 | 51.90 |
| VAGOsolutions/SauerkrautLM-ColQwen3-8b-v0.1 | 8.1B | 128 | 91.08 | 62.47 | 58.55† |
| VAGOsolutions/SauerkrautLM-ColQwen3-4b-v0.1 | 4.4B | 128 | 90.80 | 59.89 | 56.03† |
| DataScience-UIBK/Argus-Colqwen3.5-9b-v0 | 8.8B | 1024 | 92.67 | 69.27 | — |
| DataScience-UIBK/Argus-Colqwen3.5-4b-v0 | 4.7B | 1024 | 92.30 | 64.18 | — |
| Benchmark | Metric | Tasks | Score |
|---|---|---|---|
| ViDoRe V1 | ndcg@5 | 10 | 0.9221 |
| ViDoRe V2 | ndcg@5 | 4 | 0.6612 |
| ViDoRe V3 | ndcg@10 | 10 | 0.6357 |
eval_results/; the 2 private tasks are scored by
the ViDoRe maintainers and reported on the public leaderboard. Measured with the official MTEB
late-interaction evaluator.Qwen/Qwen3.5-4B (hybrid GatedDeltaNet + full-attention backbone).ColQwen3_5): native 320-dim multi-vector embeddings, MaxSim scoring,
image + text inputs.score_multi_vector.MultiVectorEncoder:pip install "sentence-transformers[image]>=6.0.0"1from sentence_transformers import MultiVectorEncoder
2
3model = MultiVectorEncoder("vultr/VultronRetrieverCore-Qwen3.5-4.5B")
4
5queries = [
6 "What is the variable represented on the y-axis of the graph?",
7 "Total outlay is maximum in which year?",
8]
9images = [
10 "https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/doc1.jpg",
11 "https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/doc2.jpg",
12]
13
14query_embeddings = model.encode_query(queries)
15image_embeddings = model.encode_document(images)
16print(query_embeddings[0].shape, image_embeddings[0].shape)
17# torch.Size([23, 320]) torch.Size([1251, 320])
18
19# Diagonal should have higher scores
20scores = model.similarity(query_embeddings, image_embeddings)
21print(scores)
22# tensor([[16.2559, 10.9844],
23# [ 5.7363, 12.9688]], device='cuda:0')1pip install "git+https://github.com/illuin-tech/colpali@2e0b927051af727238783af039dcc2c50a4d8c27"
2pip install causal-conv1d flash-linear-attentioncausal-conv1d + flash-linear-attention are required (the hybrid layers import them at runtime).1import torch
2from PIL import Image
3from colpali_engine.models import ColQwen3_5, ColQwen3_5Processor
4
5model = ColQwen3_5.from_pretrained(
6 "vultr/VultronRetrieverCore-Qwen3.5-4.5B",
7 torch_dtype=torch.bfloat16,
8 attn_implementation="sdpa", # required (see above)
9 device_map="cuda:0",
10).eval()
11processor = ColQwen3_5Processor.from_pretrained(
12 "vultr/VultronRetrieverCore-Qwen3.5-4.5B",
13 max_num_visual_tokens=1792,
14)
15
16# Document pages (rendered to images) and text queries
17images = [Image.open("page_0.png"), Image.open("page_1.png")]
18queries = ["What was Q3 revenue?", "Summarize the safety findings."]
19
20with torch.no_grad():
21 doc_emb = model(**processor.process_images(images).to(model.device))
22 qry_emb = model(**processor.process_queries(queries).to(model.device))
23
24# Late-interaction MaxSim scoring (feed fp32 to match the eval discipline)
25scores = processor.score_multi_vector(qry_emb.float(), doc_emb.float())
26# scores[i, j] = relevance of query i to page j
27print(scores.shape) # torch.Size([2, 2])config.json carries dim=320, so custom_text_proj is sized correctly at load, with no manual
config edits needed. It also carries retrieval_attention_contract="causal"; a conflicting runtime
override is an error.ColQwen3_5 architecture), returning
the per-token multi-vectors for late-interaction scoring. It requires a vLLM build that includes the
projection-bias fix and explicit retrieval-attention metadata support. The handler reads
retrieval_attention_contract="causal" from this checkpoint and constructs all eight full-attention
layers as AttentionType.DECODER; it must reject missing, conflicting, or unsupported contract
metadata. The server uses the stock chat/image processor, so the ColQwen3.5
prompt contract is applied client-side: wrap each page image in the instruction template, append
the query-augmentation tokens to each query, and set the visual-token budget through
mm-processor-kwargs. Prefix caching and chunked prefill remain off for the GatedDeltaNet hybrid.pip install vllm1import torch
2from PIL import Image
3from vllm import LLM
4MODEL = "vultr/VultronRetrieverCore-Qwen3.5-4.5B"
5MAX_PIXELS = 1792 * 32 * 32 # max_num_visual_tokens * (patch_size 16 * merge_size 2)^2
6llm = LLM(
7 model=MODEL,
8 runner="pooling",
9 dtype="bfloat16",
10 enable_prefix_caching=False,
11 enable_chunked_prefill=False,
12 mm_processor_kwargs={"min_pixels": 65536, "max_pixels": MAX_PIXELS},
13)
14# ColQwen3.5 processor contract, applied client-side:
15IMAGE_PROMPT = ("<|im_start|>user\n<|vision_start|><|image_pad|><|vision_end|>"
16 "Describe the image.<|im_end|><|endoftext|>")
17def query_prompt(q): return q + "<|endoftext|>" * 10 # query augmentation
18images = [Image.open("page_0.png"), Image.open("page_1.png")]
19queries = ["What was Q3 revenue?", "Summarize the safety findings."]
20doc_out = llm.encode([{"prompt": IMAGE_PROMPT, "multi_modal_data": {"image": im}}
21 for im in images], pooling_task="token_embed")
22qry_out = llm.encode([query_prompt(q) for q in queries], pooling_task="token_embed")
23def mv(o): # one [num_tokens, 320] multi-vector per item, L2-normalized per token
24 t = torch.as_tensor(o.outputs.data, dtype=torch.float32)
25 return torch.nn.functional.normalize(t, p=2, dim=-1)
26docs, qrys = [mv(o) for o in doc_out], [mv(o) for o in qry_out]
27# late-interaction MaxSim: per query token take the best doc token, then sum
28scores = [[(q @ d.T).max(dim=-1).values.sum().item() for d in docs] for q in qrys]
29print(scores) # scores[i][j] = relevance of query i to page j1vllm serve vultr/VultronRetrieverCore-Qwen3.5-4.5B \
2 --runner pooling \
3 --no-enable-prefix-caching --no-enable-chunked-prefill \
4 --mm-processor-kwargs '{"min_pixels": 65536, "max_pixels": 1835008}'examples/pooling/score/colqwen3_5_rerank_online.py for the full online rerank flow.Qwen/Qwen3.5-4B (Apache 2.0); the upstream license and attribution are retained. The
training recipe and the assembled training dataset are not distributed in this repository.1@misc{vultronretrievercore2026,
2 title = {VultronRetrieverCore-Qwen3.5-4.5B: Mid-Tier Late-Interaction Visual Document Retrieval at 320 Dimensions},
3 author = {Georgiou, Athos (athrael-soju)},
4 year = {2026},
5 howpublished = {\url{https://huggingface.co/vultr/VultronRetrieverCore-Qwen3.5-4.5B}}
6}