VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

How AI Works | Product Quantization — Codebooks, Compressed Vectors and Approximate Nearest Neighbours

Three students in school uniforms work through open books at a classroom table, with textbooks and stationery nearby and study notes on the whiteboard behind them.

Product quantization, or PQ, makes large-scale similarity search cheaper by storing each high-dimensional vector as several small codebook indices instead of retaining every original coordinate in the search index. It splits a vector into sub-vectors, learns a set of representative centroids for each part, and stores the nearest centroid number for each part. At query time, a table of distances lets the system compare the query with many compressed database vectors without fully reconstructing them.

This is a technique used in present-day machine-learning search infrastructure, not a statement about artificial superintelligence. PQ is approximate: compression changes distances and can reorder neighbours. Its real engineering achievement is a measurable trade-off among memory, latency and recall, and its real responsibility is to tell users when the approximation is too coarse for the decision being made. This guide derives the mechanism, checks arithmetic, explains implementation choices and gives an evaluation plan rather than promising free accuracy.

Contents: What problem is product quantization solving? · Start with the ordinary Euclidean-distance baseline · Break one vector into several independent subspaces · Learn codebooks rather than inventing arbitrary bins · Encode a stored vector with a short sequence of indices · Account for codebook memory, not just code bytes · A tiny worked codebook with four dimensions · Build the asymmetric distance table and read it · Compare approximate and exact distances honestly · Why a compressed score is not a probability · Symmetric versus asymmetric distance computation · Choose the number of subquantizers as a trade-off · What changes when you allocate more bits per block? · Do not confuse PQ with scalar quantization · Why coordinate ordering and rotation can matter · Codebooks need a representative and controlled training set · Separate training, index construction and live queries · How an inverted file works with compressed codes · The two independent sources of IVF-PQ misses · Rerank the shortlist with original coordinates · Choose a distance metric that matches the embedding task · Build an exact ground truth before celebrating recall · Measure latency at a workload level, not one screenshot · Index updates can silently mix incompatible versions · Distribution shift changes the error you thought you bought · What happens when a codebook wastes its available centroids? · Memory capacity planning for one million and ten million items · Compression is not encryption or de-identification · A practical example: searching a curriculum archive · A second example: duplicate-photo search · Failure mode: training or testing against the wrong snapshot · Failure mode: evaluating the code without the complete query path · Failure mode: ranking without documenting filters · Evaluation protocol that another team can reproduce · Changed-context transfer: what if the embeddings become twice as long? · Changed-context transfer: what if shortlist reranking is slow? · Frequently asked questions · Primary research, implementation documents and learning paths

What problem is product quantization solving?

An embedding model converts a document, photograph, audio clip or other object into a vector of numbers. A semantic-search service wants the vectors closest to a new query. If its archive contains only a few thousand items, comparing the query with every uncompressed vector may be simple enough. At a million or a billion items, repeatedly reading thousands of floating-point coordinates per candidate becomes a serious memory-bandwidth and storage problem. Product quantization changes the representation the search engine has to read, while preserving enough geometric information for useful candidate ranking.

Separate two questions before changing an index: how many bytes does each stored vector require, and how much work does each query require? PQ directly attacks the first and often improves the second by using compact codes and distance lookup tables. It does not by itself guarantee sublinear search; a flat PQ index still scans every compressed code. Combining PQ with an inverted file or another candidate-selection method introduces a second, independent approximation. These layers must be evaluated separately because a missed candidate and an incorrectly ranked candidate are different failures.

Start with the ordinary Euclidean-distance baseline

Take a query vector q and stored vector x with d dimensions. Squared Euclidean distance is the sum, over all d coordinates, of the squared difference between q and x. Squaring avoids a square root without changing the order of nonnegative distances. If the embedding is an abstract model output, these squared distances are in squared coordinate units, not metres or a guaranteed percentage of relevance. The model may put semantically related items nearby, but that quality is a property of its training and validation, not of the distance formula alone.

With 768 dimensions stored as 32-bit floats, one uncompressed vector has 768 × 4 = 3,072 bytes before identifiers and indexing overhead. One million such vectors have 3,072,000,000 bytes, roughly 2.86 GiB using 1 GiB = 1,073,741,824 bytes. A query against all million vectors reads far more than one modest processor cache, and query concurrency increases pressure on bandwidth. An exact index such as Faiss IndexFlatL2 is a useful reference because it preserves distances, even when it is not the production design.

Break one vector into several independent subspaces

PQ chooses a number M of subspaces and partitions the d coordinates into M nonoverlapping blocks. For a straightforward equal-size split, each block has d/M coordinates, so d must be divisible by M. For example, a 768-dimensional embedding and M = 96 yield 96 blocks of eight coordinates each. The division into blocks is an engineering choice: neighbouring coordinates in the model’s output are not guaranteed to be statistically independent or even naturally grouped. The method assumes these separately quantized blocks will approximate the full vector well enough.

Every block has its own small quantizer. That is what product means here: the complete quantization code describes a Cartesian product of choices from multiple codebooks. It does not mean multiplying all the vector coordinates, multiplying similarity scores or combining multiple neural models. Splitting the coordinate space allows a potentially huge collection of reconstructed vectors from a modest number of learned centroids, without explicitly storing every combination. The assumption should be checked through reconstruction error and search recall on representative held-out vectors.

Learn codebooks rather than inventing arbitrary bins

For each subspace m, train a set of K representative sub-vectors, usually with a clustering procedure such as k-means. These representatives are the centroids of codebook m. Training samples should represent the distribution of database vectors that will actually be indexed. A uniform random sample is a useful beginning, but a corpus dominated by duplicates or one language may produce a codebook that works poorly for rare items, specialised subjects or newly added material. Training on irrelevant or future data can also misstate held-out quality.

For an eight-bit subquantizer, K = 2^8 = 256 possible centroid indices, numbered 0 through 255. Training each codebook is a separate optimization problem: choose centroids to reduce the total squared reconstruction error for that block on the training sample. The objective is a geometric proxy, not direct maximisation of retrieval quality. A model might reconstruct average vectors extremely well while distorting the fine distinctions that matter to the nearest ten neighbours. Consequently, inspect both quantization loss and real retrieval measurements rather than declaring success from a training-loss curve.

Encode a stored vector with a short sequence of indices

After codebooks are learned, encoding a vector means taking each of its M sub-vectors, finding the nearest centroid in that block’s codebook, and writing only the centroid index. If M = 96 and there are 256 centroids per block, each code is 96 indices of eight bits: 96 bytes. The original 768 float32 coordinates required 3,072 bytes. The ideal per-vector code-size ratio is therefore 3,072/96 = 32. This is a representation ratio, not a claim that an entire running service uses exactly 32 times less memory.

A production index also needs codebooks, identifiers, deleted-item state, optional vector reconstructions, inverted-list pointers, metadata and sometimes exact originals for final verification. A good capacity plan records these separately. Compression is beneficial when enough vectors share the learned tables that the shared codebook cost becomes small per item. If the dataset contains only twenty vectors, the tables may outweigh the codes. If it contains ten million vectors, the same codebooks are amortised much more widely.

Account for codebook memory, not just code bytes

Consider the 768-dimensional, M = 96, eight-bit configuration. Each codebook has 256 centroids, each centroid contains eight float32 values, and there are 96 codebooks. Codebook storage is 96 × 256 × 8 × 4 = 786,432 bytes, or 0.75 MiB. For a million vectors, 96-byte codes occupy 96,000,000 bytes, about 91.55 MiB. Their combined illustrative storage is about 92.3 MiB before IDs, structural overhead or backups. The comparison with 2.86 GiB of raw coordinates is encouraging but incomplete.

If every stored item also carries an eight-byte identifier, that is another 8,000,000 bytes for a million items. Some database systems also retain an uncompressed embedding in a separate persistent store, so total storage can be much higher even while the fast search index is compressed. Report the precise denominator when advertising savings: memory per encoded vector, complete in-memory index, combined disk footprint or whole application. A number that silently changes its denominator is a misleading benchmark.

A tiny worked codebook with four dimensions

Use a miniature four-dimensional example so every arithmetic step is visible. Split dimensions one and two from dimensions three and four, so M = 2. Codebook A has centroids A0 = (0,0) and A1 = (2,0); codebook B has B0 = (0,0) and B1 = (0,3). There are only two choices per block for teaching purposes, equivalent to one bit per index. A real eight-bit index often has 256 choices per block. Let query q = (1.6, 0.2, 0.1, 2.6).

For the first two coordinates, squared distances are A0: 1.6² + 0.2² = 2.60, and A1: (1.6 − 2)² + 0.2² = 0.20. For the last two coordinates they are B0: 0.1² + 2.6² = 6.77, and B1: 0.1² + (2.6 − 3)² = 0.17. These four lookup entries are sufficient to score any two-bit compressed code. They are exact distances from the query blocks to centroids, not exact distances from the query to the original database vectors.

Build the asymmetric distance table and read it

A database vector encoded as indices (A1,B1) receives approximate squared distance 0.20 + 0.17 = 0.37. A code (A0,B1) scores 2.60 + 0.17 = 2.77. Code (A1,B0) scores 0.20 + 6.77 = 6.97. Code (A0,B0) scores 2.60 + 6.77 = 9.37. Within this deliberately small example the compressed search prefers (A1,B1). It looks up two entries and adds them; no original four-coordinate database vector must be loaded for that calculation.

The method is often called asymmetric distance computation, or ADC, because the query remains uncompressed while the stored item is approximated by its codeword. The query-specific table contains M × K squared distances. With M = 96 and K = 256, that is 24,576 entries, or 98,304 bytes if represented as float32: 96 KiB of lookup values per query before implementation-specific buffers. This is a much smaller hot working set than the million uncompressed candidate vectors. Cache behaviour and throughput still depend on the implementation, batching and hardware.

Compare approximate and exact distances honestly

Suppose an actual stored vector x = (1.8, 0.3, 0.2, 2.8) encodes to (A1,B1) using the toy centroids. Its actual squared distance to q is (1.6 − 1.8)² + (0.2 − 0.3)² + (0.1 − 0.2)² + (2.6 − 2.8)² = 0.04 + 0.01 + 0.01 + 0.04 = 0.10. The ADC score is 0.37. Both are valid calculations, but they answer different questions: one measures distance to x and the other measures distance to x’s reconstruction (2,0,0,3).

Now take y = (1.45, 0.3, 0.2, 2.3). Its exact squared distance is 0.15² + 0.10² + 0.10² + 0.30² = 0.1325. Under the same miniature codebooks, y also encodes to (A1,B1), so ADC assigns x and y the identical 0.37 score even though exact distances differ. This loss of resolution is the essential approximation risk. A compressed ranking may be excellent on average yet undecidable for two candidates sharing a code. Exact reranking is a principled repair when the original vectors are available.

Why a compressed score is not a probability

A vector distance of 0.37 does not mean 37% similarity, 63% confidence or a 37% chance of relevance. Squared Euclidean scores describe a chosen representation space. Their magnitudes depend on model scale, normalization, feature weighting and the quantizer’s reconstruction. The distances can support ranking, but a user-facing probability needs a separate calibrated statistical model and an outcome definition. Treating distances as probabilities creates a false sense of precision, especially in high-stakes educational or administrative search.

A practical interface can say that results were retrieved approximately and that important claims require checking the referenced documents. For a question-answering assistant, retrieval is only the candidate-gathering stage; source quality, citation fidelity and answer generation remain separate steps. PQ cannot verify the truth of a source and cannot replace an authorization check. If a returned document is outside the user’s permitted collection, excellent nearest-neighbour math does not make it appropriate to disclose.

Symmetric versus asymmetric distance computation

There are two basic ways to compare compressed representations. A symmetric approximation encodes both the query and database vectors and compares the corresponding reconstructed centroids. It can be convenient when both sides arrive as codes, but quantization error affects both query and stored item. Asymmetric distance computation keeps the incoming query in its original numeric form and precomputes its distances to each stored codebook centroid. It then accumulates those lookups for every candidate code.

Keeping the query uncompressed often improves ranking because it avoids query-side quantization error, although actual gains depend on workload and model geometry. The seminal 2011 product-quantization research distinguishes these approaches. A system should explicitly record whether it reports reconstructed-vector distances, ADC lookup sums, or exact L2 distances from uncompressed vectors. Otherwise the same column name such as score may refer to incompatible quantities after an index migration. Reproduce a handful of candidates manually before trusting a large benchmark pipeline.

Choose the number of subquantizers as a trade-off

Increasing M while holding eight bits per block fixed allocates more total code bits per vector. For 768 dimensions, M = 48 means 16 coordinates per subvector and 48-byte codes. M = 96 means eight coordinates and 96-byte codes. M = 192 means four coordinates and 192-byte codes. More bytes often permit lower reconstruction error because smaller subspaces can be represented with the same 256 centroids, but training, table size and per-candidate additions also change. The relationship is not guaranteed to improve every important metric monotonically.

A sensible selection exercise compares at least a few feasible configurations on the same held-out queries, database snapshot, hardware and workload. For each, report code bytes/vector, complete memory, index-build time, update behaviour, recall@k and latency distributions. A team may prefer 48 bytes when documents are numerous and approximate results are sufficient, while a narrow technical reference collection may justify 192 bytes for higher recall. Choosing only the most compact code without inspecting false negatives is a design shortcut, not an optimization.

What changes when you allocate more bits per block?

The codebook size K is 2 to the power of the bits per subquantizer. Four bits give 16 possible centroids; eight bits give 256. More bits improve the representational capacity of each individual block but make its codebook and query lookup table larger. Training more centroids also requires adequate examples and computation. It is not enough to raise K and assume rare centroids have been learned reliably: a sparse training distribution can leave some centroids poorly supported or effectively unused.

Suppose M = 96 but each index uses four bits. The packed code occupies 96 × 4 / 8 = 48 bytes per vector, assuming an efficient bit-packed representation, and each query table has 96 × 16 = 1,536 distances. With eight bits it occupies 96 bytes and has 24,576 table entries. Compare these as distinct operating points rather than assuming the 48-byte version is automatically twice as fast. Processing fewer bytes and handling packed indices have different costs, and library implementations support different bit widths and accelerations.

Do not confuse PQ with scalar quantization

Scalar quantization reduces the precision of individual coordinates, often by mapping each to a small integer. PQ instead approximates a short block of coordinates jointly using a learned centroid. Joint encoding can exploit correlations inside that block, such as two coordinates moving together, rather than rounding them independently. It still ignores correlations across different blocks unless a preprocessing transformation redistributes those correlations. The two methods make distinct errors and often have different instruction and memory-access patterns.

For an eight-bit scalar representation of a 768-dimensional vector, the naïve code needs 768 bytes because there is one byte per coordinate. The earlier M = 96, eight-bit PQ uses 96 bytes because there is one byte per eight-coordinate block. This eight-to-one comparison concerns these example encodings only; it does not establish that PQ always wins on latency or recall. Scalar codes are simpler to interpret coordinate by coordinate, and the best choice depends on model geometry, implementation maturity, update rates and accuracy requirements.

Why coordinate ordering and rotation can matter

A simple PQ design divides the original coordinates into consecutive blocks. That can waste codebook capacity when strongly dependent coordinates fall into different blocks. Imagine one useful direction distributed across many dimensions: each block learns part of it without seeing the full structure. An orthogonal rotation before splitting can move correlations into shapes more suitable for subspace quantization. Optimized product quantization, often abbreviated OPQ, learns such a transformation along with a quantization objective.

A rotation is not magic. It adds training steps and another versioned transformation that must be applied identically when indexing stored vectors and processing new queries. After changing a rotation matrix, old codes do not silently become compatible with the new codebooks. Compare plain PQ and OPQ on held-out retrieval, not on training reconstruction alone. Also distinguish the mathematical property of a full orthogonal transform preserving Euclidean distances from the practical fact that a new split-and-quantize procedure can change approximation error.

Codebooks need a representative and controlled training set

A codebook is a learned component of the retrieval system. If training examples come only from yesterday’s popular articles, unusual science diagrams or recently introduced course topics may reconstruct poorly. Sampling policies should include important slices, such as subject, language, content age and media type, when those slices matter to the application. Do not use personally sensitive material merely because it is conveniently available: sampling and storage must satisfy the same purpose and authorization rules as the underlying corpus.

A diagnostic can compare held-out reconstruction error across slices. For instance, two subject groups might have mean squared reconstruction errors of 0.08 and 0.22 in the same normalized embedding space. That disparity does not automatically imply disparate relevance, but it signals the need to check whether the second group loses more true neighbours. Training on 200,000 vectors with 256 centroids per block averages 781.25 examples per centroid only as a division; actual cluster sizes can be extremely uneven. Inspect occupancy counts rather than treating the average as a guaranteed minimum.

Separate training, index construction and live queries

A robust implementation has at least three distinguishable stages. First, it trains the codebooks on representative vectors. Second, it encodes the intended database vectors with those frozen codebooks, writes their indices and constructs any auxiliary search structure. Third, it answers incoming queries by computing the appropriate lookup tables and examining candidate codes. This separation makes it possible to reproduce an index and to know whether a regression came from an embedding model, a codebook change or a query-serving change.

Version every boundary. Record the embedding model identifier and normalization rule; the codebook or rotation version; the encoded-vector manifest and snapshot; any coarse clustering parameters; and the distance metric. If a newly deployed embedding model changes coordinate meaning, reusing an old PQ codebook merely because both models output 768 numbers is unsafe. Equal dimensionality does not prove comparable geometry. A careful rollout builds a parallel index, compares it with the old one on agreed queries, and switches traffic only after measurable acceptance checks.

How an inverted file works with compressed codes

Product quantization compresses vectors. An inverted file, often called IVF, narrows which groups of vectors are scanned. A coarse quantizer assigns database vectors to one of nlist cells. At query time the system visits nprobe nearby cells and evaluates their members, possibly using PQ codes of residual vectors relative to the coarse centroid. This IVF-PQ arrangement trades another form of approximation for faster candidate generation. Faiss documents IndexIVFPQ and distinguishes it from flat IndexPQ.

Suppose a million vectors are spread perfectly evenly over 4,096 lists and a query probes 32 lists. The selected-list fraction is 32/4,096 = 0.0078125, or 0.78125%, giving an expected 7,812.5 candidate vectors under the unrealistic equal-size assumption. Real lists vary in population and true neighbours may lie outside selected cells. Therefore nprobe is neither a guaranteed fraction of measured work nor a direct recall percentage. Benchmark actual scanned candidates, missed true neighbours and latency on the real index rather than inferring quality from this neat ratio.

The two independent sources of IVF-PQ misses

A correct mental model separates routing error from representation error. Routing error occurs when a true nearest neighbour belongs to a coarse cluster that the query does not probe. PQ error occurs when a true neighbour is scanned but its compressed distance is distorted enough to lose a place in the final top-k. Raising nprobe helps the first kind by inspecting more clusters, while increasing code length or improving codebooks helps the second. Exact reranking can fix ranking among retrieved candidates but cannot recover a neighbour excluded before reranking.

This distinction tells an engineer which knob to turn. If recall improves sharply as nprobe grows, candidate coverage may be the principal problem. If more probing barely helps but exact reranking fixes many top-k mistakes, quantization is a bigger issue. If neither helps, investigate upstream embedding quality, dataset freshness, filters and ground-truth labels. Making one configuration parameter arbitrarily large without diagnosing the failure wastes memory, CPU cycles or engineering time.

Rerank the shortlist with original coordinates

A practical hybrid can use PQ to find a shortlist of perhaps 100 or 500 candidates, then look up the uncompressed coordinates of those candidates and compute their exact distances to the query. This spends expensive memory reads only on a small subset rather than on every indexed item. It is especially useful when several stored vectors share similar PQ codes, as in the toy example, and accurate ordering of the first ten results matters.

There are two limits. First, full-resolution vectors must exist in a retrievable, authorized store, with identifiers correctly mapped to PQ codes. Second, reranking only reorders the candidates it receives; it cannot restore a missed item that never reached the shortlist. Measure end-to-end recall after reranking, not simply the accuracy of ordering inside a handpicked candidate set. Include any remote storage lookup in latency statistics. An index may appear extremely fast until those supposedly optional full-vector reads move onto its critical path.

Choose a distance metric that matches the embedding task

Euclidean distance, dot product and cosine similarity are not automatically interchangeable. For unit-normalized vectors q and x, squared Euclidean distance equals 2 − 2(q·x), so exact rankings by Euclidean distance and dot product agree. The identity assumes both vectors truly have unit norm. PQ reconstruction can alter norms, which means ranking compressed reconstructions by L2 may not replicate ranking original normalized vectors by cosine. Library index families also differ in which metrics and transformations they support.

Decide the intended metric before training and validation. Apply the same normalization to training, database and query vectors when appropriate. Recheck behaviour after a new embedding model or preprocessing pipeline, particularly if someone changes how blank inputs, zero vectors or malformed coordinates are handled. A mismatch can create confident-looking but wrong results with no crash and no obvious error message. The engineer’s job is to validate semantic retrieval outcomes as well as the numerical code path.

Build an exact ground truth before celebrating recall

Recall@k asks how many of the exact top-k neighbours also appear among the approximate top-k. For 300 held-out queries and k = 10, there are 3,000 exact neighbour positions to recover when each query has ten distinct valid neighbours. If the approximate results contain 2,370 of those exact neighbours, the aggregate recall@10 is 2,370/3,000 = 0.79, or 79%. This denominator is retrieved-neighbour membership, not 300 queries and not the total number of corpus documents.

Exact nearest neighbours are only a computational reference, not a universal measure of user satisfaction. If the embedding model thinks a misleading source is similar, exact retrieval can reproduce that mistake perfectly. For education or research products, supplement exact-recall measurements with human-labelled relevance, source authority, answer traceability and safety checks. Keep computational recall distinct from precision of generated answers. A system can improve approximate-search recall while worsening answer quality if the indexed corpus or downstream synthesis changes.

Measure latency at a workload level, not one screenshot

Latency depends on index size, concurrent requests, hardware cache state, whether lookup tables are reused, nprobe, query batch size and whether there is a reranking stage. Report at least median and high-percentile query durations over a documented workload. One fast demonstration query is not evidence of a production service. If queries vary between a few requested results and hundreds, separate those workloads so that the summary does not hide costly cases.

Suppose one candidate configuration returns 79% recall@10 at a measured 12 ms median and 45 ms 95th-percentile latency, while another returns 92% at 20 ms median and 58 ms 95th percentile. Those are hypothetical figures for interpreting a trade-off, not claims from a published system. The right choice depends on whether missed documents or delayed responses matter more. Document sample count, host, concurrency, warm-up and index snapshot. Without those denominators and conditions, isolated speed claims are not reproducible evidence.

Index updates can silently mix incompatible versions

When a new document arrives, its embedding must be generated by the index’s intended model version, transformed by the right preprocessing and assigned against the correct frozen codebooks. A worker using a stale codebook can produce a syntactically valid index code that points at a different centroid meaning. The result may be unrelated retrieval that looks like a normal response. Embed model and codebook version identifiers into the indexing workflow, and reject writes with incompatible versions.

Deletes and retractions also matter. An old vector can remain reachable in a code index even after its source document was removed from the visible catalogue. Maintain a consistent mapping between index identifiers and authorized document states. Test interrupted batch writes and repeated updates as carefully as initial builds. PQ is a mathematical compression scheme, not a transaction protocol, access-control system or document-retention policy. Those engineering duties must be supplied by the surrounding system.

Distribution shift changes the error you thought you bought

Suppose the original codebooks are trained on short English study notes but the collection later receives longer multilingual lab reports. Even with the same vector dimensions, new data may occupy unfamiliar regions of the embedding space. More sub-vectors can land far from their nearest centroids, increasing reconstruction error and altering rankings. Monitoring only the average old-corpus recall can hide this deterioration. Slice evaluations by data source, subject and ingestion date; check hard and rare queries rather than just common examples.

A retraining decision should look at both codebook reconstruction and downstream retrieval. New codebooks change the meaning of every index code, so generally require re-encoding database vectors or maintaining a separately versioned index. Do not update a centroid table in place while leaving old codes untouched unless the implementation explicitly supports such a transition with verified semantics. A staged rebuild and atomic traffic switch may cost additional storage briefly, but avoids serving a mixture of incompatible numerical representations.

What happens when a codebook wastes its available centroids?

Centroid collapse or skew is a useful diagnostic. If a block nominally has 256 centroids but 230 of them receive almost no assignments, much of the theoretical eight-bit representational capacity is unused. This can indicate skewed training samples, too few examples, poor initialization, or a coordinate block whose true variation is much smaller than expected. Conversely, a few highly populated clusters may compress common patterns well while failing on rare ones.

Inspect assignment histograms per block, not only an average over all M blocks. Compare occupancy on training and held-out data, and watch whether it changes after corpus updates. Remedies depend on cause: obtain more representative examples, adjust M or bit width, test a rotated representation, or train with a better initialization. Simply rerunning k-means with a different seed may change a score but is not a substitute for understanding the data. Document the chosen seed when repeatability matters.

Memory capacity planning for one million and ten million items

The earlier 96-byte PQ code uses 96 MB for one million vectors in decimal units, and 960 MB for ten million vectors. The corresponding uncompressed 768-dimensional float32 vectors use about 3.072 GB and 30.72 GB. These byte counts exclude codebooks, IDs, metadata, replication and structural overhead. They are straightforward products of per-vector sizes, not benchmark observations. They also do not tell us CPU latency or network cost.

If an application runs two replicas of the compressed index, a 960 MB code array may require approximately 1.92 GB across those replicas before other structures. If the application also preserves ten million original vectors for reranking, that separate store has a further 30.72 GB of raw float32 data before backups. An honest architecture diagram names each copy and its role. The best compression strategy is one that allows the total system to meet accuracy, service and recovery requirements within a declared budget.

Compression is not encryption or de-identification

A compressed embedding remains derived from a document or user-associated record. It may reveal information through similarity comparisons or linkage to identifiers and source text. Reducing 3,072 bytes to 96 bytes does not prove that sensitive information has been destroyed. Policies for access permissions, encryption at rest, retention and deletion still apply. A system should also ensure that a query does not learn about documents it is not authorized to search.

Evaluate information leakage separately from geometric reconstruction error. Researchers sometimes examine whether representations reveal protected attributes or membership in training data, but no generic PQ compression ratio certifies privacy. If a school’s search system handles student work, its index design should minimize access and retention according to policy, not infer privacy from compact storage. This distinction is important precisely because the efficiency of a technique can encourage wider indexing of materials than the project originally intended.

A practical example: searching a curriculum archive

Imagine a school archive with a million permitted content snippets, each represented by a 768-dimensional embedding. A student enters a question about why an electromagnet stops acting when current is interrupted. The search layer computes the query vector, uses PQ or IVF-PQ to find candidate snippets and optionally reranks the top 100 by exact stored embeddings. The final answer should still cite the textbook page or teacher-approved explanation it actually used. PQ helps retrieve candidate text; it does not decide whether the explanation is scientifically correct.

Before launching, create question sets covering common topics, unusual vocabulary, bilingual phrasing and near-duplicate documents. Check whether the compressed index retains the exact top ten and whether human judges find the returned sources relevant. Test a newly withdrawn document to ensure it cannot reappear via a stale vector ID. If the archive contains restricted assessments, enforce authorization before results are delivered, even if the same index contains public materials. The search-quality and permission tests address separate possible failures.

Suppose a media library uses embeddings to find visually similar images. PQ can reduce the footprint of millions of image vectors while an exact rerank examines close matches. Yet a photograph taken at night and a daytime view of the same place may have different embedding positions, and near-identical images with minor crops can cluster very tightly. The quantizer can merge several close images into the same code and obscure their subtle differences. The application must specify whether it seeks identical files, near-duplicates, or merely similar scenes.

For exact file duplicates, a cryptographic file hash is usually the better first tool; PQ is not a substitute for byte identity. For visual near-duplicates, image-specific evaluation examples and optionally geometric checks become important. For semantic scene search, exact-match rates may matter less than diverse relevant results. One vector compression technique can serve all three workflows only if each is evaluated against its intended ground truth. Otherwise an apparently successful retrieval demo may be solving the wrong question.

Failure mode: training or testing against the wrong snapshot

If a codebook is trained on vectors from a later test snapshot, an evaluation can benefit from information unavailable at the time the design would have been deployed. If the ground-truth exact index contains documents that the approximate index never received, recall may look artificially low. If the approximate index has stale or deleted items the exact index excludes, measured results become similarly incomparable. Both indexes should use the same authorized dataset and embedding version when their computational retrieval quality is compared.

Version the evaluation manifest with document IDs, embedding hashes or agreed checksums, preprocessing rules, and excluded records. Recompute exact neighbours after meaningful corpus changes, rather than carrying over last month’s labels indefinitely. A reproducible report states whether distance evaluation was performed on a frozen scientific benchmark or a living production archive. The former supports clean comparisons; the latter tests operational freshness. Both are useful, but combining them without explanation obscures the source of errors.

Failure mode: evaluating the code without the complete query path

Some experiments time only the inner loop that sums PQ lookup distances. A real query may also include embedding inference, network transfer, coarse assignment, lookup-table construction, top-k selection, filtered candidate retrieval, reranking and source loading. If these other stages dominate total response time, halving the inner-loop runtime may barely affect what the user experiences. A timing profile should separate compute from waiting and should include failure recovery under the expected concurrency.

One way to diagnose this is to trace a sample of requests with timing fields for each stage. Suppose a hypothetical 80 ms end-to-end query spends 12 ms on compressed scanning, 38 ms on embedding generation, 18 ms on document fetch and 12 ms elsewhere. Cutting scanning from 12 to 6 ms reduces the complete 80 ms to 74 ms, a 7.5% end-to-end improvement, not 50%. The arithmetic explicitly uses total latency as denominator. This prevents an impressive kernel benchmark from being mistaken for an equally impressive application improvement.

Failure mode: ranking without documenting filters

Search applications commonly filter by language, curriculum year, publication status, user permission or school subject. The order of filtering and approximate candidate generation changes observed recall. If the engine first retrieves only 100 global candidates and then discards 98 for permission reasons, the student may receive just two answers even though many permitted neighbours exist elsewhere. A filter-aware index or an appropriately expanded candidate search may be needed.

Define the ground-truth set after applying the same eligibility rules that the user-facing query should obey. Measure recall among eligible documents, and verify that forbidden documents are never returned, even transiently. Keep quality metrics for each important filter combination because rare cohorts can suffer more from small candidate pools. A retrieval system that is mathematically efficient but unreliable under access filters is not production-ready. This issue belongs in design reviews alongside code size and raw nearest-neighbour speed.

Evaluation protocol that another team can reproduce

Freeze the database vectors, choose held-out queries and compute exact top-k results with the intended metric. Train codebooks without peeking at held-out query labels. Build multiple candidate indexes using declared M, bits-per-block, rotation and coarse-index settings. For each configuration record total index bytes, build time, assignment occupancy, reconstruction error, recall at several k values, filtered recall, and median plus tail latency under a fixed concurrency. Keep the same queries and hardware when comparing methods.

Also record operational metrics such as newly ingested items per minute, index age, crash recovery, fraction of documents with matching versions and results excluded by permissions. Plot recall against full-system latency and memory rather than relying on a single winner label. For decisions with nontrivial consequences, inspect individual failure examples: which correct item disappeared, whether it was routed out by IVF, whether its PQ score was distorted, and whether an exact reranker would have repaired it. Those case studies lead to specific engineering action.

Changed-context transfer: what if the embeddings become twice as long?

A retrieval team upgrades from 768 dimensions to 1,536 dimensions while retaining M = 96 and eight-bit codes. First calculate sizes. The raw float32 vector grows from 3,072 to 6,144 bytes. The PQ code remains 96 bytes because it still contains 96 one-byte centroid indices. Each new subvector has 1,536/96 = 16 coordinates rather than eight. If the implementation stores 256 float32 centroids for each block, codebook storage doubles from 786,432 to 1,572,864 bytes. The ideal raw-to-code size ratio rises from 32 to 64.

Does the larger ratio guarantee equal recall or a superior search system? No. Each centroid now approximates a 16-dimensional block with the same 256 choices, potentially increasing reconstruction error. More importantly, the new embedding model changes vector geometry, so fresh codebook training and an entirely new quality evaluation are required. An alternative is M = 192: eight coordinates per block again, but 192-byte codes. Test both rather than claiming that preserving the old code length preserves the old quality.

Changed-context transfer: what if shortlist reranking is slow?

Suppose an IVF-PQ system finds 300 candidates quickly but must fetch original vectors from a remote store. It fetches candidates one at a time and each request incurs 4 ms of fixed overhead. At 300 separate requests, just the fixed overhead is 1,200 ms, before transfer and distance computation. The PQ math can be impeccable while the application still feels unusable. The useful redesign may be batched fetching, locally cached originals for popular items, or a shorter shortlist that has been shown to preserve adequate recall.

Now assume the same 300 candidate vectors are fetched in six batches of fifty, each with 4 ms fixed overhead. Ignoring transfer and processing, the fixed component falls to 24 ms. The illustrative saving is 1,176 ms. Real batching has bandwidth, memory and queueing limits, so it requires measurement. This example teaches a broader lesson: improve the slowest end-to-end stage rather than automatically spending more code bytes on a ranking problem that is already sufficiently accurate.

Frequently asked questions

Is PQ itself a neural network? No. It is a learned vector compression method, commonly trained through clustering, that can be applied to embeddings produced by many different models. Is it lossless? No; two distinct vectors can map to the same code. Can it search without the original vectors? Yes, compressed-domain search can run on codes and codebooks, although exact reranking needs access to originals. Does a PQ match establish factual relevance? No; it estimates proximity in the chosen representation.

Does using more subquantizers always win? It generally spends more bits and lookup work for the same bits-per-block, but accuracy and latency must be measured. Is IVF a required part of PQ? No; flat PQ is possible and scans compressed codes exhaustively. Can a codebook remain valid after a model upgrade? Do not assume so merely from identical dimensionality. Is PQ a form of privacy protection? Compression alone provides no such guarantee. Should a student trust an answer because retrieval was fast? No; verify the cited source, the applicable syllabus and the reasoning.

Primary research, implementation documents and learning paths

The original peer-reviewed research is Hervé Jégou, Matthijs Douze and Cordelia Schmid, Product Quantization for Nearest Neighbor Search, IEEE TPAMI 33(1), 2011, DOI 10.1109/TPAMI.2010.57: https://pubmed.ncbi.nlm.nih.gov/21088323/. It introduces Cartesian-product subspace codes and distinguishes approximate distance comparisons. The Faiss maintainers document actual index variants, code sizes, train/add/search operations and IVF probing: https://github.com/facebookresearch/faiss/wiki/Faiss-indexes. Consult the exact version of your installed library rather than assuming every published example has identical supported parameters.

For GPU-oriented large-scale context, see Johnson, Douze and Jégou, Billion-scale similarity search with GPUs, 2017: https://arxiv.org/abs/1702.08734. Related eduKateSG reading: Feature Scaling — Distance Geometry, Outliers and Train-Only Statistics explains why input geometry must be consistent; NDCG Ranking Evaluation — Graded Relevance, Position Discounts and Honest Search Tests explains a different assessment of ranked usefulness. Return to the How AI Works guide for the broader learning pathway.

Discover more from eduKate Singapore

Subscribe now to keep reading and get access to the full archive.

Continue reading