# संपीड़न: Scalar और Product Quantisation — Embeddings और Vector Search

Source: https://www.geekswithgeeks.com/hi/embeddings/s-quant

> Vectors छोटे करें ताकि ज़्यादा memory में समाएँ।

## प्रति vector कम bytes, छोटी सटीकता क़ीमत

बड़े पैमाने पर memory मुख्य लागत है, इसलिए vectors अक्सर संपीड़ित होते हैं। **Scalar quantisation** हर संख्या को 32 की जगह 8 bits (int8) या 16 bits में रखता है: 4 या 2 गुना छोटा, आम तौर पर बहुत छोटी सटीकता हानि के साथ। **Product quantisation (PQ)** vector को उप-vectors में बाँटकर हर एक को छोटे सीखे codebook की निकटतम प्रविष्टि की id से बदलता है, इसलिए 256-byte का vector 8 bytes (32 गुना छोटा) बन सकता है, बड़ी पर अक्सर स्वीकार्य सटीकता हानि के साथ। संपीड़ित खोज approximate है, इसलिए **उम्मीदवार** खोजने में इसे उपयोग करें और चाहें तो शीर्ष परिणामों को मूल पूर्ण-परिशुद्धता vectors से **दोबारा score** करें। अपने डेटा पर खोया recall हमेशा मापें।

## Product quantisation, चलाकर

मैंने यह Python virtual environment में numpy 2.5.3, scikit-learn 1.9.1 और faiss-cpu 1.15.1 के साथ चलाया, निश्चित random seeds के साथ ताकि संख्याएँ दोहराई जाएँ। 64-आयामी float32 vector 256 bytes लेता है; PQ index प्रति vector 8 bytes रखता है (32 गुना छोटा), और इस आसान परीक्षण में 100 थोड़े बदले queries में से हर एक को अपना मूल vector फिर भी top-1 मिला। असली डेटा और कठिन queries ज़्यादा खोते हैं।

```python
import numpy as np, faiss
rng = np.random.default_rng(0)
d, n = 64, 20000
xb = rng.normal(size=(n, d)).astype("float32"); xq = xb[:100] + 0.05 * rng.normal(size=(100, d)).astype("float32")

flat = faiss.IndexFlatL2(d); flat.add(xb)
_, truth = flat.search(xq, 1)
pq = faiss.IndexPQ(d, 8, 8); pq.train(xb); pq.add(xb)                # 8 sub-vectors, 8 bits each = 8 bytes per vector
_, found = pq.search(xq, 1)
print("float32 bytes per vector :", d * 4)
print("PQ bytes per vector      :", 8)
print("compression              :", d * 4 // 8, "x")
print("top-1 still correct      :", float(np.mean(found[:, 0] == truth[:, 0])))

```

Output:

```
float32 bytes per vector : 256
PQ bytes per vector      : 8
compression              : 32 x
top-1 still correct      : 1.0
```

## Scalar (int8) quantisation, चलाकर

मैंने यह Python virtual environment में numpy 2.5.3, scikit-learn 1.9.1 और faiss-cpu 1.15.1 के साथ चलाया, निश्चित random seeds के साथ ताकि संख्याएँ दोहराई जाएँ। 128-आयामी vectors को int8 में रखने से 512 bytes घटकर 128 रह जाते हैं, प्रति मान सबसे बड़ी त्रुटि 0.0016 है, और सटीक शीर्ष-10 के सारे परिणाम अब भी मिलते हैं।

```python
import numpy as np
rng = np.random.default_rng(0)
X = rng.normal(size=(5000, 128)).astype("float32")
X /= np.linalg.norm(X, axis=1, keepdims=True)
q = X[0] + 0.1 * rng.normal(size=128).astype("float32"); q /= np.linalg.norm(q)

scale = 127 / np.abs(X).max()
Xi = np.round(X * scale).astype(np.int8)                      # 1 byte per number instead of 4
Xd = Xi.astype("float32") / scale
exact = np.argsort(-(X @ q))[:10]
approx = np.argsort(-(Xd @ q))[:10]
print("bytes per vector: float32 =", X.shape[1] * 4, "| int8 =", Xi.shape[1])
print("max absolute error per value:", round(float(np.abs(X - Xd).max()), 4))
print("top-10 overlap with exact:", len(set(exact) & set(approx)), "/ 10")

```

Output:

```
bytes per vector: float32 = 512 | int8 = 128
max absolute error per value: 0.0016
top-10 overlap with exact: 10 / 10
```

## शीर्ष परिणाम दोबारा score करें

संपीड़ित vectors से 100 उम्मीदवार खोजें, फिर पूर्ण-परिशुद्धता vectors से उन्हें दोबारा rank करके सटीकता लौटाएँ।

**Quiz:** Quantisation क्या बदले में देती है?

- [ ] कुछ नहीं
- [ ] अधिक सटीकता के बदले memory
- [ ] गति के बदले सुरक्षा
- [x] बहुत कम memory के बदले थोड़ी सटीकता

*Answer:* बहुत कम memory के बदले थोड़ी सटीकता. प्रति संख्या कम bits का अर्थ छोटे vectors पर कुछ rounding त्रुटि।
