Erişim artırılmış nesil (RAG), artık üretken yapay zeka (AI) uygulamalarının standart bir parçasıdır . Uygulama isteminizi bir vektör veri tabanından alınan ilgili bağlamla desteklemek, doğruluğu önemli ölçüde artırabilir ve halüsinasyonları azaltabilir. Bu, vektör arama sonuçlarındaki alaka düzeyinin artmasının, RAG uygulamanızın kalitesiyle doğrudan ilişkili olduğu anlamına gelir.
Büyük dil modelleri (LLM'ler) bağlam pencerelerini genişletse bile RAG'ın popüler ve giderek daha alakalı kalmasının iki nedeni vardır:
LLM yanıt süresi ve fiyatı, bağlam uzunluğuyla birlikte doğrusal olarak artar.
Yüksek Lisans'lar hala devasa bağlamlarda hem erişim hem de akıl yürütme konusunda zorluk yaşıyor.
Ancak RAG sihirli bir değnek değil. Özellikle, en yaygın tasarım olan yoğun geçiş erişimi (DPR), hem sorguları hem de geçişleri tek bir yerleştirme vektörü olarak temsil eder ve alaka düzeyini puanlamak için basit kosinüs benzerliğini kullanır. Bu, DPR'nin ilgili tüm arama terimlerini tanımak için geniş kapsamlı eğitime sahip yerleştirme modeline büyük ölçüde güvendiği anlamına gelir.
Ne yazık ki, kullanıma hazır modeller, eğitim verilerinde yaygın olarak bulunmayan adlar da dahil olmak üzere olağandışı terimlerle mücadele ediyor. DPR ayrıca parçalama stratejisine karşı aşırı duyarlı olma eğilimindedir; bu da, çok sayıda alakasız bilgiyle çevrelenmişse ilgili bir pasajın kaçırılmasına neden olabilir. Tüm bunlar uygulama geliştiricisi üzerinde "ilk seferde doğru yapma" yükü yaratır çünkü bir hata genellikle dizini sıfırdan yeniden oluşturma ihtiyacıyla sonuçlanır.
ColBERT, DPR ile ilgili sorunları büyük ölçüde çözen bir BERT dil modeli kullanarak pasaj alaka düzeyini puanlamanın yeni bir yoludur. İlk ColBERT makalesindeki bu şema bunun neden bu kadar heyecan verici olduğunu gösteriyor:
Bu, ColBERT'in performansını MS-MARCO veri kümesine yönelik diğer son teknoloji çözümlerle karşılaştırır. (MS-MARCO, Microsoft'un en alakalı pasajları elle puanladığı bir Bing sorguları kümesidir. Daha iyi erişim ölçütlerinden biridir.) Aşağı ve sağ daha iyidir.
Kısacası ColBERT, gecikmede küçük bir artış pahasına çoğunlukla çok daha karmaşık çözümler alanından kolayca daha iyi performans gösteriyor.
Bunu test etmek için bir demo oluşturdum ve 1000'den fazla Vikipedi makalesini hem ada002 DPR hem de ColBERT ile indeksledim. ColBERT'in alışılmadık arama terimlerinde çok daha iyi sonuçlar verdiğini buldum.
Aşağıdaki ekran görüntüsü, DPR'nin Abraham Lincoln'ün bir ortağı olan William H. Herndon'un alışılmadık adını tanıyamadığını, ColBERT'in ise Springfield makalesinde referans bulduğunu gösteriyor. Ayrıca ColBERT'in 2 numaralı sonucunun farklı bir William'a ait olduğunu ancak DPR sonuçlarının hiçbirinin alakalı olmadığını unutmayın.
ColBERT genellikle yoğun makine öğrenimi jargonuyla tanımlanır, ancak aslında çok basittir. ColBERT alımının ve puanlamasının DataStax Astra DB'de yalnızca birkaç satır Python ve Cassandra Sorgu Dili (CQL) ile nasıl uygulanacağını göstereceğim.
Pasajları tek bir "yerleştirme" vektörüne dönüştüren geleneksel, tek vektör tabanlı DPR yerine ColBERT, pasajlardaki her simge için bağlamsal olarak etkilenen bir vektör oluşturur. ColBERT benzer şekilde sorgudaki her jeton için vektörler üretir.
(Tokenleştirme, bir Yüksek Lisans tarafından işlenmeden önce girdinin kelimelerin kesirlerine bölünmesi anlamına gelir. OpenAI ekibinin kurucu üyesi Andrej Karpathy, bunun nasıl çalıştığına dair kısa süre önce olağanüstü bir video yayınladı .)
Daha sonra, her belgenin puanı, her sorgunun belge yerleştirmelerinden herhangi birine maksimum benzerliğinin toplamıdır:
def maxsim(qv, document_embeddings): return max(qv @ dv for dv in document_embeddings) def score(query_embeddings, document_embeddings): return sum(maxsim(qv, document_embeddings) for qv in query_embeddings)
(@ nokta çarpımı için PyTorch operatörüdür ve vektör benzerliğinin en yaygın ölçüsüdür .)
İşte bu; ColBERT puanlamasını Python'un dört satırında uygulayabilirsiniz! Artık ColBERT'i X'te (eski adıyla Twitter olarak biliniyordu) bu konuda paylaşım yapan insanların %99'undan daha iyi anlıyorsunuz.
ColBERT belgelerinin geri kalanı aşağıdakilerle ilgilidir:
İlk soru isteğe bağlıdır ve bu yazının kapsamı dışındadır. Önceden eğitilmiş ColBERT kontrol noktasını kullanacağım. Ancak ikincisini DataStax Astra DB gibi bir vektör veritabanıyla yapmak kolaydır.
ColBERT için RAGatouille adında popüler bir Python hepsi bir arada kitaplığı vardır; ancak statik bir veri kümesi varsayar. RAG uygulamalarının güçlü özelliklerinden biri, dinamik olarak değişen verilere gerçek zamanlı olarak yanıt vermesidir. Bunun yerine, her alt vektör için en iyi adaylara göre puanlamam gereken belge kümesini daraltmak amacıyla Astra'nın vektör indeksini kullanacağım.
ColBERT'i bir RAG uygulamasına eklerken iki adım vardır: alma ve alma.
Her belge öbeğinin kendisiyle ilişkili birden fazla yerleştirmesi olacağından iki tabloya ihtiyacım olacak:
CREATE TABLE chunks ( title text, part int, body text, PRIMARY KEY (title, part) ); CREATE TABLE colbert_embeddings ( title text, part int, embedding_id int, bert_embedding vector<float, 128>, PRIMARY KEY (title, part, embedding_id) ); CREATE INDEX colbert_ann ON colbert_embeddings(bert_embedding) WITH OPTIONS = { 'similarity_function': 'DOT_PRODUCT' };
ColBERT kitaplığını ( pip install colbert-ai
) kurduktan ve önceden eğitilmiş BERT kontrol noktasını indirdikten sonra belgeleri şu tablolara yükleyebilirim:
from colbert.infra.config import ColBERTConfig from colbert.modeling.checkpoint import Checkpoint from colbert.indexing.collection_encoder import CollectionEncoder from cassandra.concurrent import execute_concurrent_with_args from db import DB def encode_and_save(title, passages): db = DB() cf = ColBERTConfig(checkpoint='checkpoints/colbertv2.0') cp = Checkpoint(cf.checkpoint, colbert_config=cf) encoder = CollectionEncoder(cf, cp) # encode_passages returns a flat list of embeddings and a list of how many correspond to each passage embeddings_flat, counts = encoder.encode_passages(passages) # split up embeddings_flat into a nested list start_indices = [0] + list(itertools.accumulate(counts[:-1])) embeddings_by_part = [embeddings_flat[start:start+count] for start, count in zip(start_indices, counts)] # insert into the database for part, embeddings in enumerate(embeddings_by_part): execute_concurrent_with_args(db.session, db.insert_colbert_stmt, [(title, part, i, e) for i, e in enumerate(embeddings)])
(Veritabanı mantığımı özel bir modülde kapsüllemeyi seviyorum; kaynağın tamamına GitHub depomdan erişebilirsiniz.)
Daha sonra alma şöyle görünür:
def retrieve_colbert(query): db = DB() cf = ColBERTConfig(checkpoint='checkpoints/colbertv2.0') cp = Checkpoint(cf.checkpoint, colbert_config=cf) encode = lambda q: cp.queryFromText([q])[0] query_encodings = encode(query) # find the most relevant documents for each query embedding. using a set # handles duplicates so we don't retrieve the same one more than once docparts = set() for qv in query_encodings: rows = db.session.execute(db.query_colbert_ann_stmt, [list(qv)]) docparts.update((row.title, row.part) for row in rows) # retrieve these relevant documents and score each one scores = {} for title, part in docparts: rows = db.session.execute(db.query_colbert_parts_stmt, [title, part]) embeddings_for_part = [tensor(row.bert_embedding) for row in rows] scores[(title, part)] = score(query_encodings, embeddings_for_part) # return the source chunk for the top 5 return sorted(scores, key=scores.get, reverse=True)[:5]
En alakalı belgeler kısmı ( db.query_colbert_ann_stmt
) için yürütülen sorgu aşağıdadır:
SELECT title, part FROM colbert_embeddings ORDER BY bert_embedding ANN OF ? LIMIT 5
Bu makale ve bağlantılı veri deposu ColBERT'in nasıl çalıştığını kısaca tanıtmaktadır. Bunu bugün kendi verilerinizle uygulayabilir ve sonuçları anında görebilirsiniz. Yapay zekadaki her şeyde olduğu gibi en iyi uygulamalar da her gün değişiyor ve sürekli yeni teknikler ortaya çıkıyor.
DataStax, en son teknolojiye ayak uydurmayı kolaylaştırmak için bu ve diğer geliştirmeleri LangChain ve LlamaIndex'ten yararlanan üretime hazır RAG kitaplığımız RAGStack'a aktarıyor. Amacımız, geliştiricilere RAG uygulamaları için yeni işlevlere geçişte kontrolün sizde olmasını sağlayan tutarlı bir kitaplık sağlamaktır. Tekniklerdeki ve kitaplıklardaki sayısız değişikliğe ayak uydurmak zorunda kalmak yerine tek bir akışınız var, böylece uygulamanızı oluşturmaya odaklanabilirsiniz. LangChain ve LlamaIndex için en iyi uygulamaları kutudan çıktığı gibi dahil etmek için RAGStack'ı bugün kullanabilirsiniz; ColBERT gibi gelişmeler gelecek sürümlerde RAGstack'a gelecek.
Jonathan Ellis, DataStax tarafından
Ayrıca burada görünür.