19  Erişim: Üretimden Önce Arama

Bölüm durumu: çevrildi. Kaynak metin: İngilizce 19. bölüm. Ölçümler Bölüm 16’nın erişim deneyini genişletiyor — aynı 7.165 Türkçe belge (WMT16/17/18 Türkçe–İngilizce test kümelerinden en az sekiz kelimelik haber cümleleri; B koşulunun İngilizce sorguları bu cümlelerin aynı kümelerdeki profesyonel çevirileri), aynı sorgu kurulumu, aynı seed (tohum) — böylece buradaki ve oradaki seyrek (sparse) sayılar doğrudan karşılaştırılabilir. İki sorgu koşulu ve iki yoğun (dense) model bilerek kullanıldı; her birinden yalnızca birini çalıştırmanın neden yanlış şeyi ölçeceğini Bölüm 19.2 anlatıyor. Yazılım: sentence-transformers 6.0.0, snowballstemmer 3.1.1, NumPy 2.5.2, Python 3.14.5.

Öğrenme hedefleri. Bu bölümün sonunda:

19.1 İki aile ve aralarında karar veren soru

Bu bölümde erişim (retrieval), bir sorgu için büyük bir belge derleminden ilgili belgeleri bulup getirmek demek; bilgi erişiminin (information retrieval) kısa adı. Erişimin iki ailesi var ve zıt yönlerde hata yapıyorlar.

Sözcüksel erişim kelimeleri eşleştirir. Standart puanlama işlevi olan BM25 (Robertson ve Zaragoza 2009), sezgi düzeyinde Bölüm 2’nin TF-IDF’inin önemli iki düzeltmeyle donatılmış hâlidir (kuramsal olarak ise olasılıksal ilgililik çerçevesinden türetilir). Birincisi, terim frekansı doyuma ulaşır: bir kelimenin onuncu geçişi ikincisinden çok daha az katkı verir ve \(k_1\) bu doyumun ne kadar çabuk geldiğini ayarlar. İkincisi, belge uzunluğu normalleştirilir: uzun bir belge, her şeyi daha bol içerdiği için kazanmaz ve \(b\) bu düzeltmenin gücünü ayarlar (\(b = 0\) kapatır, \(b = 1\) tam uygular). (Formülü ve sayısal bir örneği Bölüm 19.10 veriyor.)

Hızlıdır, kesindir, yorumlanabilirdir, eğitim gerektirmez ve hiç görmediği bir kelimeyi eşleştiremez.

Yoğun erişim anlamı eşleştirir. Bir bi-encoder (çift kodlayıcı) (Karpukhin vd. 2020) sorguları ve belgeleri ayrı ayrı aynı uzaya gömer; böylece belgeler bir kez kodlanıp vektör benzerliğiyle (genellikle Bölüm 3’teki kosinüs benzerliğiyle) aranabilir. Yoğun erişim, aynı şeyin başka sözcüklerle söylenişini, eş anlamlılığı ve — bu bölümün göstereceği gibi — farklı dilleri ele alır.

Eğitilmiş bir model ister, bir parça numarasında tam eşleşmeyi garanti edemez ve kusurlarını açıklamak zordur.

Adlar vektörlerin biçiminden gelir. BM25 ya da TF-IDF’te bir belge, sözlük boyutunda (on binlerce boyut) ve bileşenlerinin çoğu sıfır olan bir vektördür; bu yüzden sözcüksel erişime seyrek erişim denir. Embedding tabanlı erişimde ise belge, birkaç yüz boyutlu ve her bileşeni dolu bir vektördür; bu yüzden yoğun erişim.

bi-encoder (çift kodlayıcı) — sorgu ve belge bağımsız kodlanır, böylece her belge önceden gömülebilir ve arama bir vektör aramasıdır. Ölçeklenmesini sağlayan da, çapraz kodlayıcıya kıyasla doğruluğunu sınırlayan da bu bağımsızlıktır. ↩︎

Yerleşik kanıya göre yoğun erişim modern olanıdır; sözcüksel erişim ise nezaketen raporladığınız baseline’dır. Aşağıdaki ölçümler, işimize pek gelmeyecek bir şey söylüyor.

Neye bakacağız. Önce deney; bir değil iki sorgu koşuluna ihtiyaç duyuyor, çünkü tek bir koşul sorgu formatını ölçüp faturayı modele keserdi. Sonra sonuçlar: aynı iki sistem altmış puan farkla yer değiştiriyor ve herkesin önerdiği melez birleştirme, birleştirdiği iki sistemden daha iyi olanın 32,8 ile 46,8 puan gerisinde kalıyor (zayıf olanı ise iki koşulda da 26–27 puan geçiyor). Sonra yoğun bir retriever’ın nasıl eğitildiği; orada her şey zor negatiflere bağlı. Sonra yeniden sıralama, yaklaşık indeks ve dört metrik; bunlardan biri aşağı akıştaki her şeyin tavanını belirliyor. Ve son olarak vektörlerin nereye konacağı; bu, genellikle büyütüldüğünden daha küçük bir soru.

19.2 Deney ve neden iki koşulu olduğu

Bölüm 16 seyrek tarafı 7.165 Türkçe belgede ölçmüştü: terimleri belgedekinden farklı çekimlenmiş sorgularla — kullanıcının sözlük biçimini yazdığı durum — yüzey biçimli BM25 %28,0 recall@1’e ulaşıyor ve gövdeleme onu %95,3’e taşıyor.

Bariz sonraki adım o kuruluma yoğun bir retriever ekleyip sonuca bakmak. Bariz sonraki adım aynı zamanda bir tuzak. Üzerinde bir paragraf duralım, çünkü aynı tuzak, oluşturacağınız her erişim değerlendirmesinde de var.

O sorgular birbirinden kopuk üç içerik kelimesi. Bu, sözcüksel bir eşleştirici için doğal girdidir; cümle embedding’i (gömme) üretmek üzere eğitilmiş bir çift kodlayıcı için ise dağılım dışıdır. Yalnızca o koşulu çalıştırıp “yoğun erişim Türkçede zayıf” diye raporlamak, sorgu formatını ölçüp faturayı modele kesmek olurdu.

Bu yüzden deney aynı belgeler üzerinde iki sorgu koşulu çalıştırıyor:

İki koşul: her aile birinde kendi sahasında, diğerinde deplasmanda oynuyor
koşul sorgu kimin lehine
A. anahtar kelime, çekimli belgedekinden farklı bir çekimde üç içerik kelimesi çekim farklılıklarını ele alabiliyorsa sözcüksel eşleştirme
B. diller arası belgenin profesyonel İngilizce çevirisi yalnızca yoğun — ortak sözcük dağarcığı hiç yok

Ve aynı nedenle iki yoğun model: paraphrase-multilingual-MiniLM bir benzerlik modeli, iki cümlenin ne kadar benzediğini puanlamaya eğitilmiş; multilingual-e5-base (Wang vd. 2024) ise bir erişim modeli, zor negatiflerle sorgu-belge çiftleri üzerinde eğitilmiş. Ünlü olduğu için birincisini seçmek yaygın bir hatadır; yalnızca onu çalıştırmak yoğun erişimi olduğundan kötü göstermiş olurdu.

E5’in model kartında, bu bölümün kaydetmesi gereken ama kaydetmediği bir talimat var. multilingual-e5-base asimetrik bir erişim modeli: sorgularda query:, belgelerde passage: ön ekiyle eğitiliyor ve kart, onlarsız ölçülebilir biçimde daha kötü davrandığını açıkça söylüyor. Ön eklerin en çok önem taşıdığı ayar da burası — asimetrik bir sorgu-belge görevi zaten onların var olma sebebi. Ön ekleri atlamak da bir embedding hattındaki en yaygın sessiz hatadır. Bölüm 11 simetrik durum için aynı uyarıyı yapıyor; orada kart iki tarafa da query: öngörüyor. Ön eke yakın ikinci sessiz hata normalleştirmedir: kosinüs benzerliği iç çarpıma ancak birim uzunluklu vektörlerde eşittir ve E5’in kartı da çıktıları L2 normalleştirmesinden geçirip öyle karşılaştırır. Normalleştirilmemiş vektörleri iç çarpımla aramak (örneğin iç çarpım kullanan bir ANN indeksinde) normu büyük belgeleri kayırır. Bizim koşularımızda hangi ön ek kuralının kullanıldığı kayıtlı değil. Ön ekler atlandıysa aşağıdaki E5 sayıları, modelin kendi kartının önermediği bir ayarda ölçülmüş demektir. Bu, deneyi yeniden koşturmak için bir sebeptir; skorların mutlaka yükseleceğinin ya da bu bölümün öne çıkardığı iki farkın da küçüleceğinin garantisi değildir. E5 satırlarını o kontrolü bekleyen satırlar sayın ve bu deneyi kendiniz çalıştırdığınızda ön ekleri model adının yanına yazın.

Bu deneyin bilerek kenara bıraktığı, ama kendi sisteminizde atlamamanız gereken iki üst akış kararı var. Birincisi, neyin “belge” sayılacağı: burada her belge tek bir cümle; gerçek belgeler ise daha uzundur ve gömülmeden önce parçalara bölünmeleri gerekir. En iyi parça boyutu sorunun türüne bağlıdır ve bunu Bölüm 20.3 ölçüyor. İkincisi, Türkçe BM25 için küçük harfe çevirmeyi Türkçe kurallarıyla yapmak: Python’un varsayılan lower()’ı I’yı ı yerine i’ye, İ’yi de i artı birleşen bir noktaya çevirir ve kelimeler daha gövdeleme başlamadan bozulur (Bölüm 16.2).

19.3 Ölçümler ne diyor

İki koşul da aynı derlem üzerinde çalışıyor, dolayısıyla aşağıdaki iki tablo doğrudan karşılaştırılabilir — asıl dikkat çekici olan da ne kadar az ortak yanları olduğu. Koşul başına 800 sorgu, 7.165 belge ve tasarım gereği sorgu başına tek bir ilgili belge — her sorgu tek bir hedef belgeden kuruluyor ve tek doğru cevap o sayılıyor.

Bu son varsayım doğrulanmadı ve simetrik değil. 7.165 haber cümlesinde üç içerik kelimesi çoğu zaman birden fazla cümleyi tarif eder ve yakın bir başka anlatımı bulup getiren sistem tam da yoğun olandır — yani etiketlenmemiş ilgili belgeler yoğun recall@1’i büyük olasılıkla BM25’inkinden daha çok aşağı çekiyor. Çözümü bu bölümün kendi mülakat kısmı veriyor: bir altörneklemde her sistemin ilk 10 sonucunu bir havuzda toplayın ve bu birleşimi elle etiketleyin. Bu havuzlama burada yapılmadı; yapılana kadar A koşulundaki yoğun sayıları bir kestirim değil, bir alt sınır olarak okuyun.

Tabloları okumadan önce bilinmesi gereken iki şey var. Birincisi sütunlar. R@1 ve R@10, recall@1 ve recall@10’dur; sorgu başına tek ilgili belge varken bunlar yalnızca “doğru belge birinci mi?” ve “ilk onun içinde bir yerde mi?” diye sorar. MRR@10 ve nDCG@10 de üst sıraları ödüllendirir; dördü de Bölüm 19.7’de düzgünce tanımlanıyor. Satır adları programın çıktısı olduğu için İngilizce kaldı: surface form yüzey biçimli, stemmed gövdelenmiş BM25; dense yoğun retriever; hybrid RRF (unweighted) ise ağırlıksız melez birleştirme. İkincisi melez satırlar. Bunlar bir BM25 sıralamasını ve bir yoğun sıralamayı sıra tersine dayalı birleştirme (reciprocal rank fusion, RRF) (Cormack vd. 2009) ile birleştirir. Her belge, onu döndüren sistemler \(s\) üzerinden toplanan \(\sum_s 1/(k + \text{sıra}_s(d))\) puanını alır ve birleşik liste bu puana göre sıralanır. Bir sistemin döndürmediği belge o sistemden hiç puan almaz. \(k\) bir yumuşatma sabitidir; özgün makale \(k = 60\) kullandı ve bu hâlâ yaygın varsayılan değer.

reciprocal rank fusion (RRF) (sıra tersine dayalı birleştirme) — birkaç sıralı listeyi, her belgeye listeler boyunca \(\sum 1/(k + \text{sıra})\) puanı verip yeniden sıralayarak birleştirmek. Skorları değil yalnızca sıraları kullanır; bu yüzden kalibrasyon gerektirmez — ama güçlü bir sistemin birinciliğini zayıf bir sistemin birinciliğinden ayıramaz. ↩︎

19.3.1 Koşul A — anahtar kelime sorguları, çekimli

Bu, sözcüksel eşleştirmenin kazanması gereken koşul; yeter ki Türkçenin çekim farklılıklarını ele alabilsin:

system                                        R@1    R@10   MRR@10  nDCG@10
BM25 surface form                           27.5%   54.1%     34.9     39.4
BM25 stemmed                                96.0%   99.8%     97.7     98.2
dense: paraphrase-MiniLM (similarity model) 10.6%   28.2%     15.6     18.6
dense: multilingual-e5-base (retrieval)     35.9%   63.7%     44.5     49.1
hybrid RRF (unweighted), surface + e5       37.6%   71.6%     47.6     53.3
hybrid RRF (unweighted), stemmed + e5       63.2%   96.5%     73.7     79.2

Gövdelenmiş BM25 altmış puan farkla kazanıyor. Elle yazılmış birkaç yüz satırlık ek soyma kuralı, eğitilmiş çok dilli bir retriever’ı %96,0’a %35,9 yeniyor — çoğu kişinin ilk tercih ettiği benzerlik modelini ise %96,0’a %10,6.

Yüzey biçimi ve gövdelenmiş satırlar Bölüm 16’nın %28,0 ve %95,3’ünü biraz farklı bir sorgu örnekleminde (oradaki 1.481 sorgu yerine koşul başına 800 sorgu) yeniden üretiyor. Bu süreklilik kontrolü, tablonun geri kalanını o bölümün sonuçlarıyla karşılaştırarak okumayı sağlıyor.

19.3.2 Koşul B — diller arası sorgular

Şimdi aynı belgeler, İngilizce sorgulanıyor. Sözcüksel bir eşleştiricinin çalışabileceği ortak bir sözcük dağarcığı yok:

system                                        R@1    R@10   MRR@10  nDCG@10
BM25 surface form                           23.2%   43.5%     28.9     32.3
BM25 stemmed                                23.8%   41.9%     29.1     32.1
dense: paraphrase-MiniLM (similarity model) 93.8%   98.1%     95.4     96.0
dense: multilingual-e5-base (retrieval)     96.2%   99.9%     97.8     98.3
hybrid RRF (unweighted), surface + e5       49.4%   99.6%     71.6     78.7
hybrid RRF (unweighted), stemmed + e5       48.1%   99.6%     70.9     78.2

Yoğun, yetmiş iki puan farkla kazanıyor. İngilizce sorgu ile Türkçe belge neredeyse hiç sözcük paylaşmıyor, dolayısıyla BM25’e yalnızca özel adları ve sayıları eşleştirmek kalıyor. Sıfır yerine hâlâ %23,8 almasının nedeni bu. Bu ayrıntı önemli, çünkü özel adlar ve sayılar tam da yoğun erişimin en kötü olduğu durumlar.

Ama koşul B’nin neye elverişli olduğunu da, koşul A için söylediğimiz gibi söyleyelim. Buradaki sorgu belgenin eksiksiz, profesyonel bir çevirisi; bu da çok dilli bir çift kodlayıcının alabileceği, eğitim dağılımına en çok uyan girdi: bu iki model de paralel cümle çiftleri üzerinde eğitildi, yani görev aramadan çok bitext madenciliğine (verilen bir cümlenin çevirisi olan cümleyi bulmaya) yakın. Gerçek diller arası sorgular kısadır, soru biçimlidir ve belgenin tamamını kapsamaz. Dolayısıyla %96,2’yi “yoğun erişim diller arası aramayı çözüyor” diye değil “yoğun erişim çeviri eşleştirmesini çözüyor” diye okuyun; yetmiş iki puanlık farkı da yoğun erişimin üstünlüğü için bir üst sınır sayın — tıpkı koşul A’daki altmış puanlık farkın sözcüksel erişimin üstünlüğü için bir üst sınır olması gibi. Her iki koşul da kazananına, doğrudan hedef belgenin kendisinden türetilmiş bir sorgu veriyor. Eksik kol koşul B′: İngilizce çeviriden alınmış üç içerik kelimesi, yani koşul A’nın diller arası ikizi. Bu koşu, yoğun erişimin üstünlüğü için bir alt sınır verirdi; ilk ekleyeceğimiz koşu da bu.

Gövdeleme koşul A’da 68 puan, koşul B’de 0,6 puan kazandırıyor. Bu bir çelişki değil; aynı olgunun iki kez görünüşü. Gövdeleme bir dilin içindeki sözcük uyuşmazlığını düzeltir ve koşul B’de uyuşmazlık tam olduğu için düzeltecek bir şey yok.

19.3.3 Yaygın kanıyla çelişen bulgu

Her tablodaki iki melez satırdan daha iyi olanını (A koşulunda gövdelenmiş + e5, B koşulunda yüzey + e5) en iyi tek sistemle karşılaştırın:

condition A     stemmed BM25 alone         96.0%  R@1
                hybrid stemmed + e5        63.2%  R@1      -32.8

condition B     dense e5 alone             96.2%  R@1
                hybrid surface + e5        49.4%  R@1      -46.8

Ağırlıksız RRF iki koşulda da en iyi tek sisteme göre işleri kötüleştirdi, hem de fena hâlde. Bu, melez erişimin birleştirdiği iki sistemi de yendiği yolundaki standart iddianın tersi (Cormack vd. 2009). Zayıf sistemi ise iki koşulda da 26–27 puan geçti; yani birleştirme, hangi koşulda olduğunuzu bilmediğinizde bir sigortadır, bedava bir kazanç değil. Kaybın nedeni de mekanizmada görülüyor.

Neyin ölçüldüğünü açıkça belirtelim, çünkü iddia “melez erişim abartılıyor”dan daha dar. Bu satırlar, bu bölümün raporlamadığı sabit bir \(k\) değerinde yapılmış ağırlıksız, sıra tabanlı birleştirmeye ait. Aşağıdaki widget zaten \(k\)’nın cevabı değiştirdiğini göstermek için var; dolayısıyla bu değeri raporlamamak gerçek bir boşluk. İki standart onarım denenmedi. Ağırlıklı RRF bariz olanıdır: \(\sum w_s/(k + \text{sıra}_s)\) formülündeki sistem başına ağırlık, ayrılmış (held-out) sorgularda kestirilir. Bu bölüm onu çalıştırmak yerine bir alıştırmaya bırakıyor. Skor tabanlı birleştirme ise daha iyisi: Bruch vd. (2024) bu soruyu doğrudan inceliyor ve normalleştirilmiş skorların dışbükey bir birleşiminin RRF’i hem alan içinde hem alan dışında geçtiğini, üstelik tek parametresini ayarlamak için çok az örnek yettiğini buluyor. Yani akılda tutulacak bulgu şu: güçleri eşit olmayan sistemlerin ağırlıksız sıra birleştirmesi zararlı olabilir — burada ölçülen iki durumda da öyleydi — çünkü sıra birleştirmesi tam da hangi sisteme güvenileceğini söyleyecek olan skor büyüklüğü bilgisini çöpe atar.

RRF, birleştirdiği sistemlerin karşılaştırılabilir ölçüde iyi olduğunu varsayar. Her belgeyi listeler boyunca \(\sum 1/(k + \text{sıra})\) ile puanlar; bu da işe yaramaz bir sistemden gelen 1. sıra isabetini mükemmel bir sistemden gelen 1. sıra isabetiyle birebir aynı sayar.

Bir sistem %96’da, diğeri %36’dayken zayıf sistemin üst sıralardaki ilgisiz belgeleri tam ağırlıkla gelir ve güçlü sistemin doğru cevabını yerinden eder. Burada “güven” derken bir güven skorunu kastetmiyoruz: sıra birleştirme hiçbir skor görmez; oysa hangi sisteme güvenileceğini söyleyecek bilgi tam da odur.

İki sıralayıcıyı elle birleştirin — ve doğru belgenin nasıl geride kaldığını izleyin

İkinci kaydırıcıyı hareket ettirin, mekanizma belirginleşir: zayıf sistemin sonucu değiştirmek için haklı olması gerekmiyor, yanlış belgeyi listesinin tepesine koyması yetiyor. Ve k’nın ne yaptığına dikkat edin. Küçük bir k birinci sırayı onuncudan çok daha değerli kılar; her sistemin en üstteki sonucu belirleyici olur. k’yı yükseltmek sıralar arasındaki farkları düzleştirir ve k çok büyüdüğünde birleşik sıra, sıraların toplamına göre sıralamaya dönüşür: iki listenin de ortalarında duran bir belge, bir listede birinci ama diğerinde çok aşağıda olan bir belgeyi geçebilir. İki ayar da hangi sisteme güvenileceğini bilmez.

Hasarın biçimi, birleştirmenin size ne zaman zarar vermeyeceğini söylüyor:

condition B     dense alone       R@1 96.2%    R@10  99.9%
                hybrid            R@1 49.4%    R@10  99.6%

Recall@10 neredeyse hiç oynamadı; recall@1 yarıya indi. Birleştirme belgeyi kaybetmedi — listede aşağı itti. Yani çıktıyı kullanan sistem ilk 10 sonucu okuyorsa birleştirme size neredeyse hiçbir şey kaybettirmedi; yalnızca ilk sonucu okuyorsa doğruluğunuzun yarısını kaybettirdi.

Üç bulgu da tek bir resme sığıyor — yer değiştirme, birleştirme kaybı ve bunu gizleyen metrik:

Tek bir derlemde recall@1: kazanan yer değiştiriyor ve birleştirme her iki koşulda da daha iyi sisteme kaybediyor
KOŞUL A — ANAHTAR KELİME SORGULARI, ÇEKİMLİ KOŞUL B — DİLLER ARASI SORGULAR BM25, gövdelenmiş %96,0 yoğun: multilingual-e5-base %35,9 melez RRF, gövdelenmiş + e5 %63,2 −32,8 puan BM25, gövdelenmiş %23,8 yoğun: multilingual-e5-base %96,2 melez RRF, yüzey + e5 %49,4 −46,8 puan %0 %50 %100 %0 %50 %100 KOŞUL B YİNE, RECALL@10'DA ÖLÇÜLMÜŞ — AYNI HASARIN GÖRÜNMEZ OLDUĞU YER yoğun tek başına %99,9 melez RRF %99,6 Recall@10 hiçbir şey olmadığını söylüyor. Recall@1'de ise %96,2'den %49,4'e indi.

İki panel de aynı ölçekte çizildi, dolayısıyla aynı uzunluktaki bir çubuk aynı recall@1 demek. İki aile, tek bir derlemde ve tek bir belge kümesinde koşullar arasında tümüyle yer değiştiriyor. Her birleştirme çubuğu kendi tablosundaki iki melezden daha iyisidir; B koşulunda bu, üstte çizilen gövdelenmiş BM25 ile değil yüzey biçimli BM25 (tek başına %23,2) ile yapılan birleştirmedir. Her panelde kesikli çizgi iki sistemden daha iyisini işaretliyor; gül rengi ayraç da birleştirmenin bu sisteme göre ne kadar kaybettirdiğini gösteriyor. Alt bant aynı B koşulu birleştirmesini ilk on sonuç düzeyinde gösteriyor; burada iki çubuk ayırt edilemiyor — doğru belge hiç kaybedilmedi, yalnızca aşağı itildi. İzlediğiniz sayı oynamazken bir sistemin fena hâlde gerileyebilmesinin nedeni budur.

19.3.4 Peki ne zaman birleştirmeli?

Ölçümün desteklediği kural, yaygın kanıdan daha dar:

  • Birleştirilecek sistemler benzer düzeyde başarılıysa ve farklı yerlerde hata yapıyorsa birleştirin. Cormack vd.’nin (2009) incelediği durum budur; birleştirme ününü de burada hak ediyor.
  • Sistemlerden biri baskınsa birleştirmeyin. Önce kendi sorgularınızda kontrol edin. Bunun maliyeti tek bir değerlendirme çalıştırmasıdır; alternatifi ise her blog yazısının iyileştirme dediği 47 puanlık bir gerilemeyi yayına almaktır.
  • Sorgu karışımınız iki türü de içeriyorsa — çoğu gerçek sistem içerir; kullanıcılar hem parça numarası yazar hem soru sorar — cevap genellikle birleştirmek değil yönlendirmektir: sorguyu sınıflandırın, onu ele alabilen retriever’a gönderin ve birleştirmeyi gerçekten belirsiz kalan ara durumlara saklayın.

Ağırlıklı birleştirme bariz onarımdır, ama bir bedeli var: ağırlık veriden kestirilen bir parametredir. Dolayısıyla ayrılmış sorgular ister ve sorgu karışımınız değiştikçe kayar. Yönlendirmenin de aynı gereksinimi var, ama bunu daha açık biçimde karşılıyor: bir yönlendirici, bir kez ayarladığınız bir sabit değil, değerlendirebileceğiniz bir modeldir.

19.3.5 Yoğun model seçimi, görevin zor olduğu yerde önem kazanıyor

İki koşulun mümkün kıldığı bir karşılaştırma daha. Benzerlik modeliyle erişim modelini ikisinde de yan yana koyun:

                              condition A   condition B
paraphrase-MiniLM (similarity)      10.6%         93.8%
multilingual-e5-base (retrieval)    35.9%         96.2%
                                   ------        ------
                                   +25.3          +2.4

Kolay koşulda (yoğun bir model için B) ikisi arasındaki fark 2,4 puan; dolayısıyla üstünkörü bir benchmark (kıyaslama), model seçiminin önemli olmadığı sonucuna varırdı. Zor koşulda (A) erişime eğitilmiş model üç kattan fazla yüksek recall@1 alıyor (%10,6’ya karşı %35,9).

İyi bir bileşenle vasat bir bileşen arasındaki fark yalnızca o bileşen için zor olan girdilerde ortaya çıkar; bu da kolay bir koşulun ortalamasını raporlamak yerine zor koşulu değerlendirmenize dâhil etmek için bir argümandır.

19.4 Yoğun bir retriever’ı eğitmek

Yukarıdaki modeller hazır kullanıldı. Alanınızda yeterince iyi olmadıklarında başvuracağınız eğitim tarifi kısaca anlatılabilir; tarifin bir parçası da diğerlerinden çok daha önemlidir.

Bir çift kodlayıcı karşıtsal olarak eğitilir: sorgunun embedding’i ilgili belgesine doğru çekilir, ilgisiz belgelerden uzaklaştırılır. Kayıp genellikle bir batch (yığın) üzerinde hesaplanan InfoNCE’dir. Bu, “sınıfların” aday belgeler olduğu sıradan bir softmax çapraz entropisidir: sorgu, ilgili belgeyle ve birkaç ilgisiz belgeyle puanlanır ve softmax’tan olasılığı ilgili belgeye vermesi istenir. Bütün zorluk ilgisiz kelimesindedir — yanlış cevap olarak hangi belgeleri kullandığınızda.

Batch içi negatifler (in-batch negatives) kendiliğinden elde edilir: sorgu-belge çiftlerinden oluşan bir batch’te, batch’teki diğer her belge bir negatiftir. Hiçbir şeye mal olmazlar ve çoğunlukla kolaydırlar — futbolla ilgili rastgele bir belge, faturayla ilgili bir sorgunun makul bir cevabı olamaz. Dolayısıyla model konuları birbirinden ayırmayı öğrenir ve bunun ötesine geçmez.

Zor negatifler (hard negatives) doğru görünen ama doğru olmayan belgelerdir. Onları bulmak için mevcut modelinizle erişim yapın ve en üst sıralara gelen yanlış cevapları seçin.

hard negative (zor negatif) — mevcut modele doğru görünen yanlış bir belge; modelle erişim yapıp en üst sıralardaki yanlış cevaplar alınarak bulunur. Rastgele belgeler yerine bunlara karşı eğitmek, yoğun bir retriever’ı isabetli kılan şeyin büyük kısmıdır. ↩︎

Her şey buna bağlıdır. Yalnızca rastgele negatiflerle eğitilmiş bir retriever konu benzerliğini öğrenir. Zor negatiflerle eğitilmiş bir retriever ise kullanıcılarınızın gerçekten ihtiyaç duyduğu ayrımı öğrenir: ikisi de faturayla ilgili olan ama yalnızca biri soruyu cevaplayan iki belge arasındaki ayrımı.

Önceden hesaba katmanız gereken iki kusur biçimi:

  1. Yanlış negatifler. “Zor negatifiniz” etiketlenmemiş ilgili bir belge olabilir; eğitim ise modele bu belgenin yanlış olduğunu öğretir. İlgililik etiketleri seyrek olan bir derlemde bu durum, zarar verecek kadar yaygındır. Genellikle başvurulan çözüm, erişilen listenin en tepesini atlayıp negatifleri biraz daha aşağıdan seçmektir.
  2. Bayatlama. İlk modelle seçilen negatifler, model iyileştikçe zor olmayı bırakır. Negatifleri belirli aralıklarla yeniden seçin. Bu tekrar yüzünden iş, bir ön işleme adımı değil yinelemeli bir yordamdır.

Hiç etiketli çiftiniz yoksa bu çiftleri üretin: bir LLM’den her belgenin cevapladığı bir soru yazmasını isteyin ve modeli bu çiftlerle eğitin. Sentetik sorgu girdi tarafında gürültülüdür, belge ise çıktı tarafında gerçektir — Bölüm 15’te geri çeviriyi işe yarar kılan asimetrinin aynısı.

19.5 Yeniden sıralama

Yukarıdaki her mimari, bir sorgu vektörünü sorguyu hiç görmeden hesaplanmış bir belge vektörüyle karşılaştırır. Daha doğru sonuç veren bir yol var; bu yolun derlem ölçeğinde kullanılmamasının da bir nedeni var.

Bir cross-encoder (çapraz kodlayıcı) (Nogueira ve Cho 2019) sorguyu ve belgeyi tek bir ileri geçişte birlikte okur; attention (dikkat mekanizması) ikisinin üzerinde birden çalışır. Bu, bağımsız hesaplanmış iki vektörü karşılaştırmaya göre ilke olarak daha fazla bilgi kullanır (çift kodlayıcının görebildiği her şeyi görebilir); benzer boyutta ve benzer eğitimle bir çapraz kodlayıcının çift kodlayıcıdan genellikle daha doğru olmasının nedeni de budur. Genellikle, her zaman değil: başka bir alanda eğitilmiş bir çapraz kodlayıcı, sizin alanınızda iyi eğitilmiş bir çift kodlayıcıya yine de yenilebilir.

cross-encoder (çapraz kodlayıcı) — sorgu ve belge birleştirilip tek bir ileri geçişte okunur, böylece attention ikisini birden kapsar. Çift kodlayıcıdan genellikle daha doğrudur ve önceden hesaplanamaz; bu yüzden bir derlemi aramak yerine bir kısa listeyi yeniden sıralar. ↩︎

Öte yandan retriever olarak kullanılamaz. Puan çifte bağlı olduğu için hiçbir şey önceden hesaplanamaz: bir sorgu için bir milyon belgeyi puanlamak bir milyon ileri geçiş demektir. Standart iki aşamalı örüntü bu yüzden ortaya çıkar:

Mimarinin neden hep iki aşamalı olduğu
ÇİFT KODLAYICI — AYRI, BU YÜZDEN ÖNCEDEN HESAPLAR ÇAPRAZ KODLAYICI — BİRLİKTE, ÖN HESAP YOK sorgu belge kodlayıcı kodlayıcı iç çarpım belge tarafı: bir kez, çevrimdışı hesaplanır 1M belge = 1 sorgu kodlaması + bir vektör işlemi sorgu ⧺ belge tek ileri geçiş, ikisi boyunca attention puan hiçbir şey önceden hesaplanamaz 1M belge = 1M ileri geçiş BU YÜZDEN HAT İKİSİNİ DE KULLANIR derlem 1.000.000 belge AŞAMA 1 — ERİŞ ucuz, recall odaklı BM25 / yoğun / ikisi 50–100 AŞAMA 2 — YENİDEN SIRALA pahalı, precision odaklı çapraz kodlayıcı ilk 5–10 aşama 1, aşama 2'nin yükseltemeyeceği bir tavan koyar bir yeniden sıralayıcı yalnızca kendisine verileni yeniden sıralayabilir

Çift kodlayıcı hiçbir zaman bir çift görmediği için hızlıdır; çapraz kodlayıcı yalnızca çift gördüğü için doğrudur. İki özellik de pazarlığa açık değildir; bu yüzden üretim sistemleri recall’u birincisiyle, precision’ı (kesinlik) ikincisiyle elde eder.

Buradan üç sonuç çıkıyor:

  • Birinci aşama, ikincinin yükseltemeyeceği bir tavan koyar. Bir yeniden sıralayıcı yalnızca kendisine verileni yeniden sıralayabilir. Recall@50 değeri %80 ise hiçbir yeniden sıralayıcı sizi %80’in ötesine geçiremez. Bu yüzden Bölüm 19.7, birinci aşamada izlenecek metriğin recall@k olduğunu savunur.
  • Bedel, kısa listenin uzunluğuyla doğrusal olarak artar; dolayısıyla kalite ile gecikme arasındaki dengeyi kısa liste boyutuyla ayarlarsınız. Kısa liste boyutu ANN parametresinden daha kolay bir ayardır: maliyeti öngörülebilir ve yeniden sıralayıcıya verdiği recall, liste büyüdükçe yalnızca artabilir. Son doğruluk ise başka bir konu — genellikle bir platoya ulaşır, hatta düşebilir; nedenini lab’ın 6. adımı açıklıyor (Bölüm 19.12).
  • Geç etkileşim (late interaction) orta yoldur. ColBERT (Khattab ve Zaharia 2020) token başına bir vektör tutar ve en yüksek benzerliklerin toplamıyla puanlar (her sorgu token’ı kendisine en çok benzeyen belge token’ını bulur ve bu en iyi eşleşmeler toplanır). Böylece önceden hesaplanabilir kalırken çapraz kodlayıcının doğruluğunun büyük kısmını geri kazanır. Bedeli, bir büyüklük mertebesi (yaklaşık on kat) daha fazla depolama alanıdır; ödünleşim de budur.

19.6 Yaklaşık en yakın komşu ve kimsenin bilerek seçmediği ayar

Birkaç bin vektör üzerinde tam arama bir matris çarpımıdır ve hiç zaman almaz — yukarıdaki yoğun erişim sayıları böyle hesaplandı. Milyonlarca vektörde bu arama artık maliyetsiz olmaz ve yaklaşık bir indekse geçersiniz.

“Yaklaşık”, indeksin hız karşılığında gerçek en yakın komşuların bir kısmını kaçırabileceği anlamına gelir. Pratikte iki aile öne çıkıyor:

HNSW (Malkov ve Yashunin 2018) gezilebilir bir çizge kurar ve bu çizgede kaba bir katmandan ince bir katmana doğru açgözlü biçimde ilerler. Hızlı ve doğrudur ama çok bellek ister: çizge ve vektörlerin tam hâli RAM’de tutulur.

IVF-PQ (Johnson vd. 2019) uzayı hücrelere böler (ters dosya, IVF: k-means kümeleri ve her kümenin içindeki vektörlerin listesi), yalnızca en yakın birkaç hücrede arar ve vektörleri product quantization (PQ, çarpım nicemleme) ile sıkıştırılmış olarak saklar. PQ her vektörü kısa parçalara böler ve her parçanın yerine, küçük ve öğrenilmiş bir kod kitabındaki en yakın girdinin numarasını yazar. 768 boyutlu bir float32 vektör 3.072 bayt tutar; 256 girdilik kod kitaplarıyla 96 parçaya bölündüğünde parça başına bir bayt, yani 96 bayt tutar — 32 kat daha küçük. Sıkıştırma kayıplıdır ve bu kayıp doğruluktan götürür.

İkisi de recall ile gecikme arasındaki dengeyi ayarlayan bir düğme sunar: HNSW için efSearch (çizgede ilerlerken kaç adayın tutulduğu), IVF için nprobe (kaç hücrenin arandığı). Aklınızda tutmanız gereken şu: varsayılan değer başka birinin çalışma noktasıdır ve sizin derleminiz olmayan bir benchmark için seçilmiştir.

Burada da Bölüm 12’nin karar eşiğine uyguladığı disiplin geçerlidir: düğmeyi tarayın, recall’u p95 gecikmeye (sorguların %95’inin altında kaldığı gecikme) göre çizin, gecikme SLO’nuzu (hizmet düzeyi hedefi, yani taahhüt ettiğiniz gecikme sınırı) belirtin ve bu SLO’yu karşılayan noktayı seçin.

Recall’u da kütüphanenin yayımladığı eğriye göre değil, kendi verinizde tam aramaya göre ölçün. Kayıp, vektörlerinizin nasıl dağıldığına bağlıdır; bu dağılım da derleminizin ve embedding modelinizin bir özelliğidir.

Bir ANN indeksini tam aramayla değil de etiketlerle karşılaştırarak değerlendirmenin bir tuzağı var. İndeksi açtığınızda recall@10’unuz düşüyorsa, indeksin mi belge kaybettiğini yoksa embedding’in baştan mı yanlış olduğunu bilmek istersiniz. Tam arama bu ikisini ayıran kontroldür; onu bir örneklem üzerinde bir kez çalıştırmak da ucuzdur.

19.7 Erişimi ölçmek

Yukarıdakilerin hepsi dört sütunla — iki derinlikte recall, MRR ve nDCG — raporlandı ve her biri için yalnızca tek satırlık bir açıklama verildi. Aşağıdaki tablo, tabloların kullanmadığı precision@k’yı da ekliyor. Bu metriklerin her biri farklı bir soruya cevap verir ve yanlış olanı seçmek, erişimdeki bir gerilemenin fark edilmeden kalmasına yol açar.

Dört metrik, dört soru
metrik sorduğu ne zaman kullanılır
recall@k ilgili belgelerin ne kadarı ilk k içinde? Sorgu başına tek ilgili belge varken — bu bölümün kurulumu — bu, listede hiç var mı sorusuna iner ve buna isabet oranı ya da success@k da denir çıktıyı kullanan taraf k sonucun tamamını okuduğunda — her RAG sistemi dâhil
MRR ilk doğru cevap ne kadar yukarıda? kullanıcı tek bir sonuç okuyup durduğunda
nDCG@k ilgili belgeler, ilgililik derecelerine göre ağırlıklandırıldığında listenin tepesine yakın mı? dereceli ilgililik, birden çok ilgili belge
precision@k k’nın ne kadarı ilgili? yanlış bir sonucun bedeli sonuç başına olduğunda

recall@k — bir sorgunun ilgili belgelerinin ilk k içinde görünen payı. Buradaki gibi tam olarak bir ilgili belge varken doğru belge hiç göründü mü sorusuna iner; bu niceliğe çoğunlukla isabet oranı ya da success@k denir. Sonraki bütün aşamaların sınırını bu sayı çizer: bir üretici, retriever’ın hiç döndürmediği bir belgeye cevap dayandıramaz. ↩︎

Sıraya duyarlı iki metrik, yazıya dökülecek kadar kısa. Bir sorgu kümesi \(Q\) için \(\text{sıra}_q\), \(q\) sorgusunun ilk ilgili belgesinin konumu olsun:

\[ \text{MRR@}k = \frac{1}{|Q|}\sum_{q \in Q} \frac{1}{\text{sıra}_q} \quad (\text{sıra}_q > k \text{ ise terim } 0 \text{ sayılır}) \]

\[ \text{DCG@}k = \sum_{i=1}^{k} \frac{\text{rel}_i}{\log_2(i+1)}, \qquad \text{nDCG@}k = \frac{\text{DCG@}k}{\text{IDCG@}k} \]

Burada \(\text{rel}_i\), \(i\). konumdaki belgenin ilgililik derecesidir (bu bölümde 0 ya da 1); IDCG@\(k\) ise mümkün olan en iyi sıralamanın DCG’sidir, dolayısıyla nDCG 0 ile 1 arasında kalır. Bazı araçlar kazanç olarak \(\text{rel}_i\) yerine \(2^{\text{rel}_i}-1\) kullanır; 0/1 etiketlerde ikisi aynı sonucu verir.

Bu bölümün tablolarındaki gibi tek ilgili belgeyle işlenmiş bir örnek. Belgenin 3. sırada geldiğini varsayın. O zaman recall@1 = 0, recall@10 = 1, sıra tersi (reciprocal rank, 1/sıra) \(1/3 \approx 0{,}33\) ve nDCG@10 \(1/\log_2 4 = 0{,}5\) olur (ideal liste onu 1. sıraya koyar, dolayısıyla IDCG = 1). İki metrik de 3. sırayı cezalandırır, ama nDCG daha yumuşak cezalandırır. Yukarıdaki tabloların her satırında nDCG@10’un MRR@10 ile recall@10 arasında durmasının nedeni budur.

Bir RAG sisteminin erişim aşaması için tek bir sayı raporlayacaksanız, modele gerçekten verdiğiniz k için recall@k raporlayın. Bu sayı, dayandırmanın (grounding: cevabı getirilen metne dayandırma) sağlayabileceğinin tavanıdır: üretici (Bölüm 20) cevabı yalnızca kendisine ulaşan belgelere dayandırabilir. Dolayısıyla soru başına tek ilgili belge varken erişimde recall@10 %80 ise, cevapların %20’si daha üretim başlamadan getirilen kanıta dayandırılamaz durumdadır — ve prompt (istem) üzerinde ne kadar uğraşırsanız uğraşın bunlar düzelmez. (Bu tavanın hangi koşullarda geçerli olduğunu aşağıdaki 5. sezgi kontrolü açıklıyor.)

Sonuç olarak iki aşama farklı metrikler gerektirir. Birinci aşama recall üzerinden değerlendirilir, çünkü işi hiçbir şeyi kaçırmamaktır. İkinci aşama — bir yeniden sıralayıcı ya da üreticinin kendisi — precision ve sıralama üzerinden değerlendirilir, çünkü işi seçmektir. Birinci aşamayı precision@1 için optimize etmek yaygın ve pahalı bir hatadır.

Ölçümün kendisi hakkında iki pratik not:

  • İlgililik yargılarına ihtiyacınız var ve onları kurmak asıl iştir. Etiket yoksa en ucuz sağlam başlangıç bu bölümün yaptığıdır: elinizdeki belgeleri alın, cevabını bildiğiniz sorgular kurun ve sentetik sorguların bir vekil olduğunu kabul edin. Kendi derleminizi ölçmek yerine yayımlanmış sayılarla karşılaştırmak istiyorsanız BEIR (Thakur vd. 2021) başvurulacak benchmark takımıdır.
  • Sorgu karışımını raporlayın. Bölüm 19.3 baştan sona tek bir şeyi savunur: sorgu dağılımı verilmeyen bir erişim sayısı yorumlanamaz. Aynı iki sistem, aynı derlemde iki koşul arasında altmış puanlık farkla yer değiştiriyor.

19.8 Vektör veritabanı mı, değil mi?

Son karar vektörlerin nerede tutulacağıdır ve bu karar genellikle çok erken ve çok pahalıya verilir. Kullanışlı bir rehber ölçeğe göre ayrım yapar:

Vektörler nereye konur
belge ne kullanılır neden
~100 binin altı NumPy dizisi artı tam arama bir matris çarpımı; bu bölümdeki yoğun erişim sayıları böyle hesaplandı ve sonuç kesindir
~100 bin–10 milyon zaten çalıştırdığınız Postgres’te pgvector ya da süreç içi FAISS işlemler (transaction), yedekleme, join’ler ve erişim kontrolü hazır gelir; işletmeniz gereken yeni bir servis de olmaz
10 milyon+ ya da çok kiracılı özel bir vektör deposu sharding (veriyi makinelere bölme), çoğaltma ve süzgeçli arama sizin çözeceğiniz problem olmaktan çıktığında

Çoğu proje için varsayılan cevap sıkıcı olanıdır: vektörleri ait oldukları verinin yanında tutun.

İkinci bir veri deposunun operasyonel bedeli — onunla asıl veri kaynağınız (source of truth, sistemin esas kabul ettiği kayıt deposu) arasındaki tutarlılık, kendine ait yedekleme düzeni, kendine ait erişim kontrol modeli — genellikle kısaltmaya çalıştığınız sorgu gecikmesinden büyüktür. Üstelik bu bedel, zamanlamasını başka bir ekibin belirlediği bir anda önünüze çıkar.

Özel bir depoyu gerçekten zorunlu kılan etken nadiren ham ölçektir; asıl etken ölçekte süzgeçli aramadır: “bu kullanıcının görmesine izin verilen, son 90 gündeki, Türkçe ilk 10 belge.” Bunu iyi yapmak için süzgeç ile vektör aramasının birlikte çalışması gerekir. Önce ANN ile ilk 10’u alıp sonra süzmek, süzgeç seçiciyse elinizde hiç sonuç bırakmayabilir; önce süzüp sonra aramak ise ya kalan belgelerde tam aramaya döner (yavaş) ya da HNSW gibi bir çizgede gezinmeyi koparıp recall’u düşürür. Süzgeçle vektör aramasını birlikte yürütmek bir boyut meselesi değil, ayrı bir mühendislik yeteneğidir. İzin süzgeci üstelik bir kalite değil güvenlik ayarıdır: kullanıcının görmemesi gereken bir belge, sıralamada ne kadar iyi olursa olsun erişimden dönmemelidir.

19.9 Sezgi kontrolleri

Her birini açmadan önce cevaplayın. Çoğu, bu bölümün tartışmayla değil ölçümle çözdüğü sorular.

Yalnızca gerçekte hangi sorguları aldığınızı kontrol ettikten sonra. Tek bir derlemde yapılan ölçümde aynı iki sistem, iki sorgu koşulu arasında altmış puanlık farkla yer değiştirdi: anahtar kelime sorgularında gövdelenmiş BM25 %96,0, yoğun retriever %35,9 aldı; diller arası sorgularda ise yoğun retriever %96,2, BM25 %23,8 aldı.

Hiçbir aile baskın değil. Sözcüksel erişim, tam eşleşme ve nadir token içeren sorgularda kazanır; yoğun erişim ise başka sözcüklerle anlatımda, eş anlamlılıkta ve dil sınırını aşan her şeyde. Seçmeden önce yüz gerçek sorgu örnekleyip sınıflayın.

Sistemler eşit güçte olmadığında hayır. Buradaki ölçümde RRF, her seferinde daha iyi sisteme göre bir koşulda 32,8 puan, diğerinde 46,8 puan kaybettirdi.

RRF, zayıf bir sistemden gelen 1. sıra isabetine güçlü bir sistemden gelenle birebir aynı ağırlığı verir. Bu yüzden zayıf sistemin üst sıralara koyduğu yanlış cevaplar, güçlü sistemin doğru cevaplarını yerinden eder. Birleştirme karşılaştırılabilir sistemler için bir varyans azaltma tekniğidir. Birleştirmeden önce sizinkilerin karşılaştırılabilir olduğunu kontrol edin; bunun bedeli tek bir değerlendirme çalıştırmasıdır.

Recall@1’e bakın. Bu bölümün B koşulunda birleştirme recall@10’u %99,9’dan %99,6’ya düşürdü, yani neredeyse hiç değiştirmedi; recall@1 ise %96,2’den %49,4’e indi. Belge hâlâ getiriliyordu, ama listede aşağı itilmişti.

Hangi metriğin önemli olduğu, sonucu kimin kullandığına bağlıdır. Bir modele on parça geçiren RAG hattı recall@10’u önemser. İlk sonucu okuyan bir kullanıcı recall@1’i önemser. Yalnızca iyi görüneni raporlamak, erişimde kendini kandırmanın en kolay yoludur.

Ünlü olanı değil ve fark yalnızca zor girdilerde görünür. Burada bir benzerlik modeliyle bir erişim modeli arasındaki fark kolay koşulda 2,4 puandı — zor koşulda ise 25,3 puan: %10,6’ya karşı %35,9.

Benzerlik modelleri iki cümlenin ne kadar benzediğini puanlamak üzere eğitilir; erişim modelleri zor negatiflerle sorgu-belge çiftleri üzerinde eğitilir. Bunlar farklı görevlerdir. Bunun değerlendirmeye pratik yansıması şudur: test kümeniz kolaysa her model aynı görünür ve modeli indirme sayısına göre seçersiniz.

Çünkü bir üretici, hiç almadığı bir belgeye cevap dayandıramaz. Recall@10 %80 ise ve on parça geçiriyorsanız, soruların %20’sinin cevabı daha model çağrılmadan belgeye dayandırılamaz hâle gelir ve prompt mühendisliği bu sorulara ulaşamaz.

Tavanı kesin ifade edin, çünkü bu tavan yalnızca belirli koşullarda geçerlidir. Model o %20’nin bir kısmına yine de parametrik bilgisinden cevap verebilir; bu cevaplar getirdiğiniz hiçbir şeye dayanmaz. Ama bir olgu, ilgililik yargılarınızın işaretlemediği bir belgede de geçebilir — ve o belgeyle desteklenen bir cevap, yargılar ne derse desin getirilen kanıta dayanıyordur. Yani recall@k, belgeye dayanan cevaplar için ancak iki koşulda bir sınırdır: olgu yalnızca işaretlenmiş tek bir belgede geçiyorsa ve yargılar eksiksizse. Bu koşullar tutmadığında belge recall’u iki yönde de yanıltabilir:

  • Fazla karamsar: olgu iki belgede geçiyor ama yalnızca biri işaretli (yedekli kanıt ya da eksik yargı). Retriever işaretsiz olanı getirirse recall 0 görünür, oysa cevap getirilen kanıta dayanır.
  • Fazla iyimser: cevap iki pasajı birlikte gerektiriyor ve yalnızca biri getirildi. Recall bir isabet gösterir, ama cevap getirilenlerle dayandırılamaz.

Asıl istediğiniz sayı için uçtan uca cevap doğruluğunu ayrıca ölçün.

İki aşamanın farklı metrikler istemesinin nedeni budur. Birinci aşama kaçırmamak üzerinden yargılanır; ikinci aşama — yeniden sıralayıcı ya da üretici — gelenden iyi seçmek üzerinden. Birinci aşamayı precision@1 için ayarlamak, ikinci aşamanın ihtiyaç duyduğu recall’u çöpe atar.

Yaklaşık 100 bin belgenin altında hayır — bir NumPy dizisi üzerinde tam arama bir matris çarpımıdır ve kesindir. Yaklaşık on milyona kadar, zaten çalıştırdığınız Postgres’teki pgvector size işlemleri, yedekleri, join’leri ve erişim kontrolünü ek bir maliyet olmadan sunar.

Özel bir depoyu gerçekten zorunlu kılan şey nadiren ölçektir; süzgeçli aramadır: bu kullanıcının görebileceği, son 90 gündeki, bu dildeki ilk on belge. Böyle bir arama, süzgeçle vektör aramasının birlikte çalışmasını gerektirir. Bunu, kendi tutarlılık ve yedekleme düzeni olan ikinci bir veri deposunu işletmenin yüküyle karşılaştırın.

19.10 Mülakat soruları

Kaynak konusunda — Bölüm 2’deki çekincenin aynısı. Bunlar bu kitabın kullandığı iki güvenilir açık kaynakta tekrar eder; ayrıca bu bölümün ölçümlerinin cevaplanabilir kıldığı sorular vardır.

19.10.1 Mekanizmayı anlayıp anlamadığınızı sınayanlar

S: BM25’i yazın ve k1 ile b’nin ne yaptığını açıklayın.

Puanlama işlevi, uzunluk düzeltmeli, doyuma ulaşan bir terim frekansıyla çarpılmış IDF’tir:

\[ \text{BM25}(q,d) = \sum_{t \in q} \text{IDF}(t) \cdot \frac{f_{t,d}\,(k_1+1)}{f_{t,d} + k_1\left(1 - b + b\,\frac{|d|}{\text{avgdl}}\right)} \]

Burada \(f_{t,d}\), \(t\) teriminin \(d\) belgesinde kaç kez geçtiği; \(|d|\) belgenin uzunluğu, avgdl ise derlemdeki ortalama uzunluktur. IDF genellikle, \(N\) belgenin \(n_t\) tanesinde \(t\) geçiyorsa \(\log\frac{N - n_t + 0{,}5}{n_t + 0{,}5}\) olarak alınır (Lucene, negatife düşmesin diye logaritmanın içine 1 ekler). Yaygın varsayılanlar \(k_1 \approx 1{,}2\)–\(2{,}0\) ve \(b = 0{,}75\)’tir.

Açıkça söylenmesi gereken kısım, formülün neden doyuma ulaştığıdır. Bölüm 2’nin ham sayımlı TF-IDF’inde bir terimin onuncu geçişi birincisi kadar sayılır; burada ise terim frekansı çarpanı hiçbir zaman \(k_1+1\)’i aşamaz ve \(k_1\) bu tavana ne kadar hızlı yaklaşılacağını belirler. \(k_1 = 1{,}2\) ile (uzunluğu yok sayarsak) üç kez geçen bir kelime 1,57 × IDF, yirmi kez geçen bir kelime ise yalnızca 2,08 × IDF katkı verir — yedi kat değil, üçte bir fazla. Dolayısıyla tekrar, sorgunun diğer terimlerinden daha fazlasını eşleştiren bir belgeyi ezip geçemez. \(b\) ise uzunluk normalleştirmesini iki uç arasında ayarlar: \(b=0\) belge uzunluğunu yok sayar, \(b=1\) uzunluğun etkisini tümüyle giderir. scikit-learn’deki sublinear_tf’in aynı fikrin kaba hâli olduğunu eklerseniz iki bölümü birbirine bağlamış olursunuz.

S: Çift kodlayıcı mı çapraz kodlayıcı mı? Neden her yerde daha iyi olanı kullanmıyoruz?

Bir çift kodlayıcı sorguyu ve belgeyi bağımsız gömer, dolayısıyla belgeler bir kez, çevrimdışı kodlanabilir ve arama bir vektör işlemidir. Bir çapraz kodlayıcı çifti birlikte okur ve puanlar; bu ilke olarak daha fazla bilgi kullanır ve önceden hesaplanamaz — bedeli sorgu anında aday başına bir ileri geçiştir. Bu yüzden mimaride hep ikisi birlikte bulunur: kısa listeyi ucuza getirin, pahalıya yeniden sıralayın. Sorulmadan ekleyebileceğiniz devam konusu, kısa listenin nerede doyduğudur: 1.000 adayı yeniden sıralamak, 100 adayı sıralamaktan nadiren daha fazlasını kazandırır ve on kat pahalıya gelir.

S: Yaklaşık bir indekste kaliteyi hangi ayar belirler ve şu anda kaça ayarlı?

HNSW’de efSearch, IVF’de nprobe — çizgenin ne kadarının ya da kaç kümenin ziyaret edileceği. Sorunun asıl amacı ikinci yarısıdır: bu ayarın bir varsayılan değeri vardır; o değeri siz değil, kütüphanenin yazarı seçmiştir ve bu, performans kılığına girmiş bir recall ayarıdır. Gerçek komşuların %92’sini sessizce döndüren bir ANN indeksi, model daha hiçbir şey görmeden tam aramanın bulacağı şeylerin %8’ini çöpe atmıştır. Yaklaşık aramayı bir örneklemde tam aramayla karşılaştırın; böylece sayıyı varsaymak yerine bilirsiniz.

19.10.2 Bir tane yayına alıp almadığınızı sınayanlar

S: Size bir derlem verildi ama hiç sorgu yok. Değerlendirme kümesini nasıl kurarsınız?

Yüz gerçek sorgu toplarım — kayıtlardan, destek taleplerinden, sistemi kullanacak insanlardan — çünkü uydurulmuş sorgular gerçek olanlardan sistematik biçimde daha temizdir ve sınadığınız her sistemi olduğundan iyi gösterir. Sonra havuzlarım: iki üç farklı retriever çalıştırıp ilk 10’larının birleşimini etiketlerim; böylece bütün derlemi okumadan ilgililik yargılarım olur. Şunu da açıkça söylerim: yüz etiketli sorgu bin etiketsiz sorgudan iyidir ve bu küme, sonradan yapacağınız her model seçiminden daha değerlidir.

S: Bir paydaş anlamsal aramanın anahtar kelime aramasının yerini almasını istiyor. Ona ne söylersiniz?

Cevabın onların sorguları hakkında ampirik bir soru olduğunu söyler, sonra bu bölümün iki koşulunu gösteririm: çekimli anahtar kelime sorgularında gövdelenmiş BM25 %96,0 recall@1 aldı, yoğun bir retriever %35,9; diller arası sorgularda aynı yoğun model %96,2 aldı, BM25 %23,8. Aynı derlem, zıt hükümler. Yani asıl teslim edilecek şey onların sorgu karışımının sayımıdır; sorgular gerçekten farklı türlerden oluşuyorsa sorgu türüne göre yönlendirmek birleştirmeyi yener — bu bölüm, RRF’in daha iyi tek retriever’a göre 32,8 ve 46,8 recall@1 puanına mal olduğunu ölçtü.

S: Erişim iyi görünüyor ama cevaplar kötü. Kimin problemi?

Tahmin etmeyin — hatayı bir aşamaya atfedin. Destekleyici belgenin ilk k sonuç içinde olup olmadığını kontrol edin: değilse bu bir erişim problemidir ve hiçbir promptlama bunu düzeltmez; öyleyse modelin ihtiyacı olan elindeydi ve kullanmadı, ki bu bir dayandırma problemidir. Bölüm 20 bu ayrıştırmayı düzgün biçimde kuruyor. Tek cümlelik hâli ve bu bölümün ondan önce gelmesinin nedeni şu: recall@k bütün sistemin tavanıdır; dolayısıyla ilk ölçülmesi gereken şeydir; prompt ayarlayarak ise asla düzeltemeyeceğiniz şeydir.

19.11 2026 alet çantası

Bu bölümdeki her şey aşağıdaki sürümlerle tek bir dizüstü bilgisayarda çalıştı.

Bu sayıların çıktığı yığın
kütüphane kullanılan sürüm burada ne işe yarıyor
sentence-transformers 6.0.0 iki yoğun model ve Bölüm 19.3’teki kodlama
snowballstemmer 3.1.1 A koşulunda 68 puan kazandıran Türkçe gövdeleyici
numpy 2.5.2 BM25, tam yoğun arama ve RRF — bu bölümdeki erişim yığınının tamamı birkaç yüz satır

Yukarıda kullanılmayan ama bilinmesi yararlı olanlar:

Daha geniş ekosistem, yazıldığı andaki sürümler
kütüphane güncel sürüm ne zaman kullanılır
faiss-cpu 1.15.0 HNSW ve IVF-PQ indeksleri (Johnson vd. 2019); referans uygulama ve Bölüm 19.6’nın recall/gecikme ayarını taradığınız yer
pgvector 0.5.0 zaten çalıştırdığınız veritabanında vektörler — çoğu proje için varsayılan cevap; buradaki sürüm Python istemcisinin, PostgreSQL eklentisi ayrıca sürümlenir (0.8.x)
sentence-transformers (CrossEncoder) 6.0.0 Bölüm 19.5’teki çapraz kodlayıcıyla yeniden sıralama; Türkçeyi de kapsayan çok dilli bir yeniden sıralayıcıyla (ör. BAAI/bge-reranker-v2-m3)
qdrant-client / chromadb 1.19.0 / 1.5.9 özel depolar; ölçekte süzgeçli arama gereksinim hâline geldiğinde
rank-bm25 0.2.2 kendiniz yazmadan BM25, hızlı bir baseline için
ir-measures 0.4.3 standart IR metrikleri standart biçimde hesaplanmış; böylece nDCG’niz herkesin nDCG tanımıyla eşleşir

19.12 Lab: melez bir retriever kurun ve ayarlayın

İki aileyi de kendi sorgularınızda kurun; ardından birleştirmeyi yayına aldıktan sonra değil, almadan önce kontrol edin.

19.12.1 Adım 1 — yüz gerçek sorgu toplayın

Varsa kayıtlardan, yoksa kullanıcılardan. Diğer her şeye karar veren adım budur, çünkü Bölüm 19.3 baştan sona tek bir şeyi gösterir: hangi retriever’ın kazanacağını sorgu dağılımı belirler.

Sınıflayın: tam eşleşme (parça numaraları, adlar, kodlar), doğal dil soruları ve dil sınırını aşan her şey.

19.12.2 Adım 2 — ilgililiği etiketleyin, sonra BM25 kurun

Her sorgu için onu cevaplayan belge. Elli etiketli sorgu, hata çözümlemesi için işleyebilir bir başlangıçtır; ama bu sayının on puanlık bir farkı doğrulamaya yettiğini sanmayın. Aritmetiği yapın: elli sorguda on puan, beş ek başarı demek. En elverişli dağılımda bile — beş kazanım, sıfır kayıp — iki taraflı kesin (exact) McNemar testi \(p = 2/2^5 = 0{,}0625\) verir; bu da %5 eşiğinin altına inmez. Gerçekte kaç sorgu gerektiği sistemlerin temel başarı oranına, iki sistemin hatalarının ne kadar ilişkili olduğuna (ortak sorgular üzerinde eşleştirilmiş bir test, bağımsız örneklemlerle yapılan eşleştirilmemiş bir testten çok daha az sorgu ister) ve kaç karşılaştırma yapmayı planladığınıza bağlıdır. Önemsediğiniz fark on değil beş puansa ya da sistemler neredeyse her sorguda aynı sonucu veriyorsa, birkaç yüz sorguluk bütçe ayırın. Sonra BM25 kurun — ve diliniz morfolojik olarak zenginse iki kez kurun, gövdelemeli ve gövdelemesiz, çünkü Bölüm 16 o tek adımın altmış puandan fazla kazandırabileceğini söylüyor.

19.12.3 Adım 3 — bir erişim modeliyle yoğun erişim ekleyin

Benzerlik modeliyle değil. Kodlayın, tam arayın — 100 binin altında belgede henüz indekse ihtiyacınız yok — ve recall@1 ile recall@10’u BM25’in yanına raporlayın.

19.12.4 Adım 4 — birleştirmenin yardımcı olup olmadığını yayına almadan önce kontrol edin

RRF’i çalıştırın ve sonucu zayıf olanla değil, daha iyi sistemle karşılaştırın. Sistemler yaklaşık yirmi puandan fazla ayrışıyorsa birleştirmenin zarar vermesini bekleyin ve doğrulayın. Buradaki yirmi, ölçülmüş bir eşik değil kaba bir kural: bu bölümde ölçülen farklar altmış puan ve üzeriydi. Bu on beş dakikalık bir kontroldür ve yaygın “melez her zaman kazanır” kanısı, bu kontrolün sık atlandığını düşündürüyor.

19.12.5 Adım 5 — sorgularınız karışıksa birleştirmek yerine yönlendirin

Sorguyu sınıflayın ve onu ele alabilen retriever’a gönderin. Yönlendiricinin doğruluğunu retriever’larınkinden ayrı ölçün, çünkü bir yönlendirici hatası ve bir erişim hatası son sayıda birebir aynı görünür ve farklı düzeltmeleri vardır.

19.12.6 Adım 6 — bir yeniden sıralayıcı ekleyin ve kısa listenin nerede doyduğunu bulun

İlk 10, 25, 50, 100 üzerinde çapraz kodlayıcı. Son doğruluğu gecikmeye karşı çizin. Kısa liste boyutu her ANN parametresinden daha temiz bir ayardır — ama eğrinin yalnızca yukarı gittiğini varsaymayın. Daha büyük bir havuz, yeniden sıralayıcının çalışacağı recall’u yükseltir ve bu artış monotondur; son doğruluktaki artış ise değildir, çünkü her fazladan aday aynı zamanda yeniden sıralayıcının bir çeldiriciyi doğru cevabın üstüne koyması için bir şans daha demektir. Gözlenen aralığın dışına tahmin yürütmek yerine eğriyi çizin ve bir yerden sonra bir plato ya da hafif bir düşüş bekleyin.

19.12.7 Neyi teslim edeceksiniz

Kendi sorgularınızda her sistem için sorgu türüne göre ayrılmış recall@1, recall@10 ve nDCG@10 içeren tek bir tablo; 4. adımın birleştirme kontrolü ve hükmü; ve birinci aşamanızın aşağı akıştaki her şeye dayattığı tavanı adlandıran bir cümle.

19.13 Alıştırmalar

  1. Yer değiştirmeyi bulun. Tek bir derlemde BM25 ve yoğun bir retriever kurun. Her birinin diğerini geniş farkla yendiği üçer sorgu bulun ve örüntüyü tek cümlede belirtin.

  2. Birleştirme sonucunu yeniden üretin. Verinizde en az yirmi puan ayrışan iki retriever alın ve RRF ile birleştirin. İki sistemin her biri ve birleştirme için recall@1 ile recall@10’u raporlayın. Hasarın biçimini açıklayın.

  3. Birleştirmeyi ağırlıklandırın. 2. alıştırmayı düz RRF yerine ağırlıklı bir bileşimle, ağırlığı ayrılmış sorgularda ayarlayarak tekrarlayın. Kaybın ne kadarını geri kazanıyorsunuz ve ayarlama genellemede size neye mal oldu?

  4. Benzerlik modeline karşı erişim modeli. İkisini de kolay bir sorgu kümesinde ve zor bir kümede çalıştırın. Her birindeki farkı raporlayın. Sonra yalnızca tek bir sorgu kümesi kursaydınız hangisini kullanmış olacağınızı söyleyin.

  5. ANN ayarı. efSearch ya da nprobe tarayın ve recall’u p95 gecikmeye karşı çizin. Recall’u etiketlerinize göre değil, tam aramaya göre ölçün; böylece indeks kaybını embedding hatasından ayırırsınız.

  6. Tavan olarak recall. Retriever’ınızda k = 1, 5, 10, 25 için recall@k ölçün. Her biri için aşağı akıştaki bir üreticinin ulaşabileceği en yüksek doğruluğu belirtin. RAG sisteminizin gerçekte ulaştığıyla karşılaştırın ve kalan farkın hangi aşamadan kaynaklandığını söyleyin.

  7. Sorgu türü sayımı. Üretim ortamından 100 sorgu örnekleyin ve sınıflayın. Bu bölümün tablolarına bakarak, sizin sorgu karışımınızda hangi retriever’ın kazanması gerektiğini öngörün. Sonra ölçün ve haklı olup olmadığınıza bakın.

19.14 Daha derine

Önce şunu yapın: yirmi gerçek sorgu alın ve doğru belgenin ilk 10 sonuç içinde olup olmadığını kontrol edin. O sayı, sonradan kuracağınız her şeyin tavanıdır ve çoğu ekip onu hiç ölçmemiştir.

Makalelerin ötesi
kaynak ne olduğu
Introduction to Information Retrieval — Manning, Raghavan, Schütze ücretsiz ve hâlâ en iyi temel; indeksleme ve değerlendirme bölümleri eskimedi
Sentence Transformers çift kodlayıcılar, çapraz kodlayıcılar ve her birinin ne zaman uygun olduğuna dair pratik rehber
Pinecone Learn ticari bir firmanın yayını ama ANN indeksleri ve melez arama üzerine gerçekten iyi açıklayıcı yazılar
faiss referans ANN kütüphanesi; wiki’si recall ile gecikme arasındaki ayarı çoğu makaleden iyi açıklıyor
ColBERT geç etkileşim; Bölüm 19.5’teki iki mimari arasındaki orta yol
Birincil kaynaklar
konu kaynak
BM25, iddia edilmek yerine türetilmiş Robertson ve Zaragoza (2009)
standartlaştığı hâliyle yoğun erişim Karpukhin vd. (2020)
burada kullanılan çok dilli erişim modeli Wang vd. (2024)
çapraz kodlayıcıyla yeniden sıralama Nogueira ve Cho (2019)
geç etkileşim Khattab ve Zaharia (2020)
bu bölümde ölçülüp zararlı bulunan birleştirme Cormack vd. (2009)
işe yarayan yaklaşık arama Malkov ve Yashunin (2018); Johnson vd. (2019)
genellemenin zor olduğunu gösteren benchmark Thakur vd. (2021)

19.15 Akılda kalması gerekenler

  • Hiçbir erişim ailesi baskın değildir ve sorgu türü karar verir. Aynı derlem, iki sorgu koşulu: anahtar kelime sorgularında gövdelenmiş BM25 %96,0, yoğun retriever %35,9; diller arası sorgularda yoğun retriever %96,2, BM25 %23,8. Sorgu dağılımı belirtilmeyen bir erişim sayısı yorumlanamaz.

  • Ağırlıksız RRF’in bir bedeli vardır ve etkisi her zaman olumlu değildir. İki koşulda daha iyi sisteme göre 32,8 ve 46,8 recall@1 puanına mal oldu; çünkü sıra birleştirmesi zayıf bir sistemden gelen 1. sıra isabetini güçlü bir sistemdenmiş gibi ağırlıklandırır. Ağırlıksız kelimesine dikkat: sıra birleştirmesi skor büyüklüğünü çöpe atıyor; oysa “emin ve haklı” bir sistemi “emin ama yanlış” olandan ayıran tek sinyal odur. Ağırlıklı RRF bu bilgiyi geri getirmez: yine sıraları birleştirir, yalnızca her sistemin katkısını sabit bir ağırlıkla ölçekler. Normalleştirilmiş skorlarla birleştirme (Bruch vd. 2024) ise skorların kendisini kullanır. İkisi de veriden ayarlanan tek bir parametre ister ve burada ikisi de ölçülmedi.

  • Hasar recall@10’a değil recall@1’e iner. B koşulunda birleştirme R@10’u %99,9’dan %99,6’ya, R@1’i %96,2’den %49,4’e götürdü. Hangi metriği izlediğiniz fark edip etmeyeceğinizi belirler.

  • Karşılaştırılabilir sistemleri birleştirin; karışık sorgu yüklerini yönlendirin. Sorgularınızda bir retriever baskınsa onu kullanın. Kullanıcılarınız iki türü de gönderiyorsa sorguyu sınıflayıp dağıtın — ve yönlendiriciyi ayrı değerlendirin.

  • Benzerlik modeli erişim modeli değildir. İkisi kolay koşulda 2,4 puan, zor koşulda 25,3 puan ayrıydı. Bileşen kalitesi yalnızca o bileşen için zor olan girdilerde görünür olur; bu da değerlendirmenizde zor bir dilim tutmak için bir argümandır.

  • Yoğun retriever eğitiminde asıl belirleyici olan zor negatiflerdir. Batch içi negatifler konusal ayrımı öğretir; modelin kendi sonuç listesinden seçilen zor negatifler kullanıcılarınızın ihtiyaç duyduğu ayrımı öğretir. Model iyileştikçe negatifleri yeniden seçin. Etiketlenmemiş ilgili belgeleri modele yanlış diye öğretmemek için de negatifleri listenin tepesinin biraz altından seçin.

  • Geniş erişin, hassas yeniden sıralayın. Bir çapraz kodlayıcı genellikle daha doğrudur ve önceden hesaplanamaz, dolayısıyla bir kısa listeyi yeniden sıralar. Yalnızca birinci aşamanın döndürdüğünü sıralayabilir — birinci aşama, ikincinin yükseltemeyeceği bir tavan koyar.

  • Aşağı akışa gerçekten geçirdiğiniz k için recall@k raporlayın. Herhangi bir RAG sisteminin neyi kanıta dayandırabileceğini bu sınırlar: bir üretici hiç almadığı bir belgeye cevap dayandıramaz. Soru başına tek ilgili belge varken %80 recall@10, soruların %20’sinin üretim başlamadan getirilen kanıta dayandırılamayacağı anlamına gelir (model bir kısmını yine de bellekten, dayanaksız olarak cevaplayabilir).

  • Ölçek zorlayana kadar vektörleri verinin yanında tutun. 100 binin altında belgede tam arama kesin ve anlıktır. Sonunda özel bir depoyu zorunlu kılan şey ham hacim değil ölçekte süzgeçli aramadır.