1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
30pub enum EmbeddingModel {
31 #[default]
37 BGESmallENV15,
38 AllMiniLML6V2,
40 AllMiniLML6V2Q,
42 AllMiniLML12V2,
44 AllMiniLML12V2Q,
46 AllMpnetBaseV2,
48 BGEBaseENV15,
51 BGEBaseENV15Q,
53 BGELargeENV15,
55 BGELargeENV15Q,
57 BGESmallENV15Q,
59 BGESmallZHV15,
61 BGELargeZHV15,
63 BGEM3,
65 NomicEmbedTextV1,
68 NomicEmbedTextV15,
70 NomicEmbedTextV15Q,
72 ParaphraseMLMiniLML12V2,
75 ParaphraseMLMiniLML12V2Q,
77 ParaphraseMLMpnetBaseV2,
79 ModernBertEmbedLarge,
82 MultilingualE5Small,
85 MultilingualE5Base,
87 MultilingualE5Large,
89 MxbaiEmbedLargeV1,
92 MxbaiEmbedLargeV1Q,
94 GTEBaseENV15,
97 GTEBaseENV15Q,
99 GTELargeENV15,
101 GTELargeENV15Q,
103 ClipVitB32,
106 JinaEmbeddingsV2BaseCode,
109 JinaEmbeddingsV2BaseEN,
111 EmbeddingGemma300M,
114 SnowflakeArcticEmbedXS,
117 SnowflakeArcticEmbedXSQ,
119 SnowflakeArcticEmbedS,
121 SnowflakeArcticEmbedSQ,
123 SnowflakeArcticEmbedM,
125 SnowflakeArcticEmbedMQ,
127 SnowflakeArcticEmbedMLong,
129 SnowflakeArcticEmbedMLongQ,
131 SnowflakeArcticEmbedL,
133 SnowflakeArcticEmbedLQ,
135}
136
137impl EmbeddingModel {
138 pub const fn dimension(self) -> usize {
140 match self {
141 Self::BGESmallENV15
143 | Self::AllMiniLML6V2
144 | Self::AllMiniLML6V2Q
145 | Self::AllMiniLML12V2
146 | Self::AllMiniLML12V2Q
147 | Self::BGESmallENV15Q
148 | Self::ParaphraseMLMiniLML12V2
149 | Self::ParaphraseMLMiniLML12V2Q
150 | Self::MultilingualE5Small
151 | Self::SnowflakeArcticEmbedXS
152 | Self::SnowflakeArcticEmbedXSQ
153 | Self::SnowflakeArcticEmbedS
154 | Self::SnowflakeArcticEmbedSQ => 384,
155 Self::BGESmallZHV15 | Self::ClipVitB32 => 512,
157 Self::AllMpnetBaseV2
159 | Self::BGEBaseENV15
160 | Self::BGEBaseENV15Q
161 | Self::NomicEmbedTextV1
162 | Self::NomicEmbedTextV15
163 | Self::NomicEmbedTextV15Q
164 | Self::ParaphraseMLMpnetBaseV2
165 | Self::MultilingualE5Base
166 | Self::GTEBaseENV15
167 | Self::GTEBaseENV15Q
168 | Self::JinaEmbeddingsV2BaseCode
169 | Self::JinaEmbeddingsV2BaseEN
170 | Self::EmbeddingGemma300M
171 | Self::SnowflakeArcticEmbedM
172 | Self::SnowflakeArcticEmbedMQ
173 | Self::SnowflakeArcticEmbedMLong
174 | Self::SnowflakeArcticEmbedMLongQ => 768,
175 Self::BGELargeENV15
177 | Self::BGELargeENV15Q
178 | Self::BGELargeZHV15
179 | Self::BGEM3
180 | Self::ModernBertEmbedLarge
181 | Self::MultilingualE5Large
182 | Self::MxbaiEmbedLargeV1
183 | Self::MxbaiEmbedLargeV1Q
184 | Self::GTELargeENV15
185 | Self::GTELargeENV15Q
186 | Self::SnowflakeArcticEmbedL
187 | Self::SnowflakeArcticEmbedLQ => 1024,
188 }
189 }
190
191 pub const fn description(self) -> &'static str {
193 match self {
194 Self::BGESmallENV15 => "v1.5 release of the fast and default English model",
195 Self::AllMiniLML6V2 => "Sentence Transformer model, MiniLM-L6-v2",
196 Self::AllMiniLML6V2Q => "Quantized Sentence Transformer model, MiniLM-L6-v2",
197 Self::AllMiniLML12V2 => "Sentence Transformer model, MiniLM-L12-v2",
198 Self::AllMiniLML12V2Q => "Quantized Sentence Transformer model, MiniLM-L12-v2",
199 Self::AllMpnetBaseV2 => "Sentence Transformer model, mpnet-base-v2",
200 Self::BGEBaseENV15 => "v1.5 release of the base English model",
201 Self::BGEBaseENV15Q => "Quantized v1.5 release of the base English model",
202 Self::BGELargeENV15 => "v1.5 release of the large English model",
203 Self::BGELargeENV15Q => "Quantized v1.5 release of the large English model",
204 Self::BGESmallENV15Q => "Quantized v1.5 release of the fast and default English model",
205 Self::NomicEmbedTextV1 => "8192 context length english model",
206 Self::NomicEmbedTextV15 => "v1.5 release of the 8192 context length english model",
207 Self::NomicEmbedTextV15Q => {
208 "Quantized v1.5 release of the 8192 context length english model"
209 }
210 Self::ParaphraseMLMiniLML12V2 => "Multi-lingual model",
211 Self::ParaphraseMLMiniLML12V2Q => "Quantized multi-lingual model",
212 Self::ParaphraseMLMpnetBaseV2 => {
213 "Sentence-transformers model for clustering or semantic search"
214 }
215 Self::BGESmallZHV15 => "v1.5 release of the small Chinese model",
216 Self::BGELargeZHV15 => "v1.5 release of the large Chinese model",
217 Self::BGEM3 => "Multilingual M3 model with 8192 context length, 100+ languages",
218 Self::ModernBertEmbedLarge => "Large model of ModernBert Text Embeddings",
219 Self::MultilingualE5Small => "Small model of multilingual E5 Text Embeddings",
220 Self::MultilingualE5Base => "Base model of multilingual E5 Text Embeddings",
221 Self::MultilingualE5Large => "Large model of multilingual E5 Text Embeddings",
222 Self::MxbaiEmbedLargeV1 => "Large English embedding model from MixedBreed.ai",
223 Self::MxbaiEmbedLargeV1Q => {
224 "Quantized large English embedding model from MixedBreed.ai"
225 }
226 Self::GTEBaseENV15 => "Base multilingual embedding model from Alibaba",
227 Self::GTEBaseENV15Q => "Quantized base multilingual embedding model from Alibaba",
228 Self::GTELargeENV15 => "Large multilingual embedding model from Alibaba",
229 Self::GTELargeENV15Q => "Quantized large multilingual embedding model from Alibaba",
230 Self::ClipVitB32 => "CLIP text encoder based on ViT-B/32",
231 Self::JinaEmbeddingsV2BaseCode => "Jina embeddings v2 base code",
232 Self::JinaEmbeddingsV2BaseEN => "Jina embeddings v2 base English",
233 Self::EmbeddingGemma300M => "EmbeddingGemma 300M parameter model from Google",
234 Self::SnowflakeArcticEmbedXS => "Snowflake Arctic embed model, xs",
235 Self::SnowflakeArcticEmbedXSQ => "Quantized Snowflake Arctic embed model, xs",
236 Self::SnowflakeArcticEmbedS => "Snowflake Arctic embed model, small",
237 Self::SnowflakeArcticEmbedSQ => "Quantized Snowflake Arctic embed model, small",
238 Self::SnowflakeArcticEmbedM => "Snowflake Arctic embed model, medium",
239 Self::SnowflakeArcticEmbedMQ => "Quantized Snowflake Arctic embed model, medium",
240 Self::SnowflakeArcticEmbedMLong => {
241 "Snowflake Arctic embed model, medium with 2048 context"
242 }
243 Self::SnowflakeArcticEmbedMLongQ => {
244 "Quantized Snowflake Arctic embed model, medium with 2048 context"
245 }
246 Self::SnowflakeArcticEmbedL => "Snowflake Arctic embed model, large",
247 Self::SnowflakeArcticEmbedLQ => "Quantized Snowflake Arctic embed model, large",
248 }
249 }
250
251 pub const fn query_prefix(self) -> Option<&'static str> {
253 match self {
254 Self::MultilingualE5Small | Self::MultilingualE5Base | Self::MultilingualE5Large => {
255 Some("query: ")
256 }
257 Self::NomicEmbedTextV15 | Self::NomicEmbedTextV15Q => Some("search_query: "),
258 Self::BGESmallENV15
260 | Self::BGESmallENV15Q
261 | Self::BGEBaseENV15
262 | Self::BGEBaseENV15Q
263 | Self::BGELargeENV15
264 | Self::BGELargeENV15Q
265 | Self::MxbaiEmbedLargeV1
266 | Self::MxbaiEmbedLargeV1Q
267 | Self::SnowflakeArcticEmbedXS
268 | Self::SnowflakeArcticEmbedXSQ
269 | Self::SnowflakeArcticEmbedS
270 | Self::SnowflakeArcticEmbedSQ
271 | Self::SnowflakeArcticEmbedM
272 | Self::SnowflakeArcticEmbedMQ
273 | Self::SnowflakeArcticEmbedMLong
274 | Self::SnowflakeArcticEmbedMLongQ
275 | Self::SnowflakeArcticEmbedL
276 | Self::SnowflakeArcticEmbedLQ => {
277 Some("Represent this sentence for searching relevant passages: ")
278 }
279 _ => None,
280 }
281 }
282
283 pub const fn doc_prefix(self) -> Option<&'static str> {
285 match self {
286 Self::MultilingualE5Small | Self::MultilingualE5Base | Self::MultilingualE5Large => {
287 Some("passage: ")
288 }
289 Self::NomicEmbedTextV15 | Self::NomicEmbedTextV15Q => Some("search_document: "),
290 _ => None,
291 }
292 }
293
294 pub const fn mlx_supported(self) -> bool {
316 matches!(
317 self,
318 Self::BGESmallENV15
319 | Self::BGESmallENV15Q
320 | Self::BGEBaseENV15
321 | Self::BGEBaseENV15Q
322 | Self::BGELargeENV15
323 | Self::BGELargeENV15Q
324 | Self::BGESmallZHV15
325 | Self::AllMiniLML6V2
326 | Self::AllMiniLML6V2Q
327 | Self::AllMiniLML12V2
328 | Self::AllMiniLML12V2Q
329 | Self::ParaphraseMLMiniLML12V2
330 | Self::ParaphraseMLMiniLML12V2Q
331 | Self::MultilingualE5Small
332 | Self::SnowflakeArcticEmbedXS
333 | Self::SnowflakeArcticEmbedXSQ
334 | Self::SnowflakeArcticEmbedS
335 | Self::SnowflakeArcticEmbedSQ
336 | Self::SnowflakeArcticEmbedM
337 | Self::SnowflakeArcticEmbedMQ
338 | Self::SnowflakeArcticEmbedL
339 | Self::SnowflakeArcticEmbedLQ
340 | Self::MxbaiEmbedLargeV1
341 | Self::MxbaiEmbedLargeV1Q
342 )
343 }
344
345 pub const fn uses_cls_pooling(self) -> bool {
351 matches!(
352 self,
353 Self::BGESmallENV15
354 | Self::BGESmallENV15Q
355 | Self::BGEBaseENV15
356 | Self::BGEBaseENV15Q
357 | Self::BGELargeENV15
358 | Self::BGELargeENV15Q
359 | Self::BGESmallZHV15
360 | Self::BGELargeZHV15
361 | Self::SnowflakeArcticEmbedXS
362 | Self::SnowflakeArcticEmbedXSQ
363 | Self::SnowflakeArcticEmbedS
364 | Self::SnowflakeArcticEmbedSQ
365 | Self::SnowflakeArcticEmbedM
366 | Self::SnowflakeArcticEmbedMQ
367 | Self::SnowflakeArcticEmbedMLong
368 | Self::SnowflakeArcticEmbedMLongQ
369 | Self::SnowflakeArcticEmbedL
370 | Self::SnowflakeArcticEmbedLQ
371 | Self::MxbaiEmbedLargeV1
372 | Self::MxbaiEmbedLargeV1Q
373 )
374 }
375
376 pub const fn mlx_repo(self) -> &'static str {
384 match self {
385 Self::BGESmallENV15 | Self::BGESmallENV15Q => "BAAI/bge-small-en-v1.5",
386 Self::BGEBaseENV15 | Self::BGEBaseENV15Q => "BAAI/bge-base-en-v1.5",
387 Self::BGELargeENV15 | Self::BGELargeENV15Q => "BAAI/bge-large-en-v1.5",
388 Self::BGESmallZHV15 => "BAAI/bge-small-zh-v1.5",
389 Self::AllMiniLML6V2 | Self::AllMiniLML6V2Q => "sentence-transformers/all-MiniLM-L6-v2",
390 Self::AllMiniLML12V2 | Self::AllMiniLML12V2Q => {
391 "sentence-transformers/all-MiniLM-L12-v2"
392 }
393 Self::ParaphraseMLMiniLML12V2 | Self::ParaphraseMLMiniLML12V2Q => {
394 "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
395 }
396 _ => self.model_code(),
399 }
400 }
401
402 pub const fn size_mb(self) -> usize {
404 match self {
405 Self::BGESmallENV15 | Self::BGESmallENV15Q => 40,
407 Self::AllMiniLML6V2 | Self::AllMiniLML6V2Q => 80,
409 Self::SnowflakeArcticEmbedXS | Self::SnowflakeArcticEmbedXSQ | Self::BGESmallZHV15 => {
411 90
412 }
413 Self::AllMiniLML12V2 | Self::AllMiniLML12V2Q => 120,
415 Self::SnowflakeArcticEmbedS | Self::SnowflakeArcticEmbedSQ => 130,
417 Self::JinaEmbeddingsV2BaseCode
419 | Self::JinaEmbeddingsV2BaseEN
420 | Self::EmbeddingGemma300M => 260,
421 Self::AllMpnetBaseV2
423 | Self::BGEBaseENV15
424 | Self::BGEBaseENV15Q
425 | Self::GTEBaseENV15
426 | Self::GTEBaseENV15Q => 420,
427 Self::SnowflakeArcticEmbedM
429 | Self::SnowflakeArcticEmbedMQ
430 | Self::SnowflakeArcticEmbedMLong
431 | Self::SnowflakeArcticEmbedMLongQ => 430,
432 Self::ParaphraseMLMiniLML12V2
434 | Self::ParaphraseMLMiniLML12V2Q
435 | Self::MultilingualE5Small => 470,
436 Self::NomicEmbedTextV1 | Self::NomicEmbedTextV15 | Self::NomicEmbedTextV15Q => 550,
438 Self::BGEM3 | Self::ModernBertEmbedLarge | Self::ClipVitB32 => 600,
440 Self::ParaphraseMLMpnetBaseV2 | Self::MultilingualE5Base => 970,
442 Self::BGELargeENV15
444 | Self::BGELargeENV15Q
445 | Self::BGELargeZHV15
446 | Self::MultilingualE5Large
447 | Self::MxbaiEmbedLargeV1
448 | Self::MxbaiEmbedLargeV1Q
449 | Self::GTELargeENV15
450 | Self::GTELargeENV15Q
451 | Self::SnowflakeArcticEmbedL
452 | Self::SnowflakeArcticEmbedLQ => 1300,
453 }
454 }
455
456 pub const fn model_id(self) -> &'static str {
462 match self {
463 Self::BGESmallENV15 => "BAAI/bge-small-en-v1.5",
464 Self::AllMiniLML6V2 => "sentence-transformers/all-MiniLM-L6-v2",
465 Self::AllMiniLML6V2Q => "Xenova/all-MiniLM-L6-v2",
466 Self::AllMiniLML12V2 => "sentence-transformers/all-MiniLM-L12-v2",
467 Self::AllMiniLML12V2Q => "Xenova/all-MiniLM-L12-v2",
468 Self::AllMpnetBaseV2 => "sentence-transformers/all-mpnet-base-v2",
469 Self::BGEBaseENV15 => "BAAI/bge-base-en-v1.5",
470 Self::BGEBaseENV15Q => "Qdrant/bge-base-en-v1.5-onnx-Q",
471 Self::BGELargeENV15 => "BAAI/bge-large-en-v1.5",
472 Self::BGELargeENV15Q => "Qdrant/bge-large-en-v1.5-onnx-Q",
473 Self::BGESmallENV15Q => "Qdrant/bge-small-en-v1.5-onnx-Q",
474 Self::NomicEmbedTextV1 => "nomic-ai/nomic-embed-text-v1",
475 Self::NomicEmbedTextV15 => "nomic-ai/nomic-embed-text-v1.5",
476 Self::NomicEmbedTextV15Q => "nomic-ai/nomic-embed-text-v1.5",
477 Self::ParaphraseMLMiniLML12V2 => {
478 "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
479 }
480 Self::ParaphraseMLMiniLML12V2Q => "Xenova/paraphrase-multilingual-MiniLM-L12-v2",
481 Self::ParaphraseMLMpnetBaseV2 => {
482 "sentence-transformers/paraphrase-multilingual-mpnet-base-v2"
483 }
484 Self::BGESmallZHV15 => "BAAI/bge-small-zh-v1.5",
485 Self::BGELargeZHV15 => "BAAI/bge-large-zh-v1.5",
486 Self::BGEM3 => "BAAI/bge-m3",
487 Self::ModernBertEmbedLarge => "nomic-ai/modernbert-embed-large",
488 Self::MultilingualE5Small => "intfloat/multilingual-e5-small",
489 Self::MultilingualE5Base => "intfloat/multilingual-e5-base",
490 Self::MultilingualE5Large => "intfloat/multilingual-e5-large",
491 Self::MxbaiEmbedLargeV1 => "mixedbread-ai/mxbai-embed-large-v1",
492 Self::MxbaiEmbedLargeV1Q => "mixedbread-ai/mxbai-embed-large-v1",
493 Self::GTEBaseENV15 => "Alibaba-NLP/gte-base-en-v1.5",
494 Self::GTEBaseENV15Q => "Qdrant/gte-base-en-v1.5-onnx-Q",
495 Self::GTELargeENV15 => "Alibaba-NLP/gte-large-en-v1.5",
496 Self::GTELargeENV15Q => "Qdrant/gte-large-en-v1.5-onnx-Q",
497 Self::ClipVitB32 => "openai/clip-vit-base-patch32",
498 Self::JinaEmbeddingsV2BaseCode => "jinaai/jina-embeddings-v2-base-code",
499 Self::JinaEmbeddingsV2BaseEN => "jinaai/jina-embeddings-v2-base-en",
500 Self::EmbeddingGemma300M => "google/embedding-gemma-300M",
501 Self::SnowflakeArcticEmbedXS => "Snowflake/snowflake-arctic-embed-xs",
502 Self::SnowflakeArcticEmbedXSQ => "Snowflake/snowflake-arctic-embed-xs",
503 Self::SnowflakeArcticEmbedS => "Snowflake/snowflake-arctic-embed-s",
504 Self::SnowflakeArcticEmbedSQ => "Snowflake/snowflake-arctic-embed-s",
505 Self::SnowflakeArcticEmbedM => "Snowflake/snowflake-arctic-embed-m",
506 Self::SnowflakeArcticEmbedMQ => "Snowflake/snowflake-arctic-embed-m",
507 Self::SnowflakeArcticEmbedMLong => "Snowflake/snowflake-arctic-embed-m-long",
508 Self::SnowflakeArcticEmbedMLongQ => "Snowflake/snowflake-arctic-embed-m-long",
509 Self::SnowflakeArcticEmbedL => "Snowflake/snowflake-arctic-embed-l",
510 Self::SnowflakeArcticEmbedLQ => "Snowflake/snowflake-arctic-embed-l",
511 }
512 }
513
514 pub const fn max_seq_length(self) -> usize {
516 match self {
517 Self::AllMiniLML6V2
519 | Self::AllMiniLML6V2Q
520 | Self::AllMiniLML12V2
521 | Self::AllMiniLML12V2Q => 256,
522 Self::AllMpnetBaseV2 => 384,
524 Self::BGEM3
526 | Self::NomicEmbedTextV1
527 | Self::NomicEmbedTextV15
528 | Self::NomicEmbedTextV15Q
529 | Self::JinaEmbeddingsV2BaseCode
530 | Self::JinaEmbeddingsV2BaseEN
531 | Self::EmbeddingGemma300M
532 | Self::SnowflakeArcticEmbedMLong
533 | Self::SnowflakeArcticEmbedMLongQ => 8192,
534 Self::BGESmallENV15
536 | Self::BGESmallENV15Q
537 | Self::BGEBaseENV15
538 | Self::BGEBaseENV15Q
539 | Self::BGELargeENV15
540 | Self::BGELargeENV15Q
541 | Self::BGESmallZHV15
542 | Self::BGELargeZHV15
543 | Self::ParaphraseMLMiniLML12V2
544 | Self::ParaphraseMLMiniLML12V2Q
545 | Self::ParaphraseMLMpnetBaseV2
546 | Self::ModernBertEmbedLarge
547 | Self::MultilingualE5Small
548 | Self::MultilingualE5Base
549 | Self::MultilingualE5Large
550 | Self::MxbaiEmbedLargeV1
551 | Self::MxbaiEmbedLargeV1Q
552 | Self::GTEBaseENV15
553 | Self::GTEBaseENV15Q
554 | Self::GTELargeENV15
555 | Self::GTELargeENV15Q
556 | Self::ClipVitB32
557 | Self::SnowflakeArcticEmbedXS
558 | Self::SnowflakeArcticEmbedXSQ
559 | Self::SnowflakeArcticEmbedS
560 | Self::SnowflakeArcticEmbedSQ
561 | Self::SnowflakeArcticEmbedM
562 | Self::SnowflakeArcticEmbedMQ
563 | Self::SnowflakeArcticEmbedL
564 | Self::SnowflakeArcticEmbedLQ => 512,
565 }
566 }
567
568 pub const fn is_quantized(self) -> bool {
570 matches!(
571 self,
572 Self::AllMiniLML6V2Q
573 | Self::AllMiniLML12V2Q
574 | Self::BGEBaseENV15Q
575 | Self::BGELargeENV15Q
576 | Self::BGESmallENV15Q
577 | Self::NomicEmbedTextV15Q
578 | Self::ParaphraseMLMiniLML12V2Q
579 | Self::MxbaiEmbedLargeV1Q
580 | Self::GTEBaseENV15Q
581 | Self::GTELargeENV15Q
582 | Self::SnowflakeArcticEmbedXSQ
583 | Self::SnowflakeArcticEmbedSQ
584 | Self::SnowflakeArcticEmbedMQ
585 | Self::SnowflakeArcticEmbedMLongQ
586 | Self::SnowflakeArcticEmbedLQ
587 )
588 }
589
590 pub const fn is_image_model(self) -> bool {
592 matches!(self, Self::ClipVitB32)
593 }
594
595 pub const fn model_code(self) -> &'static str {
603 match self {
604 Self::AllMiniLML6V2 => "Qdrant/all-MiniLM-L6-v2-onnx",
605 Self::AllMiniLML6V2Q => "Xenova/all-MiniLM-L6-v2",
606 Self::AllMiniLML12V2 => "Xenova/all-MiniLM-L12-v2",
607 Self::AllMiniLML12V2Q => "Xenova/all-MiniLM-L12-v2",
608 Self::AllMpnetBaseV2 => "Xenova/all-mpnet-base-v2",
609 Self::BGEBaseENV15 => "Xenova/bge-base-en-v1.5",
610 Self::BGEBaseENV15Q => "Qdrant/bge-base-en-v1.5-onnx-Q",
611 Self::BGELargeENV15 => "Xenova/bge-large-en-v1.5",
612 Self::BGELargeENV15Q => "Qdrant/bge-large-en-v1.5-onnx-Q",
613 Self::BGESmallENV15 => "Xenova/bge-small-en-v1.5",
614 Self::BGESmallENV15Q => "Qdrant/bge-small-en-v1.5-onnx-Q",
615 Self::NomicEmbedTextV1 => "nomic-ai/nomic-embed-text-v1",
616 Self::NomicEmbedTextV15 => "nomic-ai/nomic-embed-text-v1.5",
617 Self::NomicEmbedTextV15Q => "nomic-ai/nomic-embed-text-v1.5",
618 Self::ParaphraseMLMiniLML12V2 => "Xenova/paraphrase-multilingual-MiniLM-L12-v2",
619 Self::ParaphraseMLMiniLML12V2Q => "Qdrant/paraphrase-multilingual-MiniLM-L12-v2-onnx-Q",
620 Self::ParaphraseMLMpnetBaseV2 => "Xenova/paraphrase-multilingual-mpnet-base-v2",
621 Self::BGESmallZHV15 => "Xenova/bge-small-zh-v1.5",
622 Self::BGELargeZHV15 => "Xenova/bge-large-zh-v1.5",
623 Self::BGEM3 => "BAAI/bge-m3",
624 Self::ModernBertEmbedLarge => "lightonai/modernbert-embed-large",
625 Self::MultilingualE5Small => "intfloat/multilingual-e5-small",
626 Self::MultilingualE5Base => "intfloat/multilingual-e5-base",
627 Self::MultilingualE5Large => "Qdrant/multilingual-e5-large-onnx",
628 Self::MxbaiEmbedLargeV1 => "mixedbread-ai/mxbai-embed-large-v1",
629 Self::MxbaiEmbedLargeV1Q => "mixedbread-ai/mxbai-embed-large-v1",
630 Self::GTEBaseENV15 => "Alibaba-NLP/gte-base-en-v1.5",
631 Self::GTEBaseENV15Q => "Alibaba-NLP/gte-base-en-v1.5",
632 Self::GTELargeENV15 => "Alibaba-NLP/gte-large-en-v1.5",
633 Self::GTELargeENV15Q => "Alibaba-NLP/gte-large-en-v1.5",
634 Self::ClipVitB32 => "Qdrant/clip-ViT-B-32-text",
635 Self::JinaEmbeddingsV2BaseCode => "jinaai/jina-embeddings-v2-base-code",
636 Self::JinaEmbeddingsV2BaseEN => "jinaai/jina-embeddings-v2-base-en",
637 Self::EmbeddingGemma300M => "onnx-community/embeddinggemma-300m-ONNX",
638 Self::SnowflakeArcticEmbedXS => "snowflake/snowflake-arctic-embed-xs",
639 Self::SnowflakeArcticEmbedXSQ => "snowflake/snowflake-arctic-embed-xs",
640 Self::SnowflakeArcticEmbedS => "snowflake/snowflake-arctic-embed-s",
641 Self::SnowflakeArcticEmbedSQ => "snowflake/snowflake-arctic-embed-s",
642 Self::SnowflakeArcticEmbedM => "Snowflake/snowflake-arctic-embed-m",
643 Self::SnowflakeArcticEmbedMQ => "Snowflake/snowflake-arctic-embed-m",
644 Self::SnowflakeArcticEmbedMLong => "snowflake/snowflake-arctic-embed-m-long",
645 Self::SnowflakeArcticEmbedMLongQ => "snowflake/snowflake-arctic-embed-m-long",
646 Self::SnowflakeArcticEmbedL => "snowflake/snowflake-arctic-embed-l",
647 Self::SnowflakeArcticEmbedLQ => "snowflake/snowflake-arctic-embed-l",
648 }
649 }
650
651 pub fn as_str(self) -> &'static str {
653 match self {
654 Self::BGESmallENV15 => "BGESmallENV15",
655 Self::AllMiniLML6V2 => "AllMiniLML6V2",
656 Self::AllMiniLML6V2Q => "AllMiniLML6V2Q",
657 Self::AllMiniLML12V2 => "AllMiniLML12V2",
658 Self::AllMiniLML12V2Q => "AllMiniLML12V2Q",
659 Self::AllMpnetBaseV2 => "AllMpnetBaseV2",
660 Self::BGEBaseENV15 => "BGEBaseENV15",
661 Self::BGEBaseENV15Q => "BGEBaseENV15Q",
662 Self::BGELargeENV15 => "BGELargeENV15",
663 Self::BGELargeENV15Q => "BGELargeENV15Q",
664 Self::BGESmallENV15Q => "BGESmallENV15Q",
665 Self::NomicEmbedTextV1 => "NomicEmbedTextV1",
666 Self::NomicEmbedTextV15 => "NomicEmbedTextV15",
667 Self::NomicEmbedTextV15Q => "NomicEmbedTextV15Q",
668 Self::ParaphraseMLMiniLML12V2 => "ParaphraseMLMiniLML12V2",
669 Self::ParaphraseMLMiniLML12V2Q => "ParaphraseMLMiniLML12V2Q",
670 Self::ParaphraseMLMpnetBaseV2 => "ParaphraseMLMpnetBaseV2",
671 Self::BGESmallZHV15 => "BGESmallZHV15",
672 Self::BGELargeZHV15 => "BGELargeZHV15",
673 Self::BGEM3 => "BGEM3",
674 Self::ModernBertEmbedLarge => "ModernBertEmbedLarge",
675 Self::MultilingualE5Small => "MultilingualE5Small",
676 Self::MultilingualE5Base => "MultilingualE5Base",
677 Self::MultilingualE5Large => "MultilingualE5Large",
678 Self::MxbaiEmbedLargeV1 => "MxbaiEmbedLargeV1",
679 Self::MxbaiEmbedLargeV1Q => "MxbaiEmbedLargeV1Q",
680 Self::GTEBaseENV15 => "GTEBaseENV15",
681 Self::GTEBaseENV15Q => "GTEBaseENV15Q",
682 Self::GTELargeENV15 => "GTELargeENV15",
683 Self::GTELargeENV15Q => "GTELargeENV15Q",
684 Self::ClipVitB32 => "ClipVitB32",
685 Self::JinaEmbeddingsV2BaseCode => "JinaEmbeddingsV2BaseCode",
686 Self::JinaEmbeddingsV2BaseEN => "JinaEmbeddingsV2BaseEN",
687 Self::EmbeddingGemma300M => "EmbeddingGemma300M",
688 Self::SnowflakeArcticEmbedXS => "SnowflakeArcticEmbedXS",
689 Self::SnowflakeArcticEmbedXSQ => "SnowflakeArcticEmbedXSQ",
690 Self::SnowflakeArcticEmbedS => "SnowflakeArcticEmbedS",
691 Self::SnowflakeArcticEmbedSQ => "SnowflakeArcticEmbedSQ",
692 Self::SnowflakeArcticEmbedM => "SnowflakeArcticEmbedM",
693 Self::SnowflakeArcticEmbedMQ => "SnowflakeArcticEmbedMQ",
694 Self::SnowflakeArcticEmbedMLong => "SnowflakeArcticEmbedMLong",
695 Self::SnowflakeArcticEmbedMLongQ => "SnowflakeArcticEmbedMLongQ",
696 Self::SnowflakeArcticEmbedL => "SnowflakeArcticEmbedL",
697 Self::SnowflakeArcticEmbedLQ => "SnowflakeArcticEmbedLQ",
698 }
699 }
700
701 pub fn parse(s: &str) -> Result<Self, String> {
703 Self::ALL
704 .iter()
705 .find(|m| m.as_str().eq_ignore_ascii_case(s))
706 .copied()
707 .ok_or_else(|| format!("unknown embedding model: {s}"))
708 }
709
710 pub const ALL: &[Self] = &[
712 Self::BGESmallENV15,
713 Self::AllMiniLML6V2,
714 Self::AllMiniLML6V2Q,
715 Self::AllMiniLML12V2,
716 Self::AllMiniLML12V2Q,
717 Self::AllMpnetBaseV2,
718 Self::BGEBaseENV15,
719 Self::BGEBaseENV15Q,
720 Self::BGELargeENV15,
721 Self::BGELargeENV15Q,
722 Self::BGESmallENV15Q,
723 Self::NomicEmbedTextV1,
724 Self::NomicEmbedTextV15,
725 Self::NomicEmbedTextV15Q,
726 Self::ParaphraseMLMiniLML12V2,
727 Self::ParaphraseMLMiniLML12V2Q,
728 Self::ParaphraseMLMpnetBaseV2,
729 Self::BGESmallZHV15,
730 Self::BGELargeZHV15,
731 Self::BGEM3,
732 Self::ModernBertEmbedLarge,
733 Self::MultilingualE5Small,
734 Self::MultilingualE5Base,
735 Self::MultilingualE5Large,
736 Self::MxbaiEmbedLargeV1,
737 Self::MxbaiEmbedLargeV1Q,
738 Self::GTEBaseENV15,
739 Self::GTEBaseENV15Q,
740 Self::GTELargeENV15,
741 Self::GTELargeENV15Q,
742 Self::ClipVitB32,
743 Self::JinaEmbeddingsV2BaseCode,
744 Self::JinaEmbeddingsV2BaseEN,
745 Self::EmbeddingGemma300M,
746 Self::SnowflakeArcticEmbedXS,
747 Self::SnowflakeArcticEmbedXSQ,
748 Self::SnowflakeArcticEmbedS,
749 Self::SnowflakeArcticEmbedSQ,
750 Self::SnowflakeArcticEmbedM,
751 Self::SnowflakeArcticEmbedMQ,
752 Self::SnowflakeArcticEmbedMLong,
753 Self::SnowflakeArcticEmbedMLongQ,
754 Self::SnowflakeArcticEmbedL,
755 Self::SnowflakeArcticEmbedLQ,
756 ];
757
758 #[cfg(any(
763 feature = "embedding-fastembed",
764 feature = "embedding-fastembed-dynamic-linking"
765 ))]
766 pub fn as_fastembed(self) -> fastembed::EmbeddingModel {
767 match self {
768 Self::BGESmallENV15 => fastembed::EmbeddingModel::BGESmallENV15,
769 Self::AllMiniLML6V2 => fastembed::EmbeddingModel::AllMiniLML6V2,
770 Self::AllMiniLML6V2Q => fastembed::EmbeddingModel::AllMiniLML6V2Q,
771 Self::AllMiniLML12V2 => fastembed::EmbeddingModel::AllMiniLML12V2,
772 Self::AllMiniLML12V2Q => fastembed::EmbeddingModel::AllMiniLML12V2Q,
773 Self::AllMpnetBaseV2 => fastembed::EmbeddingModel::AllMpnetBaseV2,
774 Self::BGEBaseENV15 => fastembed::EmbeddingModel::BGEBaseENV15,
775 Self::BGEBaseENV15Q => fastembed::EmbeddingModel::BGEBaseENV15Q,
776 Self::BGELargeENV15 => fastembed::EmbeddingModel::BGELargeENV15,
777 Self::BGELargeENV15Q => fastembed::EmbeddingModel::BGELargeENV15Q,
778 Self::BGESmallENV15Q => fastembed::EmbeddingModel::BGESmallENV15Q,
779 Self::NomicEmbedTextV1 => fastembed::EmbeddingModel::NomicEmbedTextV1,
780 Self::NomicEmbedTextV15 => fastembed::EmbeddingModel::NomicEmbedTextV15,
781 Self::NomicEmbedTextV15Q => fastembed::EmbeddingModel::NomicEmbedTextV15Q,
782 Self::ParaphraseMLMiniLML12V2 => fastembed::EmbeddingModel::ParaphraseMLMiniLML12V2,
783 Self::ParaphraseMLMiniLML12V2Q => fastembed::EmbeddingModel::ParaphraseMLMiniLML12V2Q,
784 Self::ParaphraseMLMpnetBaseV2 => fastembed::EmbeddingModel::ParaphraseMLMpnetBaseV2,
785 Self::BGESmallZHV15 => fastembed::EmbeddingModel::BGESmallZHV15,
786 Self::BGELargeZHV15 => fastembed::EmbeddingModel::BGELargeZHV15,
787 Self::BGEM3 => fastembed::EmbeddingModel::BGEM3,
788 Self::ModernBertEmbedLarge => fastembed::EmbeddingModel::ModernBertEmbedLarge,
789 Self::MultilingualE5Small => fastembed::EmbeddingModel::MultilingualE5Small,
790 Self::MultilingualE5Base => fastembed::EmbeddingModel::MultilingualE5Base,
791 Self::MultilingualE5Large => fastembed::EmbeddingModel::MultilingualE5Large,
792 Self::MxbaiEmbedLargeV1 => fastembed::EmbeddingModel::MxbaiEmbedLargeV1,
793 Self::MxbaiEmbedLargeV1Q => fastembed::EmbeddingModel::MxbaiEmbedLargeV1Q,
794 Self::GTEBaseENV15 => fastembed::EmbeddingModel::GTEBaseENV15,
795 Self::GTEBaseENV15Q => fastembed::EmbeddingModel::GTEBaseENV15Q,
796 Self::GTELargeENV15 => fastembed::EmbeddingModel::GTELargeENV15,
797 Self::GTELargeENV15Q => fastembed::EmbeddingModel::GTELargeENV15Q,
798 Self::ClipVitB32 => fastembed::EmbeddingModel::ClipVitB32,
799 Self::JinaEmbeddingsV2BaseCode => fastembed::EmbeddingModel::JinaEmbeddingsV2BaseCode,
800 Self::JinaEmbeddingsV2BaseEN => fastembed::EmbeddingModel::JinaEmbeddingsV2BaseEN,
801 Self::EmbeddingGemma300M => fastembed::EmbeddingModel::EmbeddingGemma300M,
802 Self::SnowflakeArcticEmbedXS => fastembed::EmbeddingModel::SnowflakeArcticEmbedXS,
803 Self::SnowflakeArcticEmbedXSQ => fastembed::EmbeddingModel::SnowflakeArcticEmbedXSQ,
804 Self::SnowflakeArcticEmbedS => fastembed::EmbeddingModel::SnowflakeArcticEmbedS,
805 Self::SnowflakeArcticEmbedSQ => fastembed::EmbeddingModel::SnowflakeArcticEmbedSQ,
806 Self::SnowflakeArcticEmbedM => fastembed::EmbeddingModel::SnowflakeArcticEmbedM,
807 Self::SnowflakeArcticEmbedMQ => fastembed::EmbeddingModel::SnowflakeArcticEmbedMQ,
808 Self::SnowflakeArcticEmbedMLong => fastembed::EmbeddingModel::SnowflakeArcticEmbedMLong,
809 Self::SnowflakeArcticEmbedMLongQ => {
810 fastembed::EmbeddingModel::SnowflakeArcticEmbedMLongQ
811 }
812 Self::SnowflakeArcticEmbedL => fastembed::EmbeddingModel::SnowflakeArcticEmbedL,
813 Self::SnowflakeArcticEmbedLQ => fastembed::EmbeddingModel::SnowflakeArcticEmbedLQ,
814 }
815 }
816}
817
818impl std::fmt::Display for EmbeddingModel {
819 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
820 f.write_str(self.as_str())
821 }
822}
823
824impl std::str::FromStr for EmbeddingModel {
825 type Err = String;
826
827 fn from_str(s: &str) -> Result<Self, Self::Err> {
828 Self::parse(s)
829 }
830}
831
832#[cfg(test)]
833mod tests {
834 use super::*;
835
836 #[test]
837 fn all_count() {
838 assert_eq!(EmbeddingModel::ALL.len(), 44);
839 }
840
841 #[test]
842 fn default_is_bge_small() {
843 assert_eq!(EmbeddingModel::default(), EmbeddingModel::BGESmallENV15);
844 }
845
846 #[test]
847 fn dimension_consistency() {
848 for &m in EmbeddingModel::ALL {
849 let dim = m.dimension();
850 assert!(
851 [384, 512, 768, 1024].contains(&dim),
852 "{m:?}: unexpected dimension {dim}"
853 );
854 }
855 }
856
857 #[test]
858 fn parse_roundtrip() {
859 for &m in EmbeddingModel::ALL {
860 let s = m.as_str();
861 assert_eq!(EmbeddingModel::parse(s).unwrap(), m);
862 }
863 }
864
865 #[test]
866 fn parse_case_insensitive() {
867 assert_eq!(
868 EmbeddingModel::parse("bgesmallenv15").unwrap(),
869 EmbeddingModel::BGESmallENV15
870 );
871 assert_eq!(
872 EmbeddingModel::parse("ALLMINILML6V2").unwrap(),
873 EmbeddingModel::AllMiniLML6V2
874 );
875 }
876
877 #[test]
878 fn parse_unknown_fails() {
879 assert!(EmbeddingModel::parse("NotARealModel").is_err());
880 }
881
882 #[test]
883 fn quantized_flags() {
884 let quantized: Vec<_> = EmbeddingModel::ALL
885 .iter()
886 .filter(|m| m.is_quantized())
887 .copied()
888 .collect();
889 for m in &quantized {
891 assert!(m.as_str().ends_with('Q'), "{m:?} flagged but no Q suffix");
892 }
893 for &m in EmbeddingModel::ALL {
895 if !m.as_str().ends_with('Q') {
896 assert!(!m.is_quantized(), "{m:?} not Q but flagged quantized");
897 }
898 }
899 }
900
901 #[test]
902 fn image_model_flag() {
903 assert!(EmbeddingModel::ClipVitB32.is_image_model());
904 assert_eq!(
905 EmbeddingModel::ALL
906 .iter()
907 .filter(|m| m.is_image_model())
908 .count(),
909 1
910 );
911 }
912
913 #[test]
914 fn prefix_mapping() {
915 for &m in &[
917 EmbeddingModel::MultilingualE5Small,
918 EmbeddingModel::MultilingualE5Base,
919 EmbeddingModel::MultilingualE5Large,
920 ] {
921 assert_eq!(m.query_prefix(), Some("query: "));
922 assert_eq!(m.doc_prefix(), Some("passage: "));
923 }
924 for &m in &[
926 EmbeddingModel::SnowflakeArcticEmbedXS,
927 EmbeddingModel::SnowflakeArcticEmbedLQ,
928 ] {
929 assert!(m.query_prefix().is_some());
930 assert!(m.doc_prefix().is_none());
931 }
932 for &m in &[
934 EmbeddingModel::NomicEmbedTextV15,
935 EmbeddingModel::NomicEmbedTextV15Q,
936 ] {
937 assert_eq!(m.query_prefix(), Some("search_query: "));
938 assert_eq!(m.doc_prefix(), Some("search_document: "));
939 }
940 assert!(EmbeddingModel::NomicEmbedTextV1.query_prefix().is_none());
942 assert!(EmbeddingModel::NomicEmbedTextV1.doc_prefix().is_none());
943 for &m in &[
945 EmbeddingModel::BGESmallENV15,
946 EmbeddingModel::MxbaiEmbedLargeV1,
947 ] {
948 assert!(m.query_prefix().is_some());
949 assert!(m.doc_prefix().is_none());
950 }
951 assert!(EmbeddingModel::AllMiniLML6V2.query_prefix().is_none());
953 assert!(EmbeddingModel::AllMiniLML6V2.doc_prefix().is_none());
954 }
955
956 #[test]
957 fn from_str_trait() {
958 let m: EmbeddingModel = "BGESmallENV15".parse().unwrap();
959 assert_eq!(m, EmbeddingModel::BGESmallENV15);
960 }
961
962 #[test]
963 fn display_trait() {
964 assert_eq!(EmbeddingModel::BGESmallENV15.to_string(), "BGESmallENV15");
965 }
966
967 #[test]
968 fn metadata_nonzero() {
969 for &m in EmbeddingModel::ALL {
970 assert!(m.size_mb() > 0, "{m:?}: size_mb is zero");
971 assert!(!m.model_id().is_empty(), "{m:?}: model_id is empty");
972 assert!(!m.model_code().is_empty(), "{m:?}: model_code is empty");
973 assert!(m.max_seq_length() > 0, "{m:?}: max_seq_length is zero");
974 }
975 }
976
977 #[test]
978 fn max_seq_length_values() {
979 assert_eq!(EmbeddingModel::AllMiniLML6V2.max_seq_length(), 256);
980 assert_eq!(EmbeddingModel::AllMpnetBaseV2.max_seq_length(), 384);
981 assert_eq!(EmbeddingModel::BGEM3.max_seq_length(), 8192);
982 assert_eq!(EmbeddingModel::BGESmallENV15.max_seq_length(), 512);
983 }
984
985 #[test]
990 fn mlx_supported_set_is_exact() {
991 let supported: Vec<&str> = EmbeddingModel::ALL
992 .iter()
993 .filter(|m| m.mlx_supported())
994 .map(|m| m.as_str())
995 .collect();
996 assert_eq!(
997 supported,
998 vec![
999 "BGESmallENV15",
1000 "AllMiniLML6V2",
1001 "AllMiniLML6V2Q",
1002 "AllMiniLML12V2",
1003 "AllMiniLML12V2Q",
1004 "BGEBaseENV15",
1005 "BGEBaseENV15Q",
1006 "BGELargeENV15",
1007 "BGELargeENV15Q",
1008 "BGESmallENV15Q",
1009 "ParaphraseMLMiniLML12V2",
1010 "ParaphraseMLMiniLML12V2Q",
1011 "BGESmallZHV15",
1012 "MultilingualE5Small",
1013 "MxbaiEmbedLargeV1",
1014 "MxbaiEmbedLargeV1Q",
1015 "SnowflakeArcticEmbedXS",
1016 "SnowflakeArcticEmbedXSQ",
1017 "SnowflakeArcticEmbedS",
1018 "SnowflakeArcticEmbedSQ",
1019 "SnowflakeArcticEmbedM",
1020 "SnowflakeArcticEmbedMQ",
1021 "SnowflakeArcticEmbedL",
1022 "SnowflakeArcticEmbedLQ",
1023 ]
1024 );
1025 }
1026
1027 #[test]
1031 fn mlx_excludes_non_vanilla_bert() {
1032 for &m in &[
1033 EmbeddingModel::SnowflakeArcticEmbedMLong, EmbeddingModel::SnowflakeArcticEmbedMLongQ,
1035 EmbeddingModel::NomicEmbedTextV1,
1036 EmbeddingModel::NomicEmbedTextV15,
1037 EmbeddingModel::GTEBaseENV15, EmbeddingModel::GTELargeENV15, EmbeddingModel::MultilingualE5Base, EmbeddingModel::MultilingualE5Large, EmbeddingModel::ParaphraseMLMpnetBaseV2, EmbeddingModel::BGEM3, EmbeddingModel::AllMpnetBaseV2, EmbeddingModel::JinaEmbeddingsV2BaseEN, EmbeddingModel::JinaEmbeddingsV2BaseCode,
1046 EmbeddingModel::ModernBertEmbedLarge, EmbeddingModel::EmbeddingGemma300M,
1048 EmbeddingModel::ClipVitB32,
1049 EmbeddingModel::BGELargeZHV15, ] {
1051 assert!(!m.mlx_supported(), "{m:?} must not be MLX-supported");
1052 }
1053 }
1054}