fastembed-rs

repository·main·Indexed 21 days ago

https://github.com/anush008/fastembed-rs

A high-performance Rust library for generating text (dense and sparse), image, and joint vector embeddings, as well as performing reranking locally using ONNX inference. It supports a wide range of models including BGE, Sentence Transformers, Nomic AI, and Qwen3, with features for quantization, GPU acceleration via DirectML, and in-memory similarity search.

Tokens
12.5K
Snippets
44
Records
56
Agent score
76%

What's inside fastembed

  1. Overview of FastEmbed-rs features

    main

    FastEmbed-rs is a Rust library designed for generating vector embeddings and performing reranking locally.

    Key features include:

    • Synchronous usage: Does not require a dependency on Tokio.
    • Performant ONNX inference: Powered by the ort crate.
    • Fast encodings: Powered by the tokenizers crate.
  2. Use Nomic Embed Text v2 MoE

    main

    The Nomic MoE model is available via the nomic-v2-moe feature flag. It uses the candle backend and supports over 100 languages.

    # Cargo.toml
    [dependencies]
    fastembed = { version = "5", features = ["nomic-v2-moe"] }
    use candle_core::{DType, Device};
    use fastembed::NomicV2MoeTextEmbedding;
    
    let device = Device::Cpu;
    let model = NomicV2MoeTextEmbedding::from_hf(
        "nomic-ai/nomic-embed-text-v2-moe",
        &device,
        DType::F32,
        512,
    )?;
    
    let embeddings = model.embed(&["search_query: ...", "search_document: ..."])?;
  3. Enable DirectML for GPU acceleration on Windows

    main

    To run models on a Windows GPU via DirectML, enable the directml feature in your Cargo.toml and pass a DirectML execution provider during model initialization.

    [dependencies]
    fastembed = { version = "5", features = ["directml"] }
    use fastembed::{TextEmbedding, TextInitOptions, EmbeddingModel};
    use ort::ep::DirectML;
    
    let model = TextEmbedding::try_new(
        TextInitOptions::new(EmbeddingModel::AllMiniLML6V2)
            .with_execution_providers(vec![DirectML::default().into()]),
    )?;
  4. Use Qwen3 embedding models

    main

    Qwen3 models require the qwen3 feature flag. You can use Qwen3TextEmbedding for text-only tasks or Qwen3VLEmbedding for multimodal (text and image) tasks using the candle backend.

    # Cargo.toml
    [dependencies]
    fastembed = { version = "5", features = ["qwen3"] }
    // Text-only usage
    use candle_core::{DType, Device};
    use fastembed::Qwen3TextEmbedding;
    
    let device = Device::Cpu;
    let model = Qwen3TextEmbedding::from_hf(
        "Qwen/Qwen3-Embedding-0.6B",
        &device,
        DType::F32,
        512,
    )?;
    
    let embeddings = model.embed(&["query: ...", "passage: ..."])?;
    
    // Multimodal usage
    use fastembed::Qwen3VLEmbedding;
    let model = Qwen3VLEmbedding::from_hf(
        "Qwen/Qwen3-VL-Embedding-2B",
        &device,
        DType::F32,
        2048,
    )?;
    
    let image_embeddings = model.embed_images(&["tests/assets/image_0.png", "tests/assets/image_1.png"])?;
    let text_embeddings = model.embed_texts(&["query: blue cat", "query: red cat"])?;
  5. Available Embedding Types in FastEmbed

    main

    FastEmbed provides several specialized embedding modules:

    • TextEmbedding: Dense text embeddings (default: BGE small en v1.5).
    • SparseTextEmbedding: Sparse (SPLADE) embeddings for lexical search.
    • Bgem3Embedding: Joint dense + sparse + ColBERT embeddings in a single pass (BGE-M3).
    • ImageEmbedding: Image embeddings (e.g., CLIP, ResNet) via the image-models feature.
    • TextRerank: Cross-encoder reranking of candidates.

    Specialized models like Qwen3 and Nomic v2 MoE are available via the qwen3 and nomic-v2-moe feature flags using a candle backend.

  6. Configure model cache and environment variables

    main

    Models are downloaded on first use and cached locally. You can control the cache location and Hugging Face settings using the following environment variables:

    • FASTEMBED_CACHE_DIR: The cache location (default: .fastembed_cache). This is equivalent to setting with_cache_dir in init options.
    • HF_HOME: Takes precedence over FASTEMBED_CACHE_DIR if set.
    • HF_ENDPOINT: Use this to set a Hugging Face mirror base URL for restricted networks.
  7. Configure pooling strategies for embedding generation

    main

    The Pooling enum defines the strategy used to reduce token-level embeddings into a single vector (sentence embedding).

    Available strategies:

    • Pooling::Cls: Uses the [CLS] token (typically the first token in the sequence) as the representation for the entire sequence.
    • Pooling::Mean: Calculates the element-wise arithmetic mean of the token-level embeddings, weighted by the attention mask to ignore padding tokens.

    By default, the library uses Pooling::Cls for backward compatibility.

    use fastembed::Pooling;
    
    // Example of selecting a strategy
    let strategy = Pooling::Mean;
    // or use the default
    let default_strategy = Pooling::default(); // Returns Pooling::Cls
  8. Understand the Bgem3EmbeddingOutput structure

    main

    When using the Bgem3Embedding model, the output is returned as a Bgem3EmbeddingOutput struct. This struct provides three distinct types of representations from a single model pass:

    • dense: A Vec<Vec<f32>> containing dense vector embeddings.
    • sparse: A Vec<SparseEmbedding> containing lexical (sparse) embeddings.
    • colbert: A Vec<Vec<Vec<f32>>> containing multi-vector (ColBERT) representations.
  9. Use BGE-M3 Joint Embeddings

    main

    The BGE-M3 model produces dense, sparse, and ColBERT embeddings in a single forward pass. Use Bgem3Embedding and Bgem3InitOptions.

    Note: The default quantized model (BGEM3Q) is optimized for CPUs. For GPU inference, you must load a custom exported model (FP32, FP16, or INT8) via try_new_from_path.

    use fastembed::{Bgem3Embedding, Bgem3InitOptions, Bgem3Model};
    
    let mut model = Bgem3Embedding::try_new(
        Bgem3InitOptions::new(Bgem3Model::BGEM3Q)
            .with_max_length(1024)
            .with_show_download_progress(true),
    )?;
    
    let documents = vec![
        "Hello, World!",
        "This is an example passage.",
        "fastembed-rs is licensed under Apache 2.0",
        "i dont know"
    ];
    
    let output = model.embed(documents, None)?;
    
    println!("Dense dimension: {}", output.dense[0].len());
    println!("Sparse non-zero tokens: {}", output.sparse[0].indices.len());
    println!("ColBERT token count: {}", output.colbert[0].len());
  10. Perform similarity search in-memory

    main

    The similarity module provides helpers for scoring and ranking vectors returned by embed.

    • cosine_similarity(v1, v2): Returns a score between -1.0 and 1.0 (higher is closer).
    • top_k(query, corpus, k): Returns the top k (index, score) pairs, sorted from best to worst.
    use fastembed::similarity::{cosine_similarity, top_k};
    
    // `embeddings` is the Vec<Embedding> from model.embed(...)
    let query = &embeddings[0];
    
    // Score two vectors directly ([-1.0, 1.0], higher = closer)
    let score = cosine_similarity(query, &embeddings[1]);
    
    // Or rank the corpus: (index, score) pairs, best first
    let hits = top_k(query, &embeddings, 5);
    println!("Closest: {:?}", hits);
  11. Generate Text Embeddings

    main

    Use the TextEmbedding struct to generate dense vector embeddings from text. You can initialize with default options or provide TextInitOptions to specify a model (e.g., EmbeddingModel::AllMiniLML6V2), show download progress, or set the number of intra-threads. It is recommended to use prefixes like passage: and query: for better performance.

    use fastembed::{TextEmbedding, TextInitOptions, EmbeddingModel};
    
    // With custom options
    let mut model = TextEmbedding::try_new(
        TextInitOptions::new(EmbeddingModel::AllMiniLML6V2)
            .with_show_download_progress(true)
            .with_intra_threads(4),
    )?;
    
    let documents = vec![
        "passage: Hello, World!",
        "query: Hello, World!",
        "passage: This is an example passage.",
        "fastembed-rs is licensed under Apache 2.0"
    ];
    
    // Generate embeddings with the default batch size, 256
    let embeddings = model.embed(documents, None)?;
    
    println!("Embeddings length: {}", embeddings.len());
    println!("Embedding dimension: {}", embeddings[0].len());