-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Could not import faiss-node (NextJS) when loading from python #4027
Comments
🤖 Hello @Simbaclaws! 🚀 Nice to meet you, I'm Dosu, a bot designed to help you with troubleshooting, answering questions, and guiding you on how to be a contributor. I'm here to lend a hand while a human maintainer becomes available. I'm currently looking over the issue you've posted and will get back to you with a comprehensive answer shortly. Hold tight! 🛸 |
CC @ewfian could be a Windows issue? |
I'll test this on a ubuntu server soon, I'll also test it on mac os if need be... I'll give updated info tomorrow. EDIT: Same issue on ubuntu 23.04 |
The langchain 0.1.0
langchain-community 0.0.12
langchain-core 0.1.10 from langchain_community.embeddings import FakeEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import TextLoader
loader = TextLoader("state_of_the_union.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
embeddings = FakeEmbeddings(size=4)
db = FAISS.from_documents(docs, embeddings)
query = "What did the president say about Ketanji Brown Jackson"
docs = db.similarity_search(query)
db.save_local("faiss_index") This is because the namespace of @Simbaclaws However, I did not encounter the same error as you did. Please try the example code below without async function run() {
const vectorStore = await FaissStore.fromTexts(
["Hello world", "Bye bye", "hello nice world"],
[{ id: 2 }, { id: 1 }, { id: 3 }],
new FakeEmbeddings()
);
const resultOne = await vectorStore.similaritySearch("hello world", 1);
console.log(resultOne);
} |
Where do I import FakeEmbeddings from? The suggested packages by my IDE seem to all fail:
|
Please try this: or you can also use
|
Same error message sadly:
I am using this inside a nextjs 14 api route by the way. |
@Simbaclaws I just created a Next.js project and reproduced your issue using the
I found a configuration in the documentation that exempts After adding this config for faiss-node, it should work correctly. Please give it a try. |
That works!! Thank you so much! I did not know that I had to use a experimental feature in nextjs to put the faiss-node package outside of the webpack bundler. I did see the same thing in the docs, but couldn't figure out I had to use this feature. You are my hero 💯 |
When I put loadFromPython back in it says:
perhaps I'm still doing something wrong? The only other thing I'm putting in is modelName, perhaps it's complaining about that name? const vectorstore = await FaissStore.loadFromPython("./knowledge", new OpenAIEmbeddings({
modelName: "text-embedding-ada-002"
})) EDIT: Also without the modelName it's doing that... |
@Simbaclaws It seems that import { NameRegistry } from 'pickleparser'
console.log(NameRegistry.getFullyQualifiedName("testmodule", "testname")) // testmodule.testname
const registry = new NameRegistry();
registry.register("testmodule", "testname", () => 123)
const func = registry.resolve("testmodule", "testname") as any
console.log(func()) // 123 |
I'm sorry I'm quite new to all of faiss, langchain, and openai. In the case of loading a folder with a pkl file, what exactly would I have to do with the NameRegistry? It confuses me a little. In python it looks like I can just say: VectorStore = FAISS.load_local('knowledge', OpenAIEmbeddings(model='text-embedding-ada-002', openai_api_key=OPENAI_API_KEY)) And it would work in importing the knowledge folder with the pkl. I don't have to do anything with any sort of NameRegistry in python. I assumed this worked the same way in javascript. What exactly is this NameRegistry and how do I use it in a similar fashion according to my example: const vectorstore = await FaissStore.loadFromPython("./knowledge", new OpenAIEmbeddings({
modelName: "text-embedding-ada-002"
})) I'll use your example code to test whether it'll work, but I'm just a bit confused what the extra steps would be to read from a knowledge folder that is local. EDIT:
I think this comes down to your original problem here: #4027 (comment) EDIT 2: I think I understand now that I just needed the pickleparser package to get further I guess... Wouldn't it be wise by the maintainers of faiss-node to make the pickleparser a dependency of the faiss-node package? Or is this something that should be excluded by default? If you have code in your package that makes use of another package, it would be useful to include that package in the dependencies IMO... Thank you so much for taking the time to help solve my issue on top of trying to help solve the issue mentioned in your comment. You are awesome 👍 |
@Simbaclaws Python will export two files: When pickleparser reads a .pkl file, it needs to handle the mapping relationships between Python identifiers such as modules and class names, and the data structures in JavaScript. These mappings are managed through const registry = new NameRegistry()
.register("langchain.docstore.in_memory", "InMemoryDocstore", PyInMemoryDocstore)
.register("langchain_community.docstore.in_memory", "InMemoryDocstore", PyInMemoryDocstore)
.register("langchain.schema", "Document", PyDocument)
.register("langchain.docstore.document", "Document", PyDocument)
.register("langchain.schema.document", "Document", PyDocument)
.register("langchain_core.documents.base", "Document", PyDocument)
.register("pathlib", "WindowsPath", (...args) => args.join("\\"))
.register("pathlib", "PosixPath", (...args) => args.join("/")); For example, The error you are currently encountering is a bug.
Please refer to the comments above; I will file a pull request to fix this later. In the meantime, you can make a simple edit in node_modules@langchain\community\dist\vectorstores\faiss.js. Add the following two lines of code to make it work. |
In fact, there is no relationship between the |
Oh wow, I must've overlooked that. Thank you so much for everything, I'm currently checking whether the solution works. I'll report back! EDIT: I have this right now in faiss.js: const registry = new NameRegistry()
.register("langchain.docstore.in_memory", "InMemoryDocstore", PyInMemoryDocstore)
.register("langchain_community.docstore.in_memory", "InMemoryDocstore", PyInMemoryDocstore)
.register("langchain.schema", "Document", PyDocument)
.register("langchain.docstore.document", "Document", PyDocument)
.register("langchain.schema.document", "Document", PyDocument)
.register("langchain_core.documents.base", "Document", PyDocument)
.register("pathlib", "WindowsPath", (...args) => args.join("\\"))
.register("pathlib", "PosixPath", (...args) => args.join("/")); However, it is still complaining about:
I've checked the .pnpm correct faiss.js and it's the same as the faiss.js in my node_modules. Doesn't it have to be .register("langchain.docstore.in_memory", "InMemoryDocstore", PyInMemoryDocstore)
.register("langchain_community.docstore.in_memory", "InMemoryDocstore", PyInMemoryDocstore) |
@Simbaclaws Please try deleting the .next directory to invalidate the build cache. |
Seems like the error dissapeared, but a new one popped up for me. I'm sorry if I'm being a nuisance... Currently I'm using the following code: const vectorstore = await FaissStore.loadFromPython("./knowledge", new OpenAIEmbeddings({
modelName: "text-embedding-ada-002"
}))
const vectorStoreRetriever = vectorstore.asRetriever();
// Create a system & human prompt for the chat model
const SYSTEM_TEMPLATE = `
This is some prompt I'm giving to my gpt
==========
{question}
==========
Answer:
Source:`;
const templateMessages = [
SystemMessagePromptTemplate.fromTemplate(SYSTEM_TEMPLATE),
HumanMessagePromptTemplate.fromTemplate("{question}"),
];
const docs = await vectorstore.similaritySearch(messages.content, 1);
const prompt = ChatPromptTemplate.fromMessages(templateMessages);
const chain = RunnableSequence.from([
{
// Extract the "question" field from the input object and pass it to the retriever as a string
sourceDocuments: RunnableSequence.from([
(input) => input.question,
vectorStoreRetriever,
]),
question: (input) => input.question,
},
{
// Pass the source documents through unchanged so that we can return them directly in the final result
sourceDocuments: (previousStepResult) => previousStepResult.sourceDocuments,
question: (previousStepResult) => previousStepResult.question,
context: (previousStepResult) =>
formatDocumentsAsString(previousStepResult.sourceDocuments),
},
{
result: prompt.pipe(model).pipe(new StringOutputParser()),
sourceDocuments: (previousStepResult) => previousStepResult.sourceDocuments,
},
]);
const response = await chain.invoke({
question: messages.content,
input_documents: docs
})
console.log(response)
return new NextResponse(response.result, {status: 200}) It's now responding with:
Am I using the similaritysearch wrong? I'll check the docs if I'm missing another package somewhere... |
@Simbaclaws It seems that loadFromPython has now passed. Based on the error "OpenAIEmbeddings.embedQuery," after a quick review of the code, I suspect that the replace below may be causing a Null Reference Exception (NRE). Please confirm the content of messages.content.
|
Awesome! I was indeed messing up the messages content. It's working as intended... I have a last question that I want to ask: In python there is a function called: load_qa_with_sources_chain() This is a function that loads a question and answer, and returns the answer + a source to the url it got the information from. I think the url is provided in the documents... I'm trying to accomplish the same thing by doing this part: const chain = RunnableSequence.from([
{
// Extract the "question" field from the input object and pass it to the retriever as a string
sourceDocuments: RunnableSequence.from([
(input) => input.question,
vectorStoreRetriever,
]),
question: (input) => input.question,
},
{
// Pass the source documents through unchanged so that we can return them directly in the final result
sourceDocuments: (previousStepResult) => previousStepResult.sourceDocuments,
question: (previousStepResult) => previousStepResult.question,
context: (previousStepResult) =>
formatDocumentsAsString(previousStepResult.sourceDocuments),
},
{
result: prompt.pipe(model).pipe(new StringOutputParser()),
sourceDocuments: (previousStepResult) => previousStepResult.sourceDocuments,
},
]); But instead of returning just the source url in the answer, it is giving me all of the documents it has searched and not give me back a url to where it got the answer from... Do you perhaps know of a way to put the url from the source documents into the response? It also seems that my input documents aren't working... For some reason it's not using the data I provided, just the last document is being used.. |
@Simbaclaws Sorry, I'm not familiar with this question. perhaps you can ask @jacoblee93 for help or create a new discussion. |
I'll do that, thank you for everything so far! I'm really happy with the progress that was made. EDIT: I created a discussion here: #4037 |
When your PR has been merged (for the actual fix), I'll close this github issue as solved. |
I've figured out the source code for getting my load qa chains with sources to work. |
Hi, I know this is a duplicate of:
#2107
However, in that issue it says that this has been resolved. While I'm on the latest release:
0.1.2
Which should have the fix for this available here:
#2178
My issue is the following:
#2107 (comment)
For reference, I'll post it below:
Hi there,
I'm getting the same type of error message in my console when I try to:
knowledge is a folder in the root folder that includes 2 files:
I am using the following to see whether my API route in nextjs can reach the files:
this logs the actual filenames, so I know they're there...
I'm getting the following error message in my console:
I'm running this on windows with
npm run dev
I've already tried installing the package, but I have no clue why my nextjs isn't importing the files...
My node version is 20.10.0
Is there anything I can do to get this issue sorted?
It says read properties of undefined (reading 'indexOf')
This to me indicates it can not read the ./knowledge folder with files for some reason. But I haven't been able to figure out why yet. I could be totally wrong here though.
The text was updated successfully, but these errors were encountered: