Skip to main content

fastembed/models/
text_embedding.rs

1use std::{collections::HashMap, convert::TryFrom, fmt::Display, str::FromStr, sync::OnceLock};
2
3use super::{model_info::ModelInfo, ModelTrait};
4
5/// Lazy static list of all available models.
6static MODEL_MAP: OnceLock<HashMap<EmbeddingModel, ModelInfo<EmbeddingModel>>> = OnceLock::new();
7
8#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)]
9pub enum EmbeddingModel {
10    /// sentence-transformers/all-MiniLM-L6-v2
11    AllMiniLML6V2,
12    /// Quantized sentence-transformers/all-MiniLM-L6-v2
13    AllMiniLML6V2Q,
14    /// sentence-transformers/all-MiniLM-L12-v2
15    AllMiniLML12V2,
16    /// Quantized sentence-transformers/all-MiniLM-L12-v2
17    AllMiniLML12V2Q,
18    /// sentence-transformers/all-mpnet-base-v2
19    AllMpnetBaseV2,
20    /// BAAI/bge-base-en-v1.5
21    BGEBaseENV15,
22    /// Quantized BAAI/bge-base-en-v1.5
23    BGEBaseENV15Q,
24    /// BAAI/bge-large-en-v1.5
25    BGELargeENV15,
26    /// Quantized BAAI/bge-large-en-v1.5
27    BGELargeENV15Q,
28    /// BAAI/bge-small-en-v1.5 - Default
29    #[default]
30    BGESmallENV15,
31    /// Quantized BAAI/bge-small-en-v1.5
32    BGESmallENV15Q,
33    /// nomic-ai/nomic-embed-text-v1
34    NomicEmbedTextV1,
35    /// nomic-ai/nomic-embed-text-v1.5
36    NomicEmbedTextV15,
37    /// Quantized v1.5 nomic-ai/nomic-embed-text-v1.5
38    NomicEmbedTextV15Q,
39    /// sentence-transformers/paraphrase-MiniLM-L6-v2
40    ParaphraseMLMiniLML12V2,
41    /// Quantized sentence-transformers/paraphrase-MiniLM-L6-v2
42    ParaphraseMLMiniLML12V2Q,
43    /// sentence-transformers/paraphrase-mpnet-base-v2
44    ParaphraseMLMpnetBaseV2,
45    /// BAAI/bge-small-zh-v1.5
46    BGESmallZHV15,
47    /// BAAI/bge-large-zh-v1.5
48    BGELargeZHV15,
49    /// BAAI/bge-m3
50    BGEM3,
51    /// lightonai/modernbert-embed-large
52    ModernBertEmbedLarge,
53    /// intfloat/multilingual-e5-small
54    MultilingualE5Small,
55    /// intfloat/multilingual-e5-base
56    MultilingualE5Base,
57    /// intfloat/multilingual-e5-large
58    MultilingualE5Large,
59    /// mixedbread-ai/mxbai-embed-large-v1
60    MxbaiEmbedLargeV1,
61    /// Quantized mixedbread-ai/mxbai-embed-large-v1
62    MxbaiEmbedLargeV1Q,
63    /// Alibaba-NLP/gte-base-en-v1.5
64    GTEBaseENV15,
65    /// Quantized Alibaba-NLP/gte-base-en-v1.5
66    GTEBaseENV15Q,
67    /// Alibaba-NLP/gte-large-en-v1.5
68    GTELargeENV15,
69    /// Quantized Alibaba-NLP/gte-large-en-v1.5
70    GTELargeENV15Q,
71    /// Qdrant/clip-ViT-B-32-text
72    ClipVitB32,
73    /// jinaai/jina-embeddings-v2-base-code
74    JinaEmbeddingsV2BaseCode,
75    /// jinaai/jina-embeddings-v2-base-en
76    JinaEmbeddingsV2BaseEN,
77    /// onnx-community/embeddinggemma-300m-ONNX
78    EmbeddingGemma300M,
79    /// Quantized (4-bit) onnx-community/embeddinggemma-300m-ONNX
80    EmbeddingGemma300MQ4,
81    /// Quantized onnx-community/embeddinggemma-300m-ONNX
82    EmbeddingGemma300MQ,
83    /// snowflake/snowflake-arctic-embed-xs
84    SnowflakeArcticEmbedXS,
85    /// Quantized snowflake/snowflake-arctic-embed-xs
86    SnowflakeArcticEmbedXSQ,
87    /// snowflake/snowflake-arctic-embed-s
88    SnowflakeArcticEmbedS,
89    /// Quantized snowflake/snowflake-arctic-embed-s
90    SnowflakeArcticEmbedSQ,
91    /// snowflake/snowflake-arctic-embed-m
92    SnowflakeArcticEmbedM,
93    /// Quantized snowflake/snowflake-arctic-embed-m
94    SnowflakeArcticEmbedMQ,
95    /// snowflake/snowflake-arctic-embed-m-long
96    SnowflakeArcticEmbedMLong,
97    /// Quantized snowflake/snowflake-arctic-embed-m-long
98    SnowflakeArcticEmbedMLongQ,
99    /// snowflake/snowflake-arctic-embed-l
100    SnowflakeArcticEmbedL,
101    /// Quantized snowflake/snowflake-arctic-embed-l
102    SnowflakeArcticEmbedLQ,
103}
104
105/// Centralized function to initialize the models map.
106fn init_models_map() -> HashMap<EmbeddingModel, ModelInfo<EmbeddingModel>> {
107    let models_list = vec![
108        ModelInfo {
109            model: EmbeddingModel::AllMiniLML6V2,
110            dim: 384,
111            description: String::from("Sentence Transformer model, MiniLM-L6-v2"),
112            model_code: String::from("Qdrant/all-MiniLM-L6-v2-onnx"),
113            model_file: String::from("model.onnx"),
114            additional_files: Vec::new(),
115            output_key: None,
116        },
117        ModelInfo {
118            model: EmbeddingModel::AllMiniLML6V2Q,
119            dim: 384,
120            description: String::from("Quantized Sentence Transformer model, MiniLM-L6-v2"),
121            model_code: String::from("Xenova/all-MiniLM-L6-v2"),
122            model_file: String::from("onnx/model_quantized.onnx"),
123            additional_files: Vec::new(),
124            output_key: None,
125        },
126        ModelInfo {
127            model: EmbeddingModel::AllMiniLML12V2,
128            dim: 384,
129            description: String::from("Sentence Transformer model, MiniLM-L12-v2"),
130            model_code: String::from("Xenova/all-MiniLM-L12-v2"),
131            model_file: String::from("onnx/model.onnx"),
132            additional_files: Vec::new(),
133            output_key: None,
134        },
135        ModelInfo {
136            model: EmbeddingModel::AllMiniLML12V2Q,
137            dim: 384,
138            description: String::from("Quantized Sentence Transformer model, MiniLM-L12-v2"),
139            model_code: String::from("Xenova/all-MiniLM-L12-v2"),
140            model_file: String::from("onnx/model_quantized.onnx"),
141            additional_files: Vec::new(),
142            output_key: None,
143        },
144        ModelInfo {
145            model: EmbeddingModel::AllMpnetBaseV2,
146            dim: 768,
147            description: String::from("Sentence Transformer model, mpnet-base-v2"),
148            model_code: String::from("Xenova/all-mpnet-base-v2"),
149            model_file: String::from("onnx/model.onnx"),
150            additional_files: Vec::new(),
151            output_key: None,
152        },
153        ModelInfo {
154            model: EmbeddingModel::BGEBaseENV15,
155            dim: 768,
156            description: String::from("v1.5 release of the base English model"),
157            model_code: String::from("Xenova/bge-base-en-v1.5"),
158            model_file: String::from("onnx/model.onnx"),
159            additional_files: Vec::new(),
160            output_key: None,
161        },
162        ModelInfo {
163            model: EmbeddingModel::BGEBaseENV15Q,
164            dim: 768,
165            description: String::from("Quantized v1.5 release of the large English model"),
166            model_code: String::from("Qdrant/bge-base-en-v1.5-onnx-Q"),
167            model_file: String::from("model_optimized.onnx"),
168            additional_files: Vec::new(),
169            output_key: None,
170        },
171        ModelInfo {
172            model: EmbeddingModel::BGELargeENV15,
173            dim: 1024,
174            description: String::from("v1.5 release of the large English model"),
175            model_code: String::from("Xenova/bge-large-en-v1.5"),
176            model_file: String::from("onnx/model.onnx"),
177            additional_files: Vec::new(),
178            output_key: None,
179        },
180        ModelInfo {
181            model: EmbeddingModel::BGELargeENV15Q,
182            dim: 1024,
183            description: String::from("Quantized v1.5 release of the large English model"),
184            model_code: String::from("Qdrant/bge-large-en-v1.5-onnx-Q"),
185            model_file: String::from("model_optimized.onnx"),
186            additional_files: Vec::new(),
187            output_key: None,
188        },
189        ModelInfo {
190            model: EmbeddingModel::BGESmallENV15,
191            dim: 384,
192            description: String::from("v1.5 release of the fast and default English model"),
193            model_code: String::from("Xenova/bge-small-en-v1.5"),
194            model_file: String::from("onnx/model.onnx"),
195            additional_files: Vec::new(),
196            output_key: None,
197        },
198        ModelInfo {
199            model: EmbeddingModel::BGESmallENV15Q,
200            dim: 384,
201            description: String::from(
202                "Quantized v1.5 release of the fast and default English model",
203            ),
204            model_code: String::from("Qdrant/bge-small-en-v1.5-onnx-Q"),
205            model_file: String::from("model_optimized.onnx"),
206            additional_files: Vec::new(),
207            output_key: None,
208        },
209        ModelInfo {
210            model: EmbeddingModel::NomicEmbedTextV1,
211            dim: 768,
212            description: String::from("8192 context length english model"),
213            model_code: String::from("nomic-ai/nomic-embed-text-v1"),
214            model_file: String::from("onnx/model.onnx"),
215            additional_files: Vec::new(),
216            output_key: None,
217        },
218        ModelInfo {
219            model: EmbeddingModel::NomicEmbedTextV15,
220            dim: 768,
221            description: String::from("v1.5 release of the 8192 context length english model"),
222            model_code: String::from("nomic-ai/nomic-embed-text-v1.5"),
223            model_file: String::from("onnx/model.onnx"),
224            additional_files: Vec::new(),
225            output_key: None,
226        },
227        ModelInfo {
228            model: EmbeddingModel::NomicEmbedTextV15Q,
229            dim: 768,
230            description: String::from(
231                "Quantized v1.5 release of the 8192 context length english model",
232            ),
233            model_code: String::from("nomic-ai/nomic-embed-text-v1.5"),
234            model_file: String::from("onnx/model_quantized.onnx"),
235            additional_files: Vec::new(),
236            output_key: None,
237        },
238        ModelInfo {
239            model: EmbeddingModel::ParaphraseMLMiniLML12V2Q,
240            dim: 384,
241            description: String::from("Quantized Multi-lingual model"),
242            model_code: String::from("Qdrant/paraphrase-multilingual-MiniLM-L12-v2-onnx-Q"),
243            model_file: String::from("model_optimized.onnx"),
244            additional_files: Vec::new(),
245            output_key: None,
246        },
247        ModelInfo {
248            model: EmbeddingModel::ParaphraseMLMiniLML12V2,
249            dim: 384,
250            description: String::from("Multi-lingual model"),
251            model_code: String::from("Xenova/paraphrase-multilingual-MiniLM-L12-v2"),
252            model_file: String::from("onnx/model.onnx"),
253            additional_files: Vec::new(),
254            output_key: None,
255        },
256        ModelInfo {
257            model: EmbeddingModel::ParaphraseMLMpnetBaseV2,
258            dim: 768,
259            description: String::from(
260                "Sentence-transformers model for tasks like clustering or semantic search",
261            ),
262            model_code: String::from("Xenova/paraphrase-multilingual-mpnet-base-v2"),
263            model_file: String::from("onnx/model.onnx"),
264            additional_files: Vec::new(),
265            output_key: None,
266        },
267        ModelInfo {
268            model: EmbeddingModel::BGESmallZHV15,
269            dim: 512,
270            description: String::from("v1.5 release of the small Chinese model"),
271            model_code: String::from("Xenova/bge-small-zh-v1.5"),
272            model_file: String::from("onnx/model.onnx"),
273            additional_files: Vec::new(),
274            output_key: None,
275        },
276        ModelInfo {
277            model: EmbeddingModel::BGELargeZHV15,
278            dim: 1024,
279            description: String::from("v1.5 release of the large Chinese model"),
280            model_code: String::from("Xenova/bge-large-zh-v1.5"),
281            model_file: String::from("onnx/model.onnx"),
282            additional_files: Vec::new(),
283            output_key: None,
284        },
285        ModelInfo {
286            model: EmbeddingModel::BGEM3,
287            dim: 1024,
288            description: String::from(
289                "Multilingual M3 model with 8192 context length, supports 100+ languages",
290            ),
291            model_code: String::from("BAAI/bge-m3"),
292            model_file: String::from("onnx/model.onnx"),
293            additional_files: vec![
294                "onnx/model.onnx_data".to_string(),
295                "onnx/Constant_7_attr__value".to_string(),
296            ],
297            output_key: None,
298        },
299        ModelInfo {
300            model: EmbeddingModel::ModernBertEmbedLarge,
301            dim: 1024,
302            description: String::from("Large model of ModernBert Text Embeddings"),
303            model_code: String::from("lightonai/modernbert-embed-large"),
304            model_file: String::from("onnx/model.onnx"),
305            additional_files: Vec::new(),
306            output_key: None,
307        },
308        ModelInfo {
309            model: EmbeddingModel::MultilingualE5Small,
310            dim: 384,
311            description: String::from("Small model of multilingual E5 Text Embeddings"),
312            model_code: String::from("intfloat/multilingual-e5-small"),
313            model_file: String::from("onnx/model.onnx"),
314            additional_files: Vec::new(),
315            output_key: None,
316        },
317        ModelInfo {
318            model: EmbeddingModel::MultilingualE5Base,
319            dim: 768,
320            description: String::from("Base model of multilingual E5 Text Embeddings"),
321            model_code: String::from("intfloat/multilingual-e5-base"),
322            model_file: String::from("onnx/model.onnx"),
323            additional_files: Vec::new(),
324            output_key: None,
325        },
326        ModelInfo {
327            model: EmbeddingModel::MultilingualE5Large,
328            dim: 1024,
329            description: String::from("Large model of multilingual E5 Text Embeddings"),
330            model_code: String::from("Qdrant/multilingual-e5-large-onnx"),
331            model_file: String::from("model.onnx"),
332            additional_files: vec!["model.onnx_data".to_string()],
333            output_key: None,
334        },
335        ModelInfo {
336            model: EmbeddingModel::MxbaiEmbedLargeV1,
337            dim: 1024,
338            description: String::from("Large English embedding model from MixedBreed.ai"),
339            model_code: String::from("mixedbread-ai/mxbai-embed-large-v1"),
340            model_file: String::from("onnx/model.onnx"),
341            additional_files: Vec::new(),
342            output_key: None,
343        },
344        ModelInfo {
345            model: EmbeddingModel::MxbaiEmbedLargeV1Q,
346            dim: 1024,
347            description: String::from("Quantized Large English embedding model from MixedBreed.ai"),
348            model_code: String::from("mixedbread-ai/mxbai-embed-large-v1"),
349            model_file: String::from("onnx/model_quantized.onnx"),
350            additional_files: Vec::new(),
351            output_key: None,
352        },
353        ModelInfo {
354            model: EmbeddingModel::GTEBaseENV15,
355            dim: 768,
356            description: String::from("Large multilingual embedding model from Alibaba"),
357            model_code: String::from("Alibaba-NLP/gte-base-en-v1.5"),
358            model_file: String::from("onnx/model.onnx"),
359            additional_files: Vec::new(),
360            output_key: None,
361        },
362        ModelInfo {
363            model: EmbeddingModel::GTEBaseENV15Q,
364            dim: 768,
365            description: String::from("Quantized Large multilingual embedding model from Alibaba"),
366            model_code: String::from("Alibaba-NLP/gte-base-en-v1.5"),
367            model_file: String::from("onnx/model_quantized.onnx"),
368            additional_files: Vec::new(),
369            output_key: None,
370        },
371        ModelInfo {
372            model: EmbeddingModel::GTELargeENV15,
373            dim: 1024,
374            description: String::from("Large multilingual embedding model from Alibaba"),
375            model_code: String::from("Alibaba-NLP/gte-large-en-v1.5"),
376            model_file: String::from("onnx/model.onnx"),
377            additional_files: Vec::new(),
378            output_key: None,
379        },
380        ModelInfo {
381            model: EmbeddingModel::GTELargeENV15Q,
382            dim: 1024,
383            description: String::from("Quantized Large multilingual embedding model from Alibaba"),
384            model_code: String::from("Alibaba-NLP/gte-large-en-v1.5"),
385            model_file: String::from("onnx/model_quantized.onnx"),
386            additional_files: Vec::new(),
387            output_key: None,
388        },
389        ModelInfo {
390            model: EmbeddingModel::ClipVitB32,
391            dim: 512,
392            description: String::from("CLIP text encoder based on ViT-B/32"),
393            model_code: String::from("Qdrant/clip-ViT-B-32-text"),
394            model_file: String::from("model.onnx"),
395            additional_files: Vec::new(),
396            output_key: None,
397        },
398        ModelInfo {
399            model: EmbeddingModel::JinaEmbeddingsV2BaseCode,
400            dim: 768,
401            description: String::from("Jina embeddings v2 base code"),
402            model_code: String::from("jinaai/jina-embeddings-v2-base-code"),
403            model_file: String::from("onnx/model.onnx"),
404            additional_files: Vec::new(),
405            output_key: None,
406        },
407        ModelInfo {
408            model: EmbeddingModel::JinaEmbeddingsV2BaseEN,
409            dim: 768,
410            description: String::from("Jina embeddings v2 base English"),
411            model_code: String::from("jinaai/jina-embeddings-v2-base-en"),
412            model_file: String::from("model.onnx"),
413            additional_files: Vec::new(),
414            output_key: None,
415        },
416        ModelInfo {
417            model: EmbeddingModel::EmbeddingGemma300M,
418            dim: 768,
419            description: String::from("EmbeddingGemma is a 300M parameter from Google"),
420            model_code: String::from("onnx-community/embeddinggemma-300m-ONNX"),
421            model_file: String::from("onnx/model.onnx"),
422            additional_files: vec!["onnx/model.onnx_data".to_string()],
423            output_key: Some(crate::OutputKey::ByName("sentence_embedding")),
424        },
425        ModelInfo {
426            model: EmbeddingModel::EmbeddingGemma300MQ4,
427            dim: 768,
428            description: String::from(
429                "Quantized (4-bit) EmbeddingGemma is a 300M parameter from Google",
430            ),
431            model_code: String::from("onnx-community/embeddinggemma-300m-ONNX"),
432            model_file: String::from("onnx/model_q4.onnx"),
433            additional_files: vec!["onnx/model_q4.onnx_data".to_string()],
434            output_key: Some(crate::OutputKey::ByName("sentence_embedding")),
435        },
436        ModelInfo {
437            model: EmbeddingModel::EmbeddingGemma300MQ,
438            dim: 768,
439            description: String::from("Quantized EmbeddingGemma is a 300M parameter from Google"),
440            model_code: String::from("onnx-community/embeddinggemma-300m-ONNX"),
441            model_file: String::from("onnx/model_quantized.onnx"),
442            additional_files: vec!["onnx/model_quantized.onnx_data".to_string()],
443            output_key: Some(crate::OutputKey::ByName("sentence_embedding")),
444        },
445        ModelInfo {
446            model: EmbeddingModel::SnowflakeArcticEmbedXS,
447            dim: 384,
448            description: String::from("Snowflake Arctic embed model, xs"),
449            model_code: String::from("snowflake/snowflake-arctic-embed-xs"),
450            model_file: String::from("onnx/model.onnx"),
451            additional_files: Vec::new(),
452            output_key: None,
453        },
454        ModelInfo {
455            model: EmbeddingModel::SnowflakeArcticEmbedXSQ,
456            dim: 384,
457            description: String::from("Quantized Snowflake Arctic embed model, xs"),
458            model_code: String::from("snowflake/snowflake-arctic-embed-xs"),
459            model_file: String::from("onnx/model_quantized.onnx"),
460            additional_files: Vec::new(),
461            output_key: None,
462        },
463        ModelInfo {
464            model: EmbeddingModel::SnowflakeArcticEmbedS,
465            dim: 384,
466            description: String::from("Snowflake Arctic embed model, small"),
467            model_code: String::from("snowflake/snowflake-arctic-embed-s"),
468            model_file: String::from("onnx/model.onnx"),
469            additional_files: Vec::new(),
470            output_key: None,
471        },
472        ModelInfo {
473            model: EmbeddingModel::SnowflakeArcticEmbedSQ,
474            dim: 384,
475            description: String::from("Quantized Snowflake Arctic embed model, small"),
476            model_code: String::from("snowflake/snowflake-arctic-embed-s"),
477            model_file: String::from("onnx/model_quantized.onnx"),
478            additional_files: Vec::new(),
479            output_key: None,
480        },
481        ModelInfo {
482            model: EmbeddingModel::SnowflakeArcticEmbedM,
483            dim: 768,
484            description: String::from("Snowflake Arctic embed model, medium"),
485            model_code: String::from("Snowflake/snowflake-arctic-embed-m"),
486            model_file: String::from("onnx/model.onnx"),
487            additional_files: Vec::new(),
488            output_key: None,
489        },
490        ModelInfo {
491            model: EmbeddingModel::SnowflakeArcticEmbedMQ,
492            dim: 768,
493            description: String::from("Quantized Snowflake Arctic embed model, medium"),
494            model_code: String::from("Snowflake/snowflake-arctic-embed-m"),
495            model_file: String::from("onnx/model_quantized.onnx"),
496            additional_files: Vec::new(),
497            output_key: None,
498        },
499        ModelInfo {
500            model: EmbeddingModel::SnowflakeArcticEmbedMLong,
501            dim: 768,
502            description: String::from("Snowflake Arctic embed model, medium with 2048 context"),
503            model_code: String::from("snowflake/snowflake-arctic-embed-m-long"),
504            model_file: String::from("onnx/model.onnx"),
505            additional_files: Vec::new(),
506            output_key: None,
507        },
508        ModelInfo {
509            model: EmbeddingModel::SnowflakeArcticEmbedMLongQ,
510            dim: 768,
511            description: String::from(
512                "Quantized Snowflake Arctic embed model, medium with 2048 context",
513            ),
514            model_code: String::from("snowflake/snowflake-arctic-embed-m-long"),
515            model_file: String::from("onnx/model_quantized.onnx"),
516            additional_files: Vec::new(),
517            output_key: None,
518        },
519        ModelInfo {
520            model: EmbeddingModel::SnowflakeArcticEmbedL,
521            dim: 1024,
522            description: String::from("Snowflake Arctic embed model, large"),
523            model_code: String::from("snowflake/snowflake-arctic-embed-l"),
524            model_file: String::from("onnx/model.onnx"),
525            additional_files: Vec::new(),
526            output_key: None,
527        },
528        ModelInfo {
529            model: EmbeddingModel::SnowflakeArcticEmbedLQ,
530            dim: 1024,
531            description: String::from("Quantized Snowflake Arctic embed model, large"),
532            model_code: String::from("snowflake/snowflake-arctic-embed-l"),
533            model_file: String::from("onnx/model_quantized.onnx"),
534            additional_files: Vec::new(),
535            output_key: None,
536        },
537    ];
538
539    // TODO: Use when out in stable
540    // assert_eq!(
541    //     std::mem::variant_count::<EmbeddingModel>(),
542    //     models_list.len(),
543    //     "models::models() is not exhaustive"
544    // );
545
546    models_list
547        .into_iter()
548        .fold(HashMap::new(), |mut map, model| {
549            // Insert the model into the map
550            map.insert(model.model.clone(), model);
551            map
552        })
553}
554
555/// Get a map of all available models.
556pub fn models_map() -> &'static HashMap<EmbeddingModel, ModelInfo<EmbeddingModel>> {
557    MODEL_MAP.get_or_init(init_models_map)
558}
559
560/// Get a list of all available models.
561///
562/// This will assign new memory to the models list; where possible, use
563/// [`models_map`] instead.
564pub fn models_list() -> Vec<ModelInfo<EmbeddingModel>> {
565    models_map().values().cloned().collect()
566}
567
568impl ModelTrait for EmbeddingModel {
569    type Model = Self;
570
571    /// Get model information by model code.
572    fn get_model_info(model: &EmbeddingModel) -> Option<&ModelInfo<EmbeddingModel>> {
573        models_map().get(model)
574    }
575}
576
577impl Display for EmbeddingModel {
578    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
579        write!(f, "{:?}", self)
580    }
581}
582
583impl FromStr for EmbeddingModel {
584    type Err = String;
585
586    fn from_str(s: &str) -> Result<Self, Self::Err> {
587        models_map()
588            .keys()
589            .find(|m| format!("{:?}", m).eq_ignore_ascii_case(s))
590            .cloned()
591            .ok_or_else(|| format!("Unknown embedding model: {s}"))
592    }
593}
594
595impl TryFrom<String> for EmbeddingModel {
596    type Error = String;
597
598    fn try_from(value: String) -> Result<Self, Self::Error> {
599        value.parse()
600    }
601}