Vector Databases

pgvector'ın Gücünü Serbest Bırakmak: PostgreSQL'de Gelişmiş Vektör Araması

Yıllardır "çok dilli kalıcılık" (polyglot persistence) deseni, veri türlerinin farklı depolama motorları gerektirdiğini empoze ediyordu. İşlemsel veriler ilişkisel veritabanlarında yaşarken, yapılandırılmamış günlükler belge depolarına gidiyordu. Ancak Üretken Yapay Zeka ve Büyük Dil Modelleri'nin (LLM) yükselişi, bu paradigmayı zorlayan yeni bir veri türü tanıttı: vektör. Uygulamalar giderek daha fazla anlamsal arama ve benzerlik eşleştirmesine bağımlı hale geldikçe, yüksek boyutlu dizilerin yönetimi kritik bir öneme sahip hale geldi. İşte bu noktada sahneye pgvector çıkıyor; dünyanın en popüler ilişkisel veritabanına yerel vektör benzerlik araması getiren güçlü bir PostgreSQL eklentisi.

Neden pgvector?

Geliştiriciler, vektör araması uygularken genellikle bir ikilemle karşı karşıya kalır: Pinecone veya Weaviate gibi uzmanlaşmış bir vektör veritabanı ekleyerek operasyonel karmaşıklığı ve veri senkronizasyonunu mu artırsın, yoksa mevcut altyapısına mı bağlı kalsın? pgvector, vektörleri doğrudan ilişkisel verileriniz içinde saklamanıza ve aramanıza izin vererek bu sorunu çözer.

Temel avantajlar şunları içerir:

  • ACID Uyumu: Vektör verileri işlemseldir. Bir ekleme işlemi başarısız olursa, vektörü güncelleyebilir ve değişiklikleri geri alabilirsiniz; bu özellik, NoSQL vektör depolarında genellikle eksiktir.
  • Birleştirme (Join) Yetenekleri: Vektör arama sonuçlarını diğer iş mantığıyla (ör. kullanıcı profilleri, izinler) tek bir SQL sorgusunda birleştirebilirsiniz.
  • Operasyonel Sadelik: Zaten PostgreSQL kullanıyorsanız, ayrı bir küme (cluster) bakımı yapmanıza gerek yoktur. Yedekleme, izleme ve ölçeklendirme stratejileri tutarlı kalır.

Yola Çıkış: Şema Tasarımı

pgvector'ı kurmak basittir. Öncelikle, eklentinin PostgreSQL örneğinizde yüklendiğinden emin olun (13 veya üzeri sürüm önerilir). Ardından, eklentiyi oluşturun ve tablonuzu tanımlayın:

CREATE EXTENSION vector;

CREATE TABLE embeddings (
    id BIGSERIAL PRIMARY KEY,
    metadata JSONB,
    embedding VECTOR(384) -- 384 boyutlu bir vektör varsayılıyor
);

VECTOR(384) tipine dikkat edin. Boyut, gömme (embedding) modelinizin çıktı boyutuyla eşleşmelidir (ör. OpenAI'nin text-embedding-ada-002 modeli 1536 boyutlu vektörler üretirken, bazı yerel modeller 384 boyutlu vektörler üretir). Eşleşmeyen boyutlar, ekleme sırasında bir hata ile sonuçlanacaktır.

İndeksleme Stratejileri: HNSW vs. IVFFlat

Kaba kuvvet taraması (brute-force scanning) küçük veri kümeleri için (10k satırın altı) uygulanabilir, ancak veri büyüdükçe performans doğrusal olarak düşer. Ölçeklendirmek için bir indeks kullanmanız gerekir. pgvector iki temel algoritmayı destekler:

1. IVFFlat (Düz Kuantizasyonlu Ters Dosya İndeksi)

IVFFlat, vektörleri k-means kullanarak sabit sayıda listeye kümeleştirir. Sorgu zamanında, yalnızca en yakın kümeleri (probeları) arar. Bellek açısından verimlidir ve büyük veri kümeleriyle okuma ağırlıklı iş yükleri için harikadır.

2. HNSW (Hiyerarşik Gezilebilir Küçük Dünya)

HNSW, vektörlerin bir grafik yapısını oluşturur. Daha yüksek geri çağırma (recall) ve daha hızlı sorgu süreleri sunar, ancak hem indeksleme hem de sorgulama sırasında önemli ölçüde daha fazla RAM gerektirir. Gecikmenin kritik olduğu çoğu modern yapay zeka uygulaması için HNSW tercih edilen seçimdir.

Bir HNSW indeksi oluşturmanın yolu şudur:

CREATE INDEX ON embeddings 
USING hnsw (embedding vector_cosine_ops);

Not: vector_cosine_ops operatör sınıfı, mesafe metrikini belirler. Ayrıca vector_l2_ops (Öklid) veya vector_ip_ops (İç Çarpım) da kullanabilirsiniz. Modelinizin çıktı normalizasyonuna göre seçim yapın.

Anlamsal Arama Yapma

İndeksleme yapıldıktan sonra, benzerlik araması standart bir SQL sorgusu gibi görünür. Diyelim ki bir kullanıcı sorgu vektörünüz var: [0.1, 0.5, ...] (384 boyut). Kosinüs mesafe operatörünü (<=>) kullanarak en benzer 10 kaydı bulabilirsiniz.

SELECT 
    id, 
    metadata, 
    embedding <=> '[0.1, 0.5, ...]' AS distance
FROM 
    embeddings
ORDER BY 
    distance
LIMIT 10;

Sonuç, mesafeye göre sıralanır. Kosinüs benzerliği için, 0 mesafe aynı vektörleri, 2 mesafe ise zıt vektörleri ifade eder. Birçok geliştirici, bunun yerine benzerlik puanını döndürmeyi tercih eder. Bunu, mesafeyi benzerlik puanına dönüştürerek elde edebilirsiniz:

SELECT 
    id, 
    metadata, 
    1 - (embedding <=> '[0.1, 0.5, ...]') AS similarity
FROM 
    embeddings
ORDER BY 
    embedding <=> '[0.1, 0.5, ...]'
LIMIT 10;

Performans Ayarlama İpuçları

  • Doğru Metriği Seçin: Gömmeleriniz (embeddings) birim uzunluğa normalize edildiyse, Kosinüs Benzerliği ve Öklid Mesafesi matematiksel olarak eşdeğerdir. Bu durumda, genellikle daha hızlı hesaplandığı için L2 (<->) kullanın. Normalize edilmediyse, daha iyi anlamsal doğruluk için Kosinüs (<=>) ile devam edin.
  • HNSW Parametrelerini Ayarlayın: m parametresi, düğüm başına bağlantı sayısını kontrol eder (daha yüksek = daha doğru ama daha büyük indeks). ef_search parametresi, arama sırasında dikkate alınan aday sayısını kontrol eder (daha yüksek = daha yavaş ama daha doğru). Varsayılanlarla başlayın (m=16) ve geri çağırmanızın (recall) kabul edilebilir seviyelerin altına düştüğünü fark ederseniz ef_search değerini artırın.
  • Bölümleme (Partitioning): Çok kiracılı (multi-tenant) uygulamalar için, tablonuzu kiracı kimliğine göre bölümlemeyi düşünün. Bu, vektör arama işlemlerinin yalnızca ilgili bölümleri taramasını sağlar ve G/Ç (I/O) ile bellek kullanımını önemli ölçüde azaltır.

Sonuç

pgvector, niş bir eklentiden yapay zeka destekli uygulamalar için üretim-olmaya hazır bir çözüme olgunlaştı. Geleneksel ilişkisel veriler ile modern anlamsal arama arasındaki boşluğu doldurarak, geliştiricilere güvenli, ölçeklenebilir ve bakımı kolay birleşik bir platform sunar. Uzmanlaşmış vektör veritabanları, milyar ölçeğindeki veri kümeleri için hâlâ uç durum optimizasyonları sunabilirken, pgvector, performans, esneklik ve operasyonel sadeliğin mükemmel dengesini sağlayarak yapay zeka uygulamalarının büyük çoğunluğu için en iyi seçim olmaya devam etmektedir.

Share: