Paket hnsw mengimplementasikan grafik dunia kecil yang dapat dilayari secara hierarkis di Go. Anda dapat membaca tentang cara kerja mereka di sini. Intinya, mereka memungkinkan untuk mendekati pencarian tetangga terdekat dengan data vektor dimensi tinggi.
Paket ini dapat dianggap sebagai alternatif dalam memori untuk database vektor favorit Anda (misalnya Pinecone, Weaviate). Ini menerapkan hanya operasi penting:
| Operasi | Kompleksitas | Keterangan |
|---|---|---|
| Menyisipkan | Masukkan vektor ke dalam grafik | |
| Menghapus | Hapus vektor dari grafik | |
| Mencari | Cari tetangga terdekat dari sebuah vektor | |
| Pencarian | Mengambil vektor dengan id |
Catatan
Kompleksitas perkiraan dimana
go get github.com/coder/hnsw@main
g := hnsw . NewGraph [ int ]()
g . Add (
hnsw . MakeNode ( 1 , [] float32 { 1 , 1 , 1 }),
hnsw . MakeNode ( 2 , [] float32 { 1 , - 1 , 0.999 }),
hnsw . MakeNode ( 3 , [] float32 { 1 , 0 , - 0.5 }),
)
neighbors := g . Search (
[] float32 { 0.5 , 0.5 , 0.5 },
1 ,
)
fmt . Printf ( "best friend: %v n " , neighbors [ 0 ]. Vec )
// Output: best friend: [1 1 1] Sementara semua operasi grafik dalam memori, hnsw menyediakan fasilitas untuk memuat/menghemat dari penyimpanan persisten.
Untuk antarmuka io.Reader / io.Writer , gunakan Graph.Export dan Graph.Import .
Jika Anda menggunakan satu file sebagai backend, HNSW menyediakan jenis SavedGraph yang nyaman sebagai gantinya:
path := "some.graph"
g1 , err := LoadSavedGraph [ int ]( path )
if err != nil {
panic ( err )
}
// Insert some vectors
for i := 0 ; i < 128 ; i ++ {
g1 . Add ( hnsw . MakeNode ( i , [] float32 { float32 ( i )}))
}
// Save to disk
err = g1 . Save ()
if err != nil {
panic ( err )
}
// Later...
// g2 is a copy of g1
g2 , err := LoadSavedGraph [ int ]( path )
if err != nil {
panic ( err )
}Lihat lebih lanjut:
Kami menggunakan penyandian biner cepat untuk grafik, sehingga Anda dapat menghemat/memuat hampir pada kecepatan disk. Pada M3 MacBook saya, saya mendapatkan hasil tolok ukur ini:
goos: darwin
goarch: arm64
pkg: github.com/coder/hnsw
BenchmarkGraph_Import-16 4029 259927 ns/op 796.85 MB/s 496022 B/op 3212 allocs/op
BenchmarkGraph_Export-16 7042 168028 ns/op 1232.49 MB/s 239886 B/op 2388 allocs/op
PASS
ok github.com/coder/hnsw 2.624s
Saat menyimpan/memuat grafik 100 vektor dengan 256 dimensi.
Pada umumnya efek terbesar yang dapat Anda miliki pada kinerja grafik adalah mengurangi dimensi data Anda. Pada 1536 dimensi (default OpenAI), 70% dari proses kueri di bawah parameter default dihabiskan dalam fungsi jarak.
Jika Anda berjuang dengan kelambatan / latensi, pertimbangkan:
Dan, jika Anda berjuang dengan penggunaan memori berlebih, pertimbangkan:
Graph.M (jumlah maksimum tetangga yang dapat dimiliki setiap node)Graph.Ml (parameter generasi level) Overhead memori grafik terlihat seperti:
Di mana:
Anda dapat menyimpulkan itu:
Dalam contoh grafik dengan 256 dimensi, dan
Dan pertumbuhan memori sebagian besar linier.