SQLite için yeni vektör arama eklentisi `sqlite-vec` geliştiriliyor
(alexgarcia.xyz)- Mevcut
sqlite-vsssınırlamalarını azaltmak içinsqlite-vec, saf C tabanlı bir gömülü vektör arama eklentisi olarak geliştiriliyor ve SQLite’ın çalıştığı tüm ortamları hedefliyor - SQL kullanım akışı
CREATE VIRTUAL TABLE,INSERT INTO,SELECTetrafında sadeleştiriliyor ve KNN tarzı arama ile JSON ve compact binary vektör girdilerini destekliyor - Faiss bağımlılığı kaldırılarak yalnızca Linux ve macOS değil, Windows, WebAssembly, mobil ve Raspberry Pi de hedefleniyor; ikili boyutun da mevcut 3MB~5MB yerine birkaç yüz KB seviyesinde olması bekleniyor
- Vektörler shadow table içindeki chunk birimleri halinde saklanarak tamamını RAM’e yükleme ihtiyacı azaltılıyor ve
PRAGMA mmap_sizeile bellek tabanlı arama hızı artırılabiliyor - İlk sürüm yalnızca exhaustive full-scan sunacak ve ANN içermeyecek;
sqlite-vec.ciçindeki 246 TODO tamamlandıktan sonrav0.1.0sürümünün çıkması planlanıyor
sqlite-vec ile değişmesi amaçlanan SQLite vektör araması
sqlite-vec, saf C ile yazılan yeni bir SQLite eklentisi ve Şubat 2023’te duyurulansqlite-vssyerine geçmesi hedeflenen bir proje- Hedef kapsam; hızlı vektör araması için kullanıcı tanımlı SQL fonksiyonları, sanal tablolar (virtual table), vektör işlemleri için araçlar ve yardımcı programları da içeriyor
- nicemleme
- JSON/BLOB/numpy dönüşümleri
- vektör aritmetiği
- Kullanıcılar yalnızca saf SQL ile bir vektör deposu oluşturup arama yapabiliyor
CREATE VIRTUAL TABLEile vektörler için sanal tablo oluşturmaINSERT INTOile vektör eklemeSELECT ... WHERE sample_embedding MATCH ... ORDER BY distance LIMIT ...biçiminde KNN tarzı arama
- Vektör girdisi olarak JSON dizgesi veya compact binary biçimi kullanılabiliyor
Saf C ve bağımlılıksız yapının açtığı çalışma ortamları
sqlite-vec, bağımlılıksız saf C eklentisi olmayı hedefliyor ve bu tercih, desteklenen platformları genişletmenin temel koşulu olarak görülüyor- Mevcut
sqlite-vss, C++ bağımlılığı nedeniyle yalnızca Linux ve macOS’ta istikrarlı çalışıyordu ve ikili boyutu 3MB~5MB aralığındaydı - Yeni eklenti şu ortamlarda çalışmayı hedefliyor
- Linux
- macOS
- Windows
- tarayıcıdaki WebAssembly
- mobil cihazlar
- Raspberry Pi gibi küçük cihazlar
- Beklenen ikili boyutu birkaç yüz KB aralığında
Bellek kullanımı ve arama hızını ayarlama
sqlite-vec, vektörleri shadow table içindeki chunk’lara bölerek saklama yöntemiyle bellek kullanımını kontrol ediyor- KNN araması sırasında tüm vektörler bir anda RAM’e yüklenmiyor, chunk bazında okunuyor
- Böylece tüm vektörlerin bellekte sürekli tutulması gerekmiyor
- Bellek tabanlı hız gerektiğinde SQLite’ın
PRAGMA mmap_sizeözelliği kullanılarak KNN araması hızlandırılabiliyor
Yeni vektör özellikleri ve ilk kısıtlar
sqlite-vec, güncel vektör arama araçları ve araştırma eğilimlerini yansıtacak şekilde şu özellikleri daha iyi desteklemeyi amaçlıyor- uyarlanabilir uzunlukta embedding’ler, yani Matryoshka embeddings
int8vebitvektörleri- binary and scalar quantization
- Bu özellikler, vektörlerin hız, doğruluk ve disk kullanımı üzerinde daha ince ayar yapabilmek için temel oluşturuyor
- İlk
sqlite-vecsürümü yalnızca exhaustive full-scan vektör aramasını destekleyecek- “approximate nearest neighbors” seçeneği başlangıçta olmayacak
- IVF ve HNSW ise gelecekte eklenmesi umulan özellikler
Tarayıcı demosunun yapısı
- Demo, tarayıcıda çalışan
sqlite-veckullanıyor - Geliştirici araçlarında görülebilen yapı şu bileşenlerden oluşuyor
- optimize edilmemiş 5.9MB
sqlite3.wasm sqlite-vecderlenmiş resmî SQLite WASM derlemesi- 2.6MB boyutunda
movies.bit.dbSQLite veritabanı
- optimize edilmemiş 5.9MB
movies.bit.db, TMDB film meta verileri temel alınarak hazırlanmış 4.800 film overview kaydınıarticlestablosunda içeriyor- Ayrı
vec_moviessanal tablosu ise bu overview embedding’lerinin vektör indeksini oluşturuyor- embedding’ler için Nomic 1.5 embeddings model kullanılıyor
- vektörler binary vector olarak nicemleniyor
Demo verisi ve KNN arama akışı
articlestablosundatitle,release_date,overviewgibi sütunlar bulunuyoroverviewsütunu, film özetlerini kısa cümlelerle içeriyor ve demoda embedding hedefi olarak kullanılıyorvec_moviessanal tablosu,articles.overviewembedding’lerinioverview_embeddingssütununda saklıyor- vektörler 768 boyutlu binary vector
- saklama boyutu
768 / 8 = 96, yani 96 bayt
- Kullanıcı radyo düğmesiyle bir film seçtiğinde, seçilen film kimliği KNN SQL sorgusundaki
:selected_movieparametresine yerleştiriliyor - Arama sonucu, seçilen filme en yakın 10 filmden oluşuyor
- binary vector kullanıldığı için uzaklık hesabında hamming distance kullanılıyor
- en yakın sonuç her zaman aynı film oluyor ve uzaklığı 0 çıkıyor
- Kısa tek cümlelik özetlerin ve küçük bir film veri kümesinin embedding’e dönüştürülmesi en yüksek kaliteyi vermiyor; binary quantization da kaliteyi daha da düşürüyor, ancak odak noktası tarayıcı içinde hızlı ve “yeterince iyi” vektör aramasını göstermek
- İç işleyişi görmek için
SELECTönüneEXPLAIN QUERY PLANeklenebilir; buradavec_moviestarafından kullanılan0:knn“index” görülebilir
sqlite-vss sınırlamaları ve Faiss bağımlılığı
sqlite-vssgeliştirme ve benimsenme sürecinde çeşitli engeller vardı- yalnızca Linux ve macOS’ta çalışıyor, Windows, WASM, mobil cihazlar gibi ortamları desteklemiyor
- tüm vektörleri bellekte tutuyor
- transaction ile ilgili hata ve sorunlar barındırıyor
- derlenmesi çok zor ve çok zaman alıyor
- scalar/binary quantization gibi yaygın vektör işlemleri eksik
- Bu sorunların neredeyse tamamı
Faissbağımlılığından kaynaklanıyor - Bazı sorunlar çok zaman ve emekle çözülebilir olsa da, önemli bir kısmı Faiss nedeniyle tıkanabiliyor
- Bağımlılıksız düşük seviyeli bir çözüm cazip bir seçenek haline geldi ve vektör aramasının aslında o kadar da karmaşık olmadığı değerlendirmesiyle
sqlite-vecortaya çıktı
Sürüm durumu ve sponsorluk çağrısı
sqlite-vecçekirdek işlevleri çalışıyor, ancak hata işleme ve testler hâlâ çok yetersizsqlite-vec.cdosyasında 246 TODO kalmış durumdatodo_assert()191 adet// TODOyorumu 41 adettodo panic14 adet- toplam ilerleme
sqlite-vec v0için 0/246, yani %0 olarak gösteriliyor
- 246 TODO tamamlandığında ilk
v0.1.0sürümü yayımlanacak- belgeler
- demo
- binding’ler
- diğer bileşenler birlikte sunulacak
- Hedef süre yaklaşık bir ay olsa da kesinleşmiş bir takvim yok
sqlite-vecbaşarısıyla ilgilenen şirketlerden sponsorluk aranıyor ve e-posta ile iletişime geçilebiliyor
1 yorum
Hacker News yorumları
Yazarıyım — sorunuz varsa yanıtlarım. Bu, resmi bir sürümden çok “yeni bir proje üzerinde çalışıyorum” niteliğinde; uzantının kendisi de hâlâ geliştirme aşamasında. Proje bağlantısı: https://github.com/asg017/sqlite-vec
Bu uzantının v0.1.0 sürümünün nasıl görüneceğine dair oldukça net bir resmim var, ama oraya varmak birkaç hafta daha sürecek gibi. Bu yazının amacı daha çok daha önce yaptığım SQLite vektör arama uzantısı sqlite-vss kullanıcılarına sırada ne olduğunu duyurmaktı; hazır olduğunda daha büyük bir sürüm duyurusu olacak
Genel olarak kolayca gömülebilen bir vektör arama alternatifine sahip olacağımız için çok heyecanlıyım. Tüm işletim sistemlerinde, WASM’de, mobil cihazlarda, Raspberry Pi’de vb. çalışması özellikle güzel; kişisel olarak da Beepy üzerinde küçük bir anlamsal arama uygulaması çalıştırmayı deniyorum, bu da eğlenceli
[0] https://beepy.sqfmi.com/
sqlite-vss ile karşılaştırmalı performansı da bilmek isterim. Hem sorgu hızı hem de bellek kullanımı için profil çıkarma rakamlarını merak ediyorum
Genel olarak gerçekten harika görünüyor ve bu yönü seviyorum
Başta sqlite-vec’in yalnızca tam kapsamlı brute-force vektör aramasını destekleyip yaklaşık en yakın komşu (ANN) seçeneği sunmaması, ama daha sonra IVF ve HNSW eklemek istemesi yaklaşımının %1000 doğru olduğunu düşünüyorum. En baştan aşırı karmaşık hâle getirmemesi hoşuma gidiyor
Daha önce cihaz üzerinde vektör aramayı yayına almıştım; 128 bit ikili vektörler ve Hamming uzaklığı kombinasyonunda, veritabanı 200 binden fazla öğe içerse bile her kamera karesinde tam brute-force uzaklık araması çalıştıracak kadar hızlıydı. Düşük seviye telefonlarda bile 10 fps’nin üzerinde çıkıyordu, iyi telefonlarda ise çok akıcıydı. Brute force’un yeterli olduğu durumlar şaşırtıcı derecede fazla
Ancak HNSW gibi ANN algoritmalarını uygularken bunu tablo indeksi paradigmasıyla ele alabilmek harika olurdu. Böylece brute-force aramadan ANN’e geçmek, tabloya indeks oluşturmak kadar basit olur; farklı ANN algoritmaları ve parametreleriyle denemeler yapmak da indeks oluşturma parametrelerini ayarlayarak mümkün olur. Belki zaten bu yöndedir, ama yine de belirtmek istedim
sqlite-httpvfs ile birlikte derleyip derlemediğinizi de merak ediyorum. Bu projeyle iyi uyum sağlayacak gibi: https://github.com/phiresky/sql.js-httpvfs
Ortak bir SQL vektör DSL’i için pgvector ile sözdizimi uyumlu hâle getirmeyi de düşündünüz mü merak ediyorum. Eksilerinin artılarından çok daha küçük olmayabileceğini düşünüyorum, ama mümkün mü merak ediyorum
https://observablehq.com/@asg017/introducing-sqlite-loadable...
sqlite-vss birkaç projede zaten iyi şekilde kullanılıyor
“768 boyutlu ikili vektör olduğu için 96 bayt yer kaplıyor (768 / 8 = 96)” kısmı kafamı karıştırdı. Çoğu vektör deposunun yaşadığı sorun olan boyutluluğun laneti tam da bu kısım ve bunun indekslemeden önce gelen bir problem olduğunu düşünüyorum
Muhtemelen 768 boyut * 8 bayt (f64), yani 6144 bayt demek istenmiştir diye düşündüm. Genelde biraz kaybı göze alarak f32’ye, f16’ya ya da daha küçük bir gösterime indirgenir
Sıkıştırma veya trie benzeri amortize yöntemlerle 768 boyutu 96 bayta sığdırmanın bir yolu varsa bunu ayrı bir yazıda daha fazla duymak isterim. Her boyutu 1 bit olarak ele alıyorsanız bunu anlarım, ama o zaman arama kalitesi konusunda hâlâ merak ettiğim noktalar var
nomic v1.5[0] veya mixedbread’in yeni modeli[1] gibi bazı gömme modelleri, ikili kuantizasyondan sonra da kaliteyi koruyacak şekilde özel olarak eğitiliyor. Her model için böyle değil, dolayısıyla sonuçlar değişebilir. Genel olarak OpenAI’nin 3072 boyutlu büyük gömme modeli gibi çok büyük vektörlerde, bunun için özel olarak eğitilmemiş olsa bile bir ölçüde işe yarıyor gibi görünüyor
[0] https://twitter.com/nomic_ai/status/1769837800793243687
[1] https://www.mixedbread.ai/blog/binary-mrl
Verilerde FAISS indeksi kullanıp Ürün Kuantizasyonu (Product Quantization) uygularsanız, ikili özellikler için PQ768x1 gibi bir yöntemle ikili vektörleri deneyebilir; ayrıca her vektör çifti için dört değerden birine kuantize etme gibi yaklaşımları da karşılaştırabilirsiniz: https://github.com/facebookresearch/faiss/wiki/The-index-fac...
Vektör veritabanlarında genellikle veriler depolanmadan önce daha düşük boyutlu bir uzaya sıkıştırıldığı veya projekte edildiği için bu durum aksine iyileşir
sqlite-vss sayesinde RAG’in nasıl çalıştığını öğrenip bir oyuncak projede uygulayabildim. Hata ayıklaması biraz zordu ama doğru ayarlayınca Ubuntu’da kusursuz çalıştı ve hâlâ kullanıyorum
Sınırlayıcı bağımlılıklar olmadan daha iyi yeni bir sürüm yapılıyor olması sevindirici
Yalnızca herkese açık SQLite API’lerini mi kullanmayı planladığınızı, yoksa SQLite amalgamation’a eklenen bir biçim mi öngördüğünüzü merak ediyorum
Bu tür bir özelliğe kesinlikle ilgim var, ancak Wasm tabanlı Go binding’lerinde SQLite’tan ayrı olarak nasıl dağıtacağımı düşünmem gerekiyor. Şimdiye kadar Wasm “dinamik linkleme”den çok daha basit olduğu için tüm C kodunu paketleyip dağıtıyordum
Ayrıca artımlı BLOB giriş/çıkışından bahsetmişsiniz; muhtemelen biliyorsunuzdur ama büyük BLOB’ların sayfaların bağlı listesi olarak saklandığını, bu yüzden BLOB giriş/çıkışının asla rastgele erişim olmadığını akılda tutmak gerekir
wazero SQLite binding’lerini gerçekten seviyorum. Aslında 1) sqlite-vec için CGO binding’leri ve 2) go-sqlite3’te doğrudan kullanılabilecek özel bir WASI derlemesi sqlite-vec sunmayı planlıyorum. Başta o depodaki build script’lerini kullanarak sqlite3.wasm dosyasını oluşturmayı düşünüyordum. Projede doğrudan desteklemek isterseniz sqlite-vec.c/h dosyasını go-sqlite3/sqlite3 içine koymak yeterli olabilir
Artımlı BLOB giriş/çıkışını zor yoldan öğrendim. sqlite-vec’in sorgu hızında kesinlikle sınırlayıcı bir etken. Parça boyutunu nispeten küçük, düşük MB seviyelerinde tutup page_size’ı artırınca denge fena olmuyordu; ama özellikle page_size’ın yan etkileri var. PRAGMA mmap_size da sayfaları bellekte tutarak overflow okumalarını hızlandırıyor gibi göründüğü için çok yardımcı oluyor, ama doğal olarak bellek kullanımı çok daha fazla artıyor. Zor bir denge
DuckDB bugün “Vector Similarity Search in DuckDB” eklentisini duyurdu
https://duckdb.org/2024/05/03/vector-similarity-search-vss.h...
DuckDB VSS kullanınca embedding üretip DuckDB formatında sakladıktan sonra CDN içinde SQL çalıştırarak halledilebilecek gibi görünüyor
Bu tarzdaki projeleri seviyorum. Çok belirli bir problemi hedefleyen bir açık kaynak proje olması hoşuma gidiyor
TypeScript/Next.js/React ekosisteminde de teknik bir nişte çok faydalı bir şey yapabilir miyim diye sürekli düşünüyorum ama henüz ilham gelmedi
Yapay zeka RAG uygulaması olan https://github.com/rnadigital/agentcloud içinde uçtan uca otomasyon için Qdrant vektör DB kullandık; bir devam projesi yaptığınızı duyduğuma sevindim. Ne zaman kullanıma hazır olacağını ve hızlı başlangıç kılavuzu olup olmadığını merak ediyorum
Blog yazımına da yardımcı olabilirim
Dokümante edilmemiş bir
sqlite-vecpip paketi var; Python’daki “Agent Backend” üzerinden doğrudan çağırmak isterseniz şimdiden deneyebilirsinizBu, “README odaklı geliştirme”nin nasıl görüneceğini hayal ettiğime oldukça benziyor. Yazarın önce dokümantasyonla başlayıp başlamadığını merak ediyorum
Ancak “%20 çabayla %80’ini yapmış” haldeyim; kalan %20 olan hata işleme, fuzz testleri ve doğruluk testleri zamanın %80’ini alacak gibi. Yine de insanlar mevcut
sqlite-vssdurumu hakkında zaten sorular soruyor, bu yüzden bu “devam eden çalışma” blog yazısının bazı sorulara yanıt verebileceğini düşündümÖnce dokümantasyonla başlama fikrini de seviyorum. Özellikle SQLite eklentilerinde SQL API’sinin nasıl göründüğü, yani skaler fonksiyonlar ve sanal tablolar vb. gerçekten önemli. Kodun çoğunu yazmadan önce sqlite-vec’in SQL tarafının nasıl görünmesi gerektiğini epeyce taslak olarak çıkardım
[0] https://github.com/asg017/sqlite-vec/blob/main/sqlite-vec.c
Birkaç ay önce SQLite-vss’e açtığım GitHub issue’suna verilmiş bir yanıta yakın gibi. Teknik olarak o issue’ya bir yanıt olmasa da
https://github.com/asg017/sqlite-vss/issues/124
Aslında o bileti ilk okuduğumda “sqlite-vss’i nasıl daha iyi hale getirebilirim” tavşan deliğine girdim ve sonunda “sqlite-vec’i yapmalıyım” noktasına geldim. Bu yola girmeme yardımcı olduğunuz için teşekkürler
sqlite-vec’in yerleşik ikili kuantalamasını kullanırsanız kabaca şöyle yapabilirsiniz:
CREATE VIRTUAL TABLE vec_files USING vec0 ( contents_embedding bit[1536] );INSERT INTO vec_files(rowid,contents_embedding) VALUES ((1, vec_quantize_binary( /* 1536-dimension float vector here*/)))Tarayıcı içinde çalışırken sqlite-vec’in verileri tarayıcının yerel IndexedDB’sinde kalıcı hale getirip getiremeyeceğini merak ediyorum. Yoksa bu kısmı kullanıcının kendisinin mi yönetmesi gerektiğini bilmek istiyorum
Henüz üzerine düşünmedim şeklinde bir yanıt olsa bile, bu yöndeki düşüncelerinizi paylaşırsanız memnun olurum
IndexedDB’nin özel olarak desteklenip desteklenmediğinden emin değilim, ancak localStorage/OPFS VFS kullanılabilir
[0] https://sqlite.org/wasm/doc/trunk/persistence.md#kvvfs