Embedding modelini kesintisiz değiştirmek: AlloyDB’de blue/green tarzı yeniden embedding
Upgrade Embedding Models in AlloyDB AI with Zero Downtime
Bir ürün yorumları için semantic search özelliği çıkardın ve kullanıcılar sevdi. Ertesi gün daha doğru, daha nüanslı ve çok dilli yeni bir embedding modeli duyuruluyor; dev ortamında denedin ve uyuyor. Şimdi sorun, kullanıcıları etkilemeden modeli nasıl yükselteceğin. Yazı dört engeli sayıyor:
(1) Embedding üretimi: tüm mevcut verinin yeni modelle yeniden embedding’lenmesi gerekiyor; bu genelde pipeline’ları güncellemek ve eski ve yeni modeli bir süre yan yana çalıştıran dual write stratejileri anlamına geliyor. (2) Matematiksel uyumsuzluk: farklı modellerin ürettiği embedding’ler farklı vektör uzaylarında yaşar ve doğrudan karşılaştırılamaz; uygulamanın sorgu vektörleri ile saklanan kolon vektörleri aynı anda aynı modele geçmek zorunda, yoksa arama kalitesi ağır biçimde bozulur. (3) Index rebuild maliyeti: yeni vektörler üzerinde index kurulmadan ölçekte benzerlik araması verimli çalışmaz. (4) Kullanıcı deneyimi: modeli değiştirmek, exclusive lock alan birden çok DDL işlemi gerektirir ve dikkatli yönetilmezse gelen okuma ve yazma transaction’larını durdurabilir.
AlloyDB AI’nın çözümü birkaç özelliğin birleşimi: model endpoint management herhangi bir embedding modeline (birinci taraf, üçüncü taraf ya da kendi barındırdığın) veritabanı içinden erişim veriyor; auto embeddings yeni embedding’leri arka planda saniyede 3.000’e kadar üretiyor ve kaynak veri değiştikçe güncel tutuyor; ScaNN index’i açık kaynak HNSW’ye göre 10 kat daha hızlı build ediyor; ve PostgreSQL’in yerel özellikleri (concurrent index creation, set-returning function’lar ve atomik kolon yeniden adlandırma) şeffaf blue/green ve canary tarzı geçişleri mümkün kılıyor.
Adımlar (örnek: canlı trafik varken text-embedding-005 (768 boyut) → gemini-embedding-001 (3072 boyut) geçişi). Adım 0: extension sürümünü ve model bağlantısını doğrula. Adım 1: yeni vektör kolonunu ekle. Default değeri olmayan, null olabilen bir kolon eklemek satırların yeni sürümlerini oluşturmaz, yalnızca catalog metadata’sını günceller; yani neredeyse anlıktır. Kolon boyutu modelin çıktı boyutuyla eşleşmeli ve lock_timeout 2 saniyeye ayarlanıyor: işlem exclusive lock için uzun beklerse production trafiğini bloklamasın, başarısız olursa yeniden denenir. Adım 2: yeni kolon üzerinde auto embeddings’i başlat ve backfill çalıştır. Güncel tutma için iki mod var: transactional (embedding veri değişir değişmez, aynı işlemde güncellenir; tutarlı ama her INSERT/UPDATE’e inference gecikmesi ekler, değişim düşükse uygun) ve manual (AlloyDB değişen satırları izler ama hemen güncellemez; ai.refresh_embeddings() ile kendi belirlediğin takvimde yalnızca değişenleri yeniler, değişim yüksekse ve belirli bir embedding gecikmesi tolere edilebiliyorsa uygun). Örnekte manual mod seçilmiş. Backfill sırasında eşzamanlı yazıcıların bekleme süresini sınırlamak için max_parallel_requests düşürülebilir: bu her micro batch’in commit süresini iyileştirir ama toplam backfill süresini uzatır; ilerleme bir view üzerinden izlenir. Adım 3: backfill sırasında değişen satırları ai.refresh_embeddings() ile yakala ve bunu pg_cron gibi bir zamanlayıcıyla sürdür. Adım 4: vektörlerin eksiksizliğini ve retrieval kalitesini doğrula; ardından index’i concurrent biçimde kurup sorguları yeni kolona atomik olarak geçirmek mümkün.
Öne çıkanlar
- Farklı embedding modelleri farklı vektör uzaylarındadır: sorgu ve saklanan vektör aynı modelle üretilmelidir.
- Geçişi ‘yerinde güncelleme’ değil, yeni kolon ekleyip eskisiyle paralel çalıştırarak yap (blue/green).
- Null olabilen, default’suz kolon eklemek neredeyse anlıktır;
lock_timeoutile bu işlem production trafiğini bloklamaz. - Veri sık değişiyorsa her yazmada embedding üretmek yerine değişenleri periyodik yenile (manual refresh).
- Geçişten önce retrieval kalitesini bir değerlendirme setiyle ölç; kolon dolu olması kalitenin iyi olduğu anlamına gelmez.
Neden önemli?
Embedding modelleri hızla gelişiyor ve her RAG sistemi eninde sonunda bu geçişi yapacak. Yazının yöntemi AlloyDB’ye özgü olsa da (yeni kolon, backfill, doğrulama, geçiş) genel bir migration deseni.
Pratikte
Düz PostgreSQL ve pgvector ile aynı geçişi şöyle yapabilirsin. (1) ALTER TABLE ... ADD COLUMN embedding_v2 vector(3072) ekle (default’suz, null olabilir) ve SET lock_timeout = '2s' ile çalıştır. (2) Bir batch job ile satırları küçük gruplar hâlinde yeniden embedding’le; değişen satırlar için bir updated_at kolonuna bakıp ikinci bir tur çalıştır. (3) CREATE INDEX CONCURRENTLY ile yeni kolona index kur. (4) Aynı 30-50 sorguluk bir evaluation setini eski ve yeni kolonda çalıştırıp sonuçları karşılaştır. (5) Uygulamada hangi kolonu kullandığını bir feature flag ile seç; sorunsuzsa eski kolonu sonra sil.
Sözlük
- embedding
- Bir metni, anlamını yansıtan sayı vektörüne dönüştüren temsil.
- blue/green deployment
- Yeni sürümü eskisiyle paralel kurup trafiği ona geçirme yöntemi.
- backfill
- Var olan eski kayıtlar için yeni bir alanı ya da türevi sonradan doldurma.
- DDL
- Veritabanı şemasını değiştiren komutlar (CREATE, ALTER, DROP).
- exclusive lock
- Bir kaynağa yalnızca tek bir işlemin erişmesine izin veren, diğerlerini bekleten kilit.