Skip to content
Closed
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
6c508e3
DiskBBQ - adjust query greediness based on per segment affinity
tteofili Jul 31, 2025
6281bcf
wip fixes
tteofili Jul 31, 2025
62e4d0c
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Jul 31, 2025
ab11958
wip fixes
tteofili Jul 31, 2025
980940e
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Aug 1, 2025
3f4e5fd
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Aug 1, 2025
df0210d
Include top 2 parent scores into affinity, with larger segments
tteofili Aug 1, 2025
8cbad8f
minor fix
tteofili Aug 1, 2025
b097c20
include (parent) centroids scores for affinity, with larger segments
tteofili Aug 4, 2025
9499be1
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Aug 4, 2025
0635453
more sensible and generic threshold definition
tteofili Aug 4, 2025
d52dc40
[CI] Auto commit changes from spotless
Aug 4, 2025
c658856
Merge branch 'diskbbq_segment_affinity' of github.com:tteofili/elasti…
tteofili Aug 4, 2025
34cf456
spotless
tteofili Aug 4, 2025
0dc22eb
minor tweaks
tteofili Aug 4, 2025
028482e
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Aug 4, 2025
a6702eb
minor tweaks
tteofili Aug 4, 2025
5288b8e
[CI] Auto commit changes from spotless
Aug 4, 2025
0a74a0c
set visited vector max budget ratio
tteofili Aug 5, 2025
7600d50
Merge branch 'diskbbq_segment_affinity' of github.com:tteofili/elasti…
tteofili Aug 5, 2025
c3cec18
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Aug 5, 2025
4f98473
minor
tteofili Aug 5, 2025
72d6d24
minor tweaks
tteofili Aug 5, 2025
9ee4bfd
minor
tteofili Aug 5, 2025
4f9982e
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Aug 5, 2025
aeee542
minor tweaks, add knn tester param
tteofili Aug 5, 2025
5facc1b
[CI] Auto commit changes from spotless
Aug 5, 2025
feedbdf
minor tweaks
tteofili Aug 5, 2025
58a397b
Merge branch 'diskbbq_segment_affinity' of github.com:tteofili/elasti…
tteofili Aug 5, 2025
c3f97c9
minor tweaks
tteofili Aug 5, 2025
363d987
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Aug 5, 2025
1b42ca3
spotless
tteofili Aug 5, 2025
dfd9ba2
Update docs/changelog/132396.yaml
tteofili Aug 5, 2025
b5446a2
Merge branch 'main' into diskbbq_segment_affinity
john-wagster Aug 6, 2025
e38e513
Merge branch 'main' into fork/tteofili/diskbbq_segment_affinity
iverase Aug 11, 2025
e3e2091
spotless
iverase Aug 11, 2025
ec987f7
Merge branch 'main' into diskbbq_segment_affinity
iverase Aug 11, 2025
9337703
[DiskBBQ] Replace n_probe, related to the number of centroids with v…
iverase Aug 12, 2025
71021f0
iter
iverase Aug 12, 2025
651e359
doh
iverase Aug 12, 2025
0d51546
iterate leaves to get total budget
john-wagster Aug 12, 2025
36f0169
[CI] Auto commit changes from spotless
Aug 12, 2025
35dfb21
merging w ratio switchover, set default for ratio when creating strat…
john-wagster Aug 12, 2025
08011c5
merging w head
john-wagster Aug 12, 2025
ebbbfd9
clean up refs to nprobe, fixing how we instatiate strategy and defaul…
john-wagster Aug 13, 2025
baa3ebb
improved counting docs and set a min budget
john-wagster Aug 13, 2025
c9daf27
spotless
john-wagster Aug 13, 2025
ffc9a64
Merge branch 'main' into visitRatio
iverase Aug 13, 2025
d0019c2
iter
iverase Aug 13, 2025
528367a
Merge branch 'main' into visitRatio
iverase Aug 13, 2025
ab36139
Compute visitRatio globally when doing it dynamically
iverase Aug 13, 2025
b8b8091
Merge branch 'visitRatio' of github.com:iverase/elasticsearch into vi…
iverase Aug 13, 2025
5a7f5d8
merging w latest ratioVisit, fixed how we collect docs w vectors count
john-wagster Aug 13, 2025
cb1c444
spotless
john-wagster Aug 13, 2025
3d2720a
need to validate if scorer is null
john-wagster Aug 13, 2025
5b8443c
Merge branch 'main' into visitRatio
iverase Aug 13, 2025
66e11f7
cleanup
john-wagster Aug 13, 2025
b2b8bfe
fixing some calcs
john-wagster Aug 14, 2025
da21795
make expected depend on numVectors
iverase Aug 14, 2025
c80dcfc
assert we only support Float queries
iverase Aug 14, 2025
1583fa4
two fixes
benwtrent Aug 14, 2025
db1aa73
Merge branch 'visitRatio' of github.com:iverase/elasticsearch into vi…
benwtrent Aug 14, 2025
3b6f21d
merging w latest ratioVisit, slight adjustment to low affinity explor…
john-wagster Aug 14, 2025
15d92d5
merging main
john-wagster Aug 14, 2025
8ae7787
remove unnecessary scaling and visitRatio default duplicate logic
john-wagster Aug 14, 2025
ff4916d
calculating affinities accounting for some of the wide variance seen
john-wagster Aug 15, 2025
f3afcd6
calculating affinities accounting for some of the wide variance seen
john-wagster Aug 15, 2025
22ce362
don't add task with 0 budget, adjust thresholds for skewed affinities…
tteofili Aug 19, 2025
480fc0d
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Aug 19, 2025
e8dbdef
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Aug 20, 2025
d631243
comment
tteofili Aug 20, 2025
d261f02
remove explicit budget as it conflicts with visitedRatio, normalized …
tteofili Aug 22, 2025
e9d4d82
don't use affinity calculation for filters
tteofili Aug 22, 2025
3b291df
minor fix
tteofili Aug 22, 2025
76c22b9
more sensible visited ratio adjustment
tteofili Aug 22, 2025
7f2e954
removed useless interface
tteofili Aug 22, 2025
d887b88
Merge branch 'main' into diskbbq_segment_affinity
benwtrent Aug 25, 2025
e8e7d12
pull out magic nums, clean up, set hard cap on when to apply visit ra…
john-wagster Aug 25, 2025
a67fb67
Merge branch 'main' into diskbbq_segment_affinity
john-wagster Aug 26, 2025
daea67d
Merge branch 'main' of github.com:elastic/elasticsearch into diskbbq_…
tteofili Sep 3, 2025
571534c
merge
tteofili Sep 3, 2025
8e13a3a
[CI] Auto commit changes from spotless
Sep 3, 2025
3d1c6b6
account for numVectors for segment size variance being high, more dec…
tteofili Sep 5, 2025
daa8f40
work better with unbalanced segments, simplified
tteofili Sep 5, 2025
59cae53
Merge branch 'diskbbq_segment_affinity' of github.com:tteofili/elasti…
tteofili Sep 5, 2025
b9a9e23
changelog
tteofili Sep 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/changelog/132396.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pr: 132396
summary: DiskBBQ - Adapt `nProbe` based on query - segment affinity in multi segment
scenario
area: Vector Search
type: enhancement
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ record CmdLineArgs(
static final ParseField INDEX_TYPE_FIELD = new ParseField("index_type");
static final ParseField NUM_CANDIDATES_FIELD = new ParseField("num_candidates");
static final ParseField K_FIELD = new ParseField("k");
// static final ParseField N_PROBE_FIELD = new ParseField("n_probe");
static final ParseField VISIT_PERCENTAGE_FIELD = new ParseField("visit_percentage");
static final ParseField IVF_CLUSTER_SIZE_FIELD = new ParseField("ivf_cluster_size");
static final ParseField OVER_SAMPLING_FACTOR_FIELD = new ParseField("over_sampling_factor");
Expand Down Expand Up @@ -98,7 +97,6 @@ static CmdLineArgs fromXContent(XContentParser parser) throws IOException {
PARSER.declareString(Builder::setIndexType, INDEX_TYPE_FIELD);
PARSER.declareInt(Builder::setNumCandidates, NUM_CANDIDATES_FIELD);
PARSER.declareInt(Builder::setK, K_FIELD);
// PARSER.declareIntArray(Builder::setNProbe, N_PROBE_FIELD);
PARSER.declareDoubleArray(Builder::setVisitPercentages, VISIT_PERCENTAGE_FIELD);
PARSER.declareInt(Builder::setIvfClusterSize, IVF_CLUSTER_SIZE_FIELD);
PARSER.declareInt(Builder::setOverSamplingFactor, OVER_SAMPLING_FACTOR_FIELD);
Expand Down Expand Up @@ -134,7 +132,6 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field(INDEX_TYPE_FIELD.getPreferredName(), indexType.name().toLowerCase(Locale.ROOT));
builder.field(NUM_CANDIDATES_FIELD.getPreferredName(), numCandidates);
builder.field(K_FIELD.getPreferredName(), k);
// builder.field(N_PROBE_FIELD.getPreferredName(), nProbes);
builder.field(VISIT_PERCENTAGE_FIELD.getPreferredName(), visitPercentages);
builder.field(IVF_CLUSTER_SIZE_FIELD.getPreferredName(), ivfClusterSize);
builder.field(OVER_SAMPLING_FACTOR_FIELD.getPreferredName(), overSamplingFactor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,63 @@ CentroidIterator getCentroidIterator(FieldInfo fieldInfo, int numCentroids, Inde
return getCentroidIteratorNoParent(fieldInfo, centroids, numCentroids, scorer, quantized, queryParams, globalCentroidDp);
}

@Override
public float[] getCentroidsScores(FieldInfo fieldInfo, int numCentroids, IndexInput centroids, float[] targetQuery, boolean parents)
throws IOException {
final FieldEntry fieldEntry = fields.get(fieldInfo.number);
final float globalCentroidDp = fieldEntry.globalCentroidDp();
final OptimizedScalarQuantizer scalarQuantizer = new OptimizedScalarQuantizer(fieldInfo.getVectorSimilarityFunction());
final int[] scratch = new int[targetQuery.length];
float[] targetQueryCopy = ArrayUtil.copyArray(targetQuery);
if (fieldInfo.getVectorSimilarityFunction() == COSINE) {
VectorUtil.l2normalize(targetQueryCopy);
}
final OptimizedScalarQuantizer.QuantizationResult queryParams = scalarQuantizer.scalarQuantize(
targetQueryCopy,
scratch,
(byte) 7,
fieldEntry.globalCentroid()
);
final byte[] quantizedQuery = new byte[targetQuery.length];
for (int i = 0; i < quantizedQuery.length; i++) {
quantizedQuery[i] = (byte) scratch[i];
}
final ES92Int7VectorsScorer scorer = ESVectorUtil.getES92Int7VectorsScorer(centroids, fieldInfo.getVectorDimension());
centroids.seek(0L);
// final scores
final float[] scores = new float[ES92Int7VectorsScorer.BULK_SIZE];

int numParents = centroids.readVInt();
if (parents && numParents > 0) {
final NeighborQueue parentsQueue = new NeighborQueue(numParents, true);
score(
parentsQueue,
numParents,
0,
scorer,
quantizedQuery,
queryParams,
globalCentroidDp,
fieldInfo.getVectorSimilarityFunction(),
scores
);
} else {
final NeighborQueue neighborQueue = new NeighborQueue(numCentroids, true);
score(
neighborQueue,
numCentroids,
0,
scorer,
quantizedQuery,
queryParams,
globalCentroidDp,
fieldInfo.getVectorSimilarityFunction(),
scores
);
}
return scores;
}

private static CentroidIterator getCentroidIteratorNoParent(
FieldInfo fieldInfo,
IndexInput centroids,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ protected IVFVectorsReader(SegmentReadState state, FlatVectorsReader rawVectorsR
abstract CentroidIterator getCentroidIterator(FieldInfo fieldInfo, int numCentroids, IndexInput centroids, float[] target)
throws IOException;

public abstract float[] getCentroidsScores(FieldInfo fieldInfo, int numCentroids, IndexInput centroids, float[] target, boolean parents)
throws IOException;

private static IndexInput openDataInput(
SegmentReadState state,
int versionMeta,
Expand Down Expand Up @@ -258,6 +261,9 @@ public final void search(String field, float[] target, KnnCollector knnCollector
// is enough?
expectedDocs += scorer.resetPostingsScorer(offset);
actualDocs += scorer.visit(knnCollector);
if (knnCollector.earlyTerminated()) {
break;
}
}
if (acceptDocs != null) {
float unfilteredRatioVisited = (float) expectedDocs / numVectors;
Expand All @@ -267,6 +273,9 @@ public final void search(String field, float[] target, KnnCollector knnCollector
long offset = centroidIterator.nextPostingListOffset();
scorer.resetPostingsScorer(offset);
actualDocs += scorer.visit(knnCollector);
if (knnCollector.earlyTerminated()) {
break;
}
}
}
}
Expand Down Expand Up @@ -318,6 +327,17 @@ interface CentroidIterator {
long nextPostingListOffset() throws IOException;
}

// TODO : change this to allow (batched) centroid search (with current top)
public interface ScoredCentroidIterator {
boolean hasNext();

void scorePostingList(long offset) throws IOException;

long next();

long nextPostingListOffset() throws IOException;
}

interface PostingVisitor {
// TODO maybe we can not specifically pass the centroid...

Expand All @@ -327,4 +347,16 @@ interface PostingVisitor {
/** returns the number of scored documents */
int visit(KnnCollector collector) throws IOException;
}

public IndexInput getIvfCentroids(FieldInfo fieldInfo) throws IOException {
return fields.get(fieldInfo.number).centroidSlice(ivfCentroids);
}

public int getNumCentroids(FieldInfo fieldInfo) {
return fields.get(fieldInfo.number).numCentroids;
}

public float[] getGlobalCentroid(FieldInfo fieldInfo) {
return fields.get(fieldInfo.number).globalCentroid;
}
}
Loading