withcatai / node-llama-cpp

Run AI models locally on your machine with node.js bindings for llama.cpp. Enforce a JSON schema on the model output on the generation level
https://node-llama-cpp.withcat.ai
MIT License
894 stars 86 forks source link

langchain.js - throws error "disposed undefined" #132

Closed mrddter closed 8 months ago

mrddter commented 9 months ago

Issue description

Properly use langchain.js with llama.cpp and embeddings (maybe it's a new feature?)

Expected Behavior

Use langchain.js to add some useful retrievers like for memory or file loading. I'm probably wrong somewhere but I don't know where, can you give me some advice? Thanks!

Actual Behavior

When I try to use retrievers together with LlamaCppEmbeddings I get an error:

file:///Users/mrddter/langchain-llama/node_modules/node-llama-cpp/dist/llamaEvaluator/LlamaChatSession.js:28
        if (contextSequence.disposed)
                            ^

TypeError: Cannot read properties of undefined (reading 'disposed')
    at new LlamaChatSession (file:///Users/mrddter/langchain-llama/node_modules/node-llama-cpp/dist/llamaEvaluator/LlamaChatSession.js:28:29)
    at createLlamaSession (file:///Users/mrddter/langchain-llama/node_modules/langchain/node_modules/@langchain/community/dist/utils/llama_cpp.js:27:12)
    at new LlamaCpp (file:///Users/mrddter/langchain-llama/node_modules/langchain/node_modules/@langchain/community/dist/llms/llama_cpp.js:77:25)
    at file:///Users/mrddter/langchain-llama/index.js:10:15

Steps to reproduce

I used this test code:

import { VectorStoreRetrieverMemory } from 'langchain/memory'
import { LLMChain } from 'langchain/chains'
import { PromptTemplate } from 'langchain/prompts'
import { MemoryVectorStore } from 'langchain/vectorstores/memory'

import { LlamaCppEmbeddings } from 'langchain/embeddings/llama_cpp'
import { LlamaCpp } from 'langchain/llms/llama_cpp'

const embeddings = new LlamaCppEmbeddings({ modelPath: process.env.MODEL_PATH, batchSize: 1024 })
const model = new LlamaCpp({ modelPath: process.env.MODEL_PATH, batchSize: 1024 })

const vectorStore = new MemoryVectorStore(embeddings)
const memory = new VectorStoreRetrieverMemory({
  // 1 is how many documents to return, you might want to return more, eg. 4
  vectorStoreRetriever: vectorStore.asRetriever(1),
  memoryKey: 'history'
})

// First let's save some information to memory, as it would happen when
// used inside a chain.
await memory.saveContext({ input: 'My favorite food is pizza' }, { output: 'thats good to know' })
await memory.saveContext({ input: 'My favorite sport is soccer' }, { output: '...' })
await memory.saveContext({ input: "I don't the Celtics" }, { output: 'ok' })

// Now let's use the memory to retrieve the information we saved.
console.log(await memory.loadMemoryVariables({ prompt: 'what sport should i watch?' }))
/*
{ history: 'input: My favorite sport is soccer\noutput: ...' }
*/

// Now let's use it in a chain.

const prompt =
  PromptTemplate.fromTemplate(`The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.

Relevant pieces of previous conversation:
{history}

(You do not need to use these pieces of information if not relevant)

Current conversation:
Human: {input}
AI:`)
const chain = new LLMChain({ llm: model, prompt, memory })

const res1 = await chain.call({ input: "Hi, my name is Perry, what's up?" })
console.log({ res1 })
/*
{
  res1: {
    text: " Hi Perry, I'm doing great! I'm currently exploring different topics related to artificial intelligence like natural language processing and machine learning. What about you? What have you been up to lately?"
  }
}
*/

const res2 = await chain.call({ input: "what's my favorite sport?" })
console.log({ res2 })
/*
{ res2: { text: ' You said your favorite sport is soccer.' } }
*/

const res3 = await chain.call({ input: "what's my name?" })
console.log({ res3 })
/*
{ res3: { text: ' Your name is Perry.' } }
*/

My Environment

Dependency Version
Operating System macOS Ventura
CPU Apple M1
Node.js version 10.10.0
Typescript version only js
langchain version ^0.0.212
node-llama-cpp version ^3.0.0-beta.1

Additional Context

I also tried this snippet to try to use only embeddings via langhchain.js but without success:

import { LlamaCppEmbeddings } from 'langchain/embeddings/llama_cpp'

const embeddings = new LlamaCppEmbeddings({ modelPath: process.env.MODEL_PATH, batchSize: 1024 })
const res = await embeddings.embedQuery('Hello Llama!')
console.log(res)

Relevant Features Used

Are you willing to resolve this issue by submitting a Pull Request?

Yes, I have the time, but I don't know how to start. I would need guidance.

giladgd commented 8 months ago

@mrddter Version 3 is a breaking change, and Langchain doesn't support it yet as it is still a beta. For now, use the stable version (the version that's installed when you run npm install node-llama-cpp), which is 2.8.3 at the time of writing this