Mengaktifkan dan menggunakan ekstensi DiskANN

DiskANN adalah algoritma pencarian tetangga terdekat secara perkiraan yang dapat diskalakan untuk pencarian vektor yang efisien pada skala berapapun. Ini menawarkan pengenalan tinggi, kueri tinggi per detik, dan latensi kueri rendah, bahkan untuk himpunan data miliaran titik. Karakteristik tersebut menjadikannya alat yang kuat untuk menangani data dalam volume besar.

Untuk mempelajari selengkapnya tentang DiskANN, lihat DiskANN: Pencarian Vektor untuk Pencarian dan Rekomendasi Skala Web.

pg_diskann Ekstensi menambahkan dukungan untuk menggunakan DiskANN untuk pengindeksan dan pencarian vektor yang efisien.

Mengaktifkan pg_diskann

Untuk menggunakan pg_diskann ekstensi pada instans server fleksibel Azure Database for PostgreSQL, Anda perlu mengizinkan ekstensi di tingkat instans. Kemudian Anda perlu membuat ekstensi pada setiap database tempat Anda ingin menggunakan fungsionalitas yang disediakan oleh ekstensi.

Karena pg_diskann memiliki dependensi pada vector ekstensi, Anda dapat mengizinkan atau membuatvector ekstensi di database yang sama, lalu jalankan perintah berikut:

CREATE EXTENSION IF NOT EXISTS pg_diskann;

Atau Anda dapat melewatkan secara eksplisit untuk mengizinkan dan membuat ekstensi vector, dan menjalankan perintah sebelumnya dengan menambahkan klausa CASCADE. Klausa PostgreSQL untuk menjalankan CREATE EXTENSION secara implisit pada ekstensi yang menjadi dependensinya. Untuk melakukannya, jalankan perintah berikut:

CREATE EXTENSION IF NOT EXISTS pg_diskann CASCADE;

Untuk menghilangkan ekstensi dari database yang saat ini Anda sambungkan, jalankan perintah berikut:

DROP EXTENSION IF EXISTS pg_diskann;

Menggunakan metode akses indeks diskann

Setelah ekstensi diinstal, Anda dapat membuat diskann indeks pada kolom tabel yang berisi data vektor. Misalnya, untuk membuat indeks pada embedding kolom demo tabel, gunakan perintah berikut:

CREATE TABLE demo (
 id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
 embedding public.vector(3)
 -- other columns
);

-- insert dummy data
INSERT INTO demo (embedding) VALUES
('[1.0, 2.0, 3.0]'),
('[4.0, 5.0, 6.0]'),
('[7.0, 8.0, 9.0]');

-- create a diskann index by using Cosine distance operator
CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Setelah indeks dibuat, Anda dapat menjalankan kueri untuk menemukan tetangga terdekat.

Kueri berikut menemukan 5 tetangga terdekat ke vektor [2.0, 3.0, 4.0]:

SELECT id, embedding
FROM demo
ORDER BY embedding <=> '[2.0, 3.0, 4.0]'
LIMIT 5;

Postgres secara otomatis memutuskan kapan harus menggunakan indeks DiskANN. Jika memilih untuk tidak menggunakan indeks dalam skenario di mana Anda ingin menggunakannya, jalankan perintah berikut:

-- Explicit Transcation block to force use for DiskANN index.

BEGIN;
SET LOCAL enable_seqscan TO OFF;
-- Similarity search queries
COMMIT;

Penting

Mengatur enable_seqscan ke nonaktif, ini mencegah perencana kueri menggunakan rencana pemindaian berurutan jika tersedia metode lain. Karena dinonaktifkan menggunakan SET LOCAL perintah , pengaturan hanya berlaku untuk transaksi saat ini. Setelah COMMIT atau ROLLBACK, pengaturan tingkat sesi berlaku lagi. Perhatikan bahwa jika kueri melibatkan tabel lain, pengaturan juga mencegah penggunaan pemindaian berurutan di semuanya.

Menskalakan secara efisien dengan Kuantisasi (Pratinjau)

DiskANN menggunakan kuantisasi produk (PQ) untuk mengurangi jejak memori vektor secara dramatis. Tidak seperti teknik kuantisasi lainnya, algoritma PQ dapat mengompres vektor secara lebih efektif, secara signifikan meningkatkan performa.  DiskANN menggunakan PQ dapat menyimpan lebih banyak data dalam memori, mengurangi kebutuhan untuk mengakses penyimpanan yang lebih lambat, serta menggunakan lebih sedikit komputasi saat membandingkan vektor terkompresi. Hal ini menghasilkan performa yang lebih baik dan penghematan biaya yang signifikan saat bekerja dengan jumlah data yang lebih besar (> 1 juta baris).

Penting

Dukungan kuantisasi produk di DiskANN tersedia mulai dari pg_diskann v0.6 ke atas.

Untuk mengurangi ukuran indeks Anda dan memasukkan lebih banyak data ke dalam memori, Anda dapat menggunakan PQ:

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann(embedding vector_cosine_ops) 
WITH(
    product_quantized=true
    );    

Meningkatkan akurasi saat menggunakan PQ dengan reranking vektor

Reranking dengan vektor penuh adalah teknik yang digunakan dalam sekitar sistem pencarian tetangga terdekat (ANN) seperti DiskANN dengan Kuantisasi Produk (PQ) untuk meningkatkan akurasi hasil dengan menyusun ulang kandidat yang diambil top-N menggunakan vektor asli yang tidak dikompresi (presisi penuh). Teknik reranking ini didasarkan murni pada metrik kesamaan vektor yang tepat (misalnya, kesamaan kosinus atau jarak Euclidean). Teknik ini tidak sama dengan reranking menggunakan model peringkat.

Untuk menyeimbangkan kecepatan dan presisi dalam pencarian kesamaan vektor, strategi reranking dua langkah dapat diterapkan saat mengkueri dengan DiskANN dan kuantisasi produk untuk meningkatkan akurasi.

  1. Perkiraan Awal Pencarian: Kueri dalam menggunakan DiskANN untuk mengambil 50 perkiraan tetangga terdekat teratas berdasarkan jarak kosinus antara penyematan yang disimpan dan vektor kueri. Langkah ini cepat dan efisien, memanfaatkan kemampuan pengindeksan DiskANN.

  2. Precise Reranking: Kueri luar menyusun ulang 50 hasil tersebut dengan jarak komputasi aktualnya dan mengembalikan 10 kecocokan paling relevan:

Berikut adalah contoh reranking menggunakan pendekatan 2 langkah ini:

SELECT id
FROM (
    SELECT id, embedding <=> %s::vector AS distance
    FROM demo
    ORDER BY embedding <=> %s::vector asc
    LIMIT 50
) AS t
ORDER BY t.distance
LIMIT 10;

Nota

%s harus diganti oleh vektor kueri. Anda dapat menggunakan azure_ai untuk membuat vektor kueri langsung di Postgres.

Pendekatan ini menyeimbangkan kecepatan (melalui perkiraan pencarian) dan akurasi (melalui reranking vektor penuh), memastikan hasil berkualitas tinggi tanpa memindai seluruh himpunan data.

Dukungan untuk penyematan dimensi tinggi

Aplikasi AI Generatif Tingkat Lanjut sering mengandalkan model penyematan dimensi tinggi seperti penyematan teks-3-besar untuk mencapai akurasi yang unggul. Namun, metode pengindeksan tradisional seperti HNSW di pgvector terbatas pada vektor dengan hingga 2.000 dimensi, yang membatasi penggunaan model yang kuat ini.

Mulai pg_diskann v0.6 ke atas, DiskANN sekarang mendukung vektor pengindeksan dengan hingga 16.000 dimensi, secara signifikan memperluas cakupan untuk beban kerja AI akurasi tinggi.

Penting

Kuantisasi Produk harus diaktifkan untuk memanfaatkan dukungan dimensi tinggi.

Pengaturan yang disarankan:

  • product_quantized: Atur ke true
  • pq_param_num_chunks: Atur ke sepertiga dimensi penyematan untuk performa optimal.
  • pq_param_training_samples: Ditentukan secara otomatis berdasarkan ukuran tabel kecuali diatur secara eksplisit.

Peningkatan ini memungkinkan pencarian yang dapat diskalakan dan efisien di seluruh himpunan data vektor besar sambil mempertahankan pengenalan dan presisi tinggi.

Mempercepat penyusunan indeks

Ada beberapa cara yang kami sarankan untuk meningkatkan waktu pembangunan indeks Anda.

Menggunakan lebih banyak memori

Untuk mempercepat pembuatan indeks, Anda dapat meningkatkan memori yang dialokasikan pada instans Postgres Anda untuk build indeks. Penggunaan memori dapat ditentukan melalui maintenance_work_mem parameter .

-- Set the parameters
SET maintenance_work_mem = '8GB'; -- Depending on your resources

Kemudian, CREATE INDEX perintah menggunakan memori kerja yang ditentukan, tergantung pada sumber daya yang tersedia, untuk membangun indeks.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Petunjuk / Saran

Anda dapat meningkatkan sumber daya memori Anda selama build indeks untuk meningkatkan kecepatan pengindeksan, lalu menurunkan skala saat pengindeksan selesai.

Menggunakan paralelisasi

Untuk mempercepat pembuatan indeks, Anda dapat menggunakan pekerja paralel. Jumlah pekerja dapat ditentukan melalui parameter penyimpanan parallel_workers dari pernyataan CREATE TABLE, saat membuat tabel. Dapat disesuaikan nanti dengan menggunakan klausul SET dari pernyataan ALTER TABLE.

CREATE TABLE demo (
	id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
	embedding public.vector(3)
) WITH (parallel_workers = 4);
ALTER TABLE demo SET (parallel_workers = 8);

Kemudian, CREATE INDEX perintah menggunakan jumlah pekerja paralel yang ditentukan, tergantung pada sumber daya yang tersedia, untuk membangun indeks.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Penting

Proses utama tidak dapat ikut serta dalam pembangunan indeks paralel.

Jika Anda ingin membuat indeks dengan menggunakan pekerja paralel, Anda juga perlu mengatur max_parallel_workersparameter , max_worker_processes, dan max_parallel_maintenance_workers yang sesuai. Untuk informasi selengkapnya tentang parameter ini, lihat parameter yang mengontrol penggunaan sumber daya dan perilaku asinkron.

Anda dapat mengatur parameter ini pada tingkat granularitas yang berbeda. Misalnya, untuk mengaturnya pada tingkat sesi, Anda dapat menjalankan pernyataan berikut:

-- Set the parameters
SET max_parallel_workers = 8;
SET max_worker_processes = 8; -- Note: Requires server restart
SET max_parallel_maintenance_workers = 4;

Untuk mempelajari tentang opsi lain untuk mengonfigurasi parameter ini di server fleksibel Azure Database for PostgreSQL, lihat Mengonfigurasi parameter server.

Nota

Parameter max_worker_processes mengharuskan server dihidupkan ulang agar berlaku.

Jika konfigurasi parameter tersebut dan sumber daya yang tersedia di server tidak mengizinkan peluncuran pekerja paralel, PostgreSQL secara otomatis kembali untuk membuat indeks dalam mode nonparallel.

Parameter konfigurasi

Saat membuat diskann indeks, Anda dapat menentukan berbagai parameter untuk mengontrol perilakunya.

Indeks parameter

  • max_neighbors: Jumlah maksimum tepi per simpul dalam grafik (Secara default 32). Nilai yang lebih tinggi dapat meningkatkan pengenalan hingga titik tertentu.
  • l_value_ib: Ukuran daftar pencarian selama build indeks (Secara default adalah 100). Nilai yang lebih tinggi membuat build lebih lambat, tetapi indeks akan memiliki kualitas yang lebih tinggi.
  • product_quantized: Memungkinkan kuantisasi produk untuk pencarian yang lebih efisien (Default ke false).
  • pq_param_num_chunks: Jumlah gugus untuk kuantisasi produk (Secara default adalah 0). 0 berarti ditentukan secara otomatis, berdasarkan dimensi penyematan. Disarankan untuk menggunakan 1/3 dari dimensi penyematan yang asli.
  • pq_param_training_samples: Jumlah vektor untuk melatih tabel pivot PQ di latar belakang (Secara default 0). 0 berarti ditentukan secara otomatis, berdasarkan ukuran tabel.
CREATE INDEX demo_embedding_diskann_custom_idx ON demo USING diskann (embedding vector_cosine_ops)
WITH (
 max_neighbors = 48,
 l_value_ib = 100,
 product_quantized=true, 
 pq_param_num_chunks = 0,
 pq_param_training_samples = 0
 );

Parameter ekstensi

  • diskann.iterative_search: Mengontrol perilaku pencarian.

    Konfigurasi untuk diskann.iterative_search:

    • relaxed_order (default): Memungkinkan diskann mencari graf secara berulang dalam batch diskann.l_value_is, hingga jumlah tuple yang diinginkan dihasilkan, mungkin dibatasi oleh klausul LIMIT. Mungkin menyebabkan hasilnya tidak berurutan.

    • strict_order: Mirip dengan relaxed_order, memungkinkan diskann mencari graf secara berulang, hingga menghasilkan jumlah tuple yang diinginkan. Namun, ini memastikan bahwa hasilnya dikembalikan dalam urutan ketat yang diurutkan berdasarkan jarak.

    • off: Menggunakan fungsionalitas pencarian noniteratif, yang berarti bahwa ia mencoba mengambil diskann.l_value_is tupel dalam satu langkah. Pencarian noniteratif hanya dapat mengembalikan maksimum diskann.l_value_is vektor untuk kueri, terlepas dari LIMIT klausa atau jumlah tuple yang cocok dengan kueri.

    Untuk mengubah perilaku pencarian menjadi strict_order, untuk semua kueri yang dijalankan dalam sesi saat ini, jalankan pernyataan berikut:

    SET diskann.iterative_search TO 'strict_order';
    

    Untuk mengubahnya sehingga hanya memengaruhi semua kueri yang dijalankan dalam transaksi saat ini, jalankan pernyataan berikut:

    BEGIN;
    SET LOCAL diskann.iterative_search TO 'strict_order';
    -- All your queries
    COMMIT;
    
  • diskann.l_value_is: Nilai L untuk pemindaian indeks (Default ke 100). Meningkatkan nilai meningkatkan pemanggilan tetapi mungkin memperlambat query.

    Untuk mengubah nilai L untuk pemindaian indeks menjadi 20, untuk semua kueri yang dijalankan dalam sesi saat ini, jalankan pernyataan berikut:

    SET diskann.l_value_is TO 20;
    

    Untuk mengubahnya sehingga hanya memengaruhi semua kueri yang dijalankan dalam transaksi saat ini, jalankan pernyataan berikut:

    BEGIN;
    SET LOCAL diskann.l_value_is TO 20;
    -- All your queries
    COMMIT;
    
Ukuran himpunan data (baris) Jenis parameter Nama Nilai yang direkomendasikan
<1 juta Pembangunan Indeks l_value_ib 100
<1 juta Pembangunan Indeks max_neighbors 32
<1 juta Waktu kueri diskann.l_value_is 100
 
1M-50M Pembangunan Indeks l_value_ib 100
1M-50M Pembangunan Indeks max_neighbors 64
1M-50M Pembangunan Indeks product_quantized true
1M-50M Waktu kueri diskann.l_value_is 100
 
>50M Pembangunan Indeks l_value_ib 100
>50M Pembangunan Indeks max_neighbors 96
>50M Pembangunan Indeks product_quantized true
>50M Waktu kueri diskann.l_value_is 100

Nota

Parameter ini mungkin bervariasi tergantung pada himpunan data dan kasus penggunaan tertentu. Pengguna mungkin harus bereksperimen dengan nilai parameter yang berbeda, untuk menemukan pengaturan optimal untuk skenario khusus mereka.

MEMBUAT kemajuan INDEKS dan REINDEX

Dengan PostgreSQL 12 dan yang lebih baru, Anda dapat menggunakan pg_stat_progress_create_index untuk memeriksa kemajuan operasi CREATE INDEX atau REINDEX.

SELECT phase, round(100.0 * blocks_done / nullif(blocks_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;

Untuk mempelajari selengkapnya tentang fase yang mungkin dilalui operasi CREATE INDEX atau REINDEX, lihat fase CREATE INDEX.

Memilih fungsi akses indeks

Jenis vektor memungkinkan Anda melakukan tiga jenis pencarian pada vektor yang disimpan. Anda perlu memilih fungsi akses yang benar untuk indeks Anda, sehingga database dapat mempertimbangkan indeks Anda saat menjalankan kueri Anda.

pg_diskann mendukung operator-operator jarak berikut

  • vector_l2_ops: <-> Jarak Euclidean
  • vector_cosine_ops: <=> Jarak kosinus
  • vector_ip_ops: <#> Produk Dalam

Troubleshooting

Kesalahan: assertion left == right failed left: 40 right: 0:

  • Versi GA DiskANN, v0.6.x memperkenalkan perubahan signifikan dalam format metadata indeks. Indeks yang dibuat dengan v0.5.x tidak kompatibel maju dengan operasi penyisipan v0.6.x. Mencoba menyisipkan ke dalam tabel dengan indeks yang sudah kedaluarsa akan mengakibatkan kesalahan, bahkan jika indeks tampak valid.

  • Ketika Anda mengalami kesalahan ini, Anda dapat mengatasinya dengan:

    • Opsi 1: Menjalankan REINDEX atau REDINDEX CONCURRENTLY pernyataan pada indeks.

    • Opsi 2: Membangun ulang Indeks

      DROP INDEX your_index_name;
      CREATE INDEX your_index_name ON your_table USING diskann(your_vector_column vector_cosine_ops);
      
      

Kesalahan: diskann index needs to be upgraded to version 2...:

  • Ketika Anda mengalami kesalahan ini, Anda dapat mengatasinya dengan:
    • Opsi 1: Menjalankan REINDEX atau REDINDEX CONCURRENTLY pernyataan pada indeks.

    • Opsi 2: Karena REINDEX mungkin memakan waktu lama, ekstensi juga menyediakan fungsi yang ditentukan pengguna yang disebut upgrade_diskann_index(), yang meningkatkan indeks Anda lebih cepat, jika memungkinkan.

      Untuk meningkatkan indeks Anda, jalankan pernyataan berikut:

      SELECT upgrade_diskann_index('demo_embedding_diskann_custom_idx');
      

      Untuk meningkatkan semua indeks diskann dalam database ke versi saat ini, jalankan pernyataan berikut:

      SELECT upgrade_diskann_index(pg_class.oid)
      FROM pg_class
      JOIN pg_am ON (pg_class.relam = pg_am.oid)
      WHERE pg_am.amname = 'diskann';