One embedding at a time
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ztimson/ai-utils",
|
"name": "@ztimson/ai-utils",
|
||||||
"version": "0.7.2",
|
"version": "0.7.3",
|
||||||
"description": "AI Utility library",
|
"description": "AI Utility library",
|
||||||
"author": "Zak Timson",
|
"author": "Zak Timson",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
25
src/llm.ts
25
src/llm.ts
@@ -255,12 +255,11 @@ class LLM {
|
|||||||
/**
|
/**
|
||||||
* Create a vector representation of a string
|
* Create a vector representation of a string
|
||||||
* @param {object | string} target Item that will be embedded (objects get converted)
|
* @param {object | string} target Item that will be embedded (objects get converted)
|
||||||
* @param {maxTokens?: number, overlapTokens?: number, parellel?: number} opts Options for embedding such as chunk sizes and parallel processing
|
* @param {maxTokens?: number, overlapTokens?: number} opts Options for embedding such as chunk sizes
|
||||||
* @returns {Promise<Awaited<{index: number, embedding: number[], text: string, tokens: number}>[]>} Chunked embeddings
|
* @returns {Promise<Awaited<{index: number, embedding: number[], text: string, tokens: number}>[]>} Chunked embeddings
|
||||||
*/
|
*/
|
||||||
async embedding(target: object | string, opts: {maxTokens?: number, overlapTokens?: number, parallel?: number} = {}) {
|
async embedding(target: object | string, opts: {maxTokens?: number, overlapTokens?: number} = {}) {
|
||||||
let {maxTokens = 500, overlapTokens = 50, parallel = 1} = opts;
|
let {maxTokens = 500, overlapTokens = 50} = opts;
|
||||||
|
|
||||||
const embed = (text: string): Promise<number[]> => {
|
const embed = (text: string): Promise<number[]> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const worker = new Worker(join(dirname(fileURLToPath(import.meta.url)), 'embedder.js'));
|
const worker = new Worker(join(dirname(fileURLToPath(import.meta.url)), 'embedder.js'));
|
||||||
@@ -280,19 +279,13 @@ class LLM {
|
|||||||
worker.postMessage({text, model: this.ai.options?.embedder || 'bge-small-en-v1.5', modelDir: this.ai.options.path});
|
worker.postMessage({text, model: this.ai.options?.embedder || 'bge-small-en-v1.5', modelDir: this.ai.options.path});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let i = 0, chunks = this.chunk(target, maxTokens, overlapTokens), results: any[] = [];
|
const chunks = this.chunk(target, maxTokens, overlapTokens), results: any[] = [];
|
||||||
const next: Function = () => {
|
for(let i = 0; i < chunks.length; i++) {
|
||||||
const index = i++;
|
const text= chunks[i];
|
||||||
if(index >= chunks.length) return;
|
const embedding = await embed(text);
|
||||||
const text = chunks[index];
|
results.push({index: i, embedding, text, tokens: this.estimateTokens(text)});
|
||||||
return embed(text).then(embedding => {
|
|
||||||
results.push({index, embedding, text, tokens: this.estimateTokens(text)});
|
|
||||||
return next();
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
return results;
|
||||||
await Promise.all(Array(parallel).fill(null).map(() => next()));
|
|
||||||
return results.toSorted((a, b) => a.index - b.index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user