Visual Document Retrieval
Safetensors
sentence-transformers
colpali-engine
qwen3_5
vision-language
colbert
late-interaction
multi-vector
vidore
document-retrieval
multimodal
Instructions to use tencent/EVIE-8B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- sentence-transformers
How to use tencent/EVIE-8B with sentence-transformers:
from sentence_transformers import SentenceTransformer model = SentenceTransformer("tencent/EVIE-8B") sentences = [ "The weather is lovely today.", "It's so sunny outside!", "He drove to the stadium." ] embeddings = model.encode(sentences) similarities = model.similarity(embeddings, embeddings) print(similarities.shape) # [3, 3] - Notebooks
- Google Colab
- Kaggle
Add Sentence Transformers MultiVectorEncoder integration
Browse files- 1_Dense/config.json +8 -0
- 1_Dense/model.safetensors +3 -0
- 2_Normalize/config.json +4 -0
- 3_MultiVectorMask/config.json +3 -0
- README.md +53 -2
- additional_chat_templates/sentence_transformers.jinja +19 -0
- config_sentence_transformers.json +9 -0
- modules.json +26 -0
- processor_config.json +1 -1
- sentence_bert_config.json +30 -0
- tokenizer_config.json +2 -1
1_Dense/config.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"in_features": 4096,
|
| 3 |
+
"out_features": 4096,
|
| 4 |
+
"bias": true,
|
| 5 |
+
"activation_function": "torch.nn.modules.linear.Identity",
|
| 6 |
+
"module_input_name": "token_embeddings",
|
| 7 |
+
"module_output_name": "token_embeddings"
|
| 8 |
+
}
|
1_Dense/model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5b0dc39705e9cfd9610dd3cdeaa0c6ac0540c5780e5f08d860e259f4854c887f
|
| 3 |
+
size 67125416
|
2_Normalize/config.json
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"module_input_name": "token_embeddings",
|
| 3 |
+
"module_output_name": "token_embeddings"
|
| 4 |
+
}
|
3_MultiVectorMask/config.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"skiplist_words": []
|
| 3 |
+
}
|
README.md
CHANGED
|
@@ -13,6 +13,7 @@ tags:
|
|
| 13 |
- vidore
|
| 14 |
- document-retrieval
|
| 15 |
- multimodal
|
|
|
|
| 16 |
datasets:
|
| 17 |
- vidore/vidore_benchmark
|
| 18 |
- vidore/vidore_benchmark_v2
|
|
@@ -165,7 +166,9 @@ Protocol `paired-all-pages-dedup+process_queries+ndcg2r-20260827` ($\text{MVT} =
|
|
| 165 |
|
| 166 |
## ⚡ Quick Start
|
| 167 |
|
| 168 |
-
###
|
|
|
|
|
|
|
| 169 |
|
| 170 |
```bash
|
| 171 |
git clone https://github.com/Tencent/EVIE.git
|
|
@@ -174,7 +177,7 @@ pip install -r requirements.txt
|
|
| 174 |
export PYTHONPATH="$(pwd)/colpali${PYTHONPATH:+:$PYTHONPATH}"
|
| 175 |
```
|
| 176 |
|
| 177 |
-
### Python Inference
|
| 178 |
|
| 179 |
```python
|
| 180 |
import torch
|
|
@@ -210,6 +213,52 @@ scores = processor.score(query_embeddings, image_embeddings)
|
|
| 210 |
print("Late-interaction MaxSim Relevance Score:", scores)
|
| 211 |
```
|
| 212 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
---
|
| 214 |
|
| 215 |
## 📂 Repository Layout
|
|
@@ -218,6 +267,8 @@ print("Late-interaction MaxSim Relevance Score:", scores)
|
|
| 218 |
Evie-8B/
|
| 219 |
├── model.safetensors # EVIE-8B weights (safetensors)
|
| 220 |
├── config.json # Model configuration (4096D)
|
|
|
|
|
|
|
| 221 |
├── infer.py # Standalone inference & scoring CLI
|
| 222 |
├── colpali/ # ColQwen3.5 inference engine
|
| 223 |
├── code/shared/ # 138-task eval harness
|
|
|
|
| 13 |
- vidore
|
| 14 |
- document-retrieval
|
| 15 |
- multimodal
|
| 16 |
+
- sentence-transformers
|
| 17 |
datasets:
|
| 18 |
- vidore/vidore_benchmark
|
| 19 |
- vidore/vidore_benchmark_v2
|
|
|
|
| 166 |
|
| 167 |
## ⚡ Quick Start
|
| 168 |
|
| 169 |
+
### ColPali Engine
|
| 170 |
+
|
| 171 |
+
#### Installation
|
| 172 |
|
| 173 |
```bash
|
| 174 |
git clone https://github.com/Tencent/EVIE.git
|
|
|
|
| 177 |
export PYTHONPATH="$(pwd)/colpali${PYTHONPATH:+:$PYTHONPATH}"
|
| 178 |
```
|
| 179 |
|
| 180 |
+
#### Python Inference
|
| 181 |
|
| 182 |
```python
|
| 183 |
import torch
|
|
|
|
| 213 |
print("Late-interaction MaxSim Relevance Score:", scores)
|
| 214 |
```
|
| 215 |
|
| 216 |
+
### Sentence Transformers
|
| 217 |
+
|
| 218 |
+
Load EVIE with [Sentence Transformers](https://www.sbert.net/) to encode queries and document images and compute MaxSim scores. Bidirectional attention is configured automatically.
|
| 219 |
+
|
| 220 |
+
```bash
|
| 221 |
+
pip install -U "sentence-transformers[image]>=6.0.0"
|
| 222 |
+
```
|
| 223 |
+
|
| 224 |
+
```python
|
| 225 |
+
from sentence_transformers import MultiVectorEncoder
|
| 226 |
+
|
| 227 |
+
model = MultiVectorEncoder("tencent/EVIE-8B")
|
| 228 |
+
|
| 229 |
+
queries = [
|
| 230 |
+
"What is the variable represented on the y-axis of the graph?",
|
| 231 |
+
"Total outlay is maximum in which year?",
|
| 232 |
+
]
|
| 233 |
+
documents = [
|
| 234 |
+
"https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/doc1.jpg",
|
| 235 |
+
"https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/doc2.jpg",
|
| 236 |
+
"https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/doc3.jpg",
|
| 237 |
+
"https://huggingface.co/datasets/sentence-transformers/example-documents/resolve/main/doc4.jpg",
|
| 238 |
+
]
|
| 239 |
+
|
| 240 |
+
query_embeddings = model.encode_query(queries)
|
| 241 |
+
document_embeddings = model.encode_document(documents, batch_size=1)
|
| 242 |
+
print(query_embeddings[0].shape, document_embeddings[0].shape)
|
| 243 |
+
# torch.Size([23, 4096]) torch.Size([3161, 4096])
|
| 244 |
+
|
| 245 |
+
scores = model.similarity(query_embeddings, document_embeddings)
|
| 246 |
+
print(scores)
|
| 247 |
+
# tensor([[14.3594, 6.1758, 4.5137, 3.2979],
|
| 248 |
+
# [ 1.8079, 10.9180, 1.9668, 1.9541]])
|
| 249 |
+
```
|
| 250 |
+
|
| 251 |
+
Documents can be URLs, local image paths, or `PIL.Image` objects. The output contains 4096-dimensional token embeddings. Scores can vary slightly with dtype and attention backend.
|
| 252 |
+
|
| 253 |
+
The default page budget allows up to 16,384 visual tokens. Encoding images one at a time reduces peak memory use. To use the 1,024-token budget from the evaluation protocol above, set the image processor's pixel budget:
|
| 254 |
+
|
| 255 |
+
```python
|
| 256 |
+
model = MultiVectorEncoder(
|
| 257 |
+
"tencent/EVIE-8B",
|
| 258 |
+
processor_kwargs={"size": {"longest_edge": 1024 * 32 * 32, "shortest_edge": 65536}},
|
| 259 |
+
)
|
| 260 |
+
```
|
| 261 |
+
|
| 262 |
---
|
| 263 |
|
| 264 |
## 📂 Repository Layout
|
|
|
|
| 267 |
Evie-8B/
|
| 268 |
├── model.safetensors # EVIE-8B weights (safetensors)
|
| 269 |
├── config.json # Model configuration (4096D)
|
| 270 |
+
├── 1_Dense/ # Sentence Transformers 4096D projection
|
| 271 |
+
├── modules.json # MultiVectorEncoder module graph
|
| 272 |
├── infer.py # Standalone inference & scoring CLI
|
| 273 |
├── colpali/ # ColQwen3.5 inference engine
|
| 274 |
├── code/shared/ # 138-task eval harness
|
additional_chat_templates/sentence_transformers.jinja
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- for message in messages -%}
|
| 2 |
+
{%- set ns = namespace(has_image=false, text='') -%}
|
| 3 |
+
{%- if message['content'] is string -%}
|
| 4 |
+
{%- set ns.text = message['content'] -%}
|
| 5 |
+
{%- else -%}
|
| 6 |
+
{%- for item in message['content'] -%}
|
| 7 |
+
{%- if 'image' in item or 'image_url' in item or item.type == 'image' -%}
|
| 8 |
+
{%- set ns.has_image = true -%}
|
| 9 |
+
{%- elif 'text' in item -%}
|
| 10 |
+
{%- set ns.text = ns.text + item.text -%}
|
| 11 |
+
{%- endif -%}
|
| 12 |
+
{%- endfor -%}
|
| 13 |
+
{%- endif -%}
|
| 14 |
+
{%- if ns.has_image -%}
|
| 15 |
+
{{- '<|im_start|>user\n<|vision_start|><|image_pad|><|vision_end|>Describe the image.<|im_end|><|endoftext|>' -}}
|
| 16 |
+
{%- else -%}
|
| 17 |
+
{{- ns.text + '<|endoftext|>' * 10 -}}
|
| 18 |
+
{%- endif -%}
|
| 19 |
+
{%- endfor -%}
|
config_sentence_transformers.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"__version__": {
|
| 3 |
+
"sentence_transformers": "6.0.0"
|
| 4 |
+
},
|
| 5 |
+
"model_type": "MultiVectorEncoder",
|
| 6 |
+
"similarity_fn_name": "maxsim",
|
| 7 |
+
"prompts": {},
|
| 8 |
+
"default_prompt_name": null
|
| 9 |
+
}
|
modules.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"idx": 0,
|
| 4 |
+
"name": "0",
|
| 5 |
+
"path": "",
|
| 6 |
+
"type": "sentence_transformers.base.modules.transformer.Transformer"
|
| 7 |
+
},
|
| 8 |
+
{
|
| 9 |
+
"idx": 1,
|
| 10 |
+
"name": "1",
|
| 11 |
+
"path": "1_Dense",
|
| 12 |
+
"type": "sentence_transformers.base.modules.dense.Dense"
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"idx": 2,
|
| 16 |
+
"name": "2",
|
| 17 |
+
"path": "2_Normalize",
|
| 18 |
+
"type": "sentence_transformers.sentence_transformer.modules.normalize.Normalize"
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
"idx": 3,
|
| 22 |
+
"name": "3",
|
| 23 |
+
"path": "3_MultiVectorMask",
|
| 24 |
+
"type": "sentence_transformers.multi_vector_encoder.modules.multi_vector_mask.MultiVectorMask"
|
| 25 |
+
}
|
| 26 |
+
]
|
processor_config.json
CHANGED
|
@@ -25,7 +25,7 @@
|
|
| 25 |
},
|
| 26 |
"temporal_patch_size": 2
|
| 27 |
},
|
| 28 |
-
"processor_class": "
|
| 29 |
"video_processor": {
|
| 30 |
"do_convert_rgb": true,
|
| 31 |
"do_normalize": true,
|
|
|
|
| 25 |
},
|
| 26 |
"temporal_patch_size": 2
|
| 27 |
},
|
| 28 |
+
"processor_class": "Qwen3VLProcessor",
|
| 29 |
"video_processor": {
|
| 30 |
"do_convert_rgb": true,
|
| 31 |
"do_normalize": true,
|
sentence_bert_config.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"transformer_task": "feature-extraction",
|
| 3 |
+
"modality_config": {
|
| 4 |
+
"text": {
|
| 5 |
+
"method": "forward",
|
| 6 |
+
"method_output_name": "last_hidden_state"
|
| 7 |
+
},
|
| 8 |
+
"image": {
|
| 9 |
+
"method": "forward",
|
| 10 |
+
"method_output_name": "last_hidden_state"
|
| 11 |
+
},
|
| 12 |
+
"message": {
|
| 13 |
+
"method": "forward",
|
| 14 |
+
"method_output_name": "last_hidden_state",
|
| 15 |
+
"format": "structured"
|
| 16 |
+
}
|
| 17 |
+
},
|
| 18 |
+
"module_output_name": "token_embeddings",
|
| 19 |
+
"unpad_inputs": false,
|
| 20 |
+
"config_kwargs": {
|
| 21 |
+
"text_config": {
|
| 22 |
+
"is_causal": false
|
| 23 |
+
}
|
| 24 |
+
},
|
| 25 |
+
"processing_kwargs": {
|
| 26 |
+
"chat_template": {
|
| 27 |
+
"chat_template": "sentence_transformers"
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
}
|
tokenizer_config.json
CHANGED
|
@@ -21,7 +21,8 @@
|
|
| 21 |
},
|
| 22 |
"pad_token": "<|endoftext|>",
|
| 23 |
"pretokenize_regex": "(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\\r\\n\\p{L}\\p{N}]?[\\p{L}\\p{M}]+|\\p{N}| ?[^\\s\\p{L}\\p{M}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+",
|
| 24 |
-
"processor_class": "
|
|
|
|
| 25 |
"split_special_tokens": false,
|
| 26 |
"tokenizer_class": "Qwen2Tokenizer",
|
| 27 |
"unk_token": null,
|
|
|
|
| 21 |
},
|
| 22 |
"pad_token": "<|endoftext|>",
|
| 23 |
"pretokenize_regex": "(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\\r\\n\\p{L}\\p{N}]?[\\p{L}\\p{M}]+|\\p{N}| ?[^\\s\\p{L}\\p{M}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+",
|
| 24 |
+
"processor_class": "Qwen3VLProcessor",
|
| 25 |
+
"padding_side": "left",
|
| 26 |
"split_special_tokens": false,
|
| 27 |
"tokenizer_class": "Qwen2Tokenizer",
|
| 28 |
"unk_token": null,
|