You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The process of building an index involves two steps: partitioning the vector space first, and then inserting rows into the index. The first step, partitioning the vector space, can be sped up using multiple threads.
61
+
The process of building an index involves two steps: clustering the vectors first, and then inserting vectors into the index. The first step, clustering the vectors, can be sped up using multiple threads.
62
62
63
63
```sql
64
64
CREATEINDEXON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
65
65
[build.internal]
66
66
lists = [1000]
67
67
build_threads =8
68
68
$$);
69
-
70
-
SETvchordrq.probes TO '10';
71
-
SELECT*FROM items ORDER BY embedding <->'[3,1,2]'LIMIT10;
72
69
```
73
70
74
-
The second step, inserting rows, can be parallelized using multiple processes. Refer to [PostgreSQL Tuning](performance-tuning.md).
71
+
The second step, inserting vectors into the index, can be parallelized using the appropriate GUC parameter. Refer to [PostgreSQL Tuning](performance-tuning.md).
75
72
76
-
For most datasets using cosine similarity, enabling `residual_quantization` and `build.internal.spherical_centroids`improves both QPS and recall.
73
+
For most datasets using cosine similarity, enabling `residual_quantization` and `build.internal.spherical_centroids`may improve both QPS and recall. If possible, please verify this on data from the production environment.
77
74
78
75
```sql
79
76
CREATEINDEXON items USING vchordrq (embedding vector_cosine_ops) WITH (options = $$
@@ -83,27 +80,66 @@ lists = [1000]
83
80
spherical_centroids = true
84
81
build_threads =8
85
82
$$);
83
+
```
86
84
87
-
SETvchordrq.probes TO '10';
88
-
SELECT*FROM items ORDER BY embedding <=>'[3,1,2]'LIMIT10;
85
+
## Tuning: Improve build speed
86
+
87
+
For large tables (> 50 million rows), the `build.internal` process requires significant time and memory. Let the vector dimension be $D$, `build.internal.lists[-1]` be $C$, `build.internal.sampling_factor` be $F$, `build.internal.kmeans_iterations` be $L$, and `build.internal.build_threads` be $T$.
88
+
89
+
* The memory consumption is approximately $4CD(F + T + 1)$ bytes, which usually takes more than 128 GB.
90
+
* The build time is approximately $O(FC^2DL)$, which usually takes more than one day.
91
+
92
+
To improve the build speed, you may opt to use more shared memory to accelerate the process by setting `build.pin` to `2`.
93
+
94
+
```sql
95
+
CREATEINDEXON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
96
+
build.pin=2
97
+
[build.internal]
98
+
lists = [160000]
99
+
build_threads =8
100
+
$$);
89
101
```
90
102
91
-
For large tables, you may opt to use more shared memory to accelerate the process by setting `build.pin` to `2`.
103
+
If the build speed is still unsatisfactory, you can use Hierarchical clustering to accelerate the process at the expense of some accuracy. In our benchmark, the Hierarchical clustering was 100 times faster than the default Lloyd clustering, while query accuracy decreased by less than 1%.
92
104
93
105
```sql
94
106
CREATEINDEXON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
95
-
residual_quantization = true
96
107
build.pin=2
97
108
[build.internal]
98
-
lists = [1000]
99
-
spherical_centroids = true
109
+
lists = [160000]
100
110
build_threads =8
111
+
kmeans_algorithm.hierarchical= {}
101
112
$$);
102
113
```
103
114
104
-
For large tables, the `build.internal` process costs significant time and memory. Let `build.internal.kmeans_dimension` or the dimension be $D$, `build.internal.lists[-1]` be $C$, `build.internal.sampling_factor` be $F$, and `build.internal.build_threads` be $T$. The memory consumption is approximately $4CD(F + T + 1)$ bytes. You can moderately reduce these options for lower memory usage.
115
+
## Tuning: Save more memory
116
+
117
+
As we discussed, these parameters determine the memory usage during the index build $4CD(F + T + 1)$:
118
+
119
+
* D: Vector dimension, or `build.internal.kmeans_dimension` if set
120
+
* C: `build.internal.lists[-1]`
121
+
* F: `build.internal.sampling_factor`
122
+
* T: `build.internal.build_threads`
123
+
124
+
If you encounter an Out-of-Memory (OOM) error, reducing these parameters will lower memory usage. Based on our experience, reducing D will have the least impact on accuracy, so that could be a good starting point. Decreasing `F` is also plausible next. Since `C` is much more sensitive, it should be the last thing you consider.
125
+
126
+
For your reference, this configuration has little impact on query accuracy (less than 1%):
127
+
* Reduce `D` from 768 to 100
128
+
* Reduce `F` from 256 to 64
129
+
130
+
```sql
131
+
CREATEINDEXON items USING vchordrq (embedding vector_l2_ops) WITH (options = $$
132
+
build.pin=2
133
+
[build.internal]
134
+
lists = [160000]
135
+
build_threads =8
136
+
kmeans_algorithm.hierarchical= {}
137
+
kmeans_dimension =100
138
+
sampling_factor =64
139
+
$$);
140
+
```
105
141
106
-
You can also refer to [External Build](external-index-precomputation) to offload the indexing workload to other machines.
142
+
If the decrease in accuracy is unacceptable, you can also refer to [External Build](external-index-precomputation) to offload the indexing workload to other machines.
0 commit comments