Embedding ve vektor veritabani

Bir arama kutusuna "ucuz dizüstü bilgisayar" yazdığınızda, klasik bir veritabanı tam olarak bu kelimeleri içeren satırları arar. Ama "uygun fiyatlı taşınabilir bilgisayar" yazan bir belgeyi kaçırır, çünkü harfler tutmaz. İşte modern yapay zeka sistemlerinin altında yatan kırılma noktası tam burası: anlamı harflerle değil, sayılarla temsil etmek. Bu yazıda embedding (gömme vektörler) ve vektör veritabanlarının gerçekte nasıl çalıştığını, hangi matematiğe yaslandığını ve hangi gerçek araçlarla hayata geçtiğini adım adım ele alıyoruz.

Embedding nedir? Anlamı koordinata çevirmek

Embedding, bir metni (ya da görseli, sesi) sabit uzunlukta bir sayı dizisine, yani bir vektöre dönüştürmektir. Örneğin bir cümle 384, 768 veya 1536 boyutlu bir vektöre çevrilir. Bu vektörü çok yüksek boyutlu bir uzayda bir nokta gibi düşünebilirsiniz. Buradaki temel fikir şudur: anlamca yakın şeyler bu uzayda birbirine yakın noktalara düşer.

Bu yaklaşımın kökeni 2013'te Tomas Mikolov ve ekibinin Google'da yayımladığı word2vec çalışmasına dayanır. Makale, kelimeleri sürekli vektör uzayında temsil etmek için iki mimari önerir: CBOW (bağlam kelimelerinden hedef kelimeyi tahmin eden) ve Skip-Gram (hedef kelimeden bağlamı tahmin eden). Bu modellerin çarpıcı yanı, ortaya çıkan vektörlerin aritmetik özellikler taşımasıydı; "kral" eksi "erkek" artı "kadın" işlemi sizi "kraliçe" vektörüne yakın bir yere götürebiliyordu. Yani anlam, geometriye dökülmüştü.

Bugün kullandığımız embedding modelleri word2vec'ten çok daha gelişmiş; tek tek kelimeler yerine cümlenin tamamının bağlamını kavrayan Transformer tabanlı modeller kullanılıyor. Ama temel sezgi aynı kaldı: metni, üzerinde mesafe ölçebileceğimiz bir koordinata indirgemek.

Anlamsal arama muhendisligi

Benzerlik nasıl ölçülür? Kosinüs ve mesafe

İki vektörün ne kadar benzer olduğunu ölçmek için birkaç yöntem var. En yaygını kosinüs benzerliğidir. Kosinüs benzerliği, iki vektör arasındaki açının kosinüsünü hesaplar; yani vektörlerin uzunluğunu değil, yönünü karşılaştırır. İki nokta çarpımının, vektör uzunluklarının çarpımına bölünmesiyle bulunur. Sonuç 1'e yaklaştıkça vektörler aynı yöne, yani aynı anlama bakıyor demektir; 0'a yaklaştıkça ilgisizleşir.

Neden açı da uzunluk değil? Çünkü bir metnin embedding'inde önemli olan genellikle "hangi yöne" işaret ettiğidir, vektörün büyüklüğü değil. Bu yüzden anlamsal aramada kosinüs çok pratiktir. Bunun yanında başka metrikler de kullanılır:

  • L2 (Öklid) mesafesi: İki nokta arasındaki düz çizgi mesafesi. Küçük değer, yakınlık demektir.
  • İç çarpım (dot product / inner product): Vektörler normalize edildiğinde kosinüsle aynı sonucu verir ve hesaplaması hızlıdır; öneri sistemlerinde sık kullanılır.

Anlamsal arama (semantic search) dediğimiz şey özünde basit bir döngüdür: kullanıcının sorgusunu da embedding'e çevir, sonra veritabanındaki tüm vektörlerle benzerliğini ölç, en yakın olanları geri döndür. Sorun şu ki milyonlarca vektörle bunu tek tek yapmak pahalıdır.

Vektor uzayi temsili

Milyonlarca vektörde aramak: ANN ve HNSW

Her sorguda veritabanındaki her vektörle karşılaştırma yapmaya kaba kuvvet (brute-force) veya tam (exact) arama denir. Birkaç bin vektör için sorun değil; ama on milyonlarca vektörde her sorgu için tüm koleksiyonu taramak gerçek zamanlı uygulamalar için fazla yavaştır.

Çözüm, Yaklaşık En Yakın Komşu (ANN, Approximate Nearest Neighbor) aramasıdır. Buradaki anlaşma açıktır: mükemmel doğruluktan (recall) küçük bir taviz verir, karşılığında muazzam hız kazanırsınız. Çoğu uygulamada en yakın 10 sonuçtan 9-10'unu doğru getirmek, hepsini taramaktan kat kat hızlı olduğu için fazlasıyla yeterlidir.

ANN dünyasının en etkili algoritması, 2016'da Yu. A. Malkov ve D. A. Yashunin'in yayımladığı HNSW (Hierarchical Navigable Small World)'dür. HNSW, vektörleri katmanlı bir yakınlık grafiği olarak örgütler. Mantığını şöyle düşünebilirsiniz:

  • Üst katmanlar seyrektir ve yalnızca az sayıda "otoyol" düğüm içerir; uzak mesafeleri hızla kat etmenizi sağlar. Bir düğümün hangi en üst katmana çıkacağı, üssel azalan bir olasılıkla rastgele seçilir.
  • Alt katmanlar yoğunlaşır; hedefe yaklaştıkça ince ayar yaparsınız.
  • Arama en üst katmandan başlar, kabaca doğru bölgeye atlar, sonra aşağı inerek komşuluğu hassaslaştırır.

Bu katmanlı yapı sayesinde arama, koleksiyon büyüdükçe doğrusal değil, logaritmik bir hızla ölçeklenir; yani veri 10 kat büyüdüğünde arama süresi 10 kat değil, çok daha az artar. HNSW bugün neredeyse tüm ciddi vektör veritabanlarının varsayılan indeksleme yöntemidir. Bir alternatif olarak IVF (Inverted File) ailesi vardır; bu yöntem vektör uzayını önceden kümelere böler ve sorgu sırasında yalnızca en yakın birkaç kümeyi tarar. IVF, indeks oluşturması daha hızlı ve daha az bellek harcayan bir seçenektir, ama hız-doğruluk dengesinde genellikle HNSW'nin gerisinde kalır.

Gerçek araçlar: FAISS, pgvector ve yönetilen servisler

Teori güzel ama bu işi pratikte yapan, gerçekten var olan ve yaygın kullanılan araçlar şunlardır:

FAISS

FAISS (Facebook AI Similarity Search), Meta AI Research tarafından geliştirilen, yoğun vektörlerde verimli benzerlik araması ve kümeleme için bir kütüphanedir. Çoğunlukla C++ ile yazılmıştır, opsiyonel Python arayüzü sunar ve CUDA ya da AMD ROCm üzerinden GPU desteği verir. MIT lisanslıdır. FAISS bir veritabanı değil, bir kütüphanedir; vektörleri bir indekste tutar ve L2 ya da iç çarpımla arama yapar. RAM'e sığmayan dev koleksiyonlar için bile algoritmalar içerir. Kendi altyapınıza gömeceğiniz, üzerinde tam kontrol istediğiniz durumlarda güçlü bir tercihtir.

pgvector

Eğer zaten PostgreSQL kullanıyorsanız, ayrı bir vektör veritabanı kurmadan aynı işi yapabilirsiniz. pgvector, Postgres'e vektör tipi ve benzerlik araması ekleyen açık kaynaklı bir uzantıdır. Hem HNSW hem IVFFlat indekslerini destekler ve indekssiz tam arama da yapabilir (mükemmel recall, daha yavaş). Mesafe operatörleri doğrudan SQL içinde yazılır: kosinüs mesafesi için <=>, L2 için <->, iç çarpım için <#>. Verinizin geri kalanıyla aynı veritabanında yaşaması, işlem (transaction) tutarlılığı ve mevcut yedekleme akışlarınızı koruması büyük bir operasyonel avantajdır.

Yönetilen ve diğer seçenekler

Altyapıyı kendiniz işletmek istemiyorsanız, tamamen yönetilen bulut servisleri vardır; Pinecone bunun bilinen bir örneğidir ve ölçeklendirme, dayanıklılık gibi yükü sizden alır. Bunların dışında açık kaynak dünyasında Milvus, Qdrant, Weaviate ve Chroma gibi, doğrudan vektör araması için tasarlanmış olgun veritabanları yaygın olarak kullanılır. Hangisini seçeceğiniz; ölçeğinize, ekibinizin işletim kapasitesine ve verinizin nerede yaşadığına bağlıdır.

Peki RAG ile ilişkisi ne?

Tüm bu makineyi son dönemde popülerleştiren şey büyük ölçüde RAG (Retrieval-Augmented Generation), yani "getirimle desteklenmiş üretim" oldu. Büyük dil modelleri yalnızca eğitildikleri bilgiyi bilir ve uydurma (hallüsinasyon) yapabilirler. RAG bu sorunu şöyle çözer: önce belgelerinizi parçalara böler, her parçayı embedding'e çevirip bir vektör veritabanına koyarsınız. Kullanıcı soru sorduğunda, sorunun embedding'iyle anlamsal arama yapılır, en alakalı birkaç parça çekilir ve bunlar modele bağlam olarak verilir. Model de cevabı bu gerçek belgelere dayanarak üretir.

Yani bu yazıda anlattığımız embedding üretimi, kosinüs benzerliği ve HNSW indekslemesi, bir RAG sisteminin "getirme" (retrieval) ayağının ta kendisidir. Vektör veritabanı, dil modelinin harici ve güncellenebilir hafızası gibi çalışır.

Sonuç

Embedding'ler anlamı geometriye çevirir, kosinüs benzerliği bu geometride yakınlığı ölçer, HNSW gibi ANN algoritmaları ise milyonlarca vektör arasında bu aramayı milisaniyeler içinde yapılabilir kılar. FAISS, pgvector ve yönetilen servisler bu fikirleri üretime taşıyan gerçek araçlardır. Anlamsal arama ve RAG gibi uygulamaların sihir gibi görünen tarafı, aslında iyi tanımlanmış matematik ve dikkatli mühendisliğin birleşiminden ibaret. Bu temeli kavradığınızda, kendi sisteminiz için doğru aracı ve doğru hız-doğruluk dengesini seçmek çok daha bilinçli bir karar haline gelir.