sliftutils 1.4.86 → 1.4.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts
CHANGED
|
@@ -2393,7 +2393,7 @@ declare module "sliftutils/storage/proxydatabase/ivfEmbeddingDatabase" {
|
|
|
2393
2393
|
};
|
|
2394
2394
|
export declare function rebuildStructure(database: Database<IvfEmbeddingRoot>): void;
|
|
2395
2395
|
export declare function searchEmbeddings(database: Database<IvfEmbeddingRoot>, query: StoredEmbedding, options: {
|
|
2396
|
-
|
|
2396
|
+
probeCellCount: number;
|
|
2397
2397
|
resultCount: number;
|
|
2398
2398
|
}): SearchHit[] | undefined;
|
|
2399
2399
|
export declare function lookupEmbeddings(database: Database<IvfEmbeddingRoot>, refs: string[]): Map<string, StoredEmbedding> | undefined;
|
package/package.json
CHANGED
|
@@ -72,7 +72,7 @@ async function main() {
|
|
|
72
72
|
const sampleCount = 100;
|
|
73
73
|
for (let index = 0; index < sampleCount; index++) {
|
|
74
74
|
const query = allInputs[Math.floor(index * run.size / sampleCount)];
|
|
75
|
-
const hits = searchEmbeddings(database, query.embedding, {
|
|
75
|
+
const hits = searchEmbeddings(database, query.embedding, { probeCellCount: 64, resultCount: 1 });
|
|
76
76
|
if (hits && hits.length && hits[0].ref === query.ref) {
|
|
77
77
|
found++;
|
|
78
78
|
}
|
|
@@ -31,7 +31,7 @@ export type SearchHit = {
|
|
|
31
31
|
};
|
|
32
32
|
export declare function rebuildStructure(database: Database<IvfEmbeddingRoot>): void;
|
|
33
33
|
export declare function searchEmbeddings(database: Database<IvfEmbeddingRoot>, query: StoredEmbedding, options: {
|
|
34
|
-
|
|
34
|
+
probeCellCount: number;
|
|
35
35
|
resultCount: number;
|
|
36
36
|
}): SearchHit[] | undefined;
|
|
37
37
|
export declare function lookupEmbeddings(database: Database<IvfEmbeddingRoot>, refs: string[]): Map<string, StoredEmbedding> | undefined;
|
|
@@ -218,7 +218,8 @@ export function rebuildStructure(database: Database<IvfEmbeddingRoot>): void {
|
|
|
218
218
|
export function searchEmbeddings(
|
|
219
219
|
database: Database<IvfEmbeddingRoot>,
|
|
220
220
|
query: StoredEmbedding,
|
|
221
|
-
|
|
221
|
+
// NOTE: We do a progressive search, so probe cell count can be very high.
|
|
222
|
+
options: { probeCellCount: number; resultCount: number },
|
|
222
223
|
): SearchHit[] | undefined {
|
|
223
224
|
const config = database.readData(root => root.config);
|
|
224
225
|
if (!config) return undefined;
|
|
@@ -239,13 +240,36 @@ export function searchEmbeddings(
|
|
|
239
240
|
const centroids = transactionRead(centroidStore(database));
|
|
240
241
|
if (!centroids) return undefined;
|
|
241
242
|
if (!centroids.size) return [];
|
|
242
|
-
const probeCellCount = Math.
|
|
243
|
-
|
|
244
|
-
|
|
243
|
+
const probeCellCount = Math.min(centroids.size, options.probeCellCount);
|
|
244
|
+
|
|
245
|
+
let rankedCellIds = rankCellsByCloseness(query, centroids);
|
|
246
|
+
let stores: TransactionSetStore<StoredEmbedding>[] = [];
|
|
247
|
+
// A somewhat strange search, trying to load more and more data. The reason we can't load everything at once is because the server has no way of knowing what we want first, and so it'll just wait until it can give us everything at once. By waiting until all of the earlier values load before even requesting the later values, it means that we will receive the earlier values sooner. Which will result in the search immediately returning results with very few accesses, And then the results improving in quality as time goes on, which is very desirable.
|
|
248
|
+
{
|
|
249
|
+
let stopAtNextKeyPoint = false;
|
|
250
|
+
let keyPoints: number[] = [];
|
|
251
|
+
let currentProbeAdd = 4;
|
|
252
|
+
let currentTarget = currentProbeAdd;
|
|
253
|
+
while (currentTarget < probeCellCount) {
|
|
254
|
+
keyPoints.push(currentTarget);
|
|
255
|
+
currentTarget += currentProbeAdd;
|
|
256
|
+
currentProbeAdd *= 2;
|
|
257
|
+
}
|
|
258
|
+
for (let i = 0; i < probeCellCount; i++) {
|
|
259
|
+
if (keyPoints.includes(i) && stopAtNextKeyPoint) break;
|
|
260
|
+
let store = database.readData(root => root.cells[rankedCellIds[i]]);
|
|
261
|
+
if (!store) {
|
|
262
|
+
stopAtNextKeyPoint = true;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
stores.push(store);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
245
269
|
for (const store of stores) {
|
|
246
270
|
const members = replayTransactionStore<StoredEmbedding>(store);
|
|
247
|
-
for (const ref of members
|
|
248
|
-
hits.push({ ref, closeness: getCloseness(query,
|
|
271
|
+
for (const [ref, value] of members) {
|
|
272
|
+
hits.push({ ref, closeness: getCloseness(query, value) });
|
|
249
273
|
}
|
|
250
274
|
}
|
|
251
275
|
hits.sort((left, right) => right.closeness - left.closeness);
|