Skip to content
AstraBertPublic

About

Fast, lightweight static text embeddings for Rust and Python

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

29 Commits

Folders and files

Repository files navigation

statembed

Fast, lightweight static text embeddings.

statembed loads pre-trained static embedding models stored in the Safetensors format and produces fixed-length text embeddings via mean-pooling over token-level vectors, with optional L2 normalization. There's no neural network forward pass at inference time (just a lookup-and-average over an embedding matrix) which makes it extremely fast compared to transformer-based embedding models, at some cost to embedding quality.

This repository is a Cargo workspace with two crates:

Crate Language Description
statembed Rust Core library: model loading, tokenization, pooling, normalization.
statembed-py Python (via PyO3) Python bindings: embed texts, or pre-tokenized token IDs.

How it works

  1. Lazy loading — the model file is memory-mapped and the tokenizer is loaded on the first embedding call (or on init()), then kept in memory.
  2. Mean pooling — each token ID maps to a row in the embedding matrix; the rows for all tokens in the input are averaged into a single fixed-length vector.
  3. Optional normalization — when enabled, the resulting vector is L2-normalized.
  4. Decoded table — the embedding matrix is decoded to a flat f32 table, either entirely at load time (small models) or row by row the first time a token is seen (large models).

Rust: statembed

[dependencies]
statembed = "1"
use statembed::StaticEmbedding;

let mut model = StaticEmbedding::from_dir("./my-model", Some(true), None, None)?;
let embedding = model.embed_text("hello world")?;

The model directory must contain model.safetensors and tokenizer.json. Models can also be downloaded directly from the Hugging Face Hub with the hf-hub feature. See crates/statembed/README.md for the full feature list (simd, hf-hub, rayon) and API details.

Python: statembed-py

uv add statembed-py
from statembed_py import StaticEmbedding

model = StaticEmbedding(model_dir="./my-model")  # must contain model.safetensors and tokenizer.json
embedding = model.embed_text("hello world")
embeddings = model.embed_texts(["hello world", "goodbye world"])

If you already tokenize your texts, you can pass token IDs with embed_tokens or embed_tokens_batch, using the tokenizer library you prefer.

See crates/statembed-py/README.md for installation options, building from source, and the full API.

Development

This is a Cargo workspace (resolver = "3"); run standard Cargo commands from the repo root:

cargo build
cargo test
cargo bench -p statembed   # compares against model2vec-rs

Benchmarks

statembed is compared against model2vec-rs (Rust) and model2vec (Python) on minishlab/potion-base-8M, on single texts and on batches, with and without normalization. In our runs it is roughly 3 to 7 times faster on single texts and about 3 times faster on batches. See pages/index.html for the full comparison.

# Rust (Criterion)
cargo bench -p statembed --bench m2vec_benchmark   # model2vec-rs
cargo bench -p statembed --bench embed_benchmark   # statembed
cargo bench -p statembed --features rayon --bench embed_benchmark   # statembed with parallel pooling

# Python (single uv script, builds statembed-py from this repo)
uv run crates/statembed-py/benches/bench_vs_model2vec.py

Results depend on the machine, so run the benchmarks on your own hardware before drawing conclusions. The Rust benchmarks are described in crates/statembed/README.md.

License

MIT

About

Fast, lightweight static text embeddings for Rust and Python

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages