paint-brush
5 Zor Vektör Arama Problemi ve Bunları Apache Cassandra'da Nasıl Çözdük?by@datastax
120

5 Zor Vektör Arama Problemi ve Bunları Apache Cassandra'da Nasıl Çözdük?

DataStax10m2023/10/10
Read on Terminal Reader

Vektör arama seçeneklerini araştırırken aşağıdaki zor sorunları ve bunları çözmeye yönelik farklı yaklaşımları göz önünde bulundurmanız gerekecektir.
featured image - 5 Zor Vektör Arama Problemi ve Bunları Apache Cassandra'da Nasıl Çözdük?
DataStax HackerNoon profile picture


Vektör arama, artırılmış üretimin (RAG) nasıl elde edildiği nedeniyle üretken yapay zeka araçlarının kritik bir bileşenidir. FİŞEK Yüksek Lisans'ların halüsinasyonlardan kaçınırken güncel, özelleştirilmiş bilgileri birleştirmesine yardımcı olur . Aynı zamanda, vektör arama bir ürün değil, bir özelliktir; vektörleri tek başına değil, verilerinizin geri kalanıyla ilişkili oldukları için sorgulamanız gerekir ve verinizin geri kalanını senkronize etmek için bir işlem hattı oluşturmanıza gerek yoktur. Bunu yapmak için verileri bir vektör deposuyla kullanın.

2023 yılı, vektör arama ürünleri ve projelerinde bir patlamaya tanık oldu ve bunlar arasında seçim yapmayı ciddi bir çaba haline getirdi. Seçenekleri araştırırken aşağıdaki zor sorunları ve bunları çözmeye yönelik farklı yaklaşımları göz önünde bulundurmanız gerekecektir. Burada size bu zorluklarla ilgili yol göstereceğim ve DataStax Astra DB ve Apache Cassandra için vektör arama uygulamamızda DataStax'in bunları nasıl aştığını açıklayacağım.


İçeriğe Genel Bakış

  • Boyutsallığın laneti
  • Sorun 1: Ölçek genişletme
  • Sorun 2: Verimli çöp toplama
  • Kenar Çubuğu: Bulut uygulaması iş yükleri
  • Sorun 3: Eşzamanlılık
  • Sorun 4: Diskin etkili kullanımı
  • Sorun 5: Şekillendirilebilirlik
  • Sarmak


Boyutsallığın laneti

Bu zorlu sorunların temelinde araştırmacıların " boyutluluğun laneti .” Bunun pratikte anlamı, 2 boyutlu veya 3 boyutlu uzaylarda tam vektör araması için çalışan algoritmalardır. kd ağaçları , vektörlerinizde 10'larca, 100'lerce veya 1000'lerce boyuta ulaştığınızda dağılırsınız. Sonuç olarak, yüksek boyutlu vektörlerle tam benzerlik araması için bir kısayol yoktur; Logaritmik zamanlı sonuçlar elde etmek için yaklaşık en yakın komşu (YSA) algoritmalarını kullanmamız gerekiyor ve bu da aşağıdaki alanlarda zorlukları beraberinde getiriyor.


Sorun 1: Ölçek genişletme

Birçok vektör arama algoritması, tek bir makinedeki belleğe sığan veri kümeleri için tasarlanmıştır ve bu, hala tarafından test edilen tek senaryodur. ann-kıyaslamalar . (Ann-benchmarks, testini tek bir çekirdekle daha da kısıtlıyor!) Bu, bir milyon belge veya satırdan oluşan akademik çalışma için uygun olabilir, ancak bunun gerçek dünyadaki iş yüklerini temsil ettiği düşünülebilmesinin üzerinden uzun yıllar geçti.


Diğer tüm etki alanlarında olduğu gibi ölçeği genişletme, hem çoğaltma hem de bölümlendirmenin yanı sıra, ölü kopyaların değiştirilmesini, ağ bölümünden sonra bunların onarılmasını vb. gerçekleştirecek alt sistemler gerektirir.


Bu bizim için kolay bir işti: ölçeği genişleterek çoğaltma, Cassandra'nın ekmeği ve tereyağıdır ve bunu Cassandra-5.0'daki yeni SAI (Depolamaya Ekli Dizin Oluşturma - bkz. YSÖP-7 nasıl çalıştığı ve SAI belgeleri nasıl kullanılacağını öğrenmek için) vektör arama uygulamamıza ücretsiz, etkili bir şekilde güçlü ölçeklendirme yetenekleri kazandırdı.




Sorun 2: Verimli çöp toplama

"Çöp toplama" derken, eski bilgilerin dizinden kaldırılmasını, silinen satırların temizlenmesini ve dizine alınmış vektör değeri değişen satırlarla ilgilenmeyi kastediyorum. Bu, bahsetmeye değer görünmeyebilir - ilişkisel veritabanı dünyasında kırk yıldır az çok çözülmüş bir sorundur - ancak vektör indeksleri benzersizdir.


Temel sorun , hem düşük gecikmeli aramalar hem de yüksek hatırlama sonuçları sağlayan, bildiğimiz tüm algoritmaların grafik tabanlı olmasıdır. Pek çok başka vektör indeksleme algoritması da mevcuttur – FAISS birçoğunu uyguluyor - ancak hepsi ya inşa edilemeyecek kadar yavaş, aranamayacak kadar yavaş ya da genel amaçlı bir çözüm olamayacak kadar düşük geri çağırma özelliği sunuyor (ve bazen üçü birden!). Bu nedenle bildiğim her üretim vektör veritabanı grafik tabanlı bir dizin kullanıyor; en basiti HNSW. Hiyerarşik Gezinilebilir Küçük Dünya grafikleri Yury Malkov ve arkadaşları tarafından 2016'da tanıtıldı ; makale oldukça okunabilir ve kesinlikle tavsiye ederim. Aşağıda HNSW hakkında daha fazla bilgi bulabilirsiniz.


Grafik indeksleriyle ilgili zorluk, bir satır veya belge değiştiğinde eski (vektörle ilişkili) düğümü öylece söküp atamayacağınızdır; bunu birkaç defadan fazla yaparsanız, grafiğiniz artık BFS'yi (genişlik öncelikli arama) bir sorgu vektörüne daha fazla benzeyen alanlara yönlendirme amacını yerine getiremeyecektir.


Dolayısıyla bu çöp toplama işlemini gerçekleştirmek için bir noktada dizinlerinizi yeniden oluşturmanız gerekecek, ancak bunu ne zaman ve nasıl organize edeceksiniz? Değişiklikler yapıldığında her zaman her şeyi yeniden kurarsanız, gerçekleştirilen fiziksel yazma işlemlerini büyük ölçüde artıracaksınız; buna yazma amplifikasyonu denir. Öte yandan, hiçbir zaman yeniden oluşturmazsanız, sorgu zamanında eski satırları filtreleyerek ("okuma büyütme") fazladan iş yaparsınız.


Bu Cassandra'nın yıllardır üzerinde çalıştığı başka bir sorun alanıdır. SAI endeksleri ana depolama yaşam döngüsüne bağlı olduğundan Cassandra'ya da katılırlar. sıkıştırma okuma ve yazma arasında sağlıklı bir denge sağlamak için depolama birimlerini logaritmik olarak artırır.



Kenar Çubuğu: Bulut uygulaması iş yükleri

DataStax Astra DB, bulut uygulaması iş yükleri için bir platform sağlamak üzere Apache Cassandra'yı temel alır.


Bu, aşağıdaki iş yükleri anlamına gelir:

  • Genellikle her biri yalnızca birkaç satırı almak için, saniyede binlerce ila milyonlarca eş zamanlı istek. Bu nedenle, bütçeniz yetse bile Netflix'i Snowflake'te çalıştıramazsınız: Snowflake ve benzeri analitik sistemler, her biri birkaç saniyeden dakikaya kadar hatta daha uzun süre boyunca çalışan yalnızca birkaç eşzamanlı isteği işlemek üzere tasarlanmıştır.


  • Bellekten daha büyük Veri kümeniz tek bir makinenin belleğine sığıyorsa, hangi araçları kullandığınızın neredeyse hiçbir önemi yoktur. Sqlite, MongoDB, MySQL – hepsi iyi çalışacak. Durum böyle olmadığında işler daha da zorlaşır - ve kötü haber şu ki, vektör yerleştirmeleri genellikle birkaç KB boyutundadır veya tipik veritabanı belgelerinden birkaç kat daha büyüktür, dolayısıyla bellekten daha büyük boyuta nispeten hızlı bir şekilde ulaşırsınız.


  • Uygulamanın özü Verilerinizi kaybetmeyi umursamıyorsanız, ya o kadar önemli olmadığı için ya da gerçek kayıt kaynağından yeniden oluşturabildiğiniz için, o zaman yine hangi araçları kullandığınızın bir önemi yoktur. Cassandra ve Astra DB gibi veritabanları, verilerinizi ne olursa olsun kullanılabilir ve dayanıklı tutacak şekilde tasarlanmıştır.


Sorun 3: Eşzamanlılık

Yukarıda çok iyi bilinenlerden bahsetmiştim. ann-kıyaslamalar karşılaştırma tüm algoritmaları tek bir çekirdekle sınırlar. Bu, oyun alanını eşitlerken, aynı zamanda son yirmi yıldaki temel donanım iyileştirme kaynağından yararlanabilenleri de engelliyor.


İlgili bir sorun, ann-benchmark'ların aynı anda yalnızca tek türde bir işlem gerçekleştirmesidir: önce dizini oluşturur, sonra onu sorgular. Aramaların arasına eklenen güncellemelerle uğraşmak isteğe bağlıdır ve hatta muhtemelen bir engeldir; Güncellemelerle uğraşmanıza gerek olmadığını biliyorsanız, yapay kıyaslamalarda iyi görünen birçok basitleştirici varsayımda bulunabilirsiniz.


Dizininizle birden fazla eş zamanlı işlem yapabilmeyi veya dizini oluşturulduktan sonra güncellemeyi önemsiyorsanız, nasıl çalıştığını ve hangi ödünleşimlerin dahil olduğunu anlamak için biraz daha derinlere bakmanız gerekir.


İlk olarak, bildiğim tüm genel amaçlı vektör veritabanları grafik tabanlı indeksler kullanıyor. Bunun nedeni, ilk vektör eklenir eklenmez bir grafik indeksini sorgulamaya başlayabilmenizdir. Diğer seçeneklerin çoğu, ya dizini sorgulamadan önce tüm dizini oluşturmanızı ya da en azından bazı istatistiksel özellikleri öğrenmek için verilerin ön taramasını yapmanızı gerektirir.


Ancak grafik indeksi kategorisinde bile hala önemli uygulama detayları bulunmaktadır. Örneğin, ilk başta MongoDB Elastic ve Solr'un yaptığı gibi Lucene'nin HNSW indeks uygulamasını kullanarak zamandan tasarruf edebileceğimizi düşündük. Ancak kısa sürede Lucene'nin yalnızca tek iş parçacıklı, eş zamanlı olmayan dizin yapısı sunduğunu öğrendik. Yani, onu oluşturulurken sorgulayamazsınız (ki bu, bu veri yapısını kullanmanın temel nedenlerinden biri olmalıdır!) veya birden fazla iş parçacığının aynı anda oluşturmasına izin veremezsiniz.


HNSW makalesi, ince taneli bir kilitleme yaklaşımının işe yarayabileceğini öne sürüyor, ancak biz daha iyisini yaptık ve engellemeyen bir dizin oluşturduk. Bu açık kaynaklıdır JVektör .


JVector, eşzamanlı güncellemeleri doğrusal olarak en az 32 iş parçacığına ölçeklendirir. Bu grafik hem x hem de y eksenlerinde log ölçeğindedir ve iş parçacığı sayısını iki katına çıkarmanın derleme süresini yarıya indirdiğini gösterir.



Daha da önemlisi, JVector'un engellemesiz eşzamanlılığı, aramaları güncellemelerle birleştirerek daha gerçekçi iş yüklerine fayda sağlar. Farklı veri kümelerinde Astra DB'nin performansının (JVector kullanılarak) Pinecone ile karşılaştırmasını burada bulabilirsiniz. Astra DB, statik bir veri kümesi için Pinecone'dan yaklaşık %10 daha hızlı olmasına rağmen, yeni verileri indekslerken 8 ila 15 kat daha hızlıdır. Daha yüksek verim ve daha düşük gecikme önerilerine dayanarak Çam Kozalaklı mevcut en iyi kapsül katmanını (Bölme Türü: p2 ve Kapsül Boyutu: x8, kopya başına 2 bölmeyle) seçtik. Çam kozalağı bunun hangi fiziksel kaynaklara karşılık geldiğini açıklamıyor. Astra DB tarafında varsayılan PAYG dağıtım modelini seçtik ve sunucusuz olduğundan kaynak seçimi konusunda endişelenmemize gerek kalmadı. Testler kullanılarak yapıldı NoSQLBench .



Astra DB bunu daha yüksek geri çağırma ve hassasiyeti korurken yapıyor ( F1, geri çağırma ve hassasiyetin birleşimidir ) :




Sorun 4: Diskin etkili kullanımı

ile başladık HNSW grafik indeksleme algoritması çünkü dizini oluşturmak hızlıdır, sorgulaması hızlıdır, doğruluğu yüksektir ve uygulaması kolaydır. Ancak bunun bilinen bir dezavantajı vardır: Çok fazla bellek gerektirir.


Bir HNSW dizini, temel katmanın üzerindeki her katmanın bir öncekinin kabaca %10'u kadar düğüm içerdiği bir dizi katmandır. Bu, üst katmanların bir atlama listesi olarak hareket etmesini sağlayarak, aramanın tüm vektörleri içeren alt katmanın sağ komşuluğuna odaklanmasını sağlar.

Ancak bu tasarım, (tüm grafik indekslerinde olduğu gibi) "Disk önbelleği bizi kurtaracak" demekten kurtulamayacağınız anlamına gelir, çünkü normal veritabanı sorgusu iş yüklerinin aksine, grafikteki her vektörün neredeyse eşit başarı şansı vardır. bir aramayla alakalı olmak. (İstisna, önbelleğe alabileceğimiz ve yapabileceğimiz üst katmanlardır.)


Lucene'yi kullandığımızda, 64 GB RAM ile masaüstümde Vikipedi makale parçalarından (diskte yaklaşık 120 GB) oluşan 100 milyon vektör veri kümesini sunma profili şöyle görünüyordu:



Cassandra neredeyse zamanının tamamını diskteki vektörleri okumayı bekleyerek geçiriyor.


Bu sorunu çözmek için DiskANN adında daha gelişmiş bir algoritma uyguladık ve onu bağımsız bir gömülü vektör arama motoru olarak açık kaynaklı hale getirdik. JVektör . (Özellikle JVector, DiskANN'in şurada açıklanan artımlı sürümünü uygular. FreshDiskANN Kısaca, DiskANN, disk IOPS'sini azaltmak için HNSW'den daha uzun kenarları olan tek düzeyli bir grafik ve optimize edilmiş vektörler ve komşular düzeni kullanır ve benzerlik hesaplamalarını hızlandırmak için vektörlerin sıkıştırılmış bir temsilini bellekte tutar. Bu, Vikipedi iş yükünün veriminin üç katına çıkmasıyla sonuçlanır.


İstemci/sunucu bileşeni olmayan tamamen yerleşik bir senaryoda HNSW ile DiskANN arasındaki karşılaştırma şöyle görünüyor. Bu, Lucene (HNSW) ve JVector (DiskANN) altında Deep100M veri kümesini arama hızını ölçer. Lucene dizini, dizin ve ham vektörler dahil 55 GB'tır. JVector dizini 64GB'tır. Arama, dizini RAM'de tutmak için gereken belleğin yaklaşık üçte biri kadar belleğe sahip olan 24 GB MacBook'umda gerçekleştirildi.





Sorun 5: Şekillendirilebilirlik

Veritabanı sistemleri bağlamında şekillendirilebilirlik, çeşitli özelliklerin ve yeteneklerin tutarlı bir şekilde sorunsuz bir şekilde bütünleştirilmesi yeteneğini ifade eder. Bu, vektör arama gibi yeni bir yetenek kategorisinin entegrasyonu tartışılırken özellikle önemlidir. Oyuncak dışı uygulamalar her zaman hem klasik hem de REZİL veritabanı özelliklerinin yanı sıra yeni vektör araması.


Basit olanı düşünün Yapay zeka sohbet robotu Astra DB için örnek uygulama. Bu, kullanıcı sorularına yanıt vermek üzere LLM'ye uygun belgeleri sunmak için vektör aramayı kullanan, bulacağınız kadar saf bir RAG uygulamasıdır. Bununla birlikte, bunun gibi basit bir demoda bile, konuşma geçmişini almak için Astra DB'ye yine de "normal", vektör olmayan sorgular yapılması gerekir; bunun da LLM'ye yapılan her talebe dahil edilmesi gerekir, böylece zaten olanı "hatırlayabilir". gerçekleşti. Dolayısıyla anahtar sorgular şunları içerir:


  1. Kullanıcının sorusuna en uygun belgeleri (veya belge parçalarını) bulun
  2. Kullanıcının konuşmasındaki son yirmi mesajı al


Daha gerçekçi bir kullanım örneğinde, çözüm mühendislerimizden biri kısa süre önce Asya'da ürün kataloğuna anlamsal arama eklemek isteyen ancak aynı zamanda terime dayalı eşleştirmeyi de etkinleştirmek isteyen bir şirketle çalışıyordu. Örneğin, kullanıcı [“kırmızı” küresel vana] araması yaparsa, vektör yerleştirmeleri semantik olarak ne kadar benzer olursa olsun, aramayı açıklaması “kırmızı” terimiyle eşleşen öğelerle sınırlamak ister. O halde temel yeni sorgu (oturum yönetimi, sipariş geçmişi ve alışveriş sepeti güncellemeleri gibi klasik işlevlerin yanı sıra) şu şekildedir: Ürünleri, alıntılanan tüm terimleri içeren ürünlerle sınırlandırın, ardından kullanıcının aramasına en benzer olanı bulun


Bu ikinci örnek, uygulamaların hem klasik sorgu işlevselliğine hem de vektör aramaya ihtiyaç duyduğunun yanı sıra çoğu zaman her birinin öğelerini aynı sorguda kullanabilmeleri gerektiğini açıkça ortaya koymaktadır.


Bu genç alandaki mevcut teknoloji, benim "normal" bir veritabanında klasik sorgular dediğim şeyi yapmaya çalışmak, bir vektör veritabanında vektör sorguları yapmak ve daha sonra her ikisi de birbirine bağlandığında bu ikisini geçici bir şekilde bir araya getirmektir. aynı anda gereklidir. Bu hataya açık, yavaş ve pahalıdır; tek erdemi, daha iyi bir çözüm bulana kadar onu çalıştırabilmenizdir.


Astra DB'de Cassandra SAI'nin üzerine daha iyi bir çözüm geliştirdik (ve açık kaynaklı). SAI, tamamı Cassandra kararlı ve sıkıştırma yaşam döngüsüne bağlı özel dizin türleri oluşturmaya izin verdiğinden, Astra DB'nin geliştiricilerin hiçbir ek yük olmadan boole yüklemlerini, terim tabanlı aramayı ve vektör aramasını karıştırıp eşleştirmesine olanak tanıması kolaydır. ayrı sistemleri yönetme ve senkronize etme. Bu, üretken yapay zeka uygulamaları geliştiren geliştiricilere, daha fazla üretkenlik ve daha hızlı pazara çıkış süresi sağlayan daha gelişmiş sorgu yetenekleri sağlar.


Sarmak

Vektör arama motorları, ölçeği genişletme, çöp toplama, eş zamanlılık, diskin etkili kullanımı ve şekillendirilebilirlik dahil olmak üzere birden fazla mimari zorluğa sahip önemli ve yeni bir veritabanı özelliğidir. Astra DB için vektör araması oluştururken, üretken yapay zeka uygulamaları geliştiricilerine sınıfının en iyisi deneyimi sunmak amacıyla Cassandra'nın yeteneklerinden yararlanabildiğimize inanıyorum. Astra DB hakkında daha fazla bilgiyi burada bulabilirsiniz veya vektör arama algoritmalarını yakından ve kişisel olarak öğrenmek istiyorsanız şuraya göz atın: JVektör .



- Jonathan Ellis tarafından, DataStax