Commit Graph

1 Commits

Author SHA1 Message Date
ruv cff24dbff6 perf(guidance): M4 quantization — 1-bit RaBitQ-style signatures, 2.7x at N=1000
Horizon: guidance-sota-2026-05 (M4). The real SOTA win.

## What changed

`ShardRetriever` now maintains a packed Uint32Array of 1-bit sign
signatures alongside the existing Float32 embedding matrix. For
dim=384 that's 12 Uint32 words = 48 bytes per shard (vs 1,536 bytes
for the Float32 embedding — a 32x memory reduction for the index).

`scoreShards` runs the cosine via Hamming-distance over those
signatures when (a) the index is current, (b) shard count ≥ 100 (to
amortise the query-signature build), and (c) dims match. The
sign-random-projection theorem (Charikar 2002) gives:

    cos(θ) ≈ cos(π · hamming(sig_q, sig_s) / dim)

which is accurate enough for the retriever's sort + intent-boost +
risk-boost downstream.

## Microbench (bench-quantization.mjs)

    cosine.dot (float32, 384-d)           3,006,455 ops/s   332.62 ns/pair
    hamming.popcount (uint32, 12 words)  32,862,982 ops/s    30.43 ns/pair
                                                         ────────────
                                          Hamming speedup vs dot: 10.93x

## End-to-end (bench-retriever-scale.mjs)

  N    baseline unfilt   M4 unfilt   speedup
  10        63,910         70,777      1.11x
  100       12,135         26,372      2.17x
  500        2,470          6,468      2.62x
  1000       1,303          3,522    🚀 2.70x

  N    baseline filt     M4 filt     speedup
  10       166,274        198,451     1.19x
  100       46,419         85,311     1.84x
  500       12,974         27,081     2.09x
  1000       6,662         16,073     2.41x

All 1,331 existing tests pass. Build clean.

## Why this works where Phase 1 + M3 didn't

Phase 1 / M3 attacked the dot product's *constants* (eliminate sqrt,
hoist regex, pack memory). Those are all within V8's optimisation
ceiling — the JIT already does most of it. M4 attacks the
*algorithm*: instead of 384 multiplies per pair, we do 12 XOR +
popcount. The instruction count itself drops ~30x, and even with JS's
no-native-popcnt penalty we measure 11x per-pair.

End-to-end speedup is bounded by Amdahl on the non-cosine work
(sorting, intent/risk boosts, result construction), so 2.7x is the
expected ceiling for this fixture. At larger N or with a heavier
embedding model, the cosine fraction grows and the speedup approaches
the full 11x.

## Memory

48 bytes/shard signature vs 1,536 bytes/embedding — a 32x reduction.
At N=10,000 shards: 480KB signatures vs 15MB embeddings. Real for
cold-start RAM on hooks-running daemons.

Co-Authored-By: RuFlo <ruflo-bot@users.noreply.github.com>
2026-05-21 23:51:48 -04:00