Metadata-Version: 2.4
Name: faster-clip
Version: 0.1.0
Summary: Dependency-light pure-numpy CPU inference for CLIP embeddings, inference-free SPLADE, and BERT fill-mask — a drop-in replacement for the transformers / sentence-transformers models in a RAG stack (no PyTorch, no ONNX).
Author: cnmoro
License: MIT
Project-URL: Homepage, https://github.com/cnmoro/faster-clip
Project-URL: Repository, https://github.com/cnmoro/faster-clip
Keywords: clip,splade,sparse-embeddings,fill-mask,embeddings,rag,numpy,no-torch
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Intended Audience :: Developers
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: tokenizers
Requires-Dist: safetensors
Requires-Dist: huggingface_hub
Requires-Dist: pillow
Dynamic: license-file

# faster-clip

Dependency-light, **pure-numpy** CPU inference for the models a multilingual RAG
stack typically needs — with **no PyTorch, no transformers, no sentence-transformers,
no ONNX**. Just `numpy` + `tokenizers` (+ `safetensors` / `huggingface_hub` for
weights, `pillow` for images).

```bash
pip install faster-clip
```

It provides three drop-in replacements, each **numerically matching** the original
HuggingFace pipeline:

| Class | Replaces | Output |
|---|---|---|
| `ClipModel` | `SentenceTransformer('clip-ViT-B-32')` + `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**) |

Model weights are downloaded from HuggingFace and cached on first use (the SPLADE
weights, ~120 KB, ship inside the wheel).

## CLIP embeddings

```python
from faster_clip import ClipModel
from PIL import Image

clip = ClipModel()  # lazily downloads image / text weights on first use

text_emb = clip.encode_text(["um carro vermelho", "a red car"])   # (2, 512)
img_emb  = clip.encode_image(Image.open("photo.jpg"))             # (1, 512)
```

Image and multilingual text land in the **same** 512-d CLIP space, so you can do
cross-modal search. (Normalize yourself if you need unit vectors.)

## SPLADE sparse encoding (no sparse tensor materialized)

The model is an *inference-free* SPLADE: encoding is a pure token→weight lookup,
so the result is just a dict of the active dimensions — no dense/sparse vector is
ever built.

```python
from faster_clip import SparseEncoder

sparse = SparseEncoder()
sparse.encode("banco de dados vetorial")
# -> {'15060': 1.09, '2951': 1.11, '2078': 1.04, ...}   # {token_id: weight}
```

`encode`, `encode_query`, and `encode_document` are equivalent (the model's query
route is the default) and accept a string or a list of strings.

## Fill-mask autocomplete

```python
from faster_clip import FillMask

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

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

## Model cache

Weights are cached by `huggingface_hub` under `~/.cache/huggingface`. To run
offline, pre-download the models once (or set `HF_HOME`). CLIP vision/text and the
BERT MLMs are fetched on first use of each capability.

## License

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