chore(release): v2.6.0
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
+54
-45
@@ -1,53 +1,19 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
## v2.6.0 (2026-09-20)
|
||||
|
||||
### Testing
|
||||
- The Python interop suites honour **`CLAWHDF5_PYTHON`**, and `ci-test.sh`
|
||||
picks up a `.venv/bin/python` automatically. On a PEP 668 "externally
|
||||
managed" system h5py cannot be installed into the system interpreter at all,
|
||||
so every interop suite — the h5py writer round-trips, the facade, netCDF4
|
||||
and the reference files — was skipping silently. A silent skip here is
|
||||
exactly how the v5 compound-datatype bug reached a release.
|
||||
`CLAWHDF5_REQUIRE_INTEROP=1` still turns a skip into a failure.
|
||||
|
||||
### Memory
|
||||
- `clawhdf5-agent`: **`MemoryConfig::quantized_index`** stores the vector
|
||||
index's own copy of the embeddings as `i8` rather than `f32`, which at 100k
|
||||
384-dim entries takes the index from 266 to 123 MiB and the whole reopened
|
||||
store from 399 to 256 MiB (2.72x -> **1.74x** the raw vectors). Quantised
|
||||
distances are approximate and `ef` cannot compensate — recall@10 tops out at
|
||||
0.967 against f32's 0.9995 — so the query path re-scores the candidate pool
|
||||
against the exact embeddings the store already holds, which restores recall
|
||||
(0.9940 vs 0.9945 at ef=64) for about 13% of QPS. **Off by default**: it
|
||||
trades query speed for memory, and which side is worth more depends on the
|
||||
deployment. The setting is persisted, so a reopened store does not silently
|
||||
revert to four times the index memory.
|
||||
- `clawhdf5-ann`: `Storage::Int8` and the `build_with` / `new_with` /
|
||||
`from_graph_bytes_with` constructors that select it. The scale is per row,
|
||||
not global — a fixed `[-1, 1]` scale spends fewer than 12 of the 255 levels
|
||||
on a unit-length 128-dim vector and is unusable (0.35 top-10 overlap against
|
||||
an exact ranking, versus 0.99 per row). `compact()` keeps the storage it was
|
||||
given; serialized indexes still carry f32 vectors, so a quantised index is
|
||||
rebuilt rather than loaded.
|
||||
|
||||
### Memory
|
||||
- `clawhdf5-agent`: **a loaded store holds ~30% less memory** (100k 384-dim
|
||||
entries: 505 -> 357 MiB, 3.44x -> 2.43x the raw vectors). The cache kept
|
||||
every embedding twice — a `Vec<Vec<f32>>` and a flattened copy for the
|
||||
batched kernels, maintained in lock-step — so it now stores only the flat
|
||||
buffer and indexes into it. Recall and query latency are unchanged.
|
||||
**Breaking:** `MemoryCache::embeddings` is a `cache::Embeddings` rather than
|
||||
### Upgrade Notes
|
||||
- **Re-ranked results change, substantially for the better.** `RerankInput`
|
||||
and `ReRankConfig` gained fields (`relevance`, `relevance_weight`), so
|
||||
literal constructions need updating; `..Default::default()` does not. Any
|
||||
caller that re-ranked was previously getting results ordered by age with the
|
||||
retrieval score discarded — see below.
|
||||
- **Breaking:** `MemoryCache::embeddings` is a `cache::Embeddings` rather than
|
||||
a `Vec<Vec<f32>>` (indexing still yields a `&[f32]` row); `embeddings_flat`
|
||||
is gone, replaced by `flat_embeddings()`; `rebuild_flat()` is a deprecated
|
||||
no-op. Rows are now always exactly `dim` long — shorter ones are
|
||||
zero-padded — which makes the ragged-row case that used to silently
|
||||
misalign the flattened copy unrepresentable.
|
||||
- `clawhdf5-bench`: `search_harness --footprint` reports live heap use per
|
||||
stage, measured with a counting allocator (RSS cannot see a structure freed
|
||||
into the allocator's own pool).
|
||||
|
||||
## Unreleased
|
||||
no-op.
|
||||
- `MemoryConfig` gained `quantized_index` (default `false`, so behaviour is
|
||||
unchanged unless you opt in); literal constructions need the field.
|
||||
|
||||
### Retrieval quality
|
||||
- `clawhdf5-agent`: **re-ranking discarded the retrieval score.**
|
||||
@@ -70,6 +36,49 @@
|
||||
one it supersedes? Plain recall cannot see this, because both are labelled
|
||||
gold. New `--rerank-sweep`.
|
||||
|
||||
### Memory
|
||||
- `clawhdf5-agent`: **`MemoryConfig::quantized_index`** stores the vector
|
||||
index's own copy of the embeddings as `i8` rather than `f32`, which at 100k
|
||||
384-dim entries takes the index from 266 to 123 MiB and the whole reopened
|
||||
store from 399 to 256 MiB (2.72x -> **1.74x** the raw vectors). Quantised
|
||||
distances are approximate and `ef` cannot compensate — recall@10 tops out at
|
||||
0.967 against f32's 0.9995 — so the query path re-scores the candidate pool
|
||||
against the exact embeddings the store already holds, which restores recall
|
||||
(0.9940 vs 0.9945 at ef=64) for about 13% of QPS. **Off by default**: it
|
||||
trades query speed for memory, and which side is worth more depends on the
|
||||
deployment. The setting is persisted, so a reopened store does not silently
|
||||
revert to four times the index memory.
|
||||
- `clawhdf5-ann`: `Storage::Int8` and the `build_with` / `new_with` /
|
||||
`from_graph_bytes_with` constructors that select it. The scale is per row,
|
||||
not global — a fixed `[-1, 1]` scale spends fewer than 12 of the 255 levels
|
||||
on a unit-length 128-dim vector and is unusable (0.35 top-10 overlap against
|
||||
an exact ranking, versus 0.99 per row). `compact()` keeps the storage it was
|
||||
given; serialized indexes still carry f32 vectors, so a quantised index is
|
||||
rebuilt rather than loaded.
|
||||
- `clawhdf5-agent`: **a loaded store holds ~30% less memory** (100k 384-dim
|
||||
entries: 505 -> 357 MiB, 3.44x -> 2.43x the raw vectors). The cache kept
|
||||
every embedding twice — a `Vec<Vec<f32>>` and a flattened copy for the
|
||||
batched kernels, maintained in lock-step — so it now stores only the flat
|
||||
buffer and indexes into it. Recall and query latency are unchanged.
|
||||
**Breaking:** `MemoryCache::embeddings` is a `cache::Embeddings` rather than
|
||||
a `Vec<Vec<f32>>` (indexing still yields a `&[f32]` row); `embeddings_flat`
|
||||
is gone, replaced by `flat_embeddings()`; `rebuild_flat()` is a deprecated
|
||||
no-op. Rows are now always exactly `dim` long — shorter ones are
|
||||
zero-padded — which makes the ragged-row case that used to silently
|
||||
misalign the flattened copy unrepresentable.
|
||||
- `clawhdf5-bench`: `search_harness --footprint` reports live heap use per
|
||||
stage, measured with a counting allocator (RSS cannot see a structure freed
|
||||
into the allocator's own pool).
|
||||
|
||||
### Testing
|
||||
- The Python interop suites honour **`CLAWHDF5_PYTHON`**, and `ci-test.sh`
|
||||
picks up a `.venv/bin/python` automatically. On a PEP 668 "externally
|
||||
managed" system h5py cannot be installed into the system interpreter at all,
|
||||
so every interop suite — the h5py writer round-trips, the facade, netCDF4
|
||||
and the reference files — was skipping silently. A silent skip here is
|
||||
exactly how the v5 compound-datatype bug reached a release.
|
||||
`CLAWHDF5_REQUIRE_INTEROP=1` still turns a skip into a failure.
|
||||
|
||||
## v2.5.0 (2026-09-19)
|
||||
|
||||
### Upgrade Notes
|
||||
|
||||
Reference in New Issue
Block a user