faster-clip 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- faster_clip/__init__.py +17 -0
- faster_clip/_nn.py +51 -0
- faster_clip/assets/splade_tokenizer.json +30684 -0
- faster_clip/assets/splade_weight.npy +0 -0
- faster_clip/clip.py +140 -0
- faster_clip/fillmask.py +101 -0
- faster_clip/sparse.py +48 -0
- faster_clip-0.1.0.dist-info/METADATA +103 -0
- faster_clip-0.1.0.dist-info/RECORD +12 -0
- faster_clip-0.1.0.dist-info/WHEEL +5 -0
- faster_clip-0.1.0.dist-info/licenses/LICENSE +21 -0
- faster_clip-0.1.0.dist-info/top_level.txt +1 -0
faster_clip/__init__.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""faster-clip — dependency-light CPU replacements (pure numpy) for the
|
|
2
|
+
transformers / sentence-transformers models used in the RAG stack:
|
|
3
|
+
|
|
4
|
+
* :class:`ClipModel` — CLIP image + multilingual-text embeddings (512-d).
|
|
5
|
+
* :class:`SparseEncoder` — inference-free SPLADE sparse ``{token_id: weight}`` dicts.
|
|
6
|
+
* :class:`FillMask` — BERT masked-LM autocomplete (en / pt).
|
|
7
|
+
|
|
8
|
+
No PyTorch, no transformers, no ONNX — just numpy + tokenizers (+ safetensors,
|
|
9
|
+
huggingface_hub for weights, pillow for images).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from .clip import ClipModel
|
|
13
|
+
from .fillmask import FillMask
|
|
14
|
+
from .sparse import SparseEncoder
|
|
15
|
+
|
|
16
|
+
__all__ = ["ClipModel", "SparseEncoder", "FillMask"]
|
|
17
|
+
__version__ = "0.1.0"
|
faster_clip/_nn.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Minimal numpy neural-net primitives shared by the encoders."""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def layer_norm(x, w, b, eps=1e-5):
|
|
7
|
+
mu = x.mean(-1, keepdims=True)
|
|
8
|
+
var = x.var(-1, keepdims=True) # population variance (ddof=0), matches torch
|
|
9
|
+
return (x - mu) / np.sqrt(var + eps) * w + b
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def quick_gelu(x):
|
|
13
|
+
return x * (1.0 / (1.0 + np.exp(-1.702 * x)))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _erf(x):
|
|
17
|
+
# Abramowitz & Stegun 7.1.26, |error| < 1.5e-7
|
|
18
|
+
s = np.sign(x)
|
|
19
|
+
x = np.abs(x)
|
|
20
|
+
t = 1.0 / (1.0 + 0.3275911 * x)
|
|
21
|
+
y = 1.0 - (((((1.061405429 * t - 1.453152027) * t) + 1.421413741) * t
|
|
22
|
+
- 0.284496736) * t + 0.254829592) * t * np.exp(-x * x)
|
|
23
|
+
return s * y
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def gelu(x):
|
|
27
|
+
return 0.5 * x * (1.0 + _erf(x / np.sqrt(2.0)))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def softmax(x, axis=-1):
|
|
31
|
+
x = x - x.max(axis=axis, keepdims=True)
|
|
32
|
+
e = np.exp(x)
|
|
33
|
+
return e / e.sum(axis=axis, keepdims=True)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def multi_head_attention(x, wq, bq, wk, bk, wv, bv, wo, bo, n_heads):
|
|
37
|
+
"""Self-attention over a single (seq, dim) sequence. Weights are torch [out, in]."""
|
|
38
|
+
seq, dim = x.shape
|
|
39
|
+
hd = dim // n_heads
|
|
40
|
+
q = (x @ wq.T + bq).reshape(seq, n_heads, hd).transpose(1, 0, 2)
|
|
41
|
+
k = (x @ wk.T + bk).reshape(seq, n_heads, hd).transpose(1, 0, 2)
|
|
42
|
+
v = (x @ wv.T + bv).reshape(seq, n_heads, hd).transpose(1, 0, 2)
|
|
43
|
+
scores = q @ k.transpose(0, 2, 1) / np.sqrt(hd)
|
|
44
|
+
ctx = softmax(scores, -1) @ v # (h, seq, hd)
|
|
45
|
+
ctx = ctx.transpose(1, 0, 2).reshape(seq, dim)
|
|
46
|
+
return ctx @ wo.T + bo
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def linear(x, w, b=None):
|
|
50
|
+
y = x @ w.T
|
|
51
|
+
return y if b is None else y + b
|