diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c2d2cb77..6c560005d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ installable release; see the roadmap in [README.md](README.md). ## [Unreleased] +### Performance + +- **`hrr.DEFAULT_DIM` flips 2048 → 512** ([#538](https://github.com/robotrocketscience/aelfrice/issues/538)). Aligns the HRR default dimensionality with the lab campaign R4 verdict ("adopt dim=512 default; dim=2048 escape hatch") that produced the spec at `docs/hrr_structural_query_lane.md`. ~4× memory footprint reduction for the structural-query lane: ~200 MB at N=50k vs the prior ~800 MB. Capacity per Plate's bound stays well above realistic per-belief role multiplicity (~57 retrievable bound pairs at dim=512 vs ~5 typical outgoing edges per belief). Set `dim=2048` explicitly via the `HRRStructIndex(dim=...)` kwarg for high-multiplicity corpora. + ### Changed - **`use_heat_kernel` and `use_hrr_structural` flip to default-on** ([#154](https://github.com/robotrocketscience/aelfrice/issues/154)). Both retrieval-lane flags shipped opt-in earlier (heat-kernel #150 in v1.6, HRR structural-query lane #152 in v1.7) pending the calibrated reproducibility-harness gate. That gate cleared at 11/11 via [PR #489](https://github.com/robotrocketscience/aelfrice/pull/489) closing #437, so the #154 composition tracker flips the defaults per its status banner. Precedence (env > kwarg > TOML > default) is unchanged; only the default values flip `False` → `True`. Reversible via `[retrieval] use_heat_kernel = false` / `use_hrr_structural = false` in `.aelfrice.toml` (or `AELFRICE_HEAT_KERNEL=0` / `AELFRICE_HRR_STRUCTURAL=0`) for parity with the v2.0.x ranking. diff --git a/src/aelfrice/hrr.py b/src/aelfrice/hrr.py index 0cee8ba4b..b9ab19c80 100644 --- a/src/aelfrice/hrr.py +++ b/src/aelfrice/hrr.py @@ -28,10 +28,13 @@ Vector = npt.NDArray[np.float64] # Default dimensionality. Capacity per Plate's analysis is roughly -# dim/9 retrievable bound pairs at signal-to-noise threshold; 2048 -# accommodates ~227 distinct bindings, well above aelfrice's typical -# ~5 outgoing edges per belief. -DEFAULT_DIM: Final[int] = 2048 +# dim/9 retrievable bound pairs at signal-to-noise threshold; 512 +# accommodates ~57 distinct bindings, well above aelfrice's typical +# ~5 outgoing edges per belief. dim=2048 is the escape hatch for +# high-multiplicity corpora where K approaches the lower bound. +# See #538 / lab campaign R4 verdict (full-corpus latency budget at +# N=100k holds at dim=512; dim=2048 does not). +DEFAULT_DIM: Final[int] = 512 # --------------------------------------------------------------------------- diff --git a/src/aelfrice/hrr_index.py b/src/aelfrice/hrr_index.py index 056ca21af..c48a06ab3 100644 --- a/src/aelfrice/hrr_index.py +++ b/src/aelfrice/hrr_index.py @@ -11,8 +11,8 @@ ``bind(role[KIND], id_vec[target])`` and ranks beliefs by the inner product against ``struct[b]``. Beliefs whose structure contains exactly that bound term score high; orthogonal noise from -other bindings is ``~1/sqrt(dim)`` per term, so at ``dim=2048`` the -top-K is dominated by true structural matches. +other bindings is ``~1/sqrt(dim)`` per term, so at the default +``dim=512`` the top-K is dominated by true structural matches. Parallel to the textual lane (BM25F + heat kernel), not a competitor. A query parser (:func:`parse_structural_marker`) routes structural @@ -106,7 +106,9 @@ class HRRStructIndex: Build is offline (walks every edge once); query is one matvec against the ``(N, dim)`` struct matrix plus one bind. Storage cost is dominated by the struct matrix at ``8 * N * dim`` bytes; - at ``N=50k, dim=2048`` that is ~800 MB, fitting the AC8 budget. + at ``N=50k`` and the default ``dim=512`` that is ~200 MB + (~800 MB at the ``dim=2048`` escape-hatch value), both within + the AC8 budget. Determinism: ``random_vector`` draws are reproducible from ``np.random.default_rng(seed)``. Two builds against the same