Integrate with Sentence Transformers v5.4

#3
by tomaarsen HF Staff - opened
1_Pooling/config.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "embedding_dimension": 3584,
3
+ "pooling_mode": "lasttoken",
4
+ "include_prompt": true
5
+ }
README.md CHANGED
@@ -11,7 +11,12 @@ base_model:
11
  - Qwen/Qwen2.5-Omni-7B
12
  - Tevatron/Qwen2.5-Omni-7B-Thinker
13
  pipeline_tag: visual-document-retrieval
14
- library_name: peft
 
 
 
 
 
15
  ---
16
  # Tevatron/OmniEmbed-v0.1
17
 
@@ -37,7 +42,110 @@ OmniEmbed achieves strong performance, comparable to models specifically optimiz
37
 
38
  ---
39
 
40
- ### Usage
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  ```python
42
  # Import Library, Load Model and Processor
43
  import torch
@@ -82,7 +190,7 @@ def encode_message(message):
82
  return reps
83
  ```
84
 
85
- ### 🎬 Video Retrieval
86
  ```python
87
  example_query = 'Query: How to cook Mapo Tofu?'
88
  example_video_1 = "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/mapo_tofu.mp4"
@@ -95,9 +203,12 @@ sim1 = torch.cosine_similarity(encode_message(query), encode_message(video_1))
95
  sim2 = torch.cosine_similarity(encode_message(query), encode_message(video_2))
96
 
97
  print("Similarities:", sim1.item(), sim2.item())
 
 
 
98
  ```
99
 
100
- ### 🎵 Audio Retrieval
101
  ```python
102
  example_query = 'Query: A light piano piece'
103
  example_audio_1 = "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/joe_hisaishi_summer.mp3"
@@ -110,9 +221,10 @@ sim1 = torch.cosine_similarity(encode_message(query), encode_message(audio_1))
110
  sim2 = torch.cosine_similarity(encode_message(query), encode_message(audio_2))
111
 
112
  print("Similarities:", sim1.item(), sim2.item())
 
113
  ```
114
 
115
- ### 📈 Image Document Retrieval (Image, Chart, PDF)
116
  ```python
117
  example_query = 'Query: How many input modality does Qwen2.5-Omni support?'
118
  example_image_1 = "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/qwen2.5omni_hgf.png"
@@ -125,9 +237,10 @@ sim1 = torch.cosine_similarity(encode_message(query), encode_message(image_1))
125
  sim2 = torch.cosine_similarity(encode_message(query), encode_message(image_2))
126
 
127
  print("Similarities:", sim1.item(), sim2.item())
 
128
  ```
129
 
130
- ### 🌍 Multilingual Text Retrieval
131
  ```python
132
  example_query = 'Query: 氧气在空气中占比多少?'
133
  example_text_1 = "空气是指大气层中由不同气体和各类飘浮在其中的固体与液体颗粒(大气颗粒与气溶胶)所组成的气态混合物。地球大气层的空气主要由78.1%的氮气、20.9%氧气、0.9%的氩气和1~4%的水蒸气组成,其成分并不是固定的,随着高度、气压、温度的改变和对流情况不同,局部空气的组成比例也会改变。空气在大气层(特别是对流层)中的流动形成了风和曳流、气旋、龙卷等自然现象,而空气中飘浮的颗粒则形成了云、雾、霾和沙尘暴等短期天气情况。空气在海洋和陆地之间跨区域流动所承载的湿度和热能传导也是水循环和气候变率与变化的关键一环。"
@@ -140,6 +253,7 @@ sim1 = torch.cosine_similarity(encode_message(query), encode_message(text_1))
140
  sim2 = torch.cosine_similarity(encode_message(query), encode_message(text_2))
141
 
142
  print("Similarities:", sim1.item(), sim2.item())
 
143
  ```
144
 
145
  ## Data & Training
 
11
  - Qwen/Qwen2.5-Omni-7B
12
  - Tevatron/Qwen2.5-Omni-7B-Thinker
13
  pipeline_tag: visual-document-retrieval
14
+ library_name: sentence-transformers
15
+ tags:
16
+ - sentence-transformers
17
+ - peft
18
+ - multimodal
19
+ - feature-extraction
20
  ---
21
  # Tevatron/OmniEmbed-v0.1
22
 
 
42
 
43
  ---
44
 
45
+ ## Usage
46
+
47
+ ### Using Sentence Transformers
48
+
49
+ Install Sentence Transformers with the multimodal extras (for image, audio, and video support):
50
+
51
+ ```bash
52
+ pip install "sentence_transformers[image,audio,video]" "transformers>=5.6.0" "peft>=0.19.0"
53
+ ```
54
+
55
+ ```python
56
+ import torch
57
+ from sentence_transformers import SentenceTransformer
58
+
59
+ model = SentenceTransformer(
60
+ "Tevatron/OmniEmbed-v0.1",
61
+ model_kwargs={
62
+ "torch_dtype": torch.bfloat16,
63
+ "attn_implementation": "flash_attention_2", # pip install kernels; recommended but not mandatory
64
+ },
65
+ )
66
+ ```
67
+
68
+ #### 🎬 Video Retrieval
69
+ ```python
70
+ # For video on smaller GPUs, cap the processor up front:
71
+ model[0].processing_kwargs.update({
72
+ "video": {"max_pixels": 64 * 28 * 28, "do_sample_frames": True, "fps": 1},
73
+ })
74
+
75
+ example_query = "How to cook Mapo Tofu?"
76
+ example_videos = [
77
+ "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/mapo_tofu.mp4",
78
+ "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/zhajiang_noodle.mp4",
79
+ ]
80
+
81
+ query_embedding = model.encode_query(example_query)
82
+ document_embeddings = model.encode_document(example_videos, batch_size=1)
83
+ print(model.similarity(query_embedding, document_embeddings))
84
+ # tensor([[0.4318, 0.2858]])
85
+ ```
86
+
87
+ #### 🎵 Audio Retrieval
88
+ ```python
89
+ example_query = "A light piano piece"
90
+ example_audios = [
91
+ "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/joe_hisaishi_summer.mp3",
92
+ "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/jay_chou_superman_cant_fly.mp3",
93
+ ]
94
+
95
+ query_embedding = model.encode_query(example_query)
96
+ document_embeddings = model.encode_document(example_audios, batch_size=1)
97
+ print(model.similarity(query_embedding, document_embeddings))
98
+ # tensor([[0.2734, 0.2165]])
99
+ ```
100
+
101
+ #### 📈 Image Document Retrieval (Image, Chart, PDF)
102
+ ```python
103
+ example_query = "How many input modality does Qwen2.5-Omni support?"
104
+ example_images = [
105
+ "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/qwen2.5omni_hgf.png",
106
+ "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/llama4_hgf.png",
107
+ ]
108
+
109
+ query_embedding = model.encode_query(example_query)
110
+ document_embeddings = model.encode_document(example_images, batch_size=1)
111
+ print(model.similarity(query_embedding, document_embeddings))
112
+ # tensor([[0.4682, 0.2956]])
113
+ ```
114
+
115
+ #### 🌍 Multilingual Text Retrieval
116
+ ```python
117
+ example_query = "氧气在空气中占比多少?"
118
+ example_texts = [
119
+ "空气是指大气层中由不同气体和各类飘浮在其中的固体与液体颗粒(大气颗粒与气溶胶)所组成的气态混合物。地球大气层的空气主要由78.1%的氮气、20.9%氧气、0.9%的氩气和1~4%的水蒸气组成,其成分并不是固定的,随着高度、气压、温度的改变和对流情况不同,局部空气的组成比例也会改变。空气在大气层(特别是对流层)中的流动形成了风和曳流、气旋、龙卷等自然现象,而空气中飘浮的颗粒则形成了云、雾、霾和沙尘暴等短期天气情况。空气在海洋和陆地之间跨区域流动所承载的湿度和热能传导也是水循环和气候变率与变化的关键一环。",
120
+ "水(化学式:H2O)是一种无机化合物,在常温且无杂质中是无色[1]无味不导电的透明液体,也会通过蒸发产生气态的水蒸气(这种蒸发可以发生在任何温度下,同时取决于与空气接触的表面积和湿度差)。在标准大气压下,水的凝固点是0 °C(32 °F;273 K),沸点是100 °C(212 °F;373 K)。",
121
+ ]
122
+
123
+ query_embedding = model.encode_query(example_query)
124
+ document_embeddings = model.encode_document(example_texts, batch_size=1)
125
+ print(model.similarity(query_embedding, document_embeddings))
126
+ # tensor([[0.3371, 0.2496]])
127
+ ```
128
+
129
+ #### 🧩 Multimodal Inputs
130
+
131
+ To embed a document that combines multiple modalities, pass a dict with any combination of `"text"`, `"image"`, `"audio"`, and `"video"` keys instead of a single path or string:
132
+
133
+ ```python
134
+ documents = [
135
+ {
136
+ "text": "A cooking tutorial for Mapo Tofu",
137
+ "video": "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/mapo_tofu.mp4",
138
+ },
139
+ {
140
+ "image": "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/qwen2.5omni_hgf.png",
141
+ "audio": "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/joe_hisaishi_summer.mp3",
142
+ },
143
+ ]
144
+ document_embeddings = model.encode_document(documents, batch_size=1)
145
+ ```
146
+
147
+ ### Using Transformers
148
+
149
  ```python
150
  # Import Library, Load Model and Processor
151
  import torch
 
190
  return reps
191
  ```
192
 
193
+ #### 🎬 Video Retrieval
194
  ```python
195
  example_query = 'Query: How to cook Mapo Tofu?'
196
  example_video_1 = "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/mapo_tofu.mp4"
 
203
  sim2 = torch.cosine_similarity(encode_message(query), encode_message(video_2))
204
 
205
  print("Similarities:", sim1.item(), sim2.item())
206
+ # Video similarities: 0.408203125 0.283203125
207
+ # Defaults produce ~30 GB of video activations; on smaller GPUs add e.g.
208
+ # `"max_pixels": 64*28*28, "fps": 1, "min_pixels": 16*28*28` to each video dict.
209
  ```
210
 
211
+ #### 🎵 Audio Retrieval
212
  ```python
213
  example_query = 'Query: A light piano piece'
214
  example_audio_1 = "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/joe_hisaishi_summer.mp3"
 
221
  sim2 = torch.cosine_similarity(encode_message(query), encode_message(audio_2))
222
 
223
  print("Similarities:", sim1.item(), sim2.item())
224
+ # Audio similarities: 0.275390625 0.2353515625
225
  ```
226
 
227
+ #### 📈 Image Document Retrieval (Image, Chart, PDF)
228
  ```python
229
  example_query = 'Query: How many input modality does Qwen2.5-Omni support?'
230
  example_image_1 = "https://huggingface.co/Tevatron/OmniEmbed-v0.1/resolve/main/assets/qwen2.5omni_hgf.png"
 
237
  sim2 = torch.cosine_similarity(encode_message(query), encode_message(image_2))
238
 
239
  print("Similarities:", sim1.item(), sim2.item())
240
+ # Image similarities: 0.458984375 0.296875
241
  ```
242
 
243
+ #### 🌍 Multilingual Text Retrieval
244
  ```python
245
  example_query = 'Query: 氧气在空气中占比多少?'
246
  example_text_1 = "空气是指大气层中由不同气体和各类飘浮在其中的固体与液体颗粒(大气颗粒与气溶胶)所组成的气态混合物。地球大气层的空气主要由78.1%的氮气、20.9%氧气、0.9%的氩气和1~4%的水蒸气组成,其成分并不是固定的,随着高度、气压、温度的改变和对流情况不同,局部空气的组成比例也会改变。空气在大气层(特别是对流层)中的流动形成了风和曳流、气旋、龙卷等自然现象,而空气中飘浮的颗粒则形成了云、雾、霾和沙尘暴等短期天气情况。空气在海洋和陆地之间跨区域流动所承载的湿度和热能传导也是水循环和气候变率与变化的关键一环。"
 
253
  sim2 = torch.cosine_similarity(encode_message(query), encode_message(text_2))
254
 
255
  print("Similarities:", sim1.item(), sim2.item())
256
+ # Text similarities: 0.3359375 0.2490234375
257
  ```
258
 
259
  ## Data & Training
additional_chat_templates/sentence_transformers.jinja ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <|im_start|>system
2
+ You are a helpful assistant.<|im_end|>
3
+ <|im_start|>user
4
+ {% for message in messages %}{% if message['content'] is string %}{{ message['content'] }}{% else %}{% for content in message['content'] %}{% if content['type'] == 'image' or 'image' in content or 'image_url' in content %}<|vision_bos|><|IMAGE|><|vision_eos|>{% elif content['type'] == 'audio' or 'audio' in content or 'audio_url' in content %}<|audio_bos|><|AUDIO|><|audio_eos|>{% elif content['type'] == 'video' or 'video' in content %}<|vision_bos|><|VIDEO|><|vision_eos|>{% elif 'text' in content %}{{ content['text'] }}{% endif %}{% endfor %}{% endif %}{% endfor %}<|im_end|>
5
+ <|im_start|>assistant
6
+ <|endoftext|>
chat_template.jinja ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {% set audio_count = namespace(value=0) %}{% set image_count = namespace(value=0) %}{% set video_count = namespace(value=0) %}{% for message in messages %}{% if loop.first and message['role'] != 'system' %}<|im_start|>system
2
+ You are a helpful assistant.<|im_end|>
3
+ {% endif %}<|im_start|>{{ message['role'] }}
4
+ {% if message['content'] is string %}{{ message['content'] }}<|im_end|>
5
+ {% else %}{% for content in message['content'] %}{% if content['type'] == 'image' or 'image' in content or 'image_url' in content %}{% set image_count.value = image_count.value + 1 %}{% if add_vision_id %}Picture {{ image_count.value }}: {% endif %}<|vision_bos|><|IMAGE|><|vision_eos|>{% elif content['type'] == 'audio' or 'audio' in content or 'audio_url' in content %}{% set audio_count.value = audio_count.value + 1 %}{% if add_audio_id %}Audio {{ audio_count.value }}: {% endif %}<|audio_bos|><|AUDIO|><|audio_eos|>{% elif content['type'] == 'video' or 'video' in content %}{% set video_count.value = video_count.value + 1 %}{% if add_vision_id %}Video {{ video_count.value }}: {% endif %}<|vision_bos|><|VIDEO|><|vision_eos|>{% elif 'text' in content %}{{ content['text'] }}{% endif %}{% endfor %}<|im_end|>
6
+ {% endif %}{% endfor %}{% if add_generation_prompt %}<|im_start|>assistant
7
+ {% endif %}
chat_template.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "chat_template": "{% set audio_count = namespace(value=0) %}{% set image_count = namespace(value=0) %}{% set video_count = namespace(value=0) %}{% for message in messages %}{% if loop.first and message['role'] != 'system' %}<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n{% endif %}<|im_start|>{{ message['role'] }}\n{% if message['content'] is string %}{{ message['content'] }}<|im_end|>\n{% else %}{% for content in message['content'] %}{% if content['type'] == 'image' or 'image' in content or 'image_url' in content %}{% set image_count.value = image_count.value + 1 %}{% if add_vision_id %}Picture {{ image_count.value }}: {% endif %}<|vision_bos|><|IMAGE|><|vision_eos|>{% elif content['type'] == 'audio' or 'audio' in content or 'audio_url' in content %}{% set audio_count.value = audio_count.value + 1 %}{% if add_audio_id %}Audio {{ audio_count.value }}: {% endif %}<|audio_bos|><|AUDIO|><|audio_eos|>{% elif content['type'] == 'video' or 'video' in content %}{% set video_count.value = video_count.value + 1 %}{% if add_vision_id %}Video {{ video_count.value }}: {% endif %}<|vision_bos|><|VIDEO|><|vision_eos|>{% elif 'text' in content %}{{ content['text'] }}{% endif %}{% endfor %}<|im_end|>\n{% endif %}{% endfor %}{% if add_generation_prompt %}<|im_start|>assistant\n{% endif %}"
3
- }
 
 
 
 
config_sentence_transformers.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "__version__": {
3
+ "sentence_transformers": "5.4.0",
4
+ "transformers": "5.6.0",
5
+ "pytorch": "2.10.0+cu128"
6
+ },
7
+ "prompts": {
8
+ "query": "Query: ",
9
+ "document": ""
10
+ },
11
+ "default_prompt_name": null,
12
+ "similarity_fn_name": "cosine",
13
+ "model_type": "SentenceTransformer"
14
+ }
modules.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Pooling",
12
+ "type": "sentence_transformers.sentence_transformer.modules.pooling.Pooling"
13
+ },
14
+ {
15
+ "idx": 2,
16
+ "name": "2",
17
+ "path": "2_Normalize",
18
+ "type": "sentence_transformers.sentence_transformer.modules.normalize.Normalize"
19
+ }
20
+ ]
sentence_bert_config.json ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "transformer_task": "any-to-any",
3
+ "modality_config": {
4
+ "text": {
5
+ "method": "forward",
6
+ "method_output_name": [
7
+ "hidden_states",
8
+ -1
9
+ ]
10
+ },
11
+ "image": {
12
+ "method": "forward",
13
+ "method_output_name": [
14
+ "hidden_states",
15
+ -1
16
+ ]
17
+ },
18
+ "audio": {
19
+ "method": "forward",
20
+ "method_output_name": [
21
+ "hidden_states",
22
+ -1
23
+ ]
24
+ },
25
+ "video": {
26
+ "method": "forward",
27
+ "method_output_name": [
28
+ "hidden_states",
29
+ -1
30
+ ]
31
+ },
32
+ "message": {
33
+ "method": "forward",
34
+ "method_output_name": [
35
+ "hidden_states",
36
+ -1
37
+ ],
38
+ "format": "structured"
39
+ }
40
+ },
41
+ "module_output_name": "token_embeddings",
42
+ "processing_kwargs": {
43
+ "chat_template": {
44
+ "chat_template": "sentence_transformers"
45
+ }
46
+ }
47
+ }