Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| da15d299e6 | |||
| 7ef7c3f676 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ztimson/ai-utils",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.2",
|
||||
"description": "AI Utility library",
|
||||
"author": "Zak Timson",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -40,9 +40,11 @@ export class Audio {
|
||||
if(!this.ai.language.defaultModel) throw new Error('Configure an LLM for advanced ASR speaker detection');
|
||||
p = p.then(async transcript => {
|
||||
if(!transcript) return transcript;
|
||||
const names = await this.ai.language.json(transcript, '{1: "Detected Name"}', {
|
||||
let chunks = this.ai.language.chunk(transcript, 500, 0);
|
||||
if(chunks.length > 4) chunks = [...chunks.slice(0, 3), <string>chunks.at(-1)];
|
||||
const names = await this.ai.language.json(chunks.join('\n'), '{1: "Detected Name"}', {
|
||||
system: 'Use this following transcript to identify speakers. Only identify speakers you are sure about',
|
||||
temperature: 0.2,
|
||||
temperature: 0.1,
|
||||
});
|
||||
Object.entries(names).forEach(([speaker, name]) => {
|
||||
transcript = (<string>transcript).replaceAll(`[Speaker ${speaker}]`, `[${name}]`);
|
||||
|
||||
27
src/llm.ts
27
src/llm.ts
@@ -255,11 +255,12 @@ class LLM {
|
||||
/**
|
||||
* Create a vector representation of a string
|
||||
* @param {object | string} target Item that will be embedded (objects get converted)
|
||||
* @param {number} maxTokens Chunking size. More = better context, less = more specific (Search by paragraphs or lines)
|
||||
* @param {number} overlapTokens Includes previous X tokens to provide continuity to AI (In addition to max tokens)
|
||||
* @param {maxTokens?: number, overlapTokens?: number, parellel?: number} opts Options for embedding such as chunk sizes and parallel processing
|
||||
* @returns {Promise<Awaited<{index: number, embedding: number[], text: string, tokens: number}>[]>} Chunked embeddings
|
||||
*/
|
||||
embedding(target: object | string, maxTokens = 500, overlapTokens = 50) {
|
||||
async embedding(target: object | string, opts: {maxTokens?: number, overlapTokens?: number, parallel?: number} = {}) {
|
||||
let {maxTokens = 500, overlapTokens = 50, parallel = 1} = opts;
|
||||
|
||||
const embed = (text: string): Promise<number[]> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const worker = new Worker(join(dirname(fileURLToPath(import.meta.url)), 'embedder.js'));
|
||||
@@ -279,13 +280,19 @@ class LLM {
|
||||
worker.postMessage({text, model: this.ai.options?.embedder || 'bge-small-en-v1.5', modelDir: this.ai.options.path});
|
||||
});
|
||||
};
|
||||
const chunks = this.chunk(target, maxTokens, overlapTokens);
|
||||
return Promise.all(chunks.map(async (text, index) => ({
|
||||
index,
|
||||
embedding: await embed(text),
|
||||
text,
|
||||
tokens: this.estimateTokens(text),
|
||||
})));
|
||||
let i = 0, chunks = this.chunk(target, maxTokens, overlapTokens), results: any[] = [];
|
||||
const next: Function = () => {
|
||||
const index = i++;
|
||||
if(index >= chunks.length) return;
|
||||
const text = chunks[index];
|
||||
return embed(text).then(embedding => {
|
||||
results.push({index, embedding, text, tokens: this.estimateTokens(text)});
|
||||
return next();
|
||||
})
|
||||
}
|
||||
|
||||
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