Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions _includes/code/csharp/ConfigureRQTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,35 @@ await client.Collections.Create(
// END EnableRQ
}

[Fact]
public async Task Test4BitEnableRQ()
{
// START 4BitEnableRQ
await client.Collections.Create(
new CollectionCreateParams
{
Name = "MyCollection",
Properties = [Property.Text("title")],
VectorConfig = Configure.Vector(
"default",
v => v.Text2VecTransformers(),
index: new VectorIndex.HNSW
{
// highlight-start
Quantizer = new VectorIndex.Quantizers.RQ
{
Bits = 4,
// Raise the rescore limit; the default of 20 is too low for 4-bit RQ
RescoreLimit = 50,
},
// highlight-end
}
),
}
);
// END 4BitEnableRQ
}

[Fact]
public async Task Test1BitEnableRQ()
{
Expand Down Expand Up @@ -157,6 +186,29 @@ await collection.Config.Update(c =>
// END UpdateSchema
}

[Fact]
public async Task Test4BitUpdateSchema()
{
var collection = await client.Collections.Create(
new CollectionCreateParams
{
Name = "MyCollection",
Properties = [Property.Text("title")],
VectorConfig = Configure.Vector("default", v => v.Text2VecTransformers()),
}
);

// START 4BitUpdateSchema
await collection.Config.Update(c =>
{
var vectorConfig = c.VectorConfig["default"];
vectorConfig.VectorIndexConfig.UpdateHNSW(h =>
h.Quantizer = new VectorIndex.Quantizers.RQ { Bits = 4, RescoreLimit = 50 }
);
});
// END 4BitUpdateSchema
}

[Fact]
public async Task Test1BitUpdateSchema()
{
Expand Down
28 changes: 26 additions & 2 deletions _includes/code/howto/configure-rq/rq-compression-v3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
// ==============================

import assert from 'assert';
// START EnableRQ // START 1BitEnableRQ // START RQWithOptions // START Uncompressed
// START EnableRQ // START 4BitEnableRQ // START 1BitEnableRQ // START RQWithOptions // START Uncompressed
import weaviate, { configure } from 'weaviate-client';
// END EnableRQ // END 1BitEnableRQ // END RQWithOptions // END Uncompressed
// END EnableRQ // END 4BitEnableRQ // END 1BitEnableRQ // END RQWithOptions // END Uncompressed


const client = await weaviate.connectToLocal({
Expand Down Expand Up @@ -39,6 +39,30 @@ await client.collections.create({
})
// END EnableRQ

// ==============================
// ===== EnableRQ 4-BIT ========
// ==============================

await client.collections.delete("MyCollection")

// START 4BitEnableRQ

await client.collections.create({
name: "MyCollection",
vectorizers: configure.vectors.text2VecOpenAI({
// highlight-start
quantizer: configure.vectorIndex.quantizer.rq({
bits: 4,
rescoreLimit: 50, // Raise the rescore limit; the default of 20 is too low for 4-bit RQ
})
// highlight-end
}),
properties: [
{ name: "title", dataType: weaviate.configure.dataType.TEXT }
]
})
// END 4BitEnableRQ

// ==============================
// ===== EnableRQ 1-BIT ========
// ==============================
Expand Down
57 changes: 57 additions & 0 deletions _includes/code/howto/configure-rq/rq-compression-v4.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,31 @@
)
# END EnableRQ

# ==============================
# ===== EnableRQ 4-BIT ========
# ==============================

client.collections.delete("MyCollection")

# START 4BitEnableRQ
from weaviate.classes.config import Configure, Property, DataType

client.collections.create(
name="MyCollection",
vector_config=Configure.Vectors.text2vec_openai(
# highlight-start
quantizer=Configure.VectorIndex.Quantizer.rq(
bits=4,
rescore_limit=50, # Raise the rescore limit; the default of 20 is too low for 4-bit RQ
)
# highlight-end
),
properties=[
Property(name="title", data_type=DataType.TEXT),
],
)
# END 4BitEnableRQ

# ==============================
# ===== EnableRQ 1-BIT ========
# ==============================
Expand Down Expand Up @@ -145,6 +170,38 @@
)
# END UpdateSchema

# ================================
# ===== UPDATE SCHEMA 4-BIT =====
# ================================

client.collections.delete("MyCollection")
client.collections.create(
name="MyCollection",
vector_config=Configure.Vectors.text2vec_openai(
quantizer=Configure.VectorIndex.Quantizer.none(),
),
properties=[
Property(name="title", data_type=DataType.TEXT),
],
)

# START 4BitUpdateSchema
from weaviate.classes.config import Reconfigure

collection = client.collections.use("MyCollection")
collection.config.update(
vector_config=Reconfigure.Vectors.update(
name="default",
vector_index_config=Reconfigure.VectorIndex.hnsw(
quantizer=Reconfigure.VectorIndex.Quantizer.rq(
bits=4,
rescore_limit=50,
),
),
)
)
# END 4BitUpdateSchema

# ================================
# ===== UPDATE SCHEMA 1-BIT =====
# ================================
Expand Down
127 changes: 125 additions & 2 deletions _includes/code/howto/go/docs/configure/compression.rq_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,59 @@ func TestRQConfiguration(t *testing.T) {
assert.Equal(t, true, rqConfig["enabled"])
})

t.Run("Enable 4-bit RQ", func(t *testing.T) {
className := "MyCollectionRQDefault"
// Delete the collection if it already exists to ensure a clean start
err := client.Schema().ClassDeleter().WithClassName(className).Do(context.Background())
if err != nil {
// This is not a fatal error, the collection might not exist
log.Printf("Could not delete collection '%s', it might not exist: %v\n", className, err)
}

// START 4BitEnableRQ
// Define the configuration for RQ. 'bits' set to 4 requires an hnsw index
// highlight-start
rq_config := map[string]interface{}{
"enabled": true,
"bits": 4,
// Raise the rescore limit; the default of 20 is too low for 4-bit RQ
"rescoreLimit": 50,
}
// highlight-end

// Define the class schema
class := &models.Class{
Class: className,
Vectorizer: "text2vec-openai",
// highlight-start
// Assign the RQ configuration to the vector index config
VectorIndexConfig: map[string]interface{}{
"rq": rq_config,
},
// highlight-end
}

// Create the collection in Weaviate
err = client.Schema().ClassCreator().
WithClass(class).
Do(context.Background())
// END 4BitEnableRQ
require.NoError(t, err)

// Assertions to verify the configuration
classInfo, err := client.Schema().ClassGetter().WithClassName(className).Do(ctx)
require.NoError(t, err)
require.NotNil(t, classInfo)

vic, ok := classInfo.VectorIndexConfig.(map[string]interface{})
require.True(t, ok)
rqConfig, ok := vic["rq"].(map[string]interface{})
require.True(t, ok)
assert.Equal(t, true, rqConfig["enabled"])
assert.Equal(t, float64(4), rqConfig["bits"])
assert.Equal(t, float64(50), rqConfig["rescoreLimit"])
})

t.Run("Enable 1-bit RQ", func(t *testing.T) {
className := "MyCollectionRQDefault"
// Delete the collection if it already exists to ensure a clean start
Expand Down Expand Up @@ -214,7 +267,7 @@ func TestRQConfiguration(t *testing.T) {
Do(context.Background())
require.NoError(t, err)

// START UpdateSchemaToEnableRQ
// START 8BitUpdateSchema
// Get the existing collection configuration
class, err := client.Schema().ClassGetter().
WithClassName(className).Do(context.Background())
Expand All @@ -241,7 +294,7 @@ func TestRQConfiguration(t *testing.T) {
if err != nil {
log.Fatalf("update class to use rq: %v", err)
}
// END UpdateSchemaToEnableRQ
// END 8BitUpdateSchema

// Verify the RQ configuration was applied
updatedClass, err := client.Schema().ClassGetter().
Expand All @@ -257,6 +310,76 @@ func TestRQConfiguration(t *testing.T) {
assert.Equal(t, float64(20), rqConfig["rescoreLimit"])
})

t.Run("Enable 4-bit RQ on Existing Collection", func(t *testing.T) {
className := "MyExistingCollection"

// First, create a collection without RQ
err := client.Schema().ClassDeleter().WithClassName(className).Do(context.Background())
if err != nil {
log.Printf("Could not delete collection '%s', it might not exist: %v\n", className, err)
}

// Create initial collection without RQ
initialClass := &models.Class{
Class: className,
Vectorizer: "text2vec-openai",
VectorIndexConfig: map[string]interface{}{
"distance": "cosine",
},
}

err = client.Schema().ClassCreator().
WithClass(initialClass).
Do(context.Background())
require.NoError(t, err)

// START 4BitUpdateSchema
// Get the existing collection configuration
class, err := client.Schema().ClassGetter().
WithClassName(className).Do(context.Background())

if err != nil {
log.Fatalf("get class for vec idx cfg update: %v", err)
}

// Get the current vector index configuration
cfg := class.VectorIndexConfig.(map[string]interface{})

// Add RQ configuration to enable 4-bit quantization
cfg["rq"] = map[string]interface{}{
"enabled": true,
"bits": 4,
// Raise the rescore limit; the default of 20 is too low for 4-bit RQ
"rescoreLimit": 50,
}

// Update the class configuration
class.VectorIndexConfig = cfg

// Apply the updated configuration to the collection
err = client.Schema().ClassUpdater().
WithClass(class).Do(context.Background())

if err != nil {
log.Fatalf("update class to use rq: %v", err)
}
// END 4BitUpdateSchema

// Verify the RQ configuration was applied
updatedClass, err := client.Schema().ClassGetter().
WithClassName(className).Do(context.Background())
require.NoError(t, err)

vic, ok := updatedClass.VectorIndexConfig.(map[string]interface{})
require.True(t, ok)

rqConfig, ok := vic["rq"].(map[string]interface{})
require.True(t, ok)
assert.Equal(t, true, rqConfig["enabled"])
assert.Equal(t, float64(4), rqConfig["bits"])
assert.Equal(t, float64(50), rqConfig["rescoreLimit"])
})

t.Run("Enable 1-bit RQ on Existing Collection", func(t *testing.T) {
className := "MyExistingCollection"

Expand Down
38 changes: 38 additions & 0 deletions _includes/code/java-v6/src/test/java/ConfigureRQTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,23 @@ void testEnableRQ() throws IOException {
// END EnableRQ
}

@Test
void test4BitEnableRQ() throws IOException {
String collectionName = "MyCollection";
if (client.collections.exists(collectionName)) {
client.collections.delete(collectionName);
}

// START 4BitEnableRQ
client.collections.create("MyCollection",
col -> col.vectorConfig(VectorConfig.text2vecTransformers(vc -> vc
// highlight-start
.quantization(Quantization.rq(q -> q.bits(4)))
// highlight-end
)).properties(Property.text("title")));
// END 4BitEnableRQ
}

@Test
void test1BitEnableRQ() throws IOException {
String collectionName = "MyCollection";
Expand Down Expand Up @@ -121,6 +138,27 @@ void testUpdateSchema() throws IOException {
// END UpdateSchema
}

@Test
void test4BitUpdateSchema() throws IOException {
String collectionName = "MyCollection";
if (client.collections.exists(collectionName)) {
client.collections.delete(collectionName);
}
client.collections.create(collectionName,
col -> col
.vectorConfig(VectorConfig.text2vecTransformers(
vc -> vc.quantization(Quantization.uncompressed())))
.properties(Property.text("title")));

// START 4BitUpdateSchema
CollectionHandle<Map<String, Object>> collection =
client.collections.use("MyCollection");
collection.config
.update(c -> c.vectorConfig(VectorConfig.text2vecTransformers(
vc -> vc.quantization(Quantization.rq(q -> q.bits(4))))));
// END 4BitUpdateSchema
}

@Test
void test1BitUpdateSchema() throws IOException {
String collectionName = "MyCollection";
Expand Down
4 changes: 2 additions & 2 deletions _includes/configuration/rq-compression-parameters.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
| Parameter | Type | Default | Details |
| :---------------------- | :------ | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rq`: `bits` | integer | `8` | The number of bits used to quantize each data point. Value can be `8` or `1`. <br/> <br/>Learn more about [8-bit](/weaviate/concepts/vector-quantization#8-bit-rq) and [1-bit](/weaviate/concepts/vector-quantization#1-bit-rq) RQ. |
| `rq`: `rescoreLimit` | integer | `20` (`hnsw`, 8-bit)<br/>`512` (`hnsw`, 1-bit)<br/>`-1` (`flat`) | The minimum number of candidates to fetch before rescoring. <br/><br/>The default depends on the vector index type, and under `hnsw` also on `bits`: `20` for 8-bit RQ and `512` for 1-bit RQ. Under the `flat` index type the default is `-1`, which lets Weaviate pick the limit. <br/><br/>These defaults apply to the `hnsw` and `flat` index types. For the HFresh index, see [HFresh index parameters](/weaviate/config-refs/indexing/vector-index#hfresh-index-parameters). |
| `rq`: `bits` | integer | `8` | The number of bits used to quantize each data point. Value can be `8`, `4` or `1`, but not every index type accepts all three. The `hnsw` index type accepts `8`, `4` and `1`. The `flat` index type accepts only `8` and `1`. The `hfresh` index type accepts only `1`. <br/><br/>This parameter is fixed once RQ is enabled and cannot be changed afterwards. <br/> <br/>Learn more about [8-bit](/weaviate/concepts/vector-quantization#8-bit-rq), [4-bit](/weaviate/concepts/vector-quantization#4-bit-rq) and [1-bit](/weaviate/concepts/vector-quantization#1-bit-rq) RQ. |
| `rq`: `rescoreLimit` | integer | `20` (`hnsw`, 8-bit and 4-bit)<br/>`512` (`hnsw`, 1-bit)<br/>`-1` (`flat`) | The minimum number of candidates to fetch before rescoring. Mutable at any time. <br/><br/>The default depends on the vector index type, and under `hnsw` also on `bits`: `20` for 8-bit and 4-bit RQ, and `512` for 1-bit RQ. Under the `flat` index type the default is `-1`, which lets Weaviate pick the limit. <br/><br/>4-bit RQ inherits the 8-bit default of `20`, which is lower than the value it needs. See [4-bit RQ](/weaviate/configuration/compression/rq-compression#4-bit-rq) for guidance. <br/><br/>The Java client sends this parameter under a field name that Weaviate does not read, so values set from that client are ignored and the server default applies. <br/><br/>These defaults apply to the `hnsw` and `flat` index types. For the HFresh index, see [HFresh index parameters](/weaviate/config-refs/indexing/vector-index#hfresh-index-parameters). |
| `rq` : `cache` | boolean | `false` | Whether to cache the vectors in memory.<br/> (only when using the `flat` vector index type) |
| `vectorCacheMaxObjects` | integer | `1e12` | Maximum number of objects in the memory cache. By default, this limit is set to one trillion (`1e12`) objects when a new collection is created. For sizing recommendations, see [Vector cache considerations](/weaviate/concepts/vector-index#vector-cache-considerations). |
Loading
Loading