🚀 Coba Zilliz Cloud, Milvus yang sepenuhnya terkelola, secara gratis—rasakan performa 10x lebih cepat! Coba Sekarang>>

milvus-logo
LFAI

Memulai dengan HNSWlib

  • Engineering
November 25, 2024
Haziqa Sajid

Pencarian semantik memungkinkan mesin untuk memahami bahasa dan memberikan hasil pencarian yang lebih baik, yang sangat penting dalam AI dan analisis data. Setelah bahasa direpresentasikan sebagai sematan, pencarian dapat dilakukan dengan menggunakan metode yang tepat atau perkiraan. Pencarian Approximate Nearest Neighbor(ANN) adalah metode yang digunakan untuk menemukan dengan cepat titik-titik dalam kumpulan data yang paling dekat dengan titik kueri yang diberikan, tidak seperti pencarian tetangga terdekat yang tepat, yang dapat menjadi mahal secara komputasi untuk data berdimensi tinggi. ANN memungkinkan pengambilan yang lebih cepat dengan memberikan hasil yang kira-kira mendekati tetangga terdekat.

Salah satu algoritma untuk pencarian Approximate Nearest Neighbor (ANN) adalah HNSW (Hierarchical Navigable Small Worlds), diimplementasikan di bawah HNSWlib, yang akan menjadi fokus diskusi hari ini. Dalam blog ini, kita akan:

  • Memahami algoritma HNSW.

  • Menjelajahi HNSWlib dan fitur-fitur utamanya.

  • Menyiapkan HNSWlib, yang meliputi pembuatan indeks dan implementasi pencarian.

  • Membandingkannya dengan Milvus.

Memahami HNSW

Hierarchical Navigable Small Worlds (HNSW) adalah struktur data berbasis grafik yang memungkinkan pencarian kesamaan yang efisien, terutama di ruang berdimensi tinggi, dengan membangun grafik berlapis-lapis jaringan "dunia kecil". Diperkenalkan pada tahun 2016, HNSW mengatasi masalah skalabilitas yang terkait dengan metode pencarian tradisional seperti brute-force dan pencarian berbasis pohon. HNSW sangat ideal untuk aplikasi yang melibatkan kumpulan data yang besar, seperti sistem rekomendasi, pengenalan gambar, dan retrieval-augmented generation (RAG).

Mengapa HNSW Penting

HNSW secara signifikan meningkatkan kinerja pencarian tetangga terdekat dalam ruang dimensi tinggi. Menggabungkan struktur hirarkis dengan kemampuan navigasi dunia kecil menghindari inefisiensi komputasi dari metode yang lebih lama, memungkinkannya untuk bekerja dengan baik bahkan dengan set data yang sangat besar dan kompleks. Untuk memahami hal ini dengan lebih baik, mari kita lihat bagaimana cara kerjanya sekarang.

Cara Kerja HNSW

  1. Lapisan Hirarkis: HNSW mengatur data ke dalam hierarki lapisan, di mana setiap lapisan berisi node yang dihubungkan oleh tepi. Lapisan teratas lebih jarang, memungkinkan untuk "melompat" secara luas di seluruh grafik, seperti memperkecil peta untuk melihat jalan raya utama antar kota. Lapisan bawah semakin rapat, memberikan detail yang lebih baik dan lebih banyak koneksi antara tetangga yang lebih dekat.

  2. Konsep Dunia Kecil yang dapat dijelajahi: Setiap lapisan di HNSW dibangun berdasarkan konsep jaringan "dunia kecil", di mana node (titik data) hanya berjarak beberapa "lompatan" dari satu sama lain. Algoritma pencarian dimulai dari lapisan yang paling tinggi dan paling jarang dan bekerja ke bawah, bergerak ke lapisan yang lebih padat untuk menyempurnakan pencarian. Pendekatan ini seperti bergerak dari pandangan global ke detail tingkat lingkungan, secara bertahap mempersempit area pencarian.

Gambar 1: Contoh Graf Dunia Kecil yang Dapat Dinavigasi

  1. Melewati Struktur Seperti Daftar: Aspek hirarkis dari HNSW menyerupai sebuah daftar lewati, sebuah struktur data probabilistik di mana lapisan-lapisan yang lebih tinggi memiliki lebih sedikit simpul, memungkinkan pencarian awal yang lebih cepat.

Gambar 2: Contoh Struktur Daftar Lewati

Untuk mencari 96 dalam daftar lompatan yang diberikan, kita mulai dari tingkat paling atas di ujung kiri pada simpul header. Bergerak ke kanan, kita menemukan 31, kurang dari 96, jadi kita lanjutkan ke simpul berikutnya. Sekarang, kita perlu turun ke tingkat di mana kita melihat 31 lagi; karena masih kurang dari 96, kita turun satu tingkat lagi. Setelah menemukan 31 sekali lagi, kita kemudian bergerak ke kanan dan mencapai 96, nilai target kita. Dengan demikian, kita menemukan 96 tanpa perlu turun ke level terendah dari daftar lewati.

  1. Efisiensi Pencarian: Algoritma HNSW dimulai dari simpul entri pada lapisan tertinggi, maju ke tetangga yang lebih dekat dengan setiap langkah. Algoritma ini menuruni lapisan-lapisan, menggunakan setiap lapisan untuk eksplorasi kasar hingga halus, hingga mencapai lapisan terendah di mana node yang paling mirip kemungkinan besar ditemukan. Navigasi berlapis ini mengurangi jumlah node dan tepi yang perlu dieksplorasi, membuat pencarian menjadi cepat dan akurat.

  2. Penyisipan dan Pemeliharaan: Ketika menambahkan node baru, algoritma menentukan lapisan masuknya berdasarkan probabilitas dan menghubungkannya ke node terdekat menggunakan heuristik pemilihan tetangga. Heuristik ini bertujuan untuk mengoptimalkan konektivitas, menciptakan tautan yang meningkatkan kemampuan navigasi sekaligus menyeimbangkan kepadatan graf. Pendekatan ini membuat struktur tetap kuat dan mudah beradaptasi dengan titik-titik data baru.

Meskipun kami memiliki pemahaman dasar tentang algoritma HNSW, mengimplementasikannya dari awal bisa jadi sangat melelahkan. Untungnya, komunitas telah mengembangkan pustaka seperti HNSWlib untuk menyederhanakan penggunaan, membuatnya dapat diakses tanpa membuat Anda bingung. Jadi, mari kita lihat lebih dekat HNSWlib.

Gambaran Umum HNSWlib

HNSWlib, sebuah pustaka populer yang mengimplementasikan HNSW, sangat efisien dan dapat diskalakan, berkinerja baik bahkan dengan jutaan titik. HNSWlib mencapai kompleksitas waktu sublinear dengan memungkinkan lompatan cepat di antara lapisan-lapisan grafik dan mengoptimalkan pencarian data yang padat dan berdimensi tinggi. Berikut ini adalah fitur-fitur utama dari HNSWlib:

  • Struktur Berbasis Grafik: Grafik berlapis-lapis merepresentasikan titik-titik data, memungkinkan pencarian tetangga terdekat yang cepat.

  • Efisiensi Dimensi Tinggi: Dioptimalkan untuk data berdimensi tinggi, memberikan perkiraan pencarian yang cepat dan akurat.

  • Waktu Pencarian Sublinear: Mencapai kompleksitas sublinear dengan melompati lapisan, meningkatkan kecepatan secara signifikan.

  • Pembaruan Dinamis: Mendukung penyisipan dan penghapusan node secara real-time tanpa memerlukan pembangunan ulang grafik yang lengkap.

  • Efisiensi Memori: Penggunaan memori yang efisien, cocok untuk kumpulan data yang besar.

  • Skalabilitas: Dapat diskalakan dengan baik ke jutaan titik data, sehingga ideal untuk aplikasi skala menengah seperti sistem rekomendasi.

Catatan: HNSWlib sangat baik untuk membuat prototipe sederhana untuk aplikasi pencarian vektor. Namun, karena keterbatasan skalabilitas, mungkin ada pilihan yang lebih baik seperti database vektor yang dibuat khusus untuk skenario yang lebih kompleks yang melibatkan ratusan juta atau bahkan miliaran titik data. Mari kita lihat itu dalam tindakan.

Memulai dengan HNSWlib: Panduan Langkah-demi-Langkah

Bagian ini akan mendemonstrasikan penggunaan HNSWlib sebagai pustaka pencarian vektor dengan membuat indeks HNSW, memasukkan data, dan melakukan pencarian. Mari kita mulai dengan instalasi:

Pengaturan dan Impor

Untuk memulai dengan HNSWlib di Python, pertama-tama instal menggunakan pip:

pip install hnswlib

Kemudian, impor pustaka yang diperlukan:

import hnswlib 
import numpy as np

Mempersiapkan Data

Dalam contoh ini, kita akan menggunakan NumPyuntuk menghasilkan kumpulan data acak dengan 10.000 elemen, masing-masing dengan ukuran dimensi 256.

dim = 256  # Dimensionality of your vectors
num_elements = 10000  # Number of elements to insert

Mari kita buat datanya:

data = np.random.rand(num_elements, dim).astype(np.float32)  # Example data

Sekarang data kita sudah siap, mari kita membuat indeks.

Membangun Indeks

Dalam membuat indeks, kita perlu mendefinisikan dimensi vektor dan tipe ruang. Mari kita membuat sebuah indeks:

p = hnswlib.Index(space='l2', dim=dim)
  • space='l2': Parameter ini mendefinisikan metrik jarak yang digunakan untuk kemiripan. Mengaturnya ke 'l2' berarti menggunakan jarak Euclidean (norma L2). Jika Anda mengaturnya ke 'ip', ini akan menggunakan inner product, yang berguna untuk tugas-tugas seperti kemiripan kosinus.
  • dim=dim: Parameter ini menentukan dimensi titik data yang akan Anda gunakan. Parameter ini harus sesuai dengan dimensi data yang Anda rencanakan untuk ditambahkan ke dalam indeks.

Berikut adalah cara menginisialisasi indeks:

p.init_index(max_elements=num_elements, ef_construction=200, M=16)
  • max_elements=num_elements: Ini menetapkan jumlah maksimum elemen yang dapat ditambahkan ke indeks. Num_elements adalah kapasitas maksimum, jadi kami menetapkannya menjadi 10.000 karena kami bekerja dengan 10.000 titik data.
  • ef_construction=200: Parameter ini mengontrol pertukaran akurasi vs. kecepatan konstruksi selama pembuatan indeks. Nilai yang lebih tinggi akan meningkatkan daya ingat (akurasi) tetapi meningkatkan penggunaan memori dan waktu pembuatan. Nilai yang umum berkisar antara 100 hingga 200.
  • M=16: Parameter ini menentukan jumlah tautan dua arah yang dibuat untuk setiap titik data, yang mempengaruhi akurasi dan kecepatan pencarian. Nilai yang umum adalah antara 12 dan 48; 16 sering kali merupakan keseimbangan yang baik untuk akurasi dan kecepatan yang moderat.
p.set_ef(50)  # This parameter controls the speed/accuracy trade-off
  • ef: Parameter ef, kependekan dari "faktor eksplorasi", menentukan berapa banyak tetangga yang diperiksa selama pencarian. Nilai ef yang lebih tinggi menghasilkan lebih banyak tetangga yang dieksplorasi, yang secara umum meningkatkan akurasi (recall) pencarian tetapi juga membuatnya lebih lambat. Sebaliknya, nilai ef yang lebih rendah dapat melakukan pencarian lebih cepat tetapi dapat mengurangi akurasi.

Dalam kasus ini, pengaturan ef ke 50 berarti algoritme pencarian akan mengevaluasi hingga 50 tetangga ketika menemukan titik data yang paling mirip.

Catatan: ef_construction mengatur upaya pencarian tetangga selama pembuatan indeks, meningkatkan akurasi tetapi memperlambat konstruksi. ef mengontrol upaya pencarian selama kueri, menyeimbangkan kecepatan dan penarikan secara dinamis untuk setiap kueri.

Melakukan Pencarian

Untuk melakukan pencarian tetangga terdekat menggunakan HNSWlib, pertama-tama kita membuat vektor kueri acak. Dalam contoh ini, dimensi vektor sesuai dengan data yang diindeks.

query_vector = np.random.rand(dim).astype(np.float32)  # Example query

labels, distances = p.knn_query(query_vector, k=5)  # k is the number of nearest neighbors
  • query_vector: Baris ini menghasilkan vektor acak dengan dimensi yang sama dengan data yang diindeks, untuk memastikan kompatibilitas pencarian tetangga terdekat.
  • knn_query: Metode ini mencari k tetangga terdekat dari query_vector di dalam indeks p. Metode ini mengembalikan dua larik: labels, yang berisi indeks tetangga terdekat, dan distances, yang menunjukkan jarak dari vektor kueri ke masing-masing tetangga ini. Di sini, k=5 menetapkan bahwa kita ingin menemukan lima tetangga terdekat.

Berikut adalah hasil setelah mencetak label dan jarak:

print("Nearest neighbors' labels:", labels)
print("Distances:", distances)
> Nearest neighbors' labels: [[4498 1751 5647 4483 2471]]
> Distances: [[33.718    35.484592 35.627766 35.828312 35.91495 ]]

Ini dia, sebuah panduan sederhana untuk memulai penggunaan HNSWlib.

Seperti yang telah disebutkan, HNSWlib adalah mesin pencari vektor yang bagus untuk membuat prototipe atau bereksperimen dengan kumpulan data berukuran sedang. Jika Anda memiliki persyaratan skalabilitas yang lebih tinggi atau membutuhkan fitur tingkat perusahaan lainnya, Anda mungkin perlu memilih basis data vektor yang dibuat khusus seperti Milvus yang bersumber terbuka atau layanan terkelola penuh di Zilliz Cloud. Jadi, pada bagian berikut ini, kami akan membandingkan HNSWlib dengan Milvus.

HNSWlib vs Basis Data Vektor yang Dibangun Khusus Seperti Milvus

Basis data vektor menyimpan data sebagai representasi matematis, memungkinkan model pembelajaran mesin untuk mendukung pencarian, rekomendasi, dan pembuatan teks dengan mengidentifikasi data melalui metrik kemiripan untuk pemahaman kontekstual.

Pustaka indeks vektor seperti HNSWlib meningkatkanpencarian dan pengambilanvektor, tetapi tidak memiliki fitur manajemen seperti database lengkap. Di sisi lain, basis data vektor, seperti Milvus, dirancang untuk menangani penyematan vektor dalam skala besar, memberikan keuntungan dalam manajemen data, pengindeksan, dan kemampuan kueri yang biasanya tidak dimiliki oleh pustaka mandiri. Berikut adalah beberapa manfaat lain dari penggunaan Milvus:

  • Pencarian Kemiripan Vektor Berkecepatan Tinggi: Milvus menyediakan kinerja pencarian tingkat milidetik di seluruh set data vektor berskala miliaran, ideal untuk aplikasi seperti pencarian gambar, sistem rekomendasi, pemrosesan bahasa alami(NLP), dan retrieval augmented generation(RAG).

  • Skalabilitas dan Ketersediaan Tinggi: Dibangun untuk menangani volume data yang sangat besar, Milvus berskala horizontal dan menyertakan mekanisme replikasi dan failover untuk keandalan.

  • Arsitektur Terdistribusi: Milvus menggunakan arsitektur terdistribusi dan terukur yang memisahkan penyimpanan dan komputasi di beberapa node untuk fleksibilitas dan ketahanan.

  • Pencarian hibrida: Milvus mendukung pencarian multimodal, pencarian hibrida jarang dan padat, serta pencarian hibrida padat dan teks lengkap, yang menawarkan fungsionalitas pencarian yang serbaguna dan fleksibel.

  • Dukungan Data yang Fleksibel: Milvus mendukung berbagai jenis data-vektor, skalar, dan data terstruktur-memungkinkan manajemen dan analisis yang mulus dalam satu sistem.

  • Komunitas dan DukunganAktif: Komunitas yang berkembang menyediakan pembaruan, tutorial, dan dukungan secara berkala, memastikan Milvus tetap selaras dengan kebutuhan pengguna dan kemajuan di lapangan.

  • Integrasi AI: Milvus telah terintegrasi dengan berbagai kerangka kerja dan teknologi AI yang populer, sehingga memudahkan para pengembang untuk membangun aplikasi dengan tumpukan teknologi yang sudah mereka kenal.

Milvus juga menyediakan layanan yang dikelola sepenuhnya di Ziliz Cloud, yang bebas repot dan 10x lebih cepat dari Milvus.

Perbandingan: Milvus vs HNSWlib

FiturMilvusHNSWlib
SkalabilitasMenangani miliaran vektor dengan mudahCocok untuk dataset yang lebih kecil karena penggunaan RAM
Ideal untukPembuatan prototipe, eksperimen, dan aplikasi tingkat perusahaanBerfokus pada prototipe dan tugas-tugas ANN yang ringan
PengindeksanMendukung 10+ algoritme pengindeksan, termasuk HNSW, DiskANN, Kuantisasi, dan BinerHanya menggunakan HNSW berbasis grafik
IntegrasiMenawarkan API dan layanan cloud-nativeBerfungsi sebagai pustaka yang ringan dan mandiri
KinerjaMengoptimalkan untuk data besar, kueri terdistribusiMenawarkan kecepatan tinggi tetapi skalabilitas terbatas

Secara keseluruhan, Milvus umumnya lebih disukai untuk aplikasi berskala besar dan tingkat produksi dengan kebutuhan pengindeksan yang rumit, sementara HNSWlib ideal untuk pembuatan prototipe dan kasus penggunaan yang lebih mudah.

Kesimpulan

Pencarian semantik dapat memakan banyak sumber daya, sehingga penataan data internal, seperti yang dilakukan oleh HNSW, sangat penting untuk pengambilan data yang lebih cepat. Pustaka seperti HNSWlib peduli dengan implementasinya, sehingga para pengembang memiliki resep yang siap untuk membuat prototipe kemampuan vektor. Hanya dengan beberapa baris kode, kita dapat membangun indeks kita sendiri dan melakukan pencarian.

HNSWlib adalah cara yang bagus untuk memulai. Namun, jika Anda ingin membangun aplikasi AI yang kompleks dan siap produksi, basis data vektor yang dibuat khusus adalah pilihan terbaik. Sebagai contoh, Milvus adalah basis data vektor sumber terbuka dengan banyak fitur yang siap digunakan oleh perusahaan seperti pencarian vektor berkecepatan tinggi, skalabilitas, ketersediaan, dan fleksibilitas dalam hal tipe data dan bahasa pemrograman.

Bacaan Lebih Lanjut

Like the article? Spread the word

Terus Baca