-
Notifications
You must be signed in to change notification settings - Fork 144
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
[LuceneOnFaiss - Part1] Added building blocks for memory optimized search. #2581
[LuceneOnFaiss - Part1] Added building blocks for memory optimized search. #2581
Conversation
src/main/java/org/opensearch/knn/memoryoptsearch/MemoryOptimizedSearcherFactory.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/index/codec/KNN990Codec/NativeEngines990KnnVectorsReader.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/index/codec/KNN990Codec/NativeEngines990KnnVectorsReader.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/index/codec/KNN990Codec/NativeEngines990KnnVectorsReader.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/memoryoptsearch/MemoryOptimizedSearcher.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/memoryoptsearch/faiss/FaissMemoryOptimizedSearcherFactory.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/index/codec/KNN990Codec/NativeEngines990KnnVectorsReader.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/index/codec/KNN990Codec/NativeEngines990KnnVectorsReader.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/index/codec/KNN990Codec/NativeEngines990KnnVectorsReader.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/index/codec/KNN990Codec/NativeEngines990KnnVectorsReader.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/memoryoptsearch/faiss/FaissMemoryOptimizedSearcherFactory.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/memoryoptsearch/MemoryOptimizedSearcherFactory.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/memoryoptsearch/MemoryOptimizedSearcher.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/knn/index/codec/KNN990Codec/NativeEngines990KnnVectorsReader.java
Outdated
Show resolved
Hide resolved
@0ctopus13prime please fix the CIs too |
@@ -216,4 +218,9 @@ public ResolvedMethodContext resolveMethod( | |||
public boolean supportsRemoteIndexBuild() { | |||
return knnLibrary.supportsRemoteIndexBuild(); | |||
} | |||
|
|||
@Override | |||
public Optional<MemoryOptimizedSearcherFactory> getMemoryOptimizedSearcherFactory() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not really sure we should keep adding implementation details to the enum. Shouldn't a simple engine check inside the factory take care of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think each Engine either supports or does not support memory_optimized_search
mode.
So far, FAISS is the single engine that supports the mode but it can be expanded to other future engines.
From that perspective, it is natural to put factory-getter
method in Engine.
What is your concern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be per engine. Ideally, it would be included in something like https://github.com/opensearch-project/k-NN/blob/main/src/main/java/org/opensearch/knn/index/engine/KNNLibrarySearchContext.java. This can be retrieved via https://github.com/opensearch-project/k-NN/blob/main/src/main/java/org/opensearch/knn/index/engine/KNNLibrary.java#L121.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My problem with these enums is that its turning into giant static configuration database, along with a workaround to have dependency injection. Its a maintenance concern- It doesn't seem to be a standard coding pattern and I am not sure its the right way to go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't a simple engine check inside the factory take care of this?
I dont think we should branch throughout the code based on engine. This will make engine extendability very difficult and also will created complex branching in the code - this has happened to some degree based in the query.
The purpose of KNNLibrarySearchContext was to let the given engine tell how we are supposed to search. This isnt totally complete, but the direction to kind of further improve this is in #2568. On the indexing/reader setup side, we would need the engines to return a PerFieldKnnVectorFormat that can be added via https://github.com/opensearch-project/k-NN/blob/main/src/main/java/org/opensearch/knn/index/codec/KNNCodecService.java#L43.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@0ctopus13prime merging the thread from here #2581 (comment) too. and also adding my thoughts from the discussion happening on this thread.
@jmazanec15, the idea of engine providing a PerFieldKnnVectorFormat based on the MappedfieldType is a step in right direction. But once we have the KNNVectorFormat which is engine specific then searcher should not come from KNNEngine. It should be job of Reader to find the right searcher for the algorithm.
We moving searcher currently in KNNEngine, I somehow feel a decision we are taking too early. Should we take this decision once we move to PerFieldKnnVectorFormat being returned via KNNEngine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we could align on having a dedicated FAISS VectorFormat, then will update accordingly in the next rev.
I will add a branch in BasePerFieldKnnVectorsFormat
to return FaissVectorFormat returning a reader where it performs vector search on FAISS index for knn fields using FAISS engine.
// In BasePerFieldKnnVectorsFormat
if (engine == FAISS) {
return new FaissKnnVectorsFormat(...);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern is that the engine/method will determine if the optimized memory searcher is supported and how its supported. In the current code, Im not sure Im seeing where the branching based on method logic is implemented - for instance, where would we say HNSW fp16 is not supported or IVF is not supported (I might just be missing it). But I think this can get fairly complex, and is why I think that it would be better to go through the engine that determines what functionality is supported.
So we could just add a method in KNNLibrarySearchContext like "getMemoryOptimizedSearcherFactory()". Then, we can retrieve it via knnEngine.getLibrarySearchContext(methodName)
(we might need to take additional info like library params like what @owenhalpert is working on). With this, we keep the codec somewhat engine agnostic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern is that the engine/method will determine if the optimized memory searcher is supported and how its supported. In the current code, Im not sure Im seeing where the branching based on method logic is implemented - for instance, where would we say HNSW fp16 is not supported or IVF is not supported (I might just be missing it). But I think this can get fairly complex, and is why I think that it would be better to go through the engine that determines what functionality is supported.
So we could just add a method in KNNLibrarySearchContext like "getMemoryOptimizedSearcherFactory()". Then, we can retrieve it via
knnEngine.getLibrarySearchContext(methodName)
(we might need to take additional info like library params like what @owenhalpert is working on). With this, we keep the codec somewhat engine agnostic.
This seems reasonable to me !!
Hmm.. this PR should not affect anything at all 😅 |
I also think so, but its always better to see build CIs passing and also DCO checks. This will ensure that branch is healthy |
06716e7
to
83cd071
Compare
src/main/java/org/opensearch/knn/index/codec/KNN990Codec/NativeEngines990KnnVectorsReader.java
Outdated
Show resolved
Hide resolved
Please note that once get verbal approval on the implementation, then will ship unit tests in this PR. |
83cd071
to
3bc02d2
Compare
3bc02d2
to
20ddf6b
Compare
…, only FAISS is supporing this. Signed-off-by: Dooyong Kim <[email protected]>
20ddf6b
to
9be82c7
Compare
|
||
/** | ||
* Vectors reader class for reading the flat vectors for native engines. The class provides methods for iterating | ||
* over the vectors and retrieving their values. | ||
*/ | ||
@Slf4j |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not log4j?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slf4j is a general logging framework without tied dependency over a specific logger framework like Log4j, Logback etc. It's a facade for different logging frameworks. When there's a log framework upgrade or change, it won't need any changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let just use what we are using in the plugin to avoid conflicts for future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why it conflicts? opensearch core is using slf4j with log4j
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I say conflict, I mean mainly if someone trying add a logger they will be confused whether to use slf4j or log4j. So people will have conflicts in mind what to pick. It mainly about consistency in the code. There is no specific reason from my side, for me its all about consistency in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good, will update in the next rev.
before raising a new PR, could you share your thoughts on the code?
If you leave comments, I will factor them into the next PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should start using Slf4j and clean code by replacing log4j to Slf4j !! There are couple of benefits we have 1. We are aligning to core and Lucene , Lucene also uses Slf4j , and in future either if core replaces that with any other inline framework !! We get for free !!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in that case it should a be part of a separate GH and not scope of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will update the annotation in the next rev! :)
@jmazanec15 |
fbcdfbc
into
opensearch-project:lucene-on-faiss
Description
[1/11] This is the first PR to establish the building blocks for memory optimized search.
At the moment, FAISS is the only engine that supports memory optimized search where loading vectors in demand fashion.
Note that this will be merged into the feature branch first. Unit tests + IT tests will be covered in PR-9 and PR-10.
Related Issues
RFC : #2401
Check List
--signoff
.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.