redis-vl 0.1.0-beta.0
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/LICENSE +22 -0
- package/README.md +212 -0
- package/dist/errors.d.ts +50 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +87 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/indexes/search-index.d.ts +368 -0
- package/dist/indexes/search-index.d.ts.map +1 -0
- package/dist/indexes/search-index.js +475 -0
- package/dist/indexes/search-index.js.map +1 -0
- package/dist/query/base.d.ts +51 -0
- package/dist/query/base.d.ts.map +1 -0
- package/dist/query/base.js +6 -0
- package/dist/query/base.js.map +1 -0
- package/dist/query/index.d.ts +7 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +7 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/vector.d.ts +199 -0
- package/dist/query/vector.d.ts.map +1 -0
- package/dist/query/vector.js +198 -0
- package/dist/query/vector.js.map +1 -0
- package/dist/redis/index-info-parser.d.ts +25 -0
- package/dist/redis/index-info-parser.d.ts.map +1 -0
- package/dist/redis/index-info-parser.js +301 -0
- package/dist/redis/index-info-parser.js.map +1 -0
- package/dist/redis/schema-types.d.ts +81 -0
- package/dist/redis/schema-types.d.ts.map +1 -0
- package/dist/redis/schema-types.js +18 -0
- package/dist/redis/schema-types.js.map +1 -0
- package/dist/redis/utils.d.ts +7 -0
- package/dist/redis/utils.d.ts.map +1 -0
- package/dist/redis/utils.js +221 -0
- package/dist/redis/utils.js.map +1 -0
- package/dist/schema/fields.d.ts +163 -0
- package/dist/schema/fields.d.ts.map +1 -0
- package/dist/schema/fields.js +304 -0
- package/dist/schema/fields.js.map +1 -0
- package/dist/schema/index.d.ts +8 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +8 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/schema.d.ts +247 -0
- package/dist/schema/schema.d.ts.map +1 -0
- package/dist/schema/schema.js +403 -0
- package/dist/schema/schema.js.map +1 -0
- package/dist/schema/types.d.ts +56 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +62 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/storage/base-storage.d.ts +107 -0
- package/dist/storage/base-storage.d.ts.map +1 -0
- package/dist/storage/base-storage.js +187 -0
- package/dist/storage/base-storage.js.map +1 -0
- package/dist/storage/hash-storage.d.ts +29 -0
- package/dist/storage/hash-storage.d.ts.map +1 -0
- package/dist/storage/hash-storage.js +122 -0
- package/dist/storage/hash-storage.js.map +1 -0
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +4 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/json-storage.d.ts +19 -0
- package/dist/storage/json-storage.d.ts.map +1 -0
- package/dist/storage/json-storage.js +81 -0
- package/dist/storage/json-storage.js.map +1 -0
- package/dist/utils/distance.d.ts +92 -0
- package/dist/utils/distance.d.ts.map +1 -0
- package/dist/utils/distance.js +98 -0
- package/dist/utils/distance.js.map +1 -0
- package/dist/vectorizers/base-vectorizer.d.ts +88 -0
- package/dist/vectorizers/base-vectorizer.d.ts.map +1 -0
- package/dist/vectorizers/base-vectorizer.js +32 -0
- package/dist/vectorizers/base-vectorizer.js.map +1 -0
- package/dist/vectorizers/huggingface-vectorizer.d.ts +103 -0
- package/dist/vectorizers/huggingface-vectorizer.d.ts.map +1 -0
- package/dist/vectorizers/huggingface-vectorizer.js +142 -0
- package/dist/vectorizers/huggingface-vectorizer.js.map +1 -0
- package/dist/vectorizers/index.d.ts +10 -0
- package/dist/vectorizers/index.d.ts.map +1 -0
- package/dist/vectorizers/index.js +10 -0
- package/dist/vectorizers/index.js.map +1 -0
- package/package.json +96 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { BaseStorage } from './base-storage.js';
|
|
2
|
+
import { SchemaValidationError } from '../errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* Storage implementation for Redis JSON data type.
|
|
5
|
+
* Implements JSON-specific logic for validation and read/write operations.
|
|
6
|
+
*/
|
|
7
|
+
export class JsonStorage extends BaseStorage {
|
|
8
|
+
constructor(schema) {
|
|
9
|
+
super(schema);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Write documents to Redis as JSON entries using pipelining for performance.
|
|
13
|
+
*/
|
|
14
|
+
async write(client, data, options = {}) {
|
|
15
|
+
const { keys, ttl, batchSize = this.defaultBatchSize } = options;
|
|
16
|
+
// Validate inputs
|
|
17
|
+
if (data.length === 0) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
if (keys && keys.length !== data.length) {
|
|
21
|
+
throw new SchemaValidationError('Length of keys does not match the length of data');
|
|
22
|
+
}
|
|
23
|
+
// Pass 1: Preprocess and validate all documents
|
|
24
|
+
const preparedDocs = await this.preprocessAndValidateDocuments(data, options);
|
|
25
|
+
// Pass 2: Write all valid documents in batches using pipeline
|
|
26
|
+
const loadedKeys = [];
|
|
27
|
+
let pipeline = client.multi();
|
|
28
|
+
let commandCount = 0;
|
|
29
|
+
for (let i = 0; i < preparedDocs.length; i++) {
|
|
30
|
+
const { key, doc } = preparedDocs[i];
|
|
31
|
+
// Add JSON.SET command to pipeline
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
pipeline.json.set(key, '$', doc);
|
|
34
|
+
commandCount++;
|
|
35
|
+
// Add EXPIRE command if TTL is provided
|
|
36
|
+
if (ttl) {
|
|
37
|
+
pipeline.expire(key, ttl);
|
|
38
|
+
commandCount++;
|
|
39
|
+
}
|
|
40
|
+
loadedKeys.push(key);
|
|
41
|
+
// Execute pipeline in batches
|
|
42
|
+
if (commandCount >= batchSize || i === preparedDocs.length - 1) {
|
|
43
|
+
await pipeline.execAsPipeline();
|
|
44
|
+
pipeline = client.multi();
|
|
45
|
+
commandCount = 0;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return loadedKeys;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Read documents from Redis by keys using pipelining.
|
|
52
|
+
*/
|
|
53
|
+
async get(client, keys, batchSize = this.defaultBatchSize) {
|
|
54
|
+
if (!keys || keys.length === 0) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
const results = [];
|
|
58
|
+
// Process in batches
|
|
59
|
+
for (let i = 0; i < keys.length; i += batchSize) {
|
|
60
|
+
const batch = keys.slice(i, i + batchSize);
|
|
61
|
+
const pipeline = client.multi();
|
|
62
|
+
// Add JSON.GET commands to pipeline
|
|
63
|
+
for (const key of batch) {
|
|
64
|
+
pipeline.json.get(key);
|
|
65
|
+
}
|
|
66
|
+
// Execute pipeline and get results
|
|
67
|
+
const batchResults = (await pipeline.execAsPipeline());
|
|
68
|
+
// Process batch results
|
|
69
|
+
for (const data of batchResults) {
|
|
70
|
+
if (data && typeof data === 'object') {
|
|
71
|
+
results.push(data);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
results.push(null);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return results;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=json-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-storage.js","sourceRoot":"","sources":["../../src/storage/json-storage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,WAAW;IACxC,YAAY,MAAmB;QAC3B,KAAK,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CACP,MAAmB,EACnB,IAA+B,EAC/B,UAAwB,EAAE;QAE1B,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,OAAO,CAAC;QAEjE,kBAAkB;QAClB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YACtC,MAAM,IAAI,qBAAqB,CAAC,kDAAkD,CAAC,CAAC;QACxF,CAAC;QAED,gDAAgD;QAChD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,8BAA8B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAE9E,8DAA8D;QAC9D,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,IAAI,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAErC,mCAAmC;YACnC,8DAA8D;YAC9D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAU,CAAC,CAAC;YACxC,YAAY,EAAE,CAAC;YAEf,wCAAwC;YACxC,IAAI,GAAG,EAAE,CAAC;gBACN,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC1B,YAAY,EAAE,CAAC;YACnB,CAAC;YAED,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAErB,8BAA8B;YAC9B,IAAI,YAAY,IAAI,SAAS,IAAI,CAAC,KAAK,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7D,MAAM,QAAQ,CAAC,cAAc,EAAE,CAAC;gBAChC,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC1B,YAAY,GAAG,CAAC,CAAC;YACrB,CAAC;QACL,CAAC;QAED,OAAO,UAAU,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CACL,MAAmB,EACnB,IAAc,EACd,SAAS,GAAG,IAAI,CAAC,gBAAgB;QAEjC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAuC,EAAE,CAAC;QAEvD,qBAAqB;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;YAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;YAEhC,oCAAoC;YACpC,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;YAED,mCAAmC;YACnC,MAAM,YAAY,GAAG,CAAC,MAAM,QAAQ,CAAC,cAAc,EAAE,CAG5C,CAAC;YAEV,wBAAwB;YACxB,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;gBAC9B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACnC,OAAO,CAAC,IAAI,CAAC,IAA+B,CAAC,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvB,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;CACJ"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for normalizing vector distance metrics.
|
|
3
|
+
*
|
|
4
|
+
* Redis supports three distance metrics:
|
|
5
|
+
* - COSINE: Returns values between 0 and 2
|
|
6
|
+
* - L2 (Euclidean): Returns unbounded values (0 to infinity)
|
|
7
|
+
* - IP (Inner Product): Returns values determined by vector magnitude
|
|
8
|
+
*
|
|
9
|
+
* These functions normalize distances to similarity scores between 0 and 1:
|
|
10
|
+
* - 1.0 = perfect match (most similar)
|
|
11
|
+
* - 0.0 = completely different (least similar)
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Normalize a COSINE distance to a similarity score between 0 and 1.
|
|
15
|
+
*
|
|
16
|
+
* COSINE distance in Redis ranges from 0 (identical vectors) to 2 (opposite vectors).
|
|
17
|
+
* This function converts it to a similarity score where:
|
|
18
|
+
* - distance 0 → similarity 1.0 (identical)
|
|
19
|
+
* - distance 1 → similarity 0.5 (orthogonal)
|
|
20
|
+
* - distance 2 → similarity 0.0 (opposite)
|
|
21
|
+
*
|
|
22
|
+
* Formula: similarity = (2 - distance) / 2
|
|
23
|
+
*
|
|
24
|
+
* @param distance - COSINE distance value from Redis (0 to 2)
|
|
25
|
+
* @returns Normalized similarity score (0 to 1)
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* normalizeCosineDistance(0) // 1.0 (identical)
|
|
30
|
+
* normalizeCosineDistance(1) // 0.5 (orthogonal)
|
|
31
|
+
* normalizeCosineDistance(2) // 0.0 (opposite)
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function normalizeCosineDistance(distance: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Denormalize a similarity score to a COSINE distance.
|
|
37
|
+
*
|
|
38
|
+
* This is the inverse of normalizeCosineDistance.
|
|
39
|
+
* Converts a similarity score (0 to 1) back to COSINE distance (0 to 2).
|
|
40
|
+
*
|
|
41
|
+
* Formula: distance = 2 - 2 * similarity
|
|
42
|
+
*
|
|
43
|
+
* @param similarity - Normalized similarity score (0 to 1)
|
|
44
|
+
* @returns COSINE distance value (0 to 2)
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* denormalizeCosineDistance(1.0) // 0 (identical)
|
|
49
|
+
* denormalizeCosineDistance(0.5) // 1 (orthogonal)
|
|
50
|
+
* denormalizeCosineDistance(0.0) // 2 (opposite)
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function denormalizeCosineDistance(similarity: number): number;
|
|
54
|
+
/**
|
|
55
|
+
* Normalize an L2 (Euclidean) distance to a similarity score between 0 and 1.
|
|
56
|
+
*
|
|
57
|
+
* L2 distance in Redis is unbounded (0 to infinity).
|
|
58
|
+
* This function converts it to a similarity score using the formula:
|
|
59
|
+
* similarity = 1 / (1 + distance)
|
|
60
|
+
*
|
|
61
|
+
* - distance 0 → similarity 1.0 (identical)
|
|
62
|
+
* - distance 1 → similarity 0.5
|
|
63
|
+
* - distance ∞ → similarity 0.0 (very different)
|
|
64
|
+
*
|
|
65
|
+
* @param distance - L2 distance value from Redis (0 to infinity)
|
|
66
|
+
* @returns Normalized similarity score (0 to 1)
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* normalizeL2Distance(0) // 1.0 (identical)
|
|
71
|
+
* normalizeL2Distance(1) // 0.5
|
|
72
|
+
* normalizeL2Distance(9) // 0.1
|
|
73
|
+
* normalizeL2Distance(99) // 0.01
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare function normalizeL2Distance(distance: number): number;
|
|
77
|
+
/**
|
|
78
|
+
* Type definition for distance normalization functions.
|
|
79
|
+
*/
|
|
80
|
+
export type DistanceNormalizer = (distance: number) => number;
|
|
81
|
+
/**
|
|
82
|
+
* Map of distance metrics to their normalization functions.
|
|
83
|
+
*
|
|
84
|
+
* - COSINE: Normalizes from [0, 2] to [0, 1]
|
|
85
|
+
* - L2: Normalizes from [0, ∞] to [0, 1]
|
|
86
|
+
* - IP: null (Inner Product is not normalized; use COSINE instead)
|
|
87
|
+
*
|
|
88
|
+
* Note: COSINE is normalized Inner Product by definition, so IP
|
|
89
|
+
* should not be normalized separately.
|
|
90
|
+
*/
|
|
91
|
+
export declare const DISTANCE_NORMALIZERS: Record<string, DistanceNormalizer | null>;
|
|
92
|
+
//# sourceMappingURL=distance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distance.d.ts","sourceRoot":"","sources":["../../src/utils/distance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;AAE9D;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAI1E,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for normalizing vector distance metrics.
|
|
3
|
+
*
|
|
4
|
+
* Redis supports three distance metrics:
|
|
5
|
+
* - COSINE: Returns values between 0 and 2
|
|
6
|
+
* - L2 (Euclidean): Returns unbounded values (0 to infinity)
|
|
7
|
+
* - IP (Inner Product): Returns values determined by vector magnitude
|
|
8
|
+
*
|
|
9
|
+
* These functions normalize distances to similarity scores between 0 and 1:
|
|
10
|
+
* - 1.0 = perfect match (most similar)
|
|
11
|
+
* - 0.0 = completely different (least similar)
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Normalize a COSINE distance to a similarity score between 0 and 1.
|
|
15
|
+
*
|
|
16
|
+
* COSINE distance in Redis ranges from 0 (identical vectors) to 2 (opposite vectors).
|
|
17
|
+
* This function converts it to a similarity score where:
|
|
18
|
+
* - distance 0 → similarity 1.0 (identical)
|
|
19
|
+
* - distance 1 → similarity 0.5 (orthogonal)
|
|
20
|
+
* - distance 2 → similarity 0.0 (opposite)
|
|
21
|
+
*
|
|
22
|
+
* Formula: similarity = (2 - distance) / 2
|
|
23
|
+
*
|
|
24
|
+
* @param distance - COSINE distance value from Redis (0 to 2)
|
|
25
|
+
* @returns Normalized similarity score (0 to 1)
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* normalizeCosineDistance(0) // 1.0 (identical)
|
|
30
|
+
* normalizeCosineDistance(1) // 0.5 (orthogonal)
|
|
31
|
+
* normalizeCosineDistance(2) // 0.0 (opposite)
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function normalizeCosineDistance(distance) {
|
|
35
|
+
return Math.max((2 - distance) / 2, 0);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Denormalize a similarity score to a COSINE distance.
|
|
39
|
+
*
|
|
40
|
+
* This is the inverse of normalizeCosineDistance.
|
|
41
|
+
* Converts a similarity score (0 to 1) back to COSINE distance (0 to 2).
|
|
42
|
+
*
|
|
43
|
+
* Formula: distance = 2 - 2 * similarity
|
|
44
|
+
*
|
|
45
|
+
* @param similarity - Normalized similarity score (0 to 1)
|
|
46
|
+
* @returns COSINE distance value (0 to 2)
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* denormalizeCosineDistance(1.0) // 0 (identical)
|
|
51
|
+
* denormalizeCosineDistance(0.5) // 1 (orthogonal)
|
|
52
|
+
* denormalizeCosineDistance(0.0) // 2 (opposite)
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export function denormalizeCosineDistance(similarity) {
|
|
56
|
+
return Math.max(2 - 2 * similarity, 0);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Normalize an L2 (Euclidean) distance to a similarity score between 0 and 1.
|
|
60
|
+
*
|
|
61
|
+
* L2 distance in Redis is unbounded (0 to infinity).
|
|
62
|
+
* This function converts it to a similarity score using the formula:
|
|
63
|
+
* similarity = 1 / (1 + distance)
|
|
64
|
+
*
|
|
65
|
+
* - distance 0 → similarity 1.0 (identical)
|
|
66
|
+
* - distance 1 → similarity 0.5
|
|
67
|
+
* - distance ∞ → similarity 0.0 (very different)
|
|
68
|
+
*
|
|
69
|
+
* @param distance - L2 distance value from Redis (0 to infinity)
|
|
70
|
+
* @returns Normalized similarity score (0 to 1)
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* normalizeL2Distance(0) // 1.0 (identical)
|
|
75
|
+
* normalizeL2Distance(1) // 0.5
|
|
76
|
+
* normalizeL2Distance(9) // 0.1
|
|
77
|
+
* normalizeL2Distance(99) // 0.01
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export function normalizeL2Distance(distance) {
|
|
81
|
+
return 1 / (1 + distance);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Map of distance metrics to their normalization functions.
|
|
85
|
+
*
|
|
86
|
+
* - COSINE: Normalizes from [0, 2] to [0, 1]
|
|
87
|
+
* - L2: Normalizes from [0, ∞] to [0, 1]
|
|
88
|
+
* - IP: null (Inner Product is not normalized; use COSINE instead)
|
|
89
|
+
*
|
|
90
|
+
* Note: COSINE is normalized Inner Product by definition, so IP
|
|
91
|
+
* should not be normalized separately.
|
|
92
|
+
*/
|
|
93
|
+
export const DISTANCE_NORMALIZERS = {
|
|
94
|
+
COSINE: normalizeCosineDistance,
|
|
95
|
+
L2: normalizeL2Distance,
|
|
96
|
+
IP: null, // Normalized inner product is COSINE by definition
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=distance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distance.js","sourceRoot":"","sources":["../../src/utils/distance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACpD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,yBAAyB,CAAC,UAAkB;IACxD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAChD,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAOD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA8C;IAC3E,MAAM,EAAE,uBAAuB;IAC/B,EAAE,EAAE,mBAAmB;IACvB,EAAE,EAAE,IAAI,EAAE,mDAAmD;CAChE,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base abstract class for all vectorizers.
|
|
3
|
+
*
|
|
4
|
+
* Vectorizers are responsible for converting text into numerical embeddings (vectors)
|
|
5
|
+
* that can be stored in Redis and used for semantic search.
|
|
6
|
+
*
|
|
7
|
+
* This class defines the interface that all concrete vectorizer implementations must follow.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* class MyVectorizer extends BaseVectorizer {
|
|
12
|
+
* async embed(text: string): Promise<number[]> {
|
|
13
|
+
* // Implementation
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* async embedMany(texts: string[], batchSize?: number): Promise<number[][]> {
|
|
17
|
+
* // Implementation
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* get dims(): number {
|
|
21
|
+
* return 384; // Embedding dimensions
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* get model(): string {
|
|
25
|
+
* return 'my-model-name';
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare abstract class BaseVectorizer {
|
|
31
|
+
/**
|
|
32
|
+
* Generate an embedding for a single text.
|
|
33
|
+
*
|
|
34
|
+
* @param text - The text to embed
|
|
35
|
+
* @returns A promise that resolves to the embedding vector
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const embedding = await vectorizer.embed('Hello world');
|
|
40
|
+
* console.log(embedding); // [0.1, 0.2, 0.3, ...]
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
abstract embed(text: string): Promise<number[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Generate embeddings for multiple texts.
|
|
46
|
+
*
|
|
47
|
+
* This method should be more efficient than calling embed() multiple times
|
|
48
|
+
* by batching requests to the underlying model.
|
|
49
|
+
*
|
|
50
|
+
* @param texts - Array of texts to embed
|
|
51
|
+
* @param batchSize - Optional batch size for processing (default: 32)
|
|
52
|
+
* @returns A promise that resolves to an array of embedding vectors
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const embeddings = await vectorizer.embedMany(['Hello', 'World']);
|
|
57
|
+
* console.log(embeddings); // [[0.1, 0.2, ...], [0.3, 0.4, ...]]
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
abstract embedMany(texts: string[], batchSize?: number): Promise<number[][]>;
|
|
61
|
+
/**
|
|
62
|
+
* Get the dimensionality of the embeddings produced by this vectorizer.
|
|
63
|
+
*
|
|
64
|
+
* This should match the length of the arrays returned by embed() and embedMany().
|
|
65
|
+
*
|
|
66
|
+
* @returns The number of dimensions in the embedding vectors
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* console.log(vectorizer.dims); // 384
|
|
71
|
+
* const embedding = await vectorizer.embed('test');
|
|
72
|
+
* console.log(embedding.length === vectorizer.dims); // true
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
abstract get dims(): number;
|
|
76
|
+
/**
|
|
77
|
+
* Get the name/identifier of the model used by this vectorizer.
|
|
78
|
+
*
|
|
79
|
+
* @returns The model name or identifier
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* console.log(vectorizer.model); // "sentence-transformers/all-MiniLM-L6-v2"
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
abstract get model(): string;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=base-vectorizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-vectorizer.d.ts","sourceRoot":"","sources":["../../src/vectorizers/base-vectorizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,8BAAsB,cAAc;IAChC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAE/C;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAE5E;;;;;;;;;;;;;OAaG;IACH,QAAQ,KAAK,IAAI,IAAI,MAAM,CAAC;IAE5B;;;;;;;;;OASG;IACH,QAAQ,KAAK,KAAK,IAAI,MAAM,CAAC;CAChC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base abstract class for all vectorizers.
|
|
3
|
+
*
|
|
4
|
+
* Vectorizers are responsible for converting text into numerical embeddings (vectors)
|
|
5
|
+
* that can be stored in Redis and used for semantic search.
|
|
6
|
+
*
|
|
7
|
+
* This class defines the interface that all concrete vectorizer implementations must follow.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* class MyVectorizer extends BaseVectorizer {
|
|
12
|
+
* async embed(text: string): Promise<number[]> {
|
|
13
|
+
* // Implementation
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* async embedMany(texts: string[], batchSize?: number): Promise<number[][]> {
|
|
17
|
+
* // Implementation
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* get dims(): number {
|
|
21
|
+
* return 384; // Embedding dimensions
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* get model(): string {
|
|
25
|
+
* return 'my-model-name';
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export class BaseVectorizer {
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=base-vectorizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-vectorizer.js","sourceRoot":"","sources":["../../src/vectorizers/base-vectorizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,OAAgB,cAAc;CA4DnC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { BaseVectorizer } from './base-vectorizer.js';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for HuggingFaceVectorizer
|
|
4
|
+
*/
|
|
5
|
+
export interface HuggingFaceConfig {
|
|
6
|
+
/**
|
|
7
|
+
* The Hugging Face model to use for embeddings.
|
|
8
|
+
*
|
|
9
|
+
* Examples:
|
|
10
|
+
* - 'Xenova/all-MiniLM-L6-v2' (384 dimensions, fast)
|
|
11
|
+
* - 'Xenova/all-mpnet-base-v2' (768 dimensions, better quality)
|
|
12
|
+
* - 'sentence-transformers/all-MiniLM-L6-v2'
|
|
13
|
+
*/
|
|
14
|
+
model: string;
|
|
15
|
+
/**
|
|
16
|
+
* Device to run inference on.
|
|
17
|
+
* - 'cpu': Run on CPU (default)
|
|
18
|
+
* - 'webgpu': Run on GPU (if available)
|
|
19
|
+
*/
|
|
20
|
+
device?: 'cpu' | 'webgpu';
|
|
21
|
+
/**
|
|
22
|
+
* Data type for model weights.
|
|
23
|
+
* - 'fp32': 32-bit floating point (default, best quality)
|
|
24
|
+
* - 'fp16': 16-bit floating point (faster, less memory)
|
|
25
|
+
* - 'q8': 8-bit quantized (fastest, smallest)
|
|
26
|
+
*/
|
|
27
|
+
dtype?: 'fp32' | 'fp16' | 'q8';
|
|
28
|
+
/**
|
|
29
|
+
* Pooling strategy for combining token embeddings.
|
|
30
|
+
* - 'mean': Average all token embeddings (default)
|
|
31
|
+
* - 'cls': Use [CLS] token embedding
|
|
32
|
+
*/
|
|
33
|
+
pooling?: 'mean' | 'cls';
|
|
34
|
+
/**
|
|
35
|
+
* Whether to normalize embeddings to unit length (L2 norm = 1).
|
|
36
|
+
* Default: true
|
|
37
|
+
*/
|
|
38
|
+
normalize?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* HuggingFace vectorizer using Transformers.js for local inference.
|
|
42
|
+
*
|
|
43
|
+
* This vectorizer uses the @huggingface/transformers library to generate
|
|
44
|
+
* embeddings locally without requiring API keys or external services.
|
|
45
|
+
*
|
|
46
|
+
* Models are automatically downloaded and cached on first use.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* import { HuggingFaceVectorizer } from 'redis-vl';
|
|
51
|
+
*
|
|
52
|
+
* const vectorizer = new HuggingFaceVectorizer({
|
|
53
|
+
* model: 'Xenova/all-MiniLM-L6-v2'
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* // Generate single embedding
|
|
57
|
+
* const embedding = await vectorizer.embed('Hello world');
|
|
58
|
+
* console.log(embedding.length); // 384
|
|
59
|
+
*
|
|
60
|
+
* // Generate multiple embeddings
|
|
61
|
+
* const embeddings = await vectorizer.embedMany(['Hello', 'World']);
|
|
62
|
+
* console.log(embeddings.length); // 2
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* // Use with preprocessing
|
|
68
|
+
* await index.load(documents, {
|
|
69
|
+
* preprocess: async (doc) => ({
|
|
70
|
+
* ...doc,
|
|
71
|
+
* embedding: await vectorizer.embed(doc.text)
|
|
72
|
+
* })
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare class HuggingFaceVectorizer extends BaseVectorizer {
|
|
77
|
+
private readonly config;
|
|
78
|
+
private pipelineInstance;
|
|
79
|
+
private modelDims;
|
|
80
|
+
constructor(config: HuggingFaceConfig);
|
|
81
|
+
/**
|
|
82
|
+
* Lazy load the Transformers.js pipeline.
|
|
83
|
+
* This ensures the library is only loaded when actually needed.
|
|
84
|
+
*/
|
|
85
|
+
private loadPipeline;
|
|
86
|
+
/**
|
|
87
|
+
* Generate an embedding for a single text.
|
|
88
|
+
*/
|
|
89
|
+
embed(text: string): Promise<number[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Generate embeddings for multiple texts.
|
|
92
|
+
*/
|
|
93
|
+
embedMany(texts: string[], batchSize?: number): Promise<number[][]>;
|
|
94
|
+
/**
|
|
95
|
+
* Get the dimensionality of the embeddings.
|
|
96
|
+
*/
|
|
97
|
+
get dims(): number;
|
|
98
|
+
/**
|
|
99
|
+
* Get the model name.
|
|
100
|
+
*/
|
|
101
|
+
get model(): string;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=huggingface-vectorizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"huggingface-vectorizer.d.ts","sourceRoot":"","sources":["../../src/vectorizers/huggingface-vectorizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;;;;;;OAOG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAE1B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAE/B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAEzB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,qBAAsB,SAAQ,cAAc;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,SAAS,CAAuB;gBAE5B,MAAM,EAAE,iBAAiB;IAiBrC;;;OAGG;YACW,YAAY;IA0B1B;;OAEG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmB5C;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAsC7E;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAQjB;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;CACJ"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { BaseVectorizer } from './base-vectorizer.js';
|
|
2
|
+
import { VectorizerError } from '../errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* HuggingFace vectorizer using Transformers.js for local inference.
|
|
5
|
+
*
|
|
6
|
+
* This vectorizer uses the @huggingface/transformers library to generate
|
|
7
|
+
* embeddings locally without requiring API keys or external services.
|
|
8
|
+
*
|
|
9
|
+
* Models are automatically downloaded and cached on first use.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { HuggingFaceVectorizer } from 'redis-vl';
|
|
14
|
+
*
|
|
15
|
+
* const vectorizer = new HuggingFaceVectorizer({
|
|
16
|
+
* model: 'Xenova/all-MiniLM-L6-v2'
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Generate single embedding
|
|
20
|
+
* const embedding = await vectorizer.embed('Hello world');
|
|
21
|
+
* console.log(embedding.length); // 384
|
|
22
|
+
*
|
|
23
|
+
* // Generate multiple embeddings
|
|
24
|
+
* const embeddings = await vectorizer.embedMany(['Hello', 'World']);
|
|
25
|
+
* console.log(embeddings.length); // 2
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // Use with preprocessing
|
|
31
|
+
* await index.load(documents, {
|
|
32
|
+
* preprocess: async (doc) => ({
|
|
33
|
+
* ...doc,
|
|
34
|
+
* embedding: await vectorizer.embed(doc.text)
|
|
35
|
+
* })
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export class HuggingFaceVectorizer extends BaseVectorizer {
|
|
40
|
+
config;
|
|
41
|
+
pipelineInstance = null;
|
|
42
|
+
modelDims = null;
|
|
43
|
+
constructor(config) {
|
|
44
|
+
super();
|
|
45
|
+
if (!config.model || config.model.trim() === '') {
|
|
46
|
+
throw new VectorizerError('Model name cannot be empty');
|
|
47
|
+
}
|
|
48
|
+
// Set defaults
|
|
49
|
+
this.config = {
|
|
50
|
+
model: config.model,
|
|
51
|
+
device: config.device ?? 'cpu',
|
|
52
|
+
dtype: config.dtype ?? 'fp32',
|
|
53
|
+
pooling: config.pooling ?? 'mean',
|
|
54
|
+
normalize: config.normalize ?? true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Lazy load the Transformers.js pipeline.
|
|
59
|
+
* This ensures the library is only loaded when actually needed.
|
|
60
|
+
*/
|
|
61
|
+
async loadPipeline() {
|
|
62
|
+
if (this.pipelineInstance) {
|
|
63
|
+
return this.pipelineInstance;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const { pipeline } = await import('@huggingface/transformers');
|
|
67
|
+
this.pipelineInstance = await pipeline('feature-extraction', this.config.model, {
|
|
68
|
+
device: this.config.device,
|
|
69
|
+
dtype: this.config.dtype,
|
|
70
|
+
});
|
|
71
|
+
return this.pipelineInstance;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (error instanceof Error && error.message.includes('Cannot find module')) {
|
|
75
|
+
throw new VectorizerError('HuggingFaceVectorizer requires @huggingface/transformers. ' +
|
|
76
|
+
'Install it with: npm install @huggingface/transformers', { cause: error });
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Generate an embedding for a single text.
|
|
83
|
+
*/
|
|
84
|
+
async embed(text) {
|
|
85
|
+
const pipeline = await this.loadPipeline();
|
|
86
|
+
const output = await pipeline(text, {
|
|
87
|
+
pooling: this.config.pooling,
|
|
88
|
+
normalize: this.config.normalize,
|
|
89
|
+
});
|
|
90
|
+
// Extract the embedding from the output
|
|
91
|
+
const embedding = Array.from(output.data);
|
|
92
|
+
// Cache dimensions on first call
|
|
93
|
+
if (this.modelDims === null) {
|
|
94
|
+
this.modelDims = embedding.length;
|
|
95
|
+
}
|
|
96
|
+
return embedding;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Generate embeddings for multiple texts.
|
|
100
|
+
*/
|
|
101
|
+
async embedMany(texts, batchSize = 32) {
|
|
102
|
+
if (texts.length === 0) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
const pipeline = await this.loadPipeline();
|
|
106
|
+
const results = [];
|
|
107
|
+
// Process in batches for memory efficiency
|
|
108
|
+
for (let i = 0; i < texts.length; i += batchSize) {
|
|
109
|
+
const batch = texts.slice(i, i + batchSize);
|
|
110
|
+
// Process batch
|
|
111
|
+
const batchOutputs = await Promise.all(batch.map((text) => pipeline(text, {
|
|
112
|
+
pooling: this.config.pooling,
|
|
113
|
+
normalize: this.config.normalize,
|
|
114
|
+
})));
|
|
115
|
+
// Extract embeddings from outputs
|
|
116
|
+
const batchEmbeddings = batchOutputs.map((output) => Array.from(output.data));
|
|
117
|
+
results.push(...batchEmbeddings);
|
|
118
|
+
}
|
|
119
|
+
// Cache dimensions on first call
|
|
120
|
+
if (this.modelDims === null && results.length > 0) {
|
|
121
|
+
this.modelDims = results[0].length;
|
|
122
|
+
}
|
|
123
|
+
return results;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get the dimensionality of the embeddings.
|
|
127
|
+
*/
|
|
128
|
+
get dims() {
|
|
129
|
+
if (this.modelDims === null) {
|
|
130
|
+
throw new VectorizerError('Embedding dimensions not yet determined. ' +
|
|
131
|
+
'Call embed() or embedMany() first to initialize the model.');
|
|
132
|
+
}
|
|
133
|
+
return this.modelDims;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get the model name.
|
|
137
|
+
*/
|
|
138
|
+
get model() {
|
|
139
|
+
return this.config.model;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=huggingface-vectorizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"huggingface-vectorizer.js","sourceRoot":"","sources":["../../src/vectorizers/huggingface-vectorizer.ts"],"names":[],"mappings":"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"}
|