Lorsqu’il s’agit de traitement du langage naturel (NLP) et de récupération d’informations, la capacité de récupérer efficacement et précisément les informations pertinentes est primordiale. À mesure que le domaine continue d'évoluer, de nouvelles techniques et méthodologies sont développées pour améliorer les performances des systèmes de récupération, en particulier dans le contexte de Récupération Génération Augmentée (CHIFFON). L’une de ces techniques, connue sous le nom de récupération en deux étapes avec rerankers, s’est révélée être une solution puissante pour remédier aux limites inhérentes aux méthodes de récupération traditionnelles.
Dans cet article, nous discutons des subtilités de la récupération et des reclassements en deux étapes, en explorant leurs principes sous-jacents, leurs stratégies de mise en œuvre et les avantages qu'ils offrent pour améliorer la précision et l'efficacité des systèmes RAG. Nous fournirons également des exemples pratiques et des extraits de code pour illustrer les concepts et faciliter une compréhension plus approfondie de cette technique de pointe.
Comprendre la génération augmentée par récupération (RAG)
Avant de plonger dans les spécificités de la récupération en deux étapes et des rerankers, revenons brièvement sur le concept de Retrieval Augmented Generation (RAG). RAG est une technique qui étend les connaissances et les capacités des grands modèles de langage (LLM) en leur fournissant un accès à des sources d'informations externes, telles que des bases de données ou des collections de documents. Reportez-vous davantage à l'article «Une plongée approfondie dans la génération augmentée de récupération en LLM " .
Le processus RAG typique implique les étapes suivantes :
Question : Un utilisateur pose une question ou fournit une instruction au système.
Récupération : Le système interroge une base de données vectorielles ou une collection de documents pour trouver des informations pertinentes pour la requête de l'utilisateur.
Augmentation : Les informations récupérées sont combinées avec la requête ou l'instruction originale de l'utilisateur.
Generation : Le modèle de langage traite l'entrée augmentée et génère une réponse, en exploitant les informations externes pour améliorer la précision et l'exhaustivité de sa sortie.
Bien que RAG se soit révélé être une technique puissante, elle n’est pas sans défis. L'un des problèmes clés réside dans l'étape de récupération, où les méthodes de récupération traditionnelles peuvent ne pas parvenir à identifier les documents les plus pertinents, conduisant à des réponses sous-optimales ou inexactes de la part du modèle linguistique.
La nécessité d'une récupération en deux étapes et de reclassements
Les méthodes de récupération traditionnelles, telles que celles basées sur la correspondance de mots-clés ou les modèles spatiaux vectoriels, ont souvent du mal à capturer les relations sémantiques nuancées entre les requêtes et les documents. Cette limitation peut entraîner la récupération de documents qui ne sont que superficiellement pertinents ou omettre des informations cruciales qui pourraient améliorer considérablement la qualité de la réponse générée.
Pour relever ce défi, les chercheurs et les praticiens se sont tournés vers la récupération en deux étapes avec des rerankers. Cette approche implique un processus en deux étapes :
Récupération initiale : Dans un premier temps, un ensemble relativement important de documents potentiellement pertinents est récupéré à l'aide d'une méthode de récupération rapide et efficace, telle qu'un modèle spatial vectoriel ou une recherche par mot-clé.
Reclassement : Dans la deuxième étape, un modèle de reclassement plus sophistiqué est utilisé pour réorganiser les documents initialement récupérés en fonction de leur pertinence par rapport à la requête, plaçant ainsi les documents les plus pertinents en haut de la liste.
Le modèle de reclassement, souvent un réseau neuronal ou une architecture basée sur un transformateur, est spécifiquement formé pour évaluer la pertinence d'un document par rapport à une requête donnée. En tirant parti des capacités avancées de compréhension du langage naturel, le reclasseur peut capturer les nuances sémantiques et les relations contextuelles entre la requête et les documents, ce qui permet d'obtenir un classement plus précis et plus pertinent.
Avantages de la récupération en deux étapes et des reclassements
L'adoption de la récupération en deux étapes avec rerankers offre plusieurs avantages significatifs dans le contexte des systèmes RAG :
Amélioration de la précision : En reclassant les documents initialement récupérés et en promouvant les plus pertinents vers le haut, le système peut fournir des informations plus précises au modèle linguistique, conduisant à des réponses générées de meilleure qualité.
Problèmes hors domaine atténués : Les modèles d'intégration utilisés pour la récupération traditionnelle sont souvent formés sur des corpus de textes à usage général, qui peuvent ne pas capturer de manière adéquate le langage et la sémantique spécifiques au domaine. Les modèles de reclassement, en revanche, peuvent être formés sur des données spécifiques à un domaine, atténuant ainsi le problème « hors domaine » et améliorant la pertinence des documents récupérés dans des domaines spécialisés.
Évolutivité : L'approche en deux étapes permet une mise à l'échelle efficace en tirant parti de méthodes de récupération rapides et légères dans la phase initiale, tout en réservant le processus de reclassement, plus intensif en termes de calcul, à un sous-ensemble plus petit de documents.
Flexibilité : Les modèles de reclassement peuvent être échangés ou mis à jour indépendamment de la méthode de récupération initiale, offrant ainsi flexibilité et adaptabilité aux besoins évolutifs du système.
ColBERT : Interaction tardive efficace et efficiente
L'un des modèles les plus remarquables en matière de reclassement est ColBERT (Interaction tardive contextualisée sur BERT ). ColBERT est un modèle de reclassement de documents qui exploite les capacités approfondies de compréhension du langage de BERT tout en introduisant un nouveau mécanisme d'interaction connu sous le nom d'« interaction tardive ».
ColBERT : recherche de passage efficace et efficiente via une interaction tardive contextualisée sur BERT
Le mécanisme d'interaction tardive de ColBERT permet une récupération efficace et précise en traitant les requêtes et les documents séparément jusqu'aux étapes finales du processus de récupération. Plus précisément, ColBERT encode indépendamment la requête et le document à l'aide de BERT, puis utilise une étape d'interaction légère mais puissante qui modélise leur similarité fine. En retardant mais en conservant cette interaction fine, ColBERT peut exploiter l'expressivité des modèles de langage profond tout en acquérant simultanément la possibilité de précalculer les représentations de documents hors ligne, accélérant ainsi considérablement le traitement des requêtes.
L'architecture d'interaction tardive de ColBERT offre plusieurs avantages, notamment une efficacité informatique améliorée, une évolutivité en fonction de la taille de la collection de documents et une applicabilité pratique pour des scénarios du monde réel. De plus, ColBERT a été amélioré avec des techniques telles que la supervision débruitée et la compression résiduelle (dans ColBERTv2), qui affinent le processus de formation et réduisent l'empreinte spatiale du modèle tout en maintenant une efficacité de récupération élevée.
Cet extrait de code montre comment configurer et utiliser le modèle jina-colbert-v1-en pour indexer une collection de documents, en tirant parti de sa capacité à gérer efficacement des contextes longs.
Implémentation de la récupération en deux étapes avec les Rerankers
Maintenant que nous comprenons les principes de la récupération en deux étapes et des reclassements, explorons leur mise en œuvre pratique dans le contexte d'un système RAG. Nous exploiterons les bibliothèques et frameworks populaires pour démontrer l’intégration de ces techniques.
Configuration de l'environnement
Avant de plonger dans le code, configurons notre environnement de développement. Nous utiliserons Python et plusieurs bibliothèques NLP populaires, notamment Hugging Face Transformers, Sentence Transformers et LanceDB.
# Install required libraries
!pip install datasets huggingface_hub sentence_transformers lancedb
Préparation des données
À des fins de démonstration, nous utiliserons l'ensemble de données « ai-arxiv-chunked » de Hugging Face Datasets, qui contient plus de 400 articles ArXiv sur l'apprentissage automatique, le traitement du langage naturel et les grands modèles de langage.
from datasets import load_dataset
dataset = load_dataset("jamescalam/ai-arxiv-chunked", split="train")
<pre>
Ensuite, nous prétraiterons les données et les diviserons en morceaux plus petits pour faciliter une récupération et un traitement efficaces.
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)
Pour l'étape de récupération initiale, nous utiliserons un modèle Sentence Transformer pour encoder nos documents et requêtes dans des représentations vectorielles denses, puis effectuerons une recherche approximative du voisin le plus proche à l'aide d'une base de données vectorielle telle que 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)
Avec nos documents indexés, nous pouvons effectuer la récupération initiale en trouvant les voisins les plus proches d'un vecteur de requête donné.
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)
Reclassement
Après la récupération initiale, nous utiliserons un modèle de reclassement pour réorganiser les documents récupérés en fonction de leur pertinence par rapport à la requête. Dans cet exemple, nous utiliserons le reranker ColBERT, un modèle rapide et précis basé sur un transformateur spécialement conçu pour le classement des documents.
from lancedb.rerankers import ColbertReranker
reranker = ColbertReranker()
# Rerank initial documents
reranked_docs = reranker.rerank(query, initial_docs)
Les reranked_docs
list contient désormais les documents réorganisés en fonction de leur pertinence par rapport à la requête, telle que déterminée par le reranker ColBERT.
Augmentation et génération
Avec les documents reclassés et pertinents en main, nous pouvons passer aux étapes d'augmentation et de génération du pipeline RAG. Nous utiliserons un modèle de langage de la bibliothèque Hugging Face Transformers pour générer la réponse finale.
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)