-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Create int bfloat16 vector formats #136627
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
Open
thecoop
wants to merge
42
commits into
elastic:lucene_snapshot
Choose a base branch
from
thecoop:int-hnsw-bfloat16
base: lucene_snapshot
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
c10fd76
Add HNSW scalar quantized bfloat16 implementation
thecoop 3a6f7fc
Add flat format
thecoop a85b7ca
Add int8 implementation
thecoop a638b59
Rename class
thecoop 419032d
Improve tests
thecoop 038db83
Merge branch 'main' into int-hnsw-bfloat16
thecoop 1287a0b
Fix module reference
thecoop bd55e05
Merge branch 'lucene_snapshot' into int-hnsw-bfloat16
thecoop 7c343c5
Update to use new Lucene104 format
thecoop 4fa4338
Update more tests
thecoop 84f5bf4
Merge branch 'lucene_snapshot' into int-hnsw-bfloat16
thecoop 4815bc2
Class renames
thecoop 94ef4f1
[CI] Auto commit changes from spotless
61de804
Merge branch 'main' into int-hnsw-bfloat16
thecoop 6720384
Update for ElementType change
thecoop 5c0e171
Merge branch 'lucene_snapshot' into int-hnsw-bfloat16
thecoop 115507a
Revert "Use the reader in Lucene BWC"
thecoop 44ecd39
Remove intermediate class
thecoop cbba58b
Merge branch 'lucene_snapshot' into int-hnsw-bfloat16
thecoop f989a30
Merge branch 'lucene_snapshot' into int-hnsw-bfloat16
thecoop 33fe50d
Merge branch 'lucene_snapshot' into int-hnsw-bfloat16
thecoop f6ee769
Use public constructor
thecoop 3017e33
Mute org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapperTes…
elasticsearchmachine 70507a6
Verify execution info in remote index resolution tests (#137361)
idegtiarenko 0b8a37a
Handle ._original and._ignore_malformed stored fields correctly with …
martijnvg 18e27e2
Merge branch 'lucene_snapshot' into int-hnsw-bfloat16
thecoop ec0efaf
Support choosing the downsampling method in data stream lifecycle (#1…
gmarouli 60b89a8
Increase timeout for searchable snapshots in ILM tests (#137514)
nielsbauman ebca69f
Revert "Re-enable some performance updates to ES|QL" (#136781) (#137520)
craigtaverner 846593c
DiskBBQ - Panama support for 4 bits symmetric quantization (#137510)
tteofili da8b9c6
[ML] Skip dataframes when disabled (#137220)
prwhelan b54cd8e
Mute org.elasticsearch.xpack.ilm.CCRIndexLifecycleIT testBasicCCRAndI…
elasticsearchmachine b29af0f
Mute org.elasticsearch.xpack.ilm.CCRIndexLifecycleIT testCcrAndIlmWit…
elasticsearchmachine 4f3ff81
Fix the test dimensions for bit element_type (#137523)
thecoop 1b74ec0
Add competitive sort tests to MapperTestCase (#137437)
romseygeek 9795d0f
We don't need a separate search impl here
thecoop 9473216
Field caps transport changes to return for each original expression w…
piergm 490a2d5
Copy ES819TSDBDocValuesConsumer into tests for version 0 bwc tests (#…
parkertimmins 2047c9a
ESQL: Add support for exponential_histogram in code generation (#137459)
JonasKunz 20ce72d
Unmute FullClusterRestartIT tests (#137254)
ldematte c925aa0
Clean up `TransportResizeAction` (#137471)
DaveCTurner e330b42
Merge branch 'main' into int-hnsw-bfloat16
thecoop File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
...er/src/main/java/org/elasticsearch/index/codec/vectors/es93/ES93Int8FlatVectorFormat.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the "Elastic License | ||
| * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| package org.elasticsearch.index.codec.vectors.es93; | ||
|
|
||
| import org.apache.lucene.codecs.KnnVectorsFormat; | ||
| import org.apache.lucene.codecs.KnnVectorsReader; | ||
| import org.apache.lucene.codecs.KnnVectorsWriter; | ||
| import org.apache.lucene.codecs.hnsw.FlatVectorsFormat; | ||
| import org.apache.lucene.codecs.hnsw.FlatVectorsReader; | ||
| import org.apache.lucene.index.ByteVectorValues; | ||
| import org.apache.lucene.index.FieldInfo; | ||
| import org.apache.lucene.index.FloatVectorValues; | ||
| import org.apache.lucene.index.SegmentReadState; | ||
| import org.apache.lucene.index.SegmentWriteState; | ||
| import org.apache.lucene.search.AcceptDocs; | ||
| import org.apache.lucene.search.KnnCollector; | ||
| import org.apache.lucene.util.Bits; | ||
| import org.apache.lucene.util.hnsw.OrdinalTranslatedKnnCollector; | ||
| import org.apache.lucene.util.hnsw.RandomVectorScorer; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.Map; | ||
|
|
||
| import static org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.MAX_DIMS_COUNT; | ||
|
|
||
| public class ES93Int8FlatVectorFormat extends KnnVectorsFormat { | ||
|
|
||
| static final String NAME = "ES93Int8FlatVectorFormat"; | ||
|
|
||
| private final FlatVectorsFormat format; | ||
|
|
||
| public ES93Int8FlatVectorFormat() { | ||
| this(false, null, 7, false); | ||
| } | ||
|
|
||
| public ES93Int8FlatVectorFormat(boolean useBFloat16) { | ||
| this(useBFloat16, null, 7, false); | ||
| } | ||
|
|
||
| public ES93Int8FlatVectorFormat(boolean useBFloat16, Float confidenceInterval, int bits, boolean compress) { | ||
| super(NAME); | ||
| this.format = new ES93ScalarQuantizedVectorsFormat(useBFloat16, confidenceInterval, bits, compress, false); | ||
| } | ||
|
|
||
| @Override | ||
| public KnnVectorsWriter fieldsWriter(SegmentWriteState state) throws IOException { | ||
| return format.fieldsWriter(state); | ||
| } | ||
|
|
||
| @Override | ||
| public KnnVectorsReader fieldsReader(SegmentReadState state) throws IOException { | ||
| return new ES813FlatVectorReader(format.fieldsReader(state)); | ||
| } | ||
|
|
||
| @Override | ||
| public int getMaxDimensions(String fieldName) { | ||
| return MAX_DIMS_COUNT; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return NAME + "(name=" + NAME + ", innerFormat=" + format + ")"; | ||
| } | ||
|
|
||
| public static class ES813FlatVectorReader extends KnnVectorsReader { | ||
|
|
||
| private final FlatVectorsReader reader; | ||
|
|
||
| public ES813FlatVectorReader(FlatVectorsReader reader) { | ||
| super(); | ||
| this.reader = reader; | ||
| } | ||
|
|
||
| @Override | ||
| public void checkIntegrity() throws IOException { | ||
| reader.checkIntegrity(); | ||
| } | ||
|
|
||
| @Override | ||
| public FloatVectorValues getFloatVectorValues(String field) throws IOException { | ||
| return reader.getFloatVectorValues(field); | ||
| } | ||
|
|
||
| @Override | ||
| public ByteVectorValues getByteVectorValues(String field) throws IOException { | ||
| return reader.getByteVectorValues(field); | ||
| } | ||
|
|
||
| @Override | ||
| public void search(String field, float[] target, KnnCollector knnCollector, AcceptDocs acceptDocs) throws IOException { | ||
| collectAllMatchingDocs(knnCollector, acceptDocs, reader.getRandomVectorScorer(field, target)); | ||
| } | ||
|
|
||
| private void collectAllMatchingDocs(KnnCollector knnCollector, AcceptDocs acceptDocs, RandomVectorScorer scorer) | ||
| throws IOException { | ||
| OrdinalTranslatedKnnCollector collector = new OrdinalTranslatedKnnCollector(knnCollector, scorer::ordToDoc); | ||
| Bits acceptedOrds = scorer.getAcceptOrds(acceptDocs.bits()); | ||
| for (int i = 0; i < scorer.maxOrd(); i++) { | ||
| if (acceptedOrds == null || acceptedOrds.get(i)) { | ||
| collector.collect(i, scorer.score(i)); | ||
| collector.incVisitedCount(1); | ||
| } | ||
| } | ||
| assert collector.earlyTerminated() == false; | ||
| } | ||
|
|
||
| @Override | ||
| public void search(String field, byte[] target, KnnCollector knnCollector, AcceptDocs acceptDocs) throws IOException { | ||
| collectAllMatchingDocs(knnCollector, acceptDocs, reader.getRandomVectorScorer(field, target)); | ||
| } | ||
|
|
||
| @Override | ||
| public Map<String, Long> getOffHeapByteSize(FieldInfo fieldInfo) { | ||
| return reader.getOffHeapByteSize(fieldInfo); | ||
| } | ||
|
|
||
| @Override | ||
| public void close() throws IOException { | ||
| reader.close(); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
...ava/org/elasticsearch/index/codec/vectors/es93/ES93Int8FlatBFloat16VectorFormatTests.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the "Elastic License | ||
| * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| package org.elasticsearch.index.codec.vectors.es93; | ||
|
|
||
| import org.apache.lucene.index.VectorEncoding; | ||
|
|
||
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
|
|
||
| import static org.hamcrest.Matchers.closeTo; | ||
|
|
||
| public class ES93Int8FlatBFloat16VectorFormatTests extends ES93Int8FlatVectorFormatTests { | ||
| @Override | ||
| boolean useBFloat16() { | ||
| return true; | ||
| } | ||
|
|
||
| @Override | ||
| protected VectorEncoding randomVectorEncoding() { | ||
| return VectorEncoding.FLOAT32; | ||
| } | ||
|
|
||
| @Override | ||
| public void testEmptyByteVectorData() throws Exception { | ||
| // no bytes | ||
| } | ||
|
|
||
| @Override | ||
| public void testMergingWithDifferentByteKnnFields() throws Exception { | ||
| // no bytes | ||
| } | ||
|
|
||
| @Override | ||
| public void testByteVectorScorerIteration() throws Exception { | ||
| // no bytes | ||
| } | ||
|
|
||
| @Override | ||
| public void testSortedIndexBytes() throws Exception { | ||
| // no bytes | ||
| } | ||
|
|
||
| @Override | ||
| public void testMismatchedFields() throws Exception { | ||
| // no bytes | ||
| } | ||
|
|
||
| @Override | ||
| public void testRandomBytes() throws Exception { | ||
| // no bytes | ||
| } | ||
|
|
||
| @Override | ||
| public void testWriterRamEstimate() throws Exception { | ||
| // estimate is different due to bfloat16 | ||
| } | ||
|
|
||
| @Override | ||
| public void testRandom() throws Exception { | ||
| AssertionError err = expectThrows(AssertionError.class, super::testRandom); | ||
| assertFloatsWithinBounds(err); | ||
| } | ||
|
|
||
| @Override | ||
| public void testRandomWithUpdatesAndGraph() throws Exception { | ||
| AssertionError err = expectThrows(AssertionError.class, super::testRandomWithUpdatesAndGraph); | ||
| assertFloatsWithinBounds(err); | ||
| } | ||
|
|
||
| @Override | ||
| public void testSparseVectors() throws Exception { | ||
| AssertionError err = expectThrows(AssertionError.class, super::testSparseVectors); | ||
| assertFloatsWithinBounds(err); | ||
| } | ||
|
|
||
| @Override | ||
| public void testVectorValuesReportCorrectDocs() throws Exception { | ||
| AssertionError err = expectThrows(AssertionError.class, super::testVectorValuesReportCorrectDocs); | ||
| assertFloatsWithinBounds(err); | ||
| } | ||
|
|
||
| private static final Pattern FLOAT_ASSERTION_FAILURE = Pattern.compile(".*expected:<([0-9.-]+)> but was:<([0-9.-]+)>"); | ||
|
|
||
| private static void assertFloatsWithinBounds(AssertionError error) { | ||
| Matcher m = FLOAT_ASSERTION_FAILURE.matcher(error.getMessage()); | ||
| if (m.matches() == false) { | ||
| throw error; // nothing to do with us, just rethrow | ||
| } | ||
|
|
||
| // numbers just need to be in the same vicinity | ||
| double expected = Double.parseDouble(m.group(1)); | ||
| double actual = Double.parseDouble(m.group(2)); | ||
| double allowedError = expected * 0.01; // within 1% | ||
| assertThat(error.getMessage(), actual, closeTo(expected, allowedError)); | ||
| } | ||
| } |
77 changes: 77 additions & 0 deletions
77
...c/test/java/org/elasticsearch/index/codec/vectors/es93/ES93Int8FlatVectorFormatTests.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the "Elastic License | ||
| * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| package org.elasticsearch.index.codec.vectors.es93; | ||
|
|
||
| import org.apache.lucene.codecs.Codec; | ||
| import org.apache.lucene.codecs.KnnVectorsReader; | ||
| import org.apache.lucene.codecs.perfield.PerFieldKnnVectorsFormat; | ||
| import org.apache.lucene.document.Document; | ||
| import org.apache.lucene.document.KnnFloatVectorField; | ||
| import org.apache.lucene.index.CodecReader; | ||
| import org.apache.lucene.index.DirectoryReader; | ||
| import org.apache.lucene.index.IndexReader; | ||
| import org.apache.lucene.index.IndexWriter; | ||
| import org.apache.lucene.index.LeafReader; | ||
| import org.apache.lucene.store.Directory; | ||
| import org.apache.lucene.tests.index.BaseKnnVectorsFormatTestCase; | ||
| import org.apache.lucene.tests.util.TestUtil; | ||
| import org.elasticsearch.common.logging.LogConfigurator; | ||
| import org.elasticsearch.index.codec.vectors.BFloat16; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| import static org.apache.lucene.index.VectorSimilarityFunction.DOT_PRODUCT; | ||
|
|
||
| public class ES93Int8FlatVectorFormatTests extends BaseKnnVectorsFormatTestCase { | ||
|
|
||
| static { | ||
| LogConfigurator.loadLog4jPlugins(); | ||
| LogConfigurator.configureESLogging(); // native access requires logging to be initialized | ||
| } | ||
|
|
||
| boolean useBFloat16() { | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| protected Codec getCodec() { | ||
| return TestUtil.alwaysKnnVectorsFormat(new ES93Int8FlatVectorFormat(useBFloat16())); | ||
| } | ||
|
|
||
| public void testSearchWithVisitedLimit() { | ||
| // requires graph vector codec | ||
| } | ||
|
|
||
| public void testSimpleOffHeapSize() throws IOException { | ||
| float[] vector = randomVector(random().nextInt(12, 500)); | ||
| try (Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig())) { | ||
| Document doc = new Document(); | ||
| doc.add(new KnnFloatVectorField("f", vector, DOT_PRODUCT)); | ||
| w.addDocument(doc); | ||
| w.commit(); | ||
| try (IndexReader reader = DirectoryReader.open(w)) { | ||
| LeafReader r = getOnlyLeafReader(reader); | ||
| if (r instanceof CodecReader codecReader) { | ||
| KnnVectorsReader knnVectorsReader = codecReader.getVectorReader(); | ||
| if (knnVectorsReader instanceof PerFieldKnnVectorsFormat.FieldsReader fieldsReader) { | ||
| knnVectorsReader = fieldsReader.getFieldReader("f"); | ||
| } | ||
| var fieldInfo = r.getFieldInfos().fieldInfo("f"); | ||
| var offHeap = knnVectorsReader.getOffHeapByteSize(fieldInfo); | ||
| assertEquals(2, offHeap.size()); | ||
| int bytes = useBFloat16() ? BFloat16.BYTES : Float.BYTES; | ||
| assertEquals(vector.length * bytes, (long) offHeap.get("vec")); | ||
| assertTrue(offHeap.get("veq") > 0L); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.