Membuat indeks ScaNN

Halaman ini menjelaskan cara menggunakan embedding tersimpan untuk membuat indeks dan mengkueri embedding menggunakan indeks ScaNN dengan AlloyDB untuk PostgreSQL. Untuk mengetahui informasi selengkapnya tentang menyimpan embedding, lihat Menyimpan embedding vektor.

AlloyDB alloydb_scann, ekstensi PostgreSQL yang dikembangkan oleh Google yang menerapkan indeks tetangga terdekat yang sangat efisien yang didukung oleh algoritma ScaNN.

Indeks ScaNN adalah indeks kuantisasi berbasis pohon untuk penelusuran perkiraan tetangga terdekat. Fitur ini memberikan waktu pembuatan indeks yang lebih rendah dan jejak memori yang lebih kecil dibandingkan dengan HNSW. Selain itu, layanan ini memberikan QPS yang lebih cepat dibandingkan dengan HNSW berdasarkan workload.

Sebelum memulai

Sebelum dapat mulai membuat indeks, Anda harus menyelesaikan prasyarat berikut.

  • Vektor embedding ditambahkan ke tabel di database AlloyDB Anda.

  • Ekstensi vector yang didasarkan pada pgvector, diperluas oleh Google untuk AlloyDB, dan ekstensi alloydb_scann diinstal:

    CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;
    
  • Jika Anda ingin membuat indeks ScaNN yang disetel secara otomatis, pastikan tanda scann.enable_preview_features diaktifkan. Jika Anda tidak ingin mengaktifkan fitur pratinjau, atau untuk instance produksi, Anda dapat membuat indeks ScaNN dengan parameter tertentu.

Membuat indeks ScaNN yang disetel secara otomatis

Dengan fitur indeks otomatis, Anda dapat menyederhanakan pembuatan indeks untuk membuat indeks secara otomatis yang dioptimalkan untuk performa penelusuran atau waktu pembuatan indeks dan performa penelusuran yang seimbang.

Saat menggunakan mode AUTO, Anda hanya perlu menentukan nama tabel dan kolom embedding beserta fungsi jarak yang ingin digunakan. Anda dapat mengoptimalkan indeks untuk performa penelusuran atau menyeimbangkan antara waktu pembuatan indeks dan performa penelusuran.

Ada juga opsi untuk menggunakan mode MANUAL guna membuat indeks dengan kontrol terperinci atas parameter penyesuaian indeks lainnya.

Membuat indeks ScaNN dalam mode AUTO

Beberapa hal yang perlu diperhatikan sebelum membuat indeks dalam mode AUTO adalah sebagai berikut:

  • AlloyDB tidak dapat membuat indeks ScaNN untuk tabel dengan data yang tidak mencukupi.
  • Anda tidak dapat menetapkan parameter pembuatan indeks, seperti num_leaves, saat membuat indeks dalam mode AUTO.
  • Pemeliharaan otomatis diaktifkan secara default untuk semua indeks yang dibuat dalam mode AUTO.

Untuk membuat indeks dalam mode AUTO, jalankan perintah berikut:

      CREATE INDEX INDEX_NAME ON TABLE \
      USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
      WITH (mode=AUTO', optimization='OPTIMIZATION');

Ganti kode berikut:

  • INDEX_NAME: nama indeks yang ingin Anda buat—misalnya, my-scann-index. Nama indeks dibagikan di seluruh database Anda. Pastikan setiap nama indeks unik untuk setiap tabel dalam database Anda.

  • TABLE: tabel yang akan ditambahkan indeksnya.

  • EMBEDDING_COLUMN: kolom yang menyimpan data vector.

  • DISTANCE_FUNCTION: fungsi jarak yang akan digunakan dengan indeks ini. Pilih salah satu opsi berikut:

    • Jarak L2: l2

    • Perkalian titik: dot_product

    • Jarak kosinus: cosine

  • OPTIMIZATION: Setel ke salah satu opsi berikut:

    • SEARCH_OPTIMIZED: untuk mengoptimalkan perolehan penelusuran vektor dan latensi penelusuran vektor dengan biaya waktu pembuatan indeks yang lebih lama.
    • BALANCED: untuk membuat indeks yang menyeimbangkan waktu pembuatan indeks dan performa penelusuran.

Membuat indeks ScaNN dalam mode MANUAL

Jika Anda mengaktifkan tanda scann.enable_preview_features dan menginginkan kontrol terperinci atas parameter penyesuaian, Anda dapat membuat indeks dalam mode MANUAL.

Untuk membuat indeks ScaNN dalam mode MANUAL, jalankan perintah berikut:

      CREATE INDEX INDEX_NAME ON TABLE \
      USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
      WITH (mode='MANUAL, num_leaves=NUM_LEAVES_VALUE, [quantizer =QUANTIZER, max_num_levels=MAX_NUM_LEVELS]);

Ganti kode berikut:

  • INDEX_NAME: nama indeks yang ingin Anda buat—misalnya, my-scann-index. Nama indeks dibagikan di seluruh database Anda. Pastikan setiap nama indeks unik untuk setiap tabel dalam database Anda.

  • TABLE: tabel yang akan ditambahkan indeksnya.

  • EMBEDDING_COLUMN: kolom yang menyimpan data vector.

  • DISTANCE_FUNCTION: fungsi jarak yang akan digunakan dengan indeks ini. Pilih salah satu opsi berikut:

    • Jarak L2: l2

    • Perkalian titik: dot_product

    • Jarak kosinus: cosine

  • NUM_LEAVES_VALUE: jumlah partisi yang akan diterapkan ke indeks ini. Tetapkan ke nilai apa pun antara 1 hingga 1048576.

  • QUANTIZER: jenis penguantisasi yang ingin Anda gunakan untuk pohon K-means. Nilai default ditetapkan ke SQ8 yang memberikan performa kueri yang lebih baik dengan kehilangan perolehan minimal (biasanya kurang dari 1-2%). Anda juga dapat menyetelnya ke FLAT untuk perolehan kembali 99% atau lebih tinggi.

  • MAX_NUM_LEVELS: jumlah maksimum tingkat pohon pengelompokan K-means. Tetapkan ke 1(default) untuk kuantisasi berbasis pohon dua tingkat, dan tetapkan ke 2 untuk kuantisasi berbasis pohon tiga tingkat.

Anda dapat menambahkan parameter pembuatan indeks atau runtime kueri lainnya untuk menyesuaikan indeks. Untuk mengetahui informasi selengkapnya, lihat Menyesuaikan indeks ScaNN.

Mengubah mode untuk indeks yang ada

Jika Anda membuat indeks ScaNN menggunakan mode AUTO dan ingin menyesuaikan indeks secara manual, Anda harus mengubah mode ke MANUAL.

Untuk mengubah mode ke MANUAL, ikuti langkah-langkah berikut:

  1. Perbarui indeks untuk menyetel mode ke MANUAL:

    ALTER INDEX INDEX_NAME SET (mode = 'MANUAL', num_leaves = NUM_LEAVES_VALUE);
    

    Ganti kode berikut:

    • INDEX_NAME: nama indeks yang ingin Anda buat—misalnya, my-scann-index. Nama indeks dibagikan di seluruh database Anda. Pastikan setiap nama indeks unik untuk setiap tabel dalam database Anda.

    • NUM_LEAVES_VALUE: jumlah partisi yang akan diterapkan ke indeks ini. Tetapkan ke nilai apa pun antara 1 hingga 1048576.

    Anda dapat menambahkan parameter pembuatan indeks atau runtime kueri lainnya untuk menyesuaikan indeks. Untuk mengetahui informasi selengkapnya, lihat Menyesuaikan indeks ScaNN.

  2. Bangun ulang indeks Anda untuk menerapkan parameter:

    REINDEX INDEX CONCURRENTLY INDEX_NAME;
    

Untuk mengubah mode ke AUTO, selesaikan langkah-langkah berikut:

  1. Perbarui indeks untuk menyetel mode ke AUTO:

    ALTER INDEX INDEX_NAME SET (mode = 'AUTO');
    
  2. Bangun ulang indeks Anda untuk menerapkan parameter:

    REINDEX INDEX CONCURRENTLY INDEX_NAME;
    

Membuat indeks ScaNN dengan parameter tertentu

Jika aplikasi Anda memiliki persyaratan khusus untuk waktu pembuatan indeks dan penarikan, Anda dapat membuat indeks secara manual. Anda dapat membuat indeks pohon dua tingkat atau tiga tingkat berdasarkan beban kerja Anda. Untuk mengetahui informasi selengkapnya tentang penyesuaian parameter, lihat Menyesuaikan indeks ScaNN.

Indeks hierarki dua tingkat

Untuk menerapkan indeks pohon dua tingkat menggunakan algoritma ScaNN ke kolom yang berisi embedding vektor tersimpan, jalankan kueri DDL berikut:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE);

Ganti kode berikut:

  • INDEX_NAME: nama indeks yang ingin Anda buat—misalnya, my-scann-index. Nama indeks dibagikan di seluruh database Anda. Pastikan setiap nama indeks unik untuk setiap tabel dalam database Anda.

  • TABLE: tabel yang akan ditambahkan indeksnya.

  • EMBEDDING_COLUMN: kolom yang menyimpan data vector.

  • DISTANCE_FUNCTION: fungsi jarak yang akan digunakan dengan indeks ini. Pilih salah satu opsi berikut:

    • Jarak L2: l2

    • Perkalian titik: dot_product

    • Jarak kosinus: cosine

  • NUM_LEAVES_VALUE: jumlah partisi yang akan diterapkan ke indeks ini. Tetapkan ke nilai apa pun antara 1 hingga 1048576. Untuk mengetahui informasi selengkapnya tentang cara menentukan nilai ini, lihat Menyesuaikan indeks ScaNN.

Indeks hierarki tiga tingkat

Untuk membuat indeks pohon tiga tingkat menggunakan algoritma ScaNN ke kolom yang berisi embedding vektor tersimpan, jalankan kueri DDL berikut:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = 2);

Setelah membuat indeks, Anda dapat menjalankan kueri penelusuran tetangga terdekat yang menggunakan indeks dengan mengikuti petunjuk di Membuat kueri tetangga terdekat dengan teks tertentu.

Parameter indeks harus disetel untuk mencapai keseimbangan yang tepat antara QPS dan perolehan. Untuk mengetahui informasi selengkapnya tentang penyesuaian indeks ScaNN, lihat Menyesuaikan indeks ScaNN.

Untuk membuat indeks ini pada kolom sematan yang menggunakan jenis data real[] alih-alih vector, transmisikan kolom ke jenis data vector:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

Ganti DIMENSIONS dengan lebar dimensi kolom penyematan. Untuk mengetahui informasi selengkapnya tentang cara menemukan dimensi, lihat fungsi vector_dims di fungsi Vektor.

Untuk mendapatkan pengalaman penelusuran yang konsisten, aktifkan pemeliharaan otomatis saat Anda membuat indeks ScaNN. Untuk mengetahui informasi selengkapnya, lihat Memelihara indeks vektor. Fitur ini tersedia di Pratinjau.

Untuk melihat progres pengindeksan, gunakan tampilan pg_stat_progress_create_index:

SELECT * FROM pg_stat_progress_create_index;

Kolom phase menampilkan status pembuatan indeks Anda saat ini. Setelah fase pembuatan indeks selesai, baris untuk indeks tidak terlihat.

Untuk menyesuaikan indeks Anda agar mendapatkan keseimbangan QPS dan perolehan rata-rata, lihat Menyesuaikan indeks ScaNN.

Membangun indeks secara paralel

Untuk membangun indeks Anda lebih cepat, AlloyDB dapat secara otomatis membuat beberapa pekerja paralel, bergantung pada set data Anda dan jenis indeks yang Anda pilih.

Pembangunan indeks paralel sering dipicu jika Anda membuat indeks ScaNN 3 tingkat atau jika set data Anda melebihi 100 juta baris.

Meskipun AlloyDB mengoptimalkan jumlah pekerja paralel secara otomatis, Anda dapat menyesuaikan pekerja paralel menggunakan parameter perencanaan kueri PostgreSQL max_parallel_maintenance_workers, max_parallel_workers, dan min_parallel_table_scan_size.

Menjalankan kueri

Setelah menyimpan dan mengindeks sematan di database, Anda dapat mulai mengirimkan kueri data. Anda tidak dapat menjalankan kueri penelusuran massal menggunakan ekstensi alloydb_scann.

Untuk menemukan tetangga semantik terdekat untuk vektor embedding, Anda dapat menjalankan contoh kueri berikut, dengan menetapkan fungsi jarak yang sama dengan yang Anda gunakan selama pembuatan indeks.

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT

Ganti kode berikut:

  • TABLE: tabel yang berisi embedding untuk membandingkan teks.

  • INDEX_NAME: nama indeks yang ingin Anda gunakan—misalnya, my-scann-index.

  • EMBEDDING_COLUMN: kolom yang berisi embedding yang disimpan.

  • DISTANCE_FUNCTION_QUERY: fungsi jarak yang akan digunakan dengan kueri ini. Pilih salah satu opsi berikut berdasarkan fungsi jarak yang digunakan saat membuat indeks:

    • Jarak L2: <->

    • Produk dalam: <#>

    • Jarak kosinus: <=>

  • EMBEDDING: vektor embedding yang ingin Anda temukan tetangga semantik terdekatnya yang tersimpan.

  • ROW_COUNT: jumlah baris yang akan ditampilkan.

    Tentukan 1 jika Anda hanya menginginkan satu kecocokan terbaik.

Anda juga dapat menggunakan fungsi embedding() untuk menerjemahkan teks ke dalam vektor. Karena embedding() menampilkan array real, Anda harus melakukan transmisi eksplisit panggilan embedding() ke vector sebelum menerapkannya ke salah satu operator tetangga terdekat (misalnya, <-> untuk jarak L2). Operator ini kemudian dapat menggunakan indeks ScaNN untuk menemukan baris database dengan embedding yang paling mirip secara semantik.

Langkah berikutnya