Gömmeler: Teori ve Uygulama
Her semantik arama sistemi, her RAG işlem hattı ve dille çalışan her yapay zeka uygulaması doğalın temel bir ortak bileşeni vardır: gömmeler. Ben tercümeyim sayıların anlamı, metin dünyası ile matematik dünyası arasındaki köprü. Gömmeler olmadan, bir veritabanı "köpek"i "araba"dan ayırt edemedi - yerleştirmelerle "köpek" ve "kedi"ye "ekmek kızartma makinesi"nden daha yakın.
Bu serinin ilk makalesinde yapılandırdık pgvektör ve kurtarmayı öğrendim ve PostgreSQL'de sorgu vektörleri. Peki bu vektörler nereden geliyor? Bir yerleştirme nasıl oluşturulur? kalite? Ve hepsinden önemlisi, mevcut düzinelerce model arasından hangisini seçmelisiniz? Bu yazımızda cevaplıyoruz Matematik teorisinden Python ve PostgreSQL ile uygulamaya kadar tüm bu sorulara.
Seriye Genel Bakış
| # | Öğe | Odak |
|---|---|---|
| 1 | pgvektör | Kurulum, operatörler, indeksleme |
| 2 | Şu anda buradasınız - Gömmeler | Modeller, mesafeler, nesil |
| 3 | PostgreSQL ile RAG | Uçtan uca RAG boru hattı |
| 4 | Gelişmiş Benzerlik Araması | Hibrit arama, filtreleme |
| 5 | İndeksleme ve Performans | HNSW, IVFFlat, ayarlama |
| 6 | Üretimde RAG | İzleme, ölçeklendirme, CI/CD |
Ne Öğreneceksiniz
- Gömme nedir ve modern yapay zeka için neden temeldir?
- Tarihsel evrim: tek sıcak kodlamadan Word2Vec, GloVe, BERT ve Sentence Transformers'a
- Gömmelerin matematiksel özellikleri: vektör analojileri ve anlamsal kümeleme
- Formüller ve kullanım senaryolarıyla birlikte dört mesafe ölçümü
- Python ile yerleştirmeler nasıl oluşturulur: yerel ve API aracılığıyla
- PostgreSQL'de pgvector ile yerleştirmeler nasıl kaydedilir ve sorgulanır
- Çok modlu yerleştirmeler: metin, resimler, ses ve kod
- Bir yerleştirme modelinin (MTEB) kalitesi nasıl değerlendirilir?
- Milyonlarca belge için maliyetler ve ölçeklendirme stratejileri
1. Gömmeler Nelerdir?
Un gömme ve bir nesnenin yoğun vektör temsili (kelime, cümle, belge, resim) azaltılmış boyutluluğa sahip sürekli bir alanda. Pratik açıdan bu bir dizidir o nesnenin "anlamını" yakalayan kayan noktalı sayıların.
# L'embedding della frase "Il gatto dorme sul divano"
# generato con text-embedding-3-small di OpenAI (1536 dimensioni)
embedding = [
0.0231, -0.0456, 0.0891, -0.0123, 0.0567, -0.0234,
0.0789, -0.0345, 0.0123, -0.0678, 0.0456, -0.0891,
# ... altri 1524 valori ...
]
print(f"Tipo: {type(embedding)}") # <class 'list'>
print(f"Dimensioni: {len(embedding)}") # 1536
Temel fikir şudur: iyi eğitilmiş bir vektör uzayında, geometrik mesafe iki vektör arasındaki anlamsal benzerlik temsil ettikleri kavramlar arasındadır. İfadeler benzer anlamlara sahip olanların vektörleri birbirine yakın olacak, farklı anlamlara sahip olan cümleler ise birbirinden uzak olacaktır.
Gömmelerin Özellikleri
| Mülk | Tanım | Örnek |
|---|---|---|
| Yoğun | Her boyutun sıfır olmayan bir değeri vardır | [0,023, -0,045, 0,089, ...] |
| Devam etmek | Ayrık değerler değil, gerçek değerler | Her bileşen bir float32/float16'dır |
| Sabit boyutluluk | Aynı model her zaman aynı uzunlukta vektörler üretir | 384, 768, 1536 veya 3072 boyutları |
| Anlamsal olarak anlamlı | Vektörler arasındaki mesafeler anlam ilişkilerini yansıtır | sim("kedi", "kedi") > sim("kedi", "araba") |
Gömme alanını bir harita gibi düşünürsek, benzer kavramlar "mahalleleri" oluşturur: Bir tarafta hayvanlar, diğer tarafta araçlar, başka bir yerde duygular. Ama güzellik bu ilişkilerin eğitimden otomatik olarak ortaya çıkması gerçeğinde yatmaktadır; manuel olarak programlanmıştır.
2. Kelimelerden Vektörlere: Tarihsel Evrim
Yerleştirmelerin tarihi, her biri giderek daha karmaşık hale gelen fikirlerin bir ilerlemesidir. bu da öncekinin sınırlamalarını çözer. Bu evrimi anlamak nedenini anlamaya yardımcı olur modern modeller çok iyi çalışıyor.
2.1 Tek Kullanımlık Kodlama (1990'lar)
En basit yaklaşım: her kelime yalnızca bir tanesi 1 ve tümü olan bir vektörle temsil edilir diğerleri 0. Kelime dağarcığında V kelime varsa, her vektörün V boyutu vardır.
# Vocabolario: ["gatto", "cane", "pesce", "auto", "moto"]
# Dimensione vettore = dimensione vocabolario = 5
gatto = [1, 0, 0, 0, 0]
cane = [0, 1, 0, 0, 0]
pesce = [0, 0, 1, 0, 0]
auto = [0, 0, 0, 1, 0]
moto = [0, 0, 0, 0, 1]
# Problema 1: la distanza tra "gatto" e "cane" e uguale
# alla distanza tra "gatto" e "auto"
import numpy as np
dist_gatto_cane = np.linalg.norm(
np.array(gatto) - np.array(cane)
) # sqrt(2) = 1.414
dist_gatto_auto = np.linalg.norm(
np.array(gatto) - np.array(auto)
) # sqrt(2) = 1.414 -- identica!
# Problema 2: con un vocabolario di 100.000 parole,
# ogni vettore ha 100.000 dimensioni (sparso, inefficiente)
Tek Kullanımlık Kodlamanın Sınırları
Patlayıcı Boyutluluk: 100.000 kelimelik bir kelime dağarcığı için her vektörün 100.000 boyutu vardır, neredeyse tamamı sıfır. Anlamsal bilgi yok: tüm vektörler eşit uzaklıkta aralarında. "Kedi", "deprem"e olduğu kadar "kedi"ye de uzaktır. Bu yaklaşım kelimeler arasındaki herhangi bir anlam ilişkisini yakalamaz.
2.2 TF-IDF (Dönem Frekansı - Ters Belge Frekansı)
Bir adım daha ileri: 0/1 yerine vektör bileşenleri bir kelimenin ne kadar önemli olduğunu gösterir bir belgede tüm külliyatla karşılaştırıldı. Ancak her belge, ortama dağılmış bir vektör haline gelir. Kelime dağarcığının boyutluluğu.
from sklearn.feature_extraction.text import TfidfVectorizer
documenti = [
"il gatto dorme sul divano",
"il cane gioca nel giardino",
"l'automobile corre sulla strada",
"il felino riposa sulla poltrona",
]
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(documenti)
# Risultato: matrice sparsa (4 documenti x N termini)
print(f"Shape: {tfidf_matrix.shape}") # (4, 14)
print(f"Termini: {vectorizer.get_feature_names_out()}")
# Problema: "gatto dorme" e "felino riposa" sono lontani
# perchè usano parole diverse, anche se il significato e simile
from sklearn.metrics.pairwise import cosine_similarity
sim = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[3:4])
print(f"Similarità gatto-felino: {sim[0][0]:.3f}") # ~0.07 (bassa!)
TF-IDF, sözcükleri önemlerine göre ağırlıklandırarak tek geçişli kodlamayı geliştirir, ancak aynı sorundan muzdariptir temel sorun: "kedi" ve "kedi"nin eşanlamlı olduğunu anlamıyor çünkü öyle düşünüyor yalnızca tam sözcüksel eşleşmelerde.
2.3 Word2Vec: Devrim (2013)
2013 yılında Tomas Mikolov ve Google'daki ekibi her şeyi değiştiren Word2Vec'i piyasaya sürdü. Harika fikir: Bir kelime göründüğü bağlama göre tanımlanır. kelimeler benzer bağlamlarda ortaya çıkanlar benzer temsillere sahip olacaktır.
Word2Vec yoğun vektörleri (genellikle 100-300 boyut) öğrenmek için sığ sinir ağlarını kullanır büyük metin topluluğundan. İki mimari:
Word2Vec mimarileri
| Mimarlık | Giriş | Çıkışlar | Tanım |
|---|---|---|---|
| CBOW | Bağlam kelimeleri | Hedef kelime | Çevreleyen bağlam göz önüne alındığında merkezi kelimeyi tahmin eder |
| Gram atla | Hedef kelime | Bağlam kelimeleri | Merkezi kelime verildiğinde çevredeki kelimeleri tahmin eder |
from gensim.models import Word2Vec
# Corpus di esempio (in produzione: milioni di frasi)
frasi = [
["il", "gatto", "dorme", "sul", "divano"],
["il", "cane", "gioca", "nel", "giardino"],
["il", "felino", "riposa", "sulla", "poltrona"],
["il", "cane", "corre", "nel", "parco"],
]
# Addestramento Word2Vec (Skip-gram)
model = Word2Vec(
sentences=frasi,
vector_size=100, # dimensionalità embedding
window=5, # contesto: 5 parole prima e dopo
min_count=1, # includi parole con almeno 1 occorrenza
sg=1, # 1 = Skip-gram, 0 = CBOW
epochs=100
)
# Ora "gatto" e "felino" sono vicini!
print(model.wv.most_similar("gatto", topn=3))
# [('felino', 0.92), ('cane', 0.85), ('dorme', 0.71)]
# Accesso al vettore
vettore_gatto = model.wv["gatto"]
print(f"Dimensioni: {vettore_gatto.shape}") # (100,)
print(f"Primi 5: {vettore_gatto[:5]}")
2.4 Eldiven: Küresel Vektörler (2014)
Stanford farklı bir yaklaşımla GloVe'yi (Kelime Temsili için Küresel Vektörler) geliştirdi: GloVe, bir sinir ağı yerine, birlikte oluşum matrisi küresel külliyat. Küresel istatistiksel yöntemlerin (LSA gibi) avantajlarını aşağıdakilerle birleştirir: Word2Vec yerel bağlamının.
GloVe, iki vektör arasındaki nokta çarpımın elde edilmesini sağlayan bir maliyet fonksiyonunu en aza indirir. kelimelerin bir arada bulunma olasılıklarının logaritması ile orantılıdır:
2.5 FastText: Alt Kelime Yerleştirmeleri (2016)
Facebook Yapay Zeka Araştırması (FAIR), Word2Vec'i aşağıdakilerle genişletti: Hızlı Metintemsil ettiği Her kelime n gramlık karakter kümesi olarak. Bu, iki kritik sorunu çözer:
- Nadir veya sözlükte bulunmayan (OOV) kelimeler: FastText, alt segment vektörleri oluşturarak daha önce görülmemiş kelimeler için yerleştirmeler oluşturabilir
- Morfoloji: Morfolojik olarak ilişkili kelimeler (örneğin, "koşmak", "koşmak", "koşucu") n-gramları paylaşırlar ve bu nedenle benzer vektörlere sahiptirler
Evrim: Seyrek Temsillerden Yoğun Temsillere
| Yöntem | Yıl | Tip | Tipik Boyutlar | Anlambilim |
|---|---|---|---|---|
| Bir sıcak | - | Dağınık | V (kelime bilgisi) | Hiçbiri |
| TF-IDF | 1972 | Dağınık | V (kelime bilgisi) | İstatistikler |
| Word2Eski | 2013 | Yoğun | 100-300 | Yerel bağlamsal |
| Eldiven | 2014 | Yoğun | 50-300 | Küresel + yerel |
| Hızlı Metin | 2016 | Yoğun | 100-300 | Alt kelime + bağlam |
| BERT | 2018 | Yoğun | 768 | Bağlamsal dinamikler |
| Cümle Transformatörleri | 2019 | Yoğun | 384-1024 | Tam cümleler |
3. Gömmelerin Matematiksel Özellikleri
Word2Vec'in en büyüleyici keşiflerinden biri vektör uzayının öğrenebilmesidir kavramlar arasındaki cebirsel ilişkiler. Vektörler üzerinde aritmetik işlemler Anlamsal olarak tutarlı sonuçlar üretir.
3.1 Vektör Analojileri
Ünlü benzetme: kral - erkek + kadın = kraliçe. Vektör açısından, "kral" ve "erkek" arasındaki fark, "kraliyet" kavramını yakalıyor ve onu "kadın"a ekliyor "kraliçe" olursun. Resmi olarak:
import gensim.downloader as api
# Carica embeddings GloVe pre-addestrati
model = api.load("glove-wiki-gigaword-100")
# king - man + woman = ?
result = model.most_similar(
positive=["king", "woman"],
negative=["man"],
topn=3
)
print(result)
# [('queen', 0.7698), ('princess', 0.6450), ('monarch', 0.6345)]
# Altre analogie che funzionano:
# Parigi - Francia + Italia = Roma
result2 = model.most_similar(
positive=["paris", "italy"],
negative=["france"],
topn=1
)
print(result2) # [('rome', 0.8722)]
# buono - cattivo + triste = ?
result3 = model.most_similar(
positive=["good", "sad"],
negative=["bad"],
topn=1
)
print(result3) # [('happy', 0.6891)]
3.2 Anlamsal Kümeleme
Gömmeler doğal olarak vektör uzayında kümeler oluşturur. Eğer projelendirirsek 2 boyutlu vektörler (t-SNE veya UMAP kullanarak) kullanarak aynı kategorideki kelimelerin olduğunu gözlemliyoruz. birlikte gruplanırlar: hayvanların yakınındaki hayvanlar, ülkelerin yakınındaki ülkeler, yakınlardaki meslekler mesleklere.
Bu özellik pratik uygulamalar için temeldir: benzerlik arama çalışmaları tam olarak benzer konulara ilişkin belgelerin vektör uzayında yakın yerleşimlere sahip olması nedeniyle.
4. Modern Yerleştirmeler: Bağlamsal Yerleştirmeler
Word2Vec ve GloVe bir kelime için tek vektör, bağımsız bağlam. Ancak “okul”, “okul sırası” ve “balık okulu”nda farklı anlamlara sahiptir. THE bağlamsal yerleştirmeler2018'de BERT ile tanıtılan bu soruna çözüm: aynı kelimenin bağlama bağlı olarak farklı vektörleri vardır.
4.1 BERT Gömmeleri
BERT (Transformatörlerden Çift Yönlü Kodlayıcı Gösterimleri) tüm cümleyi ve çıktıları işler Her jeton için bir vektör. Cümlenin tamamını gömmek için genellikle şunları kullanırsınız:
- CLS jetonları: ilk özel belirteç [CLS] cümlenin toplu bir temsilini içerir
- Ortalama havuzlama: tüm belirteç vektörlerinin ortalaması - genellikle benzerlik araması için daha iyi sonuçlar üretir
BERT benzerlik araması için ideal değil
Orijinal BERT, kaliteli cümle yerleştirmeleri üretmek için eğitilmemişti. CLS jetonu ve anlamsal benzerlik için değil, sınıflandırma için optimize edilmiştir. Benzerlik araması için Cümle Dönüştürücüleri gibi özel modellere ihtiyaç vardır.
4.2 Cümle Dönüştürücüleri (SBERT)
2019'da Reimers ve Gurevych, BERT'e ince ayar yapan Sentence-BERT'i tanıttı. Anlamlı cümle yerleştirmeleri üretmek için Siyam dili. Bu devrim yaratan benzerlik arama: ilk kez cümleleri basit kosinüs mesafesiyle karşılaştırmak mümkün oldu, yüksek kalitede sonuçlar elde etmek.
4.3 Gömme Modelleri: Kapsamlı Karşılaştırma
Gömme Modelleri Karşılaştırıldı (2026)
| Modeli | Sağlayıcılar | Boyutlar | METEB Skoru | Maliyet / 1 milyon jeton | Notlar |
|---|---|---|---|---|---|
| metin yerleştirme-3-küçük | OpenAI | 1536 | 62.3 | 0,02$ | İyi kalite/fiyat oranı |
| metin gömme-3-büyük | OpenAI | 3072 | 64.6 | 0,13$ | Maksimum OpenAI kalitesi |
| gömme-v3 | tutarlı | 1024 | 64.5 | 0,10$ | 100'den fazla dili destekler |
| yolculuk-3 | Yolculuk Yapay Zekası | 1024 | 67.1 | 0,06$ | Geri alma için üst kısım |
| hepsi-MiniLM-L6-v2 | SarılmaYüz | 384 | 56.3 | Özgür | Hızlı, yerel, kompakt |
| tüm-mpnet-base-v2 | SarılmaYüz | 768 | 57.8 | Özgür | En iyi temel açık kaynak modeli |
| gte-large-en-v1.5 | Alibaba (HF) | 1024 | 65.4 | Özgür | Ticari modellerle rekabetçi |
| bge-large-tr-v1.5 | BAAI (HF) | 1024 | 64.2 | Özgür | RAG için harika |
Model Nasıl Seçilir?
- Prototip / sınırlı bütçe: all-MiniLM-L6-v2 (ücretsiz, hızlı, 384 loş)
- Üretim, düşük maliyetler: text-embedding-3-small (OpenAI, 0,02 ABD doları/1 milyon jeton)
- En yüksek kalitede alma: voyage-3 veya gte-large-en-v1.5
- Çok dilli: Cohere embed-v3 (100'den fazla dil)
- Kendi kendine barındırılan / gizlilik: bge-large-en-v1.5 veya gte-large-en-v1.5
5. Vektörler Arası Mesafe Ölçümleri
Mesafe ölçümünün seçimi benzerlik aramasının kalitesini doğrudan etkiler. Dört ana ölçümü matematiksel formülleriyle, güçlü yanlarıyla birlikte görelim. ve bunların ne zaman kullanılacağı.
5.1 Kosinüs Benzerliği
Metin yerleştirmeler için en çok kullanılan ölçüm. İki vektör arasındaki açıyı ölçer, büyüklüklerini (uzunluğunu) göz ardı ederek. Aynı yönü gösteren iki vektör kosinüs benzerliği 1, ortogonal 0, karşıtları -1'dir.
pgvector'da operatör <=> hesaplamak kosinüs mesafesi
(= 1 - kosinüs benzerliği), burada 0 aynı, 2 ise zıt anlamına gelir.
5.2 Öklid mesafesi (L2)
Uzaydaki iki nokta arasındaki "kuş uçuşu" mesafe. Her ikisini de dikkate alır vektörlerin büyüklüğünün yönü.
pgvector'da operatör <-> L2 mesafesini hesaplayın.
5.3 Nokta Çarpım (Nokta Çarpım)
Nokta çarpımı hem yönü hem de büyüklüğü ölçer. Normalleştirilmiş vektörler için (norm = 1), nokta çarpımı kosinüs benzerliğine eşdeğerdir.
pgvector'da operatör <#> Negatif iç çarpımı hesaplayın (uyumluluk için
ORDER BY ASC ile).
5.4 Manhattan'a Uzaklık (L1)
Bileşen bazında mutlak farkların toplamı. Aykırı değerlere karşı daha az duyarlı Öklid uzaklığına göre.
import numpy as np
from scipy.spatial.distance import cosine, euclidean, cityblock
# Due vettori di esempio (normalizzati)
a = np.array([0.5, 0.3, 0.8, 0.1, 0.6])
b = np.array([0.4, 0.35, 0.75, 0.15, 0.55])
# Normalizzazione L2
a_norm = a / np.linalg.norm(a)
b_norm = b / np.linalg.norm(b)
# 1. Cosine Similarity (1 - cosine distance)
cos_sim = 1 - cosine(a_norm, b_norm)
print(f"Cosine similarity: {cos_sim:.6f}") # ~0.999
# 2. Distanza Euclidea (L2)
l2_dist = euclidean(a_norm, b_norm)
print(f"Distanza L2: {l2_dist:.6f}") # ~0.042
# 3. Dot Product (per vettori normalizzati = cosine similarity)
dot = np.dot(a_norm, b_norm)
print(f"Dot product: {dot:.6f}") # ~0.999
# 4. Distanza Manhattan (L1)
l1_dist = cityblock(a_norm, b_norm)
print(f"Distanza L1: {l1_dist:.6f}") # ~0.072
# Relazione L2-Cosine per vettori normalizzati:
# d_L2^2 = 2 * (1 - cos_sim)
print(f"\nVerifica: L2^2 = {l2_dist**2:.6f}")
print(f"2*(1-cos) = {2*(1-cos_sim):.6f}") # uguale!
Hangi Metriğin Ne Zaman Kullanılacağı
| Metrik | pgvektör operatörü | Ne Zaman Kullan | Ne Zaman Kaçının |
|---|---|---|---|
| Küçük şeyler | <=> |
Büyüklük önemli olmadığında metin yerleştirmeleri | Büyüklüğün önemli olduğu mekansal veriler |
| L2 (Öklidyen) | <-> |
Büyüklük önemli olduğunda görüntüler, sayısal veriler | Bileşenler arasında farklı ölçeklere sahip vektörler |
| Nokta Ürün | <#> |
Vektörler zaten normalleştirildi (biraz daha iyi performans) | Normalleştirilmemiş vektörler (sonuçlar büyüklüğe göre bozulur) |
| Manhattan (L1) | Pgvector'da yerel olmayan | Seyrek veriler, aykırı değerlere karşı dayanıklılık | Yoğun gömmelerle genel kullanım |
Pratik Kural
Metin yerleştirmelerin olduğu durumların %95'i için şunu kullanın: kosinüs mesafesi
(<=> pgvektörde). Modern gömme modelleri vektörler üretir
zaten normalleştirilmiş, bu da kosinüs ve nokta çarpımlarını pratik olarak eşdeğer kılıyor. Mesafe
Öklid, mekansal veriler için veya vektör büyüklüğü bilgi taşıdığında anlamlıdır.
6. Python'da Gömmeler Oluşturun
Şimdi üç farklı yaklaşımla yerleştirmelerin nasıl oluşturulacağını görelim: yerel modeller Cümle Transformatörleri, OpenAI API'si ve HuggingFace Çıkarım API'si. Her yaklaşımın belirli avantajlar ve değiş tokuşlar.
6.1 Cümle Transformatörleri (Yerel)
En esnek ve özel yaklaşım: model makinenizde çalışır, veri yoktur ağ dışına çıktığında API çağrısı ücreti alınmaz.
# pip install sentence-transformers
from sentence_transformers import SentenceTransformer
import numpy as np
# Carica il modello (scaricato automaticamente al primo uso)
model = SentenceTransformer("all-MiniLM-L6-v2")
# Embedding di una singola frase
frase = "PostgreSQL e un database relazionale open-source"
embedding = model.encode(frase)
print(f"Tipo: {type(embedding)}") # numpy.ndarray
print(f"Dimensioni: {embedding.shape}") # (384,)
# Embedding di più frasi (batch - molto più efficiente)
frasi = [
"PostgreSQL e un database relazionale open-source",
"pgvector aggiunge il supporto per vettori a PostgreSQL",
"Il machine learning richiede grandi quantità di dati",
"La pizza margherita e un piatto tipico napoletano",
]
embeddings = model.encode(
frasi,
batch_size=32, # processa 32 frasi alla volta
show_progress_bar=True, # mostra progresso per batch grandi
normalize_embeddings=True # normalizza a norma L2 = 1
)
print(f"Shape: {embeddings.shape}") # (4, 384)
# Calcola similarità tra tutte le coppie
from sentence_transformers.util import cos_sim
similarities = cos_sim(embeddings, embeddings)
print(f"\nMatrice di similarità:\n{similarities}")
# Le prime 2 frasi (su PostgreSQL) avranno alta similarità
# La frase sulla pizza sarà distante dalle altre
6.2 OpenAI Yerleştirme API'si
OpenAI'nin API'si, altyapı yönetimi gerektirmeyen yüksek kaliteli modeller sunar. İdeal orta hacimli üretim için.
# pip install openai
from openai import OpenAI
import os
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def get_embeddings(
texts: list[str],
model: str = "text-embedding-3-small"
) -> list[list[float]]:
"""Genera embeddings per una lista di testi."""
response = client.embeddings.create(
input=texts,
model=model,
)
return [item.embedding for item in response.data]
# Singolo embedding
testo = "PostgreSQL come vector database per AI"
embedding = get_embeddings([testo])[0]
print(f"Dimensioni: {len(embedding)}") # 1536
# Batch di embeddings (fino a 2048 testi per chiamata)
testi = [
"Come installare pgvector su Docker",
"Tutorial per similarity search in PostgreSQL",
"Guida alla cottura della pasta al forno",
]
embeddings = get_embeddings(testi)
print(f"Embeddings generati: {len(embeddings)}") # 3
# Dimensione ridotta con text-embedding-3-small
# Puoi specificare dimensioni inferiori per risparmiare spazio
response = client.embeddings.create(
input=["Testo di esempio"],
model="text-embedding-3-small",
dimensions=512 # ridotto da 1536 a 512
)
emb_ridotto = response.data[0].embedding
print(f"Dimensioni ridotte: {len(emb_ridotto)}") # 512
6.3 HuggingFace Çıkarım API'si
Yerel modeller ile ticari API'ler arasında uzlaşma: binlerce modele erişim Cömert bir ücretsiz katmana sahip, API aracılığıyla açık kaynak.
# pip install huggingface_hub
from huggingface_hub import InferenceClient
import os
client = InferenceClient(
token=os.getenv("HF_TOKEN")
)
def get_hf_embeddings(
texts: list[str],
model: str = "BAAI/bge-large-en-v1.5"
) -> list[list[float]]:
"""Genera embeddings usando HuggingFace Inference API."""
result = client.feature_extraction(
text=texts,
model=model,
)
return result
# Genera embeddings
testi = [
"Vector search con PostgreSQL e pgvector",
"Come creare indici HNSW per ricerca veloce",
]
embeddings = get_hf_embeddings(testi)
print(f"Embeddings: {len(embeddings)}") # 2
print(f"Dimensioni: {len(embeddings[0])}") # 1024 (bge-large)
6.4 Verimli Toplu İşleme
Binlerce veya milyonlarca belge için yerleştirmeler oluşturmanız gerektiğinde verimlilik Toplu işlemenin önemi kritik hale geliyor.
import time
from typing import Generator
from sentence_transformers import SentenceTransformer
import numpy as np
def chunk_list(
lst: list, chunk_size: int
) -> Generator[list, None, None]:
"""Divide una lista in chunk di dimensione fissa."""
for i in range(0, len(lst), chunk_size):
yield lst[i:i + chunk_size]
def generate_embeddings_batch(
texts: list[str],
model_name: str = "all-MiniLM-L6-v2",
batch_size: int = 256,
device: str = "cpu" # "cuda" per GPU
) -> np.ndarray:
"""Genera embeddings in batch con progress tracking."""
model = SentenceTransformer(model_name, device=device)
all_embeddings = []
total_batches = (len(texts) + batch_size - 1) // batch_size
start = time.time()
for i, batch in enumerate(chunk_list(texts, batch_size)):
batch_emb = model.encode(
batch,
batch_size=batch_size,
normalize_embeddings=True,
show_progress_bar=False
)
all_embeddings.append(batch_emb)
elapsed = time.time() - start
rate = (i + 1) * batch_size / elapsed
print(
f"Batch {i+1}/{total_batches} - "
f"{rate:.0f} testi/sec"
)
return np.vstack(all_embeddings)
# Utilizzo
texts = [f"Documento numero {i}" for i in range(10_000)]
embeddings = generate_embeddings_batch(
texts,
batch_size=256,
device="cuda" # usa GPU se disponibile
)
print(f"Shape finale: {embeddings.shape}") # (10000, 384)
7. PostgreSQL'de Yerleştirmeleri Tarihselleştirin
Artık yerleştirmelerin nasıl oluşturulacağını bildiğimize göre, bunları PostgreSQL'de pgvector ile nasıl kaydedeceğimizi görelim. ve benzerlik arama sorguları gerçekleştirin. Bu, 1. makalenin pratik bağlantısıdır serinin.
7.1 Tablo düzeni
-- Abilita pgvector
CREATE EXTENSION IF NOT EXISTS vector;
-- Tabella documenti con embedding
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
title VARCHAR(500) NOT NULL,
content TEXT NOT NULL,
source VARCHAR(255),
category VARCHAR(100),
embedding vector(384), -- dimensione del modello scelto
created_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}'::jsonb
);
-- Indice HNSW per ricerca veloce (cosine distance)
CREATE INDEX idx_documents_embedding
ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);
-- Indice su categoria per filtri combinati
CREATE INDEX idx_documents_category
ON documents (category);
7.2 Python'dan ekleme
import psycopg2
from psycopg2.extras import execute_values
from sentence_transformers import SentenceTransformer
import numpy as np
# Configurazione
DB_CONFIG = {
"host": "localhost",
"port": 5432,
"dbname": "vectordb",
"user": "admin",
"password": "secret_password",
}
# 1. Genera embeddings
model = SentenceTransformer("all-MiniLM-L6-v2")
documenti = [
{
"title": "Introduzione a pgvector",
"content": "pgvector e un'estensione PostgreSQL per vettori...",
"source": "blog",
"category": "database"
},
{
"title": "RAG con LangChain",
"content": "Retrieval Augmented Generation combina retrieval...",
"source": "tutorial",
"category": "ai"
},
{
"title": "Python per Data Science",
"content": "Python e il linguaggio più usato per data science...",
"source": "guide",
"category": "programming"
},
]
# Genera embeddings per i contenuti
testi = [d["content"] for d in documenti]
embeddings = model.encode(testi, normalize_embeddings=True)
# 2. Salva in PostgreSQL
conn = psycopg2.connect(**DB_CONFIG)
cur = conn.cursor()
# Prepara i dati per batch insert
values = []
for doc, emb in zip(documenti, embeddings):
values.append((
doc["title"],
doc["content"],
doc["source"],
doc["category"],
emb.tolist() # converti numpy array in lista Python
))
# Inserimento batch efficiente
execute_values(
cur,
"""INSERT INTO documents
(title, content, source, category, embedding)
VALUES %s""",
values,
template="(%s, %s, %s, %s, %s::vector)"
)
conn.commit()
print(f"Inseriti {len(values)} documenti con embeddings")
cur.close()
conn.close()
7.3 Python'dan Benzerlik Araması
def similarity_search(
query: str,
top_k: int = 5,
category: str = None,
threshold: float = 0.3
) -> list[dict]:
"""Cerca documenti simili alla query."""
# Genera embedding della query
query_embedding = model.encode(
query, normalize_embeddings=True
).tolist()
conn = psycopg2.connect(**DB_CONFIG)
cur = conn.cursor()
# Query con filtro opzionale
if category:
cur.execute("""
SELECT id, title, content, category,
1 - (embedding <=> %s::vector) AS similarity
FROM documents
WHERE category = %s
AND 1 - (embedding <=> %s::vector) > %s
ORDER BY embedding <=> %s::vector
LIMIT %s
""", (
query_embedding, category,
query_embedding, threshold,
query_embedding, top_k
))
else:
cur.execute("""
SELECT id, title, content, category,
1 - (embedding <=> %s::vector) AS similarity
FROM documents
WHERE 1 - (embedding <=> %s::vector) > %s
ORDER BY embedding <=> %s::vector
LIMIT %s
""", (
query_embedding,
query_embedding, threshold,
query_embedding, top_k
))
results = []
for row in cur.fetchall():
results.append({
"id": row[0],
"title": row[1],
"content": row[2][:200], # troncato
"category": row[3],
"similarity": round(row[4], 4),
})
cur.close()
conn.close()
return results
# Esempio d'uso
risultati = similarity_search(
"come usare i vettori in un database",
top_k=3,
category="database"
)
for r in risultati:
print(f"[{r['similarity']}] {r['title']}")
7.4 İndeksleme: HNSW ve IVFFlat
Birkaç binden fazla belge içeren veri kümeleri için bir dizin gereklidir kabul edilebilir performans pgvector iki tür dizin sunar:
HNSW ve IVFFlat
| karakteristik | HNSW | IVFFlatin |
|---|---|---|
| Sorgu hızı | Çok hızlı | Hızlı |
| Hatırlamak | %95-99 | %85-95 |
| Oluşturma zamanı | Yavaş (dakika) | Hızlı (saniye) |
| Hafıza | Yüksek (RAM'deki grafik) | Düşük (merkezler) |
| Ekle/Güncelle | İyi (artımlı güncelleme) | Periyodik yeniden inşa gerektirir |
| Şunun için önerilir: | Üretim, yüksek kalite | Prototip oluşturma, statik veri kümeleri |
-- HNSW (raccomandato per produzione)
-- m: connessioni per nodo (16-64, default 16)
-- ef_construction: qualità costruzione (64-512, default 64)
CREATE INDEX idx_hnsw_cosine
ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);
-- Per L2 distance
CREATE INDEX idx_hnsw_l2
ON documents
USING hnsw (embedding vector_l2_ops)
WITH (m = 16, ef_construction = 200);
-- IVFFlat (più veloce da costruire)
-- lists: numero di cluster (sqrt(N) come regola base)
CREATE INDEX idx_ivfflat_cosine
ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100); -- per ~10K documenti
-- Parametri di query per controllare recall vs velocità
SET hnsw.ef_search = 100; -- default 40, alza per più recall
SET ivfflat.probes = 10; -- default 1, alza per più recall
8. Farklı Veri Türleri İçin Yerleştirmeler
Gömmeler metinle sınırlı değildir. Modern modeller temsiller üretebilir görüntüler, ses, kaynak kodu ve hatta çok modlu veriler için vektör grafikleri.
Multimodal Gömmeler: Veri Türü Modelleri
| Veri Türü | Modeli | Boyutlar | Kullanım Örneği |
|---|---|---|---|
| Metin | tümü-MiniLM-L6-v2, metin yerleştirme-3-küçük | 384-3072 | Anlamsal arama, RAG, sınıflandırma |
| Görseller | CLIP (OpenAI), SigLIP (Google) | 512-768 | Görsel arama, görsel sınıflandırma |
| Ses | Fısılda, alkış | 512-1280 | Sesli arama, müzik sınıflandırması |
| Kod | CodeBERT, StarCoder yerleştirmeleri | 768 | Kod arama, kopya tespiti |
| Çok modlu | KLİP, ImageBind (Meta) | 512-1024 | Çapraz modlu arama (görsele göre metin) |
# pip install transformers pillow
from transformers import CLIPProcessor, CLIPModel
from PIL import Image
import torch
import numpy as np
# Carica CLIP
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
# Embedding di un'immagine
image = Image.open("foto_gatto.jpg")
inputs = processor(images=image, return_tensors="pt")
with torch.no_grad():
image_embedding = model.get_image_features(**inputs)
image_emb = image_embedding[0].numpy()
print(f"Image embedding: {image_emb.shape}") # (512,)
# Embedding di testo (nello STESSO spazio!)
text_inputs = processor(
text=["un gatto che dorme", "un cane che gioca"],
return_tensors="pt",
padding=True
)
with torch.no_grad():
text_embeddings = model.get_text_features(**text_inputs)
text_embs = text_embeddings.numpy()
# Calcola similarità cross-modale
from numpy.linalg import norm
for i, text in enumerate(["un gatto che dorme", "un cane che gioca"]):
sim = np.dot(image_emb, text_embs[i]) / (
norm(image_emb) * norm(text_embs[i])
)
print(f"Similarità '{text}': {sim:.4f}")
# "un gatto che dorme" avra similarità più alta con foto_gatto.jpg
CLIP'in gücü metin ve görsellerin içinde yaşamasıdır aynı vektör uzayı. Metin sorgusu kullanarak görsel arayabilir veya bir görselle ilgili metni bulabilirsiniz. Bu PostgreSQL'de çok modlu arama gibi senaryoları açar: CLIP yerleştirmelerini buna kaydedin pgvector tablosu ve metin sorguları içeren daireler.
9. Gömmelerin kalitesini değerlendirin
Bir yerleştirme modelinin "iyi" olup olmadığını nasıl anlarsınız? Cevap göreve bağlıdır spesifik ancak standartlaştırılmış kriterler ve objektif ölçümler mevcuttur.
9.1 METEB: Büyük Metin Gömme Karşılaştırması
MTEB, yerleştirme modellerini değerlendirmek için referans ölçüttür. Performansı ölçün 8 kategoriye ayrılmış 58'den fazla görevde:
- Alma: sorgu verildiğinde ilgili belgeleri bulma
- Anlamsal Metin Benzerliği (STS): iki cümle ne kadar benzer
- Sınıflandırma: metinleri kategorilere ayırın
- Kümeleme: benzer metinleri gruplandır
- Çift Sınıflandırması: iki metnin ilişkili olup olmadığını belirlemek
- Yeniden sıralama: sonuçları alaka düzeyine göre yeniden sıralayın
- Özet: özetlerin kalitesi
- Bitext Madenciliği: paralel çevirileri bul
from sentence_transformers import SentenceTransformer
from sentence_transformers.evaluation import (
InformationRetrievalEvaluator
)
# Prepara dataset di valutazione
queries = {
"q1": "come installare pgvector",
"q2": "cos'è la similarity search",
"q3": "embedding di immagini con CLIP",
}
corpus = {
"d1": "Guida installazione pgvector su Ubuntu",
"d2": "pgvector per PostgreSQL: setup Docker",
"d3": "Ricerca per similarità vettoriale",
"d4": "CLIP: modello multimodale per immagini e testo",
"d5": "Ricetta pasta alla carbonara",
}
# Mappatura query -> documenti rilevanti
relevant = {
"q1": {"d1": 1, "d2": 1}, # d1 e d2 rilevanti per q1
"q2": {"d3": 1},
"q3": {"d4": 1},
}
# Valuta il modello
model = SentenceTransformer("all-MiniLM-L6-v2")
evaluator = InformationRetrievalEvaluator(
queries=queries,
corpus=corpus,
relevant_docs=relevant,
name="custom-eval"
)
results = evaluator(model)
print(f"NDCG@10: {results['custom-eval_ndcg@10']:.4f}")
print(f"MAP@10: {results['custom-eval_map@10']:.4f}")
9.2 İçsel ve Dışsal Değerlendirme
Değerlendirmede İki Yaklaşım
| Tip | Neyi ölçer | Örnek | Ne Zaman Kullanılmalı |
|---|---|---|---|
| içsel | Vektörlerin özellikleri | Analojiler, kümeleme, STS | Modeller arasında hızlı karşılaştırma |
| dışsal | Son görevdeki performans | RAG kalitesi, araştırma hassasiyeti | Üretimde son karar |
Pratik tavsiyeler
Sadece METEB puanına güvenmeyin. Bir model yüksek MTEB puanına sahip olabilir ancak kendi alan adınızda düşük performans sergileyin. Her zaman veri kümenizi değerlendirin: Alanınızdan küçük bir dizi alakalı sorgu ve belge oluşturun ve ölçüm yapın nDCG ve MAP. Bu size gerçek performansın çok daha güvenilir bir tahminini verecektir.
10. Boyutsallığın Azaltılması
Yüksek boyutlu vektörlerin görselleştirilmesi zordur ve pahalı olabilir Depolama ve hesaplama açısından. Boyut azaltma teknikleri hem görselleştirmeye hem de optimizasyona yardımcı olurlar.
10.1 Görselleştirme Teknikleri
Boyut Küçültme Teknikleri
| Teknik | Korumak | Hız | Tipik Kullanım |
|---|---|---|---|
| PCA | Küresel varyans | Çok hızlı | Depolama ve ön işleme için boyut küçültme |
| t-SNE | Yerel yapı | Yavaş | Kümelerin 2 boyutlu görselleştirilmesi |
| UMAP | Yerel + küresel yapı | Ortalama | 2D görselleştirme, ayrıca ön indeksleme azaltma için |
# pip install umap-learn matplotlib
import umap
import matplotlib.pyplot as plt
import numpy as np
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
# Testi con categorie diverse
testi = [
# Database
"PostgreSQL e un database relazionale",
"MongoDB e un database NoSQL",
"Redis e un database in-memory",
# AI/ML
"Il deep learning usa reti neurali profonde",
"GPT e un modello di linguaggio",
"La regressione lineare e un algoritmo semplice",
# Cucina
"La pizza si cuoce nel forno a legna",
"Il tiramisu e un dolce italiano",
"La pasta alla carbonara usa uova e guanciale",
]
categorie = ["DB"]*3 + ["AI"]*3 + ["Cucina"]*3
colori = ["blue"]*3 + ["red"]*3 + ["green"]*3
# Genera embeddings (384 dimensioni)
embeddings = model.encode(testi, normalize_embeddings=True)
# Riduci a 2D con UMAP
reducer = umap.UMAP(n_components=2, random_state=42)
emb_2d = reducer.fit_transform(embeddings)
# Visualizza
plt.figure(figsize=(10, 8))
for i, (x, y) in enumerate(emb_2d):
plt.scatter(x, y, c=colori[i], s=100, zorder=5)
plt.annotate(testi[i][:30], (x, y),
fontsize=8, ha='left')
plt.title("Embeddings in 2D (UMAP)")
plt.savefig("embeddings_umap.png", dpi=150)
plt.show()
10.2 Matruşka Gömmeleri
Yeni ve yenilikçi bir teknik: i Matryoshka Temsil Öğrenimi (MRL) yerleştirmeler, vektörün ilk N bileşeni zaten bir yerleştirme olacak şekilde eğitilir geçerlidir. İyi kaliteyi korurken vektörü 1536 boyutundan 512 veya 256 boyutuna kesebilirsiniz.
OpenAI text-embedding-3-small e text-embedding-3-large destek
bu teknik: parametreyi belirtebilirsiniz dimensions vektörleri elde etmek
yerleştirmeleri yeniden hesaplamadan daha kompakt.
from openai import OpenAI
import numpy as np
import os
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
testo = "PostgreSQL come vector database per applicazioni AI"
# Genera lo stesso embedding a dimensioni diverse
for dim in [256, 512, 1024, 1536]:
response = client.embeddings.create(
input=[testo],
model="text-embedding-3-small",
dimensions=dim
)
emb = response.data[0].embedding
print(f"Dimensioni: {dim}, norma: {np.linalg.norm(emb):.4f}")
# In PostgreSQL: usa colonne con dimensione appropriata
# CREATE TABLE docs_compact (
# id BIGSERIAL PRIMARY KEY,
# content TEXT,
# embedding vector(256) -- più compatto, 6x meno storage
# );
11. Maliyetleri ve Stratejileri Ölçeklendirmek
Prototipten üretime geçerken üretim ve depolama maliyetleri yerleştirmeler kritik bir faktör haline gelir. Detaylı bir analiz görelim.
11.1 1 Milyon Doküman Başına Maliyet
Maliyet Tahmini: 1 Milyon Belge (ortalama 500 jeton/belge)
| Modeli | Üretim Maliyeti | Vektör boyutu | Depolama (float32) | Başlangıç Toplamı |
|---|---|---|---|---|
| hepsi-MiniLM-L6-v2 | 0$ (yerel) | 384 | ~1,4 GB | Yalnızca GPU/CPU süresi |
| metin yerleştirme-3-küçük | ~10$ | 1536 | ~5,7GB | ~10$ + depolama alanı |
| metin gömme-3-büyük | ~65$ | 3072 | ~11,4 GB | ~65$ + depolama alanı |
| yolculuk-3 | ~30$ | 1024 | ~3,8GB | ~30$ + depolama alanı |
Depolama formülü: N belge * boyut * 4 bayt (float32). Örnek: 1M * 1536 * 4 = 5,7 GB yalnızca operatörler için.
11.2 Kendi Kendine Barındırılan ve API: Takas
Kendi Kendine Barındırılan ve API karşılaştırması
| bekliyorum | Kendi Kendine Barındırılan | API (OpenAI, Tutarlı) |
|---|---|---|
| Başlangıç maliyeti | Yüksek (GPU ~1-3$/saat) | Düşük (kullanım başına ödeme) |
| Hacim başına maliyet | ~10 milyonun üzerinde en ucuz belge | Doğrusal, hacimle ölçeklenir |
| Gecikme | Düşük (ağ yok) | Çağrı başına 50-200ms |
| Mahremiyet | Veriler şirket içinde kalır | Üçüncü taraflara gönderilen veriler |
| Bakım | GPU yönetimi, güncellemeler, izleme | Sıfır |
| kalite | Seçilen modele bağlıdır | Genellikle yüksek ve tutarlı |
11.3 Önbelleğe Alma Stratejileri
Maliyetleri ve gecikmeyi azaltmak için önbelleğe almanın yerleştirilmesi önemlidir. Eğer aynıysa metin birkaç kez isteniyorsa, yerleştirmeyi yeniden oluşturmanın bir anlamı yok.
import hashlib
import json
import psycopg2
from typing import Optional
import numpy as np
class EmbeddingCache:
"""Cache embeddings in PostgreSQL per evitare ricalcoli."""
def __init__(self, db_config: dict):
self.db_config = db_config
self._init_table()
def _init_table(self):
conn = psycopg2.connect(**self.db_config)
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS embedding_cache (
content_hash VARCHAR(64) PRIMARY KEY,
model_name VARCHAR(100) NOT NULL,
embedding vector(1536),
created_at TIMESTAMPTZ DEFAULT NOW()
)
""")
conn.commit()
cur.close()
conn.close()
def _hash(self, text: str, model: str) -> str:
"""Hash deterministico del contenuto + modello."""
key = f"{model}::{text}"
return hashlib.sha256(key.encode()).hexdigest()
def get(
self, text: str, model: str
) -> Optional[list[float]]:
"""Cerca embedding in cache."""
h = self._hash(text, model)
conn = psycopg2.connect(**self.db_config)
cur = conn.cursor()
cur.execute(
"SELECT embedding FROM embedding_cache "
"WHERE content_hash = %s",
(h,)
)
row = cur.fetchone()
cur.close()
conn.close()
return row[0] if row else None
def put(
self, text: str, model: str, embedding: list[float]
):
"""Salva embedding in cache."""
h = self._hash(text, model)
conn = psycopg2.connect(**self.db_config)
cur = conn.cursor()
cur.execute(
"INSERT INTO embedding_cache "
"(content_hash, model_name, embedding) "
"VALUES (%s, %s, %s::vector) "
"ON CONFLICT (content_hash) DO NOTHING",
(h, model, embedding)
)
conn.commit()
cur.close()
conn.close()
12. PostgreSQL AI Serisiyle Bağlantı
Yerleştirmelerin inşa ettiğimiz ekosisteme nasıl entegre olduğunu özetleyelim bu seride:
Akışın Tamamı: 1. Maddeden 3. Maddeye
| Adım | Öğe | Aksiyon |
|---|---|---|
| 1 | pgvektör (Mad. 1) | PostgreSQL'i pgvector ile yapılandırın, vektör sütunlu tablolar oluşturun |
| 2 | Gömmeler (Mad. 2 - bu) | Şablonu seçin, yerleştirmeler oluşturun, bunları pgvector'a kaydedin |
| 3 | PostgreSQL ile RAG (Mad. 3) | Soruları yanıtlamak için pgvector yoluyla almayı LLM ile birleştirin |
1.maddede altyapıyı hazırladık: pgvector yüklü PostgreSQL, tablolar vektör sütunları ve HNSW dizinleri yapılandırılmış olarak. Bu yazımızda boşluğu doldurduk temel: bu vektörlerin nereden geldiği, doğru modelin nasıl seçileceği ve bunların nasıl oluşturulacağı verimli bir şekilde. Bir sonraki makalede her şeyi kullanan eksiksiz bir RAG işlem hattı oluşturacağız bu yığın: pgvector'da indekslenen belgeler, sorgular için anında oluşturulan yerleştirmeler, ve alınan bağlama göre yanıtlar üreten bir LLM.
13. Sonuçlar ve Kontrol Listesi
Gömmeler, doğal dili birbirine bağlayan temel bileşendir. vektör veritabanlarının matematiği. Doğru modeli seçmek, mesafe ölçüsü uygun ve etkili bir ölçeklendirme stratejisi, doğrudan etkisi olan kararlardır. AI sisteminizin kalitesi ve maliyetleri.
Kontrol Listesi: Doğru Gömme Modelini Seçme
- Görevi tanımlayın: alma, sınıflandırma, kümeleme, STS?
- Dili tanımlayın: Yalnızca İngilizce mi, çok dilli mi, yoksa alana özel mi?
- Kısıtlamaları değerlendirin: bütçe, gizlilik, gecikme, kullanılabilir altyapı
- 2-3 aday seçin model tablosundan (bölüm 4.3)
- Değerlendirme seti oluşturun alanınızdan (ilgili belgelerle birlikte 50-100 sorgu)
- nDCG ve MAP'yi ölçer her aday için veri kümenizde
- Maliyetleri hesaplayın beklenen hacim için tamamen çalışır durumda (bölüm 11)
- Küçük boyutu test edin: 512 loşluk çoğu kullanım durumu için genellikle yeterlidir
- Önbelleğe alma uygulayın yeniden üretim maliyetlerini azaltmak için
- Kaliteyi izleyin değerlendirme setiniz ile zaman içinde
Sonraki Makale: PostgreSQL ile RAG
Serinin bir sonraki makalesinde bir tane inşa edeceğiz RAG boru hattı tamamlandı (Geri Alma Artırılmış Nesil) PostgreSQL + pgvector'u bilgi tabanı olarak kullanıyor. Benzerlik aramasını akıllı parçalamayla nasıl birleştireceğimizi, nasıl entegre edeceğimizi göreceğiz GPT-4 ve Claude gibi Yüksek Lisanslar ve oluşturulan yanıtların kalitesinin nasıl ölçüleceği.







