Commit e2f9cca
Fix SQtqmse codebook scale: fold 1/sqrt(d) into Lloyd-Max table (#5517)
Summary:
Pull Request resolved: #5517
`SQtqmse` reconstructions have inflated norms and badly degraded recall since
D102408184. Reported as a 1.14.2 -> 1.14.3 regression: at `d=64`, median decoded
norm of a unit-norm input went `0.9965` -> `1.1503` (+15%), while `SQtqmse8`
looked "essentially unchanged".
Fixes #5317
Root cause
-
D102408184 replaced the `tqmse` codebook construction with hardcoded Lloyd-Max
tables:
```
- scalar_quantizer::train_TurboQuantMSE(d, 4, trained);
+ populate_lloyd_max_trained(4, trained);
```
The old codebook was built for one coordinate of a unit-norm vector in R^d, so
its centroids scaled as `1/sqrt(d)`. The new tables are optimal for `N(0, 1)`
and do not depend on `d` at all.
That is correct for `_eden` and `_tq`, which rescale each vector to unit
variance before lookup. Plain `tqmse` does not: it encodes raw unit-norm
vectors, whose components are ~`1/sqrt(d)` (~`0.125` at `d=64`), against a
codebook ~50x too wide. Nearly everything falls in the innermost cells, so the
codebook collapses to a few levels and every component decodes too large:
| d | bits | distinct codes used (before D102408184 -> after) |
| --- | --- | --- |
| 64 | 4 | 16/16 -> **4/16** |
| 768 | 4 | 16/16 -> **2/16** |
| 768 | 8 | 256/256 -> **32/256** |
Gets worse as `d` grows.
Fix
-
Give `populate_lloyd_max_trained` a `scale` argument that multiplies the table.
The five `tqmse` cases pass `1/sqrt(d)` (the standard deviation of a unit-norm
vector's components) so the codebook once again (like 1.14.2) matches the data it encodes.
**No change for `_eden` / `_tq`.** They pass no `scale`, so it defaults to `1`
and every table entry is bit-identical to today.
Scaling `trained` rather than the encode path is what keeps this a one-line fix
per callsite: every SIMD specialization and distance computer reads
`this->centroids`, a pointer into `trained`.
Notes
-
- NOT A REVERT TO 1.14.2, but that is fine. 1.14.2 trained on the exact
unit-sphere marginal; this scales a Gaussian approximation of it, so centroids
differ by up to ~20% at 8 bits. The approximation is not worse: max component
error is lower than 1.14.2 and recall is restored (see test plan). The only
consequence is that `tqmse` codes are not comparable across 1.14.2 / 1.14.3 /
this version -- harmless, because the codebook ships with the index (below).
- SERIALIZATION STILL COMPATIBLE: Existing 1.14.3-written `tqmse` indexes stay readable and self-consistent:
`read_ScalarQuantizer` loads `trained` verbatim, so decode matches how they
were encoded, and `trained` length is unchanged so size validation still
passes. They are degraded, not corrupt, and need re-indexing to benefit. No
version guard added.
Reviewed By: alibeklfc
Differential Revision: D115440646
fbshipit-source-id: a559f6a6a50a65dc3ab32ff3f17cda8796b2d4ae1 parent a424dcb commit e2f9cca
2 files changed
Lines changed: 66 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| |||
425 | 426 | | |
426 | 427 | | |
427 | 428 | | |
428 | | - | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
429 | 435 | | |
430 | 436 | | |
431 | 437 | | |
432 | 438 | | |
433 | 439 | | |
434 | | - | |
435 | | - | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
436 | 452 | | |
437 | 453 | | |
438 | 454 | | |
| |||
588 | 604 | | |
589 | 605 | | |
590 | 606 | | |
591 | | - | |
| 607 | + | |
| 608 | + | |
592 | 609 | | |
593 | 610 | | |
594 | | - | |
| 611 | + | |
| 612 | + | |
595 | 613 | | |
596 | 614 | | |
597 | | - | |
| 615 | + | |
| 616 | + | |
598 | 617 | | |
599 | 618 | | |
600 | | - | |
| 619 | + | |
| 620 | + | |
601 | 621 | | |
602 | 622 | | |
603 | | - | |
| 623 | + | |
| 624 | + | |
604 | 625 | | |
605 | 626 | | |
606 | 627 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
70 | 107 | | |
71 | 108 | | |
72 | 109 | | |
| |||
0 commit comments