Product Quantization and Asymmetric Distance Computation
Quantizing each subspace independently turns one intractable codebook into a product of small ones — the additive distortion that makes it work, and the lookup table that keeps search fast
Overview & motivation
The previous topic left us at a wall. A single flat codebook of codewords compresses a -dimensional embedding to a single byte, but on the synthetic finance cloud it retained only about of the top- nearest-neighbor recall — and a flat codebook cannot do much better cheaply. To halve its distortion it must roughly square its codebook size, and a codebook of codewords needs trainable centroids: bounded above by the number of training points and, well before that, intractable to store or search. A flat codebook simply cannot reach the bit budgets that fine compression requires.
Product quantization gives up on the single codebook. Split each vector into disjoint subvectors, quantize each subspace independently with its own small codebook, and represent the vector by the tuple of sub-centroid indices. Each sub-codebook is trained by exactly the Lloyd’s k-means of the previous topic — product quantization is that algorithm run times, in parallel, on the coordinate blocks. The reward is a codebook that is the product of the sub-codebooks: with subspaces and codewords each, an effective codewords represented by only stored centroids. The whole topic is the mathematics of that trade — why the independent training is correct, what the product buys, how retrieval stays fast, and, honestly, what the factorization costs.
Before the algebra, take the product apart. Select a point and watch its two sub-codes and the two distortion bars that sum to its total:
The first panel splits a four-dimensional toy vector into two two-dimensional subspaces, each with its own Voronoi codebook; the per-subspace reconstruction errors sum exactly to the total — the identity this topic turns on. The second panel is the payoff: ADC recall against the rate, with PQ climbing past the flat-codebook ceiling it can never exceed. The third shows the lookup table that makes asymmetric distance an operation. The codebook this topic builds is the atom that optimized product quantization rotates and that the inverted-file index (IVFADC) and the multi-vector PLAID index reuse — the topics that follow.
What we cover
- The product quantizer: subspaces, sub-codebooks, codes, and the effective codebook.
- The additive distortion decomposition — why each subspace is trained independently.
- What the product buys: codewords at storage.
- Asymmetric distance computation — exact, and a table lookup; ADC versus SDC.
- Scalability, honestly: PQ reaches budgets a flat codebook cannot, but does not beat it per bit.
- The independence cost and the rotation that fixes it, a finance case study, and the tested code.
The product quantizer
Fix a source and a number of subspaces dividing , with subspace dimension .
Definition 1 (Product quantizer).
Write with each subvector the -th block of coordinates. Each subspace has its own sub-codebook and sub-quantizer . The product quantizer encodes as the tuple of indices — a code of bits — and decodes by concatenation,
Its reproduction values form the effective codebook , the Cartesian product of the sub-codebooks, with elements.
The single structural choice — quantize the blocks separately — is what we must justify. It is not obvious that independent sub-quantizers minimize the joint distortion, nor that a product codebook is a good codebook. The next theorem settles the first question completely.
The additive distortion decomposition
The distortion of is , the same squared-error objective as before. Its special structure under a product quantizer is the whole reason PQ works.
Theorem 1 (Additive distortion decomposition).
For a product quantizer, the squared reconstruction error splits over subspaces,
so the total distortion is the sum of the per-subspace distortions, with . Consequently the codebook minimizing is obtained by minimizing each independently, and each sub-problem is exactly the Lloyd–Max quantizer of the previous topic on the -th block.
Proof.
The squared Euclidean norm is a sum over coordinates, and the coordinates partition into the disjoint blocks. Since restricted to block is and depends only on the coordinates of in block ,
Taking expectations gives . The decision variables are disjoint — the sub-codebook and the encoder affect only the term and appear in no other — so the sum is minimized by minimizing each term over its own variables, with no coupling. Minimizing over a -codeword quantizer of the -dimensional subvector is precisely the vector-quantization problem of the previous topic, solved by Lloyd’s two conditions.
∎This is the theorem the laboratory’s first panel makes visible: the two per-subspace bars sum to the total, exactly, for every point. It is also the practical recipe — train separate k-means, one per block — and the reason the companion code imports the previous topic’s Lloyd implementation rather than writing a new one. Product quantization adds no new optimization; it only factors the old one.
What the product buys
The decomposition explains correctness; the product explains the win.
Proposition 1 (Effective codebook versus storage).
A product quantizer with subspaces and codewords each represents distinct reproduction vectors — the size of the product codebook — while storing only centroids and encoding each vector in bits. The per-vector distance to a query costs table lookups (next section), against for an exact distance.
The numbers are stark. At , , a product quantizer encodes each vector in bits — eight bytes — and its effective codebook holds codewords. A flat codebook with codewords is a fantasy: it would need trained centroids, impossible to store, train, or search, and unreachable in principle from any finite training set since a codebook can have at most as many codewords as training points. The product quantizer reaches the same representational resolution from stored centroids. That gap — exponential codebook from linear storage — is the entire value proposition, and we will price it honestly in two sections.
Asymmetric distance computation
A compressed index is useful only if we can search it. Given a query and database vectors stored as PQ codes, we need the distance to each. The block structure turns it into a table lookup.
Theorem 2 (Asymmetric distance is exact and a table lookup).
For an un-quantized query and a database vector with code ,
where is an table of squared sub-distances built once per query. Each database distance is then table lookups and adds — , independent of beyond the one-time table build.
Proof.
is a genuine vector in , and is untouched, so the additive decomposition of Theorem 1 applies verbatim with in place of : the squared norm splits over the blocks, and on block the reproduction is , giving . Each term depends on the database vector only through its index in subspace , so once is precomputed for all sub-centroids, the term is the single entry . The sum is exact — the table memoizes, it does not approximate.
∎This is asymmetric distance: the query stays in full precision while the database is quantized. The third panel of the laboratory shows it directly — a database vector’s code highlights cells of the table whose sum is the exact distance to its reconstruction. The companion harness checks this equality to machine precision on the finance cloud.
The alternative is symmetric distance (SDC), which quantizes the query too and reads from a precomputed table of inter-centroid distances. SDC is cheaper to precompute but adds the query’s own quantization error, and that costs accuracy.
Proposition 2 (Asymmetric beats symmetric in the mean).
Averaged over queries and database vectors, the asymmetric estimate has smaller squared distance-estimation error than the symmetric one, , and yields recall at least as high. The inequality is in expectation, not per pair: individual query–database pairs can reverse.
On the finance cloud the gap is large — the companion code measures a mean squared distance-estimation error of about for ADC against for SDC, and recall@10 of against — because keeping the query exact removes an entire source of error. We state the inequality honestly as a statement about the mean, since SDC can accidentally land closer on a given pair; what is guaranteed is the average and the recall.
Scalability, honestly
It is tempting to say product quantization “beats” a flat codebook. It does not, and the honest version is more interesting.
Remark.
At any bit budget where a flat codebook of codewords is trainable, the flat codebook is unconstrained while the product quantizer’s reconstruction is confined to the product set — a strict subset of all -codeword codebooks. So at equal trainable bits, flat-VQ distortion is at most PQ’s; PQ pays a product-separability constraint. The companion code confirms this at , , and bits on the finance cloud. PQ’s advantage is reachability: a flat codebook needs centroids — capped at training points and intractable past roughly sixteen to twenty bits — while PQ reaches rate at stored centroids. It attains distortion and recall a flat codebook cannot reach at any feasible storage.
The scalability panel of the laboratory plots this exactly. The flat ceiling is the point: a single -codeword codebook at bits, recall — the same number the previous topic baked, on the same cloud. As grows the rate grows and recall climbs to at bits, at bits, at bits — each a budget a flat codebook cannot train. The per-subspace Zador exponent of the previous topic is why each subspace needs only modest , and the product is why the budgets compose. The gain is real, but it is a gain in reach, not in quality per bit, and the laboratory labels it as such.
Finance case study
A candid note, in the spirit of the series: the cloud is a deterministic synthetic low-rank-plus-noise construction, CPU-only and reproducible to the decimal, and the distortion and recall are measured on it; it is not a trained encoder. Because the previous topic used the same generator, the flat ceiling and the PQ numbers are measured on one cloud, which is what makes the comparison fair.
The honest catch: the product constraint and the rotation that fixes it
The product-separability constraint has a name and a cure. Product quantization treats the subspaces as independent — it allocates the same to each and quantizes each in ignorance of the others. When the subspaces are genuinely independent and carry equal variance, that loses almost nothing. When they are correlated, or when their variances are uneven, PQ wastes bits: a high-variance subspace is under-quantized while a low-variance one is over-quantized, and correlation that a joint codebook would exploit is thrown away. The residual distortion PQ pays over a full joint codebook is governed by the mutual information across subspaces.
The fix is a rotation. Apply an orthogonal to every vector before splitting; since preserves distances, the retrieval problem is unchanged, but the axes along which we split are now ours to choose. The companion code makes the effect concrete on a deliberately variance-imbalanced cloud, where the coordinate variances decay so the contiguous subspaces carry very unequal variance. Raw product quantization there has distortion about . A naive rotation that only aligns to the principal axes barely helps — distortion — because it concentrates all the variance into the first subspace and starves the rest. But a rotation that balances the variance across subspaces, spreading the high-variance principal directions evenly, cuts the distortion to about , a several-fold reduction. Choosing the rotation that minimizes PQ distortion is exactly optimized product quantization (Ge et al., 2014), and it is the next topic. We show the direction of the effect, not a universal number — on the finance cloud, whose random basis already spreads variance fairly evenly, the gain is smaller — but the mechanism is the one OPQ formalizes.
Honest caveats
Implementation
The companion notebook (notebookPath) is self-contained, CPU-only, and runs in a few seconds on numpy and scipy. It imports the previous topic’s Lloyd implementation — lloyd, kmeans++ seeding, the empty-cell repair, the synthetic finance cloud, and the scipy cross-check — so product quantization is provably just that algorithm run per subspace, and then adds the PQ-specific machinery: subspace splitting, the product encoder and decoder, the asymmetric and symmetric distance tables, the recall comparison, the flat-versus-PQ accounting, the scalability frontier, and the rotation study. Its verification harness makes each claim executable: the additive decomposition is exact (Theorem 1); the asymmetric distance equals the brute-force distance to the reconstruction to machine precision (Theorem 2); the effective codebook is from centroids (Proposition 1); ADC’s mean error is below SDC’s and its recall at least as high (Proposition 2); a flat codebook’s distortion is at most PQ’s at every trainable bit budget; PQ’s -bit recall far exceeds the flat -bit ceiling on the same cloud; a variance-balancing rotation lowers distortion where a naive one does not; and each sub-codebook matches scipy.cluster.vq.kmeans2. The three pillars — the proofs above, the laboratory, and the tested code — agree by construction, the toy cloud’s sub-codebooks and the scalability frontier baked from the same viz_constants() the laboratory reads.
Connections
- product quantization is literally Lloyd's algorithm run independently on each subspace: every sub-codebook is trained by the k-means of the previous topic, the additive distortion decomposition reduces the joint problem to m independent Lloyd quantizers, and the companion code imports that topic's lloyd, kmeans++, and empty-cell repair rather than reimplementing them vector-quantization-lloyd-max
- the curse of dimensionality is exactly what a single codebook cannot scale against — Zador's distortion falls only as k^(-2/d) — and product quantization beats it by factoring the d-dimensional problem into m low-dimensional ones whose product codebook is exponentially large at linear storage, the structured escape the concentration results there motivate high-dimensional-geometry
- exact maximum-inner-product search is the scan to avoid, and asymmetric distance computation is the table-lookup escape this topic builds: replacing each database vector by a short code turns an O(d) distance into m table lookups, trading the proven hardness of exact search for the controlled approximation error PQ quantifies mips-hardness-and-sublinearity-limits
- PCA rotates and truncates to decorrelate and shrink the vector, and the rotation that makes product quantization optimal is the same kind of object: the residual loss PQ pays is cross-subspace correlation, which a PCA-like rotation reduces, so the eigenstructure developed there is exactly what optimized product quantization learns to balance variance across subspaces pca-dimensionality-reduction
References & Further Reading
- paper Product Quantization for Nearest Neighbor Search — Jégou, Douze & Schmid (2011) The paper that introduced product quantization and asymmetric distance computation for ANN search — the source of the additive decomposition and the ADC/SDC distinction proved here
- paper Optimized Product Quantization — Ge, He, Ke & Sun (2014) The learned rotation that minimizes PQ distortion by decorrelating and balancing variance across subspaces — the next topic, and the cited fix for the independence caveat
- paper Quantization — Gray & Neuhoff (1998) The definitive survey: product and structured vector quantizers, the rate-distortion framing, and the constrained-complexity codebooks PQ is an instance of
- book Vector Quantization and Signal Compression — Gersho & Gray (1992) The standard text on product-code and structured vector quantizers — the classical origin of quantizing subvectors with separate codebooks
- documentation Faiss: Billion-Scale Similarity Search — Johnson, Douze & Jégou (2019) How production ANN indexes implement PQ and IVFADC — the k-means quantizer, the asymmetric lookup tables, and the inverted-file coarse partition that compose into IndexIVFPQ