mirror of
https://github.com/nomic-ai/gpt4all.git
synced 2025-08-14 00:04:03 -04:00
Compare commits
8 Commits
f3f25a9928
...
c5d346ce98
Author | SHA1 | Date | |
---|---|---|---|
|
c5d346ce98 | ||
|
9ffa401c66 | ||
|
be219e1ce9 | ||
|
71115a344b | ||
|
5425688e63 | ||
|
8b6cc45043 | ||
|
475076fb1d | ||
|
b6c2322c31 |
@ -644,7 +644,10 @@ jobs:
|
|||||||
app-dir: gpt4all-bindings/typescript
|
app-dir: gpt4all-bindings/typescript
|
||||||
pkg-manager: yarn
|
pkg-manager: yarn
|
||||||
override-ci-command: yarn install
|
override-ci-command: yarn install
|
||||||
- run: cd gpt4all-bindings/typescript
|
- run:
|
||||||
|
command: |
|
||||||
|
cd gpt4all-bindings/typescript
|
||||||
|
yarn run test
|
||||||
- run:
|
- run:
|
||||||
command: |
|
command: |
|
||||||
cd gpt4all-bindings/typescript
|
cd gpt4all-bindings/typescript
|
||||||
@ -773,11 +776,10 @@ workflows:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
requires:
|
requires:
|
||||||
- node/test
|
|
||||||
- npm-hold
|
- npm-hold
|
||||||
# - build-bindings-backend-linux
|
- build-bindings-backend-linux
|
||||||
# - build-bindings-backend-windows-msvc
|
- build-bindings-backend-windows-msvc
|
||||||
# - build-bindings-backend-macos
|
- build-bindings-backend-macos
|
||||||
# CSharp Jobs
|
# CSharp Jobs
|
||||||
- build-csharp-linux:
|
- build-csharp-linux:
|
||||||
filters:
|
filters:
|
||||||
|
@ -53,7 +53,8 @@
|
|||||||
'-fno-rtti',
|
'-fno-rtti',
|
||||||
],
|
],
|
||||||
'cflags_cc': [
|
'cflags_cc': [
|
||||||
'-std=c++2a'
|
'-std=c++2a',
|
||||||
|
'-fexceptions'
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
]
|
]
|
||||||
|
@ -97,10 +97,20 @@ Napi::Function NodeModelWrapper::GetClass(Napi::Env env) {
|
|||||||
std::string text = info[0].As<Napi::String>().Utf8Value();
|
std::string text = info[0].As<Napi::String>().Utf8Value();
|
||||||
size_t embedding_size = 0;
|
size_t embedding_size = 0;
|
||||||
float* arr = llmodel_embedding(GetInference(), text.c_str(), &embedding_size);
|
float* arr = llmodel_embedding(GetInference(), text.c_str(), &embedding_size);
|
||||||
auto arr_size = sizeof(arr) / sizeof(float);
|
if(arr == nullptr) {
|
||||||
Napi::Float32Array js_array = Napi::Float32Array::New(info.Env(), arr_size);
|
Napi::Error::New(
|
||||||
|
env,
|
||||||
|
"Cannot embed. native embedder returned 'nullptr'"
|
||||||
|
).ThrowAsJavaScriptException();
|
||||||
|
return env.Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(embedding_size == 0 && text.size() != 0 ) {
|
||||||
|
std::cout << "Warning: embedding length 0 but input text length > 0" << std::endl;
|
||||||
|
}
|
||||||
|
Napi::Float32Array js_array = Napi::Float32Array::New(env, embedding_size);
|
||||||
|
|
||||||
for (size_t i = 0; i < arr_size; ++i) {
|
for (size_t i = 0; i < embedding_size; ++i) {
|
||||||
float element = *(arr + i);
|
float element = *(arr + i);
|
||||||
js_array[i] = element;
|
js_array[i] = element;
|
||||||
}
|
}
|
||||||
@ -220,7 +230,7 @@ Napi::Function NodeModelWrapper::GetClass(Napi::Env env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
llmodel_model NodeModelWrapper::GetInference() {
|
llmodel_model NodeModelWrapper::GetInference() {
|
||||||
return *inference_.load();
|
return *inference_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Exports Bindings
|
//Exports Bindings
|
||||||
|
@ -37,7 +37,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* The underlying inference that interfaces with the C interface
|
* The underlying inference that interfaces with the C interface
|
||||||
*/
|
*/
|
||||||
std::atomic<std::shared_ptr<llmodel_model>> inference_;
|
std::shared_ptr<llmodel_model> inference_;
|
||||||
|
|
||||||
std::string type;
|
std::string type;
|
||||||
// corresponds to LLModel::name() in typescript
|
// corresponds to LLModel::name() in typescript
|
||||||
|
@ -30,7 +30,7 @@ void threadEntry(TsfnContext* context) {
|
|||||||
context->tsfn.BlockingCall(&context->pc,
|
context->tsfn.BlockingCall(&context->pc,
|
||||||
[](Napi::Env env, Napi::Function jsCallback, PromptWorkContext* pc) {
|
[](Napi::Env env, Napi::Function jsCallback, PromptWorkContext* pc) {
|
||||||
llmodel_prompt(
|
llmodel_prompt(
|
||||||
*pc->inference_.load(),
|
*pc->inference_,
|
||||||
pc->question.c_str(),
|
pc->question.c_str(),
|
||||||
&prompt_callback,
|
&prompt_callback,
|
||||||
&response_callback,
|
&response_callback,
|
||||||
@ -55,7 +55,6 @@ void FinalizerCallback(Napi::Env env,
|
|||||||
// Resolve the Promise previously returned to JS
|
// Resolve the Promise previously returned to JS
|
||||||
context->deferred_.Resolve(Napi::String::New(env, context->pc.res));
|
context->deferred_.Resolve(Napi::String::New(env, context->pc.res));
|
||||||
// Wait for the thread to finish executing before proceeding.
|
// Wait for the thread to finish executing before proceeding.
|
||||||
std::thread::id this_id = std::this_thread::get_id();
|
|
||||||
context->nativeThread.join();
|
context->nativeThread.join();
|
||||||
delete context;
|
delete context;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
struct PromptWorkContext {
|
struct PromptWorkContext {
|
||||||
std::string question;
|
std::string question;
|
||||||
std::atomic<std::shared_ptr<llmodel_model>>& inference_;
|
std::shared_ptr<llmodel_model>& inference_;
|
||||||
llmodel_prompt_context prompt_params;
|
llmodel_prompt_context prompt_params;
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { LLModel, createCompletion, DEFAULT_DIRECTORY, DEFAULT_LIBRARIES_DIRECTORY, loadModel } from '../src/gpt4all.js'
|
import { LLModel, createCompletion, DEFAULT_DIRECTORY, DEFAULT_LIBRARIES_DIRECTORY, loadModel, createEmbedding } from '../src/gpt4all.js'
|
||||||
|
|
||||||
const ll = await loadModel(
|
const ll = await loadModel(
|
||||||
'ggml-gpt4all-j-v1.3-groovy.bin',
|
'orca-mini-3b.ggmlv3.q4_0.bin',
|
||||||
{ verbose: true }
|
{ verbose: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -37,4 +37,32 @@ const completion2 = await createCompletion(ll, [
|
|||||||
{ role : 'user', content: 'What is two plus two?' },
|
{ role : 'user', content: 'What is two plus two?' },
|
||||||
], { verbose: true })
|
], { verbose: true })
|
||||||
|
|
||||||
console.log(completion2.choices[0].message)
|
console.log(completion2.choices[0].message)
|
||||||
|
|
||||||
|
const embedder = await loadModel("ggml-all-MiniLM-L6-v2-f16.bin", { verbose: true })
|
||||||
|
|
||||||
|
console.log(createEmbedding(embedder, "sdfdsfds"))
|
||||||
|
// At the moment, from testing this code, concurrent model prompting is not possible.
|
||||||
|
// Behavior: The last prompt gets answered, but the rest are cancelled
|
||||||
|
// my experience with threading is not the best, so if anyone who is good is willing to give this a shot,
|
||||||
|
// maybe this is possible
|
||||||
|
// afaik threading with llama.cpp is not the best, so this will be left here as reference
|
||||||
|
|
||||||
|
//const responses = await Promise.all([
|
||||||
|
// createCompletion(ll, [
|
||||||
|
// { role : 'system', content: 'You are an advanced mathematician.' },
|
||||||
|
// { role : 'user', content: 'What is 1 + 1?' },
|
||||||
|
// ], { verbose: true }),
|
||||||
|
// createCompletion(ll, [
|
||||||
|
// { role : 'system', content: 'You are an advanced mathematician.' },
|
||||||
|
// { role : 'user', content: 'What is 1 + 1?' },
|
||||||
|
// ], { verbose: true }),
|
||||||
|
//
|
||||||
|
//createCompletion(ll, [
|
||||||
|
// { role : 'system', content: 'You are an advanced mathematician.' },
|
||||||
|
// { role : 'user', content: 'What is 1 + 1?' },
|
||||||
|
//], { verbose: true })
|
||||||
|
//
|
||||||
|
//])
|
||||||
|
//console.log(responses.map(s => s.choices[0].message))
|
||||||
|
|
||||||
|
17
gpt4all-bindings/typescript/src/gpt4all.d.ts
vendored
17
gpt4all-bindings/typescript/src/gpt4all.d.ts
vendored
@ -84,7 +84,7 @@ declare class LLModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Prompt the model with a given input and optional parameters.
|
* Prompt the model with a given input and optional parameters.
|
||||||
* This is the raw output from std out.
|
* This is the raw output from model.
|
||||||
* Use the prompt function exported for a value
|
* Use the prompt function exported for a value
|
||||||
* @param q The prompt input.
|
* @param q The prompt input.
|
||||||
* @param params Optional parameters for the prompt context.
|
* @param params Optional parameters for the prompt context.
|
||||||
@ -92,6 +92,15 @@ declare class LLModel {
|
|||||||
*/
|
*/
|
||||||
raw_prompt(q: string, params: Partial<LLModelPromptContext>, callback: (res: string) => void): void; // TODO work on return type
|
raw_prompt(q: string, params: Partial<LLModelPromptContext>, callback: (res: string) => void): void; // TODO work on return type
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Embed text with the model. Keep in mind that
|
||||||
|
* not all models can embed text, (only bert can embed as of 07/16/2023 (mm/dd/yyyy))
|
||||||
|
* Use the prompt function exported for a value
|
||||||
|
* @param q The prompt input.
|
||||||
|
* @param params Optional parameters for the prompt context.
|
||||||
|
* @returns The result of the model prompt.
|
||||||
|
*/
|
||||||
|
embed(text: string) : Float32Array
|
||||||
/**
|
/**
|
||||||
* Whether the model is loaded or not.
|
* Whether the model is loaded or not.
|
||||||
*/
|
*/
|
||||||
@ -152,6 +161,11 @@ declare function createCompletion(
|
|||||||
options?: CompletionOptions
|
options?: CompletionOptions
|
||||||
): Promise<CompletionReturn>;
|
): Promise<CompletionReturn>;
|
||||||
|
|
||||||
|
declare function createEmbedding(
|
||||||
|
llmodel: LLModel,
|
||||||
|
text: string,
|
||||||
|
): Float32Array
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The options for creating the completion.
|
* The options for creating the completion.
|
||||||
*/
|
*/
|
||||||
@ -383,6 +397,7 @@ export {
|
|||||||
LoadModelOptions,
|
LoadModelOptions,
|
||||||
loadModel,
|
loadModel,
|
||||||
createCompletion,
|
createCompletion,
|
||||||
|
createEmbedding,
|
||||||
createTokenStream,
|
createTokenStream,
|
||||||
DEFAULT_DIRECTORY,
|
DEFAULT_DIRECTORY,
|
||||||
DEFAULT_LIBRARIES_DIRECTORY,
|
DEFAULT_LIBRARIES_DIRECTORY,
|
||||||
|
@ -85,6 +85,10 @@ function createPrompt(messages, hasDefaultHeader, hasDefaultFooter) {
|
|||||||
return fullPrompt.join('\n');
|
return fullPrompt.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function createEmbedding(llmodel, text) {
|
||||||
|
return llmodel.embed(text)
|
||||||
|
}
|
||||||
async function createCompletion(
|
async function createCompletion(
|
||||||
llmodel,
|
llmodel,
|
||||||
messages,
|
messages,
|
||||||
@ -133,6 +137,7 @@ module.exports = {
|
|||||||
DEFAULT_DIRECTORY,
|
DEFAULT_DIRECTORY,
|
||||||
LLModel,
|
LLModel,
|
||||||
createCompletion,
|
createCompletion,
|
||||||
|
createEmbedding,
|
||||||
downloadModel,
|
downloadModel,
|
||||||
retrieveModel,
|
retrieveModel,
|
||||||
loadModel,
|
loadModel,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const { createWriteStream, existsSync, unlink } = require("node:fs");
|
const { createWriteStream, existsSync, statSync } = require("node:fs");
|
||||||
|
const fsp = require('node:fs/promises')
|
||||||
const { performance } = require("node:perf_hooks");
|
const { performance } = require("node:perf_hooks");
|
||||||
const path = require("node:path");
|
const path = require("node:path");
|
||||||
const {mkdirp} = require("mkdirp");
|
const {mkdirp} = require("mkdirp");
|
||||||
@ -122,7 +123,7 @@ function downloadModel(modelName, options = {}) {
|
|||||||
if (options.md5sum) {
|
if (options.md5sum) {
|
||||||
const fileHash = await md5File(partialModelPath);
|
const fileHash = await md5File(partialModelPath);
|
||||||
if (fileHash !== options.md5sum) {
|
if (fileHash !== options.md5sum) {
|
||||||
await fs.unlink(partialModelPath);
|
await fsp.unlink(partialModelPath);
|
||||||
return reject(
|
return reject(
|
||||||
Error(`Model "${modelName}" failed verification: Hashes mismatch`)
|
Error(`Model "${modelName}" failed verification: Hashes mismatch`)
|
||||||
);
|
);
|
||||||
@ -132,7 +133,7 @@ function downloadModel(modelName, options = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await fs.rename(partialModelPath, finalModelPath);
|
await fsp.rename(partialModelPath, finalModelPath);
|
||||||
resolve(finalModelPath);
|
resolve(finalModelPath);
|
||||||
})
|
})
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user