Skip to main content

Fast CPU inference (Rust) for CLIP embeddings, inference-free SPLADE, and BERT fill-mask — drop-in replacement for the transformers / sentence-transformers models in a RAG stack. No PyTorch, no ONNX.

Project description

faster-clip

Fast, dependency-light CPU inference for the models a multilingual RAG stack needs — no PyTorch, no transformers, no sentence-transformers, no ONNX. Since 0.2 the compute is a hand-written Rust engine (a single native extension); tokenization uses the tokenizers crate.

pip install faster-clip

Three drop-in replacements, each numerically matching the original HuggingFace pipeline:

Class Replaces Output
ClipModel SentenceTransformer('clip-ViT-B-32') + …-multilingual-v1 512-d CLIP image / text embeddings (cosine 1.0)
SparseEncoder SparseEncoder('…inference-free-splade…') {token_id: weight} sparse dicts (bit-identical)
FillMask pipeline('fill-mask', 'bert-base-uncased' / 'bert-base-portuguese-cased') top-k {token_str, sequence, score} (identical strings)

Performance

CPU (AMD Ryzen 7 3700X, 8 cores), single item, vs the original torch pipeline:

torch / sentence-transformers faster-clip (Rust)
CLIP text embed ~10 ms ~11 ms (≈ parity)
CLIP image embed ~62 ms ~81 ms
fill-mask (BERT) ~60 ms ~20 ms (3× faster)
SPLADE sparse < 0.05 ms (pure lookup)

No torch/transformers install (multi-GB) — one native wheel. Since 0.4 the 2-D weights are stored as int8 (per-output-channel symmetric quantization, upconverted on the fly in the AVX2 kernels); small layernorm/bias params stay f16. Loading copies everything into owned buffers and drops the source mmap, so nothing of the original f32 file stays resident. Measured steady-state RSS on CPU:

loaded models f32 / torch faster-clip 0.4 (int8)
CLIP image + text ~1.8 GB ~280 MiB
+ SPLADE + fill-mask (en+pt) ~495 MiB

Accuracy is essentially unchanged: CLIP cosine ≥ 0.9997 vs torch, SPLADE bit-identical, fill-mask top-5 exact (en + pt).

CLIP embeddings

from faster_clip import ClipModel

clip = ClipModel()  # lazily downloads image / text weights on first use
text_emb = clip.encode_text(["um carro vermelho", "a red car"])   # (2, 512) list
img_emb  = clip.encode_image([open("photo.jpg", "rb").read()])    # (1, 512) list
  • encode_text(list_of_str) → list of 512-float vectors.
  • encode_image(list_of_image_bytes) → list of 512-float vectors. Pass the raw image bytes (PNG/JPEG/…); decoding + CLIP preprocessing happen in Rust.

Image and multilingual text share the same 512-d space. Normalize yourself for cosine search.

SPLADE sparse encoding (no sparse tensor materialised)

from faster_clip import SparseEncoder
sparse = SparseEncoder()
sparse.encode("banco de dados vetorial")     # -> {'15060': 1.09, '2951': 1.11, ...}

Inference-free: a token→weight lookup, so only the active dims are returned — no dense/sparse vector is ever built. encode, encode_query, encode_document are equivalent; each takes a str or list of str. The weights ship in the wheel.

Fill-mask autocomplete

from faster_clip import FillMask
fm = FillMask()
fm.predict("the weather is very [MASK]", lang="en")
fm.predict("o brasil é um [MASK]", lang="pt")
# -> [{'token_str': 'lixo', 'sequence': 'o brasil é um lixo', 'score': 0.18}, ...]

lang is "en" (bert-base-uncased) or "pt" (neuralmind/bert-base-portuguese-cased).

Model cache

CLIP and BERT weights are downloaded on first use and cached under ~/.cache/faster-clip (override with $FASTER_CLIP_CACHE). Inference releases the GIL, so one instance is safe to share across threads.

License

MIT. Model weights belong to their respective authors (OpenAI / sentence-transformers / neuralmind / Microsoft) under their original licenses.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

faster_clip-0.4.0.tar.gz (396.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

faster_clip-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

File details

Details for the file faster_clip-0.4.0.tar.gz.

File metadata

  • Download URL: faster_clip-0.4.0.tar.gz
  • Upload date:
  • Size: 396.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for faster_clip-0.4.0.tar.gz
Algorithm Hash digest
SHA256 8fe99b146f6b8335e3e1971f9076495196ff622e2e336ced471981f7ad6ffc71
MD5 9f1ce54a7149edb161ee4b199a15ed81
BLAKE2b-256 9fcdc2b866fcc2211d289e60da4925cbdb9ec04c6fdb68ac7126aceba46e20f8

See more details on using hashes here.

File details

Details for the file faster_clip-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for faster_clip-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 45a20b753e5829fd69df7e4cc628af7582acec02aec204f492414c15bc0a3c16
MD5 724cb3286312246a77cfc8d264a91c4c
BLAKE2b-256 571cfe7f01b82f75416d8009fb8a487fddaf5e00205788c76872615d44d7ddaa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page