Pokud jde o zpracování přirozeného jazyka (NLP) a vyhledávání informací, schopnost efektivně a přesně získávat relevantní informace je prvořadá. Jak se tato oblast neustále vyvíjí, vyvíjejí se nové techniky a metodiky pro zvýšení výkonnosti vyhledávacích systémů, zejména v kontextu Retrieval Augmented Generation (HADR). Jedna taková technika, známá jako dvoufázové vyhledávání s rerankery, se ukázala jako výkonné řešení pro řešení inherentních omezení tradičních metod vyhledávání.
V tomto článku diskutujeme o složitosti dvoufázového vyhledávání a přehodnocení, zkoumáme jejich základní principy, implementační strategie a výhody, které nabízejí při zvyšování přesnosti a účinnosti systémů RAG. Poskytneme také praktické příklady a úryvky kódu, které ilustrují koncepty a usnadní hlubší pochopení této špičkové techniky.
Pochopení rozšířené generace získávání (RAG)
Než se ponoříme do specifik dvoufázového vyhledávání a rerankerů, vraťme se krátce ke konceptu Retrieval Augmented Generation (RAG). RAG je technika, která rozšiřuje znalosti a schopnosti velkých jazykových modelů (LLM) tím, že jim poskytuje přístup k externím informačním zdrojům, jako jsou databáze nebo kolekce dokumentů. Více viz článek „Hluboký ponor do rozšířené generace vyhledávání v LLM".
Typický proces RAG zahrnuje následující kroky:
- Dotaz: Uživatel položí otázku nebo poskytne systému pokyn.
- Načítání: Systém se dotazuje na vektorovou databázi nebo kolekci dokumentů, aby našel informace relevantní pro dotaz uživatele.
- Zvětšení: Získané informace jsou zkombinovány s původním dotazem nebo pokynem uživatele.
- Generace: Jazykový model zpracovává rozšířený vstup a generuje odezvu, přičemž využívá externí informace ke zvýšení přesnosti a komplexnosti svého výstupu.
I když se RAG ukázal jako výkonná technika, není bez problémů. Jeden z klíčových problémů spočívá ve fázi vyhledávání, kde tradiční metody vyhledávání nemusí selhat při identifikaci nejdůležitějších dokumentů, což vede k neoptimálním nebo nepřesným odpovědím jazykového modelu.
Potřeba dvoufázového vyhledávání a přehodnocení
Tradiční metody vyhledávání, jako jsou metody založené na shodě klíčových slov nebo vektorových prostorových modelech, se často potýkají s potížemi zachytit jemné sémantické vztahy mezi dotazy a dokumenty. Toto omezení může mít za následek načítání dokumentů, které jsou relevantní pouze povrchně, nebo postrádají zásadní informace, které by mohly výrazně zlepšit kvalitu generované odpovědi.
Aby se výzkumníci a praktici vypořádali s touto výzvou, obrátili se na dvoufázové vyhledávání s rerankery. Tento přístup zahrnuje dvoufázový proces:
- Počáteční načtení: V první fázi je získána relativně velká sada potenciálně relevantních dokumentů pomocí rychlé a efektivní metody vyhledávání, jako je vektorový prostorový model nebo vyhledávání na základě klíčových slov.
- Změna pořadí: Ve druhé fázi se používá propracovanější model změny pořadí k přeuspořádání původně načtených dokumentů na základě jejich relevance k dotazu, čímž se nejrelevantnější dokumenty efektivně přesunou na začátek seznamu.
Model změny pořadí, často neuronová síť nebo architektura založená na transformátoru, je speciálně trénován k posouzení relevance dokumentu pro daný dotaz. Využitím pokročilých schopností porozumění přirozenému jazyku může reranker zachytit sémantické nuance a kontextové vztahy mezi dotazem a dokumenty, což vede k přesnějšímu a relevantnějšímu hodnocení.
Výhody dvoufázového vyhledávání a přehodnocení
Přijetí dvoufázového vyhledávání pomocí rerankerů nabízí několik významných výhod v kontextu systémů RAG:
- Zlepšená přesnost: Přehodnocením původně načtených dokumentů a povýšením těch nejrelevantnějších na začátek může systém poskytnout přesnější a přesnější informace jazykovému modelu, což povede ke kvalitnějším generovaným odpovědím.
- Zmírněné problémy mimo doménu: Vkládací modely používané pro tradiční vyhledávání jsou často trénovány na obecných textových korpusech, které nemusí adekvátně zachytit doménový jazyk a sémantiku. Na druhou stranu modely změny pořadí lze trénovat na datech specifických pro doménu, čímž se zmírní problém „mimo doménu“ a zlepší se relevance vyhledávaných dokumentů ve specializovaných doménách.
- Škálovatelnost: Dvoustupňový přístup umožňuje efektivní škálování využitím rychlých a lehkých metod vyhledávání v počáteční fázi, přičemž výpočetně náročnější proces změny pořadí vyhradí pro menší podmnožinu dokumentů.
- Flexibilita: Modely změny pořadí lze vyměnit nebo aktualizovat nezávisle na počáteční metodě vyhledávání, což poskytuje flexibilitu a přizpůsobivost vyvíjejícím se potřebám systému.
ColBERT: Efektivní a efektivní pozdní interakce
Jedním ze špičkových modelů v oblasti rerankingu je ColBERT (Kontextualizovaná pozdní interakce přes BERT). ColBERT je model rerankeru dokumentů, který využívá schopnosti BERT hlubokého porozumění jazyku a zároveň zavádí nový mechanismus interakce známý jako „pozdní interakce“.
ColBERT: Efektivní a efektivní vyhledávání pasáží prostřednictvím kontextové pozdní interakce přes BERT
Mechanismus pozdní interakce v ColBERT umožňuje efektivní a přesné vyhledávání tím, že zpracovává dotazy a dokumenty odděleně až do závěrečných fází procesu vyhledávání. Konkrétně ColBERT nezávisle kóduje dotaz a dokument pomocí BERT a poté využívá lehký, ale výkonný krok interakce, který modeluje jejich jemnou podobnost. Zpožděním, ale zachováním této jemnozrnné interakce, může ColBERT využít expresivitu hlubokých jazykových modelů a současně získat schopnost předpočítat reprezentace dokumentů offline, což výrazně urychlí zpracování dotazů.
Architektura pozdní interakce ColBERT nabízí několik výhod, včetně vylepšené výpočetní efektivity, škálovatelnosti s velikostí kolekce dokumentů a praktické použitelnosti pro scénáře reálného světa. Navíc byl ColBERT dále vylepšen o techniky, jako je odšumovaný dohled a zbytková komprese (v ColBERTv2), které zpřesňují tréninkový proces a snižují prostorovou stopu modelu při zachování vysoké efektivity vyhledávání.
Tento úryvek kódu ukazuje, jak konfigurovat a používat model jina-colbert-v1-en pro indexování kolekce dokumentů s využitím jeho schopnosti efektivně zpracovávat dlouhé kontexty.
Implementace dvoufázového vyhledávání pomocí Rerankers
Nyní, když jsme pochopili principy dvoufázového vyhledávání a přehodnocení, pojďme prozkoumat jejich praktickou implementaci v kontextu systému RAG. K demonstraci integrace těchto technik využijeme oblíbené knihovny a rámce.
Nastavení prostředí
Než se ponoříme do kódu, nastavíme naše vývojové prostředí. Budeme používat Python a několik oblíbených knihoven NLP, včetně Hugging Face Transformers, Sentence Transformers a LanceDB.
# Install required libraries
!pip install datasets huggingface_hub sentence_transformers lancedb
Příprava dat
Pro demonstrační účely použijeme datovou sadu „ai-arxiv-chunked“ z Hugging Face Datasets, která obsahuje více než 400 článků ArXiv o strojovém učení, zpracování přirozeného jazyka a velkých jazykových modelech.
from datasets import load_dataset
dataset = load_dataset("jamescalam/ai-arxiv-chunked", split="train")
<pre>
Dále data předzpracujeme a rozdělíme na menší části, abychom usnadnili efektivní vyhledávání a zpracování.
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
def chunk_text(text, chunk_size=512, overlap=64):
tokens = tokenizer.encode(text, return_tensors="pt", truncation=True)
chunks = tokens.split(chunk_size - overlap)
texts = [tokenizer.decode(chunk) for chunk in chunks]
return texts
chunked_data = []
for doc in dataset:
text = doc["chunk"]
chunked_texts = chunk_text(text)
chunked_data.extend(chunked_texts)
Pro počáteční fázi vyhledávání použijeme model Sentence Transformer ke kódování našich dokumentů a dotazů do hustých vektorových reprezentací a poté provedeme přibližné vyhledávání nejbližšího souseda pomocí vektorové databáze, jako je LanceDB.
from sentence_transformers import SentenceTransformer
from lancedb import lancedb
# Load Sentence Transformer model
model = SentenceTransformer('all-MiniLM-L6-v2')
# Create LanceDB vector store
db = lancedb.lancedb('/path/to/store')
db.create_collection('docs', vector_dimension=model.get_sentence_embedding_dimension())
# Index documents
for text in chunked_data:
vector = model.encode(text).tolist()
db.insert_document('docs', vector, text)
from sentence_transformers import SentenceTransformer
from lancedb import lancedb
# Load Sentence Transformer model
model = SentenceTransformer('all-MiniLM-L6-v2')
# Create LanceDB vector store
db = lancedb.lancedb('/path/to/store')
db.create_collection('docs', vector_dimension=model.get_sentence_embedding_dimension())
# Index documents
for text in chunked_data:
vector = model.encode(text).tolist()
db.insert_document('docs', vector, text)
S našimi indexovanými dokumenty můžeme provést počáteční vyhledávání nalezením nejbližších sousedů k danému vektoru dotazu.
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
def chunk_text(text, chunk_size=512, overlap=64):
tokens = tokenizer.encode(text, return_tensors="pt", truncation=True)
chunks = tokens.split(chunk_size - overlap)
texts = [tokenizer.decode(chunk) for chunk in chunks]
return texts
chunked_data = []
for doc in dataset:
text = doc["chunk"]
chunked_texts = chunk_text(text)
chunked_data.extend(chunked_texts)
Změna pořadí
Po počátečním načtení použijeme model změny pořadí, abychom znovu seřadili načtené dokumenty na základě jejich relevance k dotazu. V tomto příkladu použijeme ColBERT reranker, rychlý a přesný model založený na transformátoru speciálně navržený pro hodnocení dokumentů.
from lancedb.rerankers import ColbertReranker
reranker = ColbertReranker()
# Rerank initial documents
reranked_docs = reranker.rerank(query, initial_docs)
Projekt reranked_docs
seznam nyní obsahuje dokumenty přeřazené na základě jejich relevance k dotazu, jak je určeno přehodnocením ColBERT.
Augmentace a generace
S přehodnocenými a relevantními dokumenty v ruce můžeme přistoupit k fázi rozšíření a generování potrubí RAG. Ke generování konečné odpovědi použijeme jazykový model z knihovny Hugging Face Transformers.
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
tokenizer = AutoTokenizer.from_pretrained("t5-base")
model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
# Augment query with reranked documents
augmented_query = query + " " + " ".join(reranked_docs[:3])
# Generate response from language model
input_ids = tokenizer.encode(augmented_query, return_tensors="pt")
output_ids = model.generate(input_ids, max_length=500)
response = tokenizer.decode(output_ids[0], skip_special_tokens=True)
print(response)