Add support for custom embedding URL in Playground (#391)

# PR Checklist
- [x] Did you check if it works normally in all models? *ignore this
when it dosen't uses models*
- [ ] Did you check if it works normally in all of web, local and node
hosted versions? if it dosen't, did you blocked it in those versions?
- [ ] Did you added a type def?

# Description

Add support Openai-compatible custom embedding server on the playground.

Openai-compatible embedding servers:
https://github.com/toshsan/embedding-server
https://github.com/limcheekin/open-text-embeddings
https://github.com/michaelfeil/infinity

I only tested it with infinity. 
there is also a feature that If url does not end in /embeddings,
automatically adds /embeddings.
I think I need to test it with more local embedding servers, but I think
it'll be okay since it's only Playground
This commit is contained in:
kwaroran
2024-04-29 01:51:07 +09:00
committed by GitHub
3 changed files with 69 additions and 11 deletions

View File

@@ -8,6 +8,7 @@
let query = "";
let model = "MiniLM";
let customEmbeddingUrl = "";
let data:string[] = [];
let dataresult:[string, number][] = [];
let running = false;
@@ -15,7 +16,7 @@
const run = async () => {
if(running) return;
running = true;
const processer = new HypaProcesser(model as any);
const processer = new HypaProcesser(model as any, customEmbeddingUrl);
await processer.addText(data);
console.log(processer.vectors)
dataresult = await processer.similaritySearchScored(query);
@@ -29,8 +30,14 @@
<SelectInput bind:value={model}>
<OptionInput value="MiniLM">MiniLM L6 v2</OptionInput>
<OptionInput value="nomic">Nomic Embed Text v1.5</OptionInput>
<OptionInput value="custom">Custom (OpenAI-compatible)</OptionInput>
</SelectInput>
{#if model === "custom"}
<span class="text-textcolor text-lg">Custom Server URL</span>
<TextInput bind:value={customEmbeddingUrl} size="lg" fullwidth />
{/if}
<span class="text-textcolor text-lg">Query</span>
<TextInput bind:value={query} size="lg" fullwidth />

View File

@@ -1,20 +1,24 @@
import localforage from "localforage";
import { globalFetch } from "src/ts/storage/globalApi";
import { runEmbedding } from "../transformers";
import { alertError } from "src/ts/alert";
import { appendLastPath } from "src/ts/util";
export class HypaProcesser{
oaikey:string
vectors:memoryVector[]
forage:LocalForage
model:'ada'|'MiniLM'|'nomic'
model:'ada'|'MiniLM'|'nomic'|'custom'
customEmbeddingUrl:string
constructor(model:'ada'|'MiniLM'|'nomic'){
constructor(model:'ada'|'MiniLM'|'nomic'|'custom',customEmbeddingUrl?:string){
this.forage = localforage.createInstance({
name: "hypaVector"
})
this.vectors = []
this.model = model
this.customEmbeddingUrl = customEmbeddingUrl
}
async embedDocuments(texts: string[]): Promise<VectorArray[]> {
@@ -40,15 +44,32 @@ export class HypaProcesser{
let results:Float32Array[] = await runEmbedding(inputs, this.model === 'nomic' ? 'nomic-ai/nomic-embed-text-v1.5' : 'Xenova/all-MiniLM-L6-v2')
return results
}
const gf = await globalFetch("https://api.openai.com/v1/embeddings", {
headers: {
"Authorization": "Bearer " + this.oaikey
},
body: {
"input": input,
"model": "text-embedding-ada-002"
let gf = null;
if(this.model === 'custom'){
if(!this.customEmbeddingUrl){
alertError('Custom model requires a Custom Server URL')
return [0]
}
})
const {customEmbeddingUrl} = this
const replaceUrl = customEmbeddingUrl.endsWith('/embeddings')?customEmbeddingUrl:appendLastPath(customEmbeddingUrl,'embeddings')
gf = await globalFetch(replaceUrl.toString(), {
body:{
"input": input
},
})
}
if(this.model === 'ada'){
gf = await globalFetch("https://api.openai.com/v1/embeddings", {
headers: {
"Authorization": "Bearer " + this.oaikey
},
body: {
"input": input,
"model": "text-embedding-ada-002"
}
})
}
const data = gf.data

View File

@@ -492,4 +492,34 @@ export function trimUntilPunctuation(s:string){
result = result.slice(0, -1)
}
return result
}
/**
* Appends the given last path to the provided URL.
*
* @param {string} url - The base URL to which the last path will be appended.
* @param {string} lastPath - The path to be appended to the URL.
* @returns {string} The modified URL with the last path appended.
*
* @example
* appendLastPath("https://github.com/kwaroran/RisuAI","/commits/main")
* return 'https://github.com/kwaroran/RisuAI/commits/main'
*
* @example
* appendLastPath("https://github.com/kwaroran/RisuAI/","/commits/main")
* return 'https://github.com/kwaroran/RisuAI/commits/main
*
* @example
* appendLastPath("http://127.0.0.1:7997","embeddings")
* return 'http://127.0.0.1:7997/embeddings'
*/
export function appendLastPath(url, lastPath) {
// Remove trailing slash from url if exists
url = url.replace(/\/$/, '');
// Remove leading slash from lastPath if exists
lastPath = lastPath.replace(/^\//, '');
// Concat the url and lastPath
return url + '/' + lastPath;
}