Topik ini menyajikan benchmark kinerja ekstensi pgvector dengan indeks HNSW pada instans ApsaraDB RDS for PostgreSQL. Benchmark menggunakan tool ann-benchmarks untuk mengevaluasi kinerja implementasi RDS dibandingkan dengan versi komunitas berdasarkan metrik utama seperti tingkat recall, permintaan per detik (QPS), dan waktu pembuatan indeks.
Lingkungan pengujian
Untuk menghindari ketidakakuratan akibat fluktuasi jaringan, tempatkan instans RDS PostgreSQL dan instans ECS client dalam Virtual Private Cloud (VPC) dan VSwitch yang sama.
|
Komponen |
Deskripsi |
|
RDS PostgreSQL instance |
|
|
ECS instance |
|
|
Test tool |
Penting
Secara default, ANN-Benchmarks menguji kinerja single-threaded. Untuk menguji kinerja konkuren instans, lihat pgvector performance test (based on an IVF index). |
Prasyarat
RDS for PostgreSQL instance
-
Buat akun berhak istimewa tinggi bernama
ann_testuserdan database uji bernamaann_testdb. Untuk informasi lebih lanjut, lihat Create accounts and databases. -
Instal plugin pgvector (vector) di database
ann_testdb. Untuk informasi lebih lanjut, lihat Manage plugins.
Client ECS instance
-
Instal Docker. Untuk informasi lebih lanjut, lihat Install Docker.
-
Jalankan perintah berikut untuk mengunduh tool ann-benchmarks.
cd ~ git clone https://github.com/erikbern/ann-benchmarks.git -
Jalankan perintah berikut untuk membuat dan mengaktifkan lingkungan virtual Python 3.10.6 bernama
ann_testmenggunakan Conda.yum install git yum install conda conda create -n ann_test python=3.10.6 conda init bash source /usr/etc/profile.d/conda.sh conda activate ann_test -
Jalankan perintah berikut untuk menginstal dependensi ann-benchmarks.
cd ~/ann-benchmarks/ pip install -r requirements.txt
Prosedur pengujian
Semua langkah dalam prosedur ini dilakukan di lingkungan virtual ann_test. Jika sesi timeout atau keluar karena alasan apa pun, gunakan perintah conda activate ann_test untuk masuk kembali ke lingkungan tersebut.
Langkah 1: Konfigurasikan pengaturan koneksi
Edit file ~/ann-benchmarks/ann_benchmarks/algorithms/pgvector/module.py dalam tool benchmark untuk menambahkan pengaturan koneksi berikut. Isi nilai-nilai tersebut berdasarkan lingkungan aktual Anda.
# Setel parameter koneksi untuk PostgreSQL
os.environ['ANN_BENCHMARKS_PG_USER'] = 'ann_testuser' # Pengguna untuk instans RDS PostgreSQL
os.environ['ANN_BENCHMARKS_PG_PASSWORD'] = 'testPawword' # Kata sandi pengguna RDS PostgreSQL
os.environ['ANN_BENCHMARKS_PG_DBNAME'] = 'ann_testdb' # Nama database instans RDS PostgreSQL
os.environ['ANN_BENCHMARKS_PG_HOST'] = 'pgm-****.pg.rds.aliyuncs.com' # Titik akhir internal instans RDS PostgreSQL
os.environ['ANN_BENCHMARKS_PG_PORT'] = '5432' # Nomor port internal instans RDS PostgreSQL
os.environ['ANN_BENCHMARKS_PG_START_SERVICE'] = 'false' # Nonaktifkan startup layanan otomatis
Langkah 2: Konfigurasikan parameter pengujian ann-benchmarks
Berdasarkan kebutuhan pengujian Anda, edit file ~/ann-benchmarks/ann_benchmarks/algorithms/pgvector/config.yml dalam tool benchmark. Contohnya:
float:
any:
- base_args: ['@metric']
constructor: PGVector
disabled: false
docker_tag: ann-benchmarks-pgvector
module: ann_benchmarks.algorithms.pgvector
name: pgvector
run_groups:
M-16(100):
arg_groups: [{M: 16, efConstruction: 100}]
args: {}
query_args: [[10, 20, 40, 80, 120, 200, 400, 800]]
M-16(200):
arg_groups: [{M: 16, efConstruction: 200}]
args: {}
query_args: [[10, 20, 40, 80, 120, 200, 400, 800]]
M-24(200):
arg_groups: [{M: 24, efConstruction: 200}]
args: {}
query_args: [[10, 20, 40, 80, 120, 200, 400, 800]]
Pengujian ini dibagi menjadi tiga kelompok: M-16(100), M-16(200), dan M-24(200). Setiap kelompok pengujian menggunakan arg_groups untuk mengonfigurasi parameter pembuatan indeks HNSW dan query_args untuk mengonfigurasi parameter pengambilan.
|
Parameter |
Deskripsi |
|
|
arg_groups |
M |
Berkorespondensi dengan parameter Nilai yang lebih besar meningkatkan kerapatan graf, yang umumnya meningkatkan recall tetapi juga meningkatkan waktu pembuatan dan kueri indeks. |
|
efConstruction |
Berkorespondensi dengan parameter Nilai yang lebih besar umumnya meningkatkan recall tetapi juga meningkatkan waktu pembuatan dan kueri indeks. |
|
|
query_args |
ef_search |
Pengaturan waktu kueri yang menentukan ukuran set kandidat yang dipertahankan selama proses pencarian. Nilai yang lebih besar umumnya meningkatkan recall tetapi juga meningkatkan waktu kueri. |
Langkah 3: Bangun image Docker pengujian
-
(Opsional) Untuk melewati pengujian versi komunitas PostgreSQL (default), ubah file
~/ann-benchmarks/ann_benchmarks/algorithms/pgvector/Dockerfilesebagai berikut:FROM ann-benchmarks USER root RUN pip install psycopg[binary] pgvector -
Jalankan install.py dengan
--algorithm pgvectoruntuk membangun image Docker pengujian.cd ~/ann-benchmarks/ python install.py --algorithm pgvectorCatatanUntuk melihat parameter yang didukung, jalankan
python install.py --help.
Langkah 4: Dapatkan dataset
Skrip benchmark secara otomatis mengunduh dataset publik yang ditentukan.
Topik ini menggunakan dataset nytimes-256-angular, yang menggunakan tipe jarak Angular, sebagai contoh pencarian kemiripan teks. Untuk dataset publik lainnya, lihat ann-benchmarks.
|
Dataset |
Dimensi |
Jumlah baris |
Vektor uji |
Tetangga Top-N |
Tipe jarak |
|
NYTimes |
256 |
290.000 |
10.000 |
100 |
Angular |
Jika dataset publik tidak memenuhi kebutuhan pengujian Anda, kami sarankan mengonversi data vektor aktual Anda ke format standar seperti HDF5 untuk menguji kinerja pengambilan. Untuk informasi lebih lanjut, lihat Appendix II: Custom Test Datasets.
Langkah 5: Jalankan pengujian dan dapatkan hasil
-
Gunakan perintah berikut untuk menjalankan skrip benchmark.
cd ~/ann-benchmarks nohup python run.py --dataset nytimes-256-angular -k 10 --algorithm pgvector --runs 1 > ann_benchmark_test.log 2>&1 & tail -f ann_benchmark_test.logParameter
Deskripsi
--dataset
Menentukan dataset yang akan diuji.
--k
Nilai LIMIT dalam Pernyataan SQL kueri, yaitu jumlah hasil yang dikembalikan.
--algorithm
Algoritma database vektor yang diuji. Atur ke pgvector untuk pengujian ini.
--runs
Jumlah kali pengujian dijalankan. Hasil terbaik dari semua percobaan dipilih.
--parallelism
Konkurensi pengujian. Nilai default adalah 1.
-
Jalankan perintah berikut untuk menghasilkan plot hasil pengujian.
cd ~/ann-benchmarks python plot.py --dataset nytimes-256-angular --recomputeFokuskan pada metrik pembuatan indeks dan peningkatan kinerja pada recall yang sama.
Perbandingan pembuatan indeks:
Tipe indeks
Waktu pembuatan (s)
Ukuran indeks
HNSW community version (v0.8.0)
127,89
7820MB
HNSW RDS version (v0.8.0.1)
77,72
3916MB
Perbandingan QPS pada recall yang sama:
Recall
Parameter HNSW v0.8.0
Parameter HNSW v0.8.0.1
QPS v0.8.0
QPS v0.8.0.1
97%
ef_search=10
ef_search=10
1635,41
1954,48
98%
ef_search=30
ef_search=20
1075,49
1379,61
99,3%
ef_search=120
ef_search=80
434,74
737,06
99,5%
ef_search=300
ef_search=350
200,06
319,19
99,6%
ef_search=500
ef_search=500
109,51
177,94
-
(Opsional) Jalankan perintah berikut untuk mengekspor hasil pengujian detail ke file CSV.
cd ~/ann-benchmarks python data_export.py --out res.csvSebagai contoh, Anda dapat menganalisis hubungan antara parameter
m,ef_construction, dan waktu pembuatan indeks:m
ef_construction
Waktu pembuatan (s)
16
100
33,35161
16
200
57,66014
24
200
87,22608
Kesimpulan
Saat Anda membangun indeks HNSW:
-
Menambah nilai
m,ef_construction, danef_searchdapat meningkatkan tingkat recall, tetapi akan menurunkan QPS. -
Menambah nilai
mdanef_constructionjuga meningkatkan tingkat recall, sekaligus menurunkan QPS dan meningkatkan waktu pembuatan indeks. -
Jika aplikasi Anda memerlukan tingkat recall yang tinggi, hindari parameter indeks default (m=16, ef_construction=64, dan ef_search=40).
Apendiks I: RDS for PostgreSQL: Dampak parameter terhadap pembuatan indeks
Apendiks ini menggunakan hasil pengujian ann-benchmarks untuk menunjukkan bagaimana berbagai parameter RDS for PostgreSQL dan vektor memengaruhi pembuatan indeks.
RDS for PostgreSQL: Dampak parameter terhadap pembuatan indeks
Sebagai contoh, ketika parameter pengujian ann-benchmarks diatur ke m=16 dan efConstruction=64, parameter RDS for PostgreSQL memengaruhi pembuatan indeks sebagai berikut.
-
maintenance_work_mem
Parameter ini menentukan memori maksimum dalam kilobita (KB) untuk operasi maintenance, seperti
VACUUMdanCREATE INDEX. Ketika nilaimaintenance_work_memlebih kecil daripada ukuran dataset, menaikkannya akan mengurangi waktu pembuatan indeks. Namun, begitu nilainya melebihi ukuran dataset, waktu pembuatan tidak lagi berkurang.Sebagai contoh, pada instans RDS for PostgreSQL tipe pg.x8.2xlarge.2c (16 core, 128 GB), dengan parameter
max_parallel_maintenance_workersdiatur ke nilai default 8 dan menggunakan dataset nytimes-256-angular (sekitar 324 MB), parametermaintenance_work_memmemengaruhi pembuatan indeks sebagai berikut:maintenance_work_mem
Waktu pembuatan indeks (s)
64 MB (65536 KB)
52,82
128 MB (131072 KB)
46,79
256 MB (262144 KB)
36,40
512 MB (524288 KB)
18,90
1 GB (1048576 KB)
19,06
-
max_parallel_maintenance_workers
Parameter ini mengatur jumlah maksimum Parallel Worker untuk
CREATE INDEX. Waktu pembuatan indeks berkurang seiring peningkatanmax_parallel_maintenance_workers.Sebagai contoh, pada instans RDS for PostgreSQL tipe pg.x8.2xlarge.2c (16 core, 128 GB), dengan parameter
maintenance_work_memdiatur ke 2 GB (2048 MB) dan menggunakan dataset nytimes-256-angular (sekitar 324 MB), parametermax_parallel_maintenance_workersmemengaruhi pembuatan indeks sebagai berikut:max_parallel_maintenance_workers
Waktu pembuatan indeks (s)
1
76,00
2
51,34
4
32,49
8
19,66
12
14,44
16
13,07
24
13,15
Dampak parameter vektor terhadap pembuatan indeks
Dengan parameter RDS for PostgreSQL diatur ke maintenance_work_mem=8 GB (8388608 KB) dan max_parallel_maintenance_workers=16, bagian berikut menunjukkan dampak parameter vektor terhadap pembuatan indeks.
-
Dimensi vektor
Pengujian berikut menggunakan dataset GloVe (1.183.514 vektor) dengan parameter pengujian ann-benchmarks diatur ke
m=16,efConstruction=64, danef_search=40. Hasilnya menunjukkan bahwa semakin besar dimensi vektor, waktu pembuatan indeks dan latensi kueri juga meningkat, sementara recall dan QPS menurun.Dimensi
Waktu pembuatan (s)
Recall
QPS
p99 (ms)
25
195,10
0,99985
192,94
7,84
50
236,92
0,99647
152,36
9,69
100
319,36
0,97231
126,89
11,14
200
529,33
0,93186
95,05
15,11
CatatanPersentil ke-99 dari latensi kueri. Artinya, 99% permintaan kueri selesai dalam waktu kurang dari nilai ini, dan hanya 1% yang memakan waktu lebih lama.
-
Jumlah vektor
Pengujian ini menggunakan rangkaian dataset
dbpedia-openai-{n}k-angular, di mananmerepresentasikan jumlah vektor dalam ribuan (dari 100 hingga 1.000). Ketika parameter pengujian ann-benchmarks diatur kem=48,efConstruction=256, danef_search=200, hasil pengujian adalah sebagai berikut. Hasilnya menunjukkan bahwa waktu pembuatan indeks meningkat secara non-linear seiring pertumbuhan jumlah vektor, sementara recall dan QPS menurun serta latensi kueri meningkat.Jumlah vektor
Jumlah baris (x10.000)
Waktu pembuatan (s)
Recall
QPS
p99 (ms)
100
10
54,05
0,9993
171,74
8,93
200
20
137,23
0,99901
146,78
10,81
500
50
436,68
0,999
118,55
13,94
1000
100
957,26
0,99879
101,60
16,35
Apendiks II: Dataset pengujian kustom
Contoh berikut menunjukkan cara membuat dataset berdasarkan format data nytimes-256-angular.
-
Jalankan skrip berikut untuk membuat dataset pengujian kustom.
CatatanContoh ini memerlukan ekstensi rds_ai. Untuk informasi lebih lanjut, lihat AI (rds_ai).
import h5py import numpy as np import psycopg2 import pgvector.psycopg2 # Detail koneksi conn_info = { 'host': 'pgm-****.rds.aliyuncs.com', 'user': 'ann_testuser', 'password': '****', 'port': '5432', 'dbname': 'ann_testdb' } embedding_len = 1024 distance_top_n = 100 query_batch_size = 100 try: # Hubungkan ke database RDS for PostgreSQL with psycopg2.connect(**conn_info) as connection: pgvector.psycopg2.register_vector(connection) with connection.cursor() as cur: # Ambil data vektor cur.execute("select count(1) from test_rag") count = cur.fetchone()[0] train_embeddings = [] for start in range(0, count, query_batch_size): query = f"SELECT embedding FROM test_rag ORDER BY id OFFSET {start} LIMIT {query_batch_size}" cur.execute(query) res = [embedding[0] for embedding in cur.fetchall()] train_embeddings.extend(res) train = np.array(train_embeddings) # Dapatkan data kueri dan hitung penyematan with open('query.txt', 'r', encoding='utf-8') as file: queries = [query.strip() for query in file] test = [] # Instal ekstensi rds_ai atau gunakan SDK Alibaba Cloud Model Studio for query in queries: cur.execute(f"SELECT rds_ai.embed('{query.strip()}')::vector(1024)") test.extend([cur.fetchone()[0]]) test = np.array(test) # Hitung jarak tetangga terdekat top N dot_product = np.dot(test, train.T) norm_test = np.linalg.norm(test, axis=1, keepdims=True) norm_train = np.linalg.norm(train, axis=1, keepdims=True) similarity = dot_product / (norm_test * norm_train.T) distance_matrix = 1 - similarity neighbors = np.argsort(distance_matrix, axis=1)[:, :distance_top_n] distances = np.take_along_axis(distance_matrix, neighbors, axis=1) with h5py.File('custom_dataset.hdf5', 'w') as f: f.create_dataset('distances', data=distances) f.create_dataset('neighbors', data=neighbors) f.create_dataset('test', data=test) f.create_dataset('train', data=train) f.attrs.update({ "type": "dense", "distance": "angular", "dimension": embedding_len, "point_type": "float" }) print("File HDF5 berhasil dibuat dan dataset telah ditambahkan.") except (Exception, psycopg2.DatabaseError) as error: print(f"Error: {error}") -
Daftarkan dataset pengujian kustom Anda di bagian
DATASETSpada file~/ann-benchmarks/ann_benchmarks/datasets.py.DATASETS: Dict[str, Callable[[str], None]] = { ......, "<custom_dataset>": None, } -
Unggah dataset pengujian kustom ke direktori
~/ann-benchmarks. Anda kemudian dapat menggunakan dataset tersebut dengan skrip pengujianrun.py.