tomaarsen HF Staff commited on
Commit
d905f99
·
verified ·
1 Parent(s): b492cfa

Add new MultiVectorEncoder model

Browse files
1_Dense/config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "in_features": 768,
3
+ "out_features": 1536,
4
+ "bias": false,
5
+ "activation_function": "torch.nn.modules.linear.Identity",
6
+ "module_input_name": "token_embeddings",
7
+ "module_output_name": "token_embeddings",
8
+ "use_residual": true
9
+ }
1_Dense/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5b21a25c38a742e510e671d0f07b30113bc073ea1564a9dd26bb71ebeaf19b31
3
+ size 9437360
2_Dense/config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "in_features": 1536,
3
+ "out_features": 768,
4
+ "bias": false,
5
+ "activation_function": "torch.nn.modules.linear.Identity",
6
+ "module_input_name": "token_embeddings",
7
+ "module_output_name": "token_embeddings",
8
+ "use_residual": true
9
+ }
2_Dense/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:875c0da032e30d06b6c14578c3f64c6da2f4c7b0860ba6a677cc04156ca0c5eb
3
+ size 9437360
3_Dense/config.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "in_features": 768,
3
+ "out_features": 128,
4
+ "bias": false,
5
+ "activation_function": "torch.nn.modules.linear.Identity",
6
+ "module_input_name": "token_embeddings",
7
+ "module_output_name": "token_embeddings"
8
+ }
3_Dense/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:387b61622add5ab3bedc80b057aa0444b9899269696e17181a7dbd7800d41bc4
3
+ size 393304
4_MultiVectorMask/config.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "skiplist_words": [
3
+ "!",
4
+ "\"",
5
+ "#",
6
+ "$",
7
+ "%",
8
+ "&",
9
+ "'",
10
+ "(",
11
+ ")",
12
+ "*",
13
+ "+",
14
+ ",",
15
+ "-",
16
+ ".",
17
+ "/",
18
+ ":",
19
+ ";",
20
+ "<",
21
+ "=",
22
+ ">",
23
+ "?",
24
+ "@",
25
+ "[",
26
+ "\\",
27
+ "]",
28
+ "^",
29
+ "_",
30
+ "`",
31
+ "{",
32
+ "|",
33
+ "}",
34
+ "~"
35
+ ],
36
+ "skiplist_tasks": [
37
+ "document"
38
+ ],
39
+ "keep_only_token_ids": null
40
+ }
5_Normalize/config.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "module_input_name": "token_embeddings",
3
+ "module_output_name": "token_embeddings"
4
+ }
README.md ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ tags:
3
+ - sentence-transformers
4
+ - multi-vector
5
+ - colbert
6
+ - late-interaction
7
+ pipeline_tag: feature-extraction
8
+ library_name: sentence-transformers
9
+ language: en
10
+ license: apache-2.0
11
+ base_model:
12
+ - chungimungi/GLInt
13
+ - lightonai/LateOn-regularized
14
+ base_model_relation: merge
15
+ ---
16
+
17
+ # ModernBERT-base-en-v1
18
+
19
+ This is a [Multi-Vector Encoder](https://www.sbert.net/docs/multi_vector_encoder/usage/usage.html) model created by a 50/50 linear merge of [chungimungi/GLInt](https://huggingface.co/chungimungi/GLInt) and [lightonai/LateOn-regularized](https://huggingface.co/lightonai/LateOn-regularized), using the [`MultiVectorEncoder.merge`](https://www.sbert.net/docs/package_reference/multi_vector_encoder/model.html#sentence_transformers.multi_vector_encoder.model.MultiVectorEncoder.merge) method from the [sentence-transformers](https://www.SBERT.net) library. It maps inputs to sequences of 128-dimensional token-level vectors and scores them with late interaction (MaxSim), useful for semantic search with late interaction.
20
+
21
+ The merged model scores above the average of its two parents on **9 of the 13 NanoBEIR datasets**, including **5 where it beats both**. It achieves a mean nDCG@10 of **0.7061**, compared with **0.6996** for GLInt and **0.6979** for LateOn-regularized, using the same inference settings for all three models.
22
+
23
+ It took a whopping 6 lines of code to merge the models and set the document length, and it took about 12 seconds to execute. See [Model Creation](#model-creation) for the full generation script.
24
+
25
+ ## Model Details
26
+
27
+ ### Model Description
28
+
29
+ - **Model Type:** Multi-Vector Encoder
30
+ - **Base models:** [GLInt](https://huggingface.co/chungimungi/GLInt) and [LateOn-regularized](https://huggingface.co/lightonai/LateOn-regularized)
31
+ - **Maximum Sequence Length:** 8192 tokens
32
+ - **Maximum Query Length:** 32 tokens
33
+ - **Maximum Document Length:** 8192 tokens
34
+ - **Output Dimensionality:** 128 dimensions
35
+ - **Similarity Function:** MaxSim
36
+ - **Supported Modality:** Text
37
+ - **Language:** English
38
+ - **License:** Apache-2.0
39
+
40
+ ### Model Sources
41
+
42
+ - **Documentation:** [Sentence Transformers Documentation](https://sbert.net)
43
+ - **Documentation:** [Multi-Vector Encoder Documentation](https://www.sbert.net/docs/multi_vector_encoder/usage/usage.html)
44
+ - **Repository:** [Sentence Transformers on GitHub](https://github.com/huggingface/sentence-transformers)
45
+ - **Hugging Face:** [Multi-Vector Encoders on Hugging Face](https://huggingface.co/models?library=sentence-transformers&other=multi-vector)
46
+
47
+ ### Full Model Architecture
48
+
49
+ ```
50
+ MultiVectorEncoder(
51
+ (0): Transformer({'transformer_task': 'feature-extraction', 'modality_config': {'text': {'method': 'forward', 'method_output_name': 'last_hidden_state'}}, 'module_output_name': 'token_embeddings', 'query_length': 32, 'document_length': 8192, 'architecture': 'ModernBertModel'})
52
+ (1): Dense({'in_features': 768, 'out_features': 1536, 'bias': False, 'activation_function': 'torch.nn.modules.linear.Identity', 'module_input_name': 'token_embeddings', 'module_output_name': 'token_embeddings', 'use_residual': True})
53
+ (2): Dense({'in_features': 1536, 'out_features': 768, 'bias': False, 'activation_function': 'torch.nn.modules.linear.Identity', 'module_input_name': 'token_embeddings', 'module_output_name': 'token_embeddings', 'use_residual': True})
54
+ (3): Dense({'in_features': 768, 'out_features': 128, 'bias': False, 'activation_function': 'torch.nn.modules.linear.Identity', 'module_input_name': 'token_embeddings', 'module_output_name': 'token_embeddings'})
55
+ (4): MultiVectorMask({'skiplist_words': ['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~'], 'skiplist_tasks': ['document'], 'keep_only_token_ids': None})
56
+ (5): Normalize({'module_input_name': 'token_embeddings', 'module_output_name': 'token_embeddings'})
57
+ )
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ ### Direct Usage (Sentence Transformers)
63
+
64
+ First install the Sentence Transformers library:
65
+
66
+ ```bash
67
+ pip install -U sentence-transformers
68
+ ```
69
+ Then you can load this model and run inference.
70
+ ```python
71
+ from sentence_transformers import MultiVectorEncoder
72
+
73
+ model = MultiVectorEncoder("multi-vector-encoder/ModernBERT-base-en-v1")
74
+ queries = [
75
+ 'Which planet is known as the Red Planet?',
76
+ ]
77
+ documents = [
78
+ "Venus is often called Earth's twin because of its similar size and proximity.",
79
+ 'Mars, known for its reddish appearance, is often referred to as the Red Planet.',
80
+ 'Saturn, famous for its rings, is sometimes mistaken for the Red Planet.',
81
+ ]
82
+ query_embeddings = model.encode_query(queries)
83
+ document_embeddings = model.encode_document(documents)
84
+ print(query_embeddings[0].shape, document_embeddings[0].shape)
85
+ # (12, 128) (18, 128)
86
+
87
+ # Get the MaxSim similarity scores
88
+ similarities = model.similarity(query_embeddings, document_embeddings)
89
+ print(similarities)
90
+ # tensor([[11.4814, 11.6525, 11.6232]])
91
+ ```
92
+
93
+ ## Evaluation
94
+
95
+ ### Metrics
96
+
97
+ #### NanoBEIR
98
+
99
+ * Dataset: [NanoBEIR-en](https://huggingface.co/datasets/sentence-transformers/NanoBEIR-en)
100
+ * Evaluated with `MultiVectorNanoBEIREvaluator` on all 13 datasets.
101
+ * Query length: 32 tokens. Document length: 8192 tokens (expanded from 300 for GLInt and LateOn-regularized).
102
+ * Metric: nDCG@10. The mean is unweighted across datasets.
103
+
104
+ The parent models were evaluated with the same prompts and length limits.
105
+
106
+ | Dataset | ModernBERT-base-en-v1 | GLInt | LateOn-regularized |
107
+ | --- | --- | --- | --- |
108
+ | msmarco | <u>0.736155</u> | 0.728477 | 0.707793 |
109
+ | nq | <u>0.818848</u> | 0.818032 | 0.782732 |
110
+ | fiqa2018 | <u>0.640317</u> | 0.625973 | 0.625546 |
111
+ | nfcorpus | 0.393756 | <u>0.399912</u> | 0.391630 |
112
+ | scidocs | 0.435285 | 0.435472 | <u>0.444901</u> |
113
+ | arguana | <u>0.588440</u> | 0.569680 | 0.561172 |
114
+ | dbpedia | 0.703868 | <u>0.709176</u> | 0.678083 |
115
+ | quoraretrieval | <u>0.990127</u> | 0.983948 | 0.986797 |
116
+ | touche2020 | 0.692082 | <u>0.696390</u> | 0.686696 |
117
+ | climatefever | 0.484580 | 0.418405 | <u>0.521409</u> |
118
+ | fever | 0.966278 | <u>0.969763</u> | 0.966278 |
119
+ | hotpotqa | 0.930661 | <u>0.934504</u> | 0.917731 |
120
+ | scifact | 0.799062 | <u>0.804524</u> | 0.802028 |
121
+ | **mean** | **<u>0.706112</u>** | **0.699558** | **0.697907** |
122
+
123
+ ## Model Creation
124
+
125
+ The backbone and all three projection layers were merged in fp32 with equal weights from [GLInt](https://huggingface.co/chungimungi/GLInt) and [LateOn-regularized](https://huggingface.co/lightonai/LateOn-regularized), without any training.
126
+
127
+ This is all it took:
128
+
129
+ ```python
130
+ # pip install "sentence-transformers[merge]"
131
+ from sentence_transformers import MultiVectorEncoder
132
+
133
+ # Load the GLInt and LateOn-regularized models,
134
+ # matching the latter's special token config
135
+ glint = MultiVectorEncoder(
136
+ "chungimungi/GLInt",
137
+ config_kwargs={
138
+ "bos_token_id": 50281,
139
+ "eos_token_id": 50282,
140
+ "pad_token_id": 50283,
141
+ },
142
+ processor_kwargs={"model_max_length": 8192, "max_length": 8192},
143
+ )
144
+ lateon = MultiVectorEncoder("lightonai/LateOn-regularized")
145
+
146
+ # Merge using simple 50/50 linear
147
+ model = MultiVectorEncoder.merge(
148
+ [glint, lateon],
149
+ method="linear",
150
+ parameters={"weight": [0.5, 0.5]},
151
+ )
152
+ # Increase the document length from 300 to 8192 tokens
153
+ model[0].document_length = 8192
154
+ # And save it for reuse
155
+ model.save_pretrained("ModernBERT-base-en-v1")
156
+ ```
157
+
158
+ ### Framework Versions
159
+
160
+ - Python: 3.12.3
161
+ - Sentence Transformers: 6.2.0
162
+ - Transformers: 5.4.0
163
+ - PyTorch: 2.11.0+cu128
164
+ - Accelerate: 1.13.0
165
+ - Datasets: 4.8.5
166
+ - Tokenizers: 0.22.2
167
+
168
+ ## Citation
169
+
170
+ ### BibTeX
171
+
172
+ #### LateOn Regularization
173
+
174
+ ```bibtex
175
+ @misc{chaffin2026lateonregularization,
176
+ title={Party is over: regularizing ColBERT models to fix efficient ANN methods},
177
+ author={Chaffin, Antoine},
178
+ year={2026},
179
+ howpublished={\url{https://huggingface.co/blog/lightonai/lateon-regularization}},
180
+ }
181
+ ```
182
+
183
+ #### GLInt
184
+
185
+ ```bibtex
186
+ @misc{aarush2026glint,
187
+ title={GLInt: Geometry-Matched Hard Negatives for Late-Interaction Retrieval},
188
+ author={Aarush},
189
+ year={2026},
190
+ howpublished={\url{https://huggingface.co/blog/chungimungi/glint}},
191
+ }
192
+ ```
193
+
194
+ ### Mergekit
195
+
196
+ ```bibtex
197
+ @inproceedings{goddard-etal-2024-arcees,
198
+ title = "Arcee{'}s {M}erge{K}it: A Toolkit for Merging Large Language Models",
199
+ author = "Goddard, Charles and Siriwardhana, Shamane and Ehghaghi, Malikeh and Meyers, Luke and Karpukhin, Vladimir and Benedict, Brian and McQuade, Mark and Solawetz, Jacob",
200
+ editor = "Dernoncourt, Franck and Preo{\c{t}}iuc-Pietro, Daniel and Shimorina, Anastasia",
201
+ booktitle = "Proceedings of the 2024 Conference on Empirical Methods in Natural Language Processing: Industry Track",
202
+ month = nov,
203
+ year = "2024",
204
+ address = "Miami, Florida, US",
205
+ publisher = "Association for Computational Linguistics",
206
+ url = "https://aclanthology.org/2024.emnlp-industry.36",
207
+ doi = "10.18653/v1/2024.emnlp-industry.36",
208
+ pages = "477--485",
209
+ }
210
+ ```
config.json ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "ModernBertModel"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 50281,
8
+ "classifier_activation": "gelu",
9
+ "classifier_bias": false,
10
+ "classifier_dropout": 0.0,
11
+ "classifier_pooling": "mean",
12
+ "cls_token_id": 50281,
13
+ "decoder_bias": true,
14
+ "deterministic_flash_attn": false,
15
+ "dtype": "float32",
16
+ "embedding_dropout": 0.0,
17
+ "eos_token_id": 50282,
18
+ "global_attn_every_n_layers": 3,
19
+ "gradient_checkpointing": false,
20
+ "hidden_activation": "gelu",
21
+ "hidden_size": 768,
22
+ "initializer_cutoff_factor": 2.0,
23
+ "initializer_range": 0.02,
24
+ "intermediate_size": 1152,
25
+ "layer_norm_eps": 1e-05,
26
+ "layer_types": [
27
+ "full_attention",
28
+ "sliding_attention",
29
+ "sliding_attention",
30
+ "full_attention",
31
+ "sliding_attention",
32
+ "sliding_attention",
33
+ "full_attention",
34
+ "sliding_attention",
35
+ "sliding_attention",
36
+ "full_attention",
37
+ "sliding_attention",
38
+ "sliding_attention",
39
+ "full_attention",
40
+ "sliding_attention",
41
+ "sliding_attention",
42
+ "full_attention",
43
+ "sliding_attention",
44
+ "sliding_attention",
45
+ "full_attention",
46
+ "sliding_attention",
47
+ "sliding_attention",
48
+ "full_attention"
49
+ ],
50
+ "local_attention": 128,
51
+ "max_position_embeddings": 8192,
52
+ "mlp_bias": false,
53
+ "mlp_dropout": 0.0,
54
+ "model_type": "modernbert",
55
+ "norm_bias": false,
56
+ "norm_eps": 1e-05,
57
+ "num_attention_heads": 12,
58
+ "num_hidden_layers": 22,
59
+ "pad_token_id": 50283,
60
+ "position_embedding_type": "absolute",
61
+ "repad_logits_with_grad": false,
62
+ "rope_parameters": {
63
+ "full_attention": {
64
+ "rope_theta": 160000.0,
65
+ "rope_type": "default"
66
+ },
67
+ "sliding_attention": {
68
+ "rope_theta": 10000.0,
69
+ "rope_type": "default"
70
+ }
71
+ },
72
+ "sep_token_id": 50282,
73
+ "sparse_pred_ignore_index": -100,
74
+ "sparse_prediction": false,
75
+ "tie_word_embeddings": true,
76
+ "transformers_version": "5.21.0.dev0",
77
+ "vocab_size": 50370
78
+ }
config_sentence_transformers.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "__version__": {
3
+ "pytorch": "2.10.0+cu128",
4
+ "sentence_transformers": "6.3.0.dev0",
5
+ "transformers": "5.21.0.dev0"
6
+ },
7
+ "default_prompt_name": null,
8
+ "model_type": "MultiVectorEncoder",
9
+ "prompts": {
10
+ "document": "[D] ",
11
+ "query": "[Q] "
12
+ },
13
+ "similarity_fn_name": "maxsim"
14
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6f0ac605ba5687101f96281169c8b4f963a73d4f7aac2b8225de2040c3fb17d0
3
+ size 596076280
modules.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Dense",
18
+ "type": "sentence_transformers.base.modules.dense.Dense"
19
+ },
20
+ {
21
+ "idx": 3,
22
+ "name": "3",
23
+ "path": "3_Dense",
24
+ "type": "sentence_transformers.base.modules.dense.Dense"
25
+ },
26
+ {
27
+ "idx": 4,
28
+ "name": "4",
29
+ "path": "4_MultiVectorMask",
30
+ "type": "sentence_transformers.multi_vector_encoder.modules.multi_vector_mask.MultiVectorMask"
31
+ },
32
+ {
33
+ "idx": 5,
34
+ "name": "5",
35
+ "path": "5_Normalize",
36
+ "type": "sentence_transformers.base.modules.normalize.Normalize"
37
+ }
38
+ ]
sentence_bert_config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "transformer_task": "feature-extraction",
3
+ "modality_config": {
4
+ "text": {
5
+ "method": "forward",
6
+ "method_output_name": "last_hidden_state"
7
+ }
8
+ },
9
+ "module_output_name": "token_embeddings",
10
+ "query_length": 32,
11
+ "document_length": 8192
12
+ }
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "clean_up_tokenization_spaces": true,
4
+ "cls_token": "[CLS]",
5
+ "is_local": true,
6
+ "local_files_only": false,
7
+ "mask_token": "[MASK]",
8
+ "max_length": 8192,
9
+ "model_input_names": [
10
+ "input_ids",
11
+ "attention_mask"
12
+ ],
13
+ "model_max_length": 8192,
14
+ "pad_to_multiple_of": null,
15
+ "pad_token": "[MASK]",
16
+ "pad_token_type_id": 0,
17
+ "padding_side": "right",
18
+ "sep_token": "[SEP]",
19
+ "stride": 0,
20
+ "tokenizer_class": "TokenizersBackend",
21
+ "truncation_side": "right",
22
+ "truncation_strategy": "longest_first",
23
+ "unk_token": "[UNK]"
24
+ }