chore: conversion and test script, make special tokens in ZeroEncoder configurable
Browse files- scripts/convert-to-safensors.py +15 -0
- scripts/test-safentesor.py +29 -0
- zero_encoder.py +6 -2
scripts/convert-to-safensors.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env -S uv run --script
|
| 2 |
+
#
|
| 3 |
+
# /// script
|
| 4 |
+
# requires-python = ">=3.12"
|
| 5 |
+
# dependencies = ["safetensors", "numpy"]
|
| 6 |
+
# ///
|
| 7 |
+
|
| 8 |
+
import numpy as np
|
| 9 |
+
from safetensors.numpy import save_file
|
| 10 |
+
|
| 11 |
+
d = np.load("model.npz")
|
| 12 |
+
W = np.ascontiguousarray(d["rows_fp16"]) # (30522, 1024) float16
|
| 13 |
+
assert W.shape == (30522, 1024) and W.dtype == np.float16
|
| 14 |
+
|
| 15 |
+
save_file({"embedding.weight": W}, "model.safetensors")
|
scripts/test-safentesor.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env -S uv run --script
|
| 2 |
+
#
|
| 3 |
+
# /// script
|
| 4 |
+
# requires-python = ">=3.12"
|
| 5 |
+
# dependencies = ["statembed-py", "numpy", "tokenizers"]
|
| 6 |
+
# ///
|
| 7 |
+
|
| 8 |
+
import sys
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
|
| 11 |
+
from statembed_py import StaticEmbedding
|
| 12 |
+
|
| 13 |
+
model_dir = Path(__file__).parents[1]
|
| 14 |
+
sys.path.insert(0, str(model_dir))
|
| 15 |
+
|
| 16 |
+
from zero_encoder import ZeroQueryEncoder
|
| 17 |
+
|
| 18 |
+
model = ZeroQueryEncoder(".", variant="fp16", add_special_tokens=False)
|
| 19 |
+
other_emb = model.encode(["hello world"]).tolist()[0]
|
| 20 |
+
|
| 21 |
+
model = StaticEmbedding(model_dir=".", normalize=True)
|
| 22 |
+
|
| 23 |
+
emb = model.embed_text("hello world")
|
| 24 |
+
|
| 25 |
+
import numpy as np
|
| 26 |
+
|
| 27 |
+
a, b = np.asarray(emb), np.asarray(other_emb)
|
| 28 |
+
print(f"cosine similarity: {float(a @ b):.6f}")
|
| 29 |
+
print(f"max abs diff: {float(np.abs(a - b).max()):.8f}")
|
zero_encoder.py
CHANGED
|
@@ -28,7 +28,7 @@ class ZeroQueryEncoder:
|
|
| 28 |
int8 was measured quality-free against it (upper bound 0.00013 nDCG@10).
|
| 29 |
"""
|
| 30 |
|
| 31 |
-
def __init__(self, model_dir, variant="int8"):
|
| 32 |
d = Path(model_dir)
|
| 33 |
self.config = json.loads((d / "config.json").read_text())
|
| 34 |
pre = self.config["preproc"]
|
|
@@ -45,6 +45,10 @@ class ZeroQueryEncoder:
|
|
| 45 |
else:
|
| 46 |
raise ValueError(f"variant must be 'int8' or 'fp16', got {variant!r}")
|
| 47 |
self.variant = variant
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
self.tokenizer = Tokenizer.from_file(str(d / "tokenizer.json"))
|
| 50 |
n = self.tokenizer.get_vocab_size(with_added_tokens=True)
|
|
@@ -75,7 +79,7 @@ class ZeroQueryEncoder:
|
|
| 75 |
if isinstance(texts, str):
|
| 76 |
texts = [texts]
|
| 77 |
out = np.empty((len(texts), self.dim), dtype=np.float32)
|
| 78 |
-
for i, enc in enumerate(self.tokenizer.encode_batch(texts)):
|
| 79 |
out[i] = self._encode_ids(enc.ids)
|
| 80 |
return out
|
| 81 |
|
|
|
|
| 28 |
int8 was measured quality-free against it (upper bound 0.00013 nDCG@10).
|
| 29 |
"""
|
| 30 |
|
| 31 |
+
def __init__(self, model_dir, variant="int8", add_special_tokens=True):
|
| 32 |
d = Path(model_dir)
|
| 33 |
self.config = json.loads((d / "config.json").read_text())
|
| 34 |
pre = self.config["preproc"]
|
|
|
|
| 45 |
else:
|
| 46 |
raise ValueError(f"variant must be 'int8' or 'fp16', got {variant!r}")
|
| 47 |
self.variant = variant
|
| 48 |
+
# static embedding models tend to have this
|
| 49 |
+
# set to False, whereas most other models
|
| 50 |
+
# default to True
|
| 51 |
+
self.add_special_tokens = add_special_tokens
|
| 52 |
|
| 53 |
self.tokenizer = Tokenizer.from_file(str(d / "tokenizer.json"))
|
| 54 |
n = self.tokenizer.get_vocab_size(with_added_tokens=True)
|
|
|
|
| 79 |
if isinstance(texts, str):
|
| 80 |
texts = [texts]
|
| 81 |
out = np.empty((len(texts), self.dim), dtype=np.float32)
|
| 82 |
+
for i, enc in enumerate(self.tokenizer.encode_batch(texts, add_special_tokens=self.add_special_tokens)):
|
| 83 |
out[i] = self._encode_ids(enc.ids)
|
| 84 |
return out
|
| 85 |
|