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.
Metadata
Release files for faster-clip 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| faster_clip-0.4.0.tar.gz | 396.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| faster_clip-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details |
Total release size: 3.9 MB
Release files / faster_clip-0.4.0.tar.gz
| Download URL | faster_clip-0.4.0.tar.gz |
|---|---|
| Size | 396.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8fe99b146f6b8335e3e1971f9076495196ff622e2e336ced471981f7ad6ffc71
|
|
BLAKE2b-256 checksum How to use checksums |
9fcdc2b866fcc2211d289e60da4925cbdb9ec04c6fdb68ac7126aceba46e20f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / faster_clip-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | faster_clip-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 3.5 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
45a20b753e5829fd69df7e4cc628af7582acec02aec204f492414c15bc0a3c16
|
|
BLAKE2b-256 checksum How to use checksums |
571cfe7f01b82f75416d8009fb8a487fddaf5e00205788c76872615d44d7ddaa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Security for faster-clip 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.