feat(agent): build the vector index in parallel by default
`parallel` joins the agent's default features, so the HNSW bulk build uses the thread pool: cold index build at 10K records 1152 -> ~380 ms in a same-moment A/B (the graph is identical either way). Nothing else on the measured paths changes — ingest, checkpoint, open and steady-state query times are the same with the feature on or off. Adds rayon to the default dependency set; opt out with `--no-default-features --features float16,hnsw`. Harness: `--e2e-only` runs the end-to-end section without the index benchmarks. Note for anyone comparing numbers: this machine's absolute timings drifted ~1.5x over a long session, so only same-moment A/B runs are comparable. Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
8803d0754b
commit
f507803ec1
+3
-1
@@ -9,7 +9,9 @@
|
|||||||
With the `parallel` feature, planning and pruning run on a thread pool (10K:
|
With the `parallel` feature, planning and pruning run on a thread pool (10K:
|
||||||
388 ms, 100K: ~21 s -> 5.9 s on 16 cores). The graph is deterministic and
|
388 ms, 100K: ~21 s -> 5.9 s on 16 cores). The graph is deterministic and
|
||||||
identical with or without the feature. `clawhdf5-agent`'s `parallel` feature
|
identical with or without the feature. `clawhdf5-agent`'s `parallel` feature
|
||||||
now enables it for the agent's index.
|
enables it for the agent's index and is now **on by default** (adds `rayon`
|
||||||
|
to the default dependency set; build with `--no-default-features --features
|
||||||
|
float16,hnsw` to opt out).
|
||||||
- `clawhdf5-ann`: `HnswIndex::search` returned fewer than `k` results — often
|
- `clawhdf5-ann`: `HnswIndex::search` returned fewer than `k` results — often
|
||||||
none — when the records nearest the query had been deleted: it collected `ef`
|
none — when the records nearest the query had been deleted: it collected `ef`
|
||||||
candidates, *then* dropped the deleted ones, *then* took `k`. Deleted nodes
|
candidates, *then* dropped the deleted ones, *then* took `k`. Deleted nodes
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ Cargo workspace with 16 crates under `crates/` (plus `libaec-sys`, an internal F
|
|||||||
the approximate `clawhdf5-ann` index for the vector stage (the index mirrors
|
the approximate `clawhdf5-ann` index for the vector stage (the index mirrors
|
||||||
the cache and self-heals on drift). Build the agent with
|
the cache and self-heals on drift). Build the agent with
|
||||||
`--no-default-features --features float16` to force the exact linear cosine scan.
|
`--no-default-features --features float16` to force the exact linear cosine scan.
|
||||||
|
The agent's `parallel` feature (also default) builds the index on a thread
|
||||||
|
pool; the graph is identical with or without it.
|
||||||
The index uses the HNSW paper's diversity heuristic for neighbour selection
|
The index uses the HNSW paper's diversity heuristic for neighbour selection
|
||||||
(plain closest-M capped recall on clustered data: 0.31 recall@10 at 100K). Its
|
(plain closest-M capped recall on clustered data: 0.31 recall@10 at 100K). Its
|
||||||
graph is saved to `<store>.h5.ann` at each checkpoint and reloaded by `open()`
|
graph is saved to `<store>.h5.ann` at each checkpoint and reloaded by `open()`
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ name = "memory_bench"
|
|||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["float16", "hnsw"]
|
default = ["float16", "hnsw", "parallel"]
|
||||||
float16 = ["half"]
|
float16 = ["half"]
|
||||||
# Rayon-parallel brute-force search strategies, and a parallel bulk build of
|
# Rayon-parallel brute-force search strategies, and a parallel bulk build of
|
||||||
# the HNSW index (same graph, several times faster on a multi-core machine).
|
# the HNSW index (same graph, several times faster on a multi-core machine).
|
||||||
|
|||||||
@@ -485,8 +485,12 @@ fn main() {
|
|||||||
|
|
||||||
let mut json = Vec::new();
|
let mut json = Vec::new();
|
||||||
println!("## Search harness");
|
println!("## Search harness");
|
||||||
for &n in sizes {
|
// `--e2e-only` skips the index benchmarks, so the end-to-end section runs
|
||||||
bench_ann(n, &mut json);
|
// in a process that has not already spun up a thread pool.
|
||||||
|
if !args.iter().any(|a| a == "--e2e-only") {
|
||||||
|
for &n in sizes {
|
||||||
|
bench_ann(n, &mut json);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ann_only {
|
if ann_only {
|
||||||
|
|||||||
Reference in New Issue
Block a user